From 9c78c2c758abc5fa92461ce9dda099fbcf69cdec Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 1 Apr 2025 21:10:58 +0200 Subject: [PATCH 1/4] fix: improve TSDoc comments for `HandleProps`, `NodeBase` and `InternalNodeBase` --- packages/system/src/types/handles.ts | 32 ++++++++++++++++------- packages/system/src/types/nodes.ts | 38 ++++++++++++++++++---------- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/packages/system/src/types/handles.ts b/packages/system/src/types/handles.ts index ef67d373..a8b51aa3 100644 --- a/packages/system/src/types/handles.ts +++ b/packages/system/src/types/handles.ts @@ -15,29 +15,43 @@ export type Handle = { export type HandleProps = { /** - * Type of the handle + * Type of the handle. + * @default "source" * @example HandleType.Source, HandleType.Target */ type: HandleType; /** - * Position of the handle - * @example Position.TopLeft, Position.TopRight, - * Position.BottomLeft, Position.BottomRight + * The position of the handle relative to the node. In a horizontal flow source handles are + * typically `Position.Right` and in a vertical flow they are typically `Position.Top`. + * @default Position.Top + * @example Position.TopLeft, Position.TopRight, Position.BottomLeft, Position.BottomRight */ position: Position; - /** Should you be able to connect to/from this handle */ + /** + * Should you be able to connect to/from this handle. + * @default true + */ isConnectable?: boolean; - /** Should you be able to connect from this handle */ + /** + * Dictates whether a connection can start from this handle. + * @default true + */ isConnectableStart?: boolean; - /** Should you be able to connect to this handle */ + /** + * Dictates whether a connection can end on this handle. + * @default true + */ isConnectableEnd?: boolean; /** - * Callback if connection is valid + * Called when a connection is dragged to this handle. You can use this callback to perform some + * custom validation logic based on the connection target and source, for example. Where possible, + * we recommend you move this logic to the `isValidConnection` prop on the main ReactFlow + * component for performance reasons. * @remarks connection becomes an edge if isValidConnection returns true */ isValidConnection?: IsValidConnection; /** - * Id of the handle + * Id of the handle. * @remarks optional if there is only one handle of this type */ id?: string | null; diff --git a/packages/system/src/types/nodes.ts b/packages/system/src/types/nodes.ts index 68dd0ce3..b32d58c5 100644 --- a/packages/system/src/types/nodes.ts +++ b/packages/system/src/types/nodes.ts @@ -12,52 +12,62 @@ export type NodeBase< NodeData extends Record = Record, NodeType extends string = string > = { - /** Unique id of a node */ + /** Unique id of a node. */ id: string; /** - * Position of a node on the pane + * Position of a node on the pane. * @example { x: 0, y: 0 } */ position: XYPosition; - /** Arbitrary data passed to a node */ + /** Arbitrary data passed to a node. */ data: NodeData; - /** Type of node defined in nodeTypes */ + /** Type of node defined in `nodeTypes`. */ type?: NodeType; /** - * Only relevant for default, source, target nodeType. controls source position + * Only relevant for default, source, target nodeType. Controls source position. * @example 'right', 'left', 'top', 'bottom' */ sourcePosition?: Position; /** - * Only relevant for default, source, target nodeType. controls target position + * Only relevant for default, source, target nodeType. Controls target position. * @example 'right', 'left', 'top', 'bottom' */ targetPosition?: Position; + /** Whether or not the node should be visible on the canvas. */ hidden?: boolean; selected?: boolean; - /** True, if node is being dragged */ + /** Whether or not the node is currently being dragged. */ dragging?: boolean; + /** Whether or not the node is able to be dragged. */ draggable?: boolean; selectable?: boolean; connectable?: boolean; deletable?: boolean; + /** + * A class name that can be applied to elements inside the node that allows those elements to act + * as drag handles, letting the user drag the node by clicking and dragging on those elements. + */ dragHandle?: string; width?: number; height?: number; initialWidth?: number; initialHeight?: number; - /** Parent node id, used for creating sub-flows */ + /** Parent node id, used for creating sub-flows. */ parentId?: string; zIndex?: number; /** - * Boundary a node can be moved in + * Boundary a node can be moved in. * @example 'parent' or [[0, 0], [100, 100]] */ extent?: 'parent' | CoordinateExtent; + /** + * When `true`, the parent node will automatically expand if this node is dragged to the edge of + * the parent node's bounds. + */ expandParent?: boolean; ariaLabel?: string; /** - * Origin of the node relative to it's position + * Origin of the node relative to its position. * @example * [0.5, 0.5] // centers the node * [0, 0] // top left @@ -71,7 +81,7 @@ export type NodeBase< }; }; -export type InternalNodeBase = NodeType & { +export type InternalNodeBase = Omit & { measured: { width?: number; height?: number; @@ -99,11 +109,11 @@ export type NodeProps = Pick< 'id' | 'data' | 'width' | 'height' | 'sourcePosition' | 'targetPosition' | 'dragHandle' | 'parentId' > & Required> & { - /** whether a node is connectable or not */ + /** Whether a node is connectable or not. */ isConnectable: boolean; - /** position absolute x value */ + /** Position absolute x value. */ positionAbsoluteX: number; - /** position absolute x value */ + /** Position absolute y value. */ positionAbsoluteY: number; }; From 24a1bc89348817ed9b5c87f74bf2519c705143be Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 1 Apr 2025 21:11:17 +0200 Subject: [PATCH 2/4] changeset --- .changeset/hungry-coins-sparkle.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/hungry-coins-sparkle.md diff --git a/.changeset/hungry-coins-sparkle.md b/.changeset/hungry-coins-sparkle.md new file mode 100644 index 00000000..a60ead63 --- /dev/null +++ b/.changeset/hungry-coins-sparkle.md @@ -0,0 +1,5 @@ +--- +'@xyflow/system': patch +--- + +fix: improve TSDoc comments for `HandleProps`, `NodeBase` and `InternalNodeBase` From 5c66916370dc66f2e42c8488e37a7bc2b95cf9f3 Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 2 Apr 2025 13:41:08 +0200 Subject: [PATCH 3/4] fix(minimap): return usernode --- packages/react/src/additional-components/MiniMap/MiniMap.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/additional-components/MiniMap/MiniMap.tsx b/packages/react/src/additional-components/MiniMap/MiniMap.tsx index ad899043..bad28242 100644 --- a/packages/react/src/additional-components/MiniMap/MiniMap.tsx +++ b/packages/react/src/additional-components/MiniMap/MiniMap.tsx @@ -125,7 +125,7 @@ function MiniMapComponent({ const onSvgNodeClick = onNodeClick ? useCallback((event: MouseEvent, nodeId: string) => { - const node = store.getState().nodeLookup.get(nodeId)!; + const node: NodeType = store.getState().nodeLookup.get(nodeId)!.internals.userNode; onNodeClick(event, node); }, []) : undefined; From 0f293eebae4019a0501a9747ba5dea61a8a413fc Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 2 Apr 2025 13:53:32 +0200 Subject: [PATCH 4/4] fix(minimap): return usernode --- .../src/additional-components/MiniMap/MiniMapNodes.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/react/src/additional-components/MiniMap/MiniMapNodes.tsx b/packages/react/src/additional-components/MiniMap/MiniMapNodes.tsx index 2c314289..e96dd9f6 100644 --- a/packages/react/src/additional-components/MiniMap/MiniMapNodes.tsx +++ b/packages/react/src/additional-components/MiniMap/MiniMapNodes.tsx @@ -6,7 +6,7 @@ import { shallow } from 'zustand/shallow'; import { useStore } from '../../hooks/useStore'; import { MiniMapNode } from './MiniMapNode'; -import type { ReactFlowState, Node, InternalNode } from '../../types'; +import type { ReactFlowState, Node } from '../../types'; import type { MiniMapNodes as MiniMapNodesProps, GetMiniMapNodeAttribute, MiniMapNodeProps } from './types'; declare const window: any; @@ -42,7 +42,7 @@ function MiniMapNodes({ * The split of responsibilities between MiniMapNodes and * NodeComponentWrapper may appear weird. However, it’s designed to * minimize the cost of updates when individual nodes change. - * + * * For more details, see a similar commit in `NodeRenderer/index.tsx`. */ @@ -84,8 +84,9 @@ function NodeComponentWrapperInner({ shapeRendering: string; }) { const { node, x, y, width, height } = useStore((s) => { - const node = s.nodeLookup.get(id) as InternalNode; - const { x, y } = node.internals.positionAbsolute; + const { internals } = s.nodeLookup.get(id)!; + const node = internals.userNode as NodeType; + const { x, y } = internals.positionAbsolute; const { width, height } = getNodeDimensions(node); return {