@theclearsky/react-blender-nodes 0.0.1 → 0.0.3
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/README.md +276 -114
- package/dist/index.d.ts +1384 -30
- package/dist/react-blender-nodes.css +1 -1
- package/dist/react-blender-nodes.es.js +2532 -2492
- package/dist/react-blender-nodes.es.js.map +1 -1
- package/dist/react-blender-nodes.umd.js +20 -20
- package/dist/react-blender-nodes.umd.js.map +1 -1
- package/package.json +6 -1
package/dist/index.d.ts
CHANGED
|
@@ -27,37 +27,59 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
27
27
|
import { XYPosition } from '@xyflow/react';
|
|
28
28
|
import { z } from 'zod';
|
|
29
29
|
|
|
30
|
-
|
|
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
|
+
*/
|
|
38
|
+
export 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
|
|
|
60
|
-
|
|
81
|
+
/** Map of action types for type-safe action dispatching */
|
|
82
|
+
export declare const actionTypesMap: {
|
|
61
83
|
readonly ADD_NODE: "ADD_NODE";
|
|
62
84
|
readonly UPDATE_NODE_BY_REACT_FLOW: "UPDATE_NODE_BY_REACT_FLOW";
|
|
63
85
|
readonly UPDATE_EDGES_BY_REACT_FLOW: "UPDATE_EDGES_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,9 +158,76 @@ 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
|
|
|
88
|
-
|
|
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
|
+
*/
|
|
230
|
+
export declare const ConfigurableEdge: ForwardRefExoticComponent<Pick<ConfigurableEdgeState, "data" | "source" | "style" | "id" | "selectable" | "deletable" | "selected" | "target" | "animated"> & EdgePosition & EdgeLabelOptions & {
|
|
89
231
|
sourceHandleId?: string | null;
|
|
90
232
|
targetHandleId?: string | null;
|
|
91
233
|
markerStart?: string;
|
|
@@ -94,111 +236,629 @@ 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
|
+
* Constructs a ConfigurableNodeInput or ConfigurableNodeOutput from a type definition
|
|
481
|
+
*
|
|
482
|
+
* This function creates the appropriate input or output instance based on the data type's
|
|
483
|
+
* underlying type (string or number). It generates a unique ID and applies the correct
|
|
484
|
+
* configuration including handle color and input allowance.
|
|
485
|
+
*
|
|
486
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
487
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
488
|
+
* @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
|
|
489
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
490
|
+
* @param typeOfDataType - The type definition for the input or output
|
|
491
|
+
* @param dataTypes - Map of data type definitions
|
|
492
|
+
* @returns Constructed input or output instance
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* ```tsx
|
|
496
|
+
* import {
|
|
497
|
+
* constructInputOrOutputOfType,
|
|
498
|
+
* makeDataTypeWithAutoInfer
|
|
499
|
+
* } from 'react-blender-nodes';
|
|
500
|
+
*
|
|
501
|
+
* // Define data types with auto-infer for type safety
|
|
502
|
+
* const dataTypes = {
|
|
503
|
+
* stringType: makeDataTypeWithAutoInfer({
|
|
504
|
+
* name: 'String',
|
|
505
|
+
* underlyingType: 'string',
|
|
506
|
+
* color: '#4A90E2',
|
|
507
|
+
* }),
|
|
508
|
+
* };
|
|
509
|
+
*
|
|
510
|
+
* // Construct input with type safety
|
|
511
|
+
* const input = constructInputOrOutputOfType(
|
|
512
|
+
* { name: 'Value', dataType: 'stringType', allowInput: true },
|
|
513
|
+
* dataTypes
|
|
514
|
+
* );
|
|
515
|
+
* ```
|
|
516
|
+
*/
|
|
517
|
+
export declare function constructInputOrOutputOfType<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never>(typeOfDataType: TypeOfInput<DataTypeUniqueId> | TypeOfNode<DataTypeUniqueId>['outputs'][number], dataTypes: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>['dataTypes']): ConfigurableNodeInput | ConfigurableNodeOutput;
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Constructs a ConfigurableNodeInputPanel from a type definition
|
|
521
|
+
*
|
|
522
|
+
* This function creates an input panel with multiple inputs based on the panel type
|
|
523
|
+
* definition. It generates a unique panel ID and constructs all the inputs within
|
|
524
|
+
* the panel using the constructInputOrOutputOfType function.
|
|
525
|
+
*
|
|
526
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
527
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
528
|
+
* @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
|
|
529
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
530
|
+
* @param typeOfPanel - The type definition for the input panel
|
|
531
|
+
* @param dataTypes - Map of data type definitions
|
|
532
|
+
* @returns Constructed input panel instance
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
* ```tsx
|
|
536
|
+
* import {
|
|
537
|
+
* constructInputPanelOfType,
|
|
538
|
+
* makeDataTypeWithAutoInfer
|
|
539
|
+
* } from 'react-blender-nodes';
|
|
540
|
+
*
|
|
541
|
+
* // Define data types with auto-infer for type safety
|
|
542
|
+
* const dataTypes = {
|
|
543
|
+
* numberType: makeDataTypeWithAutoInfer({
|
|
544
|
+
* name: 'Number',
|
|
545
|
+
* underlyingType: 'number',
|
|
546
|
+
* color: '#E74C3C',
|
|
547
|
+
* }),
|
|
548
|
+
* };
|
|
549
|
+
*
|
|
550
|
+
* // Construct panel with type safety
|
|
551
|
+
* const panel = constructInputPanelOfType(
|
|
552
|
+
* {
|
|
553
|
+
* name: 'Settings',
|
|
554
|
+
* inputs: [
|
|
555
|
+
* { name: 'Width', dataType: 'numberType' },
|
|
556
|
+
* { name: 'Height', dataType: 'numberType' }
|
|
557
|
+
* ]
|
|
558
|
+
* },
|
|
559
|
+
* dataTypes
|
|
560
|
+
* );
|
|
561
|
+
* ```
|
|
562
|
+
*/
|
|
563
|
+
export declare function constructInputPanelOfType<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never>(typeOfPanel: {
|
|
564
|
+
name: string;
|
|
565
|
+
inputs: {
|
|
566
|
+
name: string;
|
|
567
|
+
dataType: DataTypeUniqueId;
|
|
568
|
+
}[];
|
|
569
|
+
}, dataTypes: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>['dataTypes']): ConfigurableNodeInputPanel;
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Constructs a complete node from a node type definition
|
|
573
|
+
*
|
|
574
|
+
* This function creates a fully configured ReactFlow node based on the node type
|
|
575
|
+
* definition. It processes all inputs (including panels) and outputs, generates
|
|
576
|
+
* unique IDs, and sets up the node with the correct position and configuration.
|
|
577
|
+
*
|
|
578
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
579
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
580
|
+
* @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
|
|
581
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
582
|
+
* @param dataTypes - Map of data type definitions
|
|
583
|
+
* @param nodeType - The unique identifier of the node type
|
|
584
|
+
* @param typeOfNodes - Map of node type definitions
|
|
585
|
+
* @param nodeId - Unique identifier for the new node instance
|
|
586
|
+
* @param position - Position where the node should be placed
|
|
587
|
+
* @returns Complete ReactFlow node instance
|
|
588
|
+
*
|
|
589
|
+
* @example
|
|
590
|
+
* ```tsx
|
|
591
|
+
* import {
|
|
592
|
+
* constructNodeOfType,
|
|
593
|
+
* makeStateWithAutoInfer,
|
|
594
|
+
* makeNodeIdToNodeTypeWithAutoInfer,
|
|
595
|
+
* makeTypeOfNodeWithAutoInfer,
|
|
596
|
+
* makeDataTypeWithAutoInfer
|
|
597
|
+
* } from 'react-blender-nodes';
|
|
598
|
+
*
|
|
599
|
+
* // Define data types with auto-infer for type safety
|
|
600
|
+
* const dataTypes = {
|
|
601
|
+
* stringType: makeDataTypeWithAutoInfer({
|
|
602
|
+
* name: 'String',
|
|
603
|
+
* underlyingType: 'string',
|
|
604
|
+
* color: '#4A90E2',
|
|
605
|
+
* }),
|
|
606
|
+
* };
|
|
607
|
+
*
|
|
608
|
+
* // Define node types with auto-infer for type safety
|
|
609
|
+
* const typeOfNodes = {
|
|
610
|
+
* inputNode: makeTypeOfNodeWithAutoInfer({
|
|
611
|
+
* name: 'Input Node',
|
|
612
|
+
* headerColor: '#C44536',
|
|
613
|
+
* inputs: [{ name: 'Input', dataType: 'stringType', allowInput: true }],
|
|
614
|
+
* outputs: [{ name: 'Output', dataType: 'stringType' }]
|
|
615
|
+
* }),
|
|
616
|
+
* };
|
|
617
|
+
*
|
|
618
|
+
* // Construct node with type safety
|
|
619
|
+
* const node = constructNodeOfType(
|
|
620
|
+
* dataTypes,
|
|
621
|
+
* 'inputNode',
|
|
622
|
+
* typeOfNodes,
|
|
623
|
+
* 'node-123',
|
|
624
|
+
* { x: 100, y: 100 }
|
|
625
|
+
* );
|
|
626
|
+
* ```
|
|
627
|
+
*/
|
|
628
|
+
export declare function constructNodeOfType<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never>(dataTypes: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>['dataTypes'], nodeType: NodeTypeUniqueId, typeOfNodes: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>['typeOfNodes'], nodeId: string, position: XYPosition): State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>['nodes'][number];
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* A context-aware handle component for node inputs and outputs
|
|
632
|
+
*
|
|
633
|
+
* This component renders handles (connection points) for nodes with support for
|
|
634
|
+
* various shapes and automatic ReactFlow integration. It can render as either
|
|
635
|
+
* a ReactFlow Handle when inside a ReactFlow context or as a standalone element
|
|
636
|
+
* for preview purposes.
|
|
637
|
+
*
|
|
638
|
+
* Features:
|
|
639
|
+
* - 13+ custom handle shapes (circle, square, diamond, star, etc.)
|
|
640
|
+
* - Automatic ReactFlow integration
|
|
641
|
+
* - Custom colors and styling
|
|
642
|
+
* - Border support for clip-path shapes
|
|
643
|
+
* - Type-safe shape definitions
|
|
644
|
+
*
|
|
645
|
+
* @param props - The component props
|
|
646
|
+
* @param ref - Forwarded ref to the handle element
|
|
647
|
+
* @returns JSX element containing the handle
|
|
648
|
+
*
|
|
649
|
+
* @example
|
|
650
|
+
* ```tsx
|
|
651
|
+
* // Basic handle
|
|
652
|
+
* <ContextAwareHandle
|
|
653
|
+
* type="target"
|
|
654
|
+
* position={Position.Left}
|
|
655
|
+
* id="input1"
|
|
656
|
+
* color="#00BFFF"
|
|
657
|
+
* shape="circle"
|
|
658
|
+
* isCurrentlyInsideReactFlow={true}
|
|
659
|
+
* />
|
|
660
|
+
*
|
|
661
|
+
* // Custom shape handle
|
|
662
|
+
* <ContextAwareHandle
|
|
663
|
+
* type="source"
|
|
664
|
+
* position={Position.Right}
|
|
665
|
+
* id="output1"
|
|
666
|
+
* color="#FECA57"
|
|
667
|
+
* shape="diamond"
|
|
668
|
+
* isCurrentlyInsideReactFlow={true}
|
|
669
|
+
* />
|
|
670
|
+
*
|
|
671
|
+
* // Preview handle (outside ReactFlow)
|
|
672
|
+
* <ContextAwareHandle
|
|
673
|
+
* type="target"
|
|
674
|
+
* position={Position.Left}
|
|
675
|
+
* id="preview-input"
|
|
676
|
+
* color="#96CEB4"
|
|
677
|
+
* shape="star"
|
|
678
|
+
* isCurrentlyInsideReactFlow={false}
|
|
679
|
+
* />
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
162
682
|
export declare const ContextAwareHandle: ForwardRefExoticComponent< {
|
|
683
|
+
/** Type of handle (source or target) */
|
|
163
684
|
type: HandleType;
|
|
685
|
+
/** Position of the handle on the node */
|
|
164
686
|
position: Position;
|
|
687
|
+
/** Unique identifier for the handle */
|
|
165
688
|
id: string;
|
|
689
|
+
/** Color of the handle */
|
|
166
690
|
color?: string;
|
|
691
|
+
/** Shape of the handle */
|
|
167
692
|
shape?: HandleShape;
|
|
693
|
+
/** Whether the handle is currently inside a ReactFlow context */
|
|
168
694
|
isCurrentlyInsideReactFlow?: boolean;
|
|
169
695
|
} & HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>>;
|
|
170
696
|
|
|
697
|
+
/**
|
|
698
|
+
* Props for the ContextAwareHandle component
|
|
699
|
+
*/
|
|
171
700
|
export declare type ContextAwareHandleProps = {
|
|
701
|
+
/** Type of handle (source or target) */
|
|
172
702
|
type: HandleType;
|
|
703
|
+
/** Position of the handle on the node */
|
|
173
704
|
position: Position;
|
|
705
|
+
/** Unique identifier for the handle */
|
|
174
706
|
id: string;
|
|
707
|
+
/** Color of the handle */
|
|
175
708
|
color?: string;
|
|
709
|
+
/** Shape of the handle */
|
|
176
710
|
shape?: HandleShape;
|
|
711
|
+
/** Whether the handle is currently inside a ReactFlow context */
|
|
177
712
|
isCurrentlyInsideReactFlow?: boolean;
|
|
178
713
|
} & HTMLAttributes<HTMLDivElement>;
|
|
179
714
|
|
|
715
|
+
/**
|
|
716
|
+
* Context-aware input component that handles both connected and unconnected inputs
|
|
717
|
+
*
|
|
718
|
+
* This component intelligently renders either a label (for connected inputs) or an
|
|
719
|
+
* input component (for unconnected inputs) based on the connection state. It uses
|
|
720
|
+
* the ReactFlow context to determine if an input is connected to other nodes.
|
|
721
|
+
*
|
|
722
|
+
* Features:
|
|
723
|
+
* - Automatically detects input connection state
|
|
724
|
+
* - Renders appropriate UI based on connection status
|
|
725
|
+
* - Integrates with ReactFlow's connection system
|
|
726
|
+
* - Supports both string and number input types
|
|
727
|
+
*
|
|
728
|
+
* @param props - The component props
|
|
729
|
+
* @returns JSX element containing either a label or input component
|
|
730
|
+
*
|
|
731
|
+
* @example
|
|
732
|
+
* ```tsx
|
|
733
|
+
* <ContextAwareInput
|
|
734
|
+
* input={{
|
|
735
|
+
* id: 'input1',
|
|
736
|
+
* name: 'Value',
|
|
737
|
+
* type: 'string',
|
|
738
|
+
* dataType: 'stringType',
|
|
739
|
+
* allowInput: true,
|
|
740
|
+
* value: 'Hello World',
|
|
741
|
+
* }}
|
|
742
|
+
* isCurrentlyInsideReactFlow={true}
|
|
743
|
+
* />
|
|
744
|
+
* ```
|
|
745
|
+
*/
|
|
180
746
|
export declare const ContextAwareInput: ({ input, isCurrentlyInsideReactFlow, }: ContextAwareInputProps) => JSX.Element;
|
|
181
747
|
|
|
748
|
+
/**
|
|
749
|
+
* Props for the ContextAwareInput component
|
|
750
|
+
*/
|
|
182
751
|
export declare type ContextAwareInputProps = {
|
|
752
|
+
/** The input configuration */
|
|
183
753
|
input: ConfigurableNodeInput;
|
|
754
|
+
/** Whether the component is currently inside a ReactFlow context */
|
|
184
755
|
isCurrentlyInsideReactFlow: boolean;
|
|
185
756
|
};
|
|
186
757
|
|
|
758
|
+
/**
|
|
759
|
+
* A context menu component with nested submenu support
|
|
760
|
+
*
|
|
761
|
+
* This component provides a hierarchical context menu system with support for
|
|
762
|
+
* nested submenus, icons, keyboard shortcuts, and separators. It features
|
|
763
|
+
* hover-based submenu activation and Blender-inspired dark theme styling.
|
|
764
|
+
*
|
|
765
|
+
* Features:
|
|
766
|
+
* - Nested submenu support with unlimited depth
|
|
767
|
+
* - Icon and keyboard shortcut display
|
|
768
|
+
* - Separator lines for visual grouping
|
|
769
|
+
* - Hover-based submenu activation
|
|
770
|
+
* - Dark theme styling matching Blender's aesthetic
|
|
771
|
+
* - TypeScript support with full type safety
|
|
772
|
+
*
|
|
773
|
+
* @param props - The component props
|
|
774
|
+
* @returns JSX element containing the context menu
|
|
775
|
+
*
|
|
776
|
+
* @example
|
|
777
|
+
* ```tsx
|
|
778
|
+
* // Basic context menu
|
|
779
|
+
* <ContextMenu
|
|
780
|
+
* subItems={[
|
|
781
|
+
* {
|
|
782
|
+
* id: 'copy',
|
|
783
|
+
* label: 'Copy',
|
|
784
|
+
* icon: <CopyIcon className="w-4 h-4" />,
|
|
785
|
+
* shortcut: 'Ctrl+C',
|
|
786
|
+
* onClick: () => handleCopy(),
|
|
787
|
+
* },
|
|
788
|
+
* {
|
|
789
|
+
* id: 'paste',
|
|
790
|
+
* label: 'Paste',
|
|
791
|
+
* icon: <PasteIcon className="w-4 h-4" />,
|
|
792
|
+
* shortcut: 'Ctrl+V',
|
|
793
|
+
* onClick: () => handlePaste(),
|
|
794
|
+
* separator: true,
|
|
795
|
+
* },
|
|
796
|
+
* ]}
|
|
797
|
+
* />
|
|
798
|
+
*
|
|
799
|
+
* // Nested submenu
|
|
800
|
+
* <ContextMenu
|
|
801
|
+
* subItems={[
|
|
802
|
+
* {
|
|
803
|
+
* id: 'edit',
|
|
804
|
+
* label: 'Edit',
|
|
805
|
+
* icon: <EditIcon className="w-4 h-4" />,
|
|
806
|
+
* subItems: [
|
|
807
|
+
* {
|
|
808
|
+
* id: 'cut',
|
|
809
|
+
* label: 'Cut',
|
|
810
|
+
* onClick: () => handleCut(),
|
|
811
|
+
* },
|
|
812
|
+
* {
|
|
813
|
+
* id: 'copy',
|
|
814
|
+
* label: 'Copy',
|
|
815
|
+
* onClick: () => handleCopy(),
|
|
816
|
+
* },
|
|
817
|
+
* {
|
|
818
|
+
* id: 'paste',
|
|
819
|
+
* label: 'Paste',
|
|
820
|
+
* onClick: () => handlePaste(),
|
|
821
|
+
* },
|
|
822
|
+
* ],
|
|
823
|
+
* },
|
|
824
|
+
* ]}
|
|
825
|
+
* />
|
|
826
|
+
* ```
|
|
827
|
+
*/
|
|
187
828
|
export declare const ContextMenu: ({ subItems, className, onItemClick, }: ContextMenuProps) => JSX.Element;
|
|
188
829
|
|
|
830
|
+
/**
|
|
831
|
+
* Configuration for a context menu item
|
|
832
|
+
*
|
|
833
|
+
* Defines a single item in the context menu with optional submenu, icon, and actions.
|
|
834
|
+
* Supports nested submenus for hierarchical menu structures.
|
|
835
|
+
*/
|
|
189
836
|
export declare type ContextMenuItem = {
|
|
837
|
+
/** Unique identifier for the menu item */
|
|
190
838
|
id: string;
|
|
839
|
+
/** Display text for the menu item */
|
|
191
840
|
label: string;
|
|
841
|
+
/** Optional icon to display next to the label */
|
|
192
842
|
icon?: ReactNode;
|
|
843
|
+
/** Optional array of submenu items for nested menus */
|
|
193
844
|
subItems?: ContextMenuItem[];
|
|
845
|
+
/** Callback function when the item is clicked */
|
|
194
846
|
onClick?: () => void;
|
|
847
|
+
/** Optional keyboard shortcut text to display */
|
|
195
848
|
shortcut?: string;
|
|
849
|
+
/** Whether to show a separator line before this item */
|
|
196
850
|
separator?: boolean;
|
|
197
851
|
};
|
|
198
852
|
|
|
853
|
+
/**
|
|
854
|
+
* Props for the ContextMenu component
|
|
855
|
+
*/
|
|
199
856
|
export declare type ContextMenuProps = {
|
|
857
|
+
/** Array of menu items to display */
|
|
200
858
|
subItems: ContextMenuItem[];
|
|
859
|
+
/** Additional CSS classes */
|
|
201
860
|
className?: string;
|
|
861
|
+
/** Optional callback when any item is clicked */
|
|
202
862
|
onItemClick?: (item: ContextMenuItem) => void;
|
|
203
863
|
};
|
|
204
864
|
|
|
@@ -212,8 +872,13 @@ export declare type ContextMenuProps = {
|
|
|
212
872
|
*/
|
|
213
873
|
export declare function convertStringToNumber(inputNumberAsString: string): number;
|
|
214
874
|
|
|
875
|
+
/**
|
|
876
|
+
* Represents a 2D coordinate point
|
|
877
|
+
*/
|
|
215
878
|
export declare type Coordinate = {
|
|
879
|
+
/** X coordinate */
|
|
216
880
|
x: number;
|
|
881
|
+
/** Y coordinate */
|
|
217
882
|
y: number;
|
|
218
883
|
};
|
|
219
884
|
|
|
@@ -239,33 +904,159 @@ export declare type CreateNodeContextMenuProps<DataTypeUniqueId extends string =
|
|
|
239
904
|
contextMenuPosition: XYPosition;
|
|
240
905
|
};
|
|
241
906
|
|
|
242
|
-
|
|
907
|
+
/**
|
|
908
|
+
* Definition of a data type in the graph system
|
|
909
|
+
*
|
|
910
|
+
* @template UnderlyingType - The underlying type of the data
|
|
911
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
912
|
+
*/
|
|
913
|
+
export declare type DataType<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = UnderlyingType extends 'complex' ? {
|
|
914
|
+
/** Display name of the data type */
|
|
243
915
|
name: string;
|
|
916
|
+
/** The underlying type of the data */
|
|
244
917
|
underlyingType: UnderlyingType;
|
|
918
|
+
/** Zod schema for complex data validation */
|
|
245
919
|
complexSchema: ComplexSchemaType;
|
|
920
|
+
/** Color used for visual representation */
|
|
246
921
|
color: string;
|
|
247
922
|
} : {
|
|
923
|
+
/** Display name of the data type */
|
|
248
924
|
name: string;
|
|
925
|
+
/** The underlying type of the data */
|
|
249
926
|
underlyingType: UnderlyingType;
|
|
927
|
+
/** Complex schema is not used for non-complex types */
|
|
250
928
|
complexSchema?: undefined;
|
|
929
|
+
/** Color used for visual representation */
|
|
251
930
|
color: string;
|
|
252
931
|
};
|
|
253
932
|
|
|
933
|
+
/**
|
|
934
|
+
* Array of edge changes for ReactFlow
|
|
935
|
+
*/
|
|
254
936
|
export declare type EdgeChanges = EdgeChange<ConfigurableEdgeState>[];
|
|
255
937
|
|
|
938
|
+
/**
|
|
939
|
+
* Array of configurable edges in the graph
|
|
940
|
+
*/
|
|
256
941
|
export declare type Edges = ConfigurableEdgeState[];
|
|
257
942
|
|
|
943
|
+
/**
|
|
944
|
+
* Main graph editor component inspired by Blender's node editor
|
|
945
|
+
*
|
|
946
|
+
* This is the primary component for creating interactive node-based graph editors.
|
|
947
|
+
* It provides a complete ReactFlow-based interface with custom nodes, edges, and
|
|
948
|
+
* context menu functionality for adding new nodes.
|
|
949
|
+
*
|
|
950
|
+
* Features:
|
|
951
|
+
* - Pan, zoom, and select nodes with intuitive controls
|
|
952
|
+
* - Drag and drop node connections
|
|
953
|
+
* - Right-click context menu for adding new nodes
|
|
954
|
+
* - Custom node types with configurable inputs and outputs
|
|
955
|
+
* - Real-time node manipulation and state management
|
|
956
|
+
*
|
|
957
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
958
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
959
|
+
* @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
|
|
960
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
961
|
+
* @param props - The component props
|
|
962
|
+
* @returns JSX element containing the complete graph editor
|
|
963
|
+
*
|
|
964
|
+
* @example
|
|
965
|
+
* ```tsx
|
|
966
|
+
* import {
|
|
967
|
+
* FullGraph,
|
|
968
|
+
* useFullGraph,
|
|
969
|
+
* makeStateWithAutoInfer,
|
|
970
|
+
* makeNodeIdToNodeTypeWithAutoInfer,
|
|
971
|
+
* makeTypeOfNodeWithAutoInfer,
|
|
972
|
+
* makeDataTypeWithAutoInfer
|
|
973
|
+
* } from 'react-blender-nodes';
|
|
974
|
+
*
|
|
975
|
+
* function MyNodeEditor() {
|
|
976
|
+
* // Define data types with auto-infer for type safety
|
|
977
|
+
* const dataTypes = {
|
|
978
|
+
* stringType: makeDataTypeWithAutoInfer({
|
|
979
|
+
* name: 'String',
|
|
980
|
+
* underlyingType: 'string',
|
|
981
|
+
* color: '#4A90E2',
|
|
982
|
+
* }),
|
|
983
|
+
* numberType: makeDataTypeWithAutoInfer({
|
|
984
|
+
* name: 'Number',
|
|
985
|
+
* underlyingType: 'number',
|
|
986
|
+
* color: '#E74C3C',
|
|
987
|
+
* }),
|
|
988
|
+
* };
|
|
989
|
+
*
|
|
990
|
+
* // Define node types with auto-infer for type safety
|
|
991
|
+
* const typeOfNodes = {
|
|
992
|
+
* inputNode: makeTypeOfNodeWithAutoInfer({
|
|
993
|
+
* name: 'Input Node',
|
|
994
|
+
* headerColor: '#C44536',
|
|
995
|
+
* inputs: [
|
|
996
|
+
* { name: 'Input', dataType: 'stringType', allowInput: true }
|
|
997
|
+
* ],
|
|
998
|
+
* outputs: [
|
|
999
|
+
* { name: 'Output', dataType: 'stringType' }
|
|
1000
|
+
* ],
|
|
1001
|
+
* }),
|
|
1002
|
+
* outputNode: makeTypeOfNodeWithAutoInfer({
|
|
1003
|
+
* name: 'Output Node',
|
|
1004
|
+
* headerColor: '#2D5A87',
|
|
1005
|
+
* inputs: [
|
|
1006
|
+
* { name: 'Input', dataType: 'stringType' }
|
|
1007
|
+
* ],
|
|
1008
|
+
* outputs: [],
|
|
1009
|
+
* }),
|
|
1010
|
+
* };
|
|
1011
|
+
*
|
|
1012
|
+
* // Define node ID to type mapping with auto-infer
|
|
1013
|
+
* const nodeIdToNodeType = makeNodeIdToNodeTypeWithAutoInfer({
|
|
1014
|
+
* 'node-1': 'inputNode',
|
|
1015
|
+
* 'node-2': 'outputNode',
|
|
1016
|
+
* });
|
|
1017
|
+
*
|
|
1018
|
+
* // Create state with auto-infer for complete type safety
|
|
1019
|
+
* const initialState = makeStateWithAutoInfer({
|
|
1020
|
+
* dataTypes,
|
|
1021
|
+
* typeOfNodes,
|
|
1022
|
+
* nodeIdToNodeType,
|
|
1023
|
+
* nodes: [],
|
|
1024
|
+
* edges: [],
|
|
1025
|
+
* });
|
|
1026
|
+
*
|
|
1027
|
+
* const { state, dispatch } = useFullGraph(initialState);
|
|
1028
|
+
*
|
|
1029
|
+
* return (
|
|
1030
|
+
* <div style={{ height: '600px', width: '100%' }}>
|
|
1031
|
+
* <FullGraph state={state} dispatch={dispatch} />
|
|
1032
|
+
* </div>
|
|
1033
|
+
* );
|
|
1034
|
+
* }
|
|
1035
|
+
* ```
|
|
1036
|
+
*/
|
|
258
1037
|
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
1038
|
|
|
1039
|
+
/**
|
|
1040
|
+
* Props for the FullGraph component
|
|
1041
|
+
*
|
|
1042
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
1043
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
1044
|
+
* @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
|
|
1045
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
1046
|
+
*/
|
|
260
1047
|
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> = {
|
|
1048
|
+
/** The current state of the graph including nodes, edges, and type definitions */
|
|
261
1049
|
state: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>;
|
|
1050
|
+
/** Dispatch function for updating the graph state */
|
|
262
1051
|
dispatch: ActionDispatch<[
|
|
263
1052
|
action: Action<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>
|
|
264
1053
|
]>;
|
|
265
1054
|
};
|
|
266
1055
|
|
|
1056
|
+
/** Type representing all available handle shapes */
|
|
267
1057
|
export declare type HandleShape = (typeof handleShapesMap)[keyof typeof handleShapesMap];
|
|
268
1058
|
|
|
1059
|
+
/** Map of handle shapes for type-safe access */
|
|
269
1060
|
export declare const handleShapesMap: {
|
|
270
1061
|
readonly circle: "circle";
|
|
271
1062
|
readonly square: "square";
|
|
@@ -345,51 +1136,378 @@ export declare type InputProps = {
|
|
|
345
1136
|
numberOfDecimals?: never;
|
|
346
1137
|
});
|
|
347
1138
|
|
|
1139
|
+
/**
|
|
1140
|
+
* Checks if a coordinate point is within a bounding box
|
|
1141
|
+
*
|
|
1142
|
+
* @param coordinate - The coordinate point to check
|
|
1143
|
+
* @param box - The bounding box to check against
|
|
1144
|
+
* @param xAxisInclusive - Whether the x-axis boundaries are inclusive (default: false)
|
|
1145
|
+
* @param yAxisInclusive - Whether the y-axis boundaries are inclusive (default: false)
|
|
1146
|
+
* @returns True if the coordinate is within the box, false otherwise
|
|
1147
|
+
*
|
|
1148
|
+
* @example
|
|
1149
|
+
* ```tsx
|
|
1150
|
+
* const point = { x: 50, y: 50 };
|
|
1151
|
+
* const box = { top: 0, left: 0, right: 100, bottom: 100 };
|
|
1152
|
+
*
|
|
1153
|
+
* isCoordinateInBox(point, box) // true
|
|
1154
|
+
* isCoordinateInBox({ x: 0, y: 0 }, box, true, true) // true (inclusive)
|
|
1155
|
+
* isCoordinateInBox({ x: 100, y: 100 }, box) // false (exclusive)
|
|
1156
|
+
* ```
|
|
1157
|
+
*/
|
|
348
1158
|
export declare function isCoordinateInBox(coordinate: Coordinate, box: Box, xAxisInclusive?: boolean, yAxisInclusive?: boolean): boolean;
|
|
349
1159
|
|
|
1160
|
+
/**
|
|
1161
|
+
* Checks if a number is within a specified range
|
|
1162
|
+
*
|
|
1163
|
+
* @param number - The number to check
|
|
1164
|
+
* @param min - The minimum value of the range
|
|
1165
|
+
* @param max - The maximum value of the range
|
|
1166
|
+
* @param minInclusive - Whether the minimum value is inclusive (default: false)
|
|
1167
|
+
* @param maxInclusive - Whether the maximum value is inclusive (default: false)
|
|
1168
|
+
* @returns True if the number is within the range, false otherwise
|
|
1169
|
+
*
|
|
1170
|
+
* @example
|
|
1171
|
+
* ```tsx
|
|
1172
|
+
* isNumberInRange(5, 1, 10) // true (5 is between 1 and 10, exclusive)
|
|
1173
|
+
* isNumberInRange(1, 1, 10, true) // true (1 is included)
|
|
1174
|
+
* isNumberInRange(10, 1, 10, false, true) // true (10 is included)
|
|
1175
|
+
* isNumberInRange(0, 1, 10) // false (0 is below range)
|
|
1176
|
+
* ```
|
|
1177
|
+
*/
|
|
350
1178
|
export declare function isNumberInRange(number: number, min: number, max: number, minInclusive?: boolean, maxInclusive?: boolean): boolean;
|
|
351
1179
|
|
|
1180
|
+
/**
|
|
1181
|
+
* Type guard to check if a string is a supported underlying type
|
|
1182
|
+
*
|
|
1183
|
+
* @param type - The string to check
|
|
1184
|
+
* @returns True if the string is a supported underlying type
|
|
1185
|
+
*
|
|
1186
|
+
* @example
|
|
1187
|
+
* ```tsx
|
|
1188
|
+
* if (isSupportedUnderlyingType('string')) {
|
|
1189
|
+
* // type is now 'string'
|
|
1190
|
+
* }
|
|
1191
|
+
* ```
|
|
1192
|
+
*/
|
|
1193
|
+
export declare function isSupportedUnderlyingType(type: string): type is SupportedUnderlyingTypes;
|
|
1194
|
+
|
|
1195
|
+
/**
|
|
1196
|
+
* Main reducer function for managing graph state
|
|
1197
|
+
*
|
|
1198
|
+
* This reducer handles all state updates for the graph including nodes, edges,
|
|
1199
|
+
* and input values. It uses Immer for immutable state updates and integrates
|
|
1200
|
+
* with ReactFlow for node and edge management.
|
|
1201
|
+
*
|
|
1202
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
1203
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
1204
|
+
* @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
|
|
1205
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
1206
|
+
* @param oldState - The current state of the graph
|
|
1207
|
+
* @param action - The action to apply to the state
|
|
1208
|
+
* @returns New state after applying the action
|
|
1209
|
+
*
|
|
1210
|
+
* @example
|
|
1211
|
+
* ```tsx
|
|
1212
|
+
* import {
|
|
1213
|
+
* mainReducer,
|
|
1214
|
+
* makeStateWithAutoInfer,
|
|
1215
|
+
* makeNodeIdToNodeTypeWithAutoInfer,
|
|
1216
|
+
* makeTypeOfNodeWithAutoInfer,
|
|
1217
|
+
* makeDataTypeWithAutoInfer
|
|
1218
|
+
* } from 'react-blender-nodes';
|
|
1219
|
+
*
|
|
1220
|
+
* // Create type-safe state with auto-infer helpers
|
|
1221
|
+
* const dataTypes = {
|
|
1222
|
+
* stringType: makeDataTypeWithAutoInfer({
|
|
1223
|
+
* name: 'String',
|
|
1224
|
+
* underlyingType: 'string',
|
|
1225
|
+
* color: '#4A90E2',
|
|
1226
|
+
* }),
|
|
1227
|
+
* };
|
|
1228
|
+
*
|
|
1229
|
+
* const typeOfNodes = {
|
|
1230
|
+
* inputNode: makeTypeOfNodeWithAutoInfer({
|
|
1231
|
+
* name: 'Input Node',
|
|
1232
|
+
* headerColor: '#C44536',
|
|
1233
|
+
* inputs: [{ name: 'Input', dataType: 'stringType', allowInput: true }],
|
|
1234
|
+
* outputs: [{ name: 'Output', dataType: 'stringType' }],
|
|
1235
|
+
* }),
|
|
1236
|
+
* };
|
|
1237
|
+
*
|
|
1238
|
+
* const nodeIdToNodeType = makeNodeIdToNodeTypeWithAutoInfer({
|
|
1239
|
+
* 'node-1': 'inputNode',
|
|
1240
|
+
* });
|
|
1241
|
+
*
|
|
1242
|
+
* const state = makeStateWithAutoInfer({
|
|
1243
|
+
* dataTypes,
|
|
1244
|
+
* typeOfNodes,
|
|
1245
|
+
* nodeIdToNodeType,
|
|
1246
|
+
* nodes: [],
|
|
1247
|
+
* edges: [],
|
|
1248
|
+
* });
|
|
1249
|
+
*
|
|
1250
|
+
* // Add a new node (type-safe!)
|
|
1251
|
+
* const newState = mainReducer(state, {
|
|
1252
|
+
* type: 'ADD_NODE',
|
|
1253
|
+
* payload: {
|
|
1254
|
+
* type: 'inputNode',
|
|
1255
|
+
* position: { x: 100, y: 100 },
|
|
1256
|
+
* },
|
|
1257
|
+
* });
|
|
1258
|
+
*
|
|
1259
|
+
* // Update input value (type-safe!)
|
|
1260
|
+
* const updatedState = mainReducer(newState, {
|
|
1261
|
+
* type: 'UPDATE_INPUT_VALUE',
|
|
1262
|
+
* payload: {
|
|
1263
|
+
* nodeId: 'node1',
|
|
1264
|
+
* inputId: 'input1',
|
|
1265
|
+
* value: 'new value',
|
|
1266
|
+
* },
|
|
1267
|
+
* });
|
|
1268
|
+
* ```
|
|
1269
|
+
*/
|
|
1270
|
+
export declare function mainReducer<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never>(oldState: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>, action: Action<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>): State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>;
|
|
1271
|
+
|
|
1272
|
+
/**
|
|
1273
|
+
* Helper function to create a data type with automatic type inference
|
|
1274
|
+
*
|
|
1275
|
+
* This function is essential for type safety when defining data types. It ensures
|
|
1276
|
+
* that TypeScript can properly infer and validate the types throughout your graph
|
|
1277
|
+
* system, preventing runtime errors and providing better IDE support.
|
|
1278
|
+
*
|
|
1279
|
+
* @template UnderlyingType - The underlying type of the data
|
|
1280
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
1281
|
+
* @param input - The data type definition
|
|
1282
|
+
* @returns The data type definition with proper typing
|
|
1283
|
+
*
|
|
1284
|
+
* @example
|
|
1285
|
+
* ```tsx
|
|
1286
|
+
* // ✅ Type-safe - TypeScript will validate dataType references
|
|
1287
|
+
* const stringType = makeDataTypeWithAutoInfer({
|
|
1288
|
+
* name: 'String',
|
|
1289
|
+
* underlyingType: 'string',
|
|
1290
|
+
* color: '#4A90E2',
|
|
1291
|
+
* });
|
|
1292
|
+
*
|
|
1293
|
+
* // ❌ Without auto-infer - TypeScript can't validate references
|
|
1294
|
+
* const stringType = {
|
|
1295
|
+
* name: 'String',
|
|
1296
|
+
* underlyingType: 'string',
|
|
1297
|
+
* color: '#4A90E2',
|
|
1298
|
+
* };
|
|
1299
|
+
* ```
|
|
1300
|
+
*/
|
|
1301
|
+
export declare function makeDataTypeWithAutoInfer<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never>(input: DataType<UnderlyingType, ComplexSchemaType>): DataType<UnderlyingType, ComplexSchemaType>;
|
|
1302
|
+
|
|
1303
|
+
/**
|
|
1304
|
+
* Helper function to create a node ID to node type mapping with automatic type inference
|
|
1305
|
+
*
|
|
1306
|
+
* This function is essential for type safety when mapping node IDs to their types.
|
|
1307
|
+
* It ensures that TypeScript can validate that all node type references are valid,
|
|
1308
|
+
* preventing runtime errors when dispatching actions and providing better IDE support.
|
|
1309
|
+
*
|
|
1310
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
1311
|
+
* @param input - The node ID to node type mapping
|
|
1312
|
+
* @returns The mapping with proper typing
|
|
1313
|
+
*
|
|
1314
|
+
* @example
|
|
1315
|
+
* ```tsx
|
|
1316
|
+
* // ✅ Type-safe - TypeScript will validate node type references
|
|
1317
|
+
* const nodeIdToNodeType = makeNodeIdToNodeTypeWithAutoInfer({
|
|
1318
|
+
* 'node-1': 'inputNode',
|
|
1319
|
+
* 'node-2': 'outputNode',
|
|
1320
|
+
* });
|
|
1321
|
+
*
|
|
1322
|
+
* // ❌ Without auto-infer - TypeScript can't validate node type references
|
|
1323
|
+
* const nodeIdToNodeType = {
|
|
1324
|
+
* 'node-1': 'inputNode',
|
|
1325
|
+
* 'node-2': 'outputNode',
|
|
1326
|
+
* };
|
|
1327
|
+
* ```
|
|
1328
|
+
*/
|
|
1329
|
+
export declare function makeNodeIdToNodeTypeWithAutoInfer<NodeTypeUniqueId extends string = string>(input: NodeIdToNodeType<NodeTypeUniqueId>): NodeIdToNodeType<NodeTypeUniqueId>;
|
|
1330
|
+
|
|
1331
|
+
/**
|
|
1332
|
+
* Helper function to create a state with automatic type inference
|
|
1333
|
+
*
|
|
1334
|
+
* This function is essential for complete type safety when creating the graph state.
|
|
1335
|
+
* It ensures that TypeScript can properly infer and validate all type relationships
|
|
1336
|
+
* throughout your graph system, providing compile-time type checking and better IDE support.
|
|
1337
|
+
*
|
|
1338
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
1339
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
1340
|
+
* @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
|
|
1341
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
1342
|
+
* @param input - The state definition
|
|
1343
|
+
* @returns The state with proper typing
|
|
1344
|
+
*
|
|
1345
|
+
* @example
|
|
1346
|
+
* ```tsx
|
|
1347
|
+
* // ✅ Type-safe - Complete type inference and validation
|
|
1348
|
+
* const state = makeStateWithAutoInfer({
|
|
1349
|
+
* dataTypes: {
|
|
1350
|
+
* stringType: makeDataTypeWithAutoInfer({
|
|
1351
|
+
* name: 'String',
|
|
1352
|
+
* underlyingType: 'string',
|
|
1353
|
+
* color: '#4A90E2'
|
|
1354
|
+
* })
|
|
1355
|
+
* },
|
|
1356
|
+
* typeOfNodes: {
|
|
1357
|
+
* inputNode: makeTypeOfNodeWithAutoInfer({
|
|
1358
|
+
* name: 'Input',
|
|
1359
|
+
* inputs: [],
|
|
1360
|
+
* outputs: []
|
|
1361
|
+
* })
|
|
1362
|
+
* },
|
|
1363
|
+
* nodeIdToNodeType: makeNodeIdToNodeTypeWithAutoInfer({}),
|
|
1364
|
+
* nodes: [],
|
|
1365
|
+
* edges: [],
|
|
1366
|
+
* });
|
|
1367
|
+
*
|
|
1368
|
+
* // ❌ Without auto-infer - No type validation
|
|
1369
|
+
* const state = {
|
|
1370
|
+
* dataTypes: { stringType: { name: 'String', underlyingType: 'string', color: '#4A90E2' } },
|
|
1371
|
+
* typeOfNodes: { inputNode: { name: 'Input', inputs: [], outputs: [] } },
|
|
1372
|
+
* nodes: [],
|
|
1373
|
+
* nodeIdToNodeType: {},
|
|
1374
|
+
* edges: [],
|
|
1375
|
+
* };
|
|
1376
|
+
* ```
|
|
1377
|
+
*/
|
|
1378
|
+
export declare function makeStateWithAutoInfer<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never>(input: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>): State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>;
|
|
1379
|
+
|
|
1380
|
+
/**
|
|
1381
|
+
* Helper function to create a node type with automatic type inference
|
|
1382
|
+
*
|
|
1383
|
+
* This function is essential for type safety when defining node types. It ensures
|
|
1384
|
+
* that TypeScript can properly validate dataType references in inputs and outputs,
|
|
1385
|
+
* preventing runtime errors when creating nodes and providing better IDE support.
|
|
1386
|
+
*
|
|
1387
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
1388
|
+
* @param input - The node type definition
|
|
1389
|
+
* @returns The node type definition with proper typing
|
|
1390
|
+
*
|
|
1391
|
+
* @example
|
|
1392
|
+
* ```tsx
|
|
1393
|
+
* // ✅ Type-safe - TypeScript will validate dataType references
|
|
1394
|
+
* const inputNodeType = makeTypeOfNodeWithAutoInfer({
|
|
1395
|
+
* name: 'Input Node',
|
|
1396
|
+
* headerColor: '#C44536',
|
|
1397
|
+
* inputs: [{ name: 'Input', dataType: 'stringType', allowInput: true }],
|
|
1398
|
+
* outputs: [{ name: 'Output', dataType: 'stringType' }],
|
|
1399
|
+
* });
|
|
1400
|
+
*
|
|
1401
|
+
* // ❌ Without auto-infer - TypeScript can't validate dataType references
|
|
1402
|
+
* const inputNodeType = {
|
|
1403
|
+
* name: 'Input Node',
|
|
1404
|
+
* headerColor: '#C44536',
|
|
1405
|
+
* inputs: [{ name: 'Input', dataType: 'stringType', allowInput: true }],
|
|
1406
|
+
* outputs: [{ name: 'Output', dataType: 'stringType' }],
|
|
1407
|
+
* };
|
|
1408
|
+
* ```
|
|
1409
|
+
*/
|
|
1410
|
+
export declare function makeTypeOfNodeWithAutoInfer<DataTypeUniqueId extends string = string>(input: TypeOfNode<DataTypeUniqueId>): TypeOfNode<DataTypeUniqueId>;
|
|
1411
|
+
|
|
1412
|
+
/**
|
|
1413
|
+
* Array of node changes for ReactFlow
|
|
1414
|
+
*/
|
|
352
1415
|
export declare type NodeChanges = NodeChange<ConfigurableNodeState>[];
|
|
353
1416
|
|
|
354
|
-
|
|
1417
|
+
/**
|
|
1418
|
+
* Mapping from node IDs to their node types
|
|
1419
|
+
*
|
|
1420
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
1421
|
+
*/
|
|
1422
|
+
export declare type NodeIdToNodeType<NodeTypeUniqueId extends string = string> = Record<string, NodeTypeUniqueId>;
|
|
355
1423
|
|
|
356
1424
|
/**
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
1425
|
+
* Enhanced node resizer component with customizable controls
|
|
1426
|
+
*
|
|
1427
|
+
* This component extends the standard ReactFlow NodeResizer with additional
|
|
1428
|
+
* customization options for line and handle positions. It provides fine-grained
|
|
1429
|
+
* control over which resize controls are displayed and how they behave.
|
|
1430
|
+
*
|
|
1431
|
+
* Features:
|
|
1432
|
+
* - Customizable line and handle positions
|
|
1433
|
+
* - Direction-specific resize controls
|
|
1434
|
+
* - Min/max width and height constraints
|
|
1435
|
+
* - Aspect ratio preservation
|
|
1436
|
+
* - Auto-scaling support
|
|
1437
|
+
* - Custom styling options
|
|
1438
|
+
*
|
|
1439
|
+
* @param props - The component props
|
|
1440
|
+
* @returns JSX element containing the node resizer controls
|
|
360
1441
|
*
|
|
361
1442
|
* @example
|
|
362
|
-
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*}
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
|
|
1443
|
+
* ```tsx
|
|
1444
|
+
* // Basic resizer with default controls
|
|
1445
|
+
* <NodeResizerWithMoreControls
|
|
1446
|
+
* minWidth={100}
|
|
1447
|
+
* minHeight={50}
|
|
1448
|
+
* maxWidth={500}
|
|
1449
|
+
* maxHeight={300}
|
|
1450
|
+
* />
|
|
1451
|
+
*
|
|
1452
|
+
* // Custom line positions only
|
|
1453
|
+
* <NodeResizerWithMoreControls
|
|
1454
|
+
* linePosition={['left', 'right']}
|
|
1455
|
+
* minWidth={100}
|
|
1456
|
+
* minHeight={50}
|
|
1457
|
+
* />
|
|
1458
|
+
*
|
|
1459
|
+
* // Custom handle positions
|
|
1460
|
+
* <NodeResizerWithMoreControls
|
|
1461
|
+
* handlePosition={['top-left', 'bottom-right']}
|
|
1462
|
+
* minWidth={100}
|
|
1463
|
+
* minHeight={50}
|
|
1464
|
+
* />
|
|
1465
|
+
*
|
|
1466
|
+
* // Horizontal-only resizing
|
|
1467
|
+
* <NodeResizerWithMoreControls
|
|
1468
|
+
* resizeDirection="horizontal"
|
|
1469
|
+
* linePosition={['left', 'right']}
|
|
1470
|
+
* minWidth={100}
|
|
1471
|
+
* maxWidth={500}
|
|
1472
|
+
* />
|
|
1473
|
+
* ```
|
|
379
1474
|
*/
|
|
380
1475
|
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
1476
|
|
|
1477
|
+
/**
|
|
1478
|
+
* Props for the NodeResizerWithMoreControls component
|
|
1479
|
+
*/
|
|
382
1480
|
export declare type NodeResizerWithMoreControlsProps = NodeResizerProps & {
|
|
1481
|
+
/** Array of line positions for resize controls */
|
|
383
1482
|
linePosition?: ControlLinePosition[];
|
|
1483
|
+
/** Array of handle positions for resize controls */
|
|
384
1484
|
handlePosition?: ControlPosition[];
|
|
1485
|
+
/** Direction of resize operation */
|
|
385
1486
|
resizeDirection?: ResizeControlDirection;
|
|
386
1487
|
};
|
|
387
1488
|
|
|
1489
|
+
/**
|
|
1490
|
+
* Array of configurable nodes in the graph
|
|
1491
|
+
*/
|
|
388
1492
|
export declare type Nodes = ConfigurableNodeState[];
|
|
389
1493
|
|
|
1494
|
+
/**
|
|
1495
|
+
* ReactFlow-aware input component that automatically updates node data
|
|
1496
|
+
*
|
|
1497
|
+
* This component renders the appropriate input component (Input or SliderNumberInput)
|
|
1498
|
+
* and automatically updates the ReactFlow node data when values change. It integrates
|
|
1499
|
+
* with the ReactFlow context to maintain state consistency.
|
|
1500
|
+
*
|
|
1501
|
+
* @param props - The component props
|
|
1502
|
+
* @returns JSX element containing the appropriate input component
|
|
1503
|
+
*/
|
|
390
1504
|
export declare const ReactFlowAwareInput: ({ input }: ReactFlowAwareInputProps) => JSX.Element;
|
|
391
1505
|
|
|
1506
|
+
/**
|
|
1507
|
+
* Props for the ReactFlowAwareInput component
|
|
1508
|
+
*/
|
|
392
1509
|
export declare type ReactFlowAwareInputProps = {
|
|
1510
|
+
/** The input configuration */
|
|
393
1511
|
input: ConfigurableNodeInput;
|
|
394
1512
|
};
|
|
395
1513
|
|
|
@@ -401,48 +1519,209 @@ export declare type ReactFlowAwareInputProps = {
|
|
|
401
1519
|
*/
|
|
402
1520
|
export declare function sanitizeNumberToShowAsText(value: number, numberOfDecimals: number): string;
|
|
403
1521
|
|
|
1522
|
+
/**
|
|
1523
|
+
* A combined slider and number input component with drag functionality
|
|
1524
|
+
*
|
|
1525
|
+
* This component provides an intuitive way to input and adjust numeric values
|
|
1526
|
+
* through both dragging and direct input. It features a slider interface with
|
|
1527
|
+
* increment/decrement buttons and switches to a text input when clicked.
|
|
1528
|
+
*
|
|
1529
|
+
* Features:
|
|
1530
|
+
* - Drag-to-adjust functionality with visual feedback
|
|
1531
|
+
* - Increment/decrement buttons for precise control
|
|
1532
|
+
* - Click-to-edit mode with text input
|
|
1533
|
+
* - Min/max value constraints
|
|
1534
|
+
* - Customizable step size
|
|
1535
|
+
* - Blender-inspired dark theme styling
|
|
1536
|
+
*
|
|
1537
|
+
* @param props - The component props
|
|
1538
|
+
* @param ref - Forwarded ref to the component
|
|
1539
|
+
* @returns JSX element containing the slider number input
|
|
1540
|
+
*
|
|
1541
|
+
* @example
|
|
1542
|
+
* ```tsx
|
|
1543
|
+
* // Basic usage
|
|
1544
|
+
* <SliderNumberInput
|
|
1545
|
+
* name="Price"
|
|
1546
|
+
* value={10.5}
|
|
1547
|
+
* onChange={(value) => setPrice(value)}
|
|
1548
|
+
* />
|
|
1549
|
+
*
|
|
1550
|
+
* // With constraints
|
|
1551
|
+
* <SliderNumberInput
|
|
1552
|
+
* name="Temperature"
|
|
1553
|
+
* value={25}
|
|
1554
|
+
* min={0}
|
|
1555
|
+
* max={100}
|
|
1556
|
+
* step={0.5}
|
|
1557
|
+
* onChange={(value) => setTemperature(value)}
|
|
1558
|
+
* />
|
|
1559
|
+
*
|
|
1560
|
+
* // Controlled component
|
|
1561
|
+
* const [value, setValue] = useState(42);
|
|
1562
|
+
* <SliderNumberInput
|
|
1563
|
+
* name="Count"
|
|
1564
|
+
* value={value}
|
|
1565
|
+
* onChange={setValue}
|
|
1566
|
+
* min={0}
|
|
1567
|
+
* max={1000}
|
|
1568
|
+
* />
|
|
1569
|
+
* ```
|
|
1570
|
+
*/
|
|
404
1571
|
export declare const SliderNumberInput: ForwardRefExoticComponent<SliderNumberInputProps & RefAttributes<HTMLInputElement & HTMLDivElement>>;
|
|
405
1572
|
|
|
1573
|
+
/**
|
|
1574
|
+
* Props for the SliderNumberInput component
|
|
1575
|
+
*/
|
|
406
1576
|
export declare type SliderNumberInputProps = {
|
|
1577
|
+
/** Display name for the input */
|
|
407
1578
|
name?: string;
|
|
1579
|
+
/** Current numeric value */
|
|
408
1580
|
value?: number;
|
|
1581
|
+
/** Callback when the value changes */
|
|
409
1582
|
onChange?: (value: number) => void;
|
|
1583
|
+
/** Additional CSS classes */
|
|
410
1584
|
className?: string;
|
|
1585
|
+
/** Minimum allowed value */
|
|
411
1586
|
min?: number;
|
|
1587
|
+
/** Maximum allowed value */
|
|
412
1588
|
max?: number;
|
|
1589
|
+
/** Step size for value changes */
|
|
413
1590
|
step?: number;
|
|
414
1591
|
};
|
|
415
1592
|
|
|
416
|
-
|
|
1593
|
+
/**
|
|
1594
|
+
* Complete state definition for the graph system
|
|
1595
|
+
*
|
|
1596
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
1597
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
1598
|
+
* @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
|
|
1599
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
1600
|
+
*/
|
|
1601
|
+
export declare type State<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = {
|
|
1602
|
+
/** Map of data type definitions */
|
|
417
1603
|
dataTypes: Record<DataTypeUniqueId, DataType<UnderlyingType, ComplexSchemaType>>;
|
|
1604
|
+
/** Map of node type definitions */
|
|
418
1605
|
typeOfNodes: Record<NodeTypeUniqueId, TypeOfNode<DataTypeUniqueId>>;
|
|
1606
|
+
/** Array of nodes in the graph */
|
|
419
1607
|
nodes: Nodes;
|
|
1608
|
+
/** Mapping from node IDs to their types */
|
|
420
1609
|
nodeIdToNodeType: NodeIdToNodeType<NodeTypeUniqueId>;
|
|
1610
|
+
/** Array of edges in the graph */
|
|
421
1611
|
edges: Edges;
|
|
422
1612
|
};
|
|
423
1613
|
|
|
424
|
-
|
|
1614
|
+
/**
|
|
1615
|
+
* Union type of all supported underlying data types
|
|
1616
|
+
*/
|
|
1617
|
+
export declare type SupportedUnderlyingTypes = (typeof supportedUnderlyingTypes)[number];
|
|
425
1618
|
|
|
1619
|
+
/**
|
|
1620
|
+
* Array of supported underlying data types
|
|
1621
|
+
*/
|
|
426
1622
|
declare const supportedUnderlyingTypes: readonly ["string", "number", "complex", "noEquivalent", "inferFromConnection"];
|
|
427
1623
|
|
|
428
|
-
|
|
1624
|
+
/**
|
|
1625
|
+
* Map of supported underlying types for type checking
|
|
1626
|
+
*/
|
|
1627
|
+
export declare const supportedUnderlyingTypesMap: {
|
|
1628
|
+
readonly string: "string";
|
|
1629
|
+
readonly number: "number";
|
|
1630
|
+
readonly complex: "complex";
|
|
1631
|
+
readonly noEquivalent: "noEquivalent";
|
|
1632
|
+
readonly inferFromConnection: "inferFromConnection";
|
|
1633
|
+
};
|
|
1634
|
+
|
|
1635
|
+
/**
|
|
1636
|
+
* Definition of an input type in a node
|
|
1637
|
+
*
|
|
1638
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
1639
|
+
*/
|
|
1640
|
+
export declare type TypeOfInput<DataTypeUniqueId extends string = string> = {
|
|
1641
|
+
/** Display name of the input */
|
|
429
1642
|
name: string;
|
|
1643
|
+
/** The data type identifier this input uses */
|
|
430
1644
|
dataType: DataTypeUniqueId;
|
|
1645
|
+
/** Whether this input allows direct user input */
|
|
431
1646
|
allowInput?: boolean;
|
|
432
1647
|
};
|
|
433
1648
|
|
|
434
|
-
|
|
1649
|
+
/**
|
|
1650
|
+
* Definition of an input panel type in a node
|
|
1651
|
+
*
|
|
1652
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
1653
|
+
*/
|
|
1654
|
+
export declare type TypeOfInputPanel<DataTypeUniqueId extends string = string> = {
|
|
1655
|
+
/** Display name of the input panel */
|
|
435
1656
|
name: string;
|
|
1657
|
+
/** Array of inputs within this panel */
|
|
436
1658
|
inputs: TypeOfInput<DataTypeUniqueId>[];
|
|
437
1659
|
};
|
|
438
1660
|
|
|
439
|
-
|
|
1661
|
+
/**
|
|
1662
|
+
* Definition of a node type in the graph system
|
|
1663
|
+
*
|
|
1664
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
1665
|
+
*/
|
|
1666
|
+
export declare type TypeOfNode<DataTypeUniqueId extends string = string> = {
|
|
1667
|
+
/** Display name of the node type */
|
|
440
1668
|
name: string;
|
|
1669
|
+
/** Color used for the node header */
|
|
441
1670
|
headerColor?: string;
|
|
1671
|
+
/** Array of inputs (can be regular inputs or input panels) */
|
|
442
1672
|
inputs: (TypeOfInput<DataTypeUniqueId> | TypeOfInputPanel<DataTypeUniqueId>)[];
|
|
1673
|
+
/** Array of outputs */
|
|
443
1674
|
outputs: TypeOfInput<DataTypeUniqueId>[];
|
|
444
1675
|
};
|
|
445
1676
|
|
|
1677
|
+
/**
|
|
1678
|
+
* Custom hook for detecting clicks outside of a specified element
|
|
1679
|
+
*
|
|
1680
|
+
* This hook provides functionality to detect when a user clicks outside of a
|
|
1681
|
+
* specified element, commonly used for closing dropdowns, modals, or other
|
|
1682
|
+
* overlay components.
|
|
1683
|
+
*
|
|
1684
|
+
* @template T - The type of HTML element being referenced
|
|
1685
|
+
* @param ref - Reference to the element to monitor (can be RefObject or direct element)
|
|
1686
|
+
* @param callback - Function to call when a click outside is detected
|
|
1687
|
+
* @param checkDescendants - Whether to check if the click target is a descendant of the ref element (default: true)
|
|
1688
|
+
* @param checkCoordinates - Whether to use coordinate-based checking instead of DOM hierarchy (default: false)
|
|
1689
|
+
*
|
|
1690
|
+
* @example
|
|
1691
|
+
* ```tsx
|
|
1692
|
+
* function Dropdown() {
|
|
1693
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
1694
|
+
* const dropdownRef = useRef<HTMLDivElement>(null);
|
|
1695
|
+
*
|
|
1696
|
+
* useClickedOutside(dropdownRef, () => {
|
|
1697
|
+
* setIsOpen(false);
|
|
1698
|
+
* });
|
|
1699
|
+
*
|
|
1700
|
+
* return (
|
|
1701
|
+
* <div ref={dropdownRef}>
|
|
1702
|
+
* {isOpen && <div>Dropdown content</div>}
|
|
1703
|
+
* </div>
|
|
1704
|
+
* );
|
|
1705
|
+
* }
|
|
1706
|
+
* ```
|
|
1707
|
+
*
|
|
1708
|
+
* @example
|
|
1709
|
+
* ```tsx
|
|
1710
|
+
* // Using coordinate-based checking for more precise control
|
|
1711
|
+
* function Modal() {
|
|
1712
|
+
* const modalRef = useRef<HTMLDivElement>(null);
|
|
1713
|
+
*
|
|
1714
|
+
* useClickedOutside(
|
|
1715
|
+
* modalRef,
|
|
1716
|
+
* () => closeModal(),
|
|
1717
|
+
* false, // Don't check descendants
|
|
1718
|
+
* true // Use coordinate checking
|
|
1719
|
+
* );
|
|
1720
|
+
*
|
|
1721
|
+
* return <div ref={modalRef}>Modal content</div>;
|
|
1722
|
+
* }
|
|
1723
|
+
* ```
|
|
1724
|
+
*/
|
|
446
1725
|
export declare function useClickedOutside<T extends HTMLElement>(ref: RefObject<T | null> | T | null, callback: () => void, checkDescendants?: boolean, checkCoordinates?: boolean): void;
|
|
447
1726
|
|
|
448
1727
|
/**
|
|
@@ -493,6 +1772,81 @@ export declare type UseDragReturn = {
|
|
|
493
1772
|
dragRef: (element: HTMLElement | null) => void;
|
|
494
1773
|
};
|
|
495
1774
|
|
|
1775
|
+
/**
|
|
1776
|
+
* Custom hook for managing the full graph state with reducer
|
|
1777
|
+
*
|
|
1778
|
+
* This hook provides state management for the entire graph including nodes, edges,
|
|
1779
|
+
* data types, and node type definitions. It uses a reducer pattern for predictable
|
|
1780
|
+
* state updates.
|
|
1781
|
+
*
|
|
1782
|
+
* @template DataTypeUniqueId - Unique identifier type for data types
|
|
1783
|
+
* @template NodeTypeUniqueId - Unique identifier type for node types
|
|
1784
|
+
* @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
|
|
1785
|
+
* @template ComplexSchemaType - Zod schema type for complex data types
|
|
1786
|
+
* @param initialState - The initial state of the graph
|
|
1787
|
+
* @returns Object containing the current state and dispatch function
|
|
1788
|
+
*
|
|
1789
|
+
* @example
|
|
1790
|
+
* ```tsx
|
|
1791
|
+
* import {
|
|
1792
|
+
* useFullGraph,
|
|
1793
|
+
* makeStateWithAutoInfer,
|
|
1794
|
+
* makeNodeIdToNodeTypeWithAutoInfer,
|
|
1795
|
+
* makeTypeOfNodeWithAutoInfer,
|
|
1796
|
+
* makeDataTypeWithAutoInfer
|
|
1797
|
+
* } from 'react-blender-nodes';
|
|
1798
|
+
*
|
|
1799
|
+
* // Define data types with auto-infer for type safety
|
|
1800
|
+
* const dataTypes = {
|
|
1801
|
+
* stringType: makeDataTypeWithAutoInfer({
|
|
1802
|
+
* name: 'String',
|
|
1803
|
+
* underlyingType: 'string',
|
|
1804
|
+
* color: '#4A90E2',
|
|
1805
|
+
* }),
|
|
1806
|
+
* numberType: makeDataTypeWithAutoInfer({
|
|
1807
|
+
* name: 'Number',
|
|
1808
|
+
* underlyingType: 'number',
|
|
1809
|
+
* color: '#E74C3C',
|
|
1810
|
+
* }),
|
|
1811
|
+
* };
|
|
1812
|
+
*
|
|
1813
|
+
* // Define node types with auto-infer for type safety
|
|
1814
|
+
* const typeOfNodes = {
|
|
1815
|
+
* inputNode: makeTypeOfNodeWithAutoInfer({
|
|
1816
|
+
* name: 'Input Node',
|
|
1817
|
+
* headerColor: '#C44536',
|
|
1818
|
+
* inputs: [
|
|
1819
|
+
* { name: 'Input', dataType: 'stringType', allowInput: true }
|
|
1820
|
+
* ],
|
|
1821
|
+
* outputs: [
|
|
1822
|
+
* { name: 'Output', dataType: 'stringType' }
|
|
1823
|
+
* ],
|
|
1824
|
+
* }),
|
|
1825
|
+
* };
|
|
1826
|
+
*
|
|
1827
|
+
* // Define node ID to type mapping with auto-infer
|
|
1828
|
+
* const nodeIdToNodeType = makeNodeIdToNodeTypeWithAutoInfer({
|
|
1829
|
+
* 'node-1': 'inputNode',
|
|
1830
|
+
* });
|
|
1831
|
+
*
|
|
1832
|
+
* // Create state with auto-infer for complete type safety
|
|
1833
|
+
* const initialState = makeStateWithAutoInfer({
|
|
1834
|
+
* dataTypes,
|
|
1835
|
+
* typeOfNodes,
|
|
1836
|
+
* nodeIdToNodeType,
|
|
1837
|
+
* nodes: [],
|
|
1838
|
+
* edges: [],
|
|
1839
|
+
* });
|
|
1840
|
+
*
|
|
1841
|
+
* const { state, dispatch } = useFullGraph(initialState);
|
|
1842
|
+
*
|
|
1843
|
+
* // Add a new node (type-safe!)
|
|
1844
|
+
* dispatch({
|
|
1845
|
+
* type: 'ADD_NODE',
|
|
1846
|
+
* payload: { type: 'inputNode', position: { x: 100, y: 100 } },
|
|
1847
|
+
* });
|
|
1848
|
+
* ```
|
|
1849
|
+
*/
|
|
496
1850
|
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
1851
|
state: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>;
|
|
498
1852
|
dispatch: ActionDispatch<[action: Action<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>]>;
|