/** * @file Example demonstrating type-safe node definitions using generics */ import React from "react"; import classes from "./TypedNodesExample.module.css"; import { NodeRendererProps, InspectorRenderProps, createNodeDefinition } from "../../../../types/NodeDefinition"; // For this example, we'll define the types directly type CounterNodeData = { label: string; count: number; step: number; }; type TextDisplayData = { title: string; content: string; fontSize: number; }; // Step 2: Create type-safe node renderers (without module augmentation for this example) const CounterNodeRenderer = ({ node, onUpdateNode }: NodeRendererProps): React.ReactElement => { // For the example, we'll use type assertions const { label, count, step } = node.data as CounterNodeData; const handleIncrement = () => { onUpdateNode({ data: { ...node.data, count: count + step } }); }; const handleDecrement = () => { onUpdateNode({ data: { ...node.data, count: count - step } }); }; return (

{label}

{count}
); }; const CounterNodeInspector = ({ node, onUpdateNode }: InspectorRenderProps): React.ReactElement => { const { label, count, step } = node.data as CounterNodeData; return (
onUpdateNode({ data: { ...node.data, label: e.target.value } })} />
onUpdateNode({ data: { ...node.data, count: Number(e.target.value) } })} />
onUpdateNode({ data: { ...node.data, step: Number(e.target.value) } })} />
); }; // Step 3: Create the node definition export const CounterNodeDefinition = createNodeDefinition({ type: "counter-node", displayName: "Counter", description: "A node that maintains a counter", category: "Interactive", defaultData: { label: "Counter", count: 0, step: 1, }, defaultSize: { width: 200, height: 150 }, renderNode: CounterNodeRenderer, renderInspector: CounterNodeInspector, ports: [ { id: "value", type: "output", label: "Value", position: "right", }, ], }); // Text Display Node const TextDisplayRenderer = ({ node }: NodeRendererProps): React.ReactElement => { const { title, content, fontSize } = node.data as TextDisplayData; return (

{title}

{content}

); }; const TextDisplayInspector = ({ node, onUpdateNode }: InspectorRenderProps): React.ReactElement => { const { title, content, fontSize } = node.data as TextDisplayData; return (
onUpdateNode({ data: { ...node.data, title: e.target.value } })} />