@hitachivantara/uikit-react-lab 5.26.2 → 5.26.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,21 +16,27 @@ const ReactFlow__default = /* @__PURE__ */ _interopDefault(ReactFlow);
16
16
  const getNode = (nodes, nodeId) => {
17
17
  return nodes.find((n) => n.id === nodeId);
18
18
  };
19
- const validateEdge = (nodes, edges, edge, nodeMetaRegistry) => {
20
- if (!edge.sourceHandle || !edge.targetHandle)
19
+ const validateEdge = (nodes, edges, connection, nodeMetaRegistry) => {
20
+ const {
21
+ source: sourceId,
22
+ sourceHandle,
23
+ target: targetId,
24
+ targetHandle
25
+ } = connection;
26
+ if (!sourceHandle || !targetHandle || !sourceId || !targetId)
21
27
  return false;
22
- const sourceNode = getNode(nodes, edge.source);
23
- const targetNode = getNode(nodes, edge.target);
28
+ const sourceNode = getNode(nodes, sourceId);
29
+ const targetNode = getNode(nodes, targetId);
24
30
  if (!sourceNode || !targetNode)
25
31
  return false;
26
32
  const sourceType = sourceNode.type;
27
33
  const targetType = targetNode.type;
28
34
  if (!sourceType || !targetType)
29
35
  return false;
30
- const inputs = nodeMetaRegistry[edge.target]?.inputs || [];
31
- const outputs = nodeMetaRegistry[edge.source]?.outputs || [];
32
- const source = outputs.map((out) => out.outputs || out).flat().find((out) => out.id === edge.sourceHandle);
33
- const target = inputs.map((inp) => inp.inputs || inp).flat().find((inp) => inp.id === edge.targetHandle);
36
+ const inputs = nodeMetaRegistry[targetId]?.inputs || [];
37
+ const outputs = nodeMetaRegistry[sourceId]?.outputs || [];
38
+ const source = outputs.map((out) => out.outputs || out).flat().find((out) => out.id === sourceHandle);
39
+ const target = inputs.map((inp) => inp.inputs || inp).flat().find((inp) => inp.id === targetHandle);
34
40
  const sourceProvides = source?.provides || "";
35
41
  const targetAccepts = target?.accepts || [];
36
42
  const sourceMaxConnections = source?.maxConnections;
@@ -38,13 +44,13 @@ const validateEdge = (nodes, edges, edge, nodeMetaRegistry) => {
38
44
  let isValid = targetAccepts.length === 0 || targetAccepts.includes(sourceProvides);
39
45
  if (isValid && targetMaxConnections != null) {
40
46
  const targetConnections = edges.filter(
41
- (edg) => edg.target === edge.target && edg.targetHandle === edge.targetHandle
47
+ (edg) => edg.target === targetId && edg.targetHandle === targetHandle
42
48
  ).length;
43
49
  isValid = targetConnections < targetMaxConnections;
44
50
  }
45
51
  if (isValid && sourceMaxConnections != null) {
46
52
  const sourceConnections = edges.filter(
47
- (edg) => edg.source === edge.source && edg.sourceHandle === edge.sourceHandle
53
+ (edg) => edg.source === sourceId && edg.sourceHandle === sourceHandle
48
54
  ).length;
49
55
  isValid = sourceConnections < sourceMaxConnections;
50
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DroppableFlow.cjs","sources":["../../../src/Flow/DroppableFlow.tsx"],"sourcesContent":["import { useCallback, useState } from \"react\";\n\nimport ReactFlow, {\n Connection,\n EdgeChange,\n NodeChange,\n ReactFlowProps,\n addEdge,\n applyEdgeChanges,\n applyNodeChanges,\n useReactFlow,\n MarkerType,\n Edge,\n Node,\n} from \"reactflow\";\n\nimport { Global } from \"@emotion/react\";\n\nimport { DragEndEvent, useDndMonitor, useDroppable } from \"@dnd-kit/core\";\n\nimport { uid } from \"uid\";\n\nimport { ExtractNames, useUniqueId } from \"@hitachivantara/uikit-react-core\";\n\nimport {\n HvFlowNodeInputGroup,\n HvFlowNodeMetaRegistry,\n HvFlowNodeOutputGroup,\n} from \"./types\";\nimport { staticClasses, useClasses } from \"./Flow.styles\";\nimport { useFlowContext } from \"./hooks\";\nimport { flowStyles } from \"./base\";\nimport { useNodeMetaRegistry } from \"./FlowContext/NodeMetaContext\";\n\nexport { staticClasses as flowClasses };\n\nexport type HvFlowClasses = ExtractNames<typeof useClasses>;\n\nexport interface HvDroppableFlowProps<\n NodeType extends string | undefined = string | undefined,\n NodeData = any\n> extends Omit<ReactFlowProps, \"nodes\" | \"edges\" | \"nodeTypes\"> {\n /** Flow content: background, controls, and minimap. */\n children?: React.ReactNode;\n /** Flow nodes. */\n nodes?: Node<NodeData, NodeType>[];\n /** Flow edges. */\n edges?: Edge[];\n /** A Jss Object used to override or extend the styles applied to the component. */\n classes?: HvFlowClasses;\n /** Callback called when the flow changes. Returns the updated nodes and edges. */\n onFlowChange?: (nodes: Node<NodeData, NodeType>[], edges: Edge[]) => void;\n /**\n * Callback called when a node is dropped in the flow.\n *\n * This callback should be used to override the custom UI Kit drop event.\n * Thus, when defined, the user is responsible for adding nodes to the flow.\n *\n * This callback is called when `HvFlowSidebar` is used or a custom sidebar was created using Dnd Kit.\n * When a custom sidebar was created using the native HTML drag and drop API, refer to the `onDrop` callback.\n *\n * Returns the event and the node to be added to the flow.\n */\n onDndDrop?: (event: DragEndEvent, node: Node) => void;\n}\n\nexport const getNode = (nodes: Node[], nodeId: string) => {\n return nodes.find((n) => n.id === nodeId);\n};\n\nconst validateEdge = (\n nodes: Node[],\n edges: Edge[],\n edge: Edge,\n nodeMetaRegistry: HvFlowNodeMetaRegistry\n) => {\n if (!edge.sourceHandle || !edge.targetHandle) return false;\n\n const sourceNode = getNode(nodes, edge.source);\n const targetNode = getNode(nodes, edge.target);\n\n if (!sourceNode || !targetNode) return false;\n\n const sourceType = sourceNode.type;\n const targetType = targetNode.type;\n\n if (!sourceType || !targetType) return false;\n\n const inputs = nodeMetaRegistry[edge.target]?.inputs || [];\n const outputs = nodeMetaRegistry[edge.source]?.outputs || [];\n\n const source = outputs\n .map((out) => (out as HvFlowNodeOutputGroup).outputs || out)\n .flat()\n .find((out) => out.id === edge.sourceHandle);\n const target = inputs\n .map((inp) => (inp as HvFlowNodeInputGroup).inputs || inp)\n .flat()\n .find((inp) => inp.id === edge.targetHandle);\n\n const sourceProvides = source?.provides || \"\";\n const targetAccepts = target?.accepts || [];\n const sourceMaxConnections = source?.maxConnections;\n const targetMaxConnections = target?.maxConnections;\n\n let isValid =\n targetAccepts.length === 0 || targetAccepts.includes(sourceProvides);\n\n if (isValid && targetMaxConnections != null) {\n const targetConnections = edges.filter(\n (edg) =>\n edg.target === edge.target && edg.targetHandle === edge.targetHandle\n ).length;\n\n isValid = targetConnections < targetMaxConnections;\n }\n\n if (isValid && sourceMaxConnections != null) {\n const sourceConnections = edges.filter(\n (edg) =>\n edg.source === edge.source && edg.sourceHandle === edge.sourceHandle\n ).length;\n\n isValid = sourceConnections < sourceMaxConnections;\n }\n\n return isValid;\n};\n\nexport const HvDroppableFlow = ({\n id,\n className,\n children,\n onFlowChange,\n onDndDrop,\n classes: classesProp,\n nodes: initialNodes = [],\n edges: initialEdges = [],\n onConnect: onConnectProp,\n onNodesChange: onNodesChangeProp,\n onEdgesChange: onEdgesChangeProp,\n defaultEdgeOptions: defaultEdgeOptionsProp,\n ...others\n}: HvDroppableFlowProps) => {\n const { classes, cx } = useClasses(classesProp);\n\n const elementId = useUniqueId(id, \"hvFlow\");\n\n const reactFlowInstance = useReactFlow();\n\n const { nodeTypes } = useFlowContext();\n\n const [nodes, setNodes] = useState(initialNodes);\n const [edges, setEdges] = useState(initialEdges);\n\n const { setNodeRef } = useDroppable({\n id: elementId,\n });\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n if (event.over?.id !== elementId) return;\n\n const hvFlow = event.active.data.current?.hvFlow;\n const type = hvFlow?.type;\n\n // Only known node types can be dropped in the canvas\n if (!type || !nodeTypes?.[type]) {\n if (import.meta.env.DEV) {\n // eslint-disable-next-line no-console\n console.error(\n `Could not add node to the flow because of unknown type ${type}. Use nodeTypes to define all the node types.`\n );\n }\n return;\n }\n\n // Position node in the flow\n const position = reactFlowInstance.screenToFlowPosition({\n x: hvFlow?.x || 0,\n y: hvFlow?.y || 0,\n });\n\n // Node data\n const data = hvFlow?.data || {};\n\n // Node to add\n const newNode: Node = {\n id: uid(),\n position,\n data,\n type,\n };\n\n // Drop override\n if (onDndDrop) {\n onDndDrop(event, newNode);\n return;\n }\n\n setNodes((nds) => nds.concat(newNode));\n },\n [elementId, nodeTypes, onDndDrop, reactFlowInstance]\n );\n\n useDndMonitor({\n onDragEnd: handleDragEnd,\n });\n\n const handleFlowChange = useCallback(\n (\n nds: NonNullable<HvDroppableFlowProps[\"nodes\"]>,\n eds: NonNullable<HvDroppableFlowProps[\"edges\"]>\n ) => {\n // The new flow is returned if the user is not dragging nodes\n // This avoids triggering this handler too many times\n const isDragging = nds.find((node) => node.dragging);\n if (!isDragging) {\n onFlowChange?.(nds, eds);\n }\n },\n [onFlowChange]\n );\n\n const handleConnect = useCallback(\n (connection: Connection) => {\n const eds = addEdge(connection, edges);\n setEdges(eds);\n\n handleFlowChange(nodes, eds);\n onConnectProp?.(connection);\n },\n [edges, handleFlowChange, nodes, onConnectProp]\n );\n\n const handleNodesChange = useCallback(\n (changes: NodeChange[]) => {\n const nds = applyNodeChanges(changes, nodes);\n setNodes(nds);\n\n handleFlowChange(nds, edges);\n onNodesChangeProp?.(changes);\n },\n [edges, handleFlowChange, nodes, onNodesChangeProp]\n );\n\n const handleEdgesChange = useCallback(\n (changes: EdgeChange[]) => {\n const eds = applyEdgeChanges(changes, edges);\n setEdges(eds);\n\n handleFlowChange(nodes, eds);\n onEdgesChangeProp?.(changes);\n },\n [edges, handleFlowChange, nodes, onEdgesChangeProp]\n );\n\n const { registry } = useNodeMetaRegistry();\n const isValidConnection = (connection) =>\n validateEdge(nodes, edges, connection, registry);\n\n const defaultEdgeOptions = {\n markerEnd: {\n type: MarkerType.ArrowClosed,\n height: 20,\n width: 20,\n },\n type: \"smoothstep\",\n pathOptions: {\n borderRadius: 40,\n },\n ...defaultEdgeOptionsProp,\n };\n\n return (\n <>\n <Global styles={flowStyles} />\n <div\n id={elementId}\n ref={setNodeRef}\n className={cx(classes.root, className)}\n >\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onConnect={handleConnect}\n isValidConnection={isValidConnection}\n defaultEdgeOptions={defaultEdgeOptions}\n snapGrid={[1, 1]}\n snapToGrid\n onError={(code, message) => {\n if (import.meta.env.DEV) {\n // eslint-disable-next-line no-console\n console.error(message);\n }\n }}\n {...others}\n >\n {children}\n </ReactFlow>\n </div>\n </>\n );\n};\n"],"names":["useClasses","useUniqueId","useReactFlow","useFlowContext","useState","useDroppable","useCallback","uid","useDndMonitor","addEdge","applyNodeChanges","applyEdgeChanges","useNodeMetaRegistry","MarkerType","jsxs","Fragment","jsx","Global","flowStyles","ReactFlow"],"mappings":"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"}
1
+ {"version":3,"file":"DroppableFlow.cjs","sources":["../../../src/Flow/DroppableFlow.tsx"],"sourcesContent":["import { useCallback, useState } from \"react\";\nimport ReactFlow, {\n Connection,\n EdgeChange,\n NodeChange,\n ReactFlowProps,\n addEdge,\n applyEdgeChanges,\n applyNodeChanges,\n useReactFlow,\n MarkerType,\n Edge,\n Node,\n} from \"reactflow\";\nimport { Global } from \"@emotion/react\";\nimport { DragEndEvent, useDndMonitor, useDroppable } from \"@dnd-kit/core\";\nimport { uid } from \"uid\";\nimport { ExtractNames, useUniqueId } from \"@hitachivantara/uikit-react-core\";\n\nimport {\n HvFlowNodeInputGroup,\n HvFlowNodeMetaRegistry,\n HvFlowNodeOutputGroup,\n} from \"./types\";\nimport { staticClasses, useClasses } from \"./Flow.styles\";\nimport { useFlowContext } from \"./hooks\";\nimport { flowStyles } from \"./base\";\nimport { useNodeMetaRegistry } from \"./FlowContext/NodeMetaContext\";\n\nexport { staticClasses as flowClasses };\n\nexport type HvFlowClasses = ExtractNames<typeof useClasses>;\n\nexport interface HvDroppableFlowProps<\n NodeType extends string | undefined = string | undefined,\n NodeData = any\n> extends Omit<ReactFlowProps, \"nodes\" | \"edges\" | \"nodeTypes\"> {\n /** Flow content: background, controls, and minimap. */\n children?: React.ReactNode;\n /** Flow nodes. */\n nodes?: Node<NodeData, NodeType>[];\n /** Flow edges. */\n edges?: Edge[];\n /** A Jss Object used to override or extend the styles applied to the component. */\n classes?: HvFlowClasses;\n /** Callback called when the flow changes. Returns the updated nodes and edges. */\n onFlowChange?: (nodes: Node<NodeData, NodeType>[], edges: Edge[]) => void;\n /**\n * Callback called when a node is dropped in the flow.\n *\n * This callback should be used to override the custom UI Kit drop event.\n * Thus, when defined, the user is responsible for adding nodes to the flow.\n *\n * This callback is called when `HvFlowSidebar` is used or a custom sidebar was created using Dnd Kit.\n * When a custom sidebar was created using the native HTML drag and drop API, refer to the `onDrop` callback.\n *\n * Returns the event and the node to be added to the flow.\n */\n onDndDrop?: (event: DragEndEvent, node: Node) => void;\n}\n\nexport const getNode = (nodes: Node[], nodeId: string) => {\n return nodes.find((n) => n.id === nodeId);\n};\n\nconst validateEdge = (\n nodes: Node[],\n edges: Edge[],\n connection: Connection,\n nodeMetaRegistry: HvFlowNodeMetaRegistry\n) => {\n const {\n source: sourceId,\n sourceHandle,\n target: targetId,\n targetHandle,\n } = connection;\n\n if (!sourceHandle || !targetHandle || !sourceId || !targetId) return false;\n\n const sourceNode = getNode(nodes, sourceId);\n const targetNode = getNode(nodes, targetId);\n\n if (!sourceNode || !targetNode) return false;\n\n const sourceType = sourceNode.type;\n const targetType = targetNode.type;\n\n if (!sourceType || !targetType) return false;\n\n const inputs = nodeMetaRegistry[targetId]?.inputs || [];\n const outputs = nodeMetaRegistry[sourceId]?.outputs || [];\n\n const source = outputs\n .map((out) => (out as HvFlowNodeOutputGroup).outputs || out)\n .flat()\n .find((out) => out.id === sourceHandle);\n const target = inputs\n .map((inp) => (inp as HvFlowNodeInputGroup).inputs || inp)\n .flat()\n .find((inp) => inp.id === targetHandle);\n\n const sourceProvides = source?.provides || \"\";\n const targetAccepts = target?.accepts || [];\n const sourceMaxConnections = source?.maxConnections;\n const targetMaxConnections = target?.maxConnections;\n\n let isValid =\n targetAccepts.length === 0 || targetAccepts.includes(sourceProvides);\n\n if (isValid && targetMaxConnections != null) {\n const targetConnections = edges.filter(\n (edg) => edg.target === targetId && edg.targetHandle === targetHandle\n ).length;\n\n isValid = targetConnections < targetMaxConnections;\n }\n\n if (isValid && sourceMaxConnections != null) {\n const sourceConnections = edges.filter(\n (edg) => edg.source === sourceId && edg.sourceHandle === sourceHandle\n ).length;\n\n isValid = sourceConnections < sourceMaxConnections;\n }\n\n return isValid;\n};\n\nexport const HvDroppableFlow = ({\n id,\n className,\n children,\n onFlowChange,\n onDndDrop,\n classes: classesProp,\n nodes: initialNodes = [],\n edges: initialEdges = [],\n onConnect: onConnectProp,\n onNodesChange: onNodesChangeProp,\n onEdgesChange: onEdgesChangeProp,\n defaultEdgeOptions: defaultEdgeOptionsProp,\n ...others\n}: HvDroppableFlowProps) => {\n const { classes, cx } = useClasses(classesProp);\n\n const elementId = useUniqueId(id, \"hvFlow\");\n\n const reactFlowInstance = useReactFlow();\n\n const { nodeTypes } = useFlowContext();\n\n const [nodes, setNodes] = useState(initialNodes);\n const [edges, setEdges] = useState(initialEdges);\n\n const { setNodeRef } = useDroppable({\n id: elementId,\n });\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n if (event.over?.id !== elementId) return;\n\n const hvFlow = event.active.data.current?.hvFlow;\n const type = hvFlow?.type;\n\n // Only known node types can be dropped in the canvas\n if (!type || !nodeTypes?.[type]) {\n if (import.meta.env.DEV) {\n // eslint-disable-next-line no-console\n console.error(\n `Could not add node to the flow because of unknown type ${type}. Use nodeTypes to define all the node types.`\n );\n }\n return;\n }\n\n // Position node in the flow\n const position = reactFlowInstance.screenToFlowPosition({\n x: hvFlow?.x || 0,\n y: hvFlow?.y || 0,\n });\n\n // Node data\n const data = hvFlow?.data || {};\n\n // Node to add\n const newNode: Node = {\n id: uid(),\n position,\n data,\n type,\n };\n\n // Drop override\n if (onDndDrop) {\n onDndDrop(event, newNode);\n return;\n }\n\n setNodes((nds) => nds.concat(newNode));\n },\n [elementId, nodeTypes, onDndDrop, reactFlowInstance]\n );\n\n useDndMonitor({\n onDragEnd: handleDragEnd,\n });\n\n const handleFlowChange = useCallback(\n (\n nds: NonNullable<HvDroppableFlowProps[\"nodes\"]>,\n eds: NonNullable<HvDroppableFlowProps[\"edges\"]>\n ) => {\n // The new flow is returned if the user is not dragging nodes\n // This avoids triggering this handler too many times\n const isDragging = nds.find((node) => node.dragging);\n if (!isDragging) {\n onFlowChange?.(nds, eds);\n }\n },\n [onFlowChange]\n );\n\n const handleConnect = useCallback(\n (connection: Connection) => {\n const eds = addEdge(connection, edges);\n setEdges(eds);\n\n handleFlowChange(nodes, eds);\n onConnectProp?.(connection);\n },\n [edges, handleFlowChange, nodes, onConnectProp]\n );\n\n const handleNodesChange = useCallback(\n (changes: NodeChange[]) => {\n const nds = applyNodeChanges(changes, nodes);\n setNodes(nds);\n\n handleFlowChange(nds, edges);\n onNodesChangeProp?.(changes);\n },\n [edges, handleFlowChange, nodes, onNodesChangeProp]\n );\n\n const handleEdgesChange = useCallback(\n (changes: EdgeChange[]) => {\n const eds = applyEdgeChanges(changes, edges);\n setEdges(eds);\n\n handleFlowChange(nodes, eds);\n onEdgesChangeProp?.(changes);\n },\n [edges, handleFlowChange, nodes, onEdgesChangeProp]\n );\n\n const { registry } = useNodeMetaRegistry();\n\n const isValidConnection: ReactFlowProps[\"isValidConnection\"] = (connection) =>\n validateEdge(nodes, edges, connection, registry);\n\n const defaultEdgeOptions = {\n markerEnd: {\n type: MarkerType.ArrowClosed,\n height: 20,\n width: 20,\n },\n type: \"smoothstep\",\n pathOptions: {\n borderRadius: 40,\n },\n ...defaultEdgeOptionsProp,\n };\n\n return (\n <>\n <Global styles={flowStyles} />\n <div\n id={elementId}\n ref={setNodeRef}\n className={cx(classes.root, className)}\n >\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onConnect={handleConnect}\n isValidConnection={isValidConnection}\n defaultEdgeOptions={defaultEdgeOptions}\n snapGrid={[1, 1]}\n snapToGrid\n onError={(code, message) => {\n if (import.meta.env.DEV) {\n // eslint-disable-next-line no-console\n console.error(message);\n }\n }}\n {...others}\n >\n {children}\n </ReactFlow>\n </div>\n </>\n );\n};\n"],"names":["useClasses","useUniqueId","useReactFlow","useFlowContext","useState","useDroppable","useCallback","uid","useDndMonitor","addEdge","applyNodeChanges","applyEdgeChanges","useNodeMetaRegistry","MarkerType","jsxs","Fragment","jsx","Global","flowStyles","ReactFlow"],"mappings":"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"}
@@ -2,33 +2,34 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const React = require("react");
4
4
  const ReactFlow = require("reactflow");
5
+ const shallow = require("zustand/shallow");
5
6
  function useFlowNode(id) {
6
7
  const nodeSelector = React.useCallback(
7
8
  (state) => state.getNodes().find((n) => n.id === id),
8
9
  [id]
9
10
  );
10
- return ReactFlow.useStore(nodeSelector);
11
+ return ReactFlow.useStore(nodeSelector, shallow.shallow);
11
12
  }
12
13
  function useFlowNodeInputEdges(id) {
13
14
  const inputEdgesSelector = React.useCallback(
14
15
  (state) => state.edges.filter((e) => e.target === id),
15
16
  [id]
16
17
  );
17
- return ReactFlow.useStore(inputEdgesSelector);
18
+ return ReactFlow.useStore(inputEdgesSelector, shallow.shallow);
18
19
  }
19
20
  function useFlowNodeOutputEdges(id) {
20
21
  const outputEdgesSelector = React.useCallback(
21
22
  (state) => state.edges.filter((e) => e.source === id),
22
23
  [id]
23
24
  );
24
- return ReactFlow.useStore(outputEdgesSelector);
25
+ return ReactFlow.useStore(outputEdgesSelector, shallow.shallow);
25
26
  }
26
27
  function useFlowNodeEdges(id) {
27
28
  const edgesSelector = React.useCallback(
28
29
  (state) => state.edges.filter((e) => e.source === id || e.target === id),
29
30
  [id]
30
31
  );
31
- return ReactFlow.useStore(edgesSelector);
32
+ return ReactFlow.useStore(edgesSelector, shallow.shallow);
32
33
  }
33
34
  function useFlowNodeParents(id) {
34
35
  const inputEdges = useFlowNodeInputEdges(id);
@@ -38,7 +39,7 @@ function useFlowNodeParents(id) {
38
39
  },
39
40
  [inputEdges]
40
41
  );
41
- return ReactFlow.useStore(parentNodesSelector);
42
+ return ReactFlow.useStore(parentNodesSelector, shallow.shallow);
42
43
  }
43
44
  function useFlowInputNodes(id) {
44
45
  const nodes = ReactFlow.useNodes();
@@ -1 +1 @@
1
- {"version":3,"file":"useFlowNode.cjs","sources":["../../../../src/Flow/hooks/useFlowNode.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport {\n Node,\n Edge,\n ReactFlowState,\n useStore,\n useNodes,\n useEdges,\n useReactFlow,\n useNodeId,\n} from \"reactflow\";\n\nexport function useFlowNode<T extends Node = Node>(id: string) {\n const nodeSelector = useCallback(\n (state: ReactFlowState) =>\n state.getNodes().find((n: Node): n is T => n.id === id),\n [id]\n );\n return useStore<T | undefined>(nodeSelector);\n}\n\nexport function useFlowNodeInputEdges(id: string) {\n const inputEdgesSelector = useCallback(\n (state: ReactFlowState) => state.edges.filter((e: Edge) => e.target === id),\n [id]\n );\n return useStore(inputEdgesSelector);\n}\n\nexport function useFlowNodeOutputEdges(id: string) {\n const outputEdgesSelector = useCallback(\n (state: ReactFlowState) => state.edges.filter((e: Edge) => e.source === id),\n [id]\n );\n return useStore(outputEdgesSelector);\n}\n\nexport function useFlowNodeEdges(id: string) {\n const edgesSelector = useCallback(\n (state: ReactFlowState) =>\n state.edges.filter((e: Edge) => e.source === id || e.target === id),\n [id]\n );\n return useStore(edgesSelector);\n}\n\nexport function useFlowNodeParents(id: string) {\n const inputEdges = useFlowNodeInputEdges(id);\n const parentNodesSelector = useCallback(\n (state: ReactFlowState) => {\n return inputEdges\n .map((e) => state.getNodes().find((n: Node) => n.id === e.source))\n .filter((n): n is Node => n !== null);\n },\n [inputEdges]\n );\n return useStore(parentNodesSelector);\n}\n\nexport function useFlowInputNodes<T = any>(id: string) {\n const nodes = useNodes();\n const edges = useEdges();\n\n return useMemo(() => {\n return edges\n .filter((e) => e.target === id)\n .map((e) => nodes.find((n) => n.id === e.source))\n .filter((n): n is Node<T> => n !== null);\n }, [edges, id, nodes]);\n}\n\nexport function useFlowOutputNodes<T = any>(id: string) {\n const nodes = useNodes();\n const edges = useEdges();\n\n return useMemo(() => {\n return edges\n .filter((e) => e.source === id)\n .map((e) => nodes.find((n) => n.id === e.target))\n .filter((n): n is Node<T> => n !== null);\n }, [edges, id, nodes]);\n}\n\n/** Utilities to manipulate a node in the flow */\nexport function useFlowNodeUtils<NodeData = any>() {\n const nodeId = useNodeId();\n const reactFlowInstance = useReactFlow<NodeData>();\n\n /** Mutate the node's `.data` object */\n const setNodeData = useCallback(\n (setNewData: (newData?: NodeData) => NodeData) => {\n if (!nodeId) return;\n\n reactFlowInstance.setNodes((nodes) => {\n return nodes.map((n) => {\n if (n.id === nodeId) {\n return { ...n, data: setNewData(n.data) };\n }\n return n;\n });\n });\n },\n [nodeId, reactFlowInstance]\n );\n\n return useMemo(\n () => ({\n setNodeData,\n }),\n [setNodeData]\n );\n}\n"],"names":["useCallback","useStore","useNodes","useEdges","useMemo","useNodeId","useReactFlow"],"mappings":"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"}
1
+ {"version":3,"file":"useFlowNode.cjs","sources":["../../../../src/Flow/hooks/useFlowNode.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport {\n Node,\n Edge,\n ReactFlowState,\n useStore,\n useNodes,\n useEdges,\n useReactFlow,\n useNodeId,\n} from \"reactflow\";\nimport { shallow } from \"zustand/shallow\";\n\nexport function useFlowNode<T extends Node = Node>(id: string) {\n const nodeSelector = useCallback(\n (state: ReactFlowState) =>\n state.getNodes().find((n: Node): n is T => n.id === id),\n [id]\n );\n return useStore<T | undefined>(nodeSelector, shallow);\n}\n\nexport function useFlowNodeInputEdges(id: string) {\n const inputEdgesSelector = useCallback(\n (state: ReactFlowState) => state.edges.filter((e: Edge) => e.target === id),\n [id]\n );\n return useStore(inputEdgesSelector, shallow);\n}\n\nexport function useFlowNodeOutputEdges(id: string) {\n const outputEdgesSelector = useCallback(\n (state: ReactFlowState) => state.edges.filter((e: Edge) => e.source === id),\n [id]\n );\n return useStore(outputEdgesSelector, shallow);\n}\n\nexport function useFlowNodeEdges(id: string) {\n const edgesSelector = useCallback(\n (state: ReactFlowState) =>\n state.edges.filter((e: Edge) => e.source === id || e.target === id),\n [id]\n );\n return useStore(edgesSelector, shallow);\n}\n\nexport function useFlowNodeParents(id: string) {\n const inputEdges = useFlowNodeInputEdges(id);\n const parentNodesSelector = useCallback(\n (state: ReactFlowState) => {\n return inputEdges\n .map((e) => state.getNodes().find((n: Node) => n.id === e.source))\n .filter((n): n is Node => n !== null);\n },\n [inputEdges]\n );\n return useStore(parentNodesSelector, shallow);\n}\n\nexport function useFlowInputNodes<T = any>(id: string) {\n const nodes = useNodes();\n const edges = useEdges();\n\n return useMemo(() => {\n return edges\n .filter((e) => e.target === id)\n .map((e) => nodes.find((n) => n.id === e.source))\n .filter((n): n is Node<T> => n !== null);\n }, [edges, id, nodes]);\n}\n\nexport function useFlowOutputNodes<T = any>(id: string) {\n const nodes = useNodes();\n const edges = useEdges();\n\n return useMemo(() => {\n return edges\n .filter((e) => e.source === id)\n .map((e) => nodes.find((n) => n.id === e.target))\n .filter((n): n is Node<T> => n !== null);\n }, [edges, id, nodes]);\n}\n\n/** Utilities to manipulate a node in the flow */\nexport function useFlowNodeUtils<NodeData = any>() {\n const nodeId = useNodeId();\n const reactFlowInstance = useReactFlow<NodeData>();\n\n /** Mutate the node's `.data` object */\n const setNodeData = useCallback(\n (setNewData: (newData?: NodeData) => NodeData) => {\n if (!nodeId) return;\n\n reactFlowInstance.setNodes((nodes) => {\n return nodes.map((n) => {\n if (n.id === nodeId) {\n return { ...n, data: setNewData(n.data) };\n }\n return n;\n });\n });\n },\n [nodeId, reactFlowInstance]\n );\n\n return useMemo(\n () => ({\n setNodeData,\n }),\n [setNodeData]\n );\n}\n"],"names":["useCallback","useStore","shallow","useNodes","useEdges","useMemo","useNodeId","useReactFlow"],"mappings":"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"}
@@ -13,21 +13,27 @@ import { useFlowContext } from "./hooks/useFlowContext.js";
13
13
  const getNode = (nodes, nodeId) => {
14
14
  return nodes.find((n) => n.id === nodeId);
15
15
  };
16
- const validateEdge = (nodes, edges, edge, nodeMetaRegistry) => {
17
- if (!edge.sourceHandle || !edge.targetHandle)
16
+ const validateEdge = (nodes, edges, connection, nodeMetaRegistry) => {
17
+ const {
18
+ source: sourceId,
19
+ sourceHandle,
20
+ target: targetId,
21
+ targetHandle
22
+ } = connection;
23
+ if (!sourceHandle || !targetHandle || !sourceId || !targetId)
18
24
  return false;
19
- const sourceNode = getNode(nodes, edge.source);
20
- const targetNode = getNode(nodes, edge.target);
25
+ const sourceNode = getNode(nodes, sourceId);
26
+ const targetNode = getNode(nodes, targetId);
21
27
  if (!sourceNode || !targetNode)
22
28
  return false;
23
29
  const sourceType = sourceNode.type;
24
30
  const targetType = targetNode.type;
25
31
  if (!sourceType || !targetType)
26
32
  return false;
27
- const inputs = nodeMetaRegistry[edge.target]?.inputs || [];
28
- const outputs = nodeMetaRegistry[edge.source]?.outputs || [];
29
- const source = outputs.map((out) => out.outputs || out).flat().find((out) => out.id === edge.sourceHandle);
30
- const target = inputs.map((inp) => inp.inputs || inp).flat().find((inp) => inp.id === edge.targetHandle);
33
+ const inputs = nodeMetaRegistry[targetId]?.inputs || [];
34
+ const outputs = nodeMetaRegistry[sourceId]?.outputs || [];
35
+ const source = outputs.map((out) => out.outputs || out).flat().find((out) => out.id === sourceHandle);
36
+ const target = inputs.map((inp) => inp.inputs || inp).flat().find((inp) => inp.id === targetHandle);
31
37
  const sourceProvides = source?.provides || "";
32
38
  const targetAccepts = target?.accepts || [];
33
39
  const sourceMaxConnections = source?.maxConnections;
@@ -35,13 +41,13 @@ const validateEdge = (nodes, edges, edge, nodeMetaRegistry) => {
35
41
  let isValid = targetAccepts.length === 0 || targetAccepts.includes(sourceProvides);
36
42
  if (isValid && targetMaxConnections != null) {
37
43
  const targetConnections = edges.filter(
38
- (edg) => edg.target === edge.target && edg.targetHandle === edge.targetHandle
44
+ (edg) => edg.target === targetId && edg.targetHandle === targetHandle
39
45
  ).length;
40
46
  isValid = targetConnections < targetMaxConnections;
41
47
  }
42
48
  if (isValid && sourceMaxConnections != null) {
43
49
  const sourceConnections = edges.filter(
44
- (edg) => edg.source === edge.source && edg.sourceHandle === edge.sourceHandle
50
+ (edg) => edg.source === sourceId && edg.sourceHandle === sourceHandle
45
51
  ).length;
46
52
  isValid = sourceConnections < sourceMaxConnections;
47
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DroppableFlow.js","sources":["../../../src/Flow/DroppableFlow.tsx"],"sourcesContent":["import { useCallback, useState } from \"react\";\n\nimport ReactFlow, {\n Connection,\n EdgeChange,\n NodeChange,\n ReactFlowProps,\n addEdge,\n applyEdgeChanges,\n applyNodeChanges,\n useReactFlow,\n MarkerType,\n Edge,\n Node,\n} from \"reactflow\";\n\nimport { Global } from \"@emotion/react\";\n\nimport { DragEndEvent, useDndMonitor, useDroppable } from \"@dnd-kit/core\";\n\nimport { uid } from \"uid\";\n\nimport { ExtractNames, useUniqueId } from \"@hitachivantara/uikit-react-core\";\n\nimport {\n HvFlowNodeInputGroup,\n HvFlowNodeMetaRegistry,\n HvFlowNodeOutputGroup,\n} from \"./types\";\nimport { staticClasses, useClasses } from \"./Flow.styles\";\nimport { useFlowContext } from \"./hooks\";\nimport { flowStyles } from \"./base\";\nimport { useNodeMetaRegistry } from \"./FlowContext/NodeMetaContext\";\n\nexport { staticClasses as flowClasses };\n\nexport type HvFlowClasses = ExtractNames<typeof useClasses>;\n\nexport interface HvDroppableFlowProps<\n NodeType extends string | undefined = string | undefined,\n NodeData = any\n> extends Omit<ReactFlowProps, \"nodes\" | \"edges\" | \"nodeTypes\"> {\n /** Flow content: background, controls, and minimap. */\n children?: React.ReactNode;\n /** Flow nodes. */\n nodes?: Node<NodeData, NodeType>[];\n /** Flow edges. */\n edges?: Edge[];\n /** A Jss Object used to override or extend the styles applied to the component. */\n classes?: HvFlowClasses;\n /** Callback called when the flow changes. Returns the updated nodes and edges. */\n onFlowChange?: (nodes: Node<NodeData, NodeType>[], edges: Edge[]) => void;\n /**\n * Callback called when a node is dropped in the flow.\n *\n * This callback should be used to override the custom UI Kit drop event.\n * Thus, when defined, the user is responsible for adding nodes to the flow.\n *\n * This callback is called when `HvFlowSidebar` is used or a custom sidebar was created using Dnd Kit.\n * When a custom sidebar was created using the native HTML drag and drop API, refer to the `onDrop` callback.\n *\n * Returns the event and the node to be added to the flow.\n */\n onDndDrop?: (event: DragEndEvent, node: Node) => void;\n}\n\nexport const getNode = (nodes: Node[], nodeId: string) => {\n return nodes.find((n) => n.id === nodeId);\n};\n\nconst validateEdge = (\n nodes: Node[],\n edges: Edge[],\n edge: Edge,\n nodeMetaRegistry: HvFlowNodeMetaRegistry\n) => {\n if (!edge.sourceHandle || !edge.targetHandle) return false;\n\n const sourceNode = getNode(nodes, edge.source);\n const targetNode = getNode(nodes, edge.target);\n\n if (!sourceNode || !targetNode) return false;\n\n const sourceType = sourceNode.type;\n const targetType = targetNode.type;\n\n if (!sourceType || !targetType) return false;\n\n const inputs = nodeMetaRegistry[edge.target]?.inputs || [];\n const outputs = nodeMetaRegistry[edge.source]?.outputs || [];\n\n const source = outputs\n .map((out) => (out as HvFlowNodeOutputGroup).outputs || out)\n .flat()\n .find((out) => out.id === edge.sourceHandle);\n const target = inputs\n .map((inp) => (inp as HvFlowNodeInputGroup).inputs || inp)\n .flat()\n .find((inp) => inp.id === edge.targetHandle);\n\n const sourceProvides = source?.provides || \"\";\n const targetAccepts = target?.accepts || [];\n const sourceMaxConnections = source?.maxConnections;\n const targetMaxConnections = target?.maxConnections;\n\n let isValid =\n targetAccepts.length === 0 || targetAccepts.includes(sourceProvides);\n\n if (isValid && targetMaxConnections != null) {\n const targetConnections = edges.filter(\n (edg) =>\n edg.target === edge.target && edg.targetHandle === edge.targetHandle\n ).length;\n\n isValid = targetConnections < targetMaxConnections;\n }\n\n if (isValid && sourceMaxConnections != null) {\n const sourceConnections = edges.filter(\n (edg) =>\n edg.source === edge.source && edg.sourceHandle === edge.sourceHandle\n ).length;\n\n isValid = sourceConnections < sourceMaxConnections;\n }\n\n return isValid;\n};\n\nexport const HvDroppableFlow = ({\n id,\n className,\n children,\n onFlowChange,\n onDndDrop,\n classes: classesProp,\n nodes: initialNodes = [],\n edges: initialEdges = [],\n onConnect: onConnectProp,\n onNodesChange: onNodesChangeProp,\n onEdgesChange: onEdgesChangeProp,\n defaultEdgeOptions: defaultEdgeOptionsProp,\n ...others\n}: HvDroppableFlowProps) => {\n const { classes, cx } = useClasses(classesProp);\n\n const elementId = useUniqueId(id, \"hvFlow\");\n\n const reactFlowInstance = useReactFlow();\n\n const { nodeTypes } = useFlowContext();\n\n const [nodes, setNodes] = useState(initialNodes);\n const [edges, setEdges] = useState(initialEdges);\n\n const { setNodeRef } = useDroppable({\n id: elementId,\n });\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n if (event.over?.id !== elementId) return;\n\n const hvFlow = event.active.data.current?.hvFlow;\n const type = hvFlow?.type;\n\n // Only known node types can be dropped in the canvas\n if (!type || !nodeTypes?.[type]) {\n if (import.meta.env.DEV) {\n // eslint-disable-next-line no-console\n console.error(\n `Could not add node to the flow because of unknown type ${type}. Use nodeTypes to define all the node types.`\n );\n }\n return;\n }\n\n // Position node in the flow\n const position = reactFlowInstance.screenToFlowPosition({\n x: hvFlow?.x || 0,\n y: hvFlow?.y || 0,\n });\n\n // Node data\n const data = hvFlow?.data || {};\n\n // Node to add\n const newNode: Node = {\n id: uid(),\n position,\n data,\n type,\n };\n\n // Drop override\n if (onDndDrop) {\n onDndDrop(event, newNode);\n return;\n }\n\n setNodes((nds) => nds.concat(newNode));\n },\n [elementId, nodeTypes, onDndDrop, reactFlowInstance]\n );\n\n useDndMonitor({\n onDragEnd: handleDragEnd,\n });\n\n const handleFlowChange = useCallback(\n (\n nds: NonNullable<HvDroppableFlowProps[\"nodes\"]>,\n eds: NonNullable<HvDroppableFlowProps[\"edges\"]>\n ) => {\n // The new flow is returned if the user is not dragging nodes\n // This avoids triggering this handler too many times\n const isDragging = nds.find((node) => node.dragging);\n if (!isDragging) {\n onFlowChange?.(nds, eds);\n }\n },\n [onFlowChange]\n );\n\n const handleConnect = useCallback(\n (connection: Connection) => {\n const eds = addEdge(connection, edges);\n setEdges(eds);\n\n handleFlowChange(nodes, eds);\n onConnectProp?.(connection);\n },\n [edges, handleFlowChange, nodes, onConnectProp]\n );\n\n const handleNodesChange = useCallback(\n (changes: NodeChange[]) => {\n const nds = applyNodeChanges(changes, nodes);\n setNodes(nds);\n\n handleFlowChange(nds, edges);\n onNodesChangeProp?.(changes);\n },\n [edges, handleFlowChange, nodes, onNodesChangeProp]\n );\n\n const handleEdgesChange = useCallback(\n (changes: EdgeChange[]) => {\n const eds = applyEdgeChanges(changes, edges);\n setEdges(eds);\n\n handleFlowChange(nodes, eds);\n onEdgesChangeProp?.(changes);\n },\n [edges, handleFlowChange, nodes, onEdgesChangeProp]\n );\n\n const { registry } = useNodeMetaRegistry();\n const isValidConnection = (connection) =>\n validateEdge(nodes, edges, connection, registry);\n\n const defaultEdgeOptions = {\n markerEnd: {\n type: MarkerType.ArrowClosed,\n height: 20,\n width: 20,\n },\n type: \"smoothstep\",\n pathOptions: {\n borderRadius: 40,\n },\n ...defaultEdgeOptionsProp,\n };\n\n return (\n <>\n <Global styles={flowStyles} />\n <div\n id={elementId}\n ref={setNodeRef}\n className={cx(classes.root, className)}\n >\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onConnect={handleConnect}\n isValidConnection={isValidConnection}\n defaultEdgeOptions={defaultEdgeOptions}\n snapGrid={[1, 1]}\n snapToGrid\n onError={(code, message) => {\n if (import.meta.env.DEV) {\n // eslint-disable-next-line no-console\n console.error(message);\n }\n }}\n {...others}\n >\n {children}\n </ReactFlow>\n </div>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DroppableFlow.js","sources":["../../../src/Flow/DroppableFlow.tsx"],"sourcesContent":["import { useCallback, useState } from \"react\";\nimport ReactFlow, {\n Connection,\n EdgeChange,\n NodeChange,\n ReactFlowProps,\n addEdge,\n applyEdgeChanges,\n applyNodeChanges,\n useReactFlow,\n MarkerType,\n Edge,\n Node,\n} from \"reactflow\";\nimport { Global } from \"@emotion/react\";\nimport { DragEndEvent, useDndMonitor, useDroppable } from \"@dnd-kit/core\";\nimport { uid } from \"uid\";\nimport { ExtractNames, useUniqueId } from \"@hitachivantara/uikit-react-core\";\n\nimport {\n HvFlowNodeInputGroup,\n HvFlowNodeMetaRegistry,\n HvFlowNodeOutputGroup,\n} from \"./types\";\nimport { staticClasses, useClasses } from \"./Flow.styles\";\nimport { useFlowContext } from \"./hooks\";\nimport { flowStyles } from \"./base\";\nimport { useNodeMetaRegistry } from \"./FlowContext/NodeMetaContext\";\n\nexport { staticClasses as flowClasses };\n\nexport type HvFlowClasses = ExtractNames<typeof useClasses>;\n\nexport interface HvDroppableFlowProps<\n NodeType extends string | undefined = string | undefined,\n NodeData = any\n> extends Omit<ReactFlowProps, \"nodes\" | \"edges\" | \"nodeTypes\"> {\n /** Flow content: background, controls, and minimap. */\n children?: React.ReactNode;\n /** Flow nodes. */\n nodes?: Node<NodeData, NodeType>[];\n /** Flow edges. */\n edges?: Edge[];\n /** A Jss Object used to override or extend the styles applied to the component. */\n classes?: HvFlowClasses;\n /** Callback called when the flow changes. Returns the updated nodes and edges. */\n onFlowChange?: (nodes: Node<NodeData, NodeType>[], edges: Edge[]) => void;\n /**\n * Callback called when a node is dropped in the flow.\n *\n * This callback should be used to override the custom UI Kit drop event.\n * Thus, when defined, the user is responsible for adding nodes to the flow.\n *\n * This callback is called when `HvFlowSidebar` is used or a custom sidebar was created using Dnd Kit.\n * When a custom sidebar was created using the native HTML drag and drop API, refer to the `onDrop` callback.\n *\n * Returns the event and the node to be added to the flow.\n */\n onDndDrop?: (event: DragEndEvent, node: Node) => void;\n}\n\nexport const getNode = (nodes: Node[], nodeId: string) => {\n return nodes.find((n) => n.id === nodeId);\n};\n\nconst validateEdge = (\n nodes: Node[],\n edges: Edge[],\n connection: Connection,\n nodeMetaRegistry: HvFlowNodeMetaRegistry\n) => {\n const {\n source: sourceId,\n sourceHandle,\n target: targetId,\n targetHandle,\n } = connection;\n\n if (!sourceHandle || !targetHandle || !sourceId || !targetId) return false;\n\n const sourceNode = getNode(nodes, sourceId);\n const targetNode = getNode(nodes, targetId);\n\n if (!sourceNode || !targetNode) return false;\n\n const sourceType = sourceNode.type;\n const targetType = targetNode.type;\n\n if (!sourceType || !targetType) return false;\n\n const inputs = nodeMetaRegistry[targetId]?.inputs || [];\n const outputs = nodeMetaRegistry[sourceId]?.outputs || [];\n\n const source = outputs\n .map((out) => (out as HvFlowNodeOutputGroup).outputs || out)\n .flat()\n .find((out) => out.id === sourceHandle);\n const target = inputs\n .map((inp) => (inp as HvFlowNodeInputGroup).inputs || inp)\n .flat()\n .find((inp) => inp.id === targetHandle);\n\n const sourceProvides = source?.provides || \"\";\n const targetAccepts = target?.accepts || [];\n const sourceMaxConnections = source?.maxConnections;\n const targetMaxConnections = target?.maxConnections;\n\n let isValid =\n targetAccepts.length === 0 || targetAccepts.includes(sourceProvides);\n\n if (isValid && targetMaxConnections != null) {\n const targetConnections = edges.filter(\n (edg) => edg.target === targetId && edg.targetHandle === targetHandle\n ).length;\n\n isValid = targetConnections < targetMaxConnections;\n }\n\n if (isValid && sourceMaxConnections != null) {\n const sourceConnections = edges.filter(\n (edg) => edg.source === sourceId && edg.sourceHandle === sourceHandle\n ).length;\n\n isValid = sourceConnections < sourceMaxConnections;\n }\n\n return isValid;\n};\n\nexport const HvDroppableFlow = ({\n id,\n className,\n children,\n onFlowChange,\n onDndDrop,\n classes: classesProp,\n nodes: initialNodes = [],\n edges: initialEdges = [],\n onConnect: onConnectProp,\n onNodesChange: onNodesChangeProp,\n onEdgesChange: onEdgesChangeProp,\n defaultEdgeOptions: defaultEdgeOptionsProp,\n ...others\n}: HvDroppableFlowProps) => {\n const { classes, cx } = useClasses(classesProp);\n\n const elementId = useUniqueId(id, \"hvFlow\");\n\n const reactFlowInstance = useReactFlow();\n\n const { nodeTypes } = useFlowContext();\n\n const [nodes, setNodes] = useState(initialNodes);\n const [edges, setEdges] = useState(initialEdges);\n\n const { setNodeRef } = useDroppable({\n id: elementId,\n });\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n if (event.over?.id !== elementId) return;\n\n const hvFlow = event.active.data.current?.hvFlow;\n const type = hvFlow?.type;\n\n // Only known node types can be dropped in the canvas\n if (!type || !nodeTypes?.[type]) {\n if (import.meta.env.DEV) {\n // eslint-disable-next-line no-console\n console.error(\n `Could not add node to the flow because of unknown type ${type}. Use nodeTypes to define all the node types.`\n );\n }\n return;\n }\n\n // Position node in the flow\n const position = reactFlowInstance.screenToFlowPosition({\n x: hvFlow?.x || 0,\n y: hvFlow?.y || 0,\n });\n\n // Node data\n const data = hvFlow?.data || {};\n\n // Node to add\n const newNode: Node = {\n id: uid(),\n position,\n data,\n type,\n };\n\n // Drop override\n if (onDndDrop) {\n onDndDrop(event, newNode);\n return;\n }\n\n setNodes((nds) => nds.concat(newNode));\n },\n [elementId, nodeTypes, onDndDrop, reactFlowInstance]\n );\n\n useDndMonitor({\n onDragEnd: handleDragEnd,\n });\n\n const handleFlowChange = useCallback(\n (\n nds: NonNullable<HvDroppableFlowProps[\"nodes\"]>,\n eds: NonNullable<HvDroppableFlowProps[\"edges\"]>\n ) => {\n // The new flow is returned if the user is not dragging nodes\n // This avoids triggering this handler too many times\n const isDragging = nds.find((node) => node.dragging);\n if (!isDragging) {\n onFlowChange?.(nds, eds);\n }\n },\n [onFlowChange]\n );\n\n const handleConnect = useCallback(\n (connection: Connection) => {\n const eds = addEdge(connection, edges);\n setEdges(eds);\n\n handleFlowChange(nodes, eds);\n onConnectProp?.(connection);\n },\n [edges, handleFlowChange, nodes, onConnectProp]\n );\n\n const handleNodesChange = useCallback(\n (changes: NodeChange[]) => {\n const nds = applyNodeChanges(changes, nodes);\n setNodes(nds);\n\n handleFlowChange(nds, edges);\n onNodesChangeProp?.(changes);\n },\n [edges, handleFlowChange, nodes, onNodesChangeProp]\n );\n\n const handleEdgesChange = useCallback(\n (changes: EdgeChange[]) => {\n const eds = applyEdgeChanges(changes, edges);\n setEdges(eds);\n\n handleFlowChange(nodes, eds);\n onEdgesChangeProp?.(changes);\n },\n [edges, handleFlowChange, nodes, onEdgesChangeProp]\n );\n\n const { registry } = useNodeMetaRegistry();\n\n const isValidConnection: ReactFlowProps[\"isValidConnection\"] = (connection) =>\n validateEdge(nodes, edges, connection, registry);\n\n const defaultEdgeOptions = {\n markerEnd: {\n type: MarkerType.ArrowClosed,\n height: 20,\n width: 20,\n },\n type: \"smoothstep\",\n pathOptions: {\n borderRadius: 40,\n },\n ...defaultEdgeOptionsProp,\n };\n\n return (\n <>\n <Global styles={flowStyles} />\n <div\n id={elementId}\n ref={setNodeRef}\n className={cx(classes.root, className)}\n >\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onConnect={handleConnect}\n isValidConnection={isValidConnection}\n defaultEdgeOptions={defaultEdgeOptions}\n snapGrid={[1, 1]}\n snapToGrid\n onError={(code, message) => {\n if (import.meta.env.DEV) {\n // eslint-disable-next-line no-console\n console.error(message);\n }\n }}\n {...others}\n >\n {children}\n </ReactFlow>\n </div>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,32 +1,33 @@
1
1
  import { useCallback, useMemo } from "react";
2
2
  import { useStore, useNodes, useEdges, useNodeId, useReactFlow } from "reactflow";
3
+ import { shallow } from "zustand/shallow";
3
4
  function useFlowNode(id) {
4
5
  const nodeSelector = useCallback(
5
6
  (state) => state.getNodes().find((n) => n.id === id),
6
7
  [id]
7
8
  );
8
- return useStore(nodeSelector);
9
+ return useStore(nodeSelector, shallow);
9
10
  }
10
11
  function useFlowNodeInputEdges(id) {
11
12
  const inputEdgesSelector = useCallback(
12
13
  (state) => state.edges.filter((e) => e.target === id),
13
14
  [id]
14
15
  );
15
- return useStore(inputEdgesSelector);
16
+ return useStore(inputEdgesSelector, shallow);
16
17
  }
17
18
  function useFlowNodeOutputEdges(id) {
18
19
  const outputEdgesSelector = useCallback(
19
20
  (state) => state.edges.filter((e) => e.source === id),
20
21
  [id]
21
22
  );
22
- return useStore(outputEdgesSelector);
23
+ return useStore(outputEdgesSelector, shallow);
23
24
  }
24
25
  function useFlowNodeEdges(id) {
25
26
  const edgesSelector = useCallback(
26
27
  (state) => state.edges.filter((e) => e.source === id || e.target === id),
27
28
  [id]
28
29
  );
29
- return useStore(edgesSelector);
30
+ return useStore(edgesSelector, shallow);
30
31
  }
31
32
  function useFlowNodeParents(id) {
32
33
  const inputEdges = useFlowNodeInputEdges(id);
@@ -36,7 +37,7 @@ function useFlowNodeParents(id) {
36
37
  },
37
38
  [inputEdges]
38
39
  );
39
- return useStore(parentNodesSelector);
40
+ return useStore(parentNodesSelector, shallow);
40
41
  }
41
42
  function useFlowInputNodes(id) {
42
43
  const nodes = useNodes();
@@ -1 +1 @@
1
- {"version":3,"file":"useFlowNode.js","sources":["../../../../src/Flow/hooks/useFlowNode.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport {\n Node,\n Edge,\n ReactFlowState,\n useStore,\n useNodes,\n useEdges,\n useReactFlow,\n useNodeId,\n} from \"reactflow\";\n\nexport function useFlowNode<T extends Node = Node>(id: string) {\n const nodeSelector = useCallback(\n (state: ReactFlowState) =>\n state.getNodes().find((n: Node): n is T => n.id === id),\n [id]\n );\n return useStore<T | undefined>(nodeSelector);\n}\n\nexport function useFlowNodeInputEdges(id: string) {\n const inputEdgesSelector = useCallback(\n (state: ReactFlowState) => state.edges.filter((e: Edge) => e.target === id),\n [id]\n );\n return useStore(inputEdgesSelector);\n}\n\nexport function useFlowNodeOutputEdges(id: string) {\n const outputEdgesSelector = useCallback(\n (state: ReactFlowState) => state.edges.filter((e: Edge) => e.source === id),\n [id]\n );\n return useStore(outputEdgesSelector);\n}\n\nexport function useFlowNodeEdges(id: string) {\n const edgesSelector = useCallback(\n (state: ReactFlowState) =>\n state.edges.filter((e: Edge) => e.source === id || e.target === id),\n [id]\n );\n return useStore(edgesSelector);\n}\n\nexport function useFlowNodeParents(id: string) {\n const inputEdges = useFlowNodeInputEdges(id);\n const parentNodesSelector = useCallback(\n (state: ReactFlowState) => {\n return inputEdges\n .map((e) => state.getNodes().find((n: Node) => n.id === e.source))\n .filter((n): n is Node => n !== null);\n },\n [inputEdges]\n );\n return useStore(parentNodesSelector);\n}\n\nexport function useFlowInputNodes<T = any>(id: string) {\n const nodes = useNodes();\n const edges = useEdges();\n\n return useMemo(() => {\n return edges\n .filter((e) => e.target === id)\n .map((e) => nodes.find((n) => n.id === e.source))\n .filter((n): n is Node<T> => n !== null);\n }, [edges, id, nodes]);\n}\n\nexport function useFlowOutputNodes<T = any>(id: string) {\n const nodes = useNodes();\n const edges = useEdges();\n\n return useMemo(() => {\n return edges\n .filter((e) => e.source === id)\n .map((e) => nodes.find((n) => n.id === e.target))\n .filter((n): n is Node<T> => n !== null);\n }, [edges, id, nodes]);\n}\n\n/** Utilities to manipulate a node in the flow */\nexport function useFlowNodeUtils<NodeData = any>() {\n const nodeId = useNodeId();\n const reactFlowInstance = useReactFlow<NodeData>();\n\n /** Mutate the node's `.data` object */\n const setNodeData = useCallback(\n (setNewData: (newData?: NodeData) => NodeData) => {\n if (!nodeId) return;\n\n reactFlowInstance.setNodes((nodes) => {\n return nodes.map((n) => {\n if (n.id === nodeId) {\n return { ...n, data: setNewData(n.data) };\n }\n return n;\n });\n });\n },\n [nodeId, reactFlowInstance]\n );\n\n return useMemo(\n () => ({\n setNodeData,\n }),\n [setNodeData]\n );\n}\n"],"names":[],"mappings":";;AAYO,SAAS,YAAmC,IAAY;AAC7D,QAAM,eAAe;AAAA,IACnB,CAAC,UACC,MAAM,WAAW,KAAK,CAAC,MAAoB,EAAE,OAAO,EAAE;AAAA,IACxD,CAAC,EAAE;AAAA,EAAA;AAEL,SAAO,SAAwB,YAAY;AAC7C;AAEO,SAAS,sBAAsB,IAAY;AAChD,QAAM,qBAAqB;AAAA,IACzB,CAAC,UAA0B,MAAM,MAAM,OAAO,CAAC,MAAY,EAAE,WAAW,EAAE;AAAA,IAC1E,CAAC,EAAE;AAAA,EAAA;AAEL,SAAO,SAAS,kBAAkB;AACpC;AAEO,SAAS,uBAAuB,IAAY;AACjD,QAAM,sBAAsB;AAAA,IAC1B,CAAC,UAA0B,MAAM,MAAM,OAAO,CAAC,MAAY,EAAE,WAAW,EAAE;AAAA,IAC1E,CAAC,EAAE;AAAA,EAAA;AAEL,SAAO,SAAS,mBAAmB;AACrC;AAEO,SAAS,iBAAiB,IAAY;AAC3C,QAAM,gBAAgB;AAAA,IACpB,CAAC,UACC,MAAM,MAAM,OAAO,CAAC,MAAY,EAAE,WAAW,MAAM,EAAE,WAAW,EAAE;AAAA,IACpE,CAAC,EAAE;AAAA,EAAA;AAEL,SAAO,SAAS,aAAa;AAC/B;AAEO,SAAS,mBAAmB,IAAY;AACvC,QAAA,aAAa,sBAAsB,EAAE;AAC3C,QAAM,sBAAsB;AAAA,IAC1B,CAAC,UAA0B;AAClB,aAAA,WACJ,IAAI,CAAC,MAAM,MAAM,SAAS,EAAE,KAAK,CAAC,MAAY,EAAE,OAAO,EAAE,MAAM,CAAC,EAChE,OAAO,CAAC,MAAiB,MAAM,IAAI;AAAA,IACxC;AAAA,IACA,CAAC,UAAU;AAAA,EAAA;AAEb,SAAO,SAAS,mBAAmB;AACrC;AAEO,SAAS,kBAA2B,IAAY;AACrD,QAAM,QAAQ;AACd,QAAM,QAAQ;AAEd,SAAO,QAAQ,MAAM;AACZ,WAAA,MACJ,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,EAC7B,IAAI,CAAC,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAC/C,OAAO,CAAC,MAAoB,MAAM,IAAI;AAAA,EACxC,GAAA,CAAC,OAAO,IAAI,KAAK,CAAC;AACvB;AAEO,SAAS,mBAA4B,IAAY;AACtD,QAAM,QAAQ;AACd,QAAM,QAAQ;AAEd,SAAO,QAAQ,MAAM;AACZ,WAAA,MACJ,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,EAC7B,IAAI,CAAC,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAC/C,OAAO,CAAC,MAAoB,MAAM,IAAI;AAAA,EACxC,GAAA,CAAC,OAAO,IAAI,KAAK,CAAC;AACvB;AAGO,SAAS,mBAAmC;AACjD,QAAM,SAAS;AACf,QAAM,oBAAoB;AAG1B,QAAM,cAAc;AAAA,IAClB,CAAC,eAAiD;AAChD,UAAI,CAAC;AAAQ;AAEK,wBAAA,SAAS,CAAC,UAAU;AAC7B,eAAA,MAAM,IAAI,CAAC,MAAM;AAClB,cAAA,EAAE,OAAO,QAAQ;AACnB,mBAAO,EAAE,GAAG,GAAG,MAAM,WAAW,EAAE,IAAI;UACxC;AACO,iBAAA;AAAA,QAAA,CACR;AAAA,MAAA,CACF;AAAA,IACH;AAAA,IACA,CAAC,QAAQ,iBAAiB;AAAA,EAAA;AAGrB,SAAA;AAAA,IACL,OAAO;AAAA,MACL;AAAA,IAAA;AAAA,IAEF,CAAC,WAAW;AAAA,EAAA;AAEhB;"}
1
+ {"version":3,"file":"useFlowNode.js","sources":["../../../../src/Flow/hooks/useFlowNode.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport {\n Node,\n Edge,\n ReactFlowState,\n useStore,\n useNodes,\n useEdges,\n useReactFlow,\n useNodeId,\n} from \"reactflow\";\nimport { shallow } from \"zustand/shallow\";\n\nexport function useFlowNode<T extends Node = Node>(id: string) {\n const nodeSelector = useCallback(\n (state: ReactFlowState) =>\n state.getNodes().find((n: Node): n is T => n.id === id),\n [id]\n );\n return useStore<T | undefined>(nodeSelector, shallow);\n}\n\nexport function useFlowNodeInputEdges(id: string) {\n const inputEdgesSelector = useCallback(\n (state: ReactFlowState) => state.edges.filter((e: Edge) => e.target === id),\n [id]\n );\n return useStore(inputEdgesSelector, shallow);\n}\n\nexport function useFlowNodeOutputEdges(id: string) {\n const outputEdgesSelector = useCallback(\n (state: ReactFlowState) => state.edges.filter((e: Edge) => e.source === id),\n [id]\n );\n return useStore(outputEdgesSelector, shallow);\n}\n\nexport function useFlowNodeEdges(id: string) {\n const edgesSelector = useCallback(\n (state: ReactFlowState) =>\n state.edges.filter((e: Edge) => e.source === id || e.target === id),\n [id]\n );\n return useStore(edgesSelector, shallow);\n}\n\nexport function useFlowNodeParents(id: string) {\n const inputEdges = useFlowNodeInputEdges(id);\n const parentNodesSelector = useCallback(\n (state: ReactFlowState) => {\n return inputEdges\n .map((e) => state.getNodes().find((n: Node) => n.id === e.source))\n .filter((n): n is Node => n !== null);\n },\n [inputEdges]\n );\n return useStore(parentNodesSelector, shallow);\n}\n\nexport function useFlowInputNodes<T = any>(id: string) {\n const nodes = useNodes();\n const edges = useEdges();\n\n return useMemo(() => {\n return edges\n .filter((e) => e.target === id)\n .map((e) => nodes.find((n) => n.id === e.source))\n .filter((n): n is Node<T> => n !== null);\n }, [edges, id, nodes]);\n}\n\nexport function useFlowOutputNodes<T = any>(id: string) {\n const nodes = useNodes();\n const edges = useEdges();\n\n return useMemo(() => {\n return edges\n .filter((e) => e.source === id)\n .map((e) => nodes.find((n) => n.id === e.target))\n .filter((n): n is Node<T> => n !== null);\n }, [edges, id, nodes]);\n}\n\n/** Utilities to manipulate a node in the flow */\nexport function useFlowNodeUtils<NodeData = any>() {\n const nodeId = useNodeId();\n const reactFlowInstance = useReactFlow<NodeData>();\n\n /** Mutate the node's `.data` object */\n const setNodeData = useCallback(\n (setNewData: (newData?: NodeData) => NodeData) => {\n if (!nodeId) return;\n\n reactFlowInstance.setNodes((nodes) => {\n return nodes.map((n) => {\n if (n.id === nodeId) {\n return { ...n, data: setNewData(n.data) };\n }\n return n;\n });\n });\n },\n [nodeId, reactFlowInstance]\n );\n\n return useMemo(\n () => ({\n setNodeData,\n }),\n [setNodeData]\n );\n}\n"],"names":[],"mappings":";;;AAaO,SAAS,YAAmC,IAAY;AAC7D,QAAM,eAAe;AAAA,IACnB,CAAC,UACC,MAAM,WAAW,KAAK,CAAC,MAAoB,EAAE,OAAO,EAAE;AAAA,IACxD,CAAC,EAAE;AAAA,EAAA;AAEE,SAAA,SAAwB,cAAc,OAAO;AACtD;AAEO,SAAS,sBAAsB,IAAY;AAChD,QAAM,qBAAqB;AAAA,IACzB,CAAC,UAA0B,MAAM,MAAM,OAAO,CAAC,MAAY,EAAE,WAAW,EAAE;AAAA,IAC1E,CAAC,EAAE;AAAA,EAAA;AAEE,SAAA,SAAS,oBAAoB,OAAO;AAC7C;AAEO,SAAS,uBAAuB,IAAY;AACjD,QAAM,sBAAsB;AAAA,IAC1B,CAAC,UAA0B,MAAM,MAAM,OAAO,CAAC,MAAY,EAAE,WAAW,EAAE;AAAA,IAC1E,CAAC,EAAE;AAAA,EAAA;AAEE,SAAA,SAAS,qBAAqB,OAAO;AAC9C;AAEO,SAAS,iBAAiB,IAAY;AAC3C,QAAM,gBAAgB;AAAA,IACpB,CAAC,UACC,MAAM,MAAM,OAAO,CAAC,MAAY,EAAE,WAAW,MAAM,EAAE,WAAW,EAAE;AAAA,IACpE,CAAC,EAAE;AAAA,EAAA;AAEE,SAAA,SAAS,eAAe,OAAO;AACxC;AAEO,SAAS,mBAAmB,IAAY;AACvC,QAAA,aAAa,sBAAsB,EAAE;AAC3C,QAAM,sBAAsB;AAAA,IAC1B,CAAC,UAA0B;AAClB,aAAA,WACJ,IAAI,CAAC,MAAM,MAAM,SAAS,EAAE,KAAK,CAAC,MAAY,EAAE,OAAO,EAAE,MAAM,CAAC,EAChE,OAAO,CAAC,MAAiB,MAAM,IAAI;AAAA,IACxC;AAAA,IACA,CAAC,UAAU;AAAA,EAAA;AAEN,SAAA,SAAS,qBAAqB,OAAO;AAC9C;AAEO,SAAS,kBAA2B,IAAY;AACrD,QAAM,QAAQ;AACd,QAAM,QAAQ;AAEd,SAAO,QAAQ,MAAM;AACZ,WAAA,MACJ,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,EAC7B,IAAI,CAAC,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAC/C,OAAO,CAAC,MAAoB,MAAM,IAAI;AAAA,EACxC,GAAA,CAAC,OAAO,IAAI,KAAK,CAAC;AACvB;AAEO,SAAS,mBAA4B,IAAY;AACtD,QAAM,QAAQ;AACd,QAAM,QAAQ;AAEd,SAAO,QAAQ,MAAM;AACZ,WAAA,MACJ,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,EAC7B,IAAI,CAAC,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAC/C,OAAO,CAAC,MAAoB,MAAM,IAAI;AAAA,EACxC,GAAA,CAAC,OAAO,IAAI,KAAK,CAAC;AACvB;AAGO,SAAS,mBAAmC;AACjD,QAAM,SAAS;AACf,QAAM,oBAAoB;AAG1B,QAAM,cAAc;AAAA,IAClB,CAAC,eAAiD;AAChD,UAAI,CAAC;AAAQ;AAEK,wBAAA,SAAS,CAAC,UAAU;AAC7B,eAAA,MAAM,IAAI,CAAC,MAAM;AAClB,cAAA,EAAE,OAAO,QAAQ;AACnB,mBAAO,EAAE,GAAG,GAAG,MAAM,WAAW,EAAE,IAAI;UACxC;AACO,iBAAA;AAAA,QAAA,CACR;AAAA,MAAA,CACF;AAAA,IACH;AAAA,IACA,CAAC,QAAQ,iBAAiB;AAAA,EAAA;AAGrB,SAAA;AAAA,IACL,OAAO;AAAA,MACL;AAAA,IAAA;AAAA,IAEF,CAAC,WAAW;AAAA,EAAA;AAEhB;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hitachivantara/uikit-react-lab",
3
- "version": "5.26.2",
3
+ "version": "5.26.3",
4
4
  "private": false,
5
5
  "author": "Hitachi Vantara UI Kit Team",
6
6
  "description": "Contributed React components for the NEXT UI Kit.",
@@ -32,7 +32,7 @@
32
32
  "@dnd-kit/core": "^6.1.0",
33
33
  "@dnd-kit/modifiers": "^6.0.1",
34
34
  "@emotion/css": "^11.11.0",
35
- "@hitachivantara/uikit-react-core": "^5.45.0",
35
+ "@hitachivantara/uikit-react-core": "^5.46.0",
36
36
  "@hitachivantara/uikit-react-icons": "^5.8.2",
37
37
  "@hitachivantara/uikit-styles": "^5.18.0",
38
38
  "@types/react-grid-layout": "^1.3.5",
@@ -50,7 +50,7 @@
50
50
  "access": "public",
51
51
  "directory": "package"
52
52
  },
53
- "gitHead": "8b3bfd1137cc8650dcd801f4910d0bdd285a0c3c",
53
+ "gitHead": "a2562049d702de7c20373efd6785fb8f84e9a20a",
54
54
  "main": "dist/cjs/index.cjs",
55
55
  "exports": {
56
56
  ".": {