Skip to content

Commit

Permalink
feat(Flow): custom drop event
Browse files Browse the repository at this point in the history
  • Loading branch information
MEsteves22 authored and plagoa committed Oct 25, 2023
1 parent f6fd8f9 commit b55af56
Show file tree
Hide file tree
Showing 9 changed files with 388 additions and 11 deletions.
24 changes: 22 additions & 2 deletions packages/lab/src/components/Flow/DroppableFlow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,20 @@ export interface HvDroppableFlowProps<
edges?: Edge[];
/** A Jss Object used to override or extend the styles applied to the component. */
classes?: HvFlowClasses;
/** Function called when the flow changes. Returns the updated nodes and edges. */
/** Callback called when the flow changes. Returns the updated nodes and edges. */
onFlowChange?: (nodes: Node<NodeData, NodeType>[], edges: Edge[]) => void;
/**
* Callback called when a node is dropped in the flow.
*
* This callback should be used to override the custom UI Kit drop event.
* Thus, when defined, the user is responsible for adding nodes to the flow.
*
* This callback is called when `HvFlowSidebar` is used or a custom sidebar was created using Dnd Kit.
* When a custom sidebar was created using the native HTML drag and drop API, refer to the `onDrop` callback.
*
* Returns the event and the node to be added to the flow.
*/
onDndDrop?: (event: DragEndEvent, node: Node) => void;
}

export const getNode = (nodes: Node[], nodeId: string) => {
Expand Down Expand Up @@ -103,6 +115,7 @@ export const HvDroppableFlow = ({
className,
children,
onFlowChange,
onDndDrop,
classes: classesProp,
nodes: initialNodes = [],
edges: initialEdges = [],
Expand Down Expand Up @@ -146,13 +159,20 @@ export const HvDroppableFlow = ({
// Node data
const data = event.active.data.current?.hvFlow?.data || {};

// Node to add
const newNode: Node = {
id: uid(),
position,
data,
type,
};

// Drop override
if (onDndDrop) {
onDndDrop(event, newNode);
return;
}

setNodes((nds) => nds.concat(newNode));
} else {
// eslint-disable-next-line no-console
Expand All @@ -162,7 +182,7 @@ export const HvDroppableFlow = ({
}
}
},
[elementId, nodeTypes, reactFlowInstance]
[elementId, nodeTypes, onDndDrop, reactFlowInstance]
);

useDndMonitor({
Expand Down
46 changes: 46 additions & 0 deletions packages/lab/src/components/Flow/stories/CustomDrop/BarChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { css } from "@emotion/css";
import { HvFlowNode } from "@hitachivantara/uikit-react-lab";
import { HvBarChart } from "@hitachivantara/uikit-react-viz";
import { useStore } from "reactflow";

import { data } from "./data";

export const BarChart = (props) => {
const { id } = props;
const nodes = useStore((state) => state.getNodes());
const edges = useStore((state) => state.edges);
const dataNodeId = edges.find((e) => e.target === id)?.source;
const dataNode = nodes.find((n) => n.id === dataNodeId);

return (
<HvFlowNode
description="Bar Chart"
expanded
classes={{ root: css({ width: 500 }) }}
{...props}
>
{dataNode && dataNode.data && dataNode.data.country && (
<div>
<HvBarChart
data={data[dataNode.data.country]}
groupBy="Month"
measures="Precipitation"
grid={{ top: 10, bottom: 40, right: 10, left: 40 }}
/>
</div>
)}
</HvFlowNode>
);
};

BarChart.meta = {
label: "Bar Chart",
groupId: "visualizations",
inputs: [
{
label: "Data",
isMandatory: true,
accepts: ["data"],
},
],
};
46 changes: 46 additions & 0 deletions packages/lab/src/components/Flow/stories/CustomDrop/LineChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { css } from "@emotion/css";
import { HvFlowNode } from "@hitachivantara/uikit-react-lab";
import { HvLineChart } from "@hitachivantara/uikit-react-viz";
import { useStore } from "reactflow";

import { data } from "./data";

export const LineChart = (props) => {
const { id } = props;
const nodes = useStore((state) => state.getNodes());
const edges = useStore((state) => state.edges);
const dataNodeId = edges.find((e) => e.target === id)?.source;
const dataNode = nodes.find((n) => n.id === dataNodeId);

return (
<HvFlowNode
description="Line Chart"
expanded
classes={{ root: css({ width: 500 }) }}
{...props}
>
{dataNode && dataNode.data && dataNode.data.country && (
<div>
<HvLineChart
data={data[dataNode.data.country]}
groupBy="Month"
measures="Precipitation"
grid={{ top: 10, bottom: 40, right: 10, left: 40 }}
/>
</div>
)}
</HvFlowNode>
);
};

LineChart.meta = {
label: "Line Chart",
groupId: "visualizations",
inputs: [
{
label: "Data",
isMandatory: true,
accepts: ["data"],
},
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { HvFlowNode } from "@hitachivantara/uikit-react-lab";

import { data } from "./data";

export const Precipitation = (props) => {
return (
<HvFlowNode
description="Precipitation data"
expanded
params={[
{
id: "country",
label: "Country",
type: "select",
options: Object.keys(data),
},
]}
{...props}
/>
);
};

Precipitation.meta = {
label: "Precipitation",
groupId: "sources",
outputs: [
{
label: "Data",
isMandatory: true,
provides: "data",
},
],
};
35 changes: 35 additions & 0 deletions packages/lab/src/components/Flow/stories/CustomDrop/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];

export const data = {
portugal: {
Month: months,
Precipitation: [
12.6, 15.9, 19.0, 26.0, 28.2, 70.7, 145.6, 132.2, 78.7, 22.8, 4.0, 2.9,
],
},
usa: {
Month: months,
Precipitation: [
32.2, 17.2, 12.9, 22.0, 11.2, 99.7, 92.6, 11.2, 23.7, 19.8, 2.0, 7.9,
],
},
japan: {
Month: months,
Precipitation: [
12.4, 34.9, 18.0, 45.2, 33.2, 67.7, 187.6, 245.2, 22.7, 12.8, 1.0, 6.9,
],
},
};

0 comments on commit b55af56

Please sign in to comment.