Create a new canvas node type for SymposiumAI, composing from shared primitives (NodeHandles, NodeHeader, NodeActions, EditableField)
Create a new node type for the SymposiumAI canvas.
$ARGUMENTS
Every node MUST be composed from these shared primitives:
NodeHandles (8 connection points)
└── wrapper div (styled with getCardStyle or getRunStyle)
├── NodeActions (connect/edit/delete toolbar)
├── NodeHeader (colored icon + label)
└── Content area (type-specific UI)
import { NodeHandles } from "./node-handles";
import { NodeActions } from "./node-actions";
import { NodeHeader } from "./node-header";
import { EditableField } from "./editable-field";
import { useNodeData } from "@/hooks/use-node-data";
import { useConnectMode } from "@/hooks/use-connect-mode";
import { getCardStyle, tintBg, getConnectHoverShadow } from "@/lib/node-style";
import { NODE_COLORS } from "@/config/constants";
Define the data type in src/types/canvas.ts:
CanvasNodeData union typeCanvasNode type unionChoose an accent color — add to NODE_COLORS in src/config/constants.ts if new
Create the component in src/components/canvas/[name]-node.tsx:
useNodeData<YourDataType>(id, data) for type-safe stateuseConnectMode() for connection UI stategetCardStyle(color, selected) for left-accent style (or getRunStyle for uniform border)getConnectHoverShadow(color)Register in FlowCanvas — add to nodeTypes map in src/components/canvas/flow-canvas.tsx
Add creation logic — add a button/action in prompt bar or toolbar
Create Storybook story in src/stories/
text-node.tsx — simplest example (single editable text field)concept-card-node.tsx — multi-field example (title, description, tags)image-node.tsx — file input example (drag-drop + base64)run-node.tsx — AI output example (different styling with getRunStyle)