@theclearsky/react-blender-nodes 0.0.1 → 0.0.2

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.
package/dist/index.d.ts CHANGED
@@ -27,36 +27,58 @@ import { VariantProps } from 'class-variance-authority';
27
27
  import { XYPosition } from '@xyflow/react';
28
28
  import { z } from 'zod';
29
29
 
30
+ /**
31
+ * Union type of all possible actions for the graph state reducer
32
+ *
33
+ * @template DataTypeUniqueId - Unique identifier type for data types
34
+ * @template NodeTypeUniqueId - Unique identifier type for node types
35
+ * @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
36
+ * @template ComplexSchemaType - Zod schema type for complex data types
37
+ */
30
38
  declare type Action<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = {
39
+ /** Add a new node to the graph */
31
40
  type: typeof actionTypesMap.ADD_NODE;
32
41
  payload: {
42
+ /** Type of node to add */
33
43
  type: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>['nodeIdToNodeType'][string];
44
+ /** Position where to place the node */
34
45
  position: XYPosition;
35
46
  };
36
47
  } | {
48
+ /** Update nodes based on ReactFlow changes */
37
49
  type: typeof actionTypesMap.UPDATE_NODE_BY_REACT_FLOW;
38
50
  payload: {
51
+ /** Array of node changes from ReactFlow */
39
52
  changes: NodeChanges;
40
53
  };
41
54
  } | {
55
+ /** Update edges based on ReactFlow changes */
42
56
  type: typeof actionTypesMap.UPDATE_EDGES_BY_REACT_FLOW;
43
57
  payload: {
58
+ /** Array of edge changes from ReactFlow */
44
59
  changes: EdgeChanges;
45
60
  };
46
61
  } | {
62
+ /** Add a new edge to the graph */
47
63
  type: typeof actionTypesMap.ADD_EDGE_BY_REACT_FLOW;
48
64
  payload: {
65
+ /** Connection object from ReactFlow */
49
66
  edge: Connection;
50
67
  };
51
68
  } | {
69
+ /** Update the value of a node input */
52
70
  type: typeof actionTypesMap.UPDATE_INPUT_VALUE;
53
71
  payload: {
72
+ /** ID of the node containing the input */
54
73
  nodeId: string;
74
+ /** ID of the input to update */
55
75
  inputId: string;
76
+ /** New value for the input */
56
77
  value: string | number;
57
78
  };
58
79
  };
59
80
 
81
+ /** Map of action types for type-safe action dispatching */
60
82
  declare const actionTypesMap: {
61
83
  readonly ADD_NODE: "ADD_NODE";
62
84
  readonly UPDATE_NODE_BY_REACT_FLOW: "UPDATE_NODE_BY_REACT_FLOW";
@@ -65,16 +87,69 @@ declare const actionTypesMap: {
65
87
  readonly UPDATE_INPUT_VALUE: "UPDATE_INPUT_VALUE";
66
88
  };
67
89
 
90
+ /**
91
+ * Represents a rectangular bounding box
92
+ */
68
93
  export declare type Box = {
94
+ /** Top edge position */
69
95
  top: number;
96
+ /** Left edge position */
70
97
  left: number;
98
+ /** Right edge position */
71
99
  right: number;
100
+ /** Bottom edge position */
72
101
  bottom: number;
73
102
  };
74
103
 
104
+ /**
105
+ * A customizable button component with Blender-inspired styling
106
+ *
107
+ * This button component provides multiple color variants and hover states
108
+ * that match the Blender node editor aesthetic. It supports composition
109
+ * through the asChild prop and includes proper accessibility features.
110
+ *
111
+ * Features:
112
+ * - Multiple color variants (dark, lightNonPriority, lightPriority)
113
+ * - Configurable hover styles
114
+ * - Composition support with Radix Slot
115
+ * - Full TypeScript support
116
+ * - Accessibility features
117
+ *
118
+ * @param props - The component props
119
+ * @param ref - Forwarded ref to the button element
120
+ * @returns JSX element containing the button
121
+ *
122
+ * @example
123
+ * ```tsx
124
+ * // Basic button
125
+ * <Button onClick={handleClick}>Click me</Button>
126
+ *
127
+ * // Button with custom color
128
+ * <Button color="lightPriority" onClick={handleSubmit}>
129
+ * Submit
130
+ * </Button>
131
+ *
132
+ * // Button as child component
133
+ * <Button asChild>
134
+ * <Link to="/dashboard">Go to Dashboard</Link>
135
+ * </Button>
136
+ *
137
+ * // Button without hover styles
138
+ * <Button applyHoverStyles={false} disabled>
139
+ * Disabled Button
140
+ * </Button>
141
+ * ```
142
+ */
75
143
  export declare const Button: ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & RefAttributes<HTMLButtonElement>>;
76
144
 
145
+ /**
146
+ * Props for the Button component
147
+ *
148
+ * Extends the standard button element props with custom styling variants
149
+ * and composition capabilities.
150
+ */
77
151
  export declare type ButtonProps = ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
152
+ /** Whether to render as a child component using Radix Slot */
78
153
  asChild?: boolean;
79
154
  };
80
155
 
@@ -83,8 +158,75 @@ declare const buttonVariants: (props?: ({
83
158
  applyHoverStyles?: boolean | null | undefined;
84
159
  } & ClassProp) | undefined) => string;
85
160
 
161
+ /**
162
+ * Utility function for combining and merging CSS classes
163
+ *
164
+ * This function combines clsx for conditional class handling with tailwind-merge
165
+ * for intelligent Tailwind CSS class merging. It resolves conflicts between
166
+ * Tailwind classes and ensures only the last conflicting class is applied.
167
+ *
168
+ * @param inputs - Variable number of class values (strings, objects, arrays, etc.)
169
+ * @returns Merged and deduplicated class string
170
+ *
171
+ * @example
172
+ * ```tsx
173
+ * // Basic usage
174
+ * cn('px-4 py-2', 'bg-blue-500', 'text-white')
175
+ * // Returns: "px-4 py-2 bg-blue-500 text-white"
176
+ *
177
+ * // Conditional classes
178
+ * cn('base-class', isActive && 'active-class', isDisabled && 'disabled-class')
179
+ *
180
+ * // Tailwind class merging (conflicts resolved)
181
+ * cn('px-4 px-6', 'py-2 py-4')
182
+ * // Returns: "px-6 py-4" (last conflicting classes win)
183
+ *
184
+ * // With objects
185
+ * cn({
186
+ * 'bg-blue-500': isPrimary,
187
+ * 'bg-gray-500': !isPrimary,
188
+ * 'text-white': true,
189
+ * })
190
+ * ```
191
+ */
86
192
  export declare function cn(...inputs: ClassValue[]): string;
87
193
 
194
+ /**
195
+ * A configurable edge component with gradient colors and viewport optimization
196
+ *
197
+ * This component renders edges between nodes with automatic color gradients
198
+ * based on the source and target handle colors. It includes viewport optimization
199
+ * to reduce rendering overhead for edges outside the visible area.
200
+ *
201
+ * Features:
202
+ * - Automatic gradient colors based on handle colors
203
+ * - Viewport optimization for performance
204
+ * - Bezier curve rendering
205
+ * - ReactFlow integration
206
+ * - Custom styling and animations
207
+ *
208
+ * @param props - The component props
209
+ * @param _ - Unused ref parameter
210
+ * @returns JSX element containing the configurable edge
211
+ *
212
+ * @example
213
+ * ```tsx
214
+ * // Edge with automatic gradient colors
215
+ * <ConfigurableEdge
216
+ * id="edge1"
217
+ * sourceX={100}
218
+ * sourceY={50}
219
+ * targetX={200}
220
+ * targetY={50}
221
+ * sourcePosition={Position.Right}
222
+ * targetPosition={Position.Left}
223
+ * source="node1"
224
+ * target="node2"
225
+ * sourceHandleId="output1"
226
+ * targetHandleId="input1"
227
+ * />
228
+ * ```
229
+ */
88
230
  export declare const ConfigurableEdge: ForwardRefExoticComponent<Pick<ConfigurableEdgeState, "data" | "source" | "style" | "id" | "target" | "selectable" | "deletable" | "selected" | "animated"> & EdgePosition & EdgeLabelOptions & {
89
231
  sourceHandleId?: string | null;
90
232
  targetHandleId?: string | null;
@@ -94,111 +236,478 @@ pathOptions?: any;
94
236
  interactionWidth?: number;
95
237
  } & RefAttributes<HTMLDivElement>>;
96
238
 
239
+ /** Props for the ConfigurableEdge component */
97
240
  export declare type ConfigurableEdgeProps = EdgeProps<ConfigurableEdgeState>;
98
241
 
242
+ /** State type for configurable edges */
99
243
  export declare type ConfigurableEdgeState = Edge<{}, 'configurableEdge'>;
100
244
 
245
+ /**
246
+ * A customizable node component inspired by Blender's node editor
247
+ *
248
+ * This component creates a node with configurable inputs, outputs, and collapsible panels.
249
+ * It supports both standalone usage and ReactFlow integration with automatic handle
250
+ * management and interactive input components.
251
+ *
252
+ * Features:
253
+ * - Customizable header with color and name
254
+ * - Dynamic inputs and outputs with custom handle shapes
255
+ * - Collapsible input panels for organization
256
+ * - Interactive input components (text/number) when not connected
257
+ * - ReactFlow integration with automatic handle positioning
258
+ * - Node resizing controls when inside ReactFlow
259
+ *
260
+ * @param props - The component props
261
+ * @param ref - Forwarded ref to the root div element
262
+ * @returns JSX element containing the configurable node
263
+ *
264
+ * @example
265
+ * ```tsx
266
+ * // Basic node with inputs and outputs
267
+ * <ConfigurableNode
268
+ * name="Data Processor"
269
+ * headerColor="#C44536"
270
+ * inputs={[
271
+ * {
272
+ * id: 'input1',
273
+ * name: 'Text Input',
274
+ * type: 'string',
275
+ * handleColor: '#00BFFF',
276
+ * handleShape: 'circle',
277
+ * allowInput: true,
278
+ * },
279
+ * ]}
280
+ * outputs={[
281
+ * {
282
+ * id: 'output1',
283
+ * name: 'Result',
284
+ * type: 'string',
285
+ * handleColor: '#FECA57',
286
+ * handleShape: 'square',
287
+ * },
288
+ * ]}
289
+ * />
290
+ *
291
+ * // Node with collapsible panels
292
+ * <ConfigurableNode
293
+ * name="Advanced Node"
294
+ * headerColor="#2D5A87"
295
+ * inputs={[
296
+ * {
297
+ * id: 'direct-input',
298
+ * name: 'Direct Input',
299
+ * type: 'string',
300
+ * allowInput: true,
301
+ * },
302
+ * {
303
+ * id: 'settings-panel',
304
+ * name: 'Settings Panel',
305
+ * inputs: [
306
+ * {
307
+ * id: 'threshold',
308
+ * name: 'Threshold',
309
+ * type: 'number',
310
+ * handleShape: 'diamond',
311
+ * allowInput: true,
312
+ * },
313
+ * ],
314
+ * },
315
+ * ]}
316
+ * />
317
+ * ```
318
+ */
101
319
  export declare const ConfigurableNode: ForwardRefExoticComponent< {
320
+ /** Display name of the node */
102
321
  name?: string;
322
+ /** Background color of the node header */
103
323
  headerColor?: string;
324
+ /** Array of inputs and input panels */
104
325
  inputs?: (ConfigurableNodeInput | ConfigurableNodeInputPanel)[];
326
+ /** Array of output sockets */
105
327
  outputs?: ConfigurableNodeOutput[];
328
+ /** Whether the node is currently inside a ReactFlow context */
106
329
  isCurrentlyInsideReactFlow?: boolean;
330
+ /** Props for the node resizer component */
107
331
  nodeResizerProps?: NodeResizerWithMoreControlsProps;
108
332
  } & HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>>;
109
333
 
334
+ /**
335
+ * Configuration for a node input
336
+ *
337
+ * Defines an input socket on a node with optional interactive input component.
338
+ * Supports both string and number types with type-specific onChange handlers.
339
+ */
110
340
  export declare type ConfigurableNodeInput = {
341
+ /** Unique identifier for the input */
111
342
  id: string;
343
+ /** Display name for the input */
112
344
  name: string;
345
+ /** Color of the input handle/socket */
113
346
  handleColor?: string;
347
+ /** Shape of the input handle (circle, square, diamond, etc.) */
114
348
  handleShape?: HandleShape;
349
+ /** Whether to show an interactive input component when not connected */
115
350
  allowInput?: boolean;
116
351
  } & ({
352
+ /** String input type */
117
353
  type: 'string';
354
+ /** Current value of the input */
118
355
  value?: string;
356
+ /** Callback when the input value changes */
119
357
  onChange?: (value: string) => void;
120
358
  } | {
359
+ /** Number input type */
121
360
  type: 'number';
361
+ /** Current value of the input */
122
362
  value?: number;
363
+ /** Callback when the input value changes */
123
364
  onChange?: (value: number) => void;
124
365
  });
125
366
 
367
+ /**
368
+ * Configuration for a collapsible input panel
369
+ *
370
+ * Groups multiple inputs together in a collapsible panel for better organization.
371
+ */
126
372
  export declare type ConfigurableNodeInputPanel = {
373
+ /** Unique identifier for the panel */
127
374
  id: string;
375
+ /** Display name for the panel */
128
376
  name: string;
377
+ /** Array of inputs contained in this panel */
129
378
  inputs: ConfigurableNodeInput[];
130
379
  };
131
380
 
381
+ /**
382
+ * Configuration for a node output
383
+ *
384
+ * Defines an output socket on a node that can be connected to inputs.
385
+ */
132
386
  export declare type ConfigurableNodeOutput = {
387
+ /** Unique identifier for the output */
133
388
  id: string;
389
+ /** Display name for the output */
134
390
  name: string;
391
+ /** Color of the output handle/socket */
135
392
  handleColor?: string;
393
+ /** Shape of the output handle (circle, square, diamond, etc.) */
136
394
  handleShape?: HandleShape;
137
395
  } & ({
396
+ /** String output type */
138
397
  type: 'string';
139
398
  } | {
399
+ /** Number output type */
140
400
  type: 'number';
141
401
  });
142
402
 
403
+ /**
404
+ * Props for the ConfigurableNode component
405
+ *
406
+ * Defines the complete configuration for a customizable node with inputs, outputs,
407
+ * and optional panels. Supports both standalone usage and ReactFlow integration.
408
+ */
143
409
  export declare type ConfigurableNodeProps = {
410
+ /** Display name of the node */
144
411
  name?: string;
412
+ /** Background color of the node header */
145
413
  headerColor?: string;
414
+ /** Array of inputs and input panels */
146
415
  inputs?: (ConfigurableNodeInput | ConfigurableNodeInputPanel)[];
416
+ /** Array of output sockets */
147
417
  outputs?: ConfigurableNodeOutput[];
418
+ /** Whether the node is currently inside a ReactFlow context */
148
419
  isCurrentlyInsideReactFlow?: boolean;
420
+ /** Props for the node resizer component */
149
421
  nodeResizerProps?: NodeResizerWithMoreControlsProps;
150
422
  } & HTMLAttributes<HTMLDivElement>;
151
423
 
424
+ /**
425
+ * ReactFlow wrapper for the ConfigurableNode component
426
+ *
427
+ * This component wraps the ConfigurableNode for use within ReactFlow.
428
+ * It automatically sets the isCurrentlyInsideReactFlow prop to true and
429
+ * applies ReactFlow-specific styling and behavior.
430
+ *
431
+ * Features:
432
+ * - Automatic ReactFlow integration
433
+ * - Full-width styling for ReactFlow context
434
+ * - Proper handle and interaction setup
435
+ * - Node resizing controls
436
+ * - Connection management
437
+ *
438
+ * @param props - The component props
439
+ * @param ref - Forwarded ref to the node element
440
+ * @returns JSX element containing the wrapped configurable node
441
+ *
442
+ * @example
443
+ * ```tsx
444
+ * // Used as a node type in ReactFlow
445
+ * const nodeTypes = {
446
+ * configurableNode: ConfigurableNodeReactFlowWrapper,
447
+ * };
448
+ *
449
+ * <ReactFlow
450
+ * nodeTypes={nodeTypes}
451
+ * nodes={[
452
+ * {
453
+ * id: 'node1',
454
+ * type: 'configurableNode',
455
+ * position: { x: 100, y: 100 },
456
+ * data: {
457
+ * name: 'My Node',
458
+ * headerColor: '#C44536',
459
+ * inputs: [{ id: 'input1', name: 'Input', type: 'string' }],
460
+ * outputs: [{ id: 'output1', name: 'Output', type: 'string' }],
461
+ * },
462
+ * },
463
+ * ]}
464
+ * />
465
+ * ```
466
+ */
152
467
  export declare const ConfigurableNodeReactFlowWrapper: ForwardRefExoticComponent<Pick<ConfigurableNodeState, "data" | "id" | "width" | "height" | "sourcePosition" | "targetPosition" | "dragHandle" | "parentId"> & Required<Pick<ConfigurableNodeState, "type" | "draggable" | "dragging" | "zIndex" | "selectable" | "deletable" | "selected">> & {
153
468
  isConnectable: boolean;
154
469
  positionAbsoluteX: number;
155
470
  positionAbsoluteY: number;
156
471
  } & RefAttributes<HTMLDivElement>>;
157
472
 
473
+ /** Props for the ConfigurableNodeReactFlowWrapper component */
158
474
  export declare type ConfigurableNodeReactFlowWrapperProps = NodeProps<ConfigurableNodeState>;
159
475
 
476
+ /** State type for configurable nodes in ReactFlow */
160
477
  export declare type ConfigurableNodeState = Node_2<Omit<ConfigurableNodeProps, 'isCurrentlyInsideReactFlow'>, 'configurableNode'>;
161
478
 
479
+ /**
480
+ * A context-aware handle component for node inputs and outputs
481
+ *
482
+ * This component renders handles (connection points) for nodes with support for
483
+ * various shapes and automatic ReactFlow integration. It can render as either
484
+ * a ReactFlow Handle when inside a ReactFlow context or as a standalone element
485
+ * for preview purposes.
486
+ *
487
+ * Features:
488
+ * - 13+ custom handle shapes (circle, square, diamond, star, etc.)
489
+ * - Automatic ReactFlow integration
490
+ * - Custom colors and styling
491
+ * - Border support for clip-path shapes
492
+ * - Type-safe shape definitions
493
+ *
494
+ * @param props - The component props
495
+ * @param ref - Forwarded ref to the handle element
496
+ * @returns JSX element containing the handle
497
+ *
498
+ * @example
499
+ * ```tsx
500
+ * // Basic handle
501
+ * <ContextAwareHandle
502
+ * type="target"
503
+ * position={Position.Left}
504
+ * id="input1"
505
+ * color="#00BFFF"
506
+ * shape="circle"
507
+ * isCurrentlyInsideReactFlow={true}
508
+ * />
509
+ *
510
+ * // Custom shape handle
511
+ * <ContextAwareHandle
512
+ * type="source"
513
+ * position={Position.Right}
514
+ * id="output1"
515
+ * color="#FECA57"
516
+ * shape="diamond"
517
+ * isCurrentlyInsideReactFlow={true}
518
+ * />
519
+ *
520
+ * // Preview handle (outside ReactFlow)
521
+ * <ContextAwareHandle
522
+ * type="target"
523
+ * position={Position.Left}
524
+ * id="preview-input"
525
+ * color="#96CEB4"
526
+ * shape="star"
527
+ * isCurrentlyInsideReactFlow={false}
528
+ * />
529
+ * ```
530
+ */
162
531
  export declare const ContextAwareHandle: ForwardRefExoticComponent< {
532
+ /** Type of handle (source or target) */
163
533
  type: HandleType;
534
+ /** Position of the handle on the node */
164
535
  position: Position;
536
+ /** Unique identifier for the handle */
165
537
  id: string;
538
+ /** Color of the handle */
166
539
  color?: string;
540
+ /** Shape of the handle */
167
541
  shape?: HandleShape;
542
+ /** Whether the handle is currently inside a ReactFlow context */
168
543
  isCurrentlyInsideReactFlow?: boolean;
169
544
  } & HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>>;
170
545
 
546
+ /**
547
+ * Props for the ContextAwareHandle component
548
+ */
171
549
  export declare type ContextAwareHandleProps = {
550
+ /** Type of handle (source or target) */
172
551
  type: HandleType;
552
+ /** Position of the handle on the node */
173
553
  position: Position;
554
+ /** Unique identifier for the handle */
174
555
  id: string;
556
+ /** Color of the handle */
175
557
  color?: string;
558
+ /** Shape of the handle */
176
559
  shape?: HandleShape;
560
+ /** Whether the handle is currently inside a ReactFlow context */
177
561
  isCurrentlyInsideReactFlow?: boolean;
178
562
  } & HTMLAttributes<HTMLDivElement>;
179
563
 
564
+ /**
565
+ * Context-aware input component that handles both connected and unconnected inputs
566
+ *
567
+ * This component intelligently renders either a label (for connected inputs) or an
568
+ * input component (for unconnected inputs) based on the connection state. It uses
569
+ * the ReactFlow context to determine if an input is connected to other nodes.
570
+ *
571
+ * Features:
572
+ * - Automatically detects input connection state
573
+ * - Renders appropriate UI based on connection status
574
+ * - Integrates with ReactFlow's connection system
575
+ * - Supports both string and number input types
576
+ *
577
+ * @param props - The component props
578
+ * @returns JSX element containing either a label or input component
579
+ *
580
+ * @example
581
+ * ```tsx
582
+ * <ContextAwareInput
583
+ * input={{
584
+ * id: 'input1',
585
+ * name: 'Value',
586
+ * type: 'string',
587
+ * dataType: 'stringType',
588
+ * allowInput: true,
589
+ * value: 'Hello World',
590
+ * }}
591
+ * isCurrentlyInsideReactFlow={true}
592
+ * />
593
+ * ```
594
+ */
180
595
  export declare const ContextAwareInput: ({ input, isCurrentlyInsideReactFlow, }: ContextAwareInputProps) => JSX.Element;
181
596
 
597
+ /**
598
+ * Props for the ContextAwareInput component
599
+ */
182
600
  export declare type ContextAwareInputProps = {
601
+ /** The input configuration */
183
602
  input: ConfigurableNodeInput;
603
+ /** Whether the component is currently inside a ReactFlow context */
184
604
  isCurrentlyInsideReactFlow: boolean;
185
605
  };
186
606
 
607
+ /**
608
+ * A context menu component with nested submenu support
609
+ *
610
+ * This component provides a hierarchical context menu system with support for
611
+ * nested submenus, icons, keyboard shortcuts, and separators. It features
612
+ * hover-based submenu activation and Blender-inspired dark theme styling.
613
+ *
614
+ * Features:
615
+ * - Nested submenu support with unlimited depth
616
+ * - Icon and keyboard shortcut display
617
+ * - Separator lines for visual grouping
618
+ * - Hover-based submenu activation
619
+ * - Dark theme styling matching Blender's aesthetic
620
+ * - TypeScript support with full type safety
621
+ *
622
+ * @param props - The component props
623
+ * @returns JSX element containing the context menu
624
+ *
625
+ * @example
626
+ * ```tsx
627
+ * // Basic context menu
628
+ * <ContextMenu
629
+ * subItems={[
630
+ * {
631
+ * id: 'copy',
632
+ * label: 'Copy',
633
+ * icon: <CopyIcon className="w-4 h-4" />,
634
+ * shortcut: 'Ctrl+C',
635
+ * onClick: () => handleCopy(),
636
+ * },
637
+ * {
638
+ * id: 'paste',
639
+ * label: 'Paste',
640
+ * icon: <PasteIcon className="w-4 h-4" />,
641
+ * shortcut: 'Ctrl+V',
642
+ * onClick: () => handlePaste(),
643
+ * separator: true,
644
+ * },
645
+ * ]}
646
+ * />
647
+ *
648
+ * // Nested submenu
649
+ * <ContextMenu
650
+ * subItems={[
651
+ * {
652
+ * id: 'edit',
653
+ * label: 'Edit',
654
+ * icon: <EditIcon className="w-4 h-4" />,
655
+ * subItems: [
656
+ * {
657
+ * id: 'cut',
658
+ * label: 'Cut',
659
+ * onClick: () => handleCut(),
660
+ * },
661
+ * {
662
+ * id: 'copy',
663
+ * label: 'Copy',
664
+ * onClick: () => handleCopy(),
665
+ * },
666
+ * {
667
+ * id: 'paste',
668
+ * label: 'Paste',
669
+ * onClick: () => handlePaste(),
670
+ * },
671
+ * ],
672
+ * },
673
+ * ]}
674
+ * />
675
+ * ```
676
+ */
187
677
  export declare const ContextMenu: ({ subItems, className, onItemClick, }: ContextMenuProps) => JSX.Element;
188
678
 
679
+ /**
680
+ * Configuration for a context menu item
681
+ *
682
+ * Defines a single item in the context menu with optional submenu, icon, and actions.
683
+ * Supports nested submenus for hierarchical menu structures.
684
+ */
189
685
  export declare type ContextMenuItem = {
686
+ /** Unique identifier for the menu item */
190
687
  id: string;
688
+ /** Display text for the menu item */
191
689
  label: string;
690
+ /** Optional icon to display next to the label */
192
691
  icon?: ReactNode;
692
+ /** Optional array of submenu items for nested menus */
193
693
  subItems?: ContextMenuItem[];
694
+ /** Callback function when the item is clicked */
194
695
  onClick?: () => void;
696
+ /** Optional keyboard shortcut text to display */
195
697
  shortcut?: string;
698
+ /** Whether to show a separator line before this item */
196
699
  separator?: boolean;
197
700
  };
198
701
 
702
+ /**
703
+ * Props for the ContextMenu component
704
+ */
199
705
  export declare type ContextMenuProps = {
706
+ /** Array of menu items to display */
200
707
  subItems: ContextMenuItem[];
708
+ /** Additional CSS classes */
201
709
  className?: string;
710
+ /** Optional callback when any item is clicked */
202
711
  onItemClick?: (item: ContextMenuItem) => void;
203
712
  };
204
713
 
@@ -212,8 +721,13 @@ export declare type ContextMenuProps = {
212
721
  */
213
722
  export declare function convertStringToNumber(inputNumberAsString: string): number;
214
723
 
724
+ /**
725
+ * Represents a 2D coordinate point
726
+ */
215
727
  export declare type Coordinate = {
728
+ /** X coordinate */
216
729
  x: number;
730
+ /** Y coordinate */
217
731
  y: number;
218
732
  };
219
733
 
@@ -239,33 +753,159 @@ export declare type CreateNodeContextMenuProps<DataTypeUniqueId extends string =
239
753
  contextMenuPosition: XYPosition;
240
754
  };
241
755
 
756
+ /**
757
+ * Definition of a data type in the graph system
758
+ *
759
+ * @template UnderlyingType - The underlying type of the data
760
+ * @template ComplexSchemaType - Zod schema type for complex data types
761
+ */
242
762
  declare type DataType<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = UnderlyingType extends 'complex' ? {
763
+ /** Display name of the data type */
243
764
  name: string;
765
+ /** The underlying type of the data */
244
766
  underlyingType: UnderlyingType;
767
+ /** Zod schema for complex data validation */
245
768
  complexSchema: ComplexSchemaType;
769
+ /** Color used for visual representation */
246
770
  color: string;
247
771
  } : {
772
+ /** Display name of the data type */
248
773
  name: string;
774
+ /** The underlying type of the data */
249
775
  underlyingType: UnderlyingType;
776
+ /** Complex schema is not used for non-complex types */
250
777
  complexSchema?: undefined;
778
+ /** Color used for visual representation */
251
779
  color: string;
252
780
  };
253
781
 
782
+ /**
783
+ * Array of edge changes for ReactFlow
784
+ */
254
785
  export declare type EdgeChanges = EdgeChange<ConfigurableEdgeState>[];
255
786
 
787
+ /**
788
+ * Array of configurable edges in the graph
789
+ */
256
790
  export declare type Edges = ConfigurableEdgeState[];
257
791
 
792
+ /**
793
+ * Main graph editor component inspired by Blender's node editor
794
+ *
795
+ * This is the primary component for creating interactive node-based graph editors.
796
+ * It provides a complete ReactFlow-based interface with custom nodes, edges, and
797
+ * context menu functionality for adding new nodes.
798
+ *
799
+ * Features:
800
+ * - Pan, zoom, and select nodes with intuitive controls
801
+ * - Drag and drop node connections
802
+ * - Right-click context menu for adding new nodes
803
+ * - Custom node types with configurable inputs and outputs
804
+ * - Real-time node manipulation and state management
805
+ *
806
+ * @template DataTypeUniqueId - Unique identifier type for data types
807
+ * @template NodeTypeUniqueId - Unique identifier type for node types
808
+ * @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
809
+ * @template ComplexSchemaType - Zod schema type for complex data types
810
+ * @param props - The component props
811
+ * @returns JSX element containing the complete graph editor
812
+ *
813
+ * @example
814
+ * ```tsx
815
+ * import {
816
+ * FullGraph,
817
+ * useFullGraph,
818
+ * makeStateWithAutoInfer,
819
+ * makeNodeIdToNodeTypeWithAutoInfer,
820
+ * makeTypeOfNodeWithAutoInfer,
821
+ * makeDataTypeWithAutoInfer
822
+ * } from 'react-blender-nodes';
823
+ *
824
+ * function MyNodeEditor() {
825
+ * // Define data types with auto-infer for type safety
826
+ * const dataTypes = {
827
+ * stringType: makeDataTypeWithAutoInfer({
828
+ * name: 'String',
829
+ * underlyingType: 'string',
830
+ * color: '#4A90E2',
831
+ * }),
832
+ * numberType: makeDataTypeWithAutoInfer({
833
+ * name: 'Number',
834
+ * underlyingType: 'number',
835
+ * color: '#E74C3C',
836
+ * }),
837
+ * };
838
+ *
839
+ * // Define node types with auto-infer for type safety
840
+ * const typeOfNodes = {
841
+ * inputNode: makeTypeOfNodeWithAutoInfer({
842
+ * name: 'Input Node',
843
+ * headerColor: '#C44536',
844
+ * inputs: [
845
+ * { name: 'Input', dataType: 'stringType', allowInput: true }
846
+ * ],
847
+ * outputs: [
848
+ * { name: 'Output', dataType: 'stringType' }
849
+ * ],
850
+ * }),
851
+ * outputNode: makeTypeOfNodeWithAutoInfer({
852
+ * name: 'Output Node',
853
+ * headerColor: '#2D5A87',
854
+ * inputs: [
855
+ * { name: 'Input', dataType: 'stringType' }
856
+ * ],
857
+ * outputs: [],
858
+ * }),
859
+ * };
860
+ *
861
+ * // Define node ID to type mapping with auto-infer
862
+ * const nodeIdToNodeType = makeNodeIdToNodeTypeWithAutoInfer({
863
+ * 'node-1': 'inputNode',
864
+ * 'node-2': 'outputNode',
865
+ * });
866
+ *
867
+ * // Create state with auto-infer for complete type safety
868
+ * const initialState = makeStateWithAutoInfer({
869
+ * dataTypes,
870
+ * typeOfNodes,
871
+ * nodeIdToNodeType,
872
+ * nodes: [],
873
+ * edges: [],
874
+ * });
875
+ *
876
+ * const { state, dispatch } = useFullGraph(initialState);
877
+ *
878
+ * return (
879
+ * <div style={{ height: '600px', width: '100%' }}>
880
+ * <FullGraph state={state} dispatch={dispatch} />
881
+ * </div>
882
+ * );
883
+ * }
884
+ * ```
885
+ */
258
886
  export declare function FullGraph<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never>({ state, dispatch, }: FullGraphProps<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>): JSX.Element;
259
887
 
888
+ /**
889
+ * Props for the FullGraph component
890
+ *
891
+ * @template DataTypeUniqueId - Unique identifier type for data types
892
+ * @template NodeTypeUniqueId - Unique identifier type for node types
893
+ * @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
894
+ * @template ComplexSchemaType - Zod schema type for complex data types
895
+ */
260
896
  export declare type FullGraphProps<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = {
897
+ /** The current state of the graph including nodes, edges, and type definitions */
261
898
  state: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>;
899
+ /** Dispatch function for updating the graph state */
262
900
  dispatch: ActionDispatch<[
263
901
  action: Action<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>
264
902
  ]>;
265
903
  };
266
904
 
905
+ /** Type representing all available handle shapes */
267
906
  export declare type HandleShape = (typeof handleShapesMap)[keyof typeof handleShapesMap];
268
907
 
908
+ /** Map of handle shapes for type-safe access */
269
909
  export declare const handleShapesMap: {
270
910
  readonly circle: "circle";
271
911
  readonly square: "square";
@@ -345,51 +985,146 @@ export declare type InputProps = {
345
985
  numberOfDecimals?: never;
346
986
  });
347
987
 
988
+ /**
989
+ * Checks if a coordinate point is within a bounding box
990
+ *
991
+ * @param coordinate - The coordinate point to check
992
+ * @param box - The bounding box to check against
993
+ * @param xAxisInclusive - Whether the x-axis boundaries are inclusive (default: false)
994
+ * @param yAxisInclusive - Whether the y-axis boundaries are inclusive (default: false)
995
+ * @returns True if the coordinate is within the box, false otherwise
996
+ *
997
+ * @example
998
+ * ```tsx
999
+ * const point = { x: 50, y: 50 };
1000
+ * const box = { top: 0, left: 0, right: 100, bottom: 100 };
1001
+ *
1002
+ * isCoordinateInBox(point, box) // true
1003
+ * isCoordinateInBox({ x: 0, y: 0 }, box, true, true) // true (inclusive)
1004
+ * isCoordinateInBox({ x: 100, y: 100 }, box) // false (exclusive)
1005
+ * ```
1006
+ */
348
1007
  export declare function isCoordinateInBox(coordinate: Coordinate, box: Box, xAxisInclusive?: boolean, yAxisInclusive?: boolean): boolean;
349
1008
 
1009
+ /**
1010
+ * Checks if a number is within a specified range
1011
+ *
1012
+ * @param number - The number to check
1013
+ * @param min - The minimum value of the range
1014
+ * @param max - The maximum value of the range
1015
+ * @param minInclusive - Whether the minimum value is inclusive (default: false)
1016
+ * @param maxInclusive - Whether the maximum value is inclusive (default: false)
1017
+ * @returns True if the number is within the range, false otherwise
1018
+ *
1019
+ * @example
1020
+ * ```tsx
1021
+ * isNumberInRange(5, 1, 10) // true (5 is between 1 and 10, exclusive)
1022
+ * isNumberInRange(1, 1, 10, true) // true (1 is included)
1023
+ * isNumberInRange(10, 1, 10, false, true) // true (10 is included)
1024
+ * isNumberInRange(0, 1, 10) // false (0 is below range)
1025
+ * ```
1026
+ */
350
1027
  export declare function isNumberInRange(number: number, min: number, max: number, minInclusive?: boolean, maxInclusive?: boolean): boolean;
351
1028
 
1029
+ /**
1030
+ * Array of node changes for ReactFlow
1031
+ */
352
1032
  export declare type NodeChanges = NodeChange<ConfigurableNodeState>[];
353
1033
 
1034
+ /**
1035
+ * Mapping from node IDs to their node types
1036
+ *
1037
+ * @template NodeTypeUniqueId - Unique identifier type for node types
1038
+ */
354
1039
  declare type NodeIdToNodeType<NodeTypeUniqueId extends string = string> = Record<string, NodeTypeUniqueId>;
355
1040
 
356
1041
  /**
357
- * The `<NodeResizer />` component can be used to add a resize functionality to your
358
- * nodes. It renders draggable controls around the node to resize in all directions.
359
- * @public
1042
+ * Enhanced node resizer component with customizable controls
1043
+ *
1044
+ * This component extends the standard ReactFlow NodeResizer with additional
1045
+ * customization options for line and handle positions. It provides fine-grained
1046
+ * control over which resize controls are displayed and how they behave.
1047
+ *
1048
+ * Features:
1049
+ * - Customizable line and handle positions
1050
+ * - Direction-specific resize controls
1051
+ * - Min/max width and height constraints
1052
+ * - Aspect ratio preservation
1053
+ * - Auto-scaling support
1054
+ * - Custom styling options
1055
+ *
1056
+ * @param props - The component props
1057
+ * @returns JSX element containing the node resizer controls
360
1058
  *
361
1059
  * @example
362
- *```jsx
363
- *import { memo } from 'react';
364
- *import { Handle, Position, NodeResizer } from '@xyflow/react';
365
- *
366
- *function ResizableNode({ data }) {
367
- * return (
368
- * <>
369
- * <NodeResizer minWidth={100} minHeight={30} />
370
- * <Handle type="target" position={Position.Left} />
371
- * <div style={{ padding: 10 }}>{data.label}</div>
372
- * <Handle type="source" position={Position.Right} />
373
- * </>
374
- * );
375
- *};
376
- *
377
- *export default memo(ResizableNode);
378
- *```
1060
+ * ```tsx
1061
+ * // Basic resizer with default controls
1062
+ * <NodeResizerWithMoreControls
1063
+ * minWidth={100}
1064
+ * minHeight={50}
1065
+ * maxWidth={500}
1066
+ * maxHeight={300}
1067
+ * />
1068
+ *
1069
+ * // Custom line positions only
1070
+ * <NodeResizerWithMoreControls
1071
+ * linePosition={['left', 'right']}
1072
+ * minWidth={100}
1073
+ * minHeight={50}
1074
+ * />
1075
+ *
1076
+ * // Custom handle positions
1077
+ * <NodeResizerWithMoreControls
1078
+ * handlePosition={['top-left', 'bottom-right']}
1079
+ * minWidth={100}
1080
+ * minHeight={50}
1081
+ * />
1082
+ *
1083
+ * // Horizontal-only resizing
1084
+ * <NodeResizerWithMoreControls
1085
+ * resizeDirection="horizontal"
1086
+ * linePosition={['left', 'right']}
1087
+ * minWidth={100}
1088
+ * maxWidth={500}
1089
+ * />
1090
+ * ```
379
1091
  */
380
1092
  export declare function NodeResizerWithMoreControls({ nodeId, isVisible, handleClassName, handleStyle, lineClassName, lineStyle, color, minWidth, minHeight, maxWidth, maxHeight, keepAspectRatio, autoScale, shouldResize, onResizeStart, onResize, onResizeEnd, linePosition, handlePosition, resizeDirection, }: NodeResizerWithMoreControlsProps): JSX.Element | null;
381
1093
 
1094
+ /**
1095
+ * Props for the NodeResizerWithMoreControls component
1096
+ */
382
1097
  export declare type NodeResizerWithMoreControlsProps = NodeResizerProps & {
1098
+ /** Array of line positions for resize controls */
383
1099
  linePosition?: ControlLinePosition[];
1100
+ /** Array of handle positions for resize controls */
384
1101
  handlePosition?: ControlPosition[];
1102
+ /** Direction of resize operation */
385
1103
  resizeDirection?: ResizeControlDirection;
386
1104
  };
387
1105
 
1106
+ /**
1107
+ * Array of configurable nodes in the graph
1108
+ */
388
1109
  export declare type Nodes = ConfigurableNodeState[];
389
1110
 
1111
+ /**
1112
+ * ReactFlow-aware input component that automatically updates node data
1113
+ *
1114
+ * This component renders the appropriate input component (Input or SliderNumberInput)
1115
+ * and automatically updates the ReactFlow node data when values change. It integrates
1116
+ * with the ReactFlow context to maintain state consistency.
1117
+ *
1118
+ * @param props - The component props
1119
+ * @returns JSX element containing the appropriate input component
1120
+ */
390
1121
  export declare const ReactFlowAwareInput: ({ input }: ReactFlowAwareInputProps) => JSX.Element;
391
1122
 
1123
+ /**
1124
+ * Props for the ReactFlowAwareInput component
1125
+ */
392
1126
  export declare type ReactFlowAwareInputProps = {
1127
+ /** The input configuration */
393
1128
  input: ConfigurableNodeInput;
394
1129
  };
395
1130
 
@@ -401,48 +1136,198 @@ export declare type ReactFlowAwareInputProps = {
401
1136
  */
402
1137
  export declare function sanitizeNumberToShowAsText(value: number, numberOfDecimals: number): string;
403
1138
 
1139
+ /**
1140
+ * A combined slider and number input component with drag functionality
1141
+ *
1142
+ * This component provides an intuitive way to input and adjust numeric values
1143
+ * through both dragging and direct input. It features a slider interface with
1144
+ * increment/decrement buttons and switches to a text input when clicked.
1145
+ *
1146
+ * Features:
1147
+ * - Drag-to-adjust functionality with visual feedback
1148
+ * - Increment/decrement buttons for precise control
1149
+ * - Click-to-edit mode with text input
1150
+ * - Min/max value constraints
1151
+ * - Customizable step size
1152
+ * - Blender-inspired dark theme styling
1153
+ *
1154
+ * @param props - The component props
1155
+ * @param ref - Forwarded ref to the component
1156
+ * @returns JSX element containing the slider number input
1157
+ *
1158
+ * @example
1159
+ * ```tsx
1160
+ * // Basic usage
1161
+ * <SliderNumberInput
1162
+ * name="Price"
1163
+ * value={10.5}
1164
+ * onChange={(value) => setPrice(value)}
1165
+ * />
1166
+ *
1167
+ * // With constraints
1168
+ * <SliderNumberInput
1169
+ * name="Temperature"
1170
+ * value={25}
1171
+ * min={0}
1172
+ * max={100}
1173
+ * step={0.5}
1174
+ * onChange={(value) => setTemperature(value)}
1175
+ * />
1176
+ *
1177
+ * // Controlled component
1178
+ * const [value, setValue] = useState(42);
1179
+ * <SliderNumberInput
1180
+ * name="Count"
1181
+ * value={value}
1182
+ * onChange={setValue}
1183
+ * min={0}
1184
+ * max={1000}
1185
+ * />
1186
+ * ```
1187
+ */
404
1188
  export declare const SliderNumberInput: ForwardRefExoticComponent<SliderNumberInputProps & RefAttributes<HTMLInputElement & HTMLDivElement>>;
405
1189
 
1190
+ /**
1191
+ * Props for the SliderNumberInput component
1192
+ */
406
1193
  export declare type SliderNumberInputProps = {
1194
+ /** Display name for the input */
407
1195
  name?: string;
1196
+ /** Current numeric value */
408
1197
  value?: number;
1198
+ /** Callback when the value changes */
409
1199
  onChange?: (value: number) => void;
1200
+ /** Additional CSS classes */
410
1201
  className?: string;
1202
+ /** Minimum allowed value */
411
1203
  min?: number;
1204
+ /** Maximum allowed value */
412
1205
  max?: number;
1206
+ /** Step size for value changes */
413
1207
  step?: number;
414
1208
  };
415
1209
 
1210
+ /**
1211
+ * Complete state definition for the graph system
1212
+ *
1213
+ * @template DataTypeUniqueId - Unique identifier type for data types
1214
+ * @template NodeTypeUniqueId - Unique identifier type for node types
1215
+ * @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
1216
+ * @template ComplexSchemaType - Zod schema type for complex data types
1217
+ */
416
1218
  declare type State<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = {
1219
+ /** Map of data type definitions */
417
1220
  dataTypes: Record<DataTypeUniqueId, DataType<UnderlyingType, ComplexSchemaType>>;
1221
+ /** Map of node type definitions */
418
1222
  typeOfNodes: Record<NodeTypeUniqueId, TypeOfNode<DataTypeUniqueId>>;
1223
+ /** Array of nodes in the graph */
419
1224
  nodes: Nodes;
1225
+ /** Mapping from node IDs to their types */
420
1226
  nodeIdToNodeType: NodeIdToNodeType<NodeTypeUniqueId>;
1227
+ /** Array of edges in the graph */
421
1228
  edges: Edges;
422
1229
  };
423
1230
 
1231
+ /**
1232
+ * Union type of all supported underlying data types
1233
+ */
424
1234
  declare type SupportedUnderlyingTypes = (typeof supportedUnderlyingTypes)[number];
425
1235
 
1236
+ /**
1237
+ * Array of supported underlying data types
1238
+ */
426
1239
  declare const supportedUnderlyingTypes: readonly ["string", "number", "complex", "noEquivalent", "inferFromConnection"];
427
1240
 
1241
+ /**
1242
+ * Definition of an input type in a node
1243
+ *
1244
+ * @template DataTypeUniqueId - Unique identifier type for data types
1245
+ */
428
1246
  declare type TypeOfInput<DataTypeUniqueId extends string = string> = {
1247
+ /** Display name of the input */
429
1248
  name: string;
1249
+ /** The data type identifier this input uses */
430
1250
  dataType: DataTypeUniqueId;
1251
+ /** Whether this input allows direct user input */
431
1252
  allowInput?: boolean;
432
1253
  };
433
1254
 
1255
+ /**
1256
+ * Definition of an input panel type in a node
1257
+ *
1258
+ * @template DataTypeUniqueId - Unique identifier type for data types
1259
+ */
434
1260
  declare type TypeOfInputPanel<DataTypeUniqueId extends string = string> = {
1261
+ /** Display name of the input panel */
435
1262
  name: string;
1263
+ /** Array of inputs within this panel */
436
1264
  inputs: TypeOfInput<DataTypeUniqueId>[];
437
1265
  };
438
1266
 
1267
+ /**
1268
+ * Definition of a node type in the graph system
1269
+ *
1270
+ * @template DataTypeUniqueId - Unique identifier type for data types
1271
+ */
439
1272
  declare type TypeOfNode<DataTypeUniqueId extends string = string> = {
1273
+ /** Display name of the node type */
440
1274
  name: string;
1275
+ /** Color used for the node header */
441
1276
  headerColor?: string;
1277
+ /** Array of inputs (can be regular inputs or input panels) */
442
1278
  inputs: (TypeOfInput<DataTypeUniqueId> | TypeOfInputPanel<DataTypeUniqueId>)[];
1279
+ /** Array of outputs */
443
1280
  outputs: TypeOfInput<DataTypeUniqueId>[];
444
1281
  };
445
1282
 
1283
+ /**
1284
+ * Custom hook for detecting clicks outside of a specified element
1285
+ *
1286
+ * This hook provides functionality to detect when a user clicks outside of a
1287
+ * specified element, commonly used for closing dropdowns, modals, or other
1288
+ * overlay components.
1289
+ *
1290
+ * @template T - The type of HTML element being referenced
1291
+ * @param ref - Reference to the element to monitor (can be RefObject or direct element)
1292
+ * @param callback - Function to call when a click outside is detected
1293
+ * @param checkDescendants - Whether to check if the click target is a descendant of the ref element (default: true)
1294
+ * @param checkCoordinates - Whether to use coordinate-based checking instead of DOM hierarchy (default: false)
1295
+ *
1296
+ * @example
1297
+ * ```tsx
1298
+ * function Dropdown() {
1299
+ * const [isOpen, setIsOpen] = useState(false);
1300
+ * const dropdownRef = useRef<HTMLDivElement>(null);
1301
+ *
1302
+ * useClickedOutside(dropdownRef, () => {
1303
+ * setIsOpen(false);
1304
+ * });
1305
+ *
1306
+ * return (
1307
+ * <div ref={dropdownRef}>
1308
+ * {isOpen && <div>Dropdown content</div>}
1309
+ * </div>
1310
+ * );
1311
+ * }
1312
+ * ```
1313
+ *
1314
+ * @example
1315
+ * ```tsx
1316
+ * // Using coordinate-based checking for more precise control
1317
+ * function Modal() {
1318
+ * const modalRef = useRef<HTMLDivElement>(null);
1319
+ *
1320
+ * useClickedOutside(
1321
+ * modalRef,
1322
+ * () => closeModal(),
1323
+ * false, // Don't check descendants
1324
+ * true // Use coordinate checking
1325
+ * );
1326
+ *
1327
+ * return <div ref={modalRef}>Modal content</div>;
1328
+ * }
1329
+ * ```
1330
+ */
446
1331
  export declare function useClickedOutside<T extends HTMLElement>(ref: RefObject<T | null> | T | null, callback: () => void, checkDescendants?: boolean, checkCoordinates?: boolean): void;
447
1332
 
448
1333
  /**
@@ -493,6 +1378,81 @@ export declare type UseDragReturn = {
493
1378
  dragRef: (element: HTMLElement | null) => void;
494
1379
  };
495
1380
 
1381
+ /**
1382
+ * Custom hook for managing the full graph state with reducer
1383
+ *
1384
+ * This hook provides state management for the entire graph including nodes, edges,
1385
+ * data types, and node type definitions. It uses a reducer pattern for predictable
1386
+ * state updates.
1387
+ *
1388
+ * @template DataTypeUniqueId - Unique identifier type for data types
1389
+ * @template NodeTypeUniqueId - Unique identifier type for node types
1390
+ * @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
1391
+ * @template ComplexSchemaType - Zod schema type for complex data types
1392
+ * @param initialState - The initial state of the graph
1393
+ * @returns Object containing the current state and dispatch function
1394
+ *
1395
+ * @example
1396
+ * ```tsx
1397
+ * import {
1398
+ * useFullGraph,
1399
+ * makeStateWithAutoInfer,
1400
+ * makeNodeIdToNodeTypeWithAutoInfer,
1401
+ * makeTypeOfNodeWithAutoInfer,
1402
+ * makeDataTypeWithAutoInfer
1403
+ * } from 'react-blender-nodes';
1404
+ *
1405
+ * // Define data types with auto-infer for type safety
1406
+ * const dataTypes = {
1407
+ * stringType: makeDataTypeWithAutoInfer({
1408
+ * name: 'String',
1409
+ * underlyingType: 'string',
1410
+ * color: '#4A90E2',
1411
+ * }),
1412
+ * numberType: makeDataTypeWithAutoInfer({
1413
+ * name: 'Number',
1414
+ * underlyingType: 'number',
1415
+ * color: '#E74C3C',
1416
+ * }),
1417
+ * };
1418
+ *
1419
+ * // Define node types with auto-infer for type safety
1420
+ * const typeOfNodes = {
1421
+ * inputNode: makeTypeOfNodeWithAutoInfer({
1422
+ * name: 'Input Node',
1423
+ * headerColor: '#C44536',
1424
+ * inputs: [
1425
+ * { name: 'Input', dataType: 'stringType', allowInput: true }
1426
+ * ],
1427
+ * outputs: [
1428
+ * { name: 'Output', dataType: 'stringType' }
1429
+ * ],
1430
+ * }),
1431
+ * };
1432
+ *
1433
+ * // Define node ID to type mapping with auto-infer
1434
+ * const nodeIdToNodeType = makeNodeIdToNodeTypeWithAutoInfer({
1435
+ * 'node-1': 'inputNode',
1436
+ * });
1437
+ *
1438
+ * // Create state with auto-infer for complete type safety
1439
+ * const initialState = makeStateWithAutoInfer({
1440
+ * dataTypes,
1441
+ * typeOfNodes,
1442
+ * nodeIdToNodeType,
1443
+ * nodes: [],
1444
+ * edges: [],
1445
+ * });
1446
+ *
1447
+ * const { state, dispatch } = useFullGraph(initialState);
1448
+ *
1449
+ * // Add a new node (type-safe!)
1450
+ * dispatch({
1451
+ * type: 'ADD_NODE',
1452
+ * payload: { type: 'inputNode', position: { x: 100, y: 100 } },
1453
+ * });
1454
+ * ```
1455
+ */
496
1456
  export declare function useFullGraph<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never>(initialState: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>): {
497
1457
  state: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>;
498
1458
  dispatch: ActionDispatch<[action: Action<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>]>;