chore(ts): add annotations for useReactFlow/ useSvelteFlow
This commit is contained in:
@@ -34,7 +34,7 @@
|
||||
|
||||
// See of connection landed inside the flow pane
|
||||
const targetIsPane = (event.target as HTMLDivElement)?.classList.contains('svelte-flow__pane');
|
||||
if (targetIsPane) {
|
||||
if (targetIsPane && 'clientX' in event && 'clientY' in event) {
|
||||
const id = getId();
|
||||
const position = {
|
||||
x: event.clientX,
|
||||
|
||||
@@ -10,18 +10,24 @@ const selector = (s: ReactFlowStore) => ({
|
||||
position: s.connectionStartHandle ? s.connectionPosition : null,
|
||||
});
|
||||
|
||||
type UseConnectionResult = {
|
||||
/** The start handle where the user interaction started or null */
|
||||
startHandle: ReactFlowStore['connectionStartHandle'];
|
||||
/** The target handle that's inside the connection radius or null */
|
||||
endHandle: ReactFlowStore['connectionEndHandle'];
|
||||
/** The current connection status 'valid', 'invalid' or null*/
|
||||
status: ReactFlowStore['connectionStatus'];
|
||||
/** The current connection position or null */
|
||||
position: ReactFlowStore['connectionPosition'] | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook for accessing the ongoing connection.
|
||||
*
|
||||
* @public
|
||||
* @returns ongoing connection: startHandle, endHandle, status, position
|
||||
* @returns ongoing connection
|
||||
*/
|
||||
export function useConnection(): {
|
||||
startHandle: ReactFlowStore['connectionStartHandle'];
|
||||
endHandle: ReactFlowStore['connectionEndHandle'];
|
||||
status: ReactFlowStore['connectionStatus'];
|
||||
position: ReactFlowStore['connectionPosition'] | null;
|
||||
} {
|
||||
export function useConnection(): UseConnectionResult {
|
||||
const ongoingConnection = useStore(selector, shallow);
|
||||
|
||||
return ongoingConnection;
|
||||
|
||||
@@ -13,7 +13,7 @@ type useHandleConnectionsParams = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to check if a <Handle /> is connected to another <Handle /> and get the connections.
|
||||
* Hook to check if a <Handle /> is connected to another <Handle /> and get the connections.
|
||||
*
|
||||
* @public
|
||||
* @param param.type - handle type 'source' or 'target'
|
||||
|
||||
@@ -11,7 +11,7 @@ export type UseOnSelectionChangeOptions = {
|
||||
* Hook for registering an onSelectionChange handler.
|
||||
*
|
||||
* @public
|
||||
* @params params.onChange - The handler to register
|
||||
* @param params.onChange - The handler to register
|
||||
*/
|
||||
export function useOnSelectionChange({ onChange }: UseOnSelectionChangeOptions) {
|
||||
const store = useStoreApi();
|
||||
|
||||
@@ -86,31 +86,31 @@ const useViewportHelper = (): ViewportHelperFunctions => {
|
||||
|
||||
panZoom?.setViewport(viewport, { duration: options?.duration });
|
||||
},
|
||||
screenToFlowPosition: (position: XYPosition, options: { snapToGrid: boolean } = { snapToGrid: true }) => {
|
||||
screenToFlowPosition: (clientPosition: XYPosition, options: { snapToGrid: boolean } = { snapToGrid: true }) => {
|
||||
const { transform, snapGrid, domNode } = store.getState();
|
||||
|
||||
if (!domNode) {
|
||||
return position;
|
||||
return clientPosition;
|
||||
}
|
||||
|
||||
const { x: domX, y: domY } = domNode.getBoundingClientRect();
|
||||
|
||||
const correctedPosition = {
|
||||
x: position.x - domX,
|
||||
y: position.y - domY,
|
||||
x: clientPosition.x - domX,
|
||||
y: clientPosition.y - domY,
|
||||
};
|
||||
|
||||
return pointToRendererPoint(correctedPosition, transform, options.snapToGrid, snapGrid);
|
||||
},
|
||||
flowToScreenPosition: (position: XYPosition) => {
|
||||
flowToScreenPosition: (flowPosition: XYPosition) => {
|
||||
const { transform, domNode } = store.getState();
|
||||
|
||||
if (!domNode) {
|
||||
return position;
|
||||
return flowPosition;
|
||||
}
|
||||
|
||||
const { x: domX, y: domY } = domNode.getBoundingClientRect();
|
||||
const rendererPosition = rendererPointToPoint(position, transform);
|
||||
const rendererPosition = rendererPointToPoint(flowPosition, transform);
|
||||
|
||||
return {
|
||||
x: rendererPosition.x + domX,
|
||||
|
||||
@@ -47,17 +47,91 @@ export type OnInit<NodeType extends Node = Node, EdgeType extends Edge = Edge> =
|
||||
) => void;
|
||||
|
||||
export type ViewportHelperFunctions = {
|
||||
/**
|
||||
* Zooms viewport in by 1.2.
|
||||
*
|
||||
* @param options.duration - optional duration. If set, a transition will be applied
|
||||
*/
|
||||
zoomIn: ZoomInOut;
|
||||
/**
|
||||
* Zooms viewport out by 1 / 1.2.
|
||||
*
|
||||
* @param options.duration - optional duration. If set, a transition will be applied
|
||||
*/
|
||||
zoomOut: ZoomInOut;
|
||||
/**
|
||||
* Sets the current zoom level.
|
||||
*
|
||||
* @param zoomLevel - the zoom level to set
|
||||
* @param options.duration - optional duration. If set, a transition will be applied
|
||||
*/
|
||||
zoomTo: ZoomTo;
|
||||
/**
|
||||
* Returns the current zoom level.
|
||||
*
|
||||
* @returns current zoom as a number
|
||||
*/
|
||||
getZoom: GetZoom;
|
||||
/**
|
||||
* Sets the current viewport.
|
||||
*
|
||||
* @param viewport - the viewport to set
|
||||
* @param options.duration - optional duration. If set, a transition will be applied
|
||||
*/
|
||||
setViewport: SetViewport;
|
||||
/**
|
||||
* Returns the current viewport.
|
||||
*
|
||||
* @returns Viewport
|
||||
*/
|
||||
getViewport: GetViewport;
|
||||
/**
|
||||
* Fits the view.
|
||||
*
|
||||
* @param options.padding - optional padding
|
||||
* @param options.includeHiddenNodes - optional includeHiddenNodes
|
||||
* @param options.minZoom - optional minZoom
|
||||
* @param options.maxZoom - optional maxZoom
|
||||
* @param options.duration - optional duration. If set, a transition will be applied
|
||||
* @param options.nodes - optional nodes to fit the view to
|
||||
*/
|
||||
fitView: FitView;
|
||||
/**
|
||||
* Sets the center of the view to the given position.
|
||||
*
|
||||
* @param x - x position
|
||||
* @param y - y position
|
||||
* @param options.zoom - optional zoom
|
||||
*/
|
||||
setCenter: SetCenter;
|
||||
/**
|
||||
* Fits the view to the given bounds .
|
||||
*
|
||||
* @param bounds - the bounds ({ x: number, y: number, width: number, height: number }) to fit the view to
|
||||
* @param options.padding - optional padding
|
||||
*/
|
||||
fitBounds: FitBounds;
|
||||
screenToFlowPosition: (position: XYPosition, options?: { snapToGrid: boolean }) => XYPosition;
|
||||
flowToScreenPosition: (position: XYPosition) => XYPosition;
|
||||
/**
|
||||
* Converts a screen / client position to a flow position.
|
||||
*
|
||||
* @param clientPosition - the screen / client position. When you are working with events you can use event.clientX and event.clientY
|
||||
* @param options.snapToGrid - if true, the converted position will be snapped to the grid
|
||||
* @returns position as { x: number, y: number }
|
||||
*
|
||||
* @example
|
||||
* const flowPosition = screenToFlowPosition({ x: event.clientX, y: event.clientY })
|
||||
*/
|
||||
screenToFlowPosition: (clientPosition: XYPosition, options?: { snapToGrid: boolean }) => XYPosition;
|
||||
/**
|
||||
* Converts a flow position to a screen / client position.
|
||||
*
|
||||
* @param flowPosition - the screen / client position. When you are working with events you can use event.clientX and event.clientY
|
||||
* @returns position as { x: number, y: number }
|
||||
*
|
||||
* @example
|
||||
* const clientPosition = flowToScreenPosition({ x: node.position.x, y: node.position.y })
|
||||
*/
|
||||
flowToScreenPosition: (flowPosition: XYPosition) => XYPosition;
|
||||
viewportInitialized: boolean;
|
||||
};
|
||||
|
||||
|
||||
@@ -59,19 +59,112 @@ export namespace Instance {
|
||||
}
|
||||
|
||||
export type ReactFlowInstance<NodeType extends Node = Node, EdgeType extends Edge = Edge> = {
|
||||
/**
|
||||
* Returns nodes.
|
||||
*
|
||||
* @returns nodes array
|
||||
*/
|
||||
getNodes: Instance.GetNodes<NodeType>;
|
||||
/**
|
||||
* Sets nodes.
|
||||
*
|
||||
* @param payload - the nodes to set or a function that receives the current nodes and returns the new nodes
|
||||
*/
|
||||
setNodes: Instance.SetNodes<NodeType>;
|
||||
/**
|
||||
* Adds nodes.
|
||||
*
|
||||
* @param payload - the nodes to add
|
||||
*/
|
||||
addNodes: Instance.AddNodes<NodeType>;
|
||||
/**
|
||||
* Returns a node by id.
|
||||
*
|
||||
* @param id - the node id
|
||||
* @returns the node or undefined if no node was found
|
||||
*/
|
||||
getNode: Instance.GetNode<NodeType>;
|
||||
/**
|
||||
* Returns edges.
|
||||
*
|
||||
* @returns edges array
|
||||
*/
|
||||
getEdges: Instance.GetEdges<EdgeType>;
|
||||
/**
|
||||
* Sets edges.
|
||||
*
|
||||
* @param payload - the edges to set or a function that receives the current edges and returns the new edges
|
||||
*/
|
||||
setEdges: Instance.SetEdges<EdgeType>;
|
||||
/**
|
||||
* Adds edges.
|
||||
*
|
||||
* @param payload - the edges to add
|
||||
*/
|
||||
addEdges: Instance.AddEdges<EdgeType>;
|
||||
/**
|
||||
* Returns an edge by id.
|
||||
*
|
||||
* @param id - the edge id
|
||||
* @returns the edge or undefined if no edge was found
|
||||
*/
|
||||
getEdge: Instance.GetEdge<EdgeType>;
|
||||
/**
|
||||
* Returns the nodes, edges and the viewport as a JSON object.
|
||||
*
|
||||
* @returns the nodes, edges and the viewport as a JSON object
|
||||
*/
|
||||
toObject: Instance.ToObject<NodeType, EdgeType>;
|
||||
/**
|
||||
* Deletes nodes and edges.
|
||||
*
|
||||
* @param params.nodes - optional nodes array to delete
|
||||
* @param params.edges - optional edges array to delete
|
||||
*
|
||||
* @returns a promise that resolves with the deleted nodes and edges
|
||||
*/
|
||||
deleteElements: Instance.DeleteElements;
|
||||
/**
|
||||
* Returns all nodes that intersect with the given node or rect.
|
||||
*
|
||||
* @param node - the node or rect to check for intersections
|
||||
* @param partially - if true, the node is considered to be intersecting if it partially overlaps with the passed node or rect
|
||||
* @param nodes - optional nodes array to check for intersections
|
||||
*
|
||||
* @returns an array of intersecting nodes
|
||||
*/
|
||||
getIntersectingNodes: Instance.GetIntersectingNodes<NodeType>;
|
||||
/**
|
||||
* Checks if the given node or rect intersects with the passed rect.
|
||||
*
|
||||
* @param node - the node or rect to check for intersections
|
||||
* @param area - the rect to check for intersections
|
||||
* @param partially - if true, the node is considered to be intersecting if it partially overlaps with the passed react
|
||||
*
|
||||
* @returns true if the node or rect intersects with the given area
|
||||
*/
|
||||
isNodeIntersecting: Instance.IsNodeIntersecting<NodeType>;
|
||||
/**
|
||||
* Updates a node.
|
||||
*
|
||||
* @param id - id of the node to update
|
||||
* @param nodeUpdate - the node update as an object or a function that receives the current node and returns the node update
|
||||
* @param options.replace - if true, the node is replaced with the node update, otherwise the changes get merged
|
||||
*
|
||||
* @example
|
||||
* updateNode('node-1', (node) => ({ position: { x: node.position.x + 10, y: node.position.y } }));
|
||||
*/
|
||||
updateNode: Instance.UpdateNode<NodeType>;
|
||||
/**
|
||||
* Updates the data attribute of a node.
|
||||
*
|
||||
* @param id - id of the node to update
|
||||
* @param dataUpdate - the data update as an object or a function that receives the current data and returns the data update
|
||||
* @param options.replace - if true, the data is replaced with the data update, otherwise the changes get merged
|
||||
*
|
||||
* @example
|
||||
* updateNodeData('node-1', { label: 'A new label' });
|
||||
*/
|
||||
updateNodeData: Instance.UpdateNodeData<NodeType>;
|
||||
viewportInitialized: boolean;
|
||||
} & Omit<ViewportHelperFunctions, 'initialized'>;
|
||||
|
||||
@@ -24,32 +24,136 @@ import { isNode } from '$lib/utils';
|
||||
* Hook for accessing the ReactFlow instance.
|
||||
*
|
||||
* @public
|
||||
*
|
||||
* @returns helper functions
|
||||
*/
|
||||
export function useSvelteFlow(): {
|
||||
/**
|
||||
* Zooms viewport in by 1.2.
|
||||
*
|
||||
* @param options.duration - optional duration. If set, a transition will be applied
|
||||
*/
|
||||
zoomIn: ZoomInOut;
|
||||
/**
|
||||
* Zooms viewport out by 1 / 1.2.
|
||||
*
|
||||
* @param options.duration - optional duration. If set, a transition will be applied
|
||||
*/
|
||||
zoomOut: ZoomInOut;
|
||||
/**
|
||||
* Returns a node by id.
|
||||
*
|
||||
* @param id - the node id
|
||||
* @returns the node or undefined if no node was found
|
||||
*/
|
||||
getNode: (id: string) => Node | undefined;
|
||||
/**
|
||||
* Returns nodes.
|
||||
*
|
||||
* @returns nodes array
|
||||
*/
|
||||
getNodes: (ids?: string[]) => Node[];
|
||||
/**
|
||||
* Returns an edge by id.
|
||||
*
|
||||
* @param id - the edge id
|
||||
* @returns the edge or undefined if no edge was found
|
||||
*/
|
||||
getEdge: (id: string) => Edge | undefined;
|
||||
/**
|
||||
* Returns edges.
|
||||
*
|
||||
* @returns edges array
|
||||
*/
|
||||
getEdges: (ids?: string[]) => Edge[];
|
||||
/**
|
||||
* Sets the current zoom level.
|
||||
*
|
||||
* @param zoomLevel - the zoom level to set
|
||||
* @param options.duration - optional duration. If set, a transition will be applied
|
||||
*/
|
||||
setZoom: (zoomLevel: number, options?: ViewportHelperFunctionOptions) => void;
|
||||
/**
|
||||
* Returns the current zoom level.
|
||||
*
|
||||
* @returns current zoom as a number
|
||||
*/
|
||||
getZoom: () => number;
|
||||
/**
|
||||
* Sets the center of the view to the given position.
|
||||
*
|
||||
* @param x - x position
|
||||
* @param y - y position
|
||||
* @param options.zoom - optional zoom
|
||||
*/
|
||||
setCenter: (x: number, y: number, options?: SetCenterOptions) => void;
|
||||
/**
|
||||
* Sets the current viewport.
|
||||
*
|
||||
* @param viewport - the viewport to set
|
||||
* @param options.duration - optional duration. If set, a transition will be applied
|
||||
*/
|
||||
setViewport: (viewport: Viewport, options?: ViewportHelperFunctionOptions) => void;
|
||||
/**
|
||||
* Returns the current viewport.
|
||||
*
|
||||
* @returns Viewport
|
||||
*/
|
||||
getViewport: () => Viewport;
|
||||
/**
|
||||
* Fits the view.
|
||||
*
|
||||
* @param options.padding - optional padding
|
||||
* @param options.includeHiddenNodes - optional includeHiddenNodes
|
||||
* @param options.minZoom - optional minZoom
|
||||
* @param options.maxZoom - optional maxZoom
|
||||
* @param options.duration - optional duration. If set, a transition will be applied
|
||||
* @param options.nodes - optional nodes to fit the view to
|
||||
*/
|
||||
fitView: (options?: FitViewOptions) => void;
|
||||
/**
|
||||
* Returns all nodes that intersect with the given node or rect.
|
||||
*
|
||||
* @param node - the node or rect to check for intersections
|
||||
* @param partially - if true, the node is considered to be intersecting if it partially overlaps with the passed node or rect
|
||||
* @param nodes - optional nodes array to check for intersections
|
||||
*
|
||||
* @returns an array of intersecting nodes
|
||||
*/
|
||||
getIntersectingNodes: (
|
||||
nodeOrRect: Node | { id: Node['id'] } | Rect,
|
||||
partially?: boolean,
|
||||
nodesToIntersect?: Node[]
|
||||
) => Node[];
|
||||
/**
|
||||
* Checks if the given node or rect intersects with the passed rect.
|
||||
*
|
||||
* @param node - the node or rect to check for intersections
|
||||
* @param area - the rect to check for intersections
|
||||
* @param partially - if true, the node is considered to be intersecting if it partially overlaps with the passed react
|
||||
*
|
||||
* @returns true if the node or rect intersects with the given area
|
||||
*/
|
||||
isNodeIntersecting: (
|
||||
nodeOrRect: Node | { id: Node['id'] } | Rect,
|
||||
area: Rect,
|
||||
partially?: boolean
|
||||
) => boolean;
|
||||
/**
|
||||
* Fits the view to the given bounds .
|
||||
*
|
||||
* @param bounds - the bounds ({ x: number, y: number, width: number, height: number }) to fit the view to
|
||||
* @param options.padding - optional padding
|
||||
*/
|
||||
fitBounds: (bounds: Rect, options?: FitBoundsOptions) => void;
|
||||
/**
|
||||
* Deletes nodes and edges.
|
||||
*
|
||||
* @param params.nodes - optional nodes array to delete
|
||||
* @param params.edges - optional edges array to delete
|
||||
*
|
||||
* @returns a promise that resolves with the deleted nodes and edges
|
||||
*/
|
||||
deleteElements: ({
|
||||
nodes,
|
||||
edges
|
||||
@@ -57,19 +161,66 @@ export function useSvelteFlow(): {
|
||||
nodes?: (Node | { id: Node['id'] })[];
|
||||
edges?: (Edge | { id: Edge['id'] })[];
|
||||
}) => Promise<{ deletedNodes: Node[]; deletedEdges: Edge[] }>;
|
||||
screenToFlowPosition: (position: XYPosition, options?: { snapToGrid: boolean }) => XYPosition;
|
||||
flowToScreenPosition: (position: XYPosition) => XYPosition;
|
||||
/**
|
||||
* Converts a screen / client position to a flow position.
|
||||
*
|
||||
* @param clientPosition - the screen / client position. When you are working with events you can use event.clientX and event.clientY
|
||||
* @param options.snapToGrid - if true, the converted position will be snapped to the grid
|
||||
* @returns position as { x: number, y: number }
|
||||
*
|
||||
* @example
|
||||
* const flowPosition = screenToFlowPosition({ x: event.clientX, y: event.clientY })
|
||||
*/
|
||||
screenToFlowPosition: (
|
||||
clientPosition: XYPosition,
|
||||
options?: { snapToGrid: boolean }
|
||||
) => XYPosition;
|
||||
/**
|
||||
* Converts a flow position to a screen / client position.
|
||||
*
|
||||
* @param flowPosition - the screen / client position. When you are working with events you can use event.clientX and event.clientY
|
||||
* @returns position as { x: number, y: number }
|
||||
*
|
||||
* @example
|
||||
* const clientPosition = flowToScreenPosition({ x: node.position.x, y: node.position.y })
|
||||
*/
|
||||
flowToScreenPosition: (flowPosition: XYPosition) => XYPosition;
|
||||
viewport: Writable<Viewport>;
|
||||
/**
|
||||
* Updates a node.
|
||||
*
|
||||
* @param id - id of the node to update
|
||||
* @param nodeUpdate - the node update as an object or a function that receives the current node and returns the node update
|
||||
* @param options.replace - if true, the node is replaced with the node update, otherwise the changes get merged
|
||||
*
|
||||
* @example
|
||||
* updateNode('node-1', (node) => ({ position: { x: node.position.x + 10, y: node.position.y } }));
|
||||
*/
|
||||
updateNode: (
|
||||
id: string,
|
||||
nodeUpdate: Partial<Node> | ((node: Node) => Partial<Node>),
|
||||
options?: { replace: boolean }
|
||||
) => void;
|
||||
/**
|
||||
* Updates the data attribute of a node.
|
||||
*
|
||||
* @param id - id of the node to update
|
||||
* @param dataUpdate - the data update as an object or a function that receives the current data and returns the data update
|
||||
* @param options.replace - if true, the data is replaced with the data update, otherwise the changes get merged
|
||||
*
|
||||
* @example
|
||||
* updateNodeData('node-1', { label: 'A new label' });
|
||||
*/
|
||||
updateNodeData: (
|
||||
id: string,
|
||||
dataUpdate: object | ((node: Node) => object),
|
||||
options?: { replace: boolean }
|
||||
) => void;
|
||||
/**
|
||||
* Returns the nodes, edges and the viewport as a JSON object.
|
||||
*
|
||||
* @returns the nodes, edges and the viewport as a JSON object
|
||||
*/
|
||||
toObject: () => { nodes: Node[]; edges: Edge[]; viewport: Viewport };
|
||||
} {
|
||||
const {
|
||||
@@ -263,6 +414,11 @@ export function useSvelteFlow(): {
|
||||
_snapGrid || [1, 1]
|
||||
);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param position
|
||||
* @returns
|
||||
*/
|
||||
flowToScreenPosition: (position: XYPosition) => {
|
||||
const _domNode = get(domNode);
|
||||
|
||||
@@ -279,6 +435,7 @@ export function useSvelteFlow(): {
|
||||
y: rendererPosition.y + domY
|
||||
};
|
||||
},
|
||||
|
||||
toObject: () => {
|
||||
return {
|
||||
nodes: get(nodes).map((node) => ({
|
||||
|
||||
Reference in New Issue
Block a user