@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/README.md +276 -114
- package/dist/index.d.ts +980 -20
- package/dist/react-blender-nodes.css +1 -1
- package/dist/react-blender-nodes.es.js.map +1 -1
- package/dist/react-blender-nodes.umd.js.map +1 -1
- package/package.json +6 -1
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
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
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
|
-
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*}
|
|
376
|
-
*
|
|
377
|
-
*
|
|
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>]>;
|