Merge branch 'next' into fix-selection-key

This commit is contained in:
moklick
2024-01-23 10:06:40 +01:00
29 changed files with 214 additions and 151 deletions
+2 -1
View File
@@ -10,9 +10,10 @@ import {
Edge,
useReactFlow,
Panel,
OnNodeDrag,
} from '@xyflow/react';
const onNodeDrag = (_: MouseEvent, node: Node) => console.log('drag', node);
const onNodeDrag: OnNodeDrag = (_, node) => console.log('drag', node);
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
@@ -1,6 +1,8 @@
import React, { memo, FC, CSSProperties, useCallback, useEffect } from 'react';
import React, { memo, FC, CSSProperties, useCallback } from 'react';
import { Handle, Position, NodeProps, Connection, Edge, useOnViewportChange, Viewport } from '@xyflow/react';
import type { ColorSelectorNode } from '.';
const targetHandleStyle: CSSProperties = { background: '#555' };
const sourceHandleStyleA: CSSProperties = { ...targetHandleStyle, top: 10 };
const sourceHandleStyleB: CSSProperties = {
@@ -11,7 +13,7 @@ const sourceHandleStyleB: CSSProperties = {
const onConnect = (params: Connection | Edge) => console.log('handle onConnect', params);
const ColorSelectorNode: FC<NodeProps> = ({ data, isConnectable }) => {
const ColorSelectorNode: FC<NodeProps<ColorSelectorNode['data']>> = ({ data, isConnectable }) => {
const onStart = useCallback((viewport: Viewport) => console.log('onStart', viewport), []);
const onChange = useCallback((viewport: Viewport) => console.log('onChange', viewport), []);
const onEnd = useCallback((viewport: Viewport) => console.log('onEnd', viewport), []);
@@ -5,24 +5,32 @@ import {
Controls,
addEdge,
Node,
ReactFlowInstance,
Position,
SnapGrid,
Connection,
useNodesState,
useEdgesState,
Background,
Edge,
OnNodeDrag,
OnInit,
applyNodeChanges,
OnNodesChange,
OnConnect,
} from '@xyflow/react';
import ColorSelectorNode from './ColorSelectorNode';
const onInit = (reactFlowInstance: ReactFlowInstance) => {
export type ColorSelectorNode = Node<
{ color: string; onChange: (event: ChangeEvent<HTMLInputElement>) => void },
'selectorNode'
>;
export type MyNode = Node | ColorSelectorNode;
const onInit: OnInit<MyNode> = (reactFlowInstance) => {
console.log('flow loaded:', reactFlowInstance);
};
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
const onNodeDragStop: OnNodeDrag<MyNode> = (_, node) => console.log('drag stop', node);
const onNodeClick = (_: MouseEvent, node: MyNode) => console.log('click', node);
const initBgColor = '#1A192B';
@@ -34,7 +42,16 @@ const nodeTypes = {
};
const CustomNodeFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState<Node>([]);
const [nodes, setNodes] = useState<MyNode[]>([]);
const onNodesChange: OnNodesChange = useCallback(
(changes) =>
setNodes((nds) => {
const nextNodes = applyNodeChanges(changes, nds);
return nextNodes;
}),
[setNodes]
);
const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>([]);
const [bgColor, setBgColor] = useState<string>(initBgColor);
@@ -120,9 +137,8 @@ const CustomNodeFlow = () => {
]);
}, []);
const onConnect = useCallback(
(connection: Connection) =>
setEdges((eds) => addEdge({ ...connection, animated: true, style: { stroke: '#fff' } }, eds)),
const onConnect: OnConnect = useCallback(
(connection) => setEdges((eds) => addEdge({ ...connection, animated: true, style: { stroke: '#fff' } }, eds)),
[setEdges]
);
@@ -145,14 +161,14 @@ const CustomNodeFlow = () => {
maxZoom={2}
>
<MiniMap
nodeStrokeColor={(n: Node): string => {
nodeStrokeColor={(n: MyNode): string => {
if (n.type === 'input') return '#0041d0';
if (n.type === 'selectorNode') return bgColor;
if (n.type === 'output') return '#ff0072';
return '#eee';
}}
nodeColor={(n: Node): string => {
nodeColor={(n: MyNode): string => {
if (n.type === 'selectorNode') return bgColor;
return '#fff';
@@ -43,10 +43,8 @@
export let zIndex: $$Props['zIndex'] = undefined;
export let dragging: $$Props['dragging'] = false;
export let dragHandle: $$Props['dragHandle'] = undefined;
export let positionAbsolute: $$Props['positionAbsolute'] = {
x: 0,
y: 0
};
export let positionAbsoluteX: $$Props['positionAbsoluteX'] = 0;
export let positionAbsoluteY: $$Props['positionAbsoluteY'] = 0;
export let isConnectable: $$Props['isConnectable'] = undefined;
data;
@@ -59,7 +57,8 @@
zIndex;
dragging;
dragHandle;
positionAbsolute;
positionAbsoluteX;
positionAbsoluteY;
isConnectable;
</script>
+12 -3
View File
@@ -1,19 +1,28 @@
# @xyflow/react
## 12.0.0-next.8
### Patch changes
- fix `OnNodeDrag` type
## 12.0.0-next.7
## Minor changes
- pass Node/Edge types to changes thanks @FelipeEmos
- use position instead of positionAbsolute for `getNodesBounds`
- add second option param to `screenToFlowPosition` for configuring if `snapToGrid` should be used
### Patch changes
- pass `Node`/ `Edge` types to changes thanks @FelipeEmos
- use position instead of positionAbsolute for `getNodesBounds`
- infer types for `getIncomers`, `getOutgoers`, `updateEdge`, `addEdge` and `getConnectedEdges` thanks @joeyballentine
- refactor handles: prefix with flow id for handling nested flows
- add comments for types like `ReactFlowProps` or `Node` for a better developer experience
## 12.0.0-next.6
### Minor changes
### Patch changes
- fix `deleteElements`
- refactor internal `applyChanges`
@@ -186,6 +186,7 @@ export function EdgeWrapper({
animated: edge.animated,
inactive: !isSelectable && !onClick,
updating: updateHover,
selectable: isSelectable,
},
])}
onClick={onEdgeClick}
-1
View File
@@ -67,7 +67,6 @@ export {
type OnError,
type NodeProps,
type NodeOrigin,
type OnNodeDrag,
type OnSelectionDrag,
Position,
type XYPosition,
-18
View File
@@ -1,21 +1,3 @@
/* this will be exported as base.css and can be used for a basic styling */
@import '../../../system/src/styles/init.css';
@import '../../../system/src/styles/base.css';
.react-flow {
--edge-label-background-color-default: #ffffff;
--edge-label-color-default: inherit;
}
.react-flow.dark {
--edge-label-background-color-default: #141414;
--edge-label-color-default: #f8f8f8;
}
.react-flow__edge-textbg {
fill: var(--edge-label-background-color, var(--edge-label-background-color-default));
}
.react-flow__edge-text {
fill: var(--edge-label-color, var(--edge-label-color-default));
}
+2 -12
View File
@@ -3,20 +3,10 @@
@import '../../../system/src/styles/style.css';
@import '../../../system/src/styles/node-resizer.css';
.react-flow {
--edge-label-background-color-default: #ffffff;
--edge-label-color-default: inherit;
}
.react-flow.dark {
--edge-label-background-color-default: #141414;
--edge-label-color-default: #f8f8f8;
}
.react-flow__edge-textbg {
fill: var(--edge-label-background-color, var(--edge-label-background-color-default));
fill: var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default));
}
.react-flow__edge-text {
fill: var(--edge-label-color, var(--edge-label-color-default));
fill: var(--xy-edge-label-color, var(--xy-edge-label-color-default));
}
+4 -4
View File
@@ -40,10 +40,10 @@ import type {
OnDelete,
OnNodesChange,
OnEdgesChange,
NodeDragHandler,
NodeMouseHandler,
SelectionDragHandler,
EdgeMouseHandler,
OnNodeDrag,
} from '.';
/**
@@ -111,11 +111,11 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
/** This event handler is called when a user right clicks on a node */
onNodeContextMenu?: NodeMouseHandler;
/** This event handler is called when a user starts to drag a node */
onNodeDragStart?: NodeDragHandler;
onNodeDragStart?: OnNodeDrag;
/** This event handler is called when a user drags a node */
onNodeDrag?: NodeDragHandler;
onNodeDrag?: OnNodeDrag;
/** This event handler is called when a user stops dragging a node */
onNodeDragStop?: NodeDragHandler;
onNodeDragStop?: OnNodeDrag;
/** This event handler is called when a user clicks on an edge */
onEdgeClick?: (event: ReactMouseEvent, edge: Edge) => void;
/** This event handler is called when a user right clicks on an edge */
+1 -1
View File
@@ -19,7 +19,7 @@ import { ComponentType } from 'react';
export type OnNodesChange<NodeType extends Node = Node> = (changes: NodeChange<NodeType>[]) => void;
export type OnEdgesChange<EdgeType extends Edge = Edge> = (changes: EdgeChange<EdgeType>[]) => void;
export type OnNodesDelete = (nodes: Node[]) => void;
export type OnNodesDelete<NodeType extends Node = Node> = (nodes: NodeType[]) => void;
export type OnEdgesDelete = (edges: Edge[]) => void;
export type OnDelete = (params: { nodes: Node[]; edges: Edge[] }) => void;
+8 -4
View File
@@ -3,11 +3,11 @@ import type { CoordinateExtent, NodeBase, NodeOrigin, OnError } from '@xyflow/sy
import { NodeTypes } from './general';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
/**
* The node data structure that gets used for the nodes prop.
* @public
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Node<NodeData = any, NodeType extends string | undefined = string | undefined> = NodeBase<
NodeData,
NodeType
@@ -18,9 +18,13 @@ export type Node<NodeData = any, NodeType extends string | undefined = string |
focusable?: boolean;
};
export type NodeMouseHandler = (event: ReactMouseEvent, node: Node) => void;
export type NodeDragHandler = (event: ReactMouseEvent, node: Node, nodes: Node[]) => void;
export type SelectionDragHandler = (event: ReactMouseEvent, nodes: Node[]) => void;
export type NodeMouseHandler<NodeType extends Node = Node> = (event: ReactMouseEvent, node: NodeType) => void;
export type SelectionDragHandler<NodeType extends Node = Node> = (event: ReactMouseEvent, nodes: NodeType[]) => void;
export type OnNodeDrag<NodeType extends Node = Node> = (
event: ReactMouseEvent,
node: NodeType,
nodes: NodeType[]
) => void;
export type NodeWrapperProps = {
id: string;
+1 -1
View File
@@ -17,7 +17,6 @@ import {
type PanBy,
type OnConnectStart,
type OnConnectEnd,
type OnNodeDrag,
type OnSelectionDrag,
type OnMoveStart,
type OnMove,
@@ -43,6 +42,7 @@ import type {
OnSelectionChangeFunc,
UnselectNodesAndEdgesParams,
OnDelete,
OnNodeDrag,
} from '.';
export type ReactFlowStore = {
+14 -1
View File
@@ -1,11 +1,24 @@
# @xyflow/svelte
## 0.0.35
## Minor changes
- add `getNode`, `getNodes`, `getEdge` and `getEdges` to `useSvelteFlow`
## Patch changes
- Edge label has a default background and is clickable
## 0.0.34
## Minor changes
- add second option param to `screenToFlowPosition` for configuring if `snapToGrid` should be used
- add slot to `Controls`
## Patch changes
- cleanup `ControlButton` types
- infer types for `getIncomers`, `getOutgoers`, `updateEdge`, `addEdge` and `getConnectedEdges` thanks @joeyballentine
- refactor handles: prefix with flow id for handling nested flows
@@ -42,7 +55,7 @@
- add `onbeforedelete` handler to prevent/ manage deletions
- TSDocs for hooks and some types
### Minor changes
### Patch changes
- new nodeDragThreshold default is 1
- refactor/simplify edge rendering
@@ -1,7 +1,7 @@
<script lang="ts">
import cc from 'classcat';
import { EdgeLabelRenderer } from '$lib/components/EdgeLabelRenderer';
import type { BaseEdgeProps } from './types';
import EdgeLabel from '../EdgeLabel/EdgeLabel.svelte';
type $$Props = BaseEdgeProps;
@@ -18,7 +18,6 @@
let className: $$Props['class'] = undefined;
export { className as class };
// @todo, why is interactionWidth undefined after first re-render?
let interactionWidthValue = interactionWidth === undefined ? 20 : interactionWidth;
</script>
@@ -43,13 +42,7 @@
{/if}
{#if label}
<EdgeLabelRenderer>
<div
class="svelte-flow__edge-label"
style:transform="translate(-50%, -50%) translate({labelX}px,{labelY}px)"
style={labelStyle}
>
{label}
</div>
</EdgeLabelRenderer>
<EdgeLabel x={labelX} y={labelY} style={labelStyle}>
{label}
</EdgeLabel>
{/if}
@@ -0,0 +1,28 @@
<script lang="ts">
import { getContext } from 'svelte';
import { EdgeLabelRenderer } from '$lib/components/EdgeLabelRenderer';
import { useHandleEdgeSelect } from '$lib/hooks/useHandleEdgeSelect';
import type { BaseEdgeProps } from '$lib/components/BaseEdge/types';
export let style: BaseEdgeProps['labelStyle'] = undefined;
export let x: BaseEdgeProps['labelX'] = undefined;
export let y: BaseEdgeProps['labelY'] = undefined;
const handleEdgeSelect = useHandleEdgeSelect();
const id = getContext<string>('svelteflow__edge_id');
</script>
<EdgeLabelRenderer>
<div
class="svelte-flow__edge-label"
style:transform="translate(-50%, -50%) translate({x}px,{y}px)"
style={'pointer-events: all;' + style}
on:click={() => {
if (id) handleEdgeSelect(id);
}}
>
<slot />
</div>
</EdgeLabelRenderer>
@@ -0,0 +1 @@
export { default as EdgeLabel } from './EdgeLabel.svelte';
@@ -1,14 +1,14 @@
<svelte:options immutable />
<script lang="ts">
import { createEventDispatcher, setContext } from 'svelte';
import cc from 'classcat';
import { createEventDispatcher } from 'svelte';
import { errorMessages, getMarkerId } from '@xyflow/system';
import { getMarkerId } from '@xyflow/system';
import { useStore } from '$lib/store';
import { BezierEdgeInternal } from '$lib/components/edges';
import type { EdgeLayouted, Edge } from '$lib/types';
import { get } from 'svelte/store';
import { useHandleEdgeSelect } from '$lib/hooks/useHandleEdgeSelect';
type $$Props = EdgeLayouted;
@@ -22,7 +22,6 @@
export let animated: $$Props['animated'] = false;
export let selected: $$Props['selected'] = false;
export let selectable: $$Props['selectable'] = true;
export let hidden: $$Props['hidden'] = false;
export let label: $$Props['label'] = undefined;
export let labelStyle: $$Props['labelStyle'] = undefined;
@@ -43,16 +42,9 @@
let className: string = '';
export { className as class };
const {
edges,
edgeTypes,
flowId,
selectionRect,
selectionRectMode,
multiselectionKeyPressed,
addSelectedEdges,
unselectNodesAndEdges
} = useStore();
setContext('svelteflow__edge_id', id);
const { edgeLookup, edgeTypes, flowId } = useStore();
const dispatch = createEventDispatcher<{
edgeclick: { edge: Edge; event: MouseEvent | TouchEvent };
edgecontextmenu: { edge: Edge; event: MouseEvent };
@@ -62,30 +54,19 @@
$: markerStartUrl = markerStart ? `url(#${getMarkerId(markerStart, $flowId)})` : undefined;
$: markerEndUrl = markerEnd ? `url(#${getMarkerId(markerEnd, $flowId)})` : undefined;
const handleEdgeSelect = useHandleEdgeSelect();
function onClick(event: MouseEvent | TouchEvent) {
const edge = $edges.find((e) => e.id === id);
const edge = $edgeLookup.get(id);
if (!edge) {
console.warn('012', errorMessages['error012'](id));
return;
if (edge) {
handleEdgeSelect(id);
dispatch('edgeclick', { event, edge });
}
if (selectable) {
selectionRect.set(null);
selectionRectMode.set(null);
if (!edge.selected) {
addSelectedEdges([id]);
} else if (edge.selected && get(multiselectionKeyPressed)) {
unselectNodesAndEdges({ nodes: [], edges: [edge] });
}
}
dispatch('edgeclick', { event, edge });
}
function onContextMenu(event: MouseEvent) {
const edge = $edges.find((e) => e.id === id);
const edge = $edgeLookup.get(id);
if (edge) {
dispatch('edgecontextmenu', { event, edge });
@@ -24,12 +24,6 @@
</svg>
{#each $visibleEdges as edge (edge.id)}
{@const edgeType = edge.type || 'default'}
{@const selectable = !!(
edge.selectable ||
($elementsSelectable && typeof edge.selectable === 'undefined')
)}
<EdgeWrapper
id={edge.id}
source={edge.source}
@@ -54,9 +48,8 @@
ariaLabel={edge.ariaLabel}
interactionWidth={edge.interactionWidth}
class={edge.class}
type={edgeType}
type={edge.type || 'default'}
zIndex={edge.zIndex}
{selectable}
on:edgeclick
on:edgecontextmenu
/>
@@ -0,0 +1,39 @@
import { get } from 'svelte/store';
import { errorMessages } from '@xyflow/system';
import { useStore } from '$lib/store';
export function useHandleEdgeSelect() {
const {
edgeLookup,
selectionRect,
selectionRectMode,
multiselectionKeyPressed,
addSelectedEdges,
unselectNodesAndEdges,
elementsSelectable
} = useStore();
return (id: string) => {
const edge = get(edgeLookup).get(id);
if (!edge) {
console.warn('012', errorMessages['error012'](id));
return;
}
const selectable =
edge.selectable || (get(elementsSelectable) && typeof edge.selectable === 'undefined');
if (selectable) {
selectionRect.set(null);
selectionRectMode.set(null);
if (!edge.selected) {
addSelectedEdges([id]);
} else if (edge.selected && get(multiselectionKeyPressed)) {
unselectNodesAndEdges({ nodes: [], edges: [edge] });
}
}
};
}
+25 -1
View File
@@ -29,6 +29,10 @@ import { isNode } from '$lib/utils';
export function useSvelteFlow(): {
zoomIn: ZoomInOut;
zoomOut: ZoomInOut;
getNode: (id: string) => Node | undefined;
getNodes: (ids?: string[]) => Node[];
getEdge: (id: string) => Edge | undefined;
getEdges: (ids?: string[]) => Edge[];
setZoom: (zoomLevel: number, options?: ViewportHelperFunctionOptions) => void;
getZoom: () => number;
setCenter: (x: number, y: number, options?: SetCenterOptions) => void;
@@ -82,7 +86,9 @@ export function useSvelteFlow(): {
panZoom,
nodes,
edges,
domNode
domNode,
nodeLookup,
edgeLookup
} = useStore();
const getNodeRect = (
@@ -121,6 +127,10 @@ export function useSvelteFlow(): {
return {
zoomIn,
zoomOut,
getNode: (id) => get(nodeLookup).get(id),
getNodes: (ids) => (ids === undefined ? get(nodes) : getElements(get(nodeLookup), ids)),
getEdge: (id) => get(edgeLookup).get(id),
getEdges: (ids) => (ids === undefined ? get(edges) : getElements(get(edgeLookup), ids)),
setZoom: (zoomLevel, options) => {
get(panZoom)?.scaleTo(zoomLevel, { duration: options?.duration });
},
@@ -295,3 +305,17 @@ export function useSvelteFlow(): {
viewport
};
}
function getElements<EdgeOrNode>(lookup: Map<string, EdgeOrNode>, ids: string[]) {
const result = [];
for (const id of ids) {
const element = lookup.get(id);
if (element) {
result.push(element);
}
}
return result;
}
-1
View File
@@ -79,7 +79,6 @@ export {
type OnError,
type NodeProps,
type NodeOrigin,
type OnNodeDrag,
type OnSelectionDrag,
Position,
type XYPosition,
+1 -2
View File
@@ -15,7 +15,6 @@ import {
type XYPosition,
type CoordinateExtent,
type UpdateConnection,
type NodeBase,
type NodeDragItem,
errorMessages
} from '@xyflow/system';
@@ -67,7 +66,7 @@ export function createStore({
const updateNodePositions: UpdateNodePositions = (nodeDragItems, dragging = false) => {
store.nodes.update((nds) => {
return nds.map((node) => {
const nodeDragItem = (nodeDragItems as Array<NodeBase | NodeDragItem>).find(
const nodeDragItem = (nodeDragItems as Array<Node | NodeDragItem>).find(
(ndi) => ndi.id === node.id
);
-9
View File
@@ -2,16 +2,7 @@
@import '../../../system/src/styles/init.css';
@import '../../../system/src/styles/base.css';
.svelte-flow {
--edge-label-color-default: inherit;
}
.svelte-flow.dark {
--edge-label-color-default: #f8f8f8;
}
.svelte-flow__edge-label {
text-align: center;
position: absolute;
color: var(--edge-label-color, var(--edge-label-color-default));
}
+4 -9
View File
@@ -3,19 +3,14 @@
@import '../../../system/src/styles/style.css';
@import '../../../system/src/styles/node-resizer.css';
.svelte-flow {
--edge-label-color-default: inherit;
}
.svelte-flow.dark {
--edge-label-color-default: #f8f8f8;
}
.svelte-flow__edge-label {
text-align: center;
position: absolute;
padding: 2px;
font-size: 10px;
color: var(--edge-label-color, var(--edge-label-color-default));
cursor: pointer;
color: var(--xy-edge-label-color, var(--xy-edge-label-color-default));
background: var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default));
}
.svelte-flow__nodes {
+2 -2
View File
@@ -139,8 +139,8 @@
}
&.selected .xy-flow__edge-path,
&:focus .xy-flow__edge-path,
&:focus-visible .xy-flow__edge-path {
&.selectable:focus .xy-flow__edge-path,
&.selectable:focus-visible .xy-flow__edge-path {
stroke: var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default));
}
+6
View File
@@ -19,6 +19,9 @@
--xy-controls-button-color-hover-default: inherit;
--xy-controls-button-border-color-default: #eee;
--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, 0.08);
--xy-edge-label-background-color-default: #ffffff;
--xy-edge-label-color-default: inherit;
}
.xy-flow.dark {
@@ -41,6 +44,9 @@
--xy-controls-button-color-hover-default: #fff;
--xy-controls-button-border-color-default: #5b5b5b;
--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, 0.08);
--xy-edge-label-background-color-default: #141414;
--xy-edge-label-color-default: #f8f8f8;
}
.xy-flow__edge {
+3 -5
View File
@@ -94,9 +94,9 @@ export type NodeProps<T = any> = {
positionAbsoluteY: number;
width?: number;
height?: number;
dragging: boolean;
targetPosition?: Position;
sourcePosition?: Position;
dragging: NodeBase['dragging'];
sourcePosition?: NodeBase['sourcePosition'];
targetPosition?: NodeBase['targetPosition'];
};
export type NodeHandleBounds = {
@@ -134,8 +134,6 @@ export type NodeDragItem = {
export type NodeOrigin = [number, number];
export type OnNodeDrag = (event: MouseEvent, node: NodeBase, nodes: NodeBase[]) => void;
export type OnSelectionDrag = (event: MouseEvent, nodes: NodeBase[]) => void;
export type NodeHandle = Optional<HandleElement, 'width' | 'height'>;
+6 -6
View File
@@ -23,7 +23,6 @@ import type {
SnapGrid,
Transform,
PanBy,
OnNodeDrag,
OnSelectionDrag,
UpdateNodePositions,
Box,
@@ -31,7 +30,7 @@ import type {
export type OnDrag = (event: MouseEvent, dragItems: NodeDragItem[], node: NodeBase, nodes: NodeBase[]) => void;
type StoreItems = {
type StoreItems<OnNodeDrag> = {
nodes: NodeBase[];
nodeLookup: Map<string, NodeBase>;
edges: EdgeBase[];
@@ -58,9 +57,9 @@ type StoreItems = {
updateNodePositions: UpdateNodePositions;
};
export type XYDragParams = {
export type XYDragParams<OnNodeDrag> = {
domNode: Element;
getStoreItems: () => StoreItems;
getStoreItems: () => StoreItems<OnNodeDrag>;
onDragStart?: OnDrag;
onDrag?: OnDrag;
onDragStop?: OnDrag;
@@ -80,14 +79,15 @@ export type DragUpdateParams = {
domNode: Element;
};
export function XYDrag({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function XYDrag<OnNodeDrag extends (e: any, nodes: any, node: any) => void | undefined>({
domNode,
onNodeMouseDown,
getStoreItems,
onDragStart,
onDrag,
onDragStop,
}: XYDragParams): XYDragInstance {
}: XYDragParams<OnNodeDrag>): XYDragInstance {
let lastPos: { x: number | null; y: number | null } = { x: null, y: null };
let autoPanId = 0;
let dragItems: NodeDragItem[] = [];