import { ActionUnion, BoundActionCreators } from '../../utils/typedActions'; import { NodeId, ConnectionId, Position, Port as BasePort, ContextMenuState } from '../../types/core'; import { ConnectablePortsResult } from '../../core/port/connectivity/connectableTypes'; /** * @file Context for managing editor UI action states like selection, dragging, resizing, and context menus * Also provides centralized node operations (copy, paste, duplicate, delete, cut) */ import * as React from "react"; /** * Options for showing a context menu */ export type ShowContextMenuOptions = { position: Position; nodeId?: NodeId; canvasPosition?: Position; connectionId?: ConnectionId; mode?: "menu" | "search"; allowedNodeTypes?: string[]; fromPort?: BasePort; }; export type EditorActionState = { selectedNodeIds: NodeId[]; editingSelectedNodeIds: NodeId[]; selectedConnectionIds: ConnectionId[]; hoveredNodeId: NodeId | null; hoveredConnectionId: ConnectionId | null; hoveredPort: BasePort | null; connectedPorts: Set; connectablePorts: ConnectablePortsResult; contextMenu: ContextMenuState; inspectorActiveTab: number; }; export declare const editorActionStateActions: { readonly selectInteractionNode: ((nodeId: string, multiple?: boolean | undefined) => { type: "SELECT_INTERACTION_NODE"; payload: { nodeId: string; multiple: boolean; }; }) & { readonly type: "SELECT_INTERACTION_NODE"; }; readonly setInteractionSelection: ((nodeIds: string[]) => { type: "SET_INTERACTION_SELECTION"; payload: { nodeIds: string[]; }; }) & { readonly type: "SET_INTERACTION_SELECTION"; }; readonly clearInteractionSelection: (() => { type: "CLEAR_INTERACTION_SELECTION"; }) & { readonly type: "CLEAR_INTERACTION_SELECTION"; }; readonly selectEditingNode: ((nodeId: string, multiple?: boolean | undefined) => { type: "SELECT_EDITING_NODE"; payload: { nodeId: string; multiple: boolean; }; }) & { readonly type: "SELECT_EDITING_NODE"; }; readonly setEditingSelection: ((nodeIds: string[]) => { type: "SET_EDITING_SELECTION"; payload: { nodeIds: string[]; }; }) & { readonly type: "SET_EDITING_SELECTION"; }; readonly clearEditingSelection: (() => { type: "CLEAR_EDITING_SELECTION"; }) & { readonly type: "CLEAR_EDITING_SELECTION"; }; readonly selectConnection: ((connectionId: string, multiple?: boolean | undefined) => { type: "SELECT_CONNECTION"; payload: { connectionId: string; multiple: boolean; }; }) & { readonly type: "SELECT_CONNECTION"; }; readonly clearSelection: (() => { type: "CLEAR_SELECTION"; }) & { readonly type: "CLEAR_SELECTION"; }; readonly setHoveredNode: ((nodeId: string | null) => { type: "SET_HOVERED_NODE"; payload: { nodeId: string | null; }; }) & { readonly type: "SET_HOVERED_NODE"; }; readonly setHoveredConnection: ((connectionId: string | null) => { type: "SET_HOVERED_CONNECTION"; payload: { connectionId: string | null; }; }) & { readonly type: "SET_HOVERED_CONNECTION"; }; readonly setHoveredPort: ((port: BasePort | null) => { type: "SET_HOVERED_PORT"; payload: { port: BasePort | null; }; }) & { readonly type: "SET_HOVERED_PORT"; }; readonly updateConnectedPorts: ((connectedPorts: Set) => { type: "UPDATE_CONNECTED_PORTS"; payload: { connectedPorts: Set; }; }) & { readonly type: "UPDATE_CONNECTED_PORTS"; }; readonly updateConnectablePorts: ((connectablePorts: ConnectablePortsResult) => { type: "UPDATE_CONNECTABLE_PORTS"; payload: { connectablePorts: ConnectablePortsResult; }; }) & { readonly type: "UPDATE_CONNECTABLE_PORTS"; }; readonly showContextMenu: ((options: ShowContextMenuOptions) => { type: "SHOW_CONTEXT_MENU"; payload: ShowContextMenuOptions; }) & { readonly type: "SHOW_CONTEXT_MENU"; }; readonly hideContextMenu: (() => { type: "HIDE_CONTEXT_MENU"; }) & { readonly type: "HIDE_CONTEXT_MENU"; }; readonly setInspectorActiveTab: ((index: number) => { type: "SET_INSPECTOR_ACTIVE_TAB"; payload: { index: number; }; }) & { readonly type: "SET_INSPECTOR_ACTIVE_TAB"; }; }; export type EditorActionStateAction = ActionUnion; export declare const editorActionStateReducer: (state: EditorActionState, action: EditorActionStateAction) => EditorActionState; export declare const defaultEditorActionState: EditorActionState; export type NodeOperations = { /** * Duplicate nodes. If targetNodeId is in selection, duplicates all selected nodes. * Otherwise duplicates only the target node. */ duplicateNodes: (targetNodeId?: string) => void; /** * Delete nodes. If targetNodeId is in selection, deletes all selected nodes. * Otherwise deletes only the target node. */ deleteNodes: (targetNodeId?: string) => void; /** * Copy nodes to clipboard. If targetNodeId is in selection, copies all selected nodes. * Otherwise copies only the target node. */ copyNodes: (targetNodeId?: string) => void; /** * Cut nodes (copy then delete). If targetNodeId is in selection, cuts all selected nodes. * Otherwise cuts only the target node. */ cutNodes: (targetNodeId?: string) => void; /** * Paste nodes from clipboard and select them. */ pasteNodes: () => void; /** * Create a node from context menu, optionally auto-connecting to a source port. * Handles position conversion, type limit checking, and connection creation. */ createNodeFromContextMenu: (nodeType: string, screenPosition: Position) => void; /** * Create a node from a canvas drop (already in canvas coordinates). * Handles type limit checking and node creation. */ createNodeFromCanvasDrop: (nodeType: string, canvasPosition: Position) => void; }; export type EditorActionStateActionsValue = { dispatch: React.Dispatch; actions: BoundActionCreators; actionCreators: typeof editorActionStateActions; nodeOperations: NodeOperations; }; export type EditorActionStateContextValue = EditorActionStateActionsValue & { state: EditorActionState; }; export type EditorActionSelectionCounts = { selectedNodeCount: number; selectedConnectionCount: number; }; export declare const EditorActionStateContext: React.Context; export type EditorActionStateProviderProps = { children: React.ReactNode; initialState?: Partial; }; export declare const EditorActionStateProvider: React.FC; /** * Hook to access both state and actions (backward compatible) * Prefer useEditorActionStateState or useEditorActionStateActions for better performance */ export declare const useEditorActionState: () => EditorActionStateContextValue; /** * Hook to access only the editor action state. * Prefer this in performance-sensitive render paths to avoid re-renders when only actions change. */ export declare const useEditorActionStateState: () => EditorActionState; /** * Hook to access only selection counts. * Designed to avoid re-renders for hover-only state changes. */ export declare const useEditorActionSelectionCounts: () => EditorActionSelectionCounts; /** * Hook to access only the editor action actions. * Prefer this when you only need to dispatch and don't want to re-render on state changes. */ export declare const useEditorActionStateActions: () => EditorActionStateActionsValue; /** * Returns a memoized Set of selected node IDs for O(1) lookup. */ export declare const useSelectedNodeIdsSet: () => ReadonlySet; /** * Returns a memoized Set of selected connection IDs for O(1) lookup. */ export declare const useSelectedConnectionIdsSet: () => ReadonlySet;