@octaviaflow/core 3.1.0-beta.78 → 3.1.0-beta.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-FJHUWP4K.js +2756 -0
- package/dist/chunk-FJHUWP4K.js.map +1 -0
- package/dist/chunk-PB4O5GEF.js +5701 -0
- package/dist/chunk-PB4O5GEF.js.map +1 -0
- package/dist/chunk-XD5G2K2M.js +1646 -0
- package/dist/chunk-XD5G2K2M.js.map +1 -0
- package/dist/components/AuthScreen/AuthScreen.d.ts +17 -2
- package/dist/components/AuthScreen/AuthScreen.d.ts.map +1 -1
- package/dist/components/Combobox/Combobox.d.ts.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/components/DatePicker/DatePicker.d.ts.map +1 -1
- package/dist/components/Dialog/Dialog.d.ts.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.d.ts.map +1 -1
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/index.cjs +636 -555
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +270 -193
- package/dist/index.js.map +1 -1
- package/dist/marketing.cjs +1 -0
- package/dist/marketing.cjs.map +1 -1
- package/dist/marketing.js +2 -2
- package/dist/styles.css +1 -1
- package/dist/workflow.cjs +2 -0
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.js +2 -2
- package/package.json +1 -1
package/dist/workflow.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/workflow/index.ts","../src/workflow/hooks/useAutoLayout.ts","../src/workflow/store/changes.ts","../src/workflow/hooks/useFlow.ts","../src/workflow/hooks/useFlowState.ts","../src/workflow/utils/geometry.ts","../src/workflow/layout/dagre.ts","../src/workflow/layout/elk.ts","../src/workflow/store/selectors.ts","../src/workflow/store/context.ts","../src/workflow/components/ConfigPanel/ConfigPanel.tsx","../src/utils/cn.ts","../src/workflow/components/HttpActionPanel/HttpActionPanel.tsx","../src/components/Accordion/Accordion.tsx","../src/components/Badge/Badge.tsx","../src/utils/Slot.tsx","../src/utils/composeRefs.ts","../src/components/Banner/Banner.tsx","../src/components/Button/Button.tsx","../src/utils/a11y.ts","../src/components/CodeEditor/CodeEditor.tsx","../src/components/Combobox/Combobox.tsx","../src/components/Disclosure/Disclosure.tsx","../src/components/Input/Input.tsx","../src/components/JsonViewer/JsonViewer.tsx","../src/components/InlineMessage/InlineMessage.tsx","../src/components/KeyValueEditor/KeyValueEditor.tsx","../src/components/Checkbox/Checkbox.tsx","../../../node_modules/react-stately/dist/private/utils/packages/react-stately/src/utils/useControlledState.ts","../../../node_modules/react-stately/dist/private/form/packages/react-stately/src/form/useFormValidationState.ts","../../../node_modules/react-stately/dist/private/collections/packages/react-stately/src/collections/getChildNodes.ts","../../../node_modules/react-stately/dist/private/list/packages/react-stately/src/list/ListCollection.ts","../../../node_modules/react-stately/dist/private/selection/packages/react-stately/src/selection/Selection.ts","../../../node_modules/react-stately/dist/private/selection/packages/react-stately/src/selection/useMultipleSelectionState.ts","../../../node_modules/react-stately/dist/private/selection/packages/react-stately/src/selection/SelectionManager.ts","../../../node_modules/react-stately/dist/private/collections/packages/react-stately/src/collections/CollectionBuilder.ts","../../../node_modules/react-stately/dist/private/collections/packages/react-stately/src/collections/useCollection.ts","../../../node_modules/react-stately/dist/private/list/packages/react-stately/src/list/useListState.ts","../../../node_modules/react-stately/dist/private/overlays/packages/react-stately/src/overlays/useOverlayTriggerState.ts","../../../node_modules/react-stately/dist/private/collections/packages/react-stately/src/collections/Item.ts","../../../node_modules/react-stately/dist/private/list/packages/react-stately/src/list/useSingleSelectListState.ts","../../../node_modules/react-stately/dist/private/select/packages/react-stately/src/select/useSelectState.ts","../../../node_modules/react-stately/dist/private/tabs/packages/react-stately/src/tabs/useTabListState.ts","../../../node_modules/react-stately/dist/private/toggle/packages/react-stately/src/toggle/useToggleState.ts","../../../node_modules/react-stately/dist/private/tooltip/packages/react-stately/src/tooltip/useTooltipTriggerState.ts","../src/components/NumberInput/NumberInput.tsx","../src/components/PasswordInput/PasswordInput.tsx","../src/hooks/usePasswordStrength.ts","../src/components/SegmentedControl/SegmentedControl.tsx","../src/components/Select/Select.tsx","../src/components/Tooltip/Tooltip.tsx","../src/components/Spinner/Spinner.tsx","../src/components/Switch/Switch.tsx","../src/components/Tabs/Tabs.tsx","../src/workflow/components/HttpActionPanel/httpActionTypes.ts","../src/workflow/components/FlowCanvas/FlowCanvas.tsx","../src/workflow/store/createFlowStore.ts","../src/workflow/utils/collision.ts","../src/workflow/utils/parenting.ts","../src/workflow/components/FlowEdge/FlowEdge.tsx","../src/workflow/utils/paths.ts","../src/workflow/components/Handle/handleRegistry.ts","../src/workflow/components/FlowNode/FlowNode.tsx","../src/workflow/components/FlowCanvas/FlowCanvasContext.tsx","../src/workflow/components/FlowNode/FlowNodeContext.tsx","../src/workflow/components/FlowNode/nodeKinds.ts","../src/workflow/components/Handle/Handle.tsx","../src/workflow/components/NodeResizer/NodeResizer.tsx","../src/workflow/components/kinds/BaseNode.tsx","../src/workflow/components/kinds/index.tsx","../src/workflow/components/FxPanel/FxPanel.tsx","../src/workflow/components/FxPanel/DataRefButton.tsx","../src/workflow/components/NodeToolbar/NodeToolbar.tsx","../src/workflow/utils/collapse.ts"],"sourcesContent":["// ════════════════════════════════════════════════════════════════════════\n// `@octaviaflow/core/workflow` — public surface for the new editor.\n// ════════════════════════════════════════════════════════════════════════\n// The legacy editor stays at `@octaviaflow/core` (root) for one minor\n// release. Consumers migrate by switching their import path.\n\n// ── Types ───────────────────────────────────────────────────────────────\nexport type {\n BuiltInEdgeKind,\n BuiltInNodeKind,\n ConnectEndState,\n Connection,\n ConnectStartParams,\n Dimensions,\n EdgeChange,\n EdgeKind,\n FitViewOptions,\n HandlePosition,\n HandleType,\n LayoutDirection,\n LayoutEngine,\n LayoutOptions,\n NodeChange,\n NodeKind,\n Position,\n Rect,\n SelectionState,\n Viewport,\n WorkflowEdge,\n WorkflowNode,\n} from \"./editor\";\nexport {\n type UseAutoLayoutOptions,\n type UseAutoLayoutResult,\n useAutoLayout,\n} from \"./hooks/useAutoLayout\";\nexport { type FlowInstance, useFlow } from \"./hooks/useFlow\";\n// ── Hooks ───────────────────────────────────────────────────────────────\nexport {\n type FlowStateBag,\n type NodeDataPatch,\n type UseFlowStateOptions,\n useFlowState,\n} from \"./hooks/useFlowState\";\n// ── Layout engine adapters ─────────────────────────────────────────────\n// Consumers install `dagre` and/or `elkjs` themselves, then pass the\n// module to these factories. See ADR-001 — the DS never bundles the\n// underlying library.\nexport { type CreateDagreEngineOptions, createDagreEngine } from \"./layout/dagre\";\nexport { type CreateElkEngineOptions, createElkEngine } from \"./layout/elk\";\nexport type {\n DagreGraph,\n DagreLike,\n ElkEdge,\n ElkGraph,\n ElkLike,\n} from \"./layout/types\";\n// ── Change reducers ─────────────────────────────────────────────────────\nexport { applyEdgeChanges, applyNodeChanges, change } from \"./store/changes\";\n// ── Selectors (descendants of <FlowCanvas>) ─────────────────────────────\nexport {\n useConnection,\n useEdgeById,\n useEdges,\n useFlowSelector,\n useIsEdgeSelected,\n useIsNodeSelected,\n useNodeById,\n useNodeData,\n useNodes,\n useSelection,\n useViewport,\n useViewportOrNull,\n} from \"./store/selectors\";\n\n// Store creation + context are intentionally NOT exported — they are\n// canvas internals (see ADR-005).\n\n// ── Components ─────────────────────────────────────────────────────────\nexport {\n ConfigPanel,\n type ConfigPanelProps,\n type ConfigPanelSaveState,\n type ConfigPanelTab,\n} from \"./components/ConfigPanel/ConfigPanel\";\nexport {\n HttpActionPanel,\n type HttpActionPanelProps,\n type HttpConnectionEndpoint,\n type HttpConnectionOption,\n} from \"./components/HttpActionPanel/HttpActionPanel\";\nexport {\n buildCurl,\n countGraphqlVariables,\n countSchemaPaths,\n effectiveUrl,\n HTTP_ACTION_DEFAULTS,\n HTTP_METHODS,\n type HttpActionConfig,\n type HttpAuthConfig,\n type HttpBodyType,\n type HttpKeyValue,\n type HttpMethod,\n type HttpPaginationConfig,\n type HttpPaginationType,\n type HttpPreviewRequest,\n type HttpPreviewResponse,\n type HttpResponseType,\n type HttpRetryConfig,\n type HttpValidationResult,\n inferJsonSchema,\n normalizeAuth,\n normalizeKeyValues,\n parseCurl,\n serializeKeyValues,\n validateHttpConfig,\n} from \"./components/HttpActionPanel/httpActionTypes\";\nexport { FlowCanvas, type FlowCanvasProps } from \"./components/FlowCanvas/FlowCanvas\";\nexport { FlowEdge, type FlowEdgeProps } from \"./components/FlowEdge/FlowEdge\";\nexport { FlowNode, type FlowNodeProps } from \"./components/FlowNode/FlowNode\";\nexport {\n FxPanel,\n type FxItemKind,\n type FxPanelCategory,\n type FxPanelItem,\n type FxPanelProps,\n type FxValueType,\n} from \"./components/FxPanel/FxPanel\";\nexport {\n DataRefButton,\n type DataRefButtonProps,\n} from \"./components/FxPanel/DataRefButton\";\nexport {\n type FlowNodeContextValue,\n useFlowNodeContext,\n} from \"./components/FlowNode/FlowNodeContext\";\nexport {\n buildNodeKindRegistry,\n type NodeKindComponent,\n type NodeKindProps,\n type NodeKindRegistry,\n} from \"./components/FlowNode/nodeKinds\";\nexport { Handle, type HandleProps } from \"./components/Handle/Handle\";\n// ── Built-in node kinds + their default registry ──────────────────────\nexport {\n ActionNode,\n type BuiltInNodeData,\n ConditionNode,\n DEFAULT_NODE_KINDS,\n ErrorNode,\n ForEachNode,\n GroupNode,\n HttpRequestNode,\n OutputNode,\n ParallelNode,\n StickyNode,\n TriggerNode,\n WaitNode,\n WebhookNode,\n} from \"./components/kinds\";\nexport { NodeResizer, type NodeResizerProps } from \"./components/NodeResizer/NodeResizer\";\nexport { NodeToolbar, type NodeToolbarProps } from \"./components/NodeToolbar/NodeToolbar\";\n// Re-export the public EdgeRouting type alias from the type module.\nexport type { EdgeRouting } from \"./editor\";\n// ── Collapse helpers ───────────────────────────────────────────────────\n// Re-route edges that cross a collapsed group's boundary so they\n// terminate at the group's perimeter handles instead of dangling.\nexport { collapseFor, toggleGroupCollapse } from \"./utils/collapse\";\n// ── Geometry helpers ───────────────────────────────────────────────────\nexport {\n bezierPath,\n DEFAULT_NODE_HEIGHT,\n DEFAULT_NODE_WIDTH,\n flowToScreen,\n handleCentre,\n screenToFlow,\n} from \"./utils/geometry\";\n// ── Parenting helpers ──────────────────────────────────────────────────\n// Useful for consumers that build their own drag UX (e.g. dragging from\n// a palette directly onto a group).\nexport {\n clampToParentExtent,\n descendantsOf,\n findAncestor,\n findContainingGroup,\n} from \"./utils/parenting\";\n// ── Path builders (advanced — for custom edge renderers) ───────────────\nexport {\n bezierPath as bezierPathFn,\n buildEdgePath,\n type EdgeRouting as EdgeRoutingMode,\n type PathGeometry,\n smoothStepPath,\n stepPath,\n straightPath,\n} from \"./utils/paths\";\n","// ════════════════════════════════════════════════════════════════════════\n// useAutoLayout — run a layout engine and apply its output via the\n// canvas's `onNodesChange` callback.\n// ════════════════════════════════════════════════════════════════════════\n// Two trigger modes:\n//\n// 1. Imperative — call the returned `runLayout()` function (e.g. from a\n// toolbar button). This is the recommended default; users press\n// \"Auto-arrange\" and the engine runs once.\n//\n// 2. Reactive — pass `auto: true`. The hook debounces 250ms on every\n// node/edge add/remove and runs the engine. Useful for \"always\n// auto-layout\" surfaces; expensive in graphs where users drag nodes\n// around (their positions get clobbered).\n//\n// The hook does NOT subscribe to selection / drag / viewport — it watches\n// only the *shape* of the graph (node ids + edge connections). That\n// keeps reactive mode from re-running on every pointermove.\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type {\n LayoutEngine,\n LayoutOptions,\n NodeChange,\n WorkflowEdge,\n WorkflowNode,\n} from \"../editor\";\nimport { change } from \"../store/changes\";\n\nexport interface UseAutoLayoutOptions {\n /** The engine. Required. */\n engine: LayoutEngine | null | undefined;\n /** Current nodes (controlled). */\n nodes: WorkflowNode[];\n /** Current edges (controlled). */\n edges: WorkflowEdge[];\n /** Where to send position changes. Required. */\n onNodesChange?: (changes: NodeChange[]) => void;\n /** Layout options forwarded to the engine. */\n options?: LayoutOptions;\n /** Re-run on every graph-shape change (debounced 250ms). Default false. */\n auto?: boolean;\n /** Debounce delay for `auto` mode (ms). Default 250. */\n debounceMs?: number;\n /** Called after each successful run. */\n onLayout?: (positions: { id: string; position: { x: number; y: number } }[]) => void;\n /** Called when the engine throws (network / worker / library). */\n onError?: (err: unknown) => void;\n}\n\nexport interface UseAutoLayoutResult {\n /** Manually trigger a layout pass. Returns the promise of the engine. */\n runLayout(): Promise<void>;\n /** True while a layout pass is in flight. */\n isLaying: boolean;\n}\n\n/**\n * Build a stable graph-shape signature so reactive mode only re-runs when\n * the structure (node ids + edges) changes, not on position/select/drag.\n */\nfunction signature(nodes: WorkflowNode[], edges: WorkflowEdge[]): string {\n // Sorted to be invariant under array re-ordering.\n const nodeKeys = nodes\n .map((n) => `${n.id}:${n.parentId ?? \"\"}`)\n .sort()\n .join(\"|\");\n const edgeKeys = edges\n .map((e) => `${e.id}:${e.source}>${e.target}`)\n .sort()\n .join(\"|\");\n return `${nodeKeys}::${edgeKeys}`;\n}\n\nexport function useAutoLayout({\n engine,\n nodes,\n edges,\n onNodesChange,\n options,\n auto = false,\n debounceMs = 250,\n onLayout,\n onError,\n}: UseAutoLayoutOptions): UseAutoLayoutResult {\n const [isLaying, setIsLaying] = useState(false);\n const runningRef = useRef(false);\n const optionsRef = useRef(options);\n const onLayoutRef = useRef(onLayout);\n const onErrorRef = useRef(onError);\n const onNodesChangeRef = useRef(onNodesChange);\n useEffect(() => {\n optionsRef.current = options;\n }, [options]);\n useEffect(() => {\n onLayoutRef.current = onLayout;\n }, [onLayout]);\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n useEffect(() => {\n onNodesChangeRef.current = onNodesChange;\n }, [onNodesChange]);\n\n // Snapshot refs of nodes/edges so the runLayout callback can read fresh\n // data without re-creating itself on every render.\n const nodesRef = useRef(nodes);\n const edgesRef = useRef(edges);\n useEffect(() => {\n nodesRef.current = nodes;\n }, [nodes]);\n useEffect(() => {\n edgesRef.current = edges;\n }, [edges]);\n\n const runLayout = useCallback(async () => {\n if (!engine) return;\n if (runningRef.current) return;\n runningRef.current = true;\n setIsLaying(true);\n try {\n const positions = await engine.layout(nodesRef.current, edgesRef.current, optionsRef.current);\n\n // Index engine output by id + remember per-node deltas so we can\n // transitively apply them to descendants (children move with the\n // parent — otherwise a parent moves and its children get stranded\n // outside the new bbox, which is the v1 subflow auto-layout bug).\n const positionedIds = new Set(positions.map((p) => p.id));\n const deltas = new Map<string, { dx: number; dy: number }>();\n\n const cs: NodeChange[] = [];\n for (const p of positions) {\n const cur = nodesRef.current.find((n) => n.id === p.id);\n if (!cur) continue;\n if (cur.position.x === p.position.x && cur.position.y === p.position.y) continue;\n cs.push(change.node.position(p.id, p.position, false));\n deltas.set(p.id, {\n dx: p.position.x - cur.position.x,\n dy: p.position.y - cur.position.y,\n });\n }\n\n // For every node the engine did NOT reposition (typically because\n // it sat in a sub-flow that the engine treated as opaque), walk up\n // the parentId chain to find the nearest moved ancestor. Shift the\n // descendant by that ancestor's delta. The first moved ancestor\n // wins — we don't sum deltas because each child's position is\n // already relative to its ancestor's old position.\n const findParent = (id: string): WorkflowNode | undefined =>\n nodesRef.current.find((x) => x.id === id);\n\n for (const n of nodesRef.current) {\n if (positionedIds.has(n.id)) continue;\n if (!n.parentId) continue;\n let cursor: string | undefined = n.parentId;\n const seen = new Set<string>();\n let delta: { dx: number; dy: number } | undefined;\n while (cursor) {\n if (seen.has(cursor)) break; // cycle guard\n seen.add(cursor);\n const found = deltas.get(cursor);\n if (found) {\n delta = found;\n break;\n }\n cursor = findParent(cursor)?.parentId;\n }\n if (!delta) continue;\n cs.push(\n change.node.position(\n n.id,\n { x: n.position.x + delta.dx, y: n.position.y + delta.dy },\n false,\n ),\n );\n }\n\n if (cs.length) onNodesChangeRef.current?.(cs);\n onLayoutRef.current?.(positions);\n } catch (err) {\n onErrorRef.current?.(err);\n } finally {\n runningRef.current = false;\n setIsLaying(false);\n }\n }, [engine]);\n\n // Reactive auto-mode — debounce on graph-shape changes.\n const sig = signature(nodes, edges);\n const sigRef = useRef(sig);\n useEffect(() => {\n if (!auto) return;\n if (sigRef.current === sig) return; // first render after toggling auto\n sigRef.current = sig;\n const timer = setTimeout(() => void runLayout(), debounceMs);\n return () => clearTimeout(timer);\n }, [sig, auto, debounceMs, runLayout]);\n\n return { runLayout, isLaying };\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Change reducers — apply node/edge change arrays in one immutable pass.\n// ════════════════════════════════════════════════════════════════════════\n// Consumers in controlled mode write:\n//\n// <FlowCanvas\n// nodes={nodes}\n// edges={edges}\n// onNodesChange={(changes) => setNodes((ns) => applyNodeChanges(ns, changes))}\n// onEdgesChange={(changes) => setEdges((es) => applyEdgeChanges(es, changes))}\n// />\n//\n// The helpers run in O(n + m) where n is the existing list and m the\n// change count, with one shallow clone per touched item. Add / remove\n// short-circuit when the array is unchanged, so React's reconciler\n// happily reuses references.\n\nimport type { EdgeChange, NodeChange, WorkflowEdge, WorkflowNode } from \"../editor\";\n\n/**\n * Apply a batch of node changes to an existing node list. Returns a\n * **new array** if anything changed, the **same array** otherwise (so\n * React.memo'd children don't re-render unnecessarily).\n */\nexport function applyNodeChanges<TData = unknown>(\n nodes: WorkflowNode<TData>[],\n changes: NodeChange<TData>[],\n): WorkflowNode<TData>[] {\n if (changes.length === 0) return nodes;\n\n // Bucket changes by id for O(1) lookup during the single map pass.\n const byId = new Map<string, NodeChange<TData>[]>();\n const adds: WorkflowNode<TData>[] = [];\n const removes = new Set<string>();\n let touched = false;\n\n for (const change of changes) {\n switch (change.type) {\n case \"add\":\n adds.push(change.item);\n touched = true;\n break;\n case \"remove\":\n removes.add(change.id);\n touched = true;\n break;\n default: {\n const id = change.id;\n const arr = byId.get(id);\n if (arr) arr.push(change);\n else byId.set(id, [change]);\n touched = true;\n break;\n }\n }\n }\n\n if (!touched) return nodes;\n\n const next: WorkflowNode<TData>[] = [];\n for (const node of nodes) {\n if (removes.has(node.id)) continue;\n const patches = byId.get(node.id);\n if (!patches) {\n next.push(node);\n continue;\n }\n let n: WorkflowNode<TData> = node;\n for (const patch of patches) {\n switch (patch.type) {\n case \"position\":\n n = {\n ...n,\n position: patch.position,\n dragging: patch.dragging,\n };\n break;\n case \"dimensions\":\n n = {\n ...n,\n width: patch.dimensions.width,\n height: patch.dimensions.height,\n };\n break;\n case \"select\":\n // Skip if already in the target state — keeps reference stable.\n if (n.selected === patch.selected) break;\n n = { ...n, selected: patch.selected };\n break;\n case \"replace\":\n n = patch.item;\n break;\n }\n }\n next.push(n);\n }\n\n // Adds go to the end. Parents must precede children (caller's\n // responsibility; we don't reorder mid-application because that would\n // make `replace` unpredictable when a child already exists).\n for (const add of adds) next.push(add);\n\n return next;\n}\n\n/**\n * Apply a batch of edge changes. Same shape as `applyNodeChanges`.\n */\nexport function applyEdgeChanges<TData = unknown>(\n edges: WorkflowEdge<TData>[],\n changes: EdgeChange<TData>[],\n): WorkflowEdge<TData>[] {\n if (changes.length === 0) return edges;\n\n const byId = new Map<string, EdgeChange<TData>[]>();\n const adds: WorkflowEdge<TData>[] = [];\n const removes = new Set<string>();\n let touched = false;\n\n for (const change of changes) {\n switch (change.type) {\n case \"add\":\n adds.push(change.item);\n touched = true;\n break;\n case \"remove\":\n removes.add(change.id);\n touched = true;\n break;\n default: {\n const arr = byId.get(change.id);\n if (arr) arr.push(change);\n else byId.set(change.id, [change]);\n touched = true;\n break;\n }\n }\n }\n\n if (!touched) return edges;\n\n const next: WorkflowEdge<TData>[] = [];\n for (const edge of edges) {\n if (removes.has(edge.id)) continue;\n const patches = byId.get(edge.id);\n if (!patches) {\n next.push(edge);\n continue;\n }\n let e: WorkflowEdge<TData> = edge;\n for (const patch of patches) {\n switch (patch.type) {\n case \"select\":\n if (e.selected === patch.selected) break;\n e = { ...e, selected: patch.selected };\n break;\n case \"replace\":\n e = patch.item;\n break;\n }\n }\n next.push(e);\n }\n\n for (const add of adds) next.push(add);\n return next;\n}\n\n// ── Convenience builders ────────────────────────────────────────────────\n// Used by the store / hooks internally. Public consumers usually let the\n// canvas emit changes; these are handy for tests + custom interactions.\n\nexport const change = {\n node: {\n add<TData>(item: WorkflowNode<TData>): NodeChange<TData> {\n return { type: \"add\", item };\n },\n remove<TData>(id: string): NodeChange<TData> {\n return { type: \"remove\", id };\n },\n position<TData>(\n id: string,\n position: { x: number; y: number },\n dragging: boolean,\n ): NodeChange<TData> {\n return { type: \"position\", id, position, dragging };\n },\n dimensions<TData>(\n id: string,\n dimensions: { width: number; height: number },\n ): NodeChange<TData> {\n return { type: \"dimensions\", id, dimensions };\n },\n select<TData>(id: string, selected: boolean): NodeChange<TData> {\n return { type: \"select\", id, selected };\n },\n replace<TData>(id: string, item: WorkflowNode<TData>): NodeChange<TData> {\n return { type: \"replace\", id, item };\n },\n },\n edge: {\n add<TData>(item: WorkflowEdge<TData>): EdgeChange<TData> {\n return { type: \"add\", item };\n },\n remove<TData>(id: string): EdgeChange<TData> {\n return { type: \"remove\", id };\n },\n select<TData>(id: string, selected: boolean): EdgeChange<TData> {\n return { type: \"select\", id, selected };\n },\n replace<TData>(id: string, item: WorkflowEdge<TData>): EdgeChange<TData> {\n return { type: \"replace\", id, item };\n },\n },\n};\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// useFlow — imperative instance for the workflow editor.\n// ════════════════════════════════════════════════════════════════════════\n// Consumers reach inside `<FlowCanvas>` via this hook to do things that\n// React's declarative API can't express cleanly:\n//\n// - convert between screen and flow coordinates (drag-from-palette\n// needs to know where the pointer landed in flow space)\n// - imperatively fit the viewport to a set of nodes (\"zoom to error\")\n// - query intersecting nodes for marquee select / dragover hits\n// - patch node data without round-tripping through the parent reducer\n// - request a delete that respects `onBeforeDelete` veto\n//\n// All methods read from the FlowStore via narrow selectors, so the hook\n// itself doesn't trigger re-renders when state changes. The instance\n// reference is stable for the lifetime of the canvas.\n\nimport { createContext, useContext } from \"react\";\nimport type {\n FitViewOptions,\n Position,\n Rect,\n Viewport,\n WorkflowEdge,\n WorkflowNode,\n} from \"../editor\";\n\nexport interface FlowInstance {\n // ── Viewport ───────────────────────────────────────────────────────\n getViewport(): Viewport;\n setViewport(viewport: Viewport, opts?: { duration?: number }): void;\n setCenter(x: number, y: number, opts?: { duration?: number; zoom?: number }): void;\n fitView(opts?: FitViewOptions): Promise<boolean>;\n zoomIn(opts?: { step?: number }): void;\n zoomOut(opts?: { step?: number }): void;\n zoomTo(level: number): void;\n\n // ── Coordinate transforms ──────────────────────────────────────────\n /** Convert a pointer position (relative to the canvas container) into\n * flow-space coordinates. */\n screenToFlowPosition(p: Position): Position;\n /** Inverse of `screenToFlowPosition`. */\n flowToScreenPosition(p: Position): Position;\n\n // ── Data access (snapshot reads) ───────────────────────────────────\n getNodes(): WorkflowNode[];\n getEdges(): WorkflowEdge[];\n getNode(id: string): WorkflowNode | undefined;\n getEdge(id: string): WorkflowEdge | undefined;\n /** Axis-aligned bounding box of the given nodes (or every node when omitted). */\n getNodesBounds(nodes?: { id: string }[]): Rect;\n /** Find every node whose bbox overlaps the given rect.\n * `partially=true` includes partial overlaps; `false` requires full containment. */\n getIntersectingNodes(area: Rect, partially?: boolean): WorkflowNode[];\n\n // ── Mutation (round-tripped through onNodesChange/onEdgesChange) ──\n addNodes(nodes: WorkflowNode | WorkflowNode[]): void;\n addEdges(edges: WorkflowEdge | WorkflowEdge[]): void;\n /** Merge a partial into the node's existing `data` field. Cheap shorthand\n * for the common case of editing a node's payload without rebuilding it. */\n updateNodeData<TData = unknown>(id: string, partial: Partial<TData>): void;\n /** Replace the node entirely (use sparingly — usually `updateNodeData` is enough). */\n updateNode(id: string, partial: Partial<WorkflowNode>): void;\n /** Imperatively remove nodes and/or edges. Returns false if the host's\n * `onBeforeDelete` vetoed; true otherwise. Synchronous for non-async\n * vetoes; awaits the promise when the host returns one. */\n deleteElements(params: { nodes?: { id: string }[]; edges?: { id: string }[] }): Promise<boolean>;\n}\n\nexport const FlowInstanceContext = createContext<FlowInstance | null>(null);\n\n/**\n * Imperative handle for `<FlowCanvas>`. Throws if called outside the\n * canvas — the instance is canvas-scoped (not a global singleton) so\n * multiple canvases on the same page each have their own.\n */\nexport function useFlow(): FlowInstance {\n const instance = useContext(FlowInstanceContext);\n if (!instance) {\n throw new Error(\"[@octaviaflow/core/workflow] useFlow() must be called inside <FlowCanvas>.\");\n }\n return instance;\n}\n","// ════════════════════════════════════════════════════════════════════════\n// useFlowState — the uncontrolled-mode convenience.\n// ════════════════════════════════════════════════════════════════════════\n// Consumers that don't want to thread state through their own reducer\n// can use this hook and spread the result into <FlowCanvas>:\n//\n// const flow = useFlowState({ initialNodes, initialEdges });\n// <FlowCanvas {...flow} />\n//\n// In addition to the canonical change-stream contract, `useFlowState`\n// exposes per-node helpers — `updateNodeData(id, patch)` and the\n// companion `useNodeData(state, id)` selector — so individual node\n// updates can be expressed without re-mapping the entire nodes array\n// in caller code. Each helper writes ONLY the targeted node's slice;\n// React.memo'd kind components for other nodes never re-render.\n\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { EdgeChange, NodeChange, WorkflowEdge, WorkflowNode } from \"../editor\";\nimport { applyEdgeChanges, applyNodeChanges } from \"../store/changes\";\n\nexport interface UseFlowStateOptions<TNData = unknown, TEData = unknown> {\n initialNodes?: WorkflowNode<TNData>[];\n initialEdges?: WorkflowEdge<TEData>[];\n}\n\n/**\n * Patch type for `updateNodeData` — accepts a partial object that gets\n * shallow-merged, or a producer function `(prev) => next`.\n */\nexport type NodeDataPatch<TNData> =\n | Partial<TNData>\n | ((prev: TNData | undefined) => TNData | undefined);\n\nexport interface FlowStateBag<TNData = unknown, TEData = unknown> {\n nodes: WorkflowNode<TNData>[];\n edges: WorkflowEdge<TEData>[];\n onNodesChange: (changes: NodeChange<TNData>[]) => void;\n onEdgesChange: (changes: EdgeChange<TEData>[]) => void;\n setNodes: (\n update: WorkflowNode<TNData>[] | ((prev: WorkflowNode<TNData>[]) => WorkflowNode<TNData>[]),\n ) => void;\n setEdges: (\n update: WorkflowEdge<TEData>[] | ((prev: WorkflowEdge<TEData>[]) => WorkflowEdge<TEData>[]),\n ) => void;\n /**\n * Update the `data` slice of a single node by id. Only that node's\n * reference changes — every other node keeps its previous reference,\n * so React.memo'd kind components for unrelated nodes do not re-render.\n * No-ops when `id` is not present in the current nodes array.\n */\n updateNodeData: (id: string, patch: NodeDataPatch<TNData>) => void;\n /**\n * Read a single node by id from the latest snapshot. Returns undefined\n * if the id is unknown. Useful inside imperative callbacks that need\n * the freshest value without subscribing to re-renders.\n */\n getNode: (id: string) => WorkflowNode<TNData> | undefined;\n}\n\nexport function useFlowState<TNData = unknown, TEData = unknown>(\n options: UseFlowStateOptions<TNData, TEData> = {},\n): FlowStateBag<TNData, TEData> {\n const [nodes, setNodes] = useState<WorkflowNode<TNData>[]>(options.initialNodes ?? []);\n const [edges, setEdges] = useState<WorkflowEdge<TEData>[]>(options.initialEdges ?? []);\n\n // Ref-mirror of the latest nodes array. `getNode` reads through it so\n // imperative callers see fresh values without depending on render scope.\n const nodesRef = useRef(nodes);\n nodesRef.current = nodes;\n\n const onNodesChange = useCallback((changes: NodeChange<TNData>[]) => {\n setNodes((prev) => applyNodeChanges(prev, changes));\n }, []);\n\n const onEdgesChange = useCallback((changes: EdgeChange<TEData>[]) => {\n setEdges((prev) => applyEdgeChanges(prev, changes));\n }, []);\n\n const updateNodeData = useCallback((id: string, patch: NodeDataPatch<TNData>) => {\n setNodes((prev) => {\n let touched = false;\n const next: WorkflowNode<TNData>[] = prev.map((n) => {\n if (n.id !== id) return n;\n const nextData =\n typeof patch === \"function\"\n ? (patch as (p: TNData | undefined) => TNData | undefined)(n.data)\n : ({ ...(n.data ?? ({} as TNData)), ...patch } as TNData);\n if (Object.is(nextData, n.data)) return n;\n touched = true;\n return { ...n, data: nextData as TNData };\n });\n return touched ? next : prev;\n });\n }, []);\n\n const getNode = useCallback((id: string) => nodesRef.current.find((n) => n.id === id), []);\n\n return useMemo(\n () => ({\n nodes,\n edges,\n onNodesChange,\n onEdgesChange,\n setNodes,\n setEdges,\n updateNodeData,\n getNode,\n }),\n [nodes, edges, onNodesChange, onEdgesChange, updateNodeData, getNode],\n );\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Shared geometry helpers used by FlowNode, FlowEdge, and the connection\n// drag middleware. Pure functions — no state, no DOM.\n// ════════════════════════════════════════════════════════════════════════\n\nimport type { HandlePosition, Position, Viewport, WorkflowNode } from \"../editor\";\n\n// Default node footprint when the renderer hasn't yet measured a custom\n// node. Kept in lockstep with the BaseNode body width (368 px) so the\n// pre-measurement edge math anchors precisely on the handle dot. Height\n// stays 96 — the body min-height clamps the real measurement past that.\nexport const DEFAULT_NODE_WIDTH = 368;\nexport const DEFAULT_NODE_HEIGHT = 96;\n\n// Collapsed container heights — kept in lockstep with the values in\n// `kinds/index.tsx` (GroupNode renders `collapsed ? 36 : ...`,\n// ForEachNode renders `collapsed ? 40 : ...`). When a container is\n// collapsed its visual footprint shrinks to this header strip; edges to\n// the perimeter handles must use the same height or they'll terminate\n// hundreds of pixels below the visible node.\nexport const COLLAPSED_GROUP_HEIGHT = 36;\nexport const COLLAPSED_FOREACH_HEIGHT = 40;\n\n/**\n * The height the node *actually renders at* — accounts for collapsed\n * containers whose visual height differs from `node.height`. All edge\n * geometry should go through this helper instead of reading\n * `node.height` directly.\n */\nexport function effectiveHeight(node: WorkflowNode): number {\n const data = node.data as { collapsed?: boolean } | undefined;\n if (data?.collapsed) {\n if (node.type === \"group\") return COLLAPSED_GROUP_HEIGHT;\n if (node.type === \"forEach\") return COLLAPSED_FOREACH_HEIGHT;\n }\n return node.height ?? DEFAULT_NODE_HEIGHT;\n}\n\n/**\n * Compute the absolute (flow-space) centre of one of a node's handles.\n *\n * The handle's logical position (`top`/`right`/`bottom`/`left`) plus its\n * index among same-side handles determines a deterministic spread along\n * the relevant edge of the node bbox. We do NOT consult the DOM — the\n * source of truth is the node's measured (or default) dimensions.\n *\n * `total` is the count of handles on that side, `index` is this handle's\n * 0-based position among them. A single handle centres; multiple spread\n * evenly with equal margins.\n */\nexport function handleCentre(\n node: WorkflowNode,\n side: HandlePosition,\n index: number,\n total: number,\n): Position {\n const w = node.width ?? DEFAULT_NODE_WIDTH;\n // Use the EFFECTIVE rendered height — collapsed containers report a\n // tall `node.height` but visually render a 36-40px strip. Without this,\n // edges to a collapsed group's perimeter handle terminate hundreds of\n // pixels below the visible pill.\n const h = effectiveHeight(node);\n const x0 = node.position.x;\n const y0 = node.position.y;\n const denom = total + 1;\n const ratio = (index + 1) / denom;\n\n switch (side) {\n case \"top\":\n return { x: x0 + w * ratio, y: y0 };\n case \"bottom\":\n return { x: x0 + w * ratio, y: y0 + h };\n case \"left\":\n return { x: x0, y: y0 + h * ratio };\n case \"right\":\n return { x: x0 + w, y: y0 + h * ratio };\n }\n}\n\n/**\n * Cubic bezier path between two oriented points. The control points are\n * offset along each port's facing direction so the curve leaves and\n * enters along the port's axis (the same routing model as v1).\n */\nexport function bezierPath(\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n): { d: string; midX: number; midY: number } {\n const distance = Math.hypot(end.x - start.x, end.y - start.y);\n const magnitude = Math.max(40, Math.min(160, distance * 0.45));\n const c1 = offsetBySide(start, startSide, magnitude);\n const c2 = offsetBySide(end, endSide, magnitude);\n const d = `M ${start.x},${start.y} C ${c1.x},${c1.y} ${c2.x},${c2.y} ${end.x},${end.y}`;\n // Analytic midpoint of a cubic bezier at t = 0.5.\n const midX = 0.125 * start.x + 0.375 * c1.x + 0.375 * c2.x + 0.125 * end.x;\n const midY = 0.125 * start.y + 0.375 * c1.y + 0.375 * c2.y + 0.125 * end.y;\n return { d, midX, midY };\n}\n\nfunction offsetBySide(p: Position, side: HandlePosition, m: number): Position {\n switch (side) {\n case \"top\":\n return { x: p.x, y: p.y - m };\n case \"bottom\":\n return { x: p.x, y: p.y + m };\n case \"left\":\n return { x: p.x - m, y: p.y };\n case \"right\":\n return { x: p.x + m, y: p.y };\n }\n}\n\n/**\n * Convert a screen-space point (pixels relative to the viewport\n * container's top-left) to flow-space coordinates, given the current\n * viewport.\n */\nexport function screenToFlow(p: Position, vp: Viewport): Position {\n return {\n x: (p.x - vp.x) / vp.zoom,\n y: (p.y - vp.y) / vp.zoom,\n };\n}\n\n/**\n * Inverse of `screenToFlow`.\n */\nexport function flowToScreen(p: Position, vp: Viewport): Position {\n return {\n x: p.x * vp.zoom + vp.x,\n y: p.y * vp.zoom + vp.y,\n };\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Dagre adapter — wraps a consumer-supplied `dagre` module.\n// ════════════════════════════════════════════════════════════════════════\n// Usage:\n//\n// import dagre from \"dagre\";\n// import { createDagreEngine } from \"@octaviaflow/core/workflow\";\n//\n// const engine = createDagreEngine(dagre);\n// useAutoLayout({ engine, onLayout });\n//\n// Dagre is synchronous — `layout()` blocks the main thread. Good for\n// small graphs (≤ ~200 nodes). For larger graphs, see `createElkEngine`.\n\nimport type { LayoutEngine, LayoutOptions, Position, WorkflowEdge, WorkflowNode } from \"../editor\";\nimport { DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH } from \"../utils/geometry\";\nimport type { DagreLike } from \"./types\";\n\nexport interface CreateDagreEngineOptions {\n /** Default spacing between nodes within a rank (default 60). */\n nodeSpacing?: number;\n /** Default spacing between ranks (default 80). */\n rankSpacing?: number;\n /** Default direction — TB, BT, LR, RL. Defaults to TB. */\n direction?: LayoutOptions[\"direction\"];\n}\n\n/**\n * Build a `LayoutEngine` backed by a consumer-supplied `dagre` module.\n *\n * `dagre` can be passed as either the default export or the namespace\n * import (`import * as dagre from \"dagre\"`). The adapter probes both\n * shapes so consumers don't have to think about it.\n */\nexport function createDagreEngine(\n dagre:\n | DagreLike\n | { default: DagreLike }\n | { graphlib: DagreLike[\"graphlib\"]; layout: DagreLike[\"layout\"] },\n defaults: CreateDagreEngineOptions = {},\n): LayoutEngine {\n const lib = resolveDagre(dagre);\n const defaultDir = defaults.direction ?? \"TB\";\n const defaultNodeSpacing = defaults.nodeSpacing ?? 60;\n const defaultRankSpacing = defaults.rankSpacing ?? 80;\n\n return {\n name: \"dagre\",\n async layout(nodes: WorkflowNode[], edges: WorkflowEdge[], options?: LayoutOptions) {\n const direction = options?.direction ?? defaultDir;\n const nodesep = options?.nodeSpacing ?? defaultNodeSpacing;\n const ranksep = options?.rankSpacing ?? defaultRankSpacing;\n\n // Dagre requires every node to have width/height. Use the measured\n // values from the canvas; fall back to our default footprint.\n const g = new lib.graphlib.Graph({ multigraph: true, compound: true });\n g.setGraph({\n rankdir: direction,\n nodesep,\n ranksep,\n ...(options?.engine ?? {}),\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n for (const n of nodes) {\n if (n.hidden) continue;\n g.setNode(n.id, {\n width: n.width ?? DEFAULT_NODE_WIDTH,\n height: n.height ?? DEFAULT_NODE_HEIGHT,\n ...(n.parentId ? { parent: n.parentId } : {}),\n });\n // Compound graph: register the parent–child relationship.\n if (n.parentId) {\n // `setParent` is on the graph but not strongly typed in our\n // narrow surface — call via index access. dagre tolerates a\n // missing parent node (it auto-creates).\n (g as unknown as { setParent: (id: string, parent: string) => void }).setParent(\n n.id,\n n.parentId,\n );\n }\n }\n\n for (const e of edges) {\n if (e.hidden) continue;\n // Pass `e.id` as the multigraph edge NAME so parallel edges (e.g. a\n // condition's true + false branches both pointing at the same\n // downstream node) don't collapse into a single layout constraint.\n g.setEdge(e.source, e.target, { id: e.id }, e.id);\n }\n\n lib.layout(g);\n\n // Dagre stores node centres; our model uses top-left. Translate.\n const result: { id: string; position: Position }[] = [];\n for (const id of g.nodes()) {\n const out = g.node(id);\n if (!out) continue;\n result.push({\n id,\n position: { x: out.x - out.width / 2, y: out.y - out.height / 2 },\n });\n }\n return result;\n },\n };\n}\n\nfunction resolveDagre(input: unknown): DagreLike {\n const asAny = input as Partial<DagreLike> & { default?: DagreLike };\n if (asAny && typeof asAny.layout === \"function\" && asAny.graphlib?.Graph) {\n return asAny as DagreLike;\n }\n if (asAny?.default && typeof asAny.default.layout === \"function\") {\n return asAny.default;\n }\n throw new Error(\n \"[@octaviaflow/core/workflow] createDagreEngine: input does not look like the dagre module. \" +\n \"Pass `dagre` (the default export) or `import * as dagre from 'dagre'`.\",\n );\n}\n","// ════════════════════════════════════════════════════════════════════════\n// ELK adapter — wraps a consumer-supplied `elkjs` instance.\n// ════════════════════════════════════════════════════════════════════════\n// Usage (Web Worker — recommended for large graphs):\n//\n// import ELK from \"elkjs/lib/elk-api\";\n// import { createElkEngine } from \"@octaviaflow/core/workflow\";\n//\n// const elk = new ELK({ workerUrl: \"/elk-worker.min.js\" });\n// const engine = createElkEngine(elk);\n//\n// Usage (in-process, no worker):\n//\n// import ELK from \"elkjs/lib/elk.bundled\";\n// const elk = new ELK();\n// const engine = createElkEngine(elk);\n//\n// ELK supports compound graphs natively — nodes with `parentId` get\n// nested into the right `children[]` so subflow layouts just work.\n\nimport type { LayoutEngine, LayoutOptions, Position, WorkflowEdge, WorkflowNode } from \"../editor\";\nimport { DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH } from \"../utils/geometry\";\nimport type { ElkEdge, ElkGraph, ElkLike } from \"./types\";\n\nexport interface CreateElkEngineOptions {\n /** Default direction — TB / BT / LR / RL. Defaults to TB. */\n direction?: LayoutOptions[\"direction\"];\n /** Default node-to-node spacing within a layer (default 60). */\n nodeSpacing?: number;\n /** Default layer-to-layer spacing (default 80). */\n rankSpacing?: number;\n /** Override the algorithm. Defaults to `layered` (Sugiyama). */\n algorithm?:\n | \"layered\"\n | \"mrtree\"\n | \"force\"\n | \"stress\"\n | \"radial\"\n | \"disco\"\n | \"rectpacking\"\n | \"box\";\n}\n\nconst ELK_DIRECTION: Record<NonNullable<LayoutOptions[\"direction\"]>, string> = {\n TB: \"DOWN\",\n BT: \"UP\",\n LR: \"RIGHT\",\n RL: \"LEFT\",\n};\n\n/**\n * Build a `LayoutEngine` backed by a consumer-supplied `elkjs` instance.\n *\n * The consumer is responsible for constructing the ELK instance (which\n * may or may not run in a Web Worker — that's a `workerUrl` constructor\n * option on their end). Our adapter just calls `elk.layout(graph)` and\n * patches positions back.\n */\nexport function createElkEngine(elk: ElkLike, defaults: CreateElkEngineOptions = {}): LayoutEngine {\n const algorithm = defaults.algorithm ?? \"layered\";\n const defaultDir = defaults.direction ?? \"TB\";\n const defaultNodeSpacing = defaults.nodeSpacing ?? 60;\n const defaultRankSpacing = defaults.rankSpacing ?? 80;\n\n return {\n name: \"elk\",\n async layout(nodes: WorkflowNode[], edges: WorkflowEdge[], options?: LayoutOptions) {\n const direction = options?.direction ?? defaultDir;\n const nodeSpacing = options?.nodeSpacing ?? defaultNodeSpacing;\n const rankSpacing = options?.rankSpacing ?? defaultRankSpacing;\n\n // Build a nested ELK graph respecting `parentId` so compound layout\n // works. We walk the node list once into a parent → children map,\n // then recursively build ElkGraph.children[].\n const childrenByParent = new Map<string | undefined, WorkflowNode[]>();\n for (const n of nodes) {\n if (n.hidden) continue;\n const key = n.parentId ?? undefined;\n const list = childrenByParent.get(key);\n if (list) list.push(n);\n else childrenByParent.set(key, [n]);\n }\n\n // Engine options the consumer passed at the root, normalised to\n // strings. We propagate them onto every compound node too —\n // options like `elk.padding` apply per-node, so setting them only\n // on the root leaves nested compounds using ELK defaults.\n const engineOptions: Record<string, string> = Object.fromEntries(\n Object.entries(options?.engine ?? {}).map(([k, v]) => [k, String(v)]),\n );\n\n // Base layered options shared by the root graph and every compound\n // node. `considerModelOrder` makes ELK respect the INPUT ORDER of a\n // node's outgoing edges when it orders siblings within a layer — so a\n // condition's true/false branches and a forEach's each/done branches\n // land in the order the caller declared them (left → right) instead of\n // on whichever side crossing-minimisation happened to pick. That is\n // what stops branch wires from crossing back over each other at the\n // source node (DEV-201). The caller's `engine` options still win — we\n // spread `engineOptions` last everywhere.\n const baseLayeredOptions: Record<string, string> = {\n \"elk.algorithm\": algorithm,\n \"elk.direction\": ELK_DIRECTION[direction],\n \"elk.spacing.nodeNode\": String(nodeSpacing),\n \"elk.layered.spacing.nodeNodeBetweenLayers\": String(rankSpacing),\n \"elk.layered.considerModelOrder.strategy\": \"NODES_AND_EDGES\",\n };\n\n const buildChildren = (parentId: string | undefined): ElkGraph[] => {\n const list = childrenByParent.get(parentId) ?? [];\n return list.map<ElkGraph>((n) => ({\n id: n.id,\n width: n.width ?? DEFAULT_NODE_WIDTH,\n height: n.height ?? DEFAULT_NODE_HEIGHT,\n children: childrenByParent.has(n.id) ? buildChildren(n.id) : undefined,\n layoutOptions: childrenByParent.has(n.id)\n ? {\n ...baseLayeredOptions,\n ...engineOptions,\n }\n : undefined,\n }));\n };\n\n const elkEdges: ElkEdge[] = edges\n .filter((e) => !e.hidden)\n .map((e) => ({\n id: e.id,\n sources: [e.source],\n targets: [e.target],\n }));\n\n const graph: ElkGraph = {\n id: \"root\",\n layoutOptions: {\n ...baseLayeredOptions,\n ...engineOptions,\n },\n children: buildChildren(undefined),\n edges: elkEdges,\n };\n\n const laidOut = await elk.layout(graph);\n\n // Walk the resulting graph and collect (id, position). ELK returns\n // positions relative to the parent — we walk parents to flatten\n // back to absolute flow-space coordinates (matches our ADR-003\n // \"positions are always absolute\" rule).\n const result: { id: string; position: Position }[] = [];\n const walk = (g: ElkGraph, ox: number, oy: number) => {\n const ax = ox + (g.x ?? 0);\n const ay = oy + (g.y ?? 0);\n if (g.id !== \"root\") {\n result.push({ id: g.id, position: { x: ax, y: ay } });\n }\n if (g.children) {\n for (const c of g.children) walk(c, ax, ay);\n }\n };\n walk(laidOut, 0, 0);\n return result;\n },\n };\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Narrow selector hooks — the only sanctioned way to read from the store.\n// Each hook does one thing and subscribes to the smallest possible slice\n// so re-renders are surgical.\n// ════════════════════════════════════════════════════════════════════════\n\nimport { useContext, useMemo, useSyncExternalStore } from \"react\";\nimport type {\n ConnectStartParams,\n FlowStoreSnapshot,\n Viewport,\n WorkflowEdge,\n WorkflowNode,\n} from \"../editor\";\nimport { FlowStoreContext, useFlowStore } from \"./context\";\n\n/**\n * Generic selector hook. Use for one-off reads in tests or rare cases.\n * Public hooks below cover the common paths.\n *\n * NB: `selector` must be stable (referentially equal across renders) or\n * memoised — otherwise it re-subscribes every render. We do NOT do this\n * automatically because it would mask the bug.\n */\nexport function useFlowSelector<T>(\n selector: (snapshot: FlowStoreSnapshot) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n // Note: useSyncExternalStore uses Object.is internally for change\n // detection. The `isEqual` arg is reserved for a future patch that adds\n // structural equality (e.g. for array selectors); reference it so the\n // arg isn't dead.\n void isEqual;\n const store = useFlowStore();\n return useSyncExternalStore(\n store.subscribe,\n () => selector(store.getSnapshot()),\n () => selector(store.getSnapshot()),\n );\n}\n\n// ── Reads ──────────────────────────────────────────────────────────────\n\nexport function useNodes(): WorkflowNode[] {\n return useFlowSelector((s) => s.nodes);\n}\n\nexport function useEdges(): WorkflowEdge[] {\n return useFlowSelector((s) => s.edges);\n}\n\nexport function useViewport(): Viewport {\n return useFlowSelector((s) => s.viewport);\n}\n\nconst VIEWPORT_OR_NULL_NO_STORE_SUBSCRIBE = (_cb: () => void) => () => {};\nconst VIEWPORT_OR_NULL_NO_STORE_SNAPSHOT = (): Viewport | null => null;\n\n/**\n * Like `useViewport()` but returns `null` when called outside a\n * `<FlowCanvas>`. Useful for shared chrome components (FlowToolbarZoom,\n * minimap previews) that want to auto-subscribe when mounted inside the\n * canvas, but still render correctly in isolation (Storybook, design\n * docs) when no store is present.\n *\n * The subscribe/getSnapshot pair is memoised so React subscribes once per\n * mounted `<FlowCanvas>` ancestor — flipping in/out is rare (only when a\n * canvas is unmounted around the consumer).\n */\nexport function useViewportOrNull(): Viewport | null {\n const store = useContext(FlowStoreContext);\n const { sub, snap } = useMemo(\n () =>\n store\n ? {\n sub: store.subscribe,\n snap: (): Viewport | null => store.getSnapshot().viewport,\n }\n : {\n sub: VIEWPORT_OR_NULL_NO_STORE_SUBSCRIBE,\n snap: VIEWPORT_OR_NULL_NO_STORE_SNAPSHOT,\n },\n [store],\n );\n return useSyncExternalStore(sub, snap, snap);\n}\n\nexport function useNodeById(id: string): WorkflowNode | undefined {\n return useFlowSelector((s) => s.nodes.find((n) => n.id === id));\n}\n\n/**\n * Subscribe to the `data` slice of a single node by id. Re-renders only\n * when this specific node's `data` reference changes — no cross-node\n * leakage. Pair with `FlowStateBag.updateNodeData(id, patch)` to write.\n *\n * Returns undefined when the node is not present; consumers should\n * branch on that. Typed via the generic so callers get their `TData`\n * shape back without casting.\n */\nexport function useNodeData<TData = unknown>(id: string): TData | undefined {\n return useFlowSelector(\n (s) => (s.nodes.find((n) => n.id === id)?.data as TData | undefined) ?? undefined,\n );\n}\n\nexport function useEdgeById(id: string): WorkflowEdge | undefined {\n return useFlowSelector((s) => s.edges.find((e) => e.id === id));\n}\n\nexport function useIsNodeSelected(id: string): boolean {\n return useFlowSelector((s) => s.selectedNodeIds.has(id));\n}\n\nexport function useIsEdgeSelected(id: string): boolean {\n return useFlowSelector((s) => s.selectedEdgeIds.has(id));\n}\n\nexport function useConnection(): ConnectStartParams | null {\n return useFlowSelector((s) => s.connection);\n}\n\nexport function useSelection(): { nodes: WorkflowNode[]; edges: WorkflowEdge[] } {\n // Subscribe to each underlying slice separately so useSyncExternalStore\n // sees stable references — building a fresh object inside the selector\n // would force a re-render every render (snapshot-cache violation).\n const nodes = useNodes();\n const edges = useEdges();\n const selectedNodeIds = useFlowSelector((s) => s.selectedNodeIds);\n const selectedEdgeIds = useFlowSelector((s) => s.selectedEdgeIds);\n return useMemo(\n () => ({\n nodes: nodes.filter((n) => selectedNodeIds.has(n.id)),\n edges: edges.filter((e) => selectedEdgeIds.has(e.id)),\n }),\n [nodes, edges, selectedNodeIds, selectedEdgeIds],\n );\n}\n","// ════════════════════════════════════════════════════════════════════════\n// FlowStoreContext — descendants reach the store through this React\n// context. The store itself is NOT a context value (that would tank\n// perf); only the store *handle* is. Consumers read state via the\n// selector hooks in `./selectors.ts`.\n// ════════════════════════════════════════════════════════════════════════\n\nimport { createContext, useContext } from \"react\";\nimport type { FlowStore } from \"./createFlowStore\";\n\nexport const FlowStoreContext = createContext<FlowStore | null>(null);\n\nexport function useFlowStore(): FlowStore {\n const store = useContext(FlowStoreContext);\n if (!store) {\n throw new Error(\n \"[@octaviaflow/core/workflow] useFlowStore must be called inside a <FlowCanvas>.\",\n );\n }\n return store;\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// ConfigPanel v2 — right-side editor for the selected node.\n// ════════════════════════════════════════════════════════════════════════\n// Improvements over v1:\n// - Tabbed body (config / input / output schema; consumer can override)\n// - Resizable width (drag the left edge)\n// - Pinned vs floating modes\n// - Breadcrumb header showing node kind → title\n// - Footer with save-state pill (dirty / saving / saved)\n// - Slot for inline status banner (validation errors, etc.)\n// - Inline-edit-the-title affordance (double-click)\n// - Sticky footer with save / cancel buttons\n\nimport {\n type CSSProperties,\n type PointerEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../../utils/cn\";\n\nexport type ConfigPanelSaveState = \"clean\" | \"dirty\" | \"saving\" | \"saved\" | \"error\";\n\nexport interface ConfigPanelTab {\n id: string;\n label: ReactNode;\n /** Optional badge (e.g. count of errors). */\n badge?: ReactNode;\n /** When true, the tab is rendered but disabled. */\n disabled?: boolean;\n content: ReactNode;\n}\n\nexport interface ConfigPanelProps {\n open?: boolean;\n /** Title shown in the header — the action name. Double-click opens\n * the inline editor. The header shows this single line only. */\n title?: string;\n /** Optional icon rendered before the title. */\n icon?: ReactNode;\n /**\n * Modular header action slot — buttons rendered between the title and\n * the close (✕). Use it for per-action affordances like the FX\n * toggle; omit entirely for actions that don't need them.\n */\n headerActions?: ReactNode;\n /** Inline status banner — error / warning / hint, shown at the top of the body. */\n banner?: ReactNode;\n /** Tab definitions. When omitted, `children` renders directly (no tabs). */\n tabs?: ConfigPanelTab[];\n /** Initial active tab. Controlled if `onTabChange` is provided. */\n activeTab?: string;\n defaultActiveTab?: string;\n onTabChange?: (id: string) => void;\n /** Save-state pill in the footer. Omit it entirely to hide the pill —\n * the footer then shows only its action buttons. */\n saveState?: ConfigPanelSaveState;\n /** Fires on the title editor's commit. Omit to disable title editing. */\n onTitleChange?: (next: string) => void;\n onClose?: () => void;\n onSave?: () => void;\n onCancel?: () => void;\n /**\n * Padding (px, all sides) applied to the scrollable body — the work\n * area that holds the active tab's content. Default 12. Pass `0` when\n * the consumer's tab content already pads itself.\n */\n padding?: number;\n /** Resizable width — pass `resizable: false` to lock. */\n resizable?: boolean;\n /** Initial width (px). Defaults to 400. */\n defaultWidth?: number;\n /** Lower clamp during resize. Defaults to 400 — the panel can be\n * widened but never narrowed past its default. */\n minWidth?: number;\n /**\n * Upper clamp during resize. Defaults to 720. The panel ALSO clamps\n * to its parent container's measured width minus\n * `maxWidthContainerInset` (default 80 px) so the panel can never\n * cover the whole canvas — whichever is smaller wins.\n */\n maxWidth?: number;\n /**\n * How much of the parent container to leave visible at the panel's\n * widest. Subtracted from the parent's clientWidth before clamping\n * `maxWidth`. Defaults to 80 px.\n */\n maxWidthContainerInset?: number;\n /** \"pinned\" sits flush against the canvas; \"floating\" raises with shadow. */\n variant?: \"pinned\" | \"floating\";\n /** Body slot used only when `tabs` is omitted. */\n children?: ReactNode;\n /**\n * Modular footer action buttons — replaces the built-in Cancel/Save\n * pair. The footer bar itself stays static and pinned; this slot just\n * decides which buttons live in it, so a consumer can add, remove, or\n * reorder actions freely.\n */\n footerActions?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nconst SAVE_STATE_LABEL: Record<ConfigPanelSaveState, string> = {\n clean: \"Saved\",\n dirty: \"Unsaved changes\",\n saving: \"Saving…\",\n saved: \"Saved\",\n error: \"Save failed\",\n};\n\nconst SAVE_STATE_DOT: Record<ConfigPanelSaveState, string> = {\n clean: \"var(--ods-text-tertiary)\",\n dirty: \"var(--ods-status-warning, #d97706)\",\n saving: \"var(--ods-status-running, #2563eb)\",\n saved: \"var(--ods-status-success, #16a34a)\",\n error: \"var(--ods-status-failed, #dc2626)\",\n};\n\nexport function ConfigPanel({\n open = true,\n title,\n icon,\n headerActions,\n banner,\n tabs,\n activeTab: controlledActive,\n defaultActiveTab,\n onTabChange,\n saveState,\n onTitleChange,\n onClose,\n onSave,\n onCancel,\n padding = 12,\n resizable = true,\n defaultWidth = 400,\n minWidth = 400,\n maxWidth = 720,\n maxWidthContainerInset = 80,\n variant = \"pinned\",\n children,\n footerActions,\n className,\n style,\n}: ConfigPanelProps) {\n const [width, setWidth] = useState(defaultWidth);\n // Effective upper bound — `min(maxWidth, parentClientWidth - inset)`.\n // Recomputed on every parent resize so the panel can never cover the\n // canvas. Starts at `maxWidth` so the first paint is sane; the\n // ResizeObserver below tightens it as soon as the layout settles.\n const [effectiveMax, setEffectiveMax] = useState(maxWidth);\n const panelRef = useRef<HTMLElement>(null);\n useEffect(() => {\n const el = panelRef.current;\n if (!el) return;\n const parent = el.parentElement;\n if (!parent || typeof ResizeObserver === \"undefined\") return;\n const update = () => {\n const room = parent.clientWidth - maxWidthContainerInset;\n const next = Math.max(minWidth, Math.min(maxWidth, room));\n setEffectiveMax(next);\n // If the current width exceeds the new ceiling (window shrank),\n // snap the panel down so it remains inside the canvas.\n setWidth((w) => (w > next ? next : w));\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(parent);\n return () => ro.disconnect();\n }, [maxWidth, minWidth, maxWidthContainerInset]);\n const [internalActive, setInternalActive] = useState<string | undefined>(\n defaultActiveTab ?? tabs?.[0]?.id,\n );\n const activeTabId = controlledActive ?? internalActive;\n const selectTab = (id: string) => {\n if (controlledActive === undefined) setInternalActive(id);\n onTabChange?.(id);\n };\n\n // ── Title editor ────────────────────────────────────────────────────\n const [editingTitle, setEditingTitle] = useState(false);\n const [draftTitle, setDraftTitle] = useState(title ?? \"\");\n useEffect(() => {\n if (!editingTitle) setDraftTitle(title ?? \"\");\n }, [title, editingTitle]);\n const commitTitle = (next: string) => {\n setEditingTitle(false);\n if (next !== title) onTitleChange?.(next);\n };\n const titleKeyDown = (e: ReactKeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commitTitle(draftTitle);\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n setEditingTitle(false);\n setDraftTitle(title ?? \"\");\n }\n };\n\n // ── Resize handle ───────────────────────────────────────────────────\n // We capture pointer events on the drag handle; the panel width is\n // updated on every pointermove. Width is clamped to [min, max].\n const resizeRef = useRef<{ pointerId: number; startX: number; startWidth: number } | null>(null);\n const onResizeDown = useCallback(\n (e: PointerEvent<HTMLDivElement>) => {\n if (!resizable) return;\n e.preventDefault();\n e.stopPropagation();\n resizeRef.current = { pointerId: e.pointerId, startX: e.clientX, startWidth: width };\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n },\n [resizable, width],\n );\n const onResizeMove = (e: PointerEvent<HTMLDivElement>) => {\n const r = resizeRef.current;\n if (!r || r.pointerId !== e.pointerId) return;\n // Dragging LEFT widens the panel (it sticks to the right edge of\n // the canvas). Upper bound is `effectiveMax` — the smaller of the\n // consumer's `maxWidth` and the parent container's available room,\n // so the panel can never grow past the canvas itself.\n const delta = r.startX - e.clientX;\n const next = Math.max(minWidth, Math.min(effectiveMax, r.startWidth + delta));\n setWidth(next);\n };\n const onResizeUp = (e: PointerEvent<HTMLDivElement>) => {\n if (resizeRef.current?.pointerId === e.pointerId) resizeRef.current = null;\n };\n\n if (!open) return null;\n\n const activeTab = tabs?.find((t) => t.id === activeTabId);\n\n return (\n <aside\n ref={panelRef}\n className={cn(\n \"ods-flow-config-panel\",\n `ods-flow-config-panel--${variant}`,\n editingTitle && \"ods-flow-config-panel--editing-title\",\n className,\n )}\n style={{ width, ...style }}\n aria-label={title ?? \"Configuration\"}\n >\n {resizable && (\n <div\n className=\"ods-flow-config-panel__resize\"\n onPointerDown={onResizeDown}\n onPointerMove={onResizeMove}\n onPointerUp={onResizeUp}\n onPointerCancel={onResizeUp}\n aria-hidden=\"true\"\n />\n )}\n\n <header className=\"ods-flow-config-panel__header\">\n <div className=\"ods-flow-config-panel__title-row\">\n {icon && <span className=\"ods-flow-config-panel__icon\">{icon}</span>}\n {editingTitle ? (\n <input\n className=\"ods-flow-config-panel__title-input\"\n value={draftTitle}\n autoFocus\n onChange={(e) => setDraftTitle(e.target.value)}\n onBlur={() => commitTitle(draftTitle)}\n onKeyDown={titleKeyDown}\n aria-label=\"Edit title\"\n />\n ) : (\n <button\n type=\"button\"\n className=\"ods-flow-config-panel__title\"\n onDoubleClick={() => {\n if (!onTitleChange) return;\n setDraftTitle(title ?? \"\");\n setEditingTitle(true);\n }}\n title={onTitleChange ? \"Double-click to rename\" : undefined}\n >\n {title ?? \"Untitled\"}\n </button>\n )}\n {headerActions && (\n <div className=\"ods-flow-config-panel__header-actions\">\n {headerActions}\n </div>\n )}\n {onClose && (\n <button\n type=\"button\"\n className=\"ods-flow-config-panel__close\"\n onClick={onClose}\n aria-label=\"Close panel\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\">\n <path\n d=\"M3 3l8 8M11 3l-8 8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n )}\n </div>\n </header>\n\n {tabs && tabs.length > 1 && (\n <nav className=\"ods-flow-config-panel__tabs\" role=\"tablist\">\n {tabs.map((t) => (\n <button\n key={t.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeTabId === t.id}\n disabled={t.disabled}\n className={cn(\n \"ods-flow-config-panel__tab\",\n activeTabId === t.id && \"ods-flow-config-panel__tab--active\",\n )}\n onClick={() => selectTab(t.id)}\n >\n <span>{t.label}</span>\n {t.badge !== undefined && t.badge !== null && (\n <span className=\"ods-flow-config-panel__tab-badge\">{t.badge}</span>\n )}\n </button>\n ))}\n </nav>\n )}\n\n {banner && <div className=\"ods-flow-config-panel__banner\">{banner}</div>}\n\n <div\n className=\"ods-flow-config-panel__body\"\n role=\"tabpanel\"\n style={{ padding }}\n >\n {tabs ? activeTab?.content : children}\n </div>\n\n <footer className=\"ods-flow-config-panel__footer\">\n {saveState && (\n <span\n className={cn(\n \"ods-flow-config-panel__save-state\",\n `ods-flow-config-panel__save-state--${saveState}`,\n )}\n >\n <span\n className=\"ods-flow-config-panel__save-dot\"\n style={{ background: SAVE_STATE_DOT[saveState] }}\n aria-hidden=\"true\"\n />\n {SAVE_STATE_LABEL[saveState]}\n </span>\n )}\n <div className=\"ods-flow-config-panel__footer-actions\">\n {footerActions ?? (\n <>\n {onCancel && (\n <button\n type=\"button\"\n className=\"ods-flow-config-panel__btn ods-flow-config-panel__btn--ghost\"\n onClick={onCancel}\n >\n Cancel\n </button>\n )}\n {onSave && (\n <button\n type=\"button\"\n className=\"ods-flow-config-panel__btn ods-flow-config-panel__btn--primary\"\n onClick={onSave}\n disabled={saveState === \"saving\"}\n >\n {saveState === \"saving\" ? \"Saving…\" : \"Save\"}\n </button>\n )}\n </>\n )}\n </div>\n </footer>\n </aside>\n );\n}\n","import { type ClassValue, clsx } from \"clsx\";\n\nexport function cn(...inputs: ClassValue[]): string {\n return clsx(inputs);\n}\n","\"use client\";\n\nimport {\n CheckmarkIcon,\n CodeIcon,\n CopyIcon,\n DataViewAltIcon,\n GlobeIcon,\n ListIcon,\n LockedIcon,\n PlayIcon,\n RenewIcon,\n TagIcon,\n} from \"@octaviaflow/icons\";\nimport { type ReactNode, useCallback, useId, useMemo, useRef, useState } from \"react\";\nimport { Accordion } from \"../../../components/Accordion/Accordion\";\nimport { Badge } from \"../../../components/Badge/Badge\";\nimport { Banner } from \"../../../components/Banner/Banner\";\nimport { Button } from \"../../../components/Button/Button\";\nimport { CodeEditor } from \"../../../components/CodeEditor/CodeEditor\";\nimport { Combobox } from \"../../../components/Combobox/Combobox\";\nimport { Disclosure } from \"../../../components/Disclosure/Disclosure\";\nimport { Input } from \"../../../components/Input/Input\";\nimport { JsonViewer } from \"../../../components/JsonViewer/JsonViewer\";\nimport {\n KeyValueEditor,\n type KeyValuePair,\n} from \"../../../components/KeyValueEditor/KeyValueEditor\";\nimport { NumberInput } from \"../../../components/NumberInput/NumberInput\";\nimport { PasswordInput } from \"../../../components/PasswordInput/PasswordInput\";\nimport { SegmentedControl } from \"../../../components/SegmentedControl/SegmentedControl\";\nimport { Select } from \"../../../components/Select/Select\";\nimport { Spinner } from \"../../../components/Spinner/Spinner\";\nimport { Switch } from \"../../../components/Switch/Switch\";\nimport { Tabs } from \"../../../components/Tabs/Tabs\";\nimport { cn } from \"../../../utils/cn\";\nimport {\n buildCurl,\n countGraphqlVariables,\n countSchemaPaths,\n effectiveUrl,\n formatBytes,\n HTTP_ACTION_DEFAULTS,\n HTTP_METHODS,\n type HttpActionConfig,\n type HttpAuthConfig,\n type HttpBodyType,\n type HttpKeyValue,\n type HttpMethod,\n type HttpPaginationConfig,\n type HttpPreviewRequest,\n type HttpPreviewResponse,\n type HttpResponseType,\n inferJsonSchema,\n normalizeAuth,\n normalizeKeyValues,\n parseCurl,\n statusTone,\n} from \"./httpActionTypes\";\n\n/* ---------------------------------------------------------------------------\n * HttpActionPanel — the redesigned HTTP-request action configuration.\n *\n * Design intent: SIMPLER by default, MORE powerful when needed.\n * - One promoted request bar (method · URL · Send) — testing lives where you\n * type, not at the bottom of a settings pile.\n * - Five tabs for the request itself (Params / Headers / Body / Auth /\n * Response); everything operational (timeout, retry, pagination,\n * extraction) sits behind ONE collapsed \"Advanced options\" section.\n * - Power tools: cURL import (paste any curl command → full config) and\n * copy-as-cURL; a test console with status/time/size, headers/body\n * viewers and automatic response-schema inference for downstream binding.\n *\n * The panel is host-agnostic: connections and the actual test transport are\n * injected (`connections`, `onSendPreview`), state is emitted as the full\n * engine-compatible config on every change.\n * ------------------------------------------------------------------------- */\n\nexport interface HttpConnectionEndpoint {\n method: string;\n path: string;\n summary?: string;\n}\n\nexport interface HttpConnectionOption {\n id: string;\n name: string;\n icon?: ReactNode;\n /** Endpoint catalog discovered from an imported API spec, when available. */\n endpoints?: HttpConnectionEndpoint[];\n}\n\nexport interface HttpActionPanelProps {\n /** Current step config (engine-compatible). Missing keys get defaults. */\n value?: Partial<HttpActionConfig>;\n /** Fires with the FULL merged config on every edit. */\n onChange?: (config: HttpActionConfig) => void;\n disabled?: boolean;\n /** Saved API connections for the Source picker. Omit to hide the picker. */\n connections?: HttpConnectionOption[];\n connectionsLoading?: boolean;\n /** Test-send transport. Omit to hide the Send button. */\n onSendPreview?: (request: HttpPreviewRequest) => Promise<HttpPreviewResponse>;\n className?: string;\n}\n\ntype PreviewPhase =\n | { phase: \"idle\" }\n | { phase: \"loading\" }\n | { phase: \"success\"; response: HttpPreviewResponse }\n | { phase: \"error\"; message: string };\n\nfunction toPairs(rows: HttpKeyValue[]): KeyValuePair[] {\n return rows.map((r) => ({\n key: r.key,\n value: r.value,\n enabled: r.enabled !== false,\n description: r.description,\n }));\n}\n\nfunction textOf(raw: unknown): string {\n if (typeof raw === \"string\") return raw;\n if (raw == null) return \"\";\n try {\n return JSON.stringify(raw, null, 2);\n } catch {\n return \"\";\n }\n}\n\nexport function HttpActionPanel({\n value,\n onChange,\n disabled = false,\n connections,\n connectionsLoading = false,\n onSendPreview,\n className,\n}: HttpActionPanelProps) {\n const uid = useId();\n\n /* ── config state (initialized once from `value`, emitted in full) ──── */\n const cfgRef = useRef<HttpActionConfig>({\n ...HTTP_ACTION_DEFAULTS,\n ...value,\n queryParams: normalizeKeyValues(value?.queryParams),\n headers: normalizeKeyValues(value?.headers),\n formData: normalizeKeyValues(value?.formData),\n auth: normalizeAuth(value?.auth),\n retry: {\n ...HTTP_ACTION_DEFAULTS.retry,\n ...(value?.retry as object),\n } as HttpActionConfig[\"retry\"],\n pagination: {\n ...HTTP_ACTION_DEFAULTS.pagination,\n ...(value?.pagination as object),\n } as HttpActionConfig[\"pagination\"],\n });\n const [, force] = useState(0);\n const emit = useCallback(\n (patch: Partial<HttpActionConfig>) => {\n cfgRef.current = { ...cfgRef.current, ...patch };\n force((n) => n + 1);\n onChange?.(cfgRef.current);\n },\n [onChange],\n );\n const cfg = cfgRef.current;\n\n const connectionId = cfg.connectionId ?? \"\";\n const selectedConnection = connections?.find((c) => c.id === connectionId) ?? null;\n const endpoints = selectedConnection?.endpoints ?? [];\n const method = cfg.method ?? \"GET\";\n const url = cfg.url ?? \"\";\n const baseUrl = cfg.baseUrl ?? \"\";\n const fullUrl = connectionId ? url : effectiveUrl(baseUrl, url);\n const queryParams = normalizeKeyValues(cfg.queryParams);\n const headers = normalizeKeyValues(cfg.headers);\n const formData = normalizeKeyValues(cfg.formData);\n const auth = normalizeAuth(cfg.auth);\n const retry = cfg.retry ?? HTTP_ACTION_DEFAULTS.retry;\n const pagination = cfg.pagination ?? { type: \"none\" as const };\n const responseType = cfg.responseType ?? \"json\";\n\n /* ── text buffers (kept as typed, parsed on emit) ─────────────────── */\n const [bodyText, setBodyText] = useState(() => textOf(cfg.body));\n const [bodyError, setBodyError] = useState<string | undefined>();\n const [gqlVarsText, setGqlVarsText] = useState(() => textOf(cfg.graphqlVariables));\n const [gqlVarsError, setGqlVarsError] = useState<string | undefined>();\n const [retryOnText, setRetryOnText] = useState(() => (retry?.retryOn ?? []).join(\", \"));\n const [expectedCtText, setExpectedCtText] = useState(() =>\n (cfg.expectedContentTypes ?? []).join(\", \"),\n );\n const [urlError, setUrlError] = useState<string | undefined>();\n const [extractRows, setExtractRows] = useState<HttpKeyValue[]>(() =>\n Object.entries(cfg.extract ?? {}).map(([key, v]) => ({ key, value: v, enabled: true })),\n );\n\n /* ── cURL import/export ───────────────────────────────────────────── */\n const [curlOpen, setCurlOpen] = useState(false);\n const [curlText, setCurlText] = useState(\"\");\n const [curlError, setCurlError] = useState<string | undefined>();\n // Copy affordances follow the CodeEditor/JsonViewer convention:\n // CopyIcon → CheckmarkIcon + success tint for a beat, never a \"✓\" char.\n const [copiedCurl, setCopiedCurl] = useState(false);\n const [copiedResult, setCopiedResult] = useState(false);\n // Per-section copy (URL / response headers / raw body) — keyed so only the\n // clicked section flips to its \"copied\" state for a beat.\n const [copiedSection, setCopiedSection] = useState<string | null>(null);\n\n const applyCurl = () => {\n const patch = parseCurl(curlText);\n if (!patch) {\n setCurlError(\n \"That doesn't look like a cURL command — it should start with `curl` and include a URL.\",\n );\n return;\n }\n setCurlError(undefined);\n setCurlText(\"\");\n setCurlOpen(false);\n setBodyText(textOf(patch.body));\n setBodyError(undefined);\n emit({ ...patch, connectionId: undefined, baseUrl: undefined });\n };\n\n const copyCurl = async () => {\n try {\n await navigator.clipboard?.writeText(buildCurl(cfg));\n setCopiedCurl(true);\n setTimeout(() => setCopiedCurl(false), 1600);\n } catch {\n /* clipboard unavailable (permissions / insecure context) — no-op */\n }\n };\n\n /** Copy the last test result as a shareable/debuggable JSON bundle. */\n const copyResult = async () => {\n if (preview.phase !== \"success\") return;\n const r = preview.response;\n const bundle = {\n request: {\n method: cfg.apiType === \"graphql\" ? \"POST\" : method,\n url: connectionId ? `${selectedConnection?.name ?? connectionId} · ${url}` : fullUrl,\n },\n response: {\n status: r.status,\n statusText: r.statusText,\n ok: r.ok,\n durationMs: r.duration,\n sizeBytes: r.size,\n headers: r.headers,\n body: r.body,\n },\n };\n try {\n await navigator.clipboard?.writeText(JSON.stringify(bundle, null, 2));\n setCopiedResult(true);\n setTimeout(() => setCopiedResult(false), 1600);\n } catch {\n /* clipboard unavailable — no-op */\n }\n };\n\n /** Copy an individual console section (request URL / response headers / raw body). */\n const copySection = async (text: string, key: string) => {\n try {\n await navigator.clipboard?.writeText(text);\n setCopiedSection(key);\n setTimeout(() => setCopiedSection(null), 1600);\n } catch {\n /* clipboard unavailable — no-op */\n }\n };\n\n /** Icon-only ghost copy button used per console section. */\n const sectionCopyButton = (text: string, key: string, label: string) => (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label={copiedSection === key ? `${label} copied` : `Copy ${label}`}\n leftIcon={copiedSection === key ? <CheckmarkIcon size=\"sm\" /> : <CopyIcon size=\"sm\" />}\n className={cn(copiedSection === key && \"ods-http-panel__copy-done\")}\n onClick={(e) => {\n e.stopPropagation();\n void copySection(text, key);\n }}\n />\n );\n\n /* ── URL handling ─────────────────────────────────────────────────── */\n const validateUrl = (nextUrl: string, nextBase: string, hasConnection: boolean) => {\n if (!nextUrl && !nextBase && !hasConnection) {\n setUrlError(\"URL is required\");\n return;\n }\n if (!nextUrl || hasConnection || nextBase || nextUrl.includes(\"{{\")) {\n setUrlError(undefined);\n return;\n }\n try {\n new URL(nextUrl);\n setUrlError(undefined);\n } catch {\n setUrlError(\"URL does not look valid\");\n }\n };\n\n /* ── body mode (GraphQL is a body mode persisted as apiType) ──────── */\n const bodyMode = cfg.apiType === \"graphql\" ? \"graphql\" : (cfg.bodyType ?? \"json\");\n const gqlVarCount = useMemo(\n () => countGraphqlVariables(cfg.graphqlQuery ?? \"\"),\n [cfg.graphqlQuery],\n );\n const handleBodyMode = (next: string) => {\n if (next === \"graphql\") {\n // Coach (don't force) POST for GraphQL; stays editable for persisted-query GETs.\n emit(method === \"GET\" ? { apiType: \"graphql\", method: \"POST\" } : { apiType: \"graphql\" });\n return;\n }\n emit({ apiType: \"rest\", bodyType: next as HttpBodyType });\n };\n\n /* ── preview / test console ───────────────────────────────────────── */\n const [preview, setPreview] = useState<PreviewPhase>({ phase: \"idle\" });\n const [schemaInfo, setSchemaInfo] = useState<{ pathCount: number; topKeys: string[] } | null>(\n null,\n );\n const lastSchemaKey = useRef(\"\");\n\n const inferAndEmitSchema = useCallback(\n (response: HttpPreviewResponse, forceRefresh = false) => {\n if (responseType === \"binary\") return;\n const snapshot = {\n status: response.status,\n statusText: response.statusText,\n ok: response.ok,\n headers: response.headers,\n body: response.body,\n duration: response.duration,\n attempts: 1,\n extracted: {},\n };\n const inferred = inferJsonSchema(snapshot);\n const key = JSON.stringify(inferred);\n if (!forceRefresh && key === lastSchemaKey.current) return;\n lastSchemaKey.current = key;\n emit({ _outputSchema: inferred });\n const bodySchema = inferred.properties?.body;\n const topKeys = Object.keys(bodySchema?.properties ?? inferred.properties ?? {});\n setSchemaInfo({ pathCount: countSchemaPaths(inferred), topKeys });\n },\n [emit, responseType],\n );\n\n const sendPreview = async () => {\n if (!onSendPreview) return;\n setPreview({ phase: \"loading\" });\n try {\n const response = await onSendPreview({\n method: (cfg.apiType === \"graphql\" ? \"POST\" : method) as HttpMethod,\n url: connectionId ? url : fullUrl,\n connectionId: connectionId || undefined,\n headers,\n queryParams,\n bodyType: (cfg.bodyType ?? \"json\") as HttpBodyType,\n body: bodyText,\n formData,\n graphqlQuery: cfg.apiType === \"graphql\" ? (cfg.graphqlQuery ?? \"\") : undefined,\n graphqlVariables: cfg.apiType === \"graphql\" ? gqlVarsText : undefined,\n auth,\n timeout: cfg.timeout ?? 30000,\n });\n setPreview({ phase: \"success\", response });\n inferAndEmitSchema(response);\n } catch (err) {\n setPreview({\n phase: \"error\",\n message: err instanceof Error ? err.message : \"Request failed\",\n });\n }\n };\n\n const previewUrlOk = Boolean(fullUrl) && !fullUrl.includes(\"{{\");\n const canSend =\n Boolean(onSendPreview) && previewUrlOk && preview.phase !== \"loading\" && !disabled;\n\n /* ── counts / badges ──────────────────────────────────────────────── */\n const paramCount = queryParams.filter((r) => r.enabled !== false && r.key).length;\n const headerCount = headers.filter((r) => r.enabled !== false && r.key).length;\n const extractCount = extractRows.filter((r) => r.key).length;\n const advancedSummary: string[] = [];\n if ((cfg.timeout ?? 30000) !== 30000) advancedSummary.push(`${(cfg.timeout ?? 0) / 1000}s`);\n if ((retry?.maxAttempts ?? 1) > 1) advancedSummary.push(`retry ×${retry?.maxAttempts}`);\n if (pagination.type !== \"none\") advancedSummary.push(pagination.type.replace(\"_\", \" \"));\n if (extractCount > 0) advancedSummary.push(`${extractCount} extracted`);\n\n /* ── shared sub-renderers ─────────────────────────────────────────── */\n const kvTab = (\n rows: HttpKeyValue[],\n key: \"queryParams\" | \"headers\",\n desc: ReactNode,\n keyPlaceholder: string,\n ) => (\n <div className=\"ods-http-panel__tab\">\n <p className=\"ods-http-panel__desc\">{desc}</p>\n <KeyValueEditor\n pairs={toPairs(rows)}\n // Keep the rows RAW (incl. the blank row that \"Add\" appends). Running\n // serializeKeyValues here dropped fully-empty rows on every change, so\n // clicking Add produced a row that was immediately stripped and never\n // rendered. Empty rows are harmless on the wire — the engine (and the\n // preview path) skip any row with no key.\n onChange={(pairs) => emit({ [key]: pairs as HttpKeyValue[] })}\n rowToggle\n showDescription\n keyPlaceholder={keyPlaceholder}\n valuePlaceholder=\"value or {{var}}\"\n emptyLabel=\"No entries yet — click Add to begin.\"\n addLabel=\"Add\"\n size=\"sm\"\n disabled={disabled}\n />\n </div>\n );\n\n const paramsTab = kvTab(\n queryParams,\n \"queryParams\",\n <>\n Query parameters appended to the URL. Supports <code>{\"{{variable}}\"}</code> interpolation.\n </>,\n \"param name\",\n );\n\n const headersTab = kvTab(\n headers,\n \"headers\",\n <>\n Request headers. Auth headers are injected automatically from the Auth tab. Supports{\" \"}\n <code>{\"{{variable}}\"}</code> interpolation.\n </>,\n \"Header-Name\",\n );\n\n const bodyTab = (\n <div className=\"ods-http-panel__tab\">\n <SegmentedControl\n size=\"sm\"\n aria-label=\"Body type\"\n options={[\n { value: \"none\", label: \"None\" },\n { value: \"json\", label: \"JSON\" },\n { value: \"graphql\", label: \"GraphQL\" },\n { value: \"raw\", label: \"Raw\" },\n { value: \"form-data\", label: \"Form\" },\n { value: \"xml\", label: \"XML\" },\n ]}\n value={bodyMode}\n onChange={handleBodyMode}\n />\n\n {bodyMode === \"none\" && (\n <p className=\"ods-http-panel__empty\">No request body will be sent.</p>\n )}\n\n {(bodyMode === \"json\" || bodyMode === \"raw\" || bodyMode === \"xml\") && (\n <>\n <CodeEditor\n value={bodyText}\n language={bodyMode === \"json\" ? \"json\" : \"plain\"}\n onChange={(next) => {\n setBodyText(next);\n if (bodyMode === \"json\" && next.trim()) {\n try {\n emit({ body: JSON.parse(next) });\n setBodyError(undefined);\n } catch {\n setBodyError(\"Invalid JSON\");\n emit({ body: next });\n }\n } else {\n setBodyError(undefined);\n emit({ body: next || undefined });\n }\n }}\n readOnly={disabled}\n minHeight={180}\n ariaLabel=\"Request body\"\n />\n {bodyError && <p className=\"ods-http-panel__error\">⚠ {bodyError}</p>}\n <p className=\"ods-http-panel__desc\">\n Supports <code>{\"{{variable}}\"}</code> interpolation.\n </p>\n </>\n )}\n\n {bodyMode === \"graphql\" && (\n <>\n <CodeEditor\n value={cfg.graphqlQuery ?? \"\"}\n language=\"plain\"\n onChange={(next) => emit({ graphqlQuery: next })}\n readOnly={disabled}\n minHeight={160}\n placeholder={\"query ($id: ID!) {\\n node(id: $id) { id }\\n}\"}\n ariaLabel=\"GraphQL query\"\n />\n <Disclosure\n size=\"sm\"\n title=\"Variables\"\n defaultOpen={Boolean(gqlVarsText.trim()) || gqlVarCount > 0}\n trailing={\n gqlVarCount > 0 ? (\n <Badge size=\"sm\" variant=\"neutral\">\n {gqlVarCount}\n </Badge>\n ) : undefined\n }\n >\n <CodeEditor\n value={gqlVarsText}\n language=\"json\"\n onChange={(next) => {\n setGqlVarsText(next);\n if (!next.trim()) {\n setGqlVarsError(undefined);\n emit({ graphqlVariables: {} });\n return;\n }\n try {\n emit({ graphqlVariables: JSON.parse(next) });\n setGqlVarsError(undefined);\n } catch {\n setGqlVarsError(\"Invalid JSON\");\n }\n }}\n readOnly={disabled}\n minHeight={100}\n ariaLabel=\"GraphQL variables (JSON)\"\n />\n {gqlVarsError && <p className=\"ods-http-panel__error\">⚠ {gqlVarsError}</p>}\n </Disclosure>\n </>\n )}\n\n {bodyMode === \"form-data\" && (\n <>\n <p className=\"ods-http-panel__desc\">\n Multipart form fields. Content-Type is set automatically with the boundary.\n </p>\n <KeyValueEditor\n pairs={toPairs(formData)}\n onChange={(pairs) =>\n // Raw rows — see the params/headers note; serializing here ate\n // the blank row that Add appends.\n emit({ formData: pairs as HttpKeyValue[], bodyType: \"form-data\" })\n }\n rowToggle\n keyPlaceholder=\"field name\"\n valuePlaceholder=\"value or {{var}}\"\n emptyLabel=\"No fields yet — click Add to begin.\"\n addLabel=\"Add\"\n size=\"sm\"\n disabled={disabled}\n />\n </>\n )}\n </div>\n );\n\n const authTab = (\n <div className=\"ods-http-panel__tab\">\n {connectionId ? (\n <Banner variant=\"success\" appearance=\"subtle\" size=\"sm\">\n Authentication is inherited from <strong>{selectedConnection?.name}</strong> and refreshed\n automatically. Choose a type below only to override it for this step.\n </Banner>\n ) : (\n <Banner variant=\"info\" appearance=\"subtle\" size=\"sm\">\n For OAuth 2.0 APIs that need a login screen, create an API connection and select it as the\n Source — the token is obtained once and refreshed automatically. Inline auth here is for\n non-interactive credentials only.\n </Banner>\n )}\n\n <Select\n id={`${uid}-auth-type`}\n label={connectionId ? \"Override authentication\" : \"Authentication\"}\n value={auth.type}\n onChange={(next) => emit({ auth: { ...auth, type: next as HttpAuthConfig[\"type\"] } })}\n disabled={disabled}\n options={[\n { value: \"none\", label: connectionId ? \"Inherit from connection\" : \"No auth\" },\n { value: \"basic\", label: \"Basic auth (username + password)\" },\n { value: \"bearer\", label: \"Bearer token\" },\n { value: \"apikey\", label: \"API key\" },\n ]}\n />\n\n {auth.type === \"basic\" && (\n <div className=\"ods-http-panel__grid\">\n <Input\n id={`${uid}-auth-user`}\n label=\"Username\"\n value={auth.username ?? \"\"}\n placeholder=\"username or {{var}}\"\n onChange={(e) => emit({ auth: { ...auth, username: e.target.value } })}\n disabled={disabled}\n />\n <PasswordInput\n id={`${uid}-auth-pass`}\n label=\"Password\"\n value={auth.password ?? \"\"}\n placeholder=\"password or {{var}}\"\n onChange={(next: string) => emit({ auth: { ...auth, password: next } })}\n disabled={disabled}\n />\n </div>\n )}\n\n {auth.type === \"bearer\" && (\n <PasswordInput\n id={`${uid}-auth-token`}\n label=\"Token\"\n value={auth.token ?? \"\"}\n placeholder=\"your-token or {{step.token}}\"\n onChange={(next: string) => emit({ auth: { ...auth, token: next } })}\n disabled={disabled}\n />\n )}\n\n {auth.type === \"apikey\" && (\n <div className=\"ods-http-panel__grid\">\n <Input\n id={`${uid}-auth-keyname`}\n label=\"Key name\"\n value={auth.apiKeyName ?? \"\"}\n placeholder=\"X-API-Key\"\n onChange={(e) => emit({ auth: { ...auth, apiKeyName: e.target.value } })}\n disabled={disabled}\n />\n <PasswordInput\n id={`${uid}-auth-keyval`}\n label=\"Key value\"\n value={auth.apiKeyValue ?? \"\"}\n placeholder=\"your-api-key or {{var}}\"\n onChange={(next: string) => emit({ auth: { ...auth, apiKeyValue: next } })}\n disabled={disabled}\n />\n <Select\n id={`${uid}-auth-keyloc`}\n label=\"Send in\"\n value={auth.apiKeyLocation ?? \"header\"}\n onChange={(next) =>\n emit({ auth: { ...auth, apiKeyLocation: next as \"header\" | \"query\" } })\n }\n disabled={disabled}\n options={[\n { value: \"header\", label: \"Request header\" },\n { value: \"query\", label: \"Query parameter\" },\n ]}\n />\n </div>\n )}\n\n {auth.type === \"none\" && (\n <p className=\"ods-http-panel__empty\">\n {connectionId\n ? \"This step uses the connection's authentication.\"\n : \"No authentication will be added to this request.\"}\n </p>\n )}\n </div>\n );\n\n const responseTab = (\n <div className=\"ods-http-panel__tab\">\n <SegmentedControl\n size=\"sm\"\n aria-label=\"Response type\"\n options={[\n { value: \"json\", label: \"JSON\" },\n { value: \"text\", label: \"Text\" },\n { value: \"binary\", label: \"Binary\" },\n ]}\n value={responseType}\n onChange={(next) => emit({ responseType: next as HttpResponseType })}\n />\n <p className=\"ods-http-panel__desc\">\n {responseType === \"json\" &&\n \"Tries to parse the response body as JSON; falls back to raw text on parse failure.\"}\n {responseType === \"text\" && \"Returns the raw response body as a string. No JSON parsing.\"}\n {responseType === \"binary\" && (\n <>\n Returns the response as bytes with <code>fileName</code>, <code>contentType</code> and{\" \"}\n <code>size</code> on the step output — for downloads feeding file actions. Pagination is\n not compatible with binary responses.\n </>\n )}\n </p>\n\n <Input\n id={`${uid}-expected-ct`}\n label=\"Expected content-types (optional)\"\n value={expectedCtText}\n placeholder=\"application/pdf, application/json\"\n helperText=\"Comma-separated. A warning is logged when the response Content-Type matches none of these.\"\n onChange={(e) => {\n setExpectedCtText(e.target.value);\n const parts = e.target.value\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n emit({ expectedContentTypes: parts.length ? parts : undefined });\n }}\n disabled={disabled}\n />\n\n <div className=\"ods-http-panel__schema\">\n <span className=\"ods-http-panel__schema-label\">Data stream schema</span>\n {schemaInfo ? (\n <p className=\"ods-http-panel__desc\">\n <Badge size=\"sm\" variant=\"success\">\n {schemaInfo.pathCount} paths\n </Badge>{\" \"}\n Inferred from the last test send. Top-level keys:{\" \"}\n <code>{schemaInfo.topKeys.join(\", \")}</code>. Downstream binding (Field Mapper,\n Transform, ForEach) sees this shape immediately; Save persists it.\n </p>\n ) : (\n <p className=\"ods-http-panel__desc\">\n No schema yet — hit <strong>Send</strong> in the request bar. On success the response\n shape is inferred so downstream steps bind against real field names.\n </p>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={preview.phase !== \"success\" || responseType === \"binary\" || disabled}\n onClick={() => {\n if (preview.phase === \"success\") inferAndEmitSchema(preview.response, true);\n }}\n >\n Refresh schema from last send\n </Button>\n </div>\n </div>\n );\n\n const tabItems = [\n {\n value: \"params\",\n label: paramCount ? `Params · ${paramCount}` : \"Params\",\n icon: <ListIcon size=\"sm\" />,\n children: paramsTab,\n },\n {\n value: \"headers\",\n label: headerCount ? `Headers · ${headerCount}` : \"Headers\",\n icon: <TagIcon size=\"sm\" />,\n children: headersTab,\n },\n {\n value: \"body\",\n label:\n bodyMode === \"none\" ? \"Body\" : `Body · ${bodyMode === \"form-data\" ? \"form\" : bodyMode}`,\n icon: <CodeIcon size=\"sm\" />,\n children: bodyTab,\n },\n {\n value: \"auth\",\n label: auth.type === \"none\" ? \"Auth\" : `Auth · ${auth.type}`,\n icon: <LockedIcon size=\"sm\" />,\n children: authTab,\n },\n {\n value: \"response\",\n label: responseType === \"json\" ? \"Response\" : `Response · ${responseType}`,\n icon: <DataViewAltIcon size=\"sm\" />,\n children: responseTab,\n },\n ];\n\n /* ── render ───────────────────────────────────────────────────────── */\n return (\n <div className={cn(\"ods-http-panel\", className)}>\n {/* Source connection + endpoint picker */}\n {connections && (\n <div className=\"ods-http-panel__source\">\n <Select\n id={`${uid}-connection`}\n label=\"Source\"\n placeholder={connectionsLoading ? \"Loading…\" : \"No connection (manual config)\"}\n options={connections.map((c) => ({ value: c.id, label: c.name, icon: c.icon }))}\n value={connectionId}\n onChange={(next) => emit({ connectionId: next || undefined })}\n disabled={disabled || connectionsLoading}\n helperText={\n connectionId\n ? `Base URL and auth are inherited from \"${selectedConnection?.name}\" at runtime.`\n : \"Select a saved API connection to inherit base URL and auth, or configure manually.\"\n }\n />\n {connectionId && endpoints.length > 0 && (\n <Combobox\n ariaLabel=\"Endpoint\"\n placeholder={`Search ${endpoints.length} discovered endpoints…`}\n value={url}\n creatable\n options={endpoints.map((e) => ({\n value: e.path,\n label: `${e.method} ${e.path}`,\n description: e.summary,\n }))}\n onChange={(nextPath) => {\n const match = endpoints.find((e) => e.path === nextPath);\n validateUrl(nextPath, baseUrl, true);\n emit(\n match && (HTTP_METHODS as string[]).includes(match.method.toUpperCase())\n ? { url: nextPath, method: match.method.toUpperCase() as HttpMethod }\n : { url: nextPath },\n );\n }}\n />\n )}\n </div>\n )}\n\n {/* Request bar: method · URL · Send */}\n <div className=\"ods-http-panel__bar\">\n <Select\n id={`${uid}-method`}\n aria-label=\"HTTP method\"\n className={cn(\n \"ods-http-panel__method\",\n `ods-http-panel__method--${method.toLowerCase()}`,\n )}\n value={method}\n onChange={(next) => emit({ method: next as HttpMethod })}\n disabled={disabled}\n options={HTTP_METHODS.map((m) => ({ value: m, label: m }))}\n />\n <Input\n id={`${uid}-url`}\n aria-label={connectionId ? \"Path\" : \"URL\"}\n data-fx-droppable=\"true\"\n className=\"ods-http-panel__url\"\n value={url}\n placeholder={connectionId ? \"/v1/users\" : \"https://api.example.com/v1/users or {{var}}\"}\n error={Boolean(urlError)}\n errorMessage={urlError}\n onChange={(e) => {\n validateUrl(e.target.value, baseUrl, Boolean(connectionId));\n emit({ url: e.target.value });\n }}\n disabled={disabled}\n />\n {onSendPreview && (\n <Button\n variant=\"primary\"\n size=\"md\"\n leftIcon={preview.phase === \"loading\" ? undefined : <PlayIcon size=\"sm\" />}\n onClick={sendPreview}\n disabled={!canSend}\n >\n {preview.phase === \"loading\" ? \"Sending…\" : \"Send\"}\n </Button>\n )}\n </div>\n\n {/* Bar footnotes */}\n {!connectionId && baseUrl && (\n <p className=\"ods-http-panel__effective\">\n <span>Effective URL:</span> <code>{fullUrl || \"—\"}</code>\n </p>\n )}\n {fullUrl.includes(\"{{\") && (\n <p className=\"ods-http-panel__desc\">\n ⚠ URL contains <code>{\"{{variables}}\"}</code> — they resolve at run time; testing needs\n literal values.\n </p>\n )}\n <div className=\"ods-http-panel__tools\">\n <span className=\"ods-http-panel__hint\">\n Use <code>{\"{{stepName.fieldPath}}\"}</code> to insert data from upstream steps.\n </span>\n <span className=\"ods-http-panel__tools-actions\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setCurlOpen((o) => !o)}>\n Import cURL\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className={cn(copiedCurl && \"ods-http-panel__copy-done\")}\n leftIcon={copiedCurl ? <CheckmarkIcon size=\"sm\" /> : <CopyIcon size=\"sm\" />}\n onClick={copyCurl}\n >\n {copiedCurl ? \"Copied\" : \"Copy as cURL\"}\n </Button>\n </span>\n </div>\n\n {curlOpen && (\n <div className=\"ods-http-panel__curl\">\n <CodeEditor\n value={curlText}\n language=\"plain\"\n onChange={setCurlText}\n minHeight={90}\n showLineNumbers={false}\n placeholder=\"curl -X POST 'https://api.example.com/v1/users' -H 'Authorization: Bearer …' -d '{…}'\"\n ariaLabel=\"cURL command\"\n />\n {curlError && <p className=\"ods-http-panel__error\">⚠ {curlError}</p>}\n <div className=\"ods-http-panel__curl-actions\">\n <Button variant=\"secondary\" size=\"sm\" onClick={() => setCurlOpen(false)}>\n Cancel\n </Button>\n <Button variant=\"primary\" size=\"sm\" onClick={applyCurl} disabled={!curlText.trim()}>\n Apply to request\n </Button>\n </div>\n </div>\n )}\n\n {/* Request tabs */}\n <Tabs items={tabItems} defaultValue=\"params\" className=\"ods-http-panel__tabs\" />\n\n {/* ONE advanced section — everything operational */}\n <Disclosure\n size=\"sm\"\n icon={<GlobeIcon size=\"sm\" />}\n title=\"Advanced options\"\n description=\"Base URL, timeout, retries, pagination, response extraction\"\n trailing={\n advancedSummary.length ? (\n <Badge size=\"sm\" variant=\"info\">\n {advancedSummary.join(\" · \")}\n </Badge>\n ) : undefined\n }\n >\n <div className=\"ods-http-panel__grid\">\n {!connectionId && (\n <Input\n id={`${uid}-base-url`}\n label=\"Base URL (optional)\"\n value={baseUrl}\n placeholder=\"https://api.example.com\"\n helperText=\"Combined with the request path to form the full URL.\"\n onChange={(e) => {\n validateUrl(url, e.target.value, Boolean(connectionId));\n emit({ baseUrl: e.target.value || undefined });\n }}\n disabled={disabled}\n />\n )}\n <NumberInput\n label=\"Timeout (ms)\"\n helperText=\"Minimum 1000 ms\"\n value={cfg.timeout ?? 30000}\n min={1000}\n step={1000}\n onChange={(next) => {\n if (!Number.isNaN(next) && next >= 1000) emit({ timeout: next });\n }}\n disabled={disabled}\n />\n <div className=\"ods-http-panel__switches\">\n <Switch\n id={`${uid}-fail`}\n label=\"Fail on non-2xx\"\n checked={cfg.failOnError !== false}\n onChange={(next) => emit({ failOnError: next })}\n disabled={disabled}\n size=\"sm\"\n />\n <Switch\n id={`${uid}-redirects`}\n label=\"Follow redirects\"\n checked={cfg.followRedirects !== false}\n onChange={(next) => emit({ followRedirects: next })}\n disabled={disabled}\n size=\"sm\"\n />\n </div>\n </div>\n\n <Disclosure\n size=\"sm\"\n title=\"Retry\"\n trailing={\n (retry?.maxAttempts ?? 1) > 1 ? (\n <Badge size=\"sm\" variant=\"info\">\n {retry?.maxAttempts} attempts\n </Badge>\n ) : undefined\n }\n >\n <div className=\"ods-http-panel__grid\">\n <NumberInput\n label=\"Max attempts\"\n helperText=\"1 = no retry\"\n value={retry?.maxAttempts ?? 1}\n min={1}\n max={10}\n onChange={(next) => {\n if (!Number.isNaN(next) && next >= 1 && retry) {\n emit({ retry: { ...retry, maxAttempts: next } });\n }\n }}\n disabled={disabled}\n />\n <Input\n id={`${uid}-retry-on`}\n label=\"Retry on (status codes)\"\n value={retryOnText}\n placeholder=\"429, 500, 502, 503, 504\"\n helperText=\"Comma-separated HTTP status codes\"\n onChange={(e) => {\n setRetryOnText(e.target.value);\n const codes = e.target.value\n .split(\",\")\n .map((s) => Number.parseInt(s.trim(), 10))\n .filter((n) => !Number.isNaN(n));\n if (retry) emit({ retry: { ...retry, retryOn: codes } });\n }}\n disabled={disabled}\n />\n <NumberInput\n label=\"Initial delay (ms)\"\n value={retry?.initialDelayMs ?? 1000}\n min={100}\n step={100}\n onChange={(next) => {\n if (!Number.isNaN(next) && retry)\n emit({ retry: { ...retry, initialDelayMs: next } });\n }}\n disabled={disabled}\n />\n <NumberInput\n label=\"Backoff factor\"\n helperText=\"Delay multiplies by this each retry\"\n value={retry?.backoffFactor ?? 2}\n min={1}\n step={0.5}\n onChange={(next) => {\n if (!Number.isNaN(next) && retry)\n emit({ retry: { ...retry, backoffFactor: next } });\n }}\n disabled={disabled}\n />\n <NumberInput\n label=\"Max delay (ms)\"\n value={retry?.maxDelayMs ?? 30000}\n min={1000}\n step={1000}\n onChange={(next) => {\n if (!Number.isNaN(next) && retry) emit({ retry: { ...retry, maxDelayMs: next } });\n }}\n disabled={disabled}\n />\n </div>\n </Disclosure>\n\n <Disclosure\n size=\"sm\"\n title=\"Pagination\"\n trailing={\n pagination.type !== \"none\" ? (\n <Badge size=\"sm\" variant=\"success\">\n {pagination.type.replace(\"_\", \" \")}\n </Badge>\n ) : undefined\n }\n >\n <Select\n id={`${uid}-pag-type`}\n label=\"Strategy\"\n value={pagination.type}\n onChange={(next) =>\n emit({\n pagination: { ...pagination, type: next as HttpPaginationConfig[\"type\"] },\n })\n }\n disabled={disabled}\n options={[\n { value: \"none\", label: \"None (single request)\" },\n { value: \"offset\", label: \"Offset / page number\" },\n { value: \"cursor\", label: \"Cursor-based\" },\n { value: \"link_header\", label: 'Link header (rel=\"next\")' },\n { value: \"next_url\", label: \"Next URL in response body\" },\n ]}\n />\n {pagination.type !== \"none\" && (\n <div className=\"ods-http-panel__grid\">\n <NumberInput\n label=\"Max pages\"\n helperText=\"Safety cap against infinite loops\"\n value={pagination.maxPages ?? 20}\n min={1}\n onChange={(next) => {\n if (!Number.isNaN(next)) emit({ pagination: { ...pagination, maxPages: next } });\n }}\n disabled={disabled}\n />\n <Input\n id={`${uid}-pag-merge`}\n label=\"Merge key (dot path)\"\n value={pagination.mergeKey ?? \"\"}\n placeholder=\"data.items\"\n helperText=\"Array to merge across pages\"\n onChange={(e) => emit({ pagination: { ...pagination, mergeKey: e.target.value } })}\n disabled={disabled}\n />\n {(pagination.type === \"offset\" || pagination.type === \"cursor\") && (\n <>\n <Input\n id={`${uid}-pag-limitp`}\n label=\"Limit param\"\n value={pagination.limitParam ?? \"limit\"}\n onChange={(e) =>\n emit({ pagination: { ...pagination, limitParam: e.target.value } })\n }\n disabled={disabled}\n />\n <NumberInput\n label=\"Page size\"\n value={pagination.limitValue ?? 100}\n min={1}\n onChange={(next) => {\n if (!Number.isNaN(next)) {\n emit({ pagination: { ...pagination, limitValue: next } });\n }\n }}\n disabled={disabled}\n />\n </>\n )}\n {pagination.type === \"offset\" && (\n <Input\n id={`${uid}-pag-offset`}\n label=\"Offset param\"\n value={pagination.offsetParam ?? \"offset\"}\n onChange={(e) =>\n emit({ pagination: { ...pagination, offsetParam: e.target.value } })\n }\n disabled={disabled}\n />\n )}\n {pagination.type === \"cursor\" && (\n <>\n <Input\n id={`${uid}-pag-cres`}\n label=\"Cursor in response (dot path)\"\n value={pagination.cursorResponsePath ?? \"\"}\n placeholder=\"meta.next_cursor\"\n onChange={(e) =>\n emit({ pagination: { ...pagination, cursorResponsePath: e.target.value } })\n }\n disabled={disabled}\n />\n <Input\n id={`${uid}-pag-creq`}\n label=\"Cursor request param\"\n value={pagination.cursorRequestParam ?? \"cursor\"}\n onChange={(e) =>\n emit({ pagination: { ...pagination, cursorRequestParam: e.target.value } })\n }\n disabled={disabled}\n />\n </>\n )}\n {pagination.type === \"next_url\" && (\n <Input\n id={`${uid}-pag-next`}\n label=\"Next URL in response (dot path)\"\n value={pagination.nextUrlResponsePath ?? \"\"}\n placeholder=\"links.next\"\n onChange={(e) =>\n emit({ pagination: { ...pagination, nextUrlResponsePath: e.target.value } })\n }\n disabled={disabled}\n />\n )}\n </div>\n )}\n </Disclosure>\n\n <Disclosure\n size=\"sm\"\n title=\"Response field extraction\"\n trailing={\n extractCount > 0 ? (\n <Badge size=\"sm\" variant=\"info\">\n {extractCount} field{extractCount === 1 ? \"\" : \"s\"}\n </Badge>\n ) : undefined\n }\n >\n <p className=\"ods-http-panel__desc\">\n Extract fields from the response with dot paths — available downstream as{\" \"}\n <code>{\"{{extracted.keyName}}\"}</code>.\n </p>\n <KeyValueEditor\n pairs={extractRows.map((r) => ({ key: r.key, value: r.value }))}\n onChange={(pairs) => {\n const rows = pairs.map((p) => ({ key: p.key, value: p.value, enabled: true }));\n setExtractRows(rows);\n const extract: Record<string, string> = {};\n for (const r of rows) if (r.key && r.value) extract[r.key] = r.value;\n emit({ extract: Object.keys(extract).length ? extract : undefined });\n }}\n keyPlaceholder=\"outputKey\"\n valuePlaceholder=\"data.user.id\"\n emptyLabel=\"No extractions yet — click Add to begin.\"\n addLabel=\"Add\"\n size=\"sm\"\n disabled={disabled}\n />\n </Disclosure>\n </Disclosure>\n\n {/* Test console */}\n {preview.phase !== \"idle\" && (\n <div className=\"ods-http-panel__console\">\n <div className=\"ods-http-panel__console-head\">\n <code\n className={cn(\n \"ods-http-panel__console-method\",\n `ods-http-panel__method--${method.toLowerCase()}`,\n )}\n >\n {cfg.apiType === \"graphql\" ? \"POST\" : method}\n </code>\n <code className=\"ods-http-panel__console-url\">\n {connectionId\n ? `${selectedConnection?.name ?? connectionId} · ${url || \"—\"}`\n : fullUrl || \"—\"}\n </code>\n {sectionCopyButton(fullUrl || url, \"url\", \"request URL\")}\n {preview.phase === \"success\" && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className={cn(copiedResult && \"ods-http-panel__copy-done\")}\n leftIcon={copiedResult ? <CheckmarkIcon size=\"sm\" /> : <CopyIcon size=\"sm\" />}\n onClick={copyResult}\n >\n {copiedResult ? \"Copied\" : \"Copy result\"}\n </Button>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n leftIcon={<RenewIcon size=\"sm\" />}\n onClick={() => {\n setPreview({ phase: \"idle\" });\n }}\n disabled={preview.phase === \"loading\"}\n >\n Clear\n </Button>\n </div>\n\n {preview.phase === \"loading\" && (\n <div className=\"ods-http-panel__console-loading\">\n <Spinner size=\"sm\" />\n <span>Sending request…</span>\n </div>\n )}\n\n {preview.phase === \"error\" && (\n <Banner variant=\"error\" appearance=\"subtle\" size=\"sm\">\n <strong>Request failed.</strong> {preview.message}\n </Banner>\n )}\n\n {preview.phase === \"success\" && (\n <div className=\"ods-http-panel__console-result\">\n <div className=\"ods-http-panel__console-status\">\n <Badge size=\"sm\" variant={statusTone(preview.response.status)}>\n {preview.response.status} {preview.response.statusText}\n </Badge>\n <span className=\"ods-http-panel__meta\">{preview.response.duration}ms</span>\n <span className=\"ods-http-panel__meta\">{formatBytes(preview.response.size)}</span>\n </div>\n <Accordion\n size=\"sm\"\n mode=\"multiple\"\n defaultValue={[\"res-body\"]}\n items={[\n {\n id: \"res-headers\",\n label: \"Response headers\",\n trailing: (\n <>\n {sectionCopyButton(\n Object.entries(preview.response.headers)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"\\n\"),\n \"res-headers\",\n \"response headers\",\n )}\n <Badge size=\"sm\" variant=\"neutral\">\n {Object.keys(preview.response.headers).length}\n </Badge>\n </>\n ),\n content: (\n <div className=\"ods-http-panel__res-headers\">\n {Object.entries(preview.response.headers).map(([k, v]) => (\n <div key={k} className=\"ods-http-panel__res-header\">\n <span className=\"ods-http-panel__res-header-key\">{k}</span>\n <span className=\"ods-http-panel__res-header-val\">{v}</span>\n </div>\n ))}\n </div>\n ),\n },\n {\n id: \"res-body\",\n label: \"Response body\",\n trailing: (\n <>\n {sectionCopyButton(\n typeof preview.response.body === \"object\"\n ? JSON.stringify(preview.response.body, null, 2)\n : String(preview.response.bodyRaw ?? preview.response.body ?? \"\"),\n \"res-body\",\n \"response body\",\n )}\n {!preview.response.ok && (\n <Badge size=\"sm\" variant=\"error\">\n Error\n </Badge>\n )}\n </>\n ),\n content:\n // Size guard: the tree view renders recursively (no\n // virtualization) — very large bodies fall back to text.\n preview.response.body !== null &&\n typeof preview.response.body === \"object\" &&\n preview.response.size <= 1_500_000 ? (\n <JsonViewer\n data={preview.response.body}\n mode=\"view\"\n maxHeight={320}\n copyable\n />\n ) : (\n <pre className=\"ods-http-panel__res-body\">\n {typeof preview.response.body === \"object\"\n ? JSON.stringify(preview.response.body, null, 2)\n : String(\n preview.response.bodyRaw ?? preview.response.body ?? \"(empty body)\",\n )}\n </pre>\n ),\n },\n ]}\n />\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\nimport { ChevronDownIcon } from \"@octaviaflow/icons\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useId,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Accordion — collapsible content sections.\n *\n * Used in ConfigPanel-style settings surfaces, FAQ blocks, runbook\n * docs, advanced-options sections. Two selection modes:\n * - `single` (default): only one item open at a time\n * - `multiple`: any combination of items can be open\n *\n * Controlled OR uncontrolled. Animated expand/collapse via\n * framer-motion (respects reduced-motion). Keyboard nav follows the\n * WAI-ARIA accordion pattern: ↑↓ moves between triggers, Home/End\n * jump to first/last, Enter/Space toggles.\n *\n * A11y: each item is `<div>` with a `<button aria-expanded>` header\n * and a `<div role=\"region\" aria-labelledby>` content panel.\n * ------------------------------------------------------------------------- */\n\nexport type AccordionMode = \"single\" | \"multiple\";\nexport type AccordionVariant = \"default\" | \"bordered\" | \"separated\";\n\nexport interface AccordionItem {\n /** Stable identifier. */\n id: string;\n /** Header label. */\n label: ReactNode;\n /** Optional secondary line below the label. */\n description?: ReactNode;\n /** Optional leading icon. */\n icon?: ReactNode;\n /** Optional trailing slot in the header (badge, count, action). */\n trailing?: ReactNode;\n /** Panel content. */\n content: ReactNode;\n /** Disable interaction for this item. */\n disabled?: boolean;\n}\n\nexport interface AccordionProps\n extends Omit<\n ComponentPropsWithoutRef<\"div\">,\n | \"onChange\"\n | \"defaultValue\"\n | \"children\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onAnimationStart\"\n > {\n /** Items to render. */\n items: AccordionItem[];\n /** Single vs multiple expansion. Default `\"single\"`. */\n mode?: AccordionMode;\n /** Controlled expanded item ids. */\n value?: string[];\n /** Uncontrolled initial expanded ids. */\n defaultValue?: string[];\n /** Fires when the expanded set changes. */\n onValueChange?: (value: string[]) => void;\n /**\n * Allow the last open item to be closed (single mode). Default\n * `true`. When `false`, one item is always open — useful for tabbed-\n * like surfaces.\n */\n collapsible?: boolean;\n /** Visual variant. Default `\"default\"`. */\n variant?: AccordionVariant;\n /** Visual size. Default `\"md\"`. */\n size?: \"sm\" | \"md\" | \"lg\";\n /** Disable the entire accordion. */\n disabled?: boolean;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Accordion = forwardRef<HTMLDivElement, AccordionProps>(\n function Accordion(\n {\n items,\n mode = \"single\",\n value: controlledValue,\n defaultValue,\n onValueChange,\n collapsible = true,\n variant = \"default\",\n size = \"md\",\n disabled = false,\n id: providedId,\n className,\n ...rest\n },\n ref,\n ) {\n const reactId = useId();\n const baseId = providedId ?? `ods-accordion-${reactId}`;\n const reducedMotion = useReducedMotion();\n\n const [internalValue, setInternalValue] = useState<string[]>(\n defaultValue ?? [],\n );\n const isControlled = controlledValue !== undefined;\n const value = isControlled ? controlledValue : internalValue;\n const valueSet = new Set(value);\n\n const setValue = useCallback(\n (next: string[]) => {\n if (!isControlled) setInternalValue(next);\n onValueChange?.(next);\n },\n [isControlled, onValueChange],\n );\n\n const toggleItem = useCallback(\n (id: string) => {\n const isOpen = valueSet.has(id);\n if (mode === \"multiple\") {\n const next = isOpen\n ? value.filter((v) => v !== id)\n : [...value, id];\n setValue(next);\n return;\n }\n // single\n if (isOpen) {\n // Only close if collapsible — otherwise no-op.\n if (collapsible) setValue([]);\n return;\n }\n setValue([id]);\n },\n [collapsible, mode, setValue, value, valueSet],\n );\n\n const handleKeyDown = (\n e: KeyboardEvent<HTMLButtonElement>,\n index: number,\n ) => {\n const enabledIdx = items\n .map((it, i) => (it.disabled ? -1 : i))\n .filter((i) => i !== -1);\n const curr = enabledIdx.indexOf(index);\n const focusIdx = (i: number) => {\n const target = enabledIdx[i];\n if (target === undefined) return;\n const btn = document.getElementById(\n `${baseId}-trigger-${items[target]!.id}`,\n );\n (btn as HTMLButtonElement | null)?.focus();\n };\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n focusIdx((curr + 1) % enabledIdx.length);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n focusIdx((curr - 1 + enabledIdx.length) % enabledIdx.length);\n } else if (e.key === \"Home\") {\n e.preventDefault();\n focusIdx(0);\n } else if (e.key === \"End\") {\n e.preventDefault();\n focusIdx(enabledIdx.length - 1);\n }\n };\n\n return (\n <div\n {...rest}\n ref={ref}\n id={baseId}\n className={cn(\n \"ods-accordion\",\n `ods-accordion--${variant}`,\n `ods-accordion--${size}`,\n disabled && \"ods-accordion--disabled\",\n className,\n )}\n >\n {items.map((item, i) => {\n const isOpen = valueSet.has(item.id);\n const itemDisabled = item.disabled || disabled;\n const triggerId = `${baseId}-trigger-${item.id}`;\n const panelId = `${baseId}-panel-${item.id}`;\n return (\n <div\n key={item.id}\n className={cn(\n \"ods-accordion__item\",\n isOpen && \"ods-accordion__item--open\",\n itemDisabled && \"ods-accordion__item--disabled\",\n )}\n >\n <button\n id={triggerId}\n type=\"button\"\n className=\"ods-accordion__trigger\"\n aria-expanded={isOpen}\n aria-controls={panelId}\n disabled={itemDisabled}\n onClick={() => toggleItem(item.id)}\n onKeyDown={(e) => handleKeyDown(e, i)}\n >\n {item.icon && (\n <span\n className=\"ods-accordion__icon\"\n aria-hidden=\"true\"\n >\n {item.icon}\n </span>\n )}\n <span className=\"ods-accordion__label-wrap\">\n <span className=\"ods-accordion__label\">{item.label}</span>\n {item.description && (\n <span className=\"ods-accordion__description\">\n {item.description}\n </span>\n )}\n </span>\n {item.trailing && (\n <span\n className=\"ods-accordion__trailing\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.trailing}\n </span>\n )}\n <span\n className={cn(\n \"ods-accordion__chevron\",\n isOpen && \"ods-accordion__chevron--open\",\n )}\n aria-hidden=\"true\"\n >\n <ChevronDownIcon size=\"sm\" aria-hidden />\n </span>\n </button>\n\n <AnimatePresence initial={false}>\n {isOpen && (\n <motion.div\n role=\"region\"\n id={panelId}\n aria-labelledby={triggerId}\n className=\"ods-accordion__panel\"\n initial={\n reducedMotion\n ? false\n : { height: 0, opacity: 0 }\n }\n animate={\n reducedMotion\n ? undefined\n : { height: \"auto\", opacity: 1 }\n }\n exit={\n reducedMotion\n ? undefined\n : { height: 0, opacity: 0 }\n }\n transition={\n reducedMotion\n ? { duration: 0 }\n : { duration: 0.18 }\n }\n style={{ overflow: \"hidden\" }}\n >\n <div className=\"ods-accordion__content\">\n {item.content}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n })}\n </div>\n );\n },\n);\n\nAccordion.displayName = \"Accordion\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n type ElementType,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Slot } from \"../../utils/Slot\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type BadgeVariant =\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"info\"\n | \"neutral\"\n | \"accent\";\n\nexport type BadgeSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface BadgeProps\n extends Omit<ComponentPropsWithoutRef<\"span\">, \"color\" | \"onClick\"> {\n variant?: BadgeVariant;\n size?: BadgeSize;\n\n /** Render a colored dot before the text. Mutually exclusive with `icon`. */\n dot?: boolean;\n /** Custom icon node rendered before the text. If both `icon` and `dot`\n * are passed, `icon` wins. */\n icon?: ReactNode;\n\n /** Render a `×` button to remove the badge. */\n closable?: boolean;\n /** @deprecated Use `closable`. Kept as an alias for back-compat. */\n closeable?: boolean;\n /** Fires when the user clicks (or activates via keyboard) the close\n * button. Receives the MouseEvent so callers can `stopPropagation` /\n * `preventDefault` as needed. */\n onClose?: (event: MouseEvent<HTMLButtonElement>) => void;\n /** Accessible label for the close button. Defaults to \"Remove\". Override\n * for localization or contextual reads (\"Remove tag 'cdc'\"). */\n closeLabel?: string;\n\n /** Thin outline + transparent background instead of the filled chip. */\n outlined?: boolean;\n\n /** Truncate long text with an ellipsis and surface the full content as a\n * `title` tooltip. `true` uses the design default (200 px); a number sets\n * an explicit max-width in px. */\n truncate?: boolean | number;\n\n /** Numeric badge convenience. Renders the value (or \"99+\" if > 99).\n * Ignored when `children` is also set. */\n count?: number;\n\n /** Click handler for the entire badge. Sets `role=\"button\"` and wires\n * Enter / Space keyboard activation. */\n onClick?: (event: MouseEvent<HTMLSpanElement>) => void;\n\n /** Render Badge's styling onto a custom child element (Radix-style Slot).\n * Useful for letting Badge own the chrome while a router link / tooltip\n * trigger / etc. owns the actual element semantics.\n *\n * Example:\n * <Badge asChild variant=\"accent\">\n * <NextLink href=\"/pricing\">Beta</NextLink>\n * </Badge>\n *\n * When `asChild` is true, Badge does NOT render its internal `dot`,\n * `icon`, or close-button slots — the consumer fully owns the content.\n * For chips with built-in slots, use the regular form without asChild. */\n asChild?: boolean;\n\n children?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers\n * ------------------------------------------------------------------------- */\n\nfunction formatCount(value: number): string {\n if (!Number.isFinite(value)) return \"\";\n if (value < 0) return \"0\";\n if (value > 99) return \"99+\";\n return String(Math.floor(value));\n}\n\n/** Inline close glyph — kept self-contained so Badge has no runtime dep on\n * `@octaviaflow/icons` (Badge is imported by very low-level surfaces that\n * shouldn't pull the icon package). */\nfunction CloseGlyph() {\n return (\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 10 10\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M2 2 L8 8 M8 2 L2 8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n {\n variant = \"neutral\",\n size = \"md\",\n dot = false,\n icon,\n closable,\n closeable, // deprecated alias\n onClose,\n closeLabel = \"Remove\",\n outlined = false,\n truncate = false,\n count,\n onClick,\n asChild = false,\n className,\n children,\n style,\n ...rest\n },\n ref,\n) {\n // Back-compat: prefer `closable` when set; fall back to legacy `closeable`.\n const isClosable = closable ?? closeable ?? false;\n const isClickable = Boolean(onClick);\n\n // `count` is short-hand for numeric content. Real `children` always wins\n // — that's the spec for filter chips that happen to also carry a count.\n const displayChildren =\n children ?? (count !== undefined ? formatCount(count) : undefined);\n\n // Truncation: turn the bool/number into a concrete style on the text span.\n // We attach `title` on the root for the hover-tooltip when content is a\n // plain string (so AT and mouse users both get the full label).\n const maxWidth =\n truncate === true ? \"var(--ods-badge-max-width, 200px)\" : typeof truncate === \"number\" ? `${truncate}px` : undefined;\n const truncateTitle =\n truncate && typeof displayChildren === \"string\" ? displayChildren : undefined;\n\n const handleKeyDown = (e: KeyboardEvent<HTMLSpanElement>) => {\n if (!isClickable) return;\n if ((e.key === \"Enter\" || e.key === \" \") && !e.repeat) {\n e.preventDefault();\n onClick?.(e as unknown as MouseEvent<HTMLSpanElement>);\n }\n };\n\n const handleCloseClick = (e: MouseEvent<HTMLButtonElement>) => {\n // Stop propagation so a Badge nested inside a clickable surface (card,\n // row, tag-input) doesn't fire the parent's onClick when the user is\n // removing the chip. Callers can still observe the event via onClose.\n e.stopPropagation();\n onClose?.(e);\n };\n\n const rootClassName = cn(\n \"ods-badge\",\n `ods-badge--${variant}`,\n `ods-badge--${size}`,\n outlined && \"ods-badge--outlined\",\n isClickable && \"ods-badge--interactive\",\n truncate && \"ods-badge--truncate\",\n className,\n );\n\n // asChild mode: clone the consumer's element and apply Badge's styling /\n // accessibility surface onto it. Internal slots (dot, icon, close) are\n // not rendered — the consumer's element fully owns the content.\n if (asChild) {\n return (\n <Slot\n {...(rest as ComponentPropsWithoutRef<ElementType>)}\n ref={ref as Ref<HTMLElement>}\n className={rootClassName}\n style={style}\n role={isClickable ? \"button\" : rest.role}\n tabIndex={isClickable ? (rest.tabIndex ?? 0) : rest.tabIndex}\n onClick={onClick as ((e: MouseEvent<HTMLElement>) => void) | undefined}\n onKeyDown={isClickable ? handleKeyDown : rest.onKeyDown}\n title={truncateTitle ?? rest.title}\n >\n {children as React.ReactElement}\n </Slot>\n );\n }\n\n return (\n <span\n {...rest}\n ref={ref}\n className={rootClassName}\n style={style}\n // The whole badge becomes a button when onClick is set. Otherwise we\n // leave the role unset so it stays a plain inline element.\n role={isClickable ? \"button\" : rest.role}\n tabIndex={isClickable ? (rest.tabIndex ?? 0) : rest.tabIndex}\n onClick={onClick as MouseEvent<HTMLSpanElement> extends MouseEvent<HTMLSpanElement> ? typeof onClick : never}\n onKeyDown={isClickable ? handleKeyDown : rest.onKeyDown}\n title={truncateTitle ?? rest.title}\n >\n {icon ? (\n <span className=\"ods-badge__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n ) : dot ? (\n <span className=\"ods-badge__dot\" aria-hidden=\"true\" />\n ) : null}\n <span\n className=\"ods-badge__text\"\n style={maxWidth ? { maxWidth } : undefined}\n >\n {displayChildren}\n </span>\n {isClosable && (\n <button\n type=\"button\"\n className=\"ods-badge__close\"\n onClick={handleCloseClick}\n aria-label={closeLabel}\n >\n <CloseGlyph />\n </button>\n )}\n </span>\n );\n});\n\nBadge.displayName = \"Badge\";\n","\"use client\";\nimport {\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n type CSSProperties,\n type HTMLAttributes,\n type ReactElement,\n type Ref,\n} from \"react\";\nimport { composeRefs } from \"./composeRefs\";\n\n/* ---------------------------------------------------------------------------\n * Slot — the `asChild` primitive\n *\n * Takes exactly one React element child and clones it, merging the Slot's\n * own props onto the child:\n * - `className` concatenates (slot's classes follow child's)\n * - `style` merges (child's keys win on overlap)\n * - Event handlers chain (slot's handler runs first; if it calls\n * `event.preventDefault()` the child's handler is short-circuited —\n * matching React's own synthetic-event default-handling convention)\n * - Refs compose so both the forwarded ref and the child's own ref point\n * at the rendered DOM node.\n *\n * This is what powers `asChild` across our primitives: it lets consumers\n * swap the rendered element (e.g., to a router Link) without losing the\n * component's styling, accessibility, or behavioural contract.\n * ------------------------------------------------------------------------- */\n\ntype AnyProps = Record<string, unknown>;\n\ninterface SlotProps extends HTMLAttributes<HTMLElement> {\n children?: React.ReactNode;\n}\n\nexport const Slot = forwardRef<HTMLElement, SlotProps>(function Slot(\n { children, ...slotProps },\n forwardedRef,\n) {\n if (!isValidElement(children)) {\n // Slot requires exactly one React element child. Returning null is\n // safer than throwing — callers that conditionally use `asChild` are\n // common, and we don't want stories / SSR to crash on an empty pass.\n return null;\n }\n const child = Children.only(children) as ReactElement<AnyProps>;\n const childProps = child.props ?? {};\n const childRef = (child as unknown as { ref?: Ref<HTMLElement> }).ref;\n\n return cloneElement(child, {\n ...mergeProps(slotProps as AnyProps, childProps),\n ref: forwardedRef ? composeRefs(forwardedRef, childRef) : childRef,\n });\n});\n\nfunction mergeProps(slotProps: AnyProps, childProps: AnyProps): AnyProps {\n // Start with the slot's props, then layer the child's on top. We then\n // walk back over the overlapping keys to apply per-key merge rules.\n const merged: AnyProps = { ...slotProps, ...childProps };\n\n for (const key of Object.keys(slotProps)) {\n const slotValue = slotProps[key];\n const childValue = childProps[key];\n\n // Event handlers — chain. Slot's handler runs first; if it invokes\n // event.preventDefault() the child's is skipped, matching the React\n // norm. Both being functions is the trigger.\n if (\n /^on[A-Z]/.test(key) &&\n typeof slotValue === \"function\" &&\n typeof childValue === \"function\"\n ) {\n merged[key] = (...args: unknown[]) => {\n (slotValue as (...a: unknown[]) => void)(...args);\n const event = args[0] as { defaultPrevented?: boolean } | undefined;\n if (event?.defaultPrevented) return;\n (childValue as (...a: unknown[]) => void)(...args);\n };\n continue;\n }\n\n // className — concatenate (slot's classes come first so child's can\n // visually override on direct conflict, which matches authoring intent).\n if (key === \"className\") {\n merged.className = [slotValue, childValue].filter(Boolean).join(\" \");\n continue;\n }\n\n // style — merge; child's keys win on overlap so consumers' inline\n // styles can override our defaults.\n if (key === \"style\") {\n merged.style = {\n ...(slotValue as CSSProperties | undefined),\n ...(childValue as CSSProperties | undefined),\n };\n continue;\n }\n }\n\n return merged;\n}\n","import type { MutableRefObject, Ref, RefCallback } from \"react\";\n\n/** Compose any number of refs (callback or object) into a single ref-callback.\n * Each underlying ref receives the node when React assigns it. Useful for the\n * `asChild` pattern where both the forwarded ref and the child's own ref need\n * to point at the same DOM node. */\nexport function composeRefs<T>(...refs: Array<Ref<T> | undefined | null>): RefCallback<T> {\n return (node: T) => {\n for (const ref of refs) {\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref != null) {\n (ref as MutableRefObject<T | null>).current = node;\n }\n }\n };\n}\n","\"use client\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport {\n type ComponentPropsWithoutRef,\n type ElementType,\n forwardRef,\n type ReactElement,\n type ReactNode,\n type Ref,\n useEffect,\n useRef,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Slot } from \"../../utils/Slot\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type BannerVariant = \"info\" | \"success\" | \"warning\" | \"error\" | \"promo\" | \"neutral\";\nexport type BannerSize = \"sm\" | \"md\" | \"lg\";\n\n/** Direction the banner slides in / out from. Default = `down` (enters\n * slightly above its final position, settles down + fades in). */\nexport type BannerAnimateFrom = \"top\" | \"bottom\" | \"left\" | \"right\" | \"none\";\nexport type BannerAppearance = \"filled\" | \"outlined\" | \"subtle\";\n\nexport interface BannerProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"color\" | \"title\"> {\n /** Visual / semantic variant. `error` defaults to `role=\"alert\"`; the rest\n * default to `role=\"status\"` (polite live region). */\n variant?: BannerVariant;\n /** Size variant. */\n size?: BannerSize;\n /** Appearance treatment. `filled` (default) uses the variant's bg/border;\n * `outlined` keeps the border but drops the fill; `subtle` mutes both. */\n appearance?: BannerAppearance;\n\n /** Leading icon. If omitted, Banner renders a sensible default per\n * variant (info/success/warning/error/promo). Pass `null` explicitly to\n * suppress the default. */\n icon?: ReactNode | null;\n title?: ReactNode;\n description?: ReactNode;\n\n /** Trailing action slot (typically a Button). */\n action?: ReactNode;\n /** Renders a dismiss `×` button on the trailing edge. */\n dismissible?: boolean;\n /** Fires when the dismiss button is clicked. */\n onDismiss?: () => void;\n /** Accessible label for the dismiss button. Defaults to \"Dismiss\". */\n dismissLabel?: string;\n\n /** Override the inferred role. Pass explicitly for non-default\n * announcements (\"alert\", \"alertdialog\", \"region\", etc.). */\n role?: ComponentPropsWithoutRef<\"div\">[\"role\"];\n\n /** Auto-focus the banner when it first mounts. Useful for error banners\n * that should grab focus on appearance so AT users notice them. */\n autoFocus?: boolean;\n\n /** Controls whether the banner is mounted. Pair with `useBanner()` for\n * declarative show/hide state, or wire to your own state. When omitted,\n * the banner is always mounted (the regular, animation-free shape). */\n open?: boolean;\n /** Direction the enter/exit animation slides from. Defaults to `top`.\n * `none` disables the slide entirely (still fades). */\n animateFrom?: BannerAnimateFrom;\n /** Disable all enter/exit motion. Use when the banner is part of a\n * larger animation managed externally. */\n disableAnimation?: boolean;\n\n /** Render Banner's styling onto a custom child element (Radix-style Slot).\n *\n * Example — a clickable banner-as-link:\n * <Banner asChild variant=\"promo\">\n * <a href=\"/changelog\">New release! See what's new →</a>\n * </Banner>\n *\n * When `asChild` is true, Banner does NOT render its internal icon /\n * title / description / action / dismiss slots. The consumer's element\n * fully owns the content. */\n asChild?: boolean;\n\n children?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Default per-variant icons — self-contained SVGs so Banner has no runtime\n * dependency on @octaviaflow/icons. They inherit color via `currentColor`\n * so the variant's icon color applies.\n * ------------------------------------------------------------------------- */\n\nfunction InfoIcon() {\n return (\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <circle cx=\"9\" cy=\"9\" r=\"7.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M9 8v4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"9\" cy=\"5.5\" r=\"0.9\" fill=\"currentColor\" />\n </svg>\n );\n}\nfunction SuccessIcon() {\n return (\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <circle cx=\"9\" cy=\"9\" r=\"7.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M5.5 9.2 8 11.5 12.5 6.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n}\nfunction WarningIcon() {\n return (\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M9 2 L16 15 H2 Z\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinejoin=\"round\" />\n <path d=\"M9 7v4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"9\" cy=\"13\" r=\"0.9\" fill=\"currentColor\" />\n </svg>\n );\n}\nfunction ErrorIcon() {\n return (\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <circle cx=\"9\" cy=\"9\" r=\"7.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M6.5 6.5 11.5 11.5 M11.5 6.5 6.5 11.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n );\n}\nfunction PromoIcon() {\n return (\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <path\n d=\"M9 1.5 L11 6.5 L16.5 7 L12.4 10.7 L13.7 16 L9 13 L4.3 16 L5.6 10.7 L1.5 7 L7 6.5 Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nconst DEFAULT_ICONS: Record<BannerVariant, () => ReactElement> = {\n info: InfoIcon,\n success: SuccessIcon,\n warning: WarningIcon,\n error: ErrorIcon,\n promo: PromoIcon,\n neutral: InfoIcon,\n};\n\nfunction DismissGlyph() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <path\n d=\"M3.5 3.5 L10.5 10.5 M10.5 3.5 L3.5 10.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\n/* ---------------------------------------------------------------------------\n * Enter/exit motion offsets per direction. Subtle by design — banners\n * shouldn't fly across the viewport on appear; ~8 px is enough to read as\n * \"arrived\" without distracting from the content. Under reduced-motion we\n * zero out the transform and just cross-fade.\n * ------------------------------------------------------------------------- */\nconst MOTION_OFFSETS: Record<BannerAnimateFrom, { x: number; y: number }> = {\n top: { x: 0, y: -8 },\n bottom: { x: 0, y: 8 },\n left: { x: -8, y: 0 },\n right: { x: 8, y: 0 },\n none: { x: 0, y: 0 },\n};\n\nexport const Banner = forwardRef<HTMLDivElement, BannerProps>(function Banner(\n {\n variant = \"info\",\n size = \"md\",\n appearance = \"filled\",\n icon,\n title,\n description,\n action,\n dismissible = false,\n onDismiss,\n dismissLabel = \"Dismiss\",\n role,\n autoFocus = false,\n asChild = false,\n open,\n animateFrom = \"top\",\n disableAnimation = false,\n className,\n children,\n ...rest\n },\n ref,\n) {\n // Variant → default ARIA role. `error` is announced as an alert so AT\n // interrupts; everything else is a polite live status region.\n const resolvedRole = role ?? (variant === \"error\" ? \"alert\" : \"status\");\n\n // Resolve the icon: explicit `null` → suppress; undefined → variant default;\n // anything else → as passed.\n const DefaultIconComponent = DEFAULT_ICONS[variant];\n const resolvedIcon =\n icon === null ? null : icon === undefined ? <DefaultIconComponent /> : icon;\n\n // Hooks must run unconditionally (rules of hooks). Compose them up here\n // even though some render paths below don't use them.\n const reducedMotion = useReducedMotion();\n const internalRef = useRef<HTMLDivElement | null>(null);\n const setRef = (node: HTMLDivElement | null) => {\n internalRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as { current: HTMLDivElement | null }).current = node;\n };\n\n useEffect(() => {\n if (autoFocus && internalRef.current) {\n // Banner is not normally focusable; ensure tabIndex=-1 so focus() is\n // programmatically valid without exposing the banner to Tab traversal.\n internalRef.current.focus({ preventScroll: false });\n }\n }, [autoFocus]);\n\n const rootClassName = cn(\n \"ods-banner\",\n `ods-banner--${variant}`,\n `ods-banner--${size}`,\n `ods-banner--${appearance}`,\n className,\n );\n\n // asChild mode — clone the consumer's element and project Banner's chrome\n // onto it. Internal slots aren't rendered.\n if (asChild) {\n return (\n <Slot\n {...(rest as ComponentPropsWithoutRef<ElementType>)}\n ref={ref as Ref<HTMLElement>}\n className={rootClassName}\n role={resolvedRole}\n >\n {children as ReactElement}\n </Slot>\n );\n }\n\n // Inner slots shared by every render path (plain / animated / static\n // closed). Pulled out so the animation wrapper doesn't duplicate JSX.\n const innerSlots = (\n <>\n {resolvedIcon && (\n <span className=\"ods-banner__icon\" aria-hidden=\"true\">\n {resolvedIcon}\n </span>\n )}\n <div className=\"ods-banner__body\">\n {title && <div className=\"ods-banner__title\">{title}</div>}\n {description && <div className=\"ods-banner__description\">{description}</div>}\n {children}\n </div>\n {action && <div className=\"ods-banner__action\">{action}</div>}\n {dismissible && (\n <button\n type=\"button\"\n className=\"ods-banner__dismiss\"\n onClick={onDismiss}\n aria-label={dismissLabel}\n >\n <DismissGlyph />\n </button>\n )}\n </>\n );\n\n // Uncontrolled mode (no `open` prop): always rendered, no animation.\n // Keeps the legacy / static shape working for consumers that don't need\n // mount/unmount behaviour.\n if (open === undefined) {\n return (\n <div\n {...rest}\n ref={setRef}\n className={rootClassName}\n role={resolvedRole}\n tabIndex={autoFocus ? -1 : rest.tabIndex}\n >\n {innerSlots}\n </div>\n );\n }\n\n // Controlled mode without animation — plain mount/unmount.\n if (disableAnimation) {\n if (!open) return null;\n return (\n <div\n {...rest}\n ref={setRef}\n className={rootClassName}\n role={resolvedRole}\n tabIndex={autoFocus ? -1 : rest.tabIndex}\n >\n {innerSlots}\n </div>\n );\n }\n\n // Controlled mode with animation: AnimatePresence drives enter/exit.\n // Under prefers-reduced-motion we zero out the transform and rely on the\n // opacity cross-fade only — which is well under perceptual thresholds.\n const offset = reducedMotion\n ? { x: 0, y: 0 }\n : MOTION_OFFSETS[animateFrom];\n\n return (\n <AnimatePresence initial={false}>\n {open && (\n <motion.div\n {...(rest as Omit<typeof rest, \"onDrag\" | \"onDragStart\" | \"onDragEnd\" | \"onAnimationStart\" | \"onAnimationEnd\">)}\n ref={setRef}\n className={rootClassName}\n role={resolvedRole}\n tabIndex={autoFocus ? -1 : rest.tabIndex}\n initial={{ opacity: 0, x: offset.x, y: offset.y }}\n animate={{ opacity: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, x: offset.x, y: offset.y }}\n transition={{ duration: 0.18, ease: [0.16, 1, 0.3, 1] }}\n >\n {innerSlots}\n </motion.div>\n )}\n </AnimatePresence>\n );\n});\n\nBanner.displayName = \"Banner\";\n","\"use client\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport {\n type ButtonHTMLAttributes,\n type CSSProperties,\n forwardRef,\n type ReactElement,\n type ReactNode,\n type Ref,\n useImperativeHandle,\n useRef,\n} from \"react\";\nimport { useButton } from \"react-aria\";\nimport { resolveAccessibleName, hasRenderableText } from \"../../utils/a11y\";\nimport { cn } from \"../../utils/cn\";\nimport { Slot } from \"../../utils/Slot\";\n\nexport interface ButtonProps\n extends Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"onDrag\" | \"onDragStart\" | \"onDragEnd\" | \"onAnimationStart\"\n > {\n variant?: \"primary\" | \"secondary\" | \"ghost\" | \"danger\" | \"icon\";\n size?: \"sm\" | \"md\" | \"lg\";\n loading?: boolean;\n /** Override the rendered label while loading. Useful for action verbs that\n * change form mid-request — e.g. `\"Sign in\"` → `\"Signing in…\"`. */\n loadingText?: ReactNode;\n /** Accessible label for the spinner (announced by AT during loading).\n * Defaults to `\"Loading\"`. Customize for localization or context. */\n loadingLabel?: string;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n fullWidth?: boolean;\n /** Toggle-button state. When defined, the button advertises\n * `aria-pressed` and adds `--pressed` styling. */\n pressed?: boolean;\n children?: ReactNode;\n /**\n * Override the cursor shown on hover. When omitted, the cursor auto-resolves:\n * - `not-allowed` when disabled (CSS handles this — see Button.module.scss)\n * - `progress` when loading (request in flight)\n * - `pointer` when the button has an action (onClick, type=\"submit\",\n * or type=\"reset\"). Anchors (href) get pointer too.\n * - `default` otherwise (decorative / placeholder buttons)\n * Pass an explicit value (e.g. `\"text\"`, `\"grab\"`) to override the\n * auto-resolve for the specific story / use case.\n */\n cursor?: CSSProperties[\"cursor\"];\n /** Render Button's styling onto a custom child element (Radix-style Slot).\n *\n * <Button asChild variant=\"primary\">\n * <NextLink href=\"/checkout\">Continue</NextLink>\n * </Button>\n *\n * When `asChild` is true, Button does NOT render its internal icon /\n * label / spinner slots — the consumer's element fully owns content. Use\n * the regular form (without `asChild`) when you want the built-in\n * slots / loading spinner / size-scaled icons. */\n asChild?: boolean;\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n variant = \"primary\",\n size = \"md\",\n loading = false,\n loadingText,\n loadingLabel = \"Loading\",\n disabled = false,\n leftIcon,\n rightIcon,\n fullWidth = false,\n pressed,\n asChild = false,\n className,\n children,\n type,\n cursor,\n style,\n ...props\n },\n forwardedRef,\n) {\n const ref = useRef<HTMLButtonElement>(null);\n useImperativeHandle(forwardedRef, () => ref.current as HTMLButtonElement);\n const isDisabled = disabled || loading;\n // Respect users who've asked for reduced motion (OS-level a11y setting).\n // When true we skip the whileTap scale animation entirely — Framer's own\n // hook reads `prefers-reduced-motion: reduce` and stays reactive.\n const prefersReducedMotion = useReducedMotion();\n\n // Cursor resolution (centralised in JS so inline-style specificity wins\n // over any CSS cursor rule). Order of precedence:\n // 1. Caller's explicit `cursor` prop.\n // 2. `not-allowed` when disabled (and not also loading — see below).\n // 3. `progress` when loading (button is intentionally non-interactive\n // but the user should see we're working on it).\n // 4. `pointer` when the button has an action.\n // 5. `default` for decorative buttons.\n // Disabled takes precedence over loading when BOTH are set: explicit\n // disabled is a stronger intent than \"currently busy\".\n // Button always renders a native <button>; anchor semantics live on\n // LinkButton. No href branch needed here.\n const hasAction = Boolean(props.onClick) || type === \"submit\" || type === \"reset\";\n const resolvedCursor: string =\n cursor ?? (disabled ? \"not-allowed\" : loading ? \"progress\" : hasAction ? \"pointer\" : \"default\");\n // Forms rely on `type=\"submit\"` to trigger submission. React Aria's useButton\n // defaults type to \"button\" when omitted, so we always pass the caller's type\n // through (defaulting to \"button\" only when truly unspecified).\n const resolvedType: \"button\" | \"submit\" | \"reset\" = type ?? \"button\";\n\n // Buttons get their accessible name from children. Icon-only buttons\n // (variant=\"icon\" or empty children + iconLeft/Right) MUST provide\n // aria-label or aria-labelledby — we resolve it here so react-aria's\n // useButton receives a guaranteed string-or-id, and dev-mode console.error\n // surfaces the missing-name case.\n //\n // `hasVisibleText` counts any renderable TEXT in children — including text\n // inside arrays/fragments/elements (e.g. `{cond && \"Connect\"}` which React\n // passes as an array, or `<span>Save</span>`). SVG/icon-only subtrees carry\n // no readable text, so genuinely icon-only buttons still require an explicit\n // aria-label. (A glyph string like \"×\" counts — announced verbatim.) This\n // must NOT be a bare `typeof children === \"string\"` check: conditional or\n // interpolated text children are arrays, and missing them here forces a\n // bogus `aria-label=\"Unlabeled Button\"` that overrides the real label.\n const hasVisibleText = hasRenderableText(children);\n // In `asChild` mode the consumer's element owns its own accessible name\n // (e.g., the anchor's text content). Suppress Button's own a11y check\n // to avoid false-positive dev warnings.\n const needsAriaName = !hasVisibleText && !asChild;\n const ariaNameProps = needsAriaName\n ? resolveAccessibleName({\n ariaLabel: (props as any)[\"aria-label\"],\n ariaLabelledby: (props as any)[\"aria-labelledby\"],\n componentName: \"Button\",\n })\n : undefined;\n\n const { buttonProps } = useButton(\n {\n isDisabled,\n onPress: props.onClick as any,\n type: resolvedType,\n ...(ariaNameProps ?? {}),\n },\n ref,\n );\n\n // Strip Framer-conflicting props from React Aria output\n const { onDrag, onDragStart, onDragEnd, onAnimationStart, ...safeButtonProps } =\n buttonProps as any;\n\n // Native HTML button attributes the caller passed (form, name, value,\n // aria-*, data-*, etc.) must reach the DOM. We strip the ones React Aria\n // already manages from buttonProps to avoid double-binding event handlers.\n const {\n onClick: _onClick,\n onKeyDown: _onKeyDown,\n onKeyUp: _onKeyUp,\n onMouseDown: _onMouseDown,\n onPointerDown: _onPointerDown,\n onPointerUp: _onPointerUp,\n onFocus: _onFocus,\n onBlur: _onBlur,\n ...passthroughProps\n } = props as Record<string, unknown>;\n\n const rootClassName = cn(\n \"ods-btn\",\n `ods-btn--${variant}`,\n `ods-btn--${size}`,\n loading && \"ods-btn--loading\",\n fullWidth && \"ods-btn--full\",\n pressed && \"ods-btn--pressed\",\n className,\n );\n\n // asChild mode — project Button's chrome onto the consumer's element.\n // Internal slots (icons, spinner, label) are NOT rendered — consumer\n // owns the content. react-aria event wiring is also skipped because\n // the consumer's element handles its own activation semantics.\n if (asChild) {\n return (\n <Slot\n {...(passthroughProps as Record<string, unknown>)}\n ref={forwardedRef as unknown as Ref<HTMLElement>}\n className={rootClassName}\n style={{ cursor: resolvedCursor, ...(style as CSSProperties) }}\n aria-pressed={pressed}\n aria-disabled={isDisabled || undefined}\n >\n {children as ReactElement}\n </Slot>\n );\n }\n\n // The visible label — `loadingText` overrides `children` while loading\n // so the in-progress verb form (\"Signing in…\") replaces the idle one.\n const visibleLabel = loading && loadingText !== undefined ? loadingText : children;\n\n return (\n <motion.button\n {...(passthroughProps as any)}\n {...safeButtonProps}\n type={resolvedType}\n ref={ref}\n className={rootClassName}\n // Disabled state CSS rule (cursor: not-allowed) outranks this inline\n // value — see Button.module.scss. So `style.cursor` only applies to\n // idle/loading/active states, exactly what we want.\n style={{ cursor: resolvedCursor, ...(style as any) }}\n data-loading={loading || undefined}\n aria-busy={loading || undefined}\n aria-pressed={pressed}\n whileTap={isDisabled || prefersReducedMotion ? undefined : { scale: 0.97 }}\n transition={{ duration: 0.1 }}\n >\n {/* Content layer. When loading, the leftIcon slot is replaced by an\n inline spinner — both spinner AND label stay visible so the user\n sees the in-progress text (e.g. \"Signing in…\") next to the\n activity indicator. */}\n <span className=\"ods-btn__content\">\n {loading ? (\n <span\n className=\"ods-btn__icon ods-btn__icon--left ods-btn__icon--spinner\"\n role=\"status\"\n aria-label={loadingLabel}\n >\n {/* viewBox is 1em-scaled by CSS (.ods-btn__icon svg → 1em) so\n the spinner tracks the per-size icon scale (12 / 14 / 16 px)\n without needing per-size width attributes. */}\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeDasharray=\"32\"\n strokeDashoffset=\"12\"\n />\n </svg>\n </span>\n ) : (\n leftIcon && <span className=\"ods-btn__icon ods-btn__icon--left\">{leftIcon}</span>\n )}\n {visibleLabel != null && visibleLabel !== false && (\n <span className=\"ods-btn__label\">{visibleLabel}</span>\n )}\n {rightIcon && !loading && (\n <span className=\"ods-btn__icon ods-btn__icon--right\">{rightIcon}</span>\n )}\n </span>\n </motion.button>\n );\n});\n\nButton.displayName = \"Button\";\n","/**\n * a11y — shared helpers for resolving an accessible name from the union of\n * props every form/interactive component accepts.\n *\n * Why this exists:\n * react-aria's hooks (useCheckbox, useSwitch, useRadio, useTextField,\n * useButton, etc.) emit a runtime warning to the browser console when\n * none of the following is present on the underlying element:\n * - aria-label\n * - aria-labelledby\n * - a visible <label> with htmlFor pointing to the element id\n *\n * Many of our components accept `label` as `string | ReactNode`. When\n * `label` is a ReactNode (icon + text, custom JSX), react-aria can't see\n * a text label and the warning fires. This helper centralizes the\n * derivation: it returns a single { 'aria-label' or 'aria-labelledby' }\n * shape that react-aria will accept, and — in development only — it\n * surfaces a focused console.error pointing the developer at the prop\n * they're missing instead of the generic react-aria warning.\n *\n * Usage:\n * const ariaProps = resolveAccessibleName({\n * label,\n * ariaLabel: props['aria-label'],\n * ariaLabelledby: props['aria-labelledby'],\n * componentName: 'Checkbox',\n * });\n * // → { 'aria-label': string } | { 'aria-labelledby': string } | { 'aria-label': string }\n *\n * useCheckbox({ ...otherProps, ...ariaProps }, state, ref);\n */\n\nimport { isValidElement, type ReactNode } from \"react\";\n\n/**\n * True when a ReactNode renders any non-empty, human-readable text.\n *\n * Used by controls whose accessible name comes from their CHILDREN (e.g.\n * Button). Recurses through arrays, fragments, and element children so that\n * conditionally-rendered or wrapped text is detected — e.g.\n * `{cond && \"Save\"}`, `[\"Connect with \", name]`, or `<span>Save</span>`.\n *\n * Returns false for icon/SVG-only subtrees (no string content), so genuinely\n * icon-only controls still trip the missing-accessible-name check. Numbers\n * count (they render as announced text, including 0); booleans / null /\n * undefined do not render and so don't count.\n */\nexport function hasRenderableText(node: ReactNode): boolean {\n if (node === null || node === undefined || typeof node === \"boolean\") return false;\n if (typeof node === \"string\") return node.trim().length > 0;\n if (typeof node === \"number\") return true;\n if (Array.isArray(node)) return node.some(hasRenderableText);\n if (isValidElement(node)) {\n return hasRenderableText((node.props as { children?: ReactNode }).children);\n }\n return false;\n}\n\n/**\n * Extract the concatenated visible text from a ReactNode — used to derive an\n * accessible name when a control accepts a rich `label` (icon + text, custom\n * JSX). Mirrors `hasRenderableText`'s traversal: strings/numbers contribute,\n * arrays/fragments/elements recurse into their children, and\n * booleans/null/undefined contribute nothing. Returns '' when there is no text.\n */\nexport function getRenderableText(node: ReactNode): string {\n if (node === null || node === undefined || typeof node === \"boolean\") return \"\";\n if (typeof node === \"string\") return node;\n if (typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(getRenderableText).join(\"\");\n if (isValidElement(node)) {\n return getRenderableText((node.props as { children?: ReactNode }).children);\n }\n return \"\";\n}\n\nexport interface ResolveAccessibleNameInput {\n /** The visible label, if any. Strings are auto-used as aria-label. */\n label?: ReactNode;\n /** Caller-provided aria-label override. Highest priority when present. */\n ariaLabel?: string;\n /** Caller-provided aria-labelledby. Wins over label-derived values. */\n ariaLabelledby?: string;\n /**\n * Component name used in dev-mode error messages. Helps the developer\n * locate which usage needs a label.\n */\n componentName: string;\n /**\n * Optional secondary fallbacks the component knows about — e.g. a Radio\n * can fall back to its `value` so radios in a group are at least\n * distinguishable. The first non-empty string is used.\n */\n fallbacks?: Array<string | undefined>;\n}\n\nexport type ResolvedAccessibleName = { \"aria-label\": string } | { \"aria-labelledby\": string };\n\n/**\n * Resolve the accessible-name props that should be spread onto the\n * underlying element. Guarantees at least one of aria-label / aria-labelledby\n * is present so react-aria won't warn at runtime.\n *\n * Priority order:\n * 1. aria-labelledby (caller-provided)\n * 2. aria-label (caller-provided)\n * 3. label (when string)\n * 4. fallbacks (when string)\n * 5. component-name placeholder + dev-mode console.error\n */\nexport function resolveAccessibleName(input: ResolveAccessibleNameInput): ResolvedAccessibleName {\n if (input.ariaLabelledby) {\n return { \"aria-labelledby\": input.ariaLabelledby };\n }\n if (input.ariaLabel) {\n return { \"aria-label\": input.ariaLabel };\n }\n if (typeof input.label === \"string\" && input.label.trim().length > 0) {\n return { \"aria-label\": input.label };\n }\n for (const candidate of input.fallbacks ?? []) {\n if (typeof candidate === \"string\" && candidate.trim().length > 0) {\n return { \"aria-label\": candidate };\n }\n }\n\n // Last resort — emit a placeholder so react-aria stays quiet in\n // production, but loudly point at the missing prop in development so the\n // developer fixes the real bug rather than ignoring a global warning.\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line no-console\n console.error(\n `[@octaviaflow/core ${input.componentName}] No accessible name. ` +\n `Pass a string \\`label\\`, or \\`aria-label\\`, or \\`aria-labelledby\\` ` +\n `so screen readers can announce this control.`,\n );\n }\n return { \"aria-label\": `Unlabeled ${input.componentName}` };\n}\n","\"use client\";\nimport {\n CheckmarkIcon,\n CopyIcon,\n MagicWandIcon,\n SearchIcon,\n TextWrapIcon,\n} from \"@octaviaflow/icons\";\nimport {\n forwardRef,\n type ReactNode,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport type CodeEditorLanguage = \"sql\" | \"json\" | \"javascript\" | \"typescript\" | \"yaml\" | \"plain\";\n\nexport interface CodeEditorProps {\n value: string;\n onChange?: (value: string) => void;\n language?: CodeEditorLanguage;\n /** Read-only mode. */\n readOnly?: boolean;\n /** Hide the gutter (line numbers). */\n showLineNumbers?: boolean;\n /** Highlight the active line. */\n highlightActiveLine?: boolean;\n /** Number of spaces a Tab inserts. */\n tabSize?: number;\n /** Minimum height in pixels. */\n minHeight?: number;\n /** Maximum height in pixels. */\n maxHeight?: number;\n placeholder?: string;\n ariaLabel?: string;\n /** Optional toolbar slot above the editor. */\n toolbar?: ReactNode;\n /** Status pill on the right side of the toolbar. */\n status?: ReactNode;\n className?: string;\n /** Show built-in Copy button. Default true. */\n showCopy?: boolean;\n /** Show built-in Format button (JSON only by default). */\n showFormat?: boolean;\n /** Word wrap (controlled). */\n wordWrap?: boolean;\n /** Show built-in word-wrap toggle. Default true (only when uncontrolled). */\n showWordWrapToggle?: boolean;\n /** Enable auto-pair brackets and quotes. Default true. */\n autoPair?: boolean;\n /** Show character/selection counter at bottom. Default true. */\n showCounter?: boolean;\n /** Enable Cmd+F search bar. Default true. */\n searchable?: boolean;\n\n /** Form integration — passes through to the underlying <textarea>. */\n name?: string;\n /** Form attribute (for buttons rendered outside their parent form). */\n form?: string;\n /** Mark as required for native form validation. */\n required?: boolean;\n /** Native id (replaces the auto-generated one if you need to pair a\n * <label htmlFor> with this editor). */\n id?: string;\n}\n\nconst COMMENT_PREFIX: Record<CodeEditorLanguage, string> = {\n sql: \"-- \",\n json: \"// \",\n javascript: \"// \",\n typescript: \"// \",\n yaml: \"# \",\n plain: \"// \",\n};\n\nconst OPEN_PAIRS: Record<string, string> = {\n \"{\": \"}\",\n \"[\": \"]\",\n \"(\": \")\",\n '\"': '\"',\n \"'\": \"'\",\n \"`\": \"`\",\n};\nconst CLOSE_PAIRS = new Set(Object.values(OPEN_PAIRS));\n\nfunction tryFormat(value: string, language: CodeEditorLanguage): string | null {\n if (language === \"json\") {\n try {\n return JSON.stringify(JSON.parse(value), null, 2);\n } catch {\n return null;\n }\n }\n return null;\n}\n\nexport const CodeEditor = forwardRef<HTMLTextAreaElement, CodeEditorProps>(\n function CodeEditor(\n {\n value,\n onChange,\n language = \"plain\",\n readOnly = false,\n showLineNumbers = true,\n highlightActiveLine = true,\n tabSize = 2,\n minHeight = 120,\n maxHeight,\n placeholder = \"Type code here…\",\n ariaLabel = \"Code editor\",\n toolbar,\n status,\n className,\n showCopy = true,\n showFormat,\n wordWrap: wordWrapProp,\n showWordWrapToggle = true,\n autoPair = true,\n showCounter = true,\n searchable = true,\n name,\n form,\n required,\n id,\n },\n forwardedRef,\n ) {\n const taRef = useRef<HTMLTextAreaElement>(null);\n // Bridge the local ref to the forwarded one so consumers can access the\n // underlying textarea (focus, select, scrollIntoView, etc.).\n useImperativeHandle(forwardedRef, () => taRef.current as HTMLTextAreaElement);\n const gutterRef = useRef<HTMLDivElement>(null);\n const [activeLine, setActiveLine] = useState(1);\n const [copied, setCopied] = useState(false);\n const [internalWrap, setInternalWrap] = useState<boolean>(wordWrapProp ?? false);\n const wordWrap = wordWrapProp ?? internalWrap;\n const [selectionLen, setSelectionLen] = useState(0);\n const [selectionLines, setSelectionLines] = useState(0);\n const [findOpen, setFindOpen] = useState(false);\n const [findQuery, setFindQuery] = useState(\"\");\n const [findIndex, setFindIndex] = useState(0);\n const findInputRef = useRef<HTMLInputElement>(null);\n\n const lines = value.split(\"\\n\");\n const lineCount = lines.length;\n\n const matches = useMemo(() => {\n if (!findQuery) return [] as Array<{ start: number; end: number }>;\n const out: Array<{ start: number; end: number }> = [];\n const lower = value.toLowerCase();\n const q = findQuery.toLowerCase();\n let i = 0;\n while (i <= lower.length - q.length) {\n const idx = lower.indexOf(q, i);\n if (idx < 0) break;\n out.push({ start: idx, end: idx + q.length });\n i = idx + Math.max(1, q.length);\n }\n return out;\n }, [findQuery, value]);\n\n useEffect(() => {\n const ta = taRef.current;\n const gut = gutterRef.current;\n if (!ta || !gut) return;\n const onScroll = () => {\n gut.scrollTop = ta.scrollTop;\n };\n ta.addEventListener(\"scroll\", onScroll);\n return () => ta.removeEventListener(\"scroll\", onScroll);\n }, []);\n\n const updateSelection = () => {\n const ta = taRef.current;\n if (!ta) return;\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const upTo = ta.value.slice(0, start);\n setActiveLine(upTo.split(\"\\n\").length);\n const selLen = end - start;\n setSelectionLen(selLen);\n if (selLen > 0) {\n const slice = ta.value.slice(start, end);\n setSelectionLines(slice.split(\"\\n\").length);\n } else {\n setSelectionLines(0);\n }\n };\n\n const setCaret = (start: number, end?: number) => {\n requestAnimationFrame(() => {\n const ta = taRef.current;\n if (!ta) return;\n ta.selectionStart = start;\n ta.selectionEnd = end ?? start;\n updateSelection();\n });\n };\n\n const replaceRange = (start: number, end: number, replacement: string, caretAt?: number) => {\n const next = value.slice(0, start) + replacement + value.slice(end);\n onChange?.(next);\n setCaret(caretAt ?? start + replacement.length);\n };\n\n const lineBounds = (text: string, caret: number) => {\n const before = text.lastIndexOf(\"\\n\", caret - 1);\n const after = text.indexOf(\"\\n\", caret);\n return {\n lineStart: before === -1 ? 0 : before + 1,\n lineEnd: after === -1 ? text.length : after,\n };\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n const ta = e.currentTarget;\n if (readOnly) return;\n const isMac = typeof navigator !== \"undefined\" && /Mac/.test(navigator.platform);\n const mod = isMac ? e.metaKey : e.ctrlKey;\n\n // Cmd+F → open find bar\n if (mod && (e.key === \"f\" || e.key === \"F\")) {\n if (!searchable) return;\n e.preventDefault();\n setFindOpen(true);\n requestAnimationFrame(() => findInputRef.current?.focus());\n return;\n }\n\n // Escape closes find\n if (e.key === \"Escape\" && findOpen) {\n e.preventDefault();\n setFindOpen(false);\n return;\n }\n\n // Cmd+/ → toggle comment for current line or selection\n if (mod && e.key === \"/\") {\n e.preventDefault();\n const prefix = COMMENT_PREFIX[language];\n const trimmedPrefix = prefix.trim();\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const firstStart = lineBounds(value, start).lineStart;\n const lastEnd = lineBounds(value, end).lineEnd;\n const slice = value.slice(firstStart, lastEnd);\n const partLines = slice.split(\"\\n\");\n const allCommented = partLines.every(\n (l) => l.trim() === \"\" || l.trimStart().startsWith(trimmedPrefix),\n );\n const updated = partLines\n .map((l) => {\n if (l.trim() === \"\") return l;\n if (allCommented) {\n const idx = l.indexOf(trimmedPrefix);\n if (idx >= 0) return l.slice(0, idx) + l.slice(idx + prefix.length);\n return l;\n }\n const leading = l.match(/^\\s*/)?.[0] ?? \"\";\n return `${leading}${prefix}${l.slice(leading.length)}`;\n })\n .join(\"\\n\");\n const next = value.slice(0, firstStart) + updated + value.slice(lastEnd);\n onChange?.(next);\n const delta = updated.length - slice.length;\n setCaret(start + (allCommented ? -prefix.length : prefix.length), end + delta);\n return;\n }\n\n // Cmd+D → duplicate current line (or selection)\n if (mod && (e.key === \"d\" || e.key === \"D\")) {\n e.preventDefault();\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n if (start === end) {\n const { lineStart, lineEnd } = lineBounds(value, start);\n const line = value.slice(lineStart, lineEnd);\n const next = value.slice(0, lineEnd) + \"\\n\" + line + value.slice(lineEnd);\n onChange?.(next);\n setCaret(start + line.length + 1);\n } else {\n const slice = value.slice(start, end);\n const next = value.slice(0, end) + slice + value.slice(end);\n onChange?.(next);\n setCaret(end + slice.length);\n }\n return;\n }\n\n // Alt+ArrowUp/Down → move line up/down\n if (e.altKey && (e.key === \"ArrowUp\" || e.key === \"ArrowDown\")) {\n e.preventDefault();\n const direction = e.key === \"ArrowUp\" ? -1 : 1;\n const caret = ta.selectionStart;\n const linesArr = value.split(\"\\n\");\n let acc = 0;\n let lineIdx = 0;\n let lineStart = 0;\n for (let i = 0; i < linesArr.length; i++) {\n const lineLen = linesArr[i].length;\n if (caret <= acc + lineLen) {\n lineIdx = i;\n lineStart = acc;\n break;\n }\n acc += lineLen + 1;\n lineIdx = i;\n lineStart = acc;\n }\n const target = lineIdx + direction;\n if (target < 0 || target >= linesArr.length) return;\n const swap = linesArr[lineIdx];\n linesArr[lineIdx] = linesArr[target];\n linesArr[target] = swap;\n const next = linesArr.join(\"\\n\");\n onChange?.(next);\n let newStart = 0;\n for (let i = 0; i < target; i++) newStart += linesArr[i].length + 1;\n const col = caret - lineStart;\n setCaret(newStart + Math.min(col, linesArr[target].length));\n return;\n }\n\n // Tab → spaces (or indent block when multi-line selection)\n if (e.key === \"Tab\") {\n e.preventDefault();\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n if (start !== end && value.slice(start, end).includes(\"\\n\")) {\n const firstStart = lineBounds(value, start).lineStart;\n const lastEnd = lineBounds(value, end).lineEnd;\n const block = value.slice(firstStart, lastEnd);\n let updated: string;\n if (e.shiftKey) {\n updated = block\n .split(\"\\n\")\n .map((l) => l.replace(new RegExp(`^ {1,${tabSize}}`), \"\"))\n .join(\"\\n\");\n } else {\n const pad = \" \".repeat(tabSize);\n updated = block\n .split(\"\\n\")\n .map((l) => `${pad}${l}`)\n .join(\"\\n\");\n }\n const next = value.slice(0, firstStart) + updated + value.slice(lastEnd);\n onChange?.(next);\n setCaret(firstStart, firstStart + updated.length);\n return;\n }\n const spaces = \" \".repeat(tabSize);\n replaceRange(start, end, spaces);\n return;\n }\n\n // Enter → auto-indent (+ expanded block when between auto-pair)\n if (e.key === \"Enter\") {\n const start = ta.selectionStart;\n const before = value[start - 1];\n const after = value[start];\n const upTo = value.slice(0, start);\n const currentLine = upTo.split(\"\\n\").pop() ?? \"\";\n const indent = currentLine.match(/^\\s*/)?.[0] ?? \"\";\n\n if (autoPair && before && after && OPEN_PAIRS[before] === after) {\n e.preventDefault();\n const inner = `\\n${indent}${\" \".repeat(tabSize)}\\n${indent}`;\n const next = value.slice(0, start) + inner + value.slice(ta.selectionEnd);\n onChange?.(next);\n setCaret(start + 1 + indent.length + tabSize);\n return;\n }\n\n if (indent.length > 0) {\n e.preventDefault();\n const next = value.slice(0, start) + \"\\n\" + indent + value.slice(ta.selectionEnd);\n onChange?.(next);\n setCaret(start + 1 + indent.length);\n return;\n }\n }\n\n // Auto-pair: opening bracket/quote\n if (autoPair && !e.metaKey && !e.ctrlKey && !e.altKey && OPEN_PAIRS[e.key]) {\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n if (start !== end) {\n e.preventDefault();\n const selected = value.slice(start, end);\n const wrapped = `${e.key}${selected}${OPEN_PAIRS[e.key]}`;\n replaceRange(start, end, wrapped, end + 2);\n return;\n }\n const nextChar = value[start];\n // Skip pairing if we'd just stack identical quotes\n if ((e.key === '\"' || e.key === \"'\" || e.key === \"`\") && nextChar === e.key) {\n e.preventDefault();\n setCaret(start + 1);\n return;\n }\n e.preventDefault();\n const insert = `${e.key}${OPEN_PAIRS[e.key]}`;\n const next = value.slice(0, start) + insert + value.slice(start);\n onChange?.(next);\n setCaret(start + 1);\n return;\n }\n\n // Auto-skip closing bracket when next char already matches\n if (autoPair && CLOSE_PAIRS.has(e.key)) {\n const start = ta.selectionStart;\n if (start === ta.selectionEnd && value[start] === e.key) {\n e.preventDefault();\n setCaret(start + 1);\n return;\n }\n }\n\n // Backspace inside an empty pair → delete both\n if (autoPair && e.key === \"Backspace\") {\n const start = ta.selectionStart;\n if (start === ta.selectionEnd && start > 0) {\n const left = value[start - 1];\n const right = value[start];\n if (left && right && OPEN_PAIRS[left] === right) {\n e.preventDefault();\n const next = value.slice(0, start - 1) + value.slice(start + 1);\n onChange?.(next);\n setCaret(start - 1);\n return;\n }\n }\n }\n };\n\n const doFindNext = (dir: 1 | -1 = 1) => {\n if (matches.length === 0) return;\n const next = (findIndex + dir + matches.length) % matches.length;\n setFindIndex(next);\n const m = matches[next];\n setCaret(m.start, m.end);\n requestAnimationFrame(() => taRef.current?.focus());\n };\n\n const handleCopy = async () => {\n if (typeof navigator === \"undefined\") return;\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n } catch {\n /* ignore */\n }\n };\n\n const handleFormat = () => {\n const formatted = tryFormat(value, language);\n if (formatted) onChange?.(formatted);\n };\n\n const showFormatBtn = (showFormat ?? language === \"json\") && !readOnly;\n const showWrapToggle = showWordWrapToggle && wordWrapProp === undefined;\n\n return (\n <div\n className={cn(\n \"ods-code-editor\",\n `ods-code-editor--${language}`,\n readOnly && \"ods-code-editor--readonly\",\n wordWrap && \"ods-code-editor--wrap\",\n className,\n )}\n >\n <div className=\"ods-code-editor__toolbar\">\n <div className=\"ods-code-editor__toolbar-left\">\n <span className=\"ods-code-editor__lang\">{language.toUpperCase()}</span>\n {toolbar}\n </div>\n <div className=\"ods-code-editor__toolbar-right\">\n <span className=\"ods-code-editor__lines\">\n {lineCount} line{lineCount === 1 ? \"\" : \"s\"}\n </span>\n {status && <span className=\"ods-code-editor__status\">{status}</span>}\n {showWrapToggle && (\n <button\n type=\"button\"\n className={cn(\"ods-code-editor__btn\", wordWrap && \"ods-code-editor__btn--active\")}\n onClick={() => setInternalWrap((w) => !w)}\n aria-pressed={wordWrap}\n aria-label=\"Toggle word wrap\"\n title=\"Word wrap\"\n >\n <TextWrapIcon aria-hidden=\"true\" />\n </button>\n )}\n {showFormatBtn && (\n <button\n type=\"button\"\n className=\"ods-code-editor__btn\"\n onClick={handleFormat}\n aria-label=\"Format\"\n title=\"Format (JSON)\"\n >\n <MagicWandIcon aria-hidden=\"true\" />\n </button>\n )}\n {showCopy && (\n <button\n type=\"button\"\n className={cn(\"ods-code-editor__btn\", copied && \"ods-code-editor__btn--success\")}\n onClick={handleCopy}\n aria-label=\"Copy\"\n title=\"Copy\"\n >\n {copied ? (\n <CheckmarkIcon aria-hidden=\"true\" />\n ) : (\n <CopyIcon aria-hidden=\"true\" />\n )}\n </button>\n )}\n </div>\n </div>\n\n {findOpen && (\n <div className=\"ods-code-editor__find\" role=\"search\">\n <SearchIcon aria-hidden=\"true\" />\n <input\n ref={findInputRef}\n className=\"ods-code-editor__find-input\"\n type=\"text\"\n placeholder=\"Find…\"\n value={findQuery}\n onChange={(e) => {\n setFindQuery(e.target.value);\n setFindIndex(0);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n doFindNext(e.shiftKey ? -1 : 1);\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n setFindOpen(false);\n taRef.current?.focus();\n }\n }}\n />\n <span className=\"ods-code-editor__find-count\">\n {matches.length > 0 ? `${findIndex + 1} of ${matches.length}` : \"0\"}\n </span>\n <button\n type=\"button\"\n className=\"ods-code-editor__btn\"\n onClick={() => doFindNext(-1)}\n aria-label=\"Previous match\"\n disabled={matches.length === 0}\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3 6.5 5 4.5l2 2\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n className=\"ods-code-editor__btn\"\n onClick={() => doFindNext(1)}\n aria-label=\"Next match\"\n disabled={matches.length === 0}\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3 3.5 5 5.5l2-2\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n className=\"ods-code-editor__btn\"\n onClick={() => {\n setFindOpen(false);\n taRef.current?.focus();\n }}\n aria-label=\"Close find\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"m3 3 4 4M7 3l-4 4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n )}\n\n <div className=\"ods-code-editor__body\" style={{ minHeight, maxHeight }}>\n {showLineNumbers && (\n <div ref={gutterRef} className=\"ods-code-editor__gutter\" aria-hidden=\"true\">\n {lines.map((_, i) => (\n <span\n key={i}\n className={cn(\n \"ods-code-editor__line-no\",\n highlightActiveLine && activeLine === i + 1 && \"ods-code-editor__line-no--active\",\n )}\n >\n {i + 1}\n </span>\n ))}\n </div>\n )}\n <textarea\n ref={taRef}\n id={id}\n name={name}\n form={form}\n required={required}\n className=\"ods-code-editor__textarea\"\n value={value}\n onChange={(e) => onChange?.(e.target.value)}\n onKeyDown={handleKeyDown}\n onKeyUp={updateSelection}\n onClick={updateSelection}\n onSelect={updateSelection}\n placeholder={placeholder}\n readOnly={readOnly}\n spellCheck={false}\n aria-label={ariaLabel}\n aria-required={required || undefined}\n wrap={wordWrap ? \"soft\" : \"off\"}\n />\n </div>\n\n {showCounter && (\n <div className=\"ods-code-editor__footer\">\n <span className=\"ods-code-editor__pos\">\n Ln {activeLine}\n {selectionLen > 0 && (\n <>\n {\" \"}\n · {selectionLen} char{selectionLen === 1 ? \"\" : \"s\"}\n {selectionLines > 1 && ` · ${selectionLines} lines`}\n </>\n )}\n </span>\n <span className=\"ods-code-editor__shortcut-hint\">\n <kbd className=\"ods-code-editor__kbd\">⌘/</kbd> comment\n <span className=\"ods-code-editor__sep\">·</span>\n <kbd className=\"ods-code-editor__kbd\">⌘D</kbd> duplicate\n <span className=\"ods-code-editor__sep\">·</span>\n <kbd className=\"ods-code-editor__kbd\">⌥↑↓</kbd> move\n {searchable && (\n <>\n <span className=\"ods-code-editor__sep\">·</span>\n <kbd className=\"ods-code-editor__kbd\">⌘F</kbd> find\n </>\n )}\n </span>\n </div>\n )}\n </div>\n );\n },\n);\n\nCodeEditor.displayName = \"CodeEditor\";\n","\"use client\";\nimport { ChevronDownIcon } from \"@octaviaflow/icons\";\nimport {\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface ComboboxOption {\n value: string;\n label: string;\n /** Secondary line under the label (e.g. the underlying token/expression). */\n description?: string;\n /** Optional leading glyph. */\n icon?: ReactNode;\n disabled?: boolean;\n}\n\nexport interface ComboboxProps {\n /** Current text value. Free text is always allowed — options are suggestions. */\n value: string;\n onChange: (value: string) => void;\n options: ComboboxOption[];\n placeholder?: string;\n /** Accessible name when no visible `label` is rendered. */\n ariaLabel?: string;\n /** Optional visible label rendered above the field. */\n label?: ReactNode;\n helperText?: ReactNode;\n size?: \"sm\" | \"md\" | \"lg\";\n disabled?: boolean;\n /** Shows a loading row in the panel instead of options (async option fetch). */\n loading?: boolean;\n error?: boolean;\n errorMessage?: ReactNode;\n /**\n * When true, a typed value that isn't an exact option match surfaces a\n * leading \"Use «value»\" row so users see free entry is allowed. Free typing\n * works regardless; this is purely an affordance.\n */\n creatable?: boolean;\n /** Message shown when no options match the typed text. */\n emptyMessage?: ReactNode;\n /** Override the default substring match. Receives the option and typed query. */\n filter?: (option: ComboboxOption, query: string) => boolean;\n id?: string;\n name?: string;\n required?: boolean;\n className?: string;\n onBlur?: () => void;\n}\n\nconst defaultFilter = (option: ComboboxOption, query: string) => {\n const q = query.trim().toLowerCase();\n return (\n option.label.toLowerCase().includes(q) || option.value.toLowerCase().includes(q)\n );\n};\n\n/**\n * Editable combobox: a free-text input with an attached dropdown button. The\n * button (or ArrowDown) reveals the option list; picking an option fills the\n * input, and the user can also type any value not in the list. Options filter\n * by the typed text. The panel is portal-positioned so it escapes parent\n * `overflow: hidden` clipping (side panels, drawers, scrollable sections).\n *\n * Free-type-OR-pick is the core behaviour — use it wherever a field accepts\n * both known values and arbitrary input (dynamic tokens, custom identifiers).\n */\nexport function Combobox({\n value,\n onChange,\n options,\n placeholder = \"Select or type…\",\n ariaLabel,\n label,\n helperText,\n size = \"md\",\n disabled = false,\n loading = false,\n error = false,\n errorMessage,\n creatable = false,\n emptyMessage = \"Type a custom value\",\n filter = defaultFilter,\n id,\n name,\n required,\n className,\n onBlur,\n}: ComboboxProps) {\n const [open, setOpen] = useState(false);\n const [activeIdx, setActiveIdx] = useState(0);\n const wrapRef = useRef<HTMLDivElement>(null);\n const fieldRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const reactId = useId();\n const inputId = id ?? `${reactId}-combobox`;\n const listboxId = `${reactId}-listbox`;\n const errorId = `${reactId}-err`;\n const helperId = `${reactId}-help`;\n\n const [panelPos, setPanelPos] = useState<{ top: number; left: number; width: number } | null>(\n null,\n );\n const updatePanelPos = useCallback(() => {\n if (!fieldRef.current) return;\n const r = fieldRef.current.getBoundingClientRect();\n setPanelPos({ top: r.bottom + 4, left: r.left, width: r.width });\n }, []);\n useLayoutEffect(() => {\n if (!open) return;\n updatePanelPos();\n window.addEventListener(\"scroll\", updatePanelPos, true);\n window.addEventListener(\"resize\", updatePanelPos);\n return () => {\n window.removeEventListener(\"scroll\", updatePanelPos, true);\n window.removeEventListener(\"resize\", updatePanelPos);\n };\n }, [open, updatePanelPos]);\n\n // When the value exactly matches a known option (i.e. a committed selection)\n // or is empty, show ALL options so reopening reveals the full list. Only when\n // the text diverges from any option do we treat it as a search query.\n const isExactMatch = useMemo(\n () => value !== \"\" && options.some((o) => o.value === value),\n [options, value],\n );\n const filtered = useMemo(() => {\n if (!value.trim() || isExactMatch) return options;\n return options.filter((o) => filter(o, value));\n }, [options, value, isExactMatch, filter]);\n\n // The optional \"Use «typed»\" creatable row precedes the filtered options.\n const showCreate = creatable && value.trim() !== \"\" && !isExactMatch;\n const rowCount = filtered.length + (showCreate ? 1 : 0);\n\n useEffect(() => {\n setActiveIdx(0);\n }, [value, open]);\n\n // Click outside closes.\n useEffect(() => {\n if (!open) return;\n const onDoc = (e: MouseEvent) => {\n const t = e.target as Node;\n if (!wrapRef.current?.contains(t) && !panelRef.current?.contains(t)) setOpen(false);\n };\n document.addEventListener(\"mousedown\", onDoc);\n return () => document.removeEventListener(\"mousedown\", onDoc);\n }, [open]);\n\n const commit = (v: string) => {\n onChange(v);\n setOpen(false);\n inputRef.current?.focus();\n };\n\n // ArrowDown/Up navigate the visible rows (create row is index 0 when present);\n // Enter commits the active row; Escape closes.\n const activeValueAt = (idx: number): string | undefined => {\n if (showCreate && idx === 0) return value;\n const optIdx = showCreate ? idx - 1 : idx;\n return filtered[optIdx]?.value;\n };\n\n const handleKey = (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return;\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n if (!open) {\n setOpen(true);\n return;\n }\n setActiveIdx((i) => Math.min(i + 1, Math.max(rowCount - 1, 0)));\n } else if (e.key === \"ArrowUp\") {\n if (!open) return;\n e.preventDefault();\n setActiveIdx((i) => Math.max(i - 1, 0));\n } else if (e.key === \"Enter\") {\n if (open && rowCount > 0) {\n const v = activeValueAt(activeIdx);\n if (v !== undefined) {\n e.preventDefault();\n commit(v);\n }\n }\n } else if (e.key === \"Escape\") {\n if (open) {\n e.preventDefault();\n setOpen(false);\n }\n }\n };\n\n const describedBy = error && errorMessage ? errorId : helperText ? helperId : undefined;\n const activeDescendant = open && rowCount > 0 ? `${listboxId}-opt-${activeIdx}` : undefined;\n\n return (\n <div\n ref={wrapRef}\n className={cn(\n \"ods-combobox\",\n `ods-combobox--${size}`,\n error && \"ods-combobox--error\",\n disabled && \"ods-combobox--disabled\",\n className,\n )}\n onBlur={(e) => {\n // Fire consumer onBlur only when focus leaves the whole widget.\n if (!wrapRef.current?.contains(e.relatedTarget as Node)) onBlur?.();\n }}\n >\n {label && (\n <label htmlFor={inputId} className=\"ods-combobox__label\">\n {label}\n {required && (\n <span className=\"ods-combobox__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n <div ref={fieldRef} className=\"ods-combobox__field\">\n <input\n ref={inputRef}\n id={inputId}\n name={name}\n type=\"text\"\n className=\"ods-combobox__input\"\n value={value}\n disabled={disabled}\n required={required}\n placeholder={placeholder}\n onChange={(e) => {\n onChange(e.target.value);\n if (!open) setOpen(true);\n }}\n onKeyDown={handleKey}\n onFocus={() => !disabled && setOpen(true)}\n role=\"combobox\"\n aria-expanded={open}\n aria-controls={open ? listboxId : undefined}\n aria-activedescendant={activeDescendant}\n aria-autocomplete=\"list\"\n aria-label={!label ? ariaLabel : undefined}\n aria-invalid={error || undefined}\n aria-required={required || undefined}\n aria-describedby={describedBy}\n />\n <button\n type=\"button\"\n className={cn(\"ods-combobox__toggle\", open && \"ods-combobox__toggle--open\")}\n onClick={() => {\n if (disabled) return;\n setOpen((o) => !o);\n inputRef.current?.focus();\n }}\n aria-label={`${ariaLabel ?? \"Options\"}`}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n disabled={disabled}\n tabIndex={-1}\n >\n <ChevronDownIcon aria-hidden=\"true\" className=\"ods-combobox__chev\" />\n </button>\n </div>\n\n {open && panelPos && typeof document !== \"undefined\" &&\n createPortal(\n <div\n ref={panelRef}\n className=\"ods-combobox__panel\"\n role=\"presentation\"\n style={{\n position: \"fixed\",\n top: panelPos.top,\n left: panelPos.left,\n minWidth: panelPos.width,\n }}\n >\n {loading ? (\n <div className=\"ods-combobox__status\" role=\"status\">\n <span className=\"ods-combobox__spinner\" aria-hidden=\"true\" />\n Loading…\n </div>\n ) : (\n <ul id={listboxId} role=\"listbox\" aria-label={ariaLabel} className=\"ods-combobox__list\">\n {showCreate && (\n <li>\n <button\n type=\"button\"\n id={`${listboxId}-opt-0`}\n role=\"option\"\n aria-selected={false}\n className={cn(\n \"ods-combobox__opt ods-combobox__opt--create\",\n activeIdx === 0 && \"ods-combobox__opt--active\",\n )}\n onClick={() => commit(value)}\n onMouseEnter={() => setActiveIdx(0)}\n >\n Use “<strong>{value}</strong>”\n </button>\n </li>\n )}\n {filtered.length === 0 && !showCreate && (\n <li className=\"ods-combobox__empty\">{emptyMessage}</li>\n )}\n {filtered.map((opt, i) => {\n const idx = showCreate ? i + 1 : i;\n return (\n <li key={opt.value}>\n <button\n type=\"button\"\n id={`${listboxId}-opt-${idx}`}\n role=\"option\"\n aria-selected={opt.value === value}\n disabled={opt.disabled}\n className={cn(\n \"ods-combobox__opt\",\n opt.value === value && \"ods-combobox__opt--selected\",\n idx === activeIdx && \"ods-combobox__opt--active\",\n opt.disabled && \"ods-combobox__opt--disabled\",\n )}\n onClick={() => !opt.disabled && commit(opt.value)}\n onMouseEnter={() => setActiveIdx(idx)}\n >\n {opt.icon && (\n <span className=\"ods-combobox__opt-icon\" aria-hidden=\"true\">\n {opt.icon}\n </span>\n )}\n <span className=\"ods-combobox__opt-body\">\n <span className=\"ods-combobox__opt-text\">{opt.label}</span>\n {opt.description && (\n <span className=\"ods-combobox__opt-desc\">{opt.description}</span>\n )}\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </div>,\n document.body,\n )}\n\n {error && errorMessage && (\n <div id={errorId} className=\"ods-combobox__error-message\" role=\"alert\">\n {errorMessage}\n </div>\n )}\n {!error && helperText && (\n <div id={helperId} className=\"ods-combobox__helper\">\n {helperText}\n </div>\n )}\n </div>\n );\n}\n\nCombobox.displayName = \"Combobox\";\n","\"use client\";\nimport { ChevronRightIcon } from \"@octaviaflow/icons\";\nimport { type ReactNode, useId, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface DisclosureProps {\n /** Header text (the clickable toggle). */\n title: ReactNode;\n children: ReactNode;\n /** Optional secondary line under the title. */\n description?: ReactNode;\n /** Optional leading icon in the header. */\n icon?: ReactNode;\n /** Optional trailing slot in the header (e.g. a count Badge). */\n trailing?: ReactNode;\n /** Uncontrolled initial open state. Default false. */\n defaultOpen?: boolean;\n /** Controlled open state. When set, `onOpenChange` drives changes. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n size?: \"sm\" | \"md\";\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Disclosure — a single collapsible section toggled by a button header. Use for\n * \"Advanced options\" / \"Properties\" reveals where a full Accordion (grouped\n * multi-section) is overkill. Controlled or uncontrolled. Keyboard + ARIA\n * disclosure semantics (button `aria-expanded` + `aria-controls` → region).\n */\nexport function Disclosure({\n title,\n children,\n description,\n icon,\n trailing,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n size = \"md\",\n disabled = false,\n className,\n}: DisclosureProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);\n const isControlled = controlledOpen !== undefined;\n const open = isControlled ? controlledOpen : uncontrolledOpen;\n const reactId = useId();\n const regionId = `${reactId}-region`;\n\n const toggle = () => {\n if (disabled) return;\n const next = !open;\n if (!isControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n };\n\n return (\n <div\n className={cn(\n \"ods-disclosure\",\n `ods-disclosure--${size}`,\n open && \"ods-disclosure--open\",\n disabled && \"ods-disclosure--disabled\",\n className,\n )}\n >\n <button\n type=\"button\"\n className=\"ods-disclosure__trigger\"\n onClick={toggle}\n disabled={disabled}\n aria-expanded={open}\n aria-controls={regionId}\n >\n <ChevronRightIcon aria-hidden=\"true\" className=\"ods-disclosure__chev\" />\n {icon && (\n <span className=\"ods-disclosure__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"ods-disclosure__head\">\n <span className=\"ods-disclosure__title\">{title}</span>\n {description && <span className=\"ods-disclosure__desc\">{description}</span>}\n </span>\n {trailing && <span className=\"ods-disclosure__trailing\">{trailing}</span>}\n </button>\n {open && (\n <div id={regionId} role=\"region\" className=\"ods-disclosure__content\">\n {children}\n </div>\n )}\n </div>\n );\n}\n\nDisclosure.displayName = \"Disclosure\";\n","\"use client\";\nimport { CloseIcon } from \"@octaviaflow/icons\";\nimport {\n forwardRef,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n useId,\n useImperativeHandle,\n useRef,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\"> {\n type?:\n | \"text\"\n | \"email\"\n | \"password\"\n | \"search\"\n | \"number\"\n | \"tel\"\n | \"url\"\n | \"color\"\n | \"date\"\n | \"datetime-local\"\n | \"month\"\n | \"time\"\n | \"week\";\n size?: \"sm\" | \"md\" | \"lg\";\n error?: boolean;\n errorMessage?: string;\n label?: ReactNode;\n helperText?: ReactNode;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n /**\n * Show a clear button on the right while the input has a value.\n * Auto-enabled when `type=\"search\"`; explicitly toggle for other types.\n */\n clearable?: boolean;\n onClear?: () => void;\n /**\n * Right-side keyboard shortcut hint (e.g. \"⌘K\"). Rendered as a kbd-style chip.\n * Hidden while a clear button is showing (clear takes precedence).\n */\n shortcutHint?: ReactNode;\n}\n\nconst CLEAR_GLYPH = <CloseIcon width={12} height={12} aria-hidden=\"true\" />;\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n type = \"text\",\n size = \"md\",\n error = false,\n errorMessage,\n label,\n helperText,\n leftIcon,\n rightIcon,\n clearable,\n onClear,\n shortcutHint,\n disabled = false,\n required,\n id,\n className,\n value,\n defaultValue,\n onChange,\n onKeyDown,\n ...props\n },\n forwardedRef,\n ) => {\n const innerRef = useRef<HTMLInputElement>(null);\n useImperativeHandle(forwardedRef, () => innerRef.current as HTMLInputElement);\n\n const reactId = useId();\n const inputId = id ?? `${reactId}-input`;\n const errorId = `${reactId}-err`;\n const helperId = `${reactId}-help`;\n\n const isControlled = value !== undefined;\n const isClearable = (clearable ?? type === \"search\") && !disabled;\n const isSearch = type === \"search\";\n\n const currentValue = isControlled\n ? String(value ?? \"\")\n : (innerRef.current?.value ?? String(defaultValue ?? \"\"));\n const showClear = isClearable && currentValue.length > 0;\n\n const clearValue = () => {\n const el = innerRef.current;\n if (el && !isControlled) {\n const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, \"value\")?.set;\n setter?.call(el, \"\");\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n }\n onClear?.();\n el?.focus();\n };\n\n const handleClear = (e: MouseEvent<HTMLButtonElement>) => {\n e.preventDefault();\n e.stopPropagation();\n clearValue();\n };\n\n // Esc clears the value for search inputs — standard browser-search UX.\n // Consumer's own onKeyDown still runs first; preventDefault from theirs\n // short-circuits ours.\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (isClearable && isSearch && e.key === \"Escape\" && currentValue) {\n e.preventDefault();\n clearValue();\n }\n };\n\n const describedBy = error && errorMessage ? errorId : helperText ? helperId : undefined;\n\n return (\n <div\n className={cn(\n \"ods-input\",\n `ods-input--${size}`,\n error && \"ods-input--error\",\n disabled && \"ods-input--disabled\",\n isSearch && \"ods-input--search\",\n className,\n )}\n >\n {label && (\n <label htmlFor={inputId} className=\"ods-input__label\">\n {label}\n {required && (\n <span className=\"ods-input__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n <div className=\"ods-input__wrapper\">\n {leftIcon && (\n <span className=\"ods-input__icon--left\" aria-hidden=\"true\">\n {leftIcon}\n </span>\n )}\n <input\n {...props}\n id={inputId}\n ref={innerRef}\n type={type}\n disabled={disabled}\n required={required}\n value={value}\n defaultValue={defaultValue}\n onChange={onChange}\n onKeyDown={handleKeyDown}\n className={cn(\n \"ods-input__field\",\n leftIcon && \"ods-input__field--with-left-icon\",\n (rightIcon || showClear || shortcutHint) && \"ods-input__field--with-right-icon\",\n showClear && shortcutHint && \"ods-input__field--with-right-actions\",\n )}\n aria-invalid={error || undefined}\n aria-required={required || undefined}\n aria-describedby={describedBy}\n />\n <span className=\"ods-input__right\">\n {showClear && (\n <button\n type=\"button\"\n className=\"ods-input__clear\"\n onClick={handleClear}\n aria-label=\"Clear\"\n tabIndex={-1}\n >\n {CLEAR_GLYPH}\n </button>\n )}\n {shortcutHint && !showClear && (\n <span className=\"ods-input__kbd\" aria-hidden=\"true\">\n {shortcutHint}\n </span>\n )}\n {rightIcon && !showClear && !shortcutHint && (\n <span className=\"ods-input__icon--right\" aria-hidden=\"true\">\n {rightIcon}\n </span>\n )}\n </span>\n </div>\n {error && errorMessage && (\n <div id={errorId} className=\"ods-input__error-message\" role=\"alert\">\n {errorMessage}\n </div>\n )}\n {!error && helperText && (\n <div id={helperId} className=\"ods-input__helper\">\n {helperText}\n </div>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n","\"use client\";\nimport { CheckmarkIcon, ChevronRightIcon, CopyIcon } from \"@octaviaflow/icons\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { CodeEditor } from \"../CodeEditor\";\nimport { InlineMessage } from \"../InlineMessage\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/** Result reported through `onValidate` after each edit-mode keystroke. */\nexport interface JsonViewerValidationResult {\n /** True when the current editor text parses as valid JSON. */\n valid: boolean;\n /** Parse error details — only present when `valid` is false. */\n error?: {\n /** 1-indexed line number from the parser. */\n line: number;\n /** 1-indexed column number from the parser. */\n col: number;\n /** Human-readable error message from the JSON parser. */\n message: string;\n };\n}\n\nexport interface JsonViewerProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"title\" | \"onChange\"> {\n data: unknown;\n /**\n * `view` (default) — read-only collapsible tree view of `data`.\n * `edit` — switches to a CodeEditor primed with the JSON text of `data`.\n * In edit mode `onChange` fires on every keystroke with the raw text;\n * `onValidate` reports parse success/failure (Monaco's built-in JSON\n * language service also renders inline red squiggles).\n */\n mode?: \"view\" | \"edit\";\n /** Fires on every keystroke in `mode='edit'` with the raw editor text.\n * Always fires — even when the text is currently invalid JSON. */\n onChange?: (rawText: string) => void;\n /** Fires after each parse attempt in `mode='edit'`. Consumers gate the\n * save button on `result.valid`. */\n onValidate?: (result: JsonViewerValidationResult) => void;\n /** Initially expand to N levels deep (view mode only). Default 2. */\n defaultExpandDepth?: number;\n /** Show array indexes (view mode only). Default true. */\n showIndexes?: boolean;\n /** Show a copy button on hover for each leaf value (view mode only). */\n copyable?: boolean;\n /** Optional title. */\n title?: ReactNode;\n /** Optional status pill next to title. */\n status?: ReactNode;\n /** Limit each string value display length (view mode only). */\n truncateAt?: number;\n /** Fixed body height — number → pixels, string → any CSS length.\n * The inner tree scrolls vertically when content exceeds the bound. */\n height?: number | string;\n /** Upper bound on body height. Same shape as `height`; lets the body\n * grow up to the cap before scrolling kicks in. Ignored when `height`\n * is set (height takes precedence). */\n maxHeight?: number | string;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\n/**\n * JSON viewer with two modes:\n *\n * - `view` (default) — collapsible tree of `data` with type-tinted\n * values, mono font for keys, optional copy buttons on leaves.\n * - `edit` — CodeEditor primed with JSON-stringified `data`.\n * Monaco's built-in JSON language service renders inline parse-error\n * squiggles. Consumers wire `onChange` (raw text) + `onValidate`\n * (parse result) — typical pattern is `disabled={!isValid}` on a\n * save button driven by `onValidate`.\n */\nexport const JsonViewer = forwardRef<HTMLDivElement, JsonViewerProps>(\n function JsonViewer(\n {\n data,\n mode = \"view\",\n onChange,\n onValidate,\n defaultExpandDepth = 2,\n showIndexes = true,\n copyable = false,\n title,\n status,\n truncateAt = 200,\n height,\n maxHeight,\n className,\n ...rest\n },\n ref,\n ) {\n // Constrain the scrollable body. Numbers get the `px` unit; strings\n // pass through (so consumers can use vh / clamp() / etc.). `height`\n // is the hard size; `maxHeight` is the upper bound when content fits\n // naturally — either one switches the body to a real scroll surface.\n const bodyStyle: React.CSSProperties | undefined =\n height !== undefined\n ? { height: typeof height === \"number\" ? `${height}px` : height }\n : maxHeight !== undefined\n ? { maxHeight: typeof maxHeight === \"number\" ? `${maxHeight}px` : maxHeight }\n : undefined;\n\n return (\n <div {...rest} ref={ref} className={cn(\"ods-json-viewer\", className)} data-mode={mode}>\n {(title || status) && (\n <div className=\"ods-json-viewer__head\">\n {title && <span className=\"ods-json-viewer__title\">{title}</span>}\n {status && <span className=\"ods-json-viewer__status\">{status}</span>}\n </div>\n )}\n <div className=\"ods-json-viewer__body\" style={bodyStyle}>\n {mode === \"edit\" ? (\n <JsonEditBody data={data} onChange={onChange} onValidate={onValidate} />\n ) : (\n <JsonNode\n value={data}\n depth={0}\n defaultExpandDepth={defaultExpandDepth}\n showIndexes={showIndexes}\n copyable={copyable}\n truncateAt={truncateAt}\n />\n )}\n </div>\n </div>\n );\n },\n);\n\nJsonViewer.displayName = \"JsonViewer\";\n\n/* ---------------------------------------------------------------------------\n * Inner tree node — recursive\n * ------------------------------------------------------------------------- */\n\nfunction JsonNode({\n name,\n value,\n depth,\n defaultExpandDepth,\n showIndexes,\n copyable,\n truncateAt,\n isLast = true,\n}: {\n name?: string | number;\n value: unknown;\n depth: number;\n defaultExpandDepth: number;\n showIndexes: boolean;\n copyable: boolean;\n truncateAt: number;\n isLast?: boolean;\n}) {\n const [open, setOpen] = useState(depth < defaultExpandDepth);\n\n const isObject = value !== null && typeof value === \"object\" && !Array.isArray(value);\n const isArray = Array.isArray(value);\n const isContainer = isObject || isArray;\n\n const renderKey = useMemo(() => {\n if (name === undefined) return null;\n if (typeof name === \"number\") {\n return showIndexes ? (\n <span className=\"ods-json-viewer__key ods-json-viewer__key--index\">{name}</span>\n ) : null;\n }\n return <span className=\"ods-json-viewer__key\">{`\"${name}\"`}</span>;\n }, [name, showIndexes]);\n\n if (!isContainer) {\n return (\n <div className=\"ods-json-viewer__row\" style={{ paddingLeft: depth * 14 }}>\n <span className=\"ods-json-viewer__caret-spacer\" />\n {renderKey}\n {renderKey != null && <span className=\"ods-json-viewer__colon\">:</span>}\n <Leaf value={value} truncateAt={truncateAt} copyable={copyable} />\n {!isLast && <span className=\"ods-json-viewer__comma\">,</span>}\n </div>\n );\n }\n\n const entries = isArray\n ? (value as unknown[]).map((v, i) => [i, v] as const)\n : Object.entries(value as Record<string, unknown>);\n\n const openBracket = isArray ? \"[\" : \"{\";\n const closeBracket = isArray ? \"]\" : \"}\";\n\n return (\n <div>\n <div\n className=\"ods-json-viewer__row ods-json-viewer__row--container\"\n style={{ paddingLeft: depth * 14 }}\n onClick={() => setOpen((o) => !o)}\n >\n <button\n type=\"button\"\n className={cn(\"ods-json-viewer__caret\", open && \"ods-json-viewer__caret--open\")}\n aria-expanded={open}\n aria-label={open ? \"Collapse\" : \"Expand\"}\n onClick={(e) => {\n e.stopPropagation();\n setOpen((o) => !o);\n }}\n >\n <ChevronRightIcon aria-hidden=\"true\" />\n </button>\n {renderKey}\n {renderKey != null && <span className=\"ods-json-viewer__colon\">:</span>}\n <span className=\"ods-json-viewer__bracket\">{openBracket}</span>\n {!open && (\n <>\n <span className=\"ods-json-viewer__preview\">\n {isArray\n ? entries.length === 0\n ? \"\"\n : `${entries.length} item${entries.length === 1 ? \"\" : \"s\"}`\n : entries.length === 0\n ? \"\"\n : `${entries.length} key${entries.length === 1 ? \"\" : \"s\"}`}\n </span>\n <span className=\"ods-json-viewer__bracket\">{closeBracket}</span>\n </>\n )}\n {!isLast && !open && <span className=\"ods-json-viewer__comma\">,</span>}\n </div>\n {open && (\n <>\n {entries.map(([k, v], i) => (\n <JsonNode\n key={String(k)}\n name={isArray ? (k as number) : (k as string)}\n value={v}\n depth={depth + 1}\n defaultExpandDepth={defaultExpandDepth}\n showIndexes={showIndexes}\n copyable={copyable}\n truncateAt={truncateAt}\n isLast={i === entries.length - 1}\n />\n ))}\n <div\n className=\"ods-json-viewer__row ods-json-viewer__row--close\"\n style={{ paddingLeft: depth * 14 }}\n >\n <span className=\"ods-json-viewer__caret-spacer\" />\n <span className=\"ods-json-viewer__bracket\">{closeBracket}</span>\n {!isLast && <span className=\"ods-json-viewer__comma\">,</span>}\n </div>\n </>\n )}\n </div>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Leaf value — type-tinted span + optional copy button\n * ------------------------------------------------------------------------- */\n\nfunction Leaf({\n value,\n truncateAt,\n copyable,\n}: {\n value: unknown;\n truncateAt: number;\n copyable: boolean;\n}) {\n const [copied, setCopied] = useState(false);\n\n let display: string;\n let variant: \"string\" | \"number\" | \"boolean\" | \"null\";\n if (value === null) {\n display = \"null\";\n variant = \"null\";\n } else if (typeof value === \"string\") {\n const t = value.length > truncateAt ? `${value.slice(0, truncateAt)}…` : value;\n display = `\"${t}\"`;\n variant = \"string\";\n } else if (typeof value === \"number\") {\n display = String(value);\n variant = \"number\";\n } else if (typeof value === \"boolean\") {\n display = String(value);\n variant = \"boolean\";\n } else {\n display = String(value);\n variant = \"string\";\n }\n\n const handleCopy = async () => {\n if (!copyable || typeof navigator === \"undefined\") return;\n try {\n await navigator.clipboard.writeText(\n typeof value === \"string\" ? value : JSON.stringify(value),\n );\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n } catch {\n /* clipboard write rejected (older browser, permission policy) */\n }\n };\n\n return (\n <span className={cn(\"ods-json-viewer__value\", `ods-json-viewer__value--${variant}`)}>\n <span>{display}</span>\n {copyable && (\n <button\n type=\"button\"\n className={cn(\n \"ods-json-viewer__copy\",\n copied && \"ods-json-viewer__copy--success\",\n )}\n onClick={(e) => {\n e.stopPropagation();\n handleCopy();\n }}\n aria-label={copied ? \"Copied\" : \"Copy value\"}\n >\n {copied ? (\n <CheckmarkIcon width={10} height={10} aria-hidden=\"true\" />\n ) : (\n <CopyIcon width={10} height={10} aria-hidden=\"true\" />\n )}\n </button>\n )}\n </span>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Edit-mode body — CodeEditor + JSON parse validation\n * ------------------------------------------------------------------------- */\n\n/** Extract `line` / `col` from a native `SyntaxError` thrown by `JSON.parse`.\n * The browser-reported message format varies — we look for common shapes\n * (\"at position N\", \"line N column M\", \"JSON.parse: …line N column M\") and\n * fall back to deriving line/col from the position offset when the raw\n * text is available.\n *\n * Returns `{ line: 1, col: 1 }` when no position info is recoverable —\n * consumers always get a usable location to highlight. */\nfunction extractJsonErrorPosition(\n err: unknown,\n text: string,\n): { line: number; col: number; message: string } {\n const message = err instanceof Error ? err.message : String(err);\n\n // Pattern 1: \"JSON.parse: ... at line N column M ...\"\n // Pattern 2: \"Unexpected token X in JSON at position N\"\n // Pattern 3: \"Expected … in JSON at position N (line N column M)\"\n const lineColMatch = message.match(/line (\\d+) column (\\d+)/i);\n if (lineColMatch) {\n return {\n line: Number(lineColMatch[1]),\n col: Number(lineColMatch[2]),\n message,\n };\n }\n\n const posMatch = message.match(/position (\\d+)/i);\n if (posMatch) {\n const pos = Number(posMatch[1]);\n // Walk the text to convert absolute offset → (line, col).\n let line = 1;\n let col = 1;\n for (let i = 0; i < pos && i < text.length; i++) {\n if (text[i] === \"\\n\") {\n line++;\n col = 1;\n } else {\n col++;\n }\n }\n return { line, col, message };\n }\n\n return { line: 1, col: 1, message };\n}\n\ninterface JsonEditBodyProps {\n data: unknown;\n onChange?: (rawText: string) => void;\n onValidate?: (result: JsonViewerValidationResult) => void;\n}\n\n/** Edit-mode shell — JSON-stringifies `data` once on mount, then owns the\n * text state internally. Parsing happens on every keystroke so consumers\n * get fast validation feedback through `onValidate`. */\nfunction JsonEditBody({ data, onChange, onValidate }: JsonEditBodyProps) {\n // Initial serialization — pretty-printed with 2-space indent so it\n // matches the view-mode tree's visual rhythm. We initialize from `data`\n // once; the editor then becomes the source of truth (changes through\n // `data` prop after mount are ignored to avoid stomping the user's\n // edits mid-typing).\n const initial = useMemo(() => {\n try {\n return JSON.stringify(data, null, 2);\n } catch {\n // Circular refs / non-serializable values — fall back to an empty\n // object so the editor isn't broken.\n return \"{}\";\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const [text, setText] = useState(initial);\n const [parseError, setParseError] = useState<{\n line: number;\n col: number;\n message: string;\n } | null>(null);\n\n // Parse + reporting — extracted so the initial-mount effect and the\n // per-keystroke handler share identical behaviour.\n const validate = (next: string) => {\n try {\n JSON.parse(next);\n setParseError(null);\n onValidate?.({ valid: true });\n } catch (err) {\n const pos = extractJsonErrorPosition(err, next);\n setParseError(pos);\n onValidate?.({ valid: false, error: pos });\n }\n };\n\n const handleChange = (next: string) => {\n setText(next);\n onChange?.(next);\n validate(next);\n };\n\n // Initial validation report — consumers can disable their save button\n // from mount if the seed data happens to be invalid (rare but possible\n // when `data` was already a string of bad JSON).\n useEffect(() => {\n validate(initial);\n // Run once on mount to seed the consumer's validity flag.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div className=\"ods-json-viewer__edit\">\n {parseError && (\n <InlineMessage\n tone=\"danger\"\n size=\"sm\"\n className=\"ods-json-viewer__parse-error\"\n title={`Line ${parseError.line}, column ${parseError.col}`}\n >\n Line {parseError.line}, col {parseError.col} · {parseError.message}\n </InlineMessage>\n )}\n <CodeEditor\n value={text}\n onChange={handleChange}\n language=\"json\"\n ariaLabel=\"JSON editor\"\n showFormat\n showCopy\n />\n </div>\n );\n}\n","\"use client\";\nimport {\n CheckmarkFilledIcon,\n ErrorFilledIcon,\n InformationFilledIcon,\n WarningFilledIcon,\n} from \"@octaviaflow/icons\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * InlineMessage — small, lightweight status text.\n *\n * The middle-weight between a heavy `Banner` / `Callout` (page-level\n * card-like surface with title + description + actions) and a plain\n * `<span>` of muted text. Used for:\n *\n * - Form field validation (\"Required\", \"Min 8 characters\")\n * - DataTable cell errors (\"Failed to sync · retry?\")\n * - Inline status hints (\"Last saved 4 min ago\")\n * - Connector-row warnings (\"Lag exceeds SLA\")\n *\n * Renders as inline-flex text + optional leading icon. No padding,\n * no background, no border by default — it's text, not a card.\n *\n * A11y: `aria-live` is wired via the `live` prop. Default `\"off\"` for\n * static helper text; set `\"polite\"` for validation messages so screen\n * readers announce the change when the message replaces / appears.\n * ------------------------------------------------------------------------- */\n\nexport type InlineMessageTone = \"info\" | \"success\" | \"warning\" | \"danger\";\n\nexport type InlineMessageSize = \"sm\" | \"md\";\n\nexport interface InlineMessageProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /** Tone — drives text + icon color. Default `\"info\"`. */\n tone?: InlineMessageTone;\n /** Visual size. Default `\"md\"`. */\n size?: InlineMessageSize;\n /**\n * Leading icon. When omitted, a tone-appropriate filled icon is\n * used. Pass `false` to suppress the icon entirely (text-only).\n */\n icon?: ReactNode | false;\n /**\n * ARIA live-region politeness. Use `\"polite\"` for validation\n * messages, `\"assertive\"` for blocking errors. Default `\"off\"` —\n * static helper text that doesn't need to be announced.\n */\n live?: \"off\" | \"polite\" | \"assertive\";\n /** Message text. */\n children: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Tone → default icon\n * ------------------------------------------------------------------------- */\n\nconst TONE_ICON: Record<InlineMessageTone, React.ElementType> = {\n info: InformationFilledIcon,\n success: CheckmarkFilledIcon,\n warning: WarningFilledIcon,\n danger: ErrorFilledIcon,\n};\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const InlineMessage = forwardRef<HTMLDivElement, InlineMessageProps>(\n function InlineMessage(\n {\n tone = \"info\",\n size = \"md\",\n icon,\n live = \"off\",\n className,\n children,\n ...rest\n },\n ref,\n ) {\n const DefaultIcon = TONE_ICON[tone];\n const renderIcon = icon === false ? null : (icon ?? <DefaultIcon />);\n\n return (\n <div\n {...rest}\n ref={ref}\n className={cn(\n \"ods-inline-msg\",\n `ods-inline-msg--${tone}`,\n `ods-inline-msg--${size}`,\n className,\n )}\n // role + aria-live are paired so AT picks up the announcement\n // when the message appears / changes. When `live=\"off\"`,\n // neither attribute is set — the element reads as plain text.\n role={live !== \"off\" ? \"status\" : undefined}\n aria-live={live !== \"off\" ? live : undefined}\n >\n {renderIcon && (\n <span className=\"ods-inline-msg__icon\" aria-hidden=\"true\">\n {renderIcon}\n </span>\n )}\n <span className=\"ods-inline-msg__text\">{children}</span>\n </div>\n );\n },\n);\n\nInlineMessage.displayName = \"InlineMessage\";\n","\"use client\";\nimport { AddIcon, CloseIcon } from \"@octaviaflow/icons\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Checkbox } from \"../Checkbox\";\nimport { Combobox, type ComboboxOption } from \"../Combobox\";\n\nexport interface KeyValuePair {\n key: string;\n value: string;\n /** Per-row enable flag. Only meaningful when `rowToggle` is set; a missing\n * value is treated as enabled (backward-compatible). */\n enabled?: boolean;\n /** Optional per-row description. Only rendered when `showDescription` is set. */\n description?: string;\n}\n\nexport interface KeyValueEditorProps {\n pairs: KeyValuePair[];\n onChange: (pairs: KeyValuePair[]) => void;\n label?: ReactNode;\n helperText?: ReactNode;\n keyPlaceholder?: string;\n valuePlaceholder?: string;\n descriptionPlaceholder?: string;\n addLabel?: ReactNode;\n /** When set, the key field is a Combobox of these suggestions (free-type still allowed). */\n keyOptions?: ComboboxOption[];\n /** When set, the value field is a Combobox of these suggestions (free-type still allowed). */\n valueOptions?: ComboboxOption[];\n /** Render a per-row enable Checkbox; disabled rows dim and their fields go\n * read-only (the toggle + remove stay active). New rows default to enabled. */\n rowToggle?: boolean;\n /** Render a third description column per row. */\n showDescription?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n disabled?: boolean;\n error?: boolean;\n errorMessage?: ReactNode;\n /** Shown when there are no rows yet. */\n emptyLabel?: ReactNode;\n maxRows?: number;\n className?: string;\n}\n\n/** A row counts as enabled unless explicitly turned off (so legacy pairs with\n * no `enabled` field stay active). */\nconst isRowEnabled = (pair: KeyValuePair) => pair.enabled !== false;\n\n/**\n * KeyValueEditor — a list of key/value rows with add/remove. Drives field\n * defaults, request headers/params, and similar \"name → value\" maps. Either\n * field can become a Combobox (suggestions + free entry) by passing\n * `keyOptions` / `valueOptions`; otherwise both are plain text inputs.\n */\nexport function KeyValueEditor({\n pairs,\n onChange,\n label,\n helperText,\n keyPlaceholder = \"key\",\n valuePlaceholder = \"value\",\n descriptionPlaceholder = \"description\",\n addLabel = \"Add\",\n keyOptions,\n valueOptions,\n rowToggle = false,\n showDescription = false,\n size = \"md\",\n disabled = false,\n error = false,\n errorMessage,\n emptyLabel,\n maxRows,\n className,\n}: KeyValueEditorProps) {\n const setAt = (i: number, patch: Partial<KeyValuePair>) =>\n onChange(pairs.map((p, j) => (j === i ? { ...p, ...patch } : p)));\n const removeAt = (i: number) => onChange(pairs.filter((_, j) => j !== i));\n const add = () =>\n onChange([...pairs, { key: \"\", value: \"\", ...(rowToggle ? { enabled: true } : {}) }]);\n\n const canAdd = !disabled && (maxRows === undefined || pairs.length < maxRows);\n\n return (\n <div\n className={cn(\n \"ods-kv-editor\",\n `ods-kv-editor--${size}`,\n error && \"ods-kv-editor--error\",\n showDescription && \"ods-kv-editor--with-description\",\n className,\n )}\n >\n {label && <div className=\"ods-kv-editor__label\">{label}</div>}\n\n {pairs.length === 0 && emptyLabel && (\n <div className=\"ods-kv-editor__empty\">{emptyLabel}</div>\n )}\n\n {pairs.map((pair, i) => {\n // A row's fields are read-only when the editor is globally disabled OR\n // the row has been toggled off. The toggle + remove always stay active.\n const rowOff = rowToggle && !isRowEnabled(pair);\n const fieldsDisabled = disabled || rowOff;\n return (\n <div\n key={i}\n className={cn(\"ods-kv-editor__row\", rowOff && \"ods-kv-editor__row--disabled\")}\n >\n {rowToggle && (\n <Checkbox\n size={size === \"lg\" ? \"md\" : size}\n aria-label=\"Enable row\"\n checked={isRowEnabled(pair)}\n onChange={(on) => setAt(i, { enabled: on })}\n disabled={disabled}\n />\n )}\n {keyOptions ? (\n <Combobox\n ariaLabel=\"Key\"\n size={size}\n value={pair.key}\n options={keyOptions}\n onChange={(v) => setAt(i, { key: v })}\n placeholder={keyPlaceholder}\n disabled={fieldsDisabled}\n />\n ) : (\n <input\n className=\"ods-kv-editor__input\"\n aria-label=\"Key\"\n value={pair.key}\n onChange={(e) => setAt(i, { key: e.target.value })}\n placeholder={keyPlaceholder}\n disabled={fieldsDisabled}\n />\n )}\n {valueOptions ? (\n <Combobox\n ariaLabel=\"Value\"\n size={size}\n value={pair.value}\n options={valueOptions}\n onChange={(v) => setAt(i, { value: v })}\n placeholder={valuePlaceholder}\n disabled={fieldsDisabled}\n />\n ) : (\n <input\n className=\"ods-kv-editor__input\"\n aria-label=\"Value\"\n value={pair.value}\n onChange={(e) => setAt(i, { value: e.target.value })}\n placeholder={valuePlaceholder}\n disabled={fieldsDisabled}\n />\n )}\n {showDescription && (\n <input\n className=\"ods-kv-editor__input ods-kv-editor__input--description\"\n aria-label=\"Description\"\n value={pair.description ?? \"\"}\n onChange={(e) => setAt(i, { description: e.target.value })}\n placeholder={descriptionPlaceholder}\n disabled={fieldsDisabled}\n />\n )}\n <button\n type=\"button\"\n className=\"ods-kv-editor__remove\"\n aria-label=\"Remove row\"\n onClick={() => removeAt(i)}\n disabled={disabled}\n >\n <CloseIcon width={14} height={14} aria-hidden=\"true\" />\n </button>\n </div>\n );\n })}\n\n {canAdd && (\n <button type=\"button\" className=\"ods-kv-editor__add\" onClick={add}>\n <AddIcon width={14} height={14} aria-hidden=\"true\" />\n {addLabel}\n </button>\n )}\n\n {error && errorMessage && (\n <div className=\"ods-kv-editor__error-message\" role=\"alert\">\n {errorMessage}\n </div>\n )}\n {!error && helperText && <div className=\"ods-kv-editor__helper\">{helperText}</div>}\n </div>\n );\n}\n\nKeyValueEditor.displayName = \"KeyValueEditor\";\n","\"use client\";\nimport {\n type InputHTMLAttributes,\n type ReactNode,\n forwardRef,\n useId,\n useImperativeHandle,\n useRef,\n} from \"react\";\nimport { useCheckbox } from \"react-aria\";\nimport { useToggleState } from \"react-stately\";\nimport { resolveAccessibleName } from \"../../utils/a11y\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type CheckboxSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface CheckboxProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, \"onChange\" | \"size\"> {\n /** Controlled checked state. */\n checked?: boolean;\n /** Uncontrolled initial state. */\n defaultChecked?: boolean;\n /** Fires with the new selection state. */\n onChange?: (isSelected: boolean) => void;\n /** Mixed-state checkbox (for \"select all\" with partial children). */\n indeterminate?: boolean;\n disabled?: boolean;\n /** Visible label. Pair with `description` for \"label + helper text\" stacks. */\n label?: ReactNode;\n /** Optional helper text below the label. Linked via `aria-describedby` so\n * AT users hear the description after the label. */\n description?: ReactNode;\n /** Mark the field as invalid. Adds the error tint + `aria-invalid`. */\n error?: boolean;\n /** Error message rendered under the description. */\n errorMessage?: ReactNode;\n size?: CheckboxSize;\n className?: string;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(\n function Checkbox(\n {\n checked,\n defaultChecked,\n onChange,\n indeterminate = false,\n disabled = false,\n label,\n description,\n error = false,\n errorMessage,\n size = \"md\",\n required,\n className,\n ...props\n },\n forwardedRef,\n ) {\n const internalRef = useRef<HTMLInputElement>(null);\n useImperativeHandle(forwardedRef, () => internalRef.current as HTMLInputElement);\n\n const state = useToggleState({\n isSelected: checked,\n defaultSelected: defaultChecked,\n onChange,\n });\n\n // ─ Stable IDs for description / error message wiring ──────────────────\n const reactId = useId();\n const baseId = (props.id as string | undefined) ?? `ods-cb-${reactId}`;\n const descId = description ? `${baseId}-desc` : undefined;\n const errId = error && errorMessage ? `${baseId}-err` : undefined;\n const describedBy = [descId, errId].filter(Boolean).join(\" \") || undefined;\n\n // Resolve accessible name from {label, aria-label, aria-labelledby}.\n const ariaNameProps = resolveAccessibleName({\n label,\n ariaLabel: (props as any)[\"aria-label\"],\n ariaLabelledby: (props as any)[\"aria-labelledby\"],\n componentName: \"Checkbox\",\n });\n\n const { inputProps } = useCheckbox(\n {\n isSelected: state.isSelected,\n isIndeterminate: indeterminate,\n isDisabled: disabled,\n isRequired: required,\n isInvalid: error,\n onChange,\n // useCheckbox returns `name`/`value`/`form` in its `inputProps`. If\n // we let them fall through as `undefined`, the spread overwrites\n // the consumer's attrs. Pass them via the config so react-aria\n // emits real values.\n name: (props as { name?: string }).name,\n value: (props as { value?: string }).value,\n form: (props as { form?: string }).form,\n ...ariaNameProps,\n },\n state,\n internalRef,\n );\n\n const isChecked = state.isSelected;\n\n // React Aria owns the interactive event handlers. Strip those from the\n // caller's props so we don't double-bind, then let native form attrs\n // (name, value, form, required, autoFocus, etc.) flow to the DOM.\n const {\n onClick: _onClick,\n onKeyDown: _onKeyDown,\n onKeyUp: _onKeyUp,\n onFocus: _onFocus,\n onBlur: _onBlur,\n ...passthroughProps\n } = props as Record<string, unknown>;\n\n return (\n <label\n className={cn(\n \"ods-checkbox\",\n `ods-checkbox--${size}`,\n disabled && \"ods-checkbox--disabled\",\n error && \"ods-checkbox--error\",\n description && \"ods-checkbox--with-description\",\n className,\n )}\n >\n <input\n {...(passthroughProps as any)}\n {...inputProps}\n id={baseId}\n ref={internalRef}\n aria-describedby={describedBy}\n className=\"ods-checkbox__input\"\n />\n <span\n className={cn(\n \"ods-checkbox__box\",\n isChecked && !indeterminate && \"ods-checkbox__box--checked\",\n indeterminate && \"ods-checkbox__box--indeterminate\",\n )}\n aria-hidden=\"true\"\n >\n {indeterminate ? (\n <svg\n className=\"ods-checkbox__dash\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <line\n x1=\"2\"\n y1=\"6\"\n x2=\"10\"\n y2=\"6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n ) : (\n <svg\n className={cn(\n \"ods-checkbox__checkmark\",\n isChecked && \"ods-checkbox__checkmark--checked\",\n )}\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M2 6L5 9L10 3\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </span>\n {(label || description || errorMessage) && (\n <span className=\"ods-checkbox__text\">\n {label && (\n <span className=\"ods-checkbox__label\">\n {label}\n {required && (\n <span className=\"ods-checkbox__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n {description && (\n <span id={descId} className=\"ods-checkbox__description\">\n {description}\n </span>\n )}\n {error && errorMessage && (\n <span\n id={errId}\n className=\"ods-checkbox__error-message\"\n role=\"alert\"\n >\n {errorMessage}\n </span>\n )}\n </span>\n )}\n </label>\n );\n },\n);\n\nCheckbox.displayName = \"Checkbox\";\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport React, {SetStateAction, useCallback, useEffect, useReducer, useRef, useState} from 'react';\n\n// Use the earliest effect possible to reset the ref below.\nconst useEarlyEffect: typeof React.useLayoutEffect = typeof document !== 'undefined'\n ? React['useInsertionEffect'] ?? React.useLayoutEffect\n : () => {};\n\nexport function useControlledState<T, C = T>(value: Exclude<T, undefined>, defaultValue: Exclude<T, undefined> | undefined, onChange?: (v: C, ...args: any[]) => void): [T, (value: SetStateAction<T>, ...args: any[]) => void];\nexport function useControlledState<T, C = T>(value: Exclude<T, undefined> | undefined, defaultValue: Exclude<T, undefined>, onChange?: (v: C, ...args: any[]) => void): [T, (value: SetStateAction<T>, ...args: any[]) => void];\nexport function useControlledState<T, C = T>(value: T, defaultValue: T, onChange?: (v: C, ...args: any[]) => void): [T, (value: SetStateAction<T>, ...args: any[]) => void] {\n // Store the value in both state and a ref. The state value will only be used when uncontrolled.\n // The ref is used to track the most current value, which is passed to the function setState callback.\n let [stateValue, setStateValue] = useState(value || defaultValue);\n let valueRef = useRef(stateValue);\n\n let isControlledRef = useRef(value !== undefined);\n let isControlled = value !== undefined;\n useEffect(() => {\n let wasControlled = isControlledRef.current;\n if (wasControlled !== isControlled && process.env.NODE_ENV !== 'production') {\n console.warn(`WARN: A component changed from ${wasControlled ? 'controlled' : 'uncontrolled'} to ${isControlled ? 'controlled' : 'uncontrolled'}.`);\n }\n isControlledRef.current = isControlled;\n }, [isControlled]);\n\n // After each render, update the ref to the current value.\n // This ensures that the setState callback argument is reset.\n // Note: the effect should not have any dependencies so that controlled values always reset.\n let currentValue = isControlled ? value : stateValue;\n useEarlyEffect(() => {\n valueRef.current = currentValue;\n });\n\n let [, forceUpdate] = useReducer(() => ({}), {});\n let setValue = useCallback((value: SetStateAction<T>, ...args: any[]) => {\n // @ts-ignore - TS doesn't know that T cannot be a function.\n let newValue = typeof value === 'function' ? value(valueRef.current) : value;\n if (!Object.is(valueRef.current, newValue)) {\n // Update the ref so that the next setState callback has the most recent value.\n valueRef.current = newValue;\n\n setStateValue(newValue);\n\n // Always trigger a re-render, even when controlled, so that the layout effect above runs to reset the value.\n forceUpdate();\n\n // Trigger onChange. Note that if setState is called multiple times in a single event,\n // onChange will be called for each one instead of only once.\n onChange?.(newValue, ...args);\n }\n }, [onChange]);\n\n return [currentValue, setValue];\n}\n","/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Context, createContext, useContext, useEffect, useMemo, useRef, useState} from 'react';\nimport {Validation, ValidationErrors, ValidationFunction, ValidationResult} from '@react-types/shared';\n\nexport const VALID_VALIDITY_STATE: ValidityState = {\n badInput: false,\n customError: false,\n patternMismatch: false,\n rangeOverflow: false,\n rangeUnderflow: false,\n stepMismatch: false,\n tooLong: false,\n tooShort: false,\n typeMismatch: false,\n valueMissing: false,\n valid: true\n};\n\nconst CUSTOM_VALIDITY_STATE: ValidityState = {\n ...VALID_VALIDITY_STATE,\n customError: true,\n valid: false\n};\n\nexport const DEFAULT_VALIDATION_RESULT: ValidationResult = {\n isInvalid: false,\n validationDetails: VALID_VALIDITY_STATE,\n validationErrors: []\n};\n\nexport const FormValidationContext: Context<ValidationErrors> = createContext<ValidationErrors>({});\n\n// Private props that we pass from useFormValidationState to children.\n// Ideally we'd use a Symbol for this, but React doesn't support them: https://github.com/facebook/react/issues/7552\n// This needs to be stable across server and client module evaluation for SSR hydration.\nexport const privateValidationStateProp: string = '__reactAriaFormValidationState';\n\ninterface FormValidationProps<T> extends Validation<T> {\n builtinValidation?: ValidationResult,\n name?: string | string[],\n value: T | null\n}\n\nexport interface FormValidationState {\n /** Realtime validation results, updated as the user edits the value. */\n realtimeValidation: ValidationResult,\n /** Currently displayed validation results, updated when the user commits their changes. */\n displayValidation: ValidationResult,\n /** Updates the current validation result. Not displayed to the user until `commitValidation` is called. */\n updateValidation(result: ValidationResult): void,\n /** Resets the displayed validation state to valid when the user resets the form. */\n resetValidation(): void,\n /** Commits the realtime validation so it is displayed to the user. */\n commitValidation(): void\n}\n\nexport function useFormValidationState<T>(props: FormValidationProps<T>): FormValidationState {\n // Private prop for parent components to pass state to children.\n if (props[privateValidationStateProp]) {\n let {realtimeValidation, displayValidation, updateValidation, resetValidation, commitValidation} = props[privateValidationStateProp] as FormValidationState;\n return {realtimeValidation, displayValidation, updateValidation, resetValidation, commitValidation};\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useFormValidationStateImpl(props);\n}\n\nfunction useFormValidationStateImpl<T>(props: FormValidationProps<T>): FormValidationState {\n let {isInvalid, validationState, name, value, builtinValidation, validate, validationBehavior = 'aria'} = props;\n\n // backward compatibility.\n if (validationState) {\n isInvalid ||= validationState === 'invalid';\n }\n\n // If the isInvalid prop is controlled, update validation result in realtime.\n let controlledError: ValidationResult | null = isInvalid !== undefined ? {\n isInvalid,\n validationErrors: [],\n validationDetails: CUSTOM_VALIDITY_STATE\n } : null;\n\n // Perform custom client side validation.\n let clientError: ValidationResult | null = useMemo(() => {\n if (!validate || value == null) {\n return null;\n }\n let validateErrors = runValidate(validate, value);\n return getValidationResult(validateErrors);\n }, [validate, value]);\n\n if (builtinValidation?.validationDetails.valid) {\n builtinValidation = undefined;\n }\n\n // Get relevant server errors from the form.\n let serverErrors = useContext(FormValidationContext);\n let serverErrorMessages = useMemo(() => {\n if (name) {\n return Array.isArray(name) ? name.flatMap(name => asArray(serverErrors[name])) : asArray(serverErrors[name]);\n }\n return [];\n }, [serverErrors, name]);\n\n // Show server errors when the form gets a new value, and clear when the user changes the value.\n let [lastServerErrors, setLastServerErrors] = useState(serverErrors);\n let [isServerErrorCleared, setServerErrorCleared] = useState(false);\n if (serverErrors !== lastServerErrors) {\n setLastServerErrors(serverErrors);\n setServerErrorCleared(false);\n }\n\n let serverError: ValidationResult | null = useMemo(() =>\n getValidationResult(isServerErrorCleared ? [] : serverErrorMessages),\n [isServerErrorCleared, serverErrorMessages]\n );\n\n // Track the next validation state in a ref until commitValidation is called.\n let nextValidation = useRef(DEFAULT_VALIDATION_RESULT);\n let [currentValidity, setCurrentValidity] = useState(DEFAULT_VALIDATION_RESULT);\n\n let lastError = useRef(DEFAULT_VALIDATION_RESULT);\n let commitValidation = () => {\n if (!commitQueued) {\n return;\n }\n\n setCommitQueued(false);\n let error = clientError || builtinValidation || nextValidation.current;\n if (!isEqualValidation(error, lastError.current)) {\n lastError.current = error;\n setCurrentValidity(error);\n }\n };\n\n let [commitQueued, setCommitQueued] = useState(false);\n useEffect(commitValidation);\n\n // realtimeValidation is used to update the native input element's state based on custom validation logic.\n // displayValidation is the currently displayed validation state that the user sees (e.g. on input change/form submit).\n // With validationBehavior=\"aria\", all errors are displayed in realtime rather than on submit.\n let realtimeValidation = controlledError || serverError || clientError || builtinValidation || DEFAULT_VALIDATION_RESULT;\n let displayValidation = validationBehavior === 'native'\n ? controlledError || serverError || currentValidity\n : controlledError || serverError || clientError || builtinValidation || currentValidity;\n\n return {\n realtimeValidation,\n displayValidation,\n updateValidation(value) {\n // If validationBehavior is 'aria', update in realtime. Otherwise, store in a ref until commit.\n if (validationBehavior === 'aria' && !isEqualValidation(currentValidity, value)) {\n setCurrentValidity(value);\n } else {\n nextValidation.current = value;\n }\n },\n resetValidation() {\n // Update the currently displayed validation state to valid on form reset,\n // even if the native validity says it isn't. It'll show again on the next form submit.\n let error = DEFAULT_VALIDATION_RESULT;\n if (!isEqualValidation(error, lastError.current)) {\n lastError.current = error;\n setCurrentValidity(error);\n }\n\n // Do not commit validation after the next render. This avoids a condition where\n // useSelect calls commitValidation inside an onReset handler.\n if (validationBehavior === 'native') {\n setCommitQueued(false);\n }\n\n setServerErrorCleared(true);\n },\n commitValidation() {\n // Commit validation state so the user sees it on blur/change/submit. Also clear any server errors.\n // Wait until after the next render to commit so that the latest value has been validated.\n if (validationBehavior === 'native') {\n setCommitQueued(true);\n }\n setServerErrorCleared(true);\n }\n };\n}\n\nfunction asArray<T>(v: T | T[]): T[] {\n if (!v) {\n return [];\n }\n\n return Array.isArray(v) ? v : [v];\n}\n\nfunction runValidate<T>(validate: ValidationFunction<T>, value: T): string[] {\n if (typeof validate === 'function') {\n let e = validate(value);\n if (e && typeof e !== 'boolean') {\n return asArray(e);\n }\n }\n\n return [];\n}\n\nfunction getValidationResult(errors: string[]): ValidationResult | null {\n return errors.length ? {\n isInvalid: true,\n validationErrors: errors,\n validationDetails: CUSTOM_VALIDITY_STATE\n } : null;\n}\n\nfunction isEqualValidation(a: ValidationResult | null, b: ValidationResult | null): boolean {\n if (a === b) {\n return true;\n }\n\n return !!a && !!b\n && a.isInvalid === b.isInvalid\n && a.validationErrors.length === b.validationErrors.length\n && a.validationErrors.every((a, i) => a === b.validationErrors[i])\n && Object.entries(a.validationDetails).every(([k, v]) => b.validationDetails[k] === v);\n}\n\nexport function mergeValidation(...results: ValidationResult[]): ValidationResult {\n let errors = new Set<string>();\n let isInvalid = false;\n let validationDetails = {\n ...VALID_VALIDITY_STATE\n };\n\n for (let v of results) {\n for (let e of v.validationErrors) {\n errors.add(e);\n }\n\n // Only these properties apply for checkboxes.\n isInvalid ||= v.isInvalid;\n for (let key in validationDetails) {\n validationDetails[key] ||= v.validationDetails[key];\n }\n }\n\n validationDetails.valid = !isInvalid;\n return {\n isInvalid,\n validationErrors: [...errors],\n validationDetails\n };\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type {Collection, Node} from '@react-types/shared';\n\nexport function getChildNodes<T>(node: Node<T>, collection: Collection<Node<T>>): Iterable<Node<T>> {\n // New API: call collection.getChildren with the node key.\n if (typeof collection.getChildren === 'function') {\n return collection.getChildren(node.key);\n }\n\n // Old API: access childNodes directly.\n return node.childNodes;\n}\n\nexport function getFirstItem<T>(iterable: Iterable<T>): T | undefined {\n return getNthItem(iterable, 0);\n}\n\nexport function getNthItem<T>(iterable: Iterable<T>, index: number): T | undefined {\n if (index < 0) {\n return undefined;\n }\n\n let i = 0;\n for (let item of iterable) {\n if (i === index) {\n return item;\n }\n\n i++;\n }\n}\n\nexport function getLastItem<T>(iterable: Iterable<T>): T | undefined {\n let lastItem: T | undefined = undefined;\n for (let value of iterable) {\n lastItem = value;\n }\n\n return lastItem;\n}\n\nexport function compareNodeOrder<T>(collection: Collection<Node<T>>, a: Node<T>, b: Node<T>): number {\n // If the two nodes have the same parent, compare their indices.\n if (a.parentKey === b.parentKey) {\n return a.index - b.index;\n }\n\n // Otherwise, collect all of the ancestors from each node, and find the first one that doesn't match starting from the root.\n // Include the base nodes in case we are comparing nodes of different levels so that we can compare the higher node to the lower level node's\n // ancestor of the same level\n let aAncestors = [...getAncestors(collection, a), a];\n let bAncestors = [...getAncestors(collection, b), b];\n let firstNonMatchingAncestor = aAncestors.slice(0, bAncestors.length).findIndex((a, i) => a !== bAncestors[i]);\n if (firstNonMatchingAncestor !== -1) {\n // Compare the indices of two children within the common ancestor.\n a = aAncestors[firstNonMatchingAncestor];\n b = bAncestors[firstNonMatchingAncestor];\n return a.index - b.index;\n }\n\n // If there isn't a non matching ancestor, we might be in a case where one of the nodes is the ancestor of the other.\n if (aAncestors.findIndex(node => node === b) >= 0) {\n return 1;\n } else if (bAncestors.findIndex(node => node === a) >= 0) {\n return -1;\n }\n\n // 🤷\n return -1;\n}\n\nfunction getAncestors<T>(collection: Collection<Node<T>>, node: Node<T>): Node<T>[] {\n let parents: Node<T>[] = [];\n\n let currNode: Node<T> | null = node;\n while (currNode?.parentKey != null) {\n currNode = collection.getItem(currNode.parentKey);\n if (currNode) {\n parents.unshift(currNode);\n }\n }\n\n return parents;\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, Key, Node} from '@react-types/shared';\n\nexport class ListCollection<T> implements Collection<Node<T>> {\n private keyMap: Map<Key, Node<T>> = new Map();\n private iterable: Iterable<Node<T>>;\n private firstKey: Key | null = null;\n private lastKey: Key | null = null;\n private _size: number;\n\n constructor(nodes: Iterable<Node<T>>) {\n this.iterable = nodes;\n\n let visit = (node: Node<T>) => {\n this.keyMap.set(node.key, node);\n\n if (node.childNodes && node.type === 'section') {\n for (let child of node.childNodes) {\n visit(child);\n }\n }\n };\n\n for (let node of nodes) {\n visit(node);\n }\n\n let last: Node<T> | null = null;\n let index = 0;\n let size = 0;\n for (let [key, node] of this.keyMap) {\n if (last) {\n last.nextKey = key;\n node.prevKey = last.key;\n } else {\n this.firstKey = key;\n node.prevKey = undefined;\n }\n\n if (node.type === 'item') {\n node.index = index++;\n }\n\n // Only count sections and items when determining size so that\n // loaders and separators in RAC/S2 don't influence the emptyState determination\n if (node.type === 'section' || node.type === 'item') {\n size++;\n }\n\n last = node;\n\n // Set nextKey as undefined since this might be the last node\n // If it isn't the last node, last.nextKey will properly set at start of new loop\n last.nextKey = undefined;\n }\n this._size = size;\n this.lastKey = last?.key ?? null;\n }\n\n *[Symbol.iterator](): IterableIterator<Node<T>> {\n yield* this.iterable;\n }\n\n get size(): number {\n return this._size;\n }\n\n getKeys(): IterableIterator<Key> {\n return this.keyMap.keys();\n }\n\n getKeyBefore(key: Key): Key | null {\n let node = this.keyMap.get(key);\n return node ? node.prevKey ?? null : null;\n }\n\n getKeyAfter(key: Key): Key | null {\n let node = this.keyMap.get(key);\n return node ? node.nextKey ?? null : null;\n }\n\n getFirstKey(): Key | null {\n return this.firstKey;\n }\n\n getLastKey(): Key | null {\n return this.lastKey;\n }\n\n getItem(key: Key): Node<T> | null {\n return this.keyMap.get(key) ?? null;\n }\n\n at(idx: number): Node<T> | null {\n const keys = [...this.getKeys()];\n return this.getItem(keys[idx]);\n }\n\n getChildren(key: Key): Iterable<Node<T>> {\n let node = this.keyMap.get(key);\n return node?.childNodes || [];\n }\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Key} from '@react-types/shared';\n\n/**\n * A Selection is a special Set containing Keys, which also has an anchor\n * and current selected key for use when range selecting.\n */\nexport class Selection extends Set<Key> {\n anchorKey: Key | null;\n currentKey: Key | null;\n\n constructor(keys?: Iterable<Key> | Selection, anchorKey?: Key | null, currentKey?: Key | null) {\n super(keys);\n if (keys instanceof Selection) {\n this.anchorKey = anchorKey ?? keys.anchorKey;\n this.currentKey = currentKey ?? keys.currentKey;\n } else {\n this.anchorKey = anchorKey ?? null;\n this.currentKey = currentKey ?? null;\n }\n }\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DisabledBehavior, FocusStrategy, Key, MultipleSelection, SelectionBehavior, SelectionMode} from '@react-types/shared';\nimport {MultipleSelectionState} from './types';\nimport {Selection} from './Selection';\nimport {useControlledState} from '../utils/useControlledState';\nimport {useEffect, useMemo, useRef, useState} from 'react';\n\nfunction equalSets(setA, setB) {\n if (setA.size !== setB.size) {\n return false;\n }\n\n for (let item of setA) {\n if (!setB.has(item)) {\n return false;\n }\n }\n\n return true;\n}\n\nexport interface MultipleSelectionStateProps extends MultipleSelection {\n /**\n * How multiple selection should behave in the collection.\n * @default 'toggle'\n */\n selectionBehavior?: SelectionBehavior,\n /** Whether onSelectionChange should fire even if the new set of keys is the same as the last. */\n allowDuplicateSelectionEvents?: boolean,\n /**\n * Whether `disabledKeys` applies to all interactions, or only selection.\n * @default 'all'\n */\n disabledBehavior?: DisabledBehavior\n}\n\n/**\n * Manages state for multiple selection and focus in a collection.\n */\nexport function useMultipleSelectionState(props: MultipleSelectionStateProps): MultipleSelectionState {\n let {\n selectionMode = 'none' as SelectionMode,\n disallowEmptySelection = false,\n allowDuplicateSelectionEvents,\n selectionBehavior: selectionBehaviorProp = 'toggle',\n disabledBehavior = 'all'\n } = props;\n\n // We want synchronous updates to `isFocused` and `focusedKey` after their setters are called.\n // But we also need to trigger a react re-render. So, we have both a ref (sync) and state (async).\n let isFocusedRef = useRef(false);\n let [, setFocused] = useState(false);\n let focusedKeyRef = useRef<Key | null>(null);\n let childFocusStrategyRef = useRef<FocusStrategy | null>(null);\n let [, setFocusedKey] = useState<Key | null>(null);\n let selectedKeysProp = useMemo(() => convertSelection(props.selectedKeys), [props.selectedKeys]);\n let defaultSelectedKeys = useMemo(() => convertSelection(props.defaultSelectedKeys, new Selection()), [props.defaultSelectedKeys]);\n let [selectedKeys, setSelectedKeys] = useControlledState(\n selectedKeysProp,\n defaultSelectedKeys!,\n props.onSelectionChange\n );\n let disabledKeysProp = useMemo(() =>\n props.disabledKeys ? new Set(props.disabledKeys) : new Set<Key>()\n , [props.disabledKeys]);\n let [selectionBehavior, setSelectionBehavior] = useState(selectionBehaviorProp);\n\n // If the selectionBehavior prop is set to replace, but the current state is toggle (e.g. due to long press\n // to enter selection mode on touch), and the selection becomes empty, reset the selection behavior.\n if (selectionBehaviorProp === 'replace' && selectionBehavior === 'toggle' && typeof selectedKeys === 'object' && selectedKeys.size === 0) {\n setSelectionBehavior('replace');\n }\n\n // If the selectionBehavior prop changes, update the state as well.\n let lastSelectionBehavior = useRef(selectionBehaviorProp);\n useEffect(() => {\n if (selectionBehaviorProp !== lastSelectionBehavior.current) {\n setSelectionBehavior(selectionBehaviorProp);\n lastSelectionBehavior.current = selectionBehaviorProp;\n }\n }, [selectionBehaviorProp]);\n\n return {\n selectionMode,\n disallowEmptySelection,\n selectionBehavior,\n setSelectionBehavior,\n get isFocused() {\n return isFocusedRef.current;\n },\n setFocused(f) {\n isFocusedRef.current = f;\n setFocused(f);\n },\n get focusedKey() {\n return focusedKeyRef.current;\n },\n get childFocusStrategy() {\n return childFocusStrategyRef.current;\n },\n setFocusedKey(k, childFocusStrategy = 'first') {\n focusedKeyRef.current = k;\n childFocusStrategyRef.current = childFocusStrategy;\n setFocusedKey(k);\n },\n selectedKeys,\n setSelectedKeys(keys) {\n if (allowDuplicateSelectionEvents || !equalSets(keys, selectedKeys)) {\n setSelectedKeys(keys);\n }\n },\n disabledKeys: disabledKeysProp,\n disabledBehavior\n };\n}\n\nfunction convertSelection(selection: 'all' | Iterable<Key> | null | undefined, defaultValue?: Selection): 'all' | Set<Key> | undefined {\n if (!selection) {\n return defaultValue;\n }\n\n return selection === 'all'\n ? 'all'\n : new Selection(selection);\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n Collection, DisabledBehavior,\n FocusStrategy,\n Selection as ISelection,\n Key,\n LayoutDelegate,\n LongPressEvent,\n Node,\n PressEvent,\n SelectionBehavior,\n SelectionMode\n} from '@react-types/shared';\nimport {compareNodeOrder, getChildNodes, getFirstItem} from '../collections/getChildNodes';\nimport {MultipleSelectionManager, MultipleSelectionState} from './types';\nimport {Selection} from './Selection';\n\ninterface SelectionManagerOptions {\n allowsCellSelection?: boolean,\n layoutDelegate?: LayoutDelegate,\n fullCollection?: Collection<Node<unknown>>\n}\n\n/**\n * An interface for reading and updating multiple selection state.\n */\nexport class SelectionManager implements MultipleSelectionManager {\n collection: Collection<Node<unknown>>;\n private state: MultipleSelectionState;\n private allowsCellSelection: boolean;\n private _isSelectAll: boolean | null;\n private layoutDelegate: LayoutDelegate | null;\n private fullCollection: Collection<Node<unknown>> | null;\n\n constructor(collection: Collection<Node<unknown>>, state: MultipleSelectionState, options?: SelectionManagerOptions) {\n this.collection = collection;\n this.state = state;\n this.allowsCellSelection = options?.allowsCellSelection ?? false;\n this._isSelectAll = null;\n this.layoutDelegate = options?.layoutDelegate || null;\n this.fullCollection = options?.fullCollection || null;\n }\n\n /**\n * The type of selection that is allowed in the collection.\n */\n get selectionMode(): SelectionMode {\n return this.state.selectionMode;\n }\n\n /**\n * Whether the collection allows empty selection.\n */\n get disallowEmptySelection(): boolean {\n return this.state.disallowEmptySelection;\n }\n\n /**\n * The selection behavior for the collection.\n */\n get selectionBehavior(): SelectionBehavior {\n return this.state.selectionBehavior;\n }\n\n /**\n * Sets the selection behavior for the collection.\n */\n setSelectionBehavior(selectionBehavior: SelectionBehavior): void {\n this.state.setSelectionBehavior(selectionBehavior);\n }\n\n /**\n * Whether the collection is currently focused.\n */\n get isFocused(): boolean {\n return this.state.isFocused;\n }\n\n /**\n * Sets whether the collection is focused.\n */\n setFocused(isFocused: boolean): void {\n this.state.setFocused(isFocused);\n }\n\n /**\n * The current focused key in the collection.\n */\n get focusedKey(): Key | null {\n return this.state.focusedKey;\n }\n\n /** Whether the first or last child of the focused key should receive focus. */\n get childFocusStrategy(): FocusStrategy | null {\n return this.state.childFocusStrategy;\n }\n\n /**\n * Sets the focused key.\n */\n setFocusedKey(key: Key | null, childFocusStrategy?: FocusStrategy): void {\n if (key == null || this.collection.getItem(key)) {\n this.state.setFocusedKey(key, childFocusStrategy);\n }\n }\n\n /**\n * The currently selected keys in the collection.\n */\n get selectedKeys(): Set<Key> {\n return this.state.selectedKeys === 'all'\n ? new Set(this.getSelectAllKeys())\n : this.state.selectedKeys;\n }\n\n /**\n * The raw selection value for the collection.\n * Either 'all' for select all, or a set of keys.\n */\n get rawSelection(): ISelection {\n return this.state.selectedKeys;\n }\n\n /**\n * Returns whether a key is selected.\n */\n isSelected(key: Key): boolean {\n if (this.state.selectionMode === 'none') {\n return false;\n }\n\n let mappedKey = this.getKey(key);\n if (mappedKey == null) {\n return false;\n }\n return this.state.selectedKeys === 'all'\n ? this.canSelectItem(mappedKey)\n : this.state.selectedKeys.has(mappedKey);\n }\n\n /**\n * Whether the selection is empty.\n */\n get isEmpty(): boolean {\n return this.state.selectedKeys !== 'all' && this.state.selectedKeys.size === 0;\n }\n\n /**\n * Whether all items in the collection are selected.\n */\n get isSelectAll(): boolean {\n if (this.isEmpty) {\n return false;\n }\n\n if (this.state.selectedKeys === 'all') {\n return true;\n }\n\n if (this._isSelectAll != null) {\n return this._isSelectAll;\n }\n\n let allKeys = this.getSelectAllKeys();\n let selectedKeys = this.state.selectedKeys;\n this._isSelectAll = allKeys.every(k => selectedKeys.has(k));\n return this._isSelectAll;\n }\n\n get firstSelectedKey(): Key | null {\n let first: Node<unknown> | null = null;\n for (let key of this.state.selectedKeys) {\n let item = this.collection.getItem(key);\n if (!first || (item && compareNodeOrder(this.collection, item, first) < 0)) {\n first = item;\n }\n }\n\n return first?.key ?? null;\n }\n\n get lastSelectedKey(): Key | null {\n let last: Node<unknown> | null = null;\n for (let key of this.state.selectedKeys) {\n let item = this.collection.getItem(key);\n if (!last || (item && compareNodeOrder(this.collection, item, last) > 0)) {\n last = item;\n }\n }\n\n return last?.key ?? null;\n }\n\n get disabledKeys(): Set<Key> {\n return this.state.disabledKeys;\n }\n\n get disabledBehavior(): DisabledBehavior {\n return this.state.disabledBehavior;\n }\n\n /**\n * Extends the selection to the given key.\n */\n extendSelection(toKey: Key): void {\n if (this.selectionMode === 'none') {\n return;\n }\n\n if (this.selectionMode === 'single') {\n this.replaceSelection(toKey);\n return;\n }\n\n let mappedToKey = this.getKey(toKey);\n if (mappedToKey == null) {\n return;\n }\n\n let selection: Selection;\n\n // Only select the one key if coming from a select all.\n if (this.state.selectedKeys === 'all') {\n selection = new Selection([mappedToKey], mappedToKey, mappedToKey);\n } else {\n let selectedKeys = this.state.selectedKeys as Selection;\n let anchorKey = selectedKeys.anchorKey ?? mappedToKey;\n selection = new Selection(selectedKeys, anchorKey, mappedToKey);\n for (let key of this.getKeyRange(anchorKey, selectedKeys.currentKey ?? mappedToKey)) {\n selection.delete(key);\n }\n\n for (let key of this.getKeyRange(mappedToKey, anchorKey)) {\n if (this.canSelectItem(key)) {\n selection.add(key);\n }\n }\n }\n\n this.state.setSelectedKeys(selection);\n }\n\n private getKeyRange(from: Key, to: Key) {\n let fromItem = this.collection.getItem(from);\n let toItem = this.collection.getItem(to);\n if (fromItem && toItem) {\n if (compareNodeOrder(this.collection, fromItem, toItem) <= 0) {\n return this.getKeyRangeInternal(from, to);\n }\n\n return this.getKeyRangeInternal(to, from);\n }\n\n return [];\n }\n\n private getKeyRangeInternal(from: Key, to: Key) {\n if (this.layoutDelegate?.getKeyRange) {\n return this.layoutDelegate.getKeyRange(from, to);\n }\n\n let keys: Key[] = [];\n let key: Key | null = from;\n while (key != null) {\n let item = this.collection.getItem(key);\n if (item && (item.type === 'item' || (item.type === 'cell' && this.allowsCellSelection))) {\n keys.push(key);\n }\n\n if (key === to) {\n return keys;\n }\n\n key = this.collection.getKeyAfter(key);\n }\n\n return [];\n }\n\n private getKey(key: Key) {\n let item = this.collection.getItem(key);\n if (!item) {\n // ¯\\_(ツ)_/¯\n return key;\n }\n\n // If cell selection is allowed, just return the key.\n if (item.type === 'cell' && this.allowsCellSelection) {\n return key;\n }\n\n // Find a parent item to select\n while (item && item.type !== 'item' && item.parentKey != null) {\n item = this.collection.getItem(item.parentKey);\n }\n\n if (!item || item.type !== 'item') {\n return null;\n }\n\n return item.key;\n }\n\n /**\n * Toggles whether the given key is selected.\n */\n toggleSelection(key: Key): void {\n if (this.selectionMode === 'none') {\n return;\n }\n\n if (this.selectionMode === 'single' && !this.isSelected(key)) {\n this.replaceSelection(key);\n return;\n }\n\n let mappedKey = this.getKey(key);\n if (mappedKey == null) {\n return;\n }\n\n let keys = new Selection(this.state.selectedKeys === 'all' ? this.getSelectAllKeys() : this.state.selectedKeys);\n if (keys.has(mappedKey)) {\n keys.delete(mappedKey);\n // TODO: move anchor to last selected key...\n // Does `current` need to move here too?\n } else if (this.canSelectItem(mappedKey)) {\n keys.add(mappedKey);\n keys.anchorKey = mappedKey;\n keys.currentKey = mappedKey;\n }\n\n if (this.disallowEmptySelection && keys.size === 0) {\n return;\n }\n\n this.state.setSelectedKeys(keys);\n }\n\n /**\n * Replaces the selection with only the given key.\n */\n replaceSelection(key: Key): void {\n if (this.selectionMode === 'none') {\n return;\n }\n\n let mappedKey = this.getKey(key);\n if (mappedKey == null) {\n return;\n }\n\n let selection = this.canSelectItem(mappedKey)\n ? new Selection([mappedKey], mappedKey, mappedKey)\n : new Selection();\n\n this.state.setSelectedKeys(selection);\n }\n\n /**\n * Replaces the selection with the given keys.\n */\n setSelectedKeys(keys: Iterable<Key>): void {\n if (this.selectionMode === 'none') {\n return;\n }\n\n let selection = new Selection();\n for (let key of keys) {\n let mappedKey = this.getKey(key);\n if (mappedKey != null) {\n selection.add(mappedKey);\n if (this.selectionMode === 'single') {\n break;\n }\n }\n }\n\n this.state.setSelectedKeys(selection);\n }\n\n private getSelectAllKeys() {\n // Use the full (unfiltered) collection when available so that materializing\n // the 'all' selection includes items that are currently filtered out (e.g. by Autocomplete).\n let collection = this.fullCollection ?? this.collection;\n let keys: Key[] = [];\n let addKeys = (key: Key | null) => {\n while (key != null) {\n if (this.canSelectItemIn(key, collection)) {\n let item = collection.getItem(key);\n if (item?.type === 'item') {\n keys.push(key);\n }\n\n // Add child keys. If cell selection is allowed, then include item children too.\n if (item?.hasChildNodes && (this.allowsCellSelection || item.type !== 'item')) {\n addKeys(getFirstItem(getChildNodes(item, collection))?.key ?? null);\n }\n }\n\n key = collection.getKeyAfter(key);\n }\n };\n\n addKeys(collection.getFirstKey());\n return keys;\n }\n\n /**\n * Selects all items in the collection.\n */\n selectAll(): void {\n if (!this.isSelectAll && this.selectionMode === 'multiple') {\n this.state.setSelectedKeys('all');\n }\n }\n\n /**\n * Removes all keys from the selection.\n */\n clearSelection(): void {\n if (!this.disallowEmptySelection && (this.state.selectedKeys === 'all' || this.state.selectedKeys.size > 0)) {\n this.state.setSelectedKeys(new Selection());\n }\n }\n\n /**\n * Toggles between select all and an empty selection.\n */\n toggleSelectAll(): void {\n if (this.isSelectAll) {\n this.clearSelection();\n } else {\n this.selectAll();\n }\n }\n\n select(key: Key, e?: PressEvent | LongPressEvent | PointerEvent): void {\n if (this.selectionMode === 'none') {\n return;\n }\n\n if (this.selectionMode === 'single') {\n if (this.isSelected(key) && !this.disallowEmptySelection) {\n this.toggleSelection(key);\n } else {\n this.replaceSelection(key);\n }\n } else if (this.selectionBehavior === 'toggle' || (e && (e.pointerType === 'touch' || e.pointerType === 'virtual'))) {\n // if touch or virtual (VO) then we just want to toggle, otherwise it's impossible to multi select because they don't have modifier keys\n this.toggleSelection(key);\n } else {\n this.replaceSelection(key);\n }\n }\n\n /**\n * Returns whether the current selection is equal to the given selection.\n */\n isSelectionEqual(selection: Set<Key>): boolean {\n if (selection === this.state.selectedKeys) {\n return true;\n }\n\n // Check if the set of keys match.\n let selectedKeys = this.selectedKeys;\n if (selection.size !== selectedKeys.size) {\n return false;\n }\n\n for (let key of selection) {\n if (!selectedKeys.has(key)) {\n return false;\n }\n }\n\n for (let key of selectedKeys) {\n if (!selection.has(key)) {\n return false;\n }\n }\n\n return true;\n }\n\n canSelectItem(key: Key): boolean {\n return this.canSelectItemIn(key, this.collection);\n }\n\n private canSelectItemIn(key: Key, collection: Collection<Node<unknown>>): boolean {\n if (this.state.selectionMode === 'none' || this.state.disabledKeys.has(key)) {\n return false;\n }\n\n let item = collection.getItem(key);\n if (!item || item?.props?.isDisabled || (item.type === 'cell' && !this.allowsCellSelection)) {\n return false;\n }\n\n return true;\n }\n\n isDisabled(key: Key): boolean {\n return this.state.disabledBehavior === 'all' && (this.state.disabledKeys.has(key) || !!this.collection.getItem(key)?.props?.isDisabled);\n }\n\n isLink(key: Key): boolean {\n return !!this.collection.getItem(key)?.props?.href;\n }\n\n getItemProps(key: Key): any {\n return this.collection.getItem(key)?.props;\n }\n\n withCollection(collection: Collection<Node<unknown>>): SelectionManager {\n return new SelectionManager(collection, this.state, {\n allowsCellSelection: this.allowsCellSelection,\n layoutDelegate: this.layoutDelegate || undefined,\n fullCollection: this.fullCollection ?? this.collection\n });\n }\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {CollectionBase, CollectionElement, Key, Node} from '@react-types/shared';\nimport {PartialNode} from './types';\nimport React, {ReactElement} from 'react';\n\ninterface CollectionBuilderState {\n renderer?: (value: any) => ReactElement | null\n}\n\ninterface CollectReactElement<T> extends ReactElement {\n getCollectionNode(props: any, context: any): Generator<PartialNode<T>, void, Node<T>[]>\n}\n\nexport class CollectionBuilder<T extends object> {\n private context?: unknown;\n private cache: WeakMap<T, Node<T>> = new WeakMap();\n\n build(props: Partial<CollectionBase<T>>, context?: unknown): Iterable<Node<T>> {\n this.context = context;\n return iterable(() => this.iterateCollection(props));\n }\n\n private *iterateCollection(props: Partial<CollectionBase<T>>): Generator<Node<T>> {\n let {children, items} = props;\n\n if (React.isValidElement<{children: CollectionElement<T>}>(children) && children.type === React.Fragment) {\n yield* this.iterateCollection({\n children: children.props.children,\n items\n });\n } else if (typeof children === 'function') {\n if (!items) {\n throw new Error('props.children was a function but props.items is missing');\n }\n\n let index = 0;\n for (let item of items) {\n yield* this.getFullNode({\n value: item,\n index\n }, {renderer: children});\n index++;\n }\n } else {\n let items: CollectionElement<T>[] = [];\n React.Children.forEach(children, child => {\n if (child) {\n items.push(child);\n }\n });\n\n let index = 0;\n for (let item of items) {\n let nodes = this.getFullNode({\n element: item,\n index: index\n }, {});\n\n for (let node of nodes) {\n index++;\n yield node;\n }\n }\n }\n }\n\n private getKey(item: NonNullable<CollectionElement<T>>, partialNode: PartialNode<T>, state: CollectionBuilderState, parentKey?: Key | null): Key {\n if (item.key != null) {\n return item.key;\n }\n\n if (partialNode.type === 'cell' && partialNode.key != null) {\n return `${parentKey}${partialNode.key}`;\n }\n\n let v = partialNode.value as any;\n if (v != null) {\n let key = v.key ?? v.id;\n if (key == null) {\n throw new Error('No key found for item');\n }\n\n return key;\n }\n\n return parentKey ? `${parentKey}.${partialNode.index}` : `$.${partialNode.index}`;\n }\n\n private getChildState(state: CollectionBuilderState, partialNode: PartialNode<T>) {\n return {\n renderer: partialNode.renderer || state.renderer\n };\n }\n\n private *getFullNode(partialNode: PartialNode<T> & {index: number}, state: CollectionBuilderState, parentKey?: Key | null, parentNode?: Node<T>): Generator<Node<T>> {\n if (React.isValidElement<{children: CollectionElement<T>}>(partialNode.element) && partialNode.element.type === React.Fragment) {\n let children: CollectionElement<T>[] = [];\n\n React.Children.forEach(partialNode.element.props.children, child => {\n children.push(child);\n });\n\n let index = partialNode.index ?? 0;\n\n for (const child of children) {\n yield* this.getFullNode({\n element: child,\n index: index++\n }, state, parentKey, parentNode);\n }\n\n return;\n }\n\n // If there's a value instead of an element on the node, and a parent renderer function is available,\n // use it to render an element for the value.\n let element = partialNode.element;\n if (!element && partialNode.value && state && state.renderer) {\n let cached = this.cache.get(partialNode.value);\n if (cached && (!cached.shouldInvalidate || !cached.shouldInvalidate(this.context))) {\n cached.index = partialNode.index;\n cached.parentKey = parentNode ? parentNode.key : null;\n yield cached;\n return;\n }\n\n element = state.renderer(partialNode.value);\n }\n\n // If there's an element with a getCollectionNode function on its type, then it's a supported component.\n // Call this function to get a partial node, and recursively build a full node from there.\n if (React.isValidElement(element)) {\n let type = element.type as unknown as CollectReactElement<T>;\n if (typeof type !== 'function' && typeof type.getCollectionNode !== 'function') {\n let name = element.type;\n throw new Error(`Unknown element <${name}> in collection.`);\n }\n\n let childNodes = type.getCollectionNode(element.props, this.context) as Generator<PartialNode<T>, void, Node<T>[]>;\n let index = partialNode.index ?? 0;\n let result = childNodes.next();\n while (!result.done && result.value) {\n let childNode = result.value;\n\n partialNode.index = index;\n\n let nodeKey = childNode.key ?? null;\n if (nodeKey == null) {\n nodeKey = childNode.element ? null : this.getKey(element as NonNullable<CollectionElement<T>>, partialNode, state, parentKey);\n }\n\n let nodes = this.getFullNode({\n ...childNode,\n key: nodeKey,\n index,\n wrapper: compose(partialNode.wrapper, childNode.wrapper)\n }, this.getChildState(state, childNode), parentKey ? `${parentKey}${element.key}` : element.key, parentNode);\n\n let children = [...nodes];\n for (let node of children) {\n // Cache the node based on its value\n node.value = childNode.value ?? partialNode.value ?? null;\n if (node.value) {\n this.cache.set(node.value, node);\n }\n\n // The partial node may have specified a type for the child in order to specify a constraint.\n // Verify that the full node that was built recursively matches this type.\n if (partialNode.type && node.type !== partialNode.type) {\n throw new Error(`Unsupported type <${capitalize(node.type)}> in <${capitalize(parentNode?.type ?? 'unknown parent type')}>. Only <${capitalize(partialNode.type)}> is supported.`);\n }\n\n index++;\n yield node;\n }\n\n result = childNodes.next(children);\n }\n\n return;\n }\n\n // Ignore invalid elements\n if (partialNode.key == null || partialNode.type == null) {\n return;\n }\n\n // Create full node\n let builder = this;\n let node: Node<T> = {\n type: partialNode.type,\n props: partialNode.props,\n key: partialNode.key,\n parentKey: parentNode ? parentNode.key : null,\n value: partialNode.value ?? null,\n level: (parentNode?.level ?? 0) + (parentNode?.type === 'item' ? 1 : 0),\n index: partialNode.index,\n rendered: partialNode.rendered,\n textValue: partialNode.textValue ?? '',\n 'aria-label': partialNode['aria-label'],\n wrapper: partialNode.wrapper,\n shouldInvalidate: partialNode.shouldInvalidate,\n hasChildNodes: partialNode.hasChildNodes || false,\n childNodes: iterable(function *() {\n if (!partialNode.hasChildNodes || !partialNode.childNodes) {\n return;\n }\n\n let index = 0;\n for (let child of partialNode.childNodes()) {\n // Ensure child keys are globally unique by prepending the parent node's key\n if (child.key != null) {\n // TODO: Remove this line entirely and enforce that users always provide unique keys.\n // Currently this line will have issues when a parent has a key `a` and a child with key `bc`\n // but another parent has key `ab` and its child has a key `c`. The combined keys would result in both\n // children having a key of `abc`.\n child.key = `${node.key}${child.key}`;\n }\n\n let nodes = builder.getFullNode({...child, index}, builder.getChildState(state, child), node.key, node);\n for (let node of nodes) {\n index++;\n yield node;\n }\n }\n })\n };\n\n yield node;\n }\n}\n\n// Wraps an iterator function as an iterable object, and caches the results.\nfunction iterable<T>(iterator: () => IterableIterator<Node<T>>): Iterable<Node<T>> {\n let cache: Array<Node<T>> = [];\n let iterable: null | IterableIterator<Node<T>> = null;\n return {\n *[Symbol.iterator]() {\n for (let item of cache) {\n yield item;\n }\n\n if (!iterable) {\n iterable = iterator();\n }\n\n for (let item of iterable) {\n cache.push(item);\n yield item;\n }\n }\n };\n}\n\ntype Wrapper = (element: ReactElement) => ReactElement;\nfunction compose(outer: Wrapper | void, inner: Wrapper | void): Wrapper | undefined {\n if (outer && inner) {\n return (element) => outer(inner(element));\n }\n\n if (outer) {\n return outer;\n }\n\n if (inner) {\n return inner;\n }\n}\n\nfunction capitalize(str: string) {\n return str[0].toUpperCase() + str.slice(1);\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, CollectionStateBase, Node} from '@react-types/shared';\nimport {CollectionBuilder} from './CollectionBuilder';\nimport {ReactElement, useMemo} from 'react';\n\ninterface CollectionOptions<T, C extends Collection<Node<T>>> extends Omit<CollectionStateBase<T, C>, 'children'> {\n children?: ReactElement<any> | null | (ReactElement<any> | null)[] | ((item: T) => ReactElement<any> | null)\n}\n\ntype CollectionFactory<T, C extends Collection<Node<T>>> = (node: Iterable<Node<T>>) => C;\n\nexport function useCollection<T extends object, C extends Collection<Node<T>> = Collection<Node<T>>>(props: CollectionOptions<T, C>, factory: CollectionFactory<T, C>, context?: unknown): C {\n let builder = useMemo(() => new CollectionBuilder<T>(), []);\n let {children, items, collection} = props;\n let result = useMemo(() => {\n if (collection) {\n return collection;\n }\n let nodes = builder.build({children, items}, context);\n return factory(nodes);\n }, [builder, children, items, collection, context, factory]);\n return result;\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, CollectionStateBase, Key, LayoutDelegate, Node} from '@react-types/shared';\nimport {ListCollection} from './ListCollection';\nimport {MultipleSelectionStateProps, useMultipleSelectionState} from '../selection/useMultipleSelectionState';\nimport {SelectionManager} from '../selection/SelectionManager';\nimport {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {useCollection} from '../collections/useCollection';\n\nexport interface ListProps<T> extends CollectionStateBase<T>, MultipleSelectionStateProps {\n /** Filter function to generate a filtered list of nodes. */\n filter?: (nodes: Iterable<Node<T>>) => Iterable<Node<T>>,\n /** @private */\n suppressTextValueWarning?: boolean,\n /**\n * A delegate object that provides layout information for items in the collection.\n * This can be used to override the behavior of shift selection.\n */\n layoutDelegate?: LayoutDelegate\n}\n\nexport interface ListState<T> {\n /** A collection of items in the list. */\n collection: Collection<Node<T>>,\n\n /** A set of items that are disabled. */\n disabledKeys: Set<Key>,\n\n /** A selection manager to read and update multiple selection state. */\n selectionManager: SelectionManager\n}\n\n/**\n * Provides state management for list-like components. Handles building a collection\n * of items from props, and manages multiple selection state.\n */\nexport function useListState<T extends object>(props: ListProps<T>): ListState<T> {\n let {filter, layoutDelegate} = props;\n\n let selectionState = useMultipleSelectionState(props);\n let disabledKeys = useMemo(() =>\n props.disabledKeys ? new Set(props.disabledKeys) : new Set<Key>()\n , [props.disabledKeys]);\n\n let factory = useCallback(nodes => filter ? new ListCollection(filter(nodes)) : new ListCollection(nodes as Iterable<Node<T>>), [filter]);\n let context = useMemo(() => ({suppressTextValueWarning: props.suppressTextValueWarning}), [props.suppressTextValueWarning]);\n\n let collection = useCollection(props, factory, context);\n\n let selectionManager = useMemo(() =>\n new SelectionManager(collection, selectionState, {layoutDelegate})\n , [collection, selectionState, layoutDelegate]\n );\n\n useFocusedKeyReset(collection, selectionManager);\n\n return {\n collection,\n disabledKeys,\n selectionManager\n };\n}\n\n/**\n * Filters a collection using the provided filter function and returns a new ListState.\n */\nexport function UNSTABLE_useFilteredListState<T extends object>(state: ListState<T>, filterFn: ((nodeValue: string, node: Node<T>) => boolean) | null | undefined): ListState<T> {\n let collection = useMemo(() => filterFn ? state.collection.filter!(filterFn) : state.collection, [state.collection, filterFn]);\n let selectionManager = state.selectionManager.withCollection(collection);\n useFocusedKeyReset(collection, selectionManager);\n return {\n collection,\n selectionManager,\n disabledKeys: state.disabledKeys\n };\n}\n\nfunction useFocusedKeyReset<T>(collection: Collection<Node<T>>, selectionManager: SelectionManager) {\n // Reset focused key if that item is deleted from the collection.\n const cachedCollection = useRef<Collection<Node<T>> | null>(null);\n useEffect(() => {\n if (selectionManager.focusedKey != null && !collection.getItem(selectionManager.focusedKey) && cachedCollection.current) {\n // Walk forward in the old collection to find the next key that still exists in the new collection.\n let key = cachedCollection.current.getKeyAfter(selectionManager.focusedKey);\n let nextFocusedKey: Key | null = null;\n while (key != null) {\n let node = collection.getItem(key);\n if (node && node.type === 'item' && !selectionManager.isDisabled(key)) {\n nextFocusedKey = key;\n break;\n }\n\n key = cachedCollection.current.getKeyAfter(key);\n }\n\n // If no such key exists, walk backward.\n if (nextFocusedKey == null) {\n key = cachedCollection.current.getKeyBefore(selectionManager.focusedKey);\n while (key != null) {\n let node = collection.getItem(key);\n if (node && node.type === 'item' && !selectionManager.isDisabled(key)) {\n nextFocusedKey = key;\n break;\n }\n\n key = cachedCollection.current.getKeyBefore(key);\n }\n }\n\n selectionManager.setFocusedKey(nextFocusedKey);\n }\n cachedCollection.current = collection;\n }, [collection, selectionManager]);\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {useCallback} from 'react';\nimport {useControlledState} from '../utils/useControlledState';\n\nexport interface OverlayTriggerProps {\n /** Whether the overlay is open by default (controlled). */\n isOpen?: boolean,\n /** Whether the overlay is open by default (uncontrolled). */\n defaultOpen?: boolean,\n /** Handler that is called when the overlay's open state changes. */\n onOpenChange?: (isOpen: boolean) => void\n}\n\nexport interface OverlayTriggerState {\n /** Whether the overlay is currently open. */\n readonly isOpen: boolean,\n /** Sets whether the overlay is open. */\n setOpen(isOpen: boolean): void,\n /** Opens the overlay. */\n open(): void,\n /** Closes the overlay. */\n close(): void,\n /** Toggles the overlay's visibility. */\n toggle(): void\n}\n\n/**\n * Manages state for an overlay trigger. Tracks whether the overlay is open, and provides\n * methods to toggle this state.\n */\nexport function useOverlayTriggerState(props: OverlayTriggerProps): OverlayTriggerState {\n let [isOpen, setOpen] = useControlledState(props.isOpen, props.defaultOpen || false, props.onOpenChange);\n\n const open = useCallback(() => {\n setOpen(true);\n }, [setOpen]);\n\n const close = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n const toggle = useCallback(() => {\n setOpen(!isOpen);\n }, [setOpen, isOpen]);\n\n return {\n isOpen,\n setOpen,\n open,\n close,\n toggle\n };\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {ItemElement, ItemProps} from '@react-types/shared';\nimport {PartialNode} from './types';\nimport React, {JSX, ReactElement} from 'react';\n\nfunction Item<T>(props: ItemProps<T>): ReactElement | null { // eslint-disable-line @typescript-eslint/no-unused-vars\n return null;\n}\n\nItem.getCollectionNode = function* getCollectionNode<T>(props: ItemProps<T>, context: any): Generator<PartialNode<T>> {\n let {childItems, title, children} = props;\n\n let rendered = props.title || props.children;\n let textValue = props.textValue || (typeof rendered === 'string' ? rendered : '') || props['aria-label'] || '';\n\n // suppressTextValueWarning is used in components like Tabs, which don't have type to select support.\n if (!textValue && !context?.suppressTextValueWarning && process.env.NODE_ENV !== 'production') {\n console.warn('<Item> with non-plain text contents is unsupported by type to select for accessibility. Please add a `textValue` prop.');\n }\n\n yield {\n type: 'item',\n props: props,\n rendered,\n textValue,\n 'aria-label': props['aria-label'],\n hasChildNodes: hasChildItems(props),\n *childNodes() {\n if (childItems) {\n for (let child of childItems) {\n yield {\n type: 'item',\n value: child\n };\n }\n } else if (title) {\n let items: PartialNode<T>[] = [];\n React.Children.forEach(children, child => {\n items.push({\n type: 'item',\n element: child as ItemElement<T>\n });\n });\n\n yield* items;\n }\n }\n };\n};\n\nfunction hasChildItems<T>(props: ItemProps<T>) {\n if (props.hasChildItems != null) {\n return props.hasChildItems;\n }\n\n if (props.childItems) {\n return true;\n }\n\n if (props.title && React.Children.count(props.children) > 0) {\n return true;\n }\n\n return false;\n}\n\n// We don't want getCollectionNode to show up in the type definition\nlet _Item = Item as <T>(props: ItemProps<T>) => JSX.Element;\nexport {_Item as Item};\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {CollectionStateBase, Key, Node, Selection, SingleSelection} from '@react-types/shared';\nimport {ListState, useListState} from './useListState';\nimport {useControlledState} from '../utils/useControlledState';\nimport {useMemo} from 'react';\n\nexport interface SingleSelectListProps<T> extends CollectionStateBase<T>, Omit<SingleSelection, 'disallowEmptySelection'> {\n /** Filter function to generate a filtered list of nodes. */\n filter?: (nodes: Iterable<Node<T>>) => Iterable<Node<T>>,\n /** @private */\n suppressTextValueWarning?: boolean\n}\n\nexport interface SingleSelectListState<T> extends ListState<T> {\n /** The key for the currently selected item. */\n readonly selectedKey: Key | null,\n\n /** Sets the selected key. */\n setSelectedKey(key: Key | null): void,\n\n /** The value of the currently selected item. */\n readonly selectedItem: Node<T> | null\n}\n\n/**\n * Provides state management for list-like components with single selection.\n * Handles building a collection of items from props, and manages selection state.\n */\nexport function useSingleSelectListState<T extends object>(props: SingleSelectListProps<T>): SingleSelectListState<T> {\n let [selectedKey, setSelectedKey] = useControlledState(props.selectedKey, props.defaultSelectedKey ?? null, props.onSelectionChange);\n let selectedKeys = useMemo(() => selectedKey != null ? [selectedKey] : [], [selectedKey]);\n let {collection, disabledKeys, selectionManager} = useListState({\n ...props,\n selectionMode: 'single',\n disallowEmptySelection: true,\n allowDuplicateSelectionEvents: true,\n selectedKeys,\n onSelectionChange: (keys: Selection) => {\n // impossible, but TS doesn't know that\n if (keys === 'all') {\n return;\n }\n let key = keys.values().next().value ?? null;\n\n // Always fire onSelectionChange, even if the key is the same\n // as the current key (useControlledState does not).\n if (key === selectedKey && props.onSelectionChange) {\n props.onSelectionChange(key);\n }\n\n setSelectedKey(key);\n }\n });\n\n let selectedItem = selectedKey != null\n ? collection.getItem(selectedKey)\n : null;\n\n return {\n collection,\n disabledKeys,\n selectionManager,\n selectedKey,\n setSelectedKey,\n selectedItem\n };\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {CollectionBase, CollectionStateBase, FocusableProps, FocusStrategy, HelpTextProps, InputBase, Key, LabelableProps, Node, Selection, TextInputBase, Validation, ValueBase} from '@react-types/shared';\nimport {FormValidationState, useFormValidationState} from '../form/useFormValidationState';\nimport {ListState, useListState} from '../list/useListState';\nimport {OverlayTriggerState, useOverlayTriggerState} from '../overlays/useOverlayTriggerState';\nimport {useControlledState} from '../utils/useControlledState';\nimport {useMemo, useState} from 'react';\n\nexport type SelectionMode = 'single' | 'multiple';\nexport type ValueType<M extends SelectionMode> = M extends 'single' ? Key | null : readonly Key[];\nexport type ChangeValueType<M extends SelectionMode> = M extends 'single' ? Key | null : Key[];\ntype ValidationType<M extends SelectionMode> = M extends 'single' ? Key : Key[];\n\nexport interface SelectProps<T, M extends SelectionMode = 'single'> extends CollectionBase<T>, Omit<InputBase, 'isReadOnly'>, ValueBase<ValueType<M>, ChangeValueType<M>>, Validation<ValidationType<M>>, HelpTextProps, LabelableProps, TextInputBase, FocusableProps {\n /**\n * Whether single or multiple selection is enabled.\n * @default 'single'\n */\n selectionMode?: M,\n /**\n * The currently selected key in the collection (controlled).\n * @deprecated\n */\n selectedKey?: Key | null,\n /**\n * The initial selected key in the collection (uncontrolled).\n * @deprecated\n */\n defaultSelectedKey?: Key | null,\n /**\n * Handler that is called when the selection changes.\n * @deprecated\n */\n onSelectionChange?: (key: Key | null) => void,\n /** Sets the open state of the menu. */\n isOpen?: boolean,\n /** Sets the default open state of the menu. */\n defaultOpen?: boolean,\n /** Method that is called when the open state of the menu changes. */\n onOpenChange?: (isOpen: boolean) => void,\n /** Whether the Select should close when an item is selected. Defaults to true if selectionMode is single, false otherwise. */\n shouldCloseOnSelect?: boolean,\n /** Whether the select should be allowed to be open when the collection is empty. */\n allowsEmptyCollection?: boolean\n}\n\nexport interface SelectStateOptions<T, M extends SelectionMode = 'single'> extends Omit<SelectProps<T, M>, 'children'>, CollectionStateBase<T> {}\n\nexport interface SelectState<T, M extends SelectionMode = 'single'> extends ListState<T>, OverlayTriggerState, FormValidationState {\n /**\n * The key for the first selected item.\n * @deprecated\n */\n readonly selectedKey: Key | null,\n\n /**\n * The default selected key.\n * @deprecated\n */\n readonly defaultSelectedKey: Key | null,\n\n /**\n * Sets the selected key.\n * @deprecated\n */\n setSelectedKey(key: Key | null): void,\n\n /** The current select value. */\n readonly value: ValueType<M>,\n\n /** The default select value. */\n readonly defaultValue: ValueType<M>,\n\n /** Sets the select value. */\n setValue(value: Key | readonly Key[] | null): void,\n\n /**\n * The value of the first selected item.\n * @deprecated\n */\n readonly selectedItem: Node<T> | null,\n\n /** The value of the selected items. */\n readonly selectedItems: Node<T>[],\n\n /** Whether the select is currently focused. */\n readonly isFocused: boolean,\n\n /** Sets whether the select is focused. */\n setFocused(isFocused: boolean): void,\n\n /** Controls which item will be auto focused when the menu opens. */\n readonly focusStrategy: FocusStrategy | null,\n\n /** Opens the menu. */\n open(focusStrategy?: FocusStrategy | null): void,\n\n /** Toggles the menu. */\n toggle(focusStrategy?: FocusStrategy | null): void\n}\n\n/**\n * Provides state management for a select component. Handles building a collection\n * of items from props, handles the open state for the popup menu, and manages\n * multiple selection state.\n */\nexport function useSelectState<T extends object, M extends SelectionMode = 'single'>(props: SelectStateOptions<T, M>): SelectState<T, M> {\n let {\n selectionMode = 'single' as M,\n shouldCloseOnSelect = selectionMode === 'single'\n } = props;\n let triggerState = useOverlayTriggerState(props);\n let [focusStrategy, setFocusStrategy] = useState<FocusStrategy | null>(null);\n let defaultValue = useMemo(() => {\n return props.defaultValue !== undefined ? props.defaultValue : (selectionMode === 'single' ? props.defaultSelectedKey ?? null : []) as ValueType<M>;\n }, [props.defaultValue, props.defaultSelectedKey, selectionMode]);\n let value = useMemo(() => {\n return props.value !== undefined ? props.value : (selectionMode === 'single' ? props.selectedKey : undefined) as ValueType<M>;\n }, [props.value, props.selectedKey, selectionMode]);\n let [controlledValue, setControlledValue] = useControlledState<Key | readonly Key[] | null>(value, defaultValue, props.onChange as any);\n // Only display the first selected item if in single selection mode but the value is an array.\n let displayValue = selectionMode === 'single' && Array.isArray(controlledValue) ? controlledValue[0] : controlledValue;\n let setValue = (value: Key | Key[] | null) => {\n if (selectionMode === 'single') {\n let key = Array.isArray(value) ? value[0] ?? null : value;\n setControlledValue(key);\n if (key !== displayValue) {\n props.onSelectionChange?.(key);\n }\n } else {\n let keys: Key[] = [];\n if (Array.isArray(value)) {\n keys = value;\n } else if (value != null) {\n keys = [value];\n }\n\n setControlledValue(keys);\n }\n };\n\n let listState = useListState({\n ...props,\n selectionMode,\n disallowEmptySelection: selectionMode === 'single',\n allowDuplicateSelectionEvents: true,\n selectedKeys: useMemo(() => convertValue(displayValue), [displayValue]),\n onSelectionChange: (keys: Selection) => {\n // impossible, but TS doesn't know that\n if (keys === 'all') {\n return;\n }\n\n if (selectionMode === 'single') {\n let key = keys.values().next().value ?? null;\n setValue(key);\n } else {\n setValue([...keys]);\n }\n if (shouldCloseOnSelect) {\n triggerState.close();\n }\n\n validationState.commitValidation();\n }\n });\n\n let selectedKey = listState.selectionManager.firstSelectedKey;\n let selectedItems = useMemo(() => {\n return [...listState.selectionManager.selectedKeys].map(key => listState.collection.getItem(key)).filter(item => item != null);\n }, [listState.selectionManager.selectedKeys, listState.collection]);\n\n let validationState = useFormValidationState({\n ...props,\n value: Array.isArray(displayValue) && displayValue.length === 0 ? null : displayValue as any\n });\n\n let [isFocused, setFocused] = useState(false);\n let [initialValue] = useState(displayValue);\n\n return {\n ...validationState,\n ...listState,\n ...triggerState,\n value: displayValue as ValueType<M>,\n defaultValue: defaultValue ?? initialValue as ValueType<M>,\n setValue,\n selectedKey,\n setSelectedKey: setValue,\n selectedItem: selectedItems[0] ?? null,\n selectedItems,\n defaultSelectedKey: props.defaultSelectedKey ?? (props.selectionMode === 'single' ? initialValue as Key : null),\n focusStrategy,\n open(focusStrategy: FocusStrategy | null = null) {\n // Don't open if the collection is empty.\n if (listState.collection.size !== 0 || props.allowsEmptyCollection) {\n setFocusStrategy(focusStrategy);\n triggerState.open();\n }\n },\n toggle(focusStrategy: FocusStrategy | null = null) {\n if (listState.collection.size !== 0 || props.allowsEmptyCollection) {\n setFocusStrategy(focusStrategy);\n triggerState.toggle();\n }\n },\n isFocused,\n setFocused\n };\n}\n\nfunction convertValue(value: Key | Key[] | null | undefined) {\n if (value === undefined) {\n return undefined;\n }\n if (value === null) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, CollectionBase, CollectionStateBase, Key, Node, SingleSelection} from '@react-types/shared';\nimport {SingleSelectListState, useSingleSelectListState} from '../list/useSingleSelectListState';\nimport {useEffect, useRef} from 'react';\n\nexport interface TabListProps<T> extends CollectionBase<T>, Omit<SingleSelection, 'disallowEmptySelection' | 'selectedKey' | 'defaultSelectedKey' | 'onSelectionChange'> {\n /**\n * Whether the TabList is disabled.\n * Shows that a selection exists, but is not available in that circumstance.\n */\n isDisabled?: boolean,\n /** The currently selected key in the collection (controlled). */\n selectedKey?: Key,\n /** The initial selected keys in the collection (uncontrolled). */\n defaultSelectedKey?: Key,\n /** Handler that is called when the selection changes. */\n onSelectionChange?: (key: Key) => void\n}\n\nexport interface TabListStateOptions<T> extends Omit<TabListProps<T>, 'children'>, CollectionStateBase<T> {}\n\nexport interface TabListState<T> extends SingleSelectListState<T> {\n /** Whether the tab list is disabled. */\n isDisabled: boolean\n}\n\n/**\n * Provides state management for a Tabs component. Tabs include a TabList which tracks\n * which tab is currently selected and displays the content associated with that Tab in a TabPanel.\n */\nexport function useTabListState<T extends object>(props: TabListStateOptions<T>): TabListState<T> {\n let state = useSingleSelectListState<T>({\n ...props,\n onSelectionChange: props.onSelectionChange ? (key => {\n if (key != null) {\n props.onSelectionChange?.(key);\n }\n }) : undefined,\n suppressTextValueWarning: true,\n defaultSelectedKey: props.defaultSelectedKey ?? findDefaultSelectedKey(props.collection, props.disabledKeys ? new Set(props.disabledKeys) : new Set()) ?? undefined\n });\n\n let {\n selectionManager,\n collection,\n selectedKey: currentSelectedKey\n } = state;\n\n let lastSelectedKey = useRef(currentSelectedKey);\n useEffect(() => {\n // Ensure a tab is always selected (in case no selected key was specified or if selected item was deleted from collection)\n let selectedKey = currentSelectedKey;\n if (props.selectedKey == null && (selectionManager.isEmpty || selectedKey == null || !collection.getItem(selectedKey))) {\n selectedKey = findDefaultSelectedKey(collection, state.disabledKeys);\n if (selectedKey != null) {\n // directly set selection because replace/toggle selection won't consider disabled keys\n selectionManager.setSelectedKeys([selectedKey]);\n }\n }\n\n // If the tablist doesn't have focus and the selected key changes or if there isn't a focused key yet, change focused key to the selected key if it exists.\n if (selectedKey != null && selectionManager.focusedKey == null || (!selectionManager.isFocused && selectedKey !== lastSelectedKey.current)) {\n selectionManager.setFocusedKey(selectedKey);\n }\n lastSelectedKey.current = selectedKey;\n });\n\n return {\n ...state,\n isDisabled: props.isDisabled || false\n };\n}\n\nfunction findDefaultSelectedKey<T>(collection: Collection<Node<T>> | undefined, disabledKeys: Set<Key>) {\n let selectedKey: Key | null = null;\n if (collection) {\n selectedKey = collection.getFirstKey();\n // loop over tabs until we find one that isn't disabled and select that\n while (selectedKey != null && (disabledKeys.has(selectedKey) || collection.getItem(selectedKey)?.props?.isDisabled) && selectedKey !== collection.getLastKey()) {\n selectedKey = collection.getKeyAfter(selectedKey);\n }\n // if this check is true, then every item is disabled, it makes more sense to default to the first key than the last\n if (selectedKey != null && (disabledKeys.has(selectedKey) || collection.getItem(selectedKey)?.props?.isDisabled) && selectedKey === collection.getLastKey()) {\n selectedKey = collection.getFirstKey();\n }\n }\n\n return selectedKey;\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {FocusableProps, InputBase, Validation} from '@react-types/shared';\nimport {ReactNode, useState} from 'react';\nimport {useControlledState} from '../utils/useControlledState';\n\nexport interface ToggleStateOptions extends InputBase {\n /**\n * Whether the element should be selected (uncontrolled).\n */\n defaultSelected?: boolean,\n /**\n * Whether the element should be selected (controlled).\n */\n isSelected?: boolean,\n /**\n * Handler that is called when the element's selection state changes.\n */\n onChange?: (isSelected: boolean) => void\n}\n\nexport interface ToggleProps extends ToggleStateOptions, Validation<boolean>, FocusableProps {\n /**\n * The label for the element.\n */\n children?: ReactNode,\n /**\n * The value of the input element, used when submitting an HTML form. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefvalue).\n */\n value?: string\n}\n\nexport interface ToggleState {\n /** Whether the toggle is selected. */\n readonly isSelected: boolean,\n\n /** Whether the toggle is selected by default. */\n readonly defaultSelected: boolean,\n\n /** Updates selection state. */\n setSelected(isSelected: boolean): void,\n\n /** Toggle the selection state. */\n toggle(): void\n}\n\n/**\n * Provides state management for toggle components like checkboxes and switches.\n */\nexport function useToggleState(props: ToggleStateOptions = {}): ToggleState {\n let {isReadOnly} = props;\n\n // have to provide an empty function so useControlledState doesn't throw a fit\n // can't use useControlledState's prop calling because we need the event object from the change\n let [isSelected, setSelected] = useControlledState(props.isSelected, props.defaultSelected || false, props.onChange);\n let [initialValue] = useState(isSelected);\n\n function updateSelected(value) {\n if (!isReadOnly) {\n setSelected(value);\n }\n }\n\n function toggleState() {\n if (!isReadOnly) {\n setSelected(!isSelected);\n }\n }\n\n return {\n isSelected,\n defaultSelected: props.defaultSelected ?? initialValue,\n setSelected: updateSelected,\n toggle: toggleState\n };\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {OverlayTriggerProps, useOverlayTriggerState} from '../overlays/useOverlayTriggerState';\nimport {useEffect, useMemo, useRef} from 'react';\n\nexport interface TooltipTriggerProps extends OverlayTriggerProps {\n /**\n * Whether the tooltip should be disabled, independent from the trigger.\n */\n isDisabled?: boolean,\n\n /**\n * The delay time for the tooltip to show up. [See guidelines](https://spectrum.adobe.com/page/tooltip/#Immediate-or-delayed-appearance).\n * @default 1500\n */\n delay?: number,\n\n /**\n * The delay time for the tooltip to close. [See guidelines](https://spectrum.adobe.com/page/tooltip/#Warmup-and-cooldown).\n * @default 500\n */\n closeDelay?: number,\n\n /**\n * By default, opens for both focus and hover. Can be made to open only for focus.\n * @default 'hover'\n */\n trigger?: 'hover' | 'focus',\n\n /**\n * Whether the tooltip should close when the trigger is pressed.\n * @default true\n */\n shouldCloseOnPress?: boolean\n}\n\nconst TOOLTIP_DELAY = 1500; // this seems to be a 1.5 second delay, check with design\nconst TOOLTIP_COOLDOWN = 500;\n\nexport interface TooltipTriggerState {\n /** Whether the tooltip is currently showing. */\n isOpen: boolean,\n /**\n * Shows the tooltip. By default, the tooltip becomes visible after a delay\n * depending on a global warmup timer. The `immediate` option shows the\n * tooltip immediately instead.\n */\n open(immediate?: boolean): void,\n /** Hides the tooltip. */\n close(immediate?: boolean): void\n}\n\nlet tooltips = {};\nlet tooltipId = 0;\nlet globalWarmedUp = false;\nlet globalWarmUpTimeout: ReturnType<typeof setTimeout> | null = null;\nlet globalCooldownTimeout: ReturnType<typeof setTimeout> | null = null;\n\n/**\n * Manages state for a tooltip trigger. Tracks whether the tooltip is open, and provides\n * methods to toggle this state. Ensures only one tooltip is open at a time and controls\n * the delay for showing a tooltip.\n */\nexport function useTooltipTriggerState(props: TooltipTriggerProps = {}): TooltipTriggerState {\n let {delay = TOOLTIP_DELAY, closeDelay = TOOLTIP_COOLDOWN} = props;\n let {isOpen, open, close} = useOverlayTriggerState(props);\n let id = useMemo(() => `${++tooltipId}`, []);\n let closeTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n let closeCallback = useRef<() => void>(close);\n\n let ensureTooltipEntry = () => {\n tooltips[id] = hideTooltip;\n };\n\n let closeOpenTooltips = () => {\n for (let hideTooltipId in tooltips) {\n if (hideTooltipId !== id) {\n tooltips[hideTooltipId](true);\n delete tooltips[hideTooltipId];\n }\n }\n };\n\n let showTooltip = () => {\n if (closeTimeout.current) {\n clearTimeout(closeTimeout.current);\n }\n closeTimeout.current = null;\n closeOpenTooltips();\n ensureTooltipEntry();\n globalWarmedUp = true;\n open();\n if (globalWarmUpTimeout) {\n clearTimeout(globalWarmUpTimeout);\n globalWarmUpTimeout = null;\n }\n if (globalCooldownTimeout) {\n clearTimeout(globalCooldownTimeout);\n globalCooldownTimeout = null;\n }\n };\n\n let hideTooltip = (immediate?: boolean) => {\n if (immediate || closeDelay <= 0) {\n if (closeTimeout.current) {\n clearTimeout(closeTimeout.current);\n }\n closeTimeout.current = null;\n closeCallback.current();\n } else if (!closeTimeout.current) {\n closeTimeout.current = setTimeout(() => {\n closeTimeout.current = null;\n closeCallback.current();\n }, closeDelay);\n }\n\n if (globalWarmUpTimeout) {\n clearTimeout(globalWarmUpTimeout);\n globalWarmUpTimeout = null;\n }\n if (globalWarmedUp) {\n if (globalCooldownTimeout) {\n clearTimeout(globalCooldownTimeout);\n }\n globalCooldownTimeout = setTimeout(() => {\n delete tooltips[id];\n globalCooldownTimeout = null;\n globalWarmedUp = false;\n }, Math.max(TOOLTIP_COOLDOWN, closeDelay));\n }\n };\n\n let warmupTooltip = () => {\n closeOpenTooltips();\n ensureTooltipEntry();\n if (!isOpen && !globalWarmedUp) {\n if (globalWarmUpTimeout) {\n clearTimeout(globalWarmUpTimeout);\n }\n\n globalWarmUpTimeout = setTimeout(() => {\n globalWarmUpTimeout = null;\n globalWarmedUp = true;\n showTooltip();\n }, delay);\n } else if (!isOpen) {\n showTooltip();\n }\n };\n\n useEffect(() => {\n closeCallback.current = close;\n }, [close]);\n\n\n useEffect(() => {\n return () => {\n if (closeTimeout.current) {\n clearTimeout(closeTimeout.current);\n }\n let tooltip = tooltips[id];\n if (tooltip) {\n delete tooltips[id];\n }\n };\n }, [id]);\n\n return {\n isOpen,\n open: (immediate) => {\n if (!immediate && delay > 0 && !closeTimeout.current) {\n warmupTooltip();\n } else {\n showTooltip();\n }\n },\n close: hideTooltip\n };\n}\n","\"use client\";\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useCallback,\n useId,\n} from \"react\";\nimport { AddIcon, SubtractIcon } from \"@octaviaflow/icons\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type NumberInputSize = \"sm\" | \"md\" | \"lg\";\n\n/** Native `<input>` props minus the ones the component owns. We also drop\n * the native `size` attribute because we redefine `size` as the visual\n * variant (\"sm\" | \"md\" | \"lg\"). */\ntype InputPropsBase = Omit<\n ComponentPropsWithoutRef<\"input\">,\n | \"type\"\n | \"value\"\n | \"onChange\"\n | \"min\"\n | \"max\"\n | \"step\"\n | \"size\"\n | \"prefix\"\n>;\n\nexport interface NumberInputProps extends InputPropsBase {\n label?: ReactNode;\n value: number;\n onChange?: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n prefix?: ReactNode;\n suffix?: ReactNode;\n size?: NumberInputSize;\n disabled?: boolean;\n error?: ReactNode;\n helperText?: ReactNode;\n /** Extra class on the wrapper (NOT the input — use `inputClassName` for\n * the underlying control's class). */\n wrapperClassName?: string;\n /** Hide the +/- stepper buttons — renders a plain numeric field. The\n * value can still be typed; native number-input arrow keys still work. */\n hideControls?: boolean;\n /** Horizontal alignment of the value. Defaults to \"center\" (the\n * stepper-flanked style); use \"left\" for a standard form-field look.\n * Implied when `hideControls` is set unless overridden. */\n align?: \"left\" | \"center\";\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(\n function NumberInput(\n {\n label,\n value,\n onChange,\n min,\n max,\n step = 1,\n prefix,\n suffix,\n size = \"md\",\n disabled = false,\n error,\n helperText,\n id: providedId,\n className,\n wrapperClassName,\n hideControls = false,\n align,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": consumerDescribedBy,\n ...rest\n },\n ref,\n ) {\n // When the steppers are hidden the field reads like a normal form\n // input, so default the value to left-aligned unless the consumer\n // explicitly asked for centre.\n const resolvedAlign = align ?? (hideControls ? \"left\" : \"center\");\n const reactId = useId();\n const inputId = providedId ?? `ods-num-${reactId}`;\n const labelId = label ? `${inputId}-label` : undefined;\n const hintId = error || helperText ? `${inputId}-hint` : undefined;\n\n const clamp = useCallback(\n (v: number) => {\n if (typeof min === \"number\") v = Math.max(min, v);\n if (typeof max === \"number\") v = Math.min(max, v);\n return v;\n },\n [min, max],\n );\n\n const dec = () => !disabled && onChange?.(clamp(value - step));\n const inc = () => !disabled && onChange?.(clamp(value + step));\n const handleInput = (e: ChangeEvent<HTMLInputElement>) => {\n // Empty string is a valid transient state while the user is typing\n // (e.g. erasing to retype) — preserve it via NaN so the caller can\n // decide whether to coerce. For a controlled component callers\n // typically just hold their last numeric value.\n const raw = e.target.value;\n if (raw === \"\") return;\n const num = Number(raw);\n if (!Number.isNaN(num)) onChange?.(clamp(num));\n };\n\n // Compose aria-describedby: consumer's value wins on conflict, then\n // our hint id is appended. Filter out empties to keep the attribute\n // tidy when nothing applies.\n const describedBy =\n [consumerDescribedBy, hintId].filter(Boolean).join(\" \") || undefined;\n\n return (\n <div\n className={cn(\n \"ods-num\",\n `ods-num--${size}`,\n disabled && \"ods-num--disabled\",\n error && \"ods-num--error\",\n hideControls && \"ods-num--no-controls\",\n resolvedAlign === \"left\" && \"ods-num--align-left\",\n wrapperClassName,\n )}\n >\n {label && (\n <label\n id={labelId}\n htmlFor={inputId}\n className=\"ods-num__label\"\n >\n {label}\n </label>\n )}\n <div className=\"ods-num__field\">\n {!hideControls && (\n <button\n type=\"button\"\n className=\"ods-num__step ods-num__step--dec\"\n onClick={dec}\n disabled={disabled || (typeof min === \"number\" && value <= min)}\n aria-label=\"Decrease\"\n tabIndex={-1}\n >\n <SubtractIcon />\n </button>\n )}\n {prefix && (\n <span className=\"ods-num__prefix\" aria-hidden=\"true\">\n {prefix}\n </span>\n )}\n <input\n {...rest}\n ref={ref}\n id={inputId}\n type=\"number\"\n className={cn(\"ods-num__input\", className)}\n value={Number.isFinite(value) ? value : \"\"}\n onChange={handleInput}\n disabled={disabled}\n min={min}\n max={max}\n step={step}\n aria-invalid={error ? true : undefined}\n aria-describedby={describedBy}\n // Accessible-name fallback chain: an explicit aria-labelledby\n // or aria-label always wins. Otherwise we fall back to the\n // visible <label> when one was rendered.\n aria-labelledby={ariaLabelledBy ?? labelId}\n aria-label={\n !labelId && !ariaLabelledBy ? ariaLabel : undefined\n }\n />\n {suffix && (\n <span className=\"ods-num__suffix\" aria-hidden=\"true\">\n {suffix}\n </span>\n )}\n {!hideControls && (\n <button\n type=\"button\"\n className=\"ods-num__step ods-num__step--inc\"\n onClick={inc}\n disabled={disabled || (typeof max === \"number\" && value >= max)}\n aria-label=\"Increase\"\n tabIndex={-1}\n >\n <AddIcon />\n </button>\n )}\n </div>\n {error ? (\n <div\n id={hintId}\n className=\"ods-num__hint ods-num__hint--error\"\n role=\"alert\"\n >\n {error}\n </div>\n ) : helperText ? (\n <div id={hintId} className=\"ods-num__hint\">\n {helperText}\n </div>\n ) : null}\n </div>\n );\n },\n);\n\nNumberInput.displayName = \"NumberInput\";\n","\"use client\";\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useId,\n useState,\n} from \"react\";\nimport { CheckmarkIcon, ViewIcon, ViewOffIcon } from \"@octaviaflow/icons\";\nimport {\n type PasswordRule,\n type PasswordStrengthScore,\n usePasswordStrength,\n} from \"../../hooks/usePasswordStrength\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type PasswordInputSize = \"sm\" | \"md\" | \"lg\";\n\ntype InputPropsBase = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"type\" | \"size\" | \"value\" | \"onChange\" | \"prefix\"\n>;\n\nexport interface PasswordInputProps extends InputPropsBase {\n label?: ReactNode;\n value: string;\n onChange?: (value: string) => void;\n size?: PasswordInputSize;\n error?: ReactNode;\n helperText?: ReactNode;\n /** 0–4 strength score. When set, renders the visual strength meter.\n * `strength` takes precedence over `strengthRules` so consumers can\n * always override what the rules computed (e.g. server-derived score). */\n strength?: PasswordStrengthScore;\n /** Rule set to evaluate the password against. When provided (and\n * `strength` is NOT), the component runs `usePasswordStrength`\n * internally and renders the meter from the derived score. */\n strengthRules?: PasswordRule[];\n /** Render the requirements checklist below the meter. Each rule shows\n * a met/unmet glyph + its label, and the list is wired via\n * `aria-describedby` so screen readers announce the state. */\n showRequirements?: boolean;\n /** Show the show/hide-password toggle. Default true. */\n showToggle?: boolean;\n leftIcon?: ReactNode;\n /** Extra class on the wrapper (NOT the input). */\n wrapperClassName?: string;\n}\n\nconst strengthLabels = [\n \"Very weak\",\n \"Weak\",\n \"Fair\",\n \"Strong\",\n \"Very strong\",\n] as const;\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const PasswordInput = forwardRef<HTMLInputElement, PasswordInputProps>(\n function PasswordInput(\n {\n label,\n value,\n onChange,\n size = \"md\",\n error,\n helperText,\n strength,\n strengthRules,\n showRequirements = false,\n showToggle = true,\n leftIcon,\n disabled,\n id: providedId,\n className,\n wrapperClassName,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": consumerDescribedBy,\n ...rest\n },\n ref,\n ) {\n const reactId = useId();\n const inputId = providedId ?? `ods-pwd-${reactId}`;\n const labelId = label ? `${inputId}-label` : undefined;\n const hintId = error || helperText ? `${inputId}-hint` : undefined;\n // strengthId is rendered only when the meter is actually displayed.\n // We resolve `effectiveScore` below; the id is built upfront so the\n // memoization order stays stable, and we strip it from describedBy\n // when there's nothing to describe.\n\n const [shown, setShown] = useState(false);\n const handle = (e: ChangeEvent<HTMLInputElement>) =>\n onChange?.(e.target.value);\n\n // Hook ALWAYS runs — pass an empty rule list when the consumer didn't\n // configure one to keep the call cheap. Manual `strength` wins over\n // the derived score so server-side / app-side computations override\n // the local heuristic. The meter renders whenever EITHER the manual\n // score or a non-empty rule set is provided.\n const derived = usePasswordStrength(value, strengthRules ?? []);\n const ruleDriven = (strengthRules?.length ?? 0) > 0;\n const effectiveScore: PasswordStrengthScore | undefined =\n typeof strength === \"number\"\n ? strength\n : ruleDriven\n ? derived.score\n : undefined;\n const strengthId =\n typeof effectiveScore === \"number\" ? `${inputId}-strength` : undefined;\n const requirementsId =\n showRequirements && ruleDriven ? `${inputId}-requirements` : undefined;\n\n // Compose aria-describedby — consumer's value wins, then our hint id,\n // then the strength meter so AT users hear \"Weak / Strong / …\", then\n // the requirements checklist so they hear \"3 of 4 met\".\n const describedBy =\n [consumerDescribedBy, hintId, strengthId, requirementsId]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n return (\n <div\n className={cn(\n \"ods-pwd\",\n `ods-pwd--${size}`,\n disabled && \"ods-pwd--disabled\",\n error && \"ods-pwd--error\",\n wrapperClassName,\n )}\n >\n {label && (\n <label\n id={labelId}\n htmlFor={inputId}\n className=\"ods-pwd__label\"\n >\n {label}\n </label>\n )}\n <div className=\"ods-pwd__field\">\n {leftIcon && (\n <span className=\"ods-pwd__icon\" aria-hidden=\"true\">\n {leftIcon}\n </span>\n )}\n <input\n {...rest}\n ref={ref}\n id={inputId}\n type={shown ? \"text\" : \"password\"}\n value={value}\n onChange={handle}\n disabled={disabled}\n className={cn(\"ods-pwd__input\", className)}\n aria-invalid={error ? true : undefined}\n aria-describedby={describedBy}\n aria-labelledby={ariaLabelledBy ?? labelId}\n aria-label={\n !labelId && !ariaLabelledBy ? ariaLabel : undefined\n }\n />\n {showToggle && (\n <button\n type=\"button\"\n className=\"ods-pwd__toggle\"\n onClick={() => setShown((s) => !s)}\n aria-label={shown ? \"Hide password\" : \"Show password\"}\n aria-pressed={shown}\n disabled={disabled}\n tabIndex={-1}\n >\n {shown ? <ViewOffIcon /> : <ViewIcon />}\n </button>\n )}\n </div>\n {typeof effectiveScore === \"number\" && (\n <div\n id={strengthId}\n className=\"ods-pwd__strength\"\n data-level={effectiveScore}\n >\n <span className=\"ods-pwd__meter\" aria-hidden=\"true\">\n <span\n className={cn(\n \"ods-pwd__bar\",\n `ods-pwd__bar--${effectiveScore}`,\n )}\n />\n </span>\n <span className=\"ods-pwd__strength-label\">\n {strengthLabels[effectiveScore]}\n </span>\n </div>\n )}\n {showRequirements && ruleDriven && (\n // The checklist is decorative for sighted users + announced via\n // `aria-describedby` for AT. Each <li>'s `aria-label` encodes\n // state inline so screen readers say \"At least 8 characters,\n // met\" without any visible SR-only span — bullet-proof across\n // CSS reset variations and stale build artifacts.\n <ul\n id={requirementsId}\n className=\"ods-pwd__requirements\"\n aria-label={`Password requirements (${derived.passed} of ${derived.total} met)`}\n >\n {derived.rules.map((r) => (\n <li\n key={r.id}\n className={cn(\n \"ods-pwd__requirement\",\n r.passed && \"ods-pwd__requirement--met\",\n )}\n aria-label={`${r.label}, ${r.passed ? \"met\" : \"not met\"}`}\n >\n {/* Custom dot+check morph — the dot is a CSS-drawn 14-px\n * circle so we don't fight an icon's intrinsic sizing,\n * and the check fades + scales in on state flip for a\n * crisp micro-interaction. `prefers-reduced-motion`\n * drops the transitions in SCSS. */}\n <span\n className=\"ods-pwd__requirement-dot\"\n aria-hidden=\"true\"\n >\n <CheckmarkIcon\n size=\"xs\"\n tone=\"inverse\"\n className=\"ods-pwd__requirement-check\"\n />\n </span>\n <span className=\"ods-pwd__requirement-label\">{r.label}</span>\n </li>\n ))}\n </ul>\n )}\n {error ? (\n <div\n id={hintId}\n className=\"ods-pwd__hint ods-pwd__hint--error\"\n role=\"alert\"\n >\n {error}\n </div>\n ) : helperText ? (\n <div id={hintId} className=\"ods-pwd__hint\">\n {helperText}\n </div>\n ) : null}\n </div>\n );\n },\n);\n\nPasswordInput.displayName = \"PasswordInput\";\n","\"use client\";\nimport { useMemo } from \"react\";\n\n/* ---------------------------------------------------------------------------\n * usePasswordStrength — declarative password-rule evaluation\n *\n * Evaluates a password value against an ordered list of rules and returns a\n * 0–4 score plus per-rule pass/fail metadata. The score is ratio-based so\n * it stays sensible regardless of how many rules the consumer configures\n * (a 4-of-4 rule set and an 8-of-8 rule set both top out at score 4).\n *\n * const { score, rules, passed, total, isValid } = usePasswordStrength(\n * value,\n * [\n * { id: \"len\", label: \"At least 8 chars\", test: /.{8,}/ },\n * { id: \"low\", label: \"A lower-case letter\", test: /[a-z]/ },\n * { id: \"up\", label: \"An upper-case letter\", test: /[A-Z]/ },\n * { id: \"num\", label: \"A digit\", test: /\\d/ },\n * ],\n * );\n *\n * Defaults: when `rules` is omitted, `DEFAULT_PASSWORD_RULES` is used\n * (4 rules: length-8, lower, upper, digit). Pass an empty array to\n * disable all rules (score will always be 0).\n * ------------------------------------------------------------------------- */\n\nexport interface PasswordRule {\n /** Stable id — keyed in the result for React rendering and useful for\n * driving per-rule a11y associations. */\n id: string;\n /** Human-readable description (\"At least 8 characters\"). Surfaced in\n * the PasswordInput requirements checklist. */\n label: string;\n /** Regex (preferred) or predicate function. Regexes are tested with\n * `.test(value)`; predicates receive the raw value. */\n test: RegExp | ((value: string) => boolean);\n}\n\nexport interface PasswordRuleResult {\n id: string;\n label: string;\n passed: boolean;\n}\n\nexport type PasswordStrengthScore = 0 | 1 | 2 | 3 | 4;\n\nexport interface PasswordStrengthResult {\n /** 0–4, derived from `passed / total` (ratio-scaled). 0 = very weak,\n * 4 = very strong. */\n score: PasswordStrengthScore;\n /** Per-rule pass/fail in the order rules were supplied. */\n rules: PasswordRuleResult[];\n /** Count of rules that passed. */\n passed: number;\n /** Total rules evaluated. */\n total: number;\n /** True iff every rule passed (or the rule set is empty — vacuously\n * satisfied; consumers should usually require a non-empty rule set). */\n isValid: boolean;\n}\n\n/* ---------------------------------------------------------------------------\n * Defaults\n * ------------------------------------------------------------------------- */\n\n/** Reasonable starter rule set — 8-char minimum + character-class diversity.\n * Consumers should override for any compliance regime (passphrases,\n * banking, etc.). */\nexport const DEFAULT_PASSWORD_RULES: PasswordRule[] = [\n { id: \"length-8\", label: \"At least 8 characters\", test: /.{8,}/ },\n { id: \"lowercase\", label: \"A lower-case letter\", test: /[a-z]/ },\n { id: \"uppercase\", label: \"An upper-case letter\", test: /[A-Z]/ },\n { id: \"digit\", label: \"A digit\", test: /\\d/ },\n];\n\n/* ---------------------------------------------------------------------------\n * Hook\n * ------------------------------------------------------------------------- */\n\nexport function usePasswordStrength(\n value: string,\n rules: PasswordRule[] = DEFAULT_PASSWORD_RULES,\n): PasswordStrengthResult {\n return useMemo(() => {\n const evaluated: PasswordRuleResult[] = rules.map((r) => ({\n id: r.id,\n label: r.label,\n passed: runRule(r.test, value),\n }));\n const passed = evaluated.filter((r) => r.passed).length;\n const total = evaluated.length;\n const score = computeScore(passed, total);\n return {\n score,\n rules: evaluated,\n passed,\n total,\n isValid: total === 0 || passed === total,\n };\n }, [value, rules]);\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers\n * ------------------------------------------------------------------------- */\n\nfunction runRule(\n test: PasswordRule[\"test\"],\n value: string,\n): boolean {\n if (typeof test === \"function\") return test(value);\n // Regexes used as rule predicates can be stateful (the `g` and `y` flags\n // hold a `lastIndex` between calls). Re-running `.test` on a stale regex\n // returns wrong results — reset before testing.\n test.lastIndex = 0;\n return test.test(value);\n}\n\nfunction computeScore(passed: number, total: number): PasswordStrengthScore {\n if (total === 0) return 0;\n // Ratio-based: 0/total → 0, total/total → 4, evenly stepped between.\n // `floor(ratio * 5)` maps to {0,1,2,3,4,5} — clamp the perfect score\n // back to 4 so the meter caps at \"Very strong\".\n const ratio = passed / total;\n return Math.min(4, Math.floor(ratio * 5)) as PasswordStrengthScore;\n}\n","\"use client\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useId,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * SegmentedControl — small mutually-exclusive view-mode toggle.\n *\n * Common ETL UI uses:\n * - View toggle: Grid | List | Table\n * - Time range: Day | Week | Month | Year\n * - Mode flip: Edit | Preview\n * - Direction: Source | Destination\n *\n * Each segment is a button; the radiogroup pattern is the WAI-ARIA\n * recommended approach. Keyboard nav: ← → cycles, Home / End jump to\n * boundaries. A motion-backed \"indicator\" slides between segments on\n * change for a tactile feel (respects reduced-motion).\n *\n * Controlled OR uncontrolled — pass `value` for controlled, omit and\n * let the component own state with `defaultValue`.\n * ------------------------------------------------------------------------- */\n\nexport type SegmentedControlSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface SegmentedControlOption<T extends string = string> {\n /** Stable value identifier. */\n value: T;\n /** Display label. */\n label: ReactNode;\n /** Optional leading icon. */\n icon?: ReactNode;\n /** Disable this segment. */\n disabled?: boolean;\n}\n\nexport interface SegmentedControlProps<T extends string = string>\n extends Omit<\n ComponentPropsWithoutRef<\"div\">,\n | \"onChange\"\n | \"defaultValue\"\n | \"children\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onAnimationStart\"\n > {\n /** Available segments. */\n options: SegmentedControlOption<T>[];\n /** Controlled: currently-selected value. */\n value?: T;\n /** Uncontrolled fallback. Default = first non-disabled option. */\n defaultValue?: T;\n /** Fires on selection change. */\n onChange?: (value: T) => void;\n /** Visual size. Default `\"md\"`. */\n size?: SegmentedControlSize;\n /** Stretch to fill the container. Default `false`. */\n fullWidth?: boolean;\n /** Hide labels (icon-only segments). Default `false`. */\n iconOnly?: boolean;\n /** Disable the entire control. */\n disabled?: boolean;\n /** Accessible label for the group (required when no visible label). */\n \"aria-label\"?: string;\n /** id of an element that labels the group. */\n \"aria-labelledby\"?: string;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nfunction SegmentedControlInner<T extends string>(\n {\n options,\n value: controlledValue,\n defaultValue,\n onChange,\n size = \"md\",\n fullWidth = false,\n iconOnly = false,\n disabled = false,\n id: providedId,\n className,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...rest\n }: SegmentedControlProps<T>,\n ref: React.Ref<HTMLDivElement>,\n) {\n const reactId = useId();\n const baseId = providedId ?? `ods-segmented-${reactId}`;\n const reducedMotion = useReducedMotion();\n\n // Initial value: explicit defaultValue → first non-disabled option.\n const fallback =\n defaultValue ?? options.find((o) => !o.disabled)?.value ?? options[0]?.value;\n const [internalValue, setInternalValue] = useState<T | undefined>(\n fallback as T | undefined,\n );\n const isControlled = controlledValue !== undefined;\n const value = isControlled ? controlledValue : internalValue;\n\n const setValue = useCallback(\n (next: T) => {\n if (!isControlled) setInternalValue(next);\n onChange?.(next);\n },\n [isControlled, onChange],\n );\n\n const handleClick =\n (option: SegmentedControlOption<T>) =>\n (e: MouseEvent<HTMLButtonElement>) => {\n if (disabled || option.disabled) return;\n e.preventDefault();\n if (option.value !== value) setValue(option.value);\n };\n\n const handleKeyDown = (\n e: KeyboardEvent<HTMLButtonElement>,\n index: number,\n ) => {\n if (disabled) return;\n const enabled = options.filter((o) => !o.disabled);\n const currentEnabledIdx = enabled.findIndex((o) => o.value === value);\n let nextIdx = currentEnabledIdx;\n if (e.key === \"ArrowRight\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n nextIdx = (currentEnabledIdx + 1) % enabled.length;\n } else if (e.key === \"ArrowLeft\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n nextIdx =\n (currentEnabledIdx - 1 + enabled.length) % enabled.length;\n } else if (e.key === \"Home\") {\n e.preventDefault();\n nextIdx = 0;\n } else if (e.key === \"End\") {\n e.preventDefault();\n nextIdx = enabled.length - 1;\n } else {\n return;\n }\n const next = enabled[nextIdx];\n if (next) {\n setValue(next.value);\n const btn = document.getElementById(`${baseId}-seg-${next.value}`);\n (btn as HTMLButtonElement | null)?.focus();\n }\n // index is kept for future per-segment handling; currently unused\n void index;\n };\n\n return (\n <div\n {...rest}\n ref={ref}\n id={baseId}\n role=\"radiogroup\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n className={cn(\n \"ods-segmented\",\n `ods-segmented--${size}`,\n fullWidth && \"ods-segmented--full\",\n iconOnly && \"ods-segmented--icon-only\",\n disabled && \"ods-segmented--disabled\",\n className,\n )}\n >\n {options.map((opt, i) => {\n const selected = opt.value === value;\n return (\n <button\n key={opt.value}\n id={`${baseId}-seg-${opt.value}`}\n type=\"button\"\n role=\"radio\"\n aria-checked={selected}\n aria-label={iconOnly && typeof opt.label === \"string\" ? opt.label : undefined}\n tabIndex={selected ? 0 : -1}\n disabled={disabled || opt.disabled}\n className={cn(\n \"ods-segmented__segment\",\n selected && \"ods-segmented__segment--selected\",\n )}\n onClick={handleClick(opt)}\n onKeyDown={(e) => handleKeyDown(e, i)}\n >\n {selected && (\n <motion.span\n layoutId={`${baseId}-indicator`}\n className=\"ods-segmented__indicator\"\n aria-hidden=\"true\"\n transition={\n reducedMotion\n ? { duration: 0 }\n : { type: \"spring\", stiffness: 480, damping: 38 }\n }\n />\n )}\n {opt.icon && (\n <span\n className=\"ods-segmented__icon\"\n aria-hidden=\"true\"\n >\n {opt.icon}\n </span>\n )}\n {!iconOnly && (\n <span className=\"ods-segmented__label\">{opt.label}</span>\n )}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport const SegmentedControl = forwardRef(SegmentedControlInner) as <\n T extends string = string,\n>(\n props: SegmentedControlProps<T> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement;\n","\"use client\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport {\n forwardRef,\n type MouseEvent as ReactMouseEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { HiddenSelect, useButton, useListBox, useOption, useSelect } from \"react-aria\";\nimport { createPortal } from \"react-dom\";\nimport { Item, useSelectState } from \"react-stately\";\nimport { CheckmarkIcon, ChevronDownIcon } from \"@octaviaflow/icons\";\nimport { resolveAccessibleName } from \"../../utils/a11y\";\nimport { cn } from \"../../utils/cn\";\nimport { Tooltip } from \"../Tooltip/Tooltip\";\n\nexport interface SelectOption {\n value: string;\n label: string;\n icon?: ReactNode;\n description?: string;\n disabled?: boolean;\n}\n\nexport interface SelectProps {\n options: SelectOption[];\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n searchable?: boolean;\n label?: string;\n error?: boolean;\n errorMessage?: string;\n disabled?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n /** Name for form submission (forwarded to the HiddenSelect element). */\n name?: string;\n /** Required flag for form submission (forwarded to HiddenSelect). */\n required?: boolean;\n /** Stable id for the trigger button (and the source for label htmlFor). */\n id?: string;\n /** Associate this control with an external <form id=\"...\"> element. */\n form?: string;\n /** Auto-focus the trigger on mount. */\n autoFocus?: boolean;\n /** Optional aria-label when no visible label is provided. */\n \"aria-label\"?: string;\n /** Optional aria-labelledby override. */\n \"aria-labelledby\"?: string;\n /** Optional aria-describedby (e.g. for helper text outside the component). */\n \"aria-describedby\"?: string;\n /** Helper text rendered below the trigger. Suppressed when `error`\n * is set (the error message takes the slot). */\n helperText?: ReactNode;\n /**\n * Render a check-mark glyph next to the currently selected option in\n * the dropdown. Defaults to `false` — the highlighted background is\n * already a strong visual cue, so doubling up reads as visual noise\n * in dense menus. Re-enable when the menu sits in a context where the\n * highlight isn't enough (e.g. extremely tall menus).\n */\n showCheckmark?: boolean;\n /**\n * Close the popover when the user clicks anywhere outside the trigger\n * + menu. Defaults to `true` — set to `false` for cases where the\n * caller manages dismissal explicitly (e.g. a modal that wraps the\n * select and owns its own close logic).\n */\n closeOnOutsideClick?: boolean;\n /** Show our design-system `<Tooltip>` on hover over options whose\n * label may be truncated. Default `false` — opt-in via this flag per\n * the platform's \"chrome stays quiet unless explicitly enabled\"\n * convention. The popover surfaces the full label plus the\n * description on a second line when present. */\n showOverflowTooltips?: boolean;\n /**\n * Floor for the dropdown popover width in pixels. The popover is\n * normally pinned to the trigger's width (visual alignment); pass\n * a number here when the trigger is narrow but option labels are\n * long — e.g. Calendar's compact `size=\"sm\"` month/year caption\n * where the trigger is ~70 px but month names like \"September\"\n * need ~110 px. Defaults to the trigger width (no override).\n */\n dropdownMinWidth?: number;\n}\n\n/* ------------------------------------------------------------------ */\n/* OverflowTooltip helper */\n/* ------------------------------------------------------------------ */\n\n/** Wraps `children` in our design-system Tooltip only when the flag is\n * on AND there's content to surface. Mirrors the MultiSelect pattern\n * so both pickers stay consistent. */\nfunction OverflowTooltip({\n enabled,\n content,\n children,\n}: {\n enabled: boolean;\n content: ReactNode;\n children: React.ReactElement;\n}) {\n if (!enabled || content == null || content === \"\") return children;\n return <Tooltip content={content}>{children}</Tooltip>;\n}\n\n/* ------------------------------------------------------------------ */\n/* Internal ListBox rendered inside the dropdown */\n/* ------------------------------------------------------------------ */\n\nfunction ListBox(props: any) {\n const ref = useRef<HTMLUListElement>(null);\n const {\n listBoxRef = ref,\n state,\n showCheckmark,\n showOverflowTooltips,\n } = props;\n const { listBoxProps } = useListBox(props, state, listBoxRef);\n\n return (\n <ul {...listBoxProps} ref={listBoxRef} className={\"ods-select__options\"}>\n {[...state.collection].map((item: any) => (\n <Option\n key={item.key}\n item={item}\n state={state}\n showCheckmark={showCheckmark}\n showOverflowTooltips={showOverflowTooltips}\n />\n ))}\n </ul>\n );\n}\n\nfunction Option({\n item,\n state,\n showCheckmark,\n showOverflowTooltips,\n}: {\n item: any;\n state: any;\n showCheckmark?: boolean;\n showOverflowTooltips?: boolean;\n}) {\n const ref = useRef<HTMLLIElement>(null);\n const { optionProps, isSelected, isFocused, isDisabled } = useOption(\n { key: item.key },\n state,\n ref,\n );\n\n // item.value is the items-array object; the actual SelectOption is nested inside\n const raw = item.value;\n const option: SelectOption | undefined = raw?.value ?? raw;\n\n // Tooltip content — label by itself, OR label + description on two\n // lines so the popover surfaces everything the row contains.\n const tooltipContent: ReactNode = option?.description ? (\n <>\n <span>{option.label}</span>\n <br />\n <span style={{ opacity: 0.75 }}>{option.description}</span>\n </>\n ) : (\n option?.label\n );\n\n return (\n <OverflowTooltip\n enabled={!!showOverflowTooltips}\n content={tooltipContent}\n >\n <li\n {...optionProps}\n ref={ref}\n className={cn(\n \"ods-select__option\",\n isFocused && \"ods-select__option--highlighted\",\n isSelected && \"ods-select__option--selected\",\n isDisabled && \"ods-select__option--disabled\",\n )}\n >\n {option?.icon && <span className={\"ods-select__option-icon\"}>{option.icon}</span>}\n <span className={\"ods-select__option-text\"}>\n <span className={\"ods-select__option-label\"}>{item.rendered}</span>\n {option?.description && (\n <span className={\"ods-select__option-desc\"}>{option.description}</span>\n )}\n </span>\n {isSelected && showCheckmark && (\n <span className={\"ods-select__check\"} aria-hidden=\"true\">\n <CheckmarkIcon size=\"xs\" tone=\"accent\" />\n </span>\n )}\n </li>\n </OverflowTooltip>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Main Select component */\n/* ------------------------------------------------------------------ */\n\n// Generic default placeholder. A select left on THIS placeholder with no\n// label is a genuine a11y gap (we still warn). But a CUSTOM placeholder\n// (e.g. \"Search channels and people…\") describes the control's purpose, so\n// it's used as the accessible-name fallback — see ariaNameProps below.\nconst DEFAULT_SELECT_PLACEHOLDER = \"Select an option...\";\n\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n options,\n value,\n defaultValue,\n onChange,\n placeholder = DEFAULT_SELECT_PLACEHOLDER,\n searchable = false,\n label,\n error = false,\n errorMessage,\n helperText,\n disabled = false,\n size = \"md\",\n className,\n name,\n required,\n id: providedId,\n form,\n autoFocus,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": consumerDescribedBy,\n showCheckmark = false,\n closeOnOutsideClick = true,\n showOverflowTooltips = false,\n dropdownMinWidth,\n },\n forwardedRef,\n) {\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listBoxRef = useRef<HTMLUListElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLInputElement>(null);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [dropdownPos, setDropdownPos] = useState<{\n top?: number;\n bottom?: number;\n left: number;\n width: number;\n maxHeight: number;\n /** \"down\" = popover hangs below the trigger; \"up\" = it stacks above. */\n direction: \"down\" | \"up\";\n }>({ left: 0, width: 0, maxHeight: 240, direction: \"down\" });\n\n // Compose the forwarded ref with our internal trigger ref so consumers\n // can `.focus()` the button while react-aria's internal needs still work.\n const setTriggerRef = (node: HTMLButtonElement | null) => {\n (triggerRef as { current: HTMLButtonElement | null }).current = node;\n if (typeof forwardedRef === \"function\") forwardedRef(node);\n else if (forwardedRef)\n (forwardedRef as { current: HTMLButtonElement | null }).current = node;\n };\n\n const reactId = useId();\n const baseId = providedId ?? `ods-select-${reactId}`;\n const hintId = error || helperText ? `${baseId}-hint` : undefined;\n const describedBy =\n [consumerDescribedBy, hintId].filter(Boolean).join(\" \") || undefined;\n\n // Build react-stately items from options, applying search filter\n const filteredOptions = useMemo(() => {\n if (!searchable || !searchQuery) return options;\n const q = searchQuery.toLowerCase();\n return options.filter(\n (o) => o.label.toLowerCase().includes(q) || o.description?.toLowerCase().includes(q),\n );\n }, [options, searchQuery, searchable]);\n\n // Build collection props for useSelectState\n // Resolve accessible name from {label, aria-label, aria-labelledby}. Removes\n // the literal \"Select\" fallback that was masking the real \"no label\" bug.\n // A CUSTOM placeholder is accepted as a last-resort accessible name (a\n // placeholder like \"Search channels and people…\" is a meaningful control\n // description); the generic default placeholder is NOT, so a truly\n // unlabeled select still trips the dev warning.\n const ariaNameProps = useMemo(\n () =>\n resolveAccessibleName({\n label,\n ariaLabel,\n ariaLabelledby: ariaLabelledBy,\n componentName: \"Select\",\n fallbacks: [\n placeholder && placeholder !== DEFAULT_SELECT_PLACEHOLDER ? placeholder : undefined,\n ],\n }),\n [label, ariaLabel, ariaLabelledBy, placeholder],\n );\n\n const ariaProps = useMemo(() => {\n const items = filteredOptions.map((o) => ({\n key: o.value,\n label: o.label,\n value: o,\n isDisabled: o.disabled,\n }));\n\n const props: any = {\n // Visible string label when present; otherwise rely on the aria-*\n // props for screen-reader name.\n label: typeof label === \"string\" ? label : undefined,\n ...ariaNameProps,\n items,\n children: (item: any) => (\n <Item key={item.key} textValue={item.label}>\n {item.label}\n </Item>\n ),\n isDisabled: disabled,\n onSelectionChange: (key: any) => {\n onChange?.(String(key));\n setSearchQuery(\"\");\n },\n };\n\n if (value !== undefined) {\n props.selectedKey = value;\n }\n if (defaultValue !== undefined) {\n props.defaultSelectedKey = defaultValue;\n }\n\n return props;\n }, [filteredOptions, label, disabled, value, defaultValue, onChange, ariaNameProps]);\n\n const state = useSelectState(ariaProps);\n\n const { triggerProps, menuProps } = useSelect(ariaProps, state, triggerRef);\n const { buttonProps } = useButton(triggerProps, triggerRef);\n\n // Position dropdown using getBoundingClientRect (fixed positioning to\n // escape stacking contexts). Now viewport-aware: when the trigger sits\n // near the bottom of the screen we flip the popover upward; either\n // way we cap its height to what's actually available so option lists\n // never spill off-screen (the prior behavior on tall pages).\n const updatePosition = useCallback(() => {\n if (!triggerRef.current) return;\n const rect = triggerRef.current.getBoundingClientRect();\n const viewportH = window.innerHeight;\n const margin = 8; // breathing room at the viewport edge\n const gap = 4; // gap between trigger and popover\n const spaceBelow = viewportH - rect.bottom - gap - margin;\n const spaceAbove = rect.top - gap - margin;\n // Prefer downward; flip up when below is cramped AND above has more\n // room. Falls back to whichever side has more space if both are tight.\n const PREFERRED_MIN = 200;\n const openUp =\n spaceBelow < PREFERRED_MIN && spaceAbove > spaceBelow;\n setDropdownPos({\n ...(openUp\n ? { bottom: viewportH - rect.top + gap }\n : { top: rect.bottom + gap }),\n left: rect.left,\n width: rect.width,\n maxHeight: Math.max(120, openUp ? spaceAbove : spaceBelow),\n direction: openUp ? \"up\" : \"down\",\n });\n }, []);\n\n useEffect(() => {\n if (state.isOpen) {\n updatePosition();\n window.addEventListener(\"scroll\", updatePosition, true);\n window.addEventListener(\"resize\", updatePosition);\n return () => {\n window.removeEventListener(\"scroll\", updatePosition, true);\n window.removeEventListener(\"resize\", updatePosition);\n };\n }\n }, [state.isOpen, updatePosition]);\n\n // Focus search input when dropdown opens\n useEffect(() => {\n if (state.isOpen && searchable && searchRef.current) {\n // Small delay to allow animation frame\n requestAnimationFrame(() => searchRef.current?.focus());\n }\n }, [state.isOpen, searchable]);\n\n // Outside-click + Escape close. react-aria's `useSelect` wires Escape\n // when the trigger keeps focus, but because the dropdown is portaled\n // to <body> and we move focus into the search input on open, the\n // built-in dismiss does not fire on document-level outside clicks.\n // Wire it here ourselves; the `closeOnOutsideClick` prop lets a\n // consumer opt out for modal-managed selects.\n useEffect(() => {\n if (!state.isOpen || !closeOnOutsideClick) return;\n const onPointer = (e: MouseEvent) => {\n const target = e.target as Node;\n if (dropdownRef.current?.contains(target)) return;\n if (triggerRef.current?.contains(target)) return;\n state.close();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") state.close();\n };\n document.addEventListener(\"mousedown\", onPointer);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onPointer);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [state.isOpen, state.close, closeOnOutsideClick]);\n\n // Find currently selected option for display\n const selectedOption = options.find((o) => o.value === String(state.selectedKey ?? \"\"));\n\n // ── Close-on-re-click ──────────────────────────────────────────────\n // react-aria's `useSelect` opens on press but does NOT toggle when\n // the trigger is pressed again with the menu open — that's the\n // \"click trigger again\" close pattern users expect from every other\n // select on the web. We restore it here: stash the open state right\n // before the press, and on the trailing click, if it was open AND\n // still is open (meaning react-aria didn't auto-close), force close.\n const wasOpenBeforePressRef = useRef(false);\n const handleTriggerPointerDown = (e: ReactPointerEvent<HTMLButtonElement>) => {\n wasOpenBeforePressRef.current = state.isOpen;\n // Forward to react-aria's own handler if present.\n const baseHandler = (buttonProps as { onPointerDown?: (e: ReactPointerEvent<HTMLButtonElement>) => void }).onPointerDown;\n baseHandler?.(e);\n };\n const handleTriggerClick = (e: ReactMouseEvent<HTMLButtonElement>) => {\n const baseHandler = (buttonProps as { onClick?: (e: ReactMouseEvent<HTMLButtonElement>) => void }).onClick;\n baseHandler?.(e);\n if (wasOpenBeforePressRef.current && state.isOpen) {\n state.close();\n }\n wasOpenBeforePressRef.current = false;\n };\n\n return (\n <div\n className={cn(\n \"ods-select\",\n `ods-select--${size}`,\n error && \"ods-select--error\",\n disabled && \"ods-select--disabled\",\n className,\n )}\n >\n {label && (\n <label className={\"ods-select__label\"} htmlFor={baseId}>\n {label}\n </label>\n )}\n\n <HiddenSelect state={state} triggerRef={triggerRef} label={label} name={name} />\n\n <button\n {...buttonProps}\n onPointerDown={handleTriggerPointerDown}\n onClick={handleTriggerClick}\n ref={setTriggerRef}\n id={baseId}\n form={form}\n autoFocus={autoFocus}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={describedBy}\n aria-required={required || undefined}\n aria-invalid={error ? true : undefined}\n className={cn(\"ods-select__trigger\", state.isOpen && \"ods-select__trigger--open\")}\n >\n <span className={\"ods-select__value\"}>\n {selectedOption ? (\n <>\n {selectedOption.icon && (\n <span className={\"ods-select__value-icon\"}>{selectedOption.icon}</span>\n )}\n {selectedOption.label}\n </>\n ) : (\n <span className={\"ods-select__placeholder\"}>{placeholder}</span>\n )}\n </span>\n <span\n className={cn(\n \"ods-select__chevron\",\n state.isOpen && \"ods-select__chevron--open\",\n )}\n aria-hidden=\"true\"\n >\n <ChevronDownIcon size=\"xs\" />\n </span>\n </button>\n\n {typeof document !== \"undefined\" &&\n createPortal(\n <AnimatePresence>\n {state.isOpen && (\n <motion.div\n ref={dropdownRef}\n className={\"ods-select__dropdown\"}\n style={{\n position: \"fixed\",\n ...(dropdownPos.top !== undefined && { top: dropdownPos.top }),\n ...(dropdownPos.bottom !== undefined && { bottom: dropdownPos.bottom }),\n left: dropdownPos.left,\n // `minWidth` (not `width`) keeps the popover at\n // least as wide as the trigger — preserves visual\n // alignment — but allows the consumer to widen it\n // explicitly when option labels demand more room\n // (pass `dropdownMinWidth` to set a higher floor).\n // Avoids the previous `max-content` recipe which\n // made the popover grow uncomfortably wide on\n // searchable / long-option menus.\n minWidth: Math.max(dropdownPos.width, dropdownMinWidth ?? 0),\n // Bound the popover to the available viewport edge so\n // it never spills off-screen on tall pages. Pairs with\n // `overflow-y: auto` from the .ods-select__dropdown\n // SCSS so long option lists scroll internally.\n maxHeight: dropdownPos.maxHeight,\n }}\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={{ duration: 0.2, ease: [0.16, 1, 0.3, 1] }}\n >\n {searchable && (\n <div className={\"ods-select__search-wrap\"}>\n <input\n ref={searchRef}\n className={\"ods-select__search\"}\n type=\"text\"\n placeholder=\"Search...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n aria-label=\"Search options\"\n onKeyDown={(e) => {\n // Allow Escape to close the dropdown\n if (e.key === \"Escape\") {\n state.close();\n }\n }}\n />\n </div>\n )}\n <ListBox\n {...menuProps}\n listBoxRef={listBoxRef}\n state={state}\n showCheckmark={showCheckmark}\n showOverflowTooltips={showOverflowTooltips}\n />\n {filteredOptions.length === 0 && (\n <div className={\"ods-select__empty\"}>No results found</div>\n )}\n </motion.div>\n )}\n </AnimatePresence>,\n document.body,\n )}\n\n {error && errorMessage ? (\n <span\n id={hintId}\n className={\"ods-select__error\"}\n role=\"alert\"\n >\n {errorMessage}\n </span>\n ) : helperText ? (\n <span id={hintId} className={\"ods-select__hint\"}>\n {helperText}\n </span>\n ) : null}\n </div>\n );\n});\n\nSelect.displayName = \"Select\";\n","\"use client\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport {\n cloneElement,\n type ComponentPropsWithRef,\n type DOMAttributes,\n isValidElement,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefObject,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useTooltip, useTooltipTrigger } from \"react-aria\";\nimport { createPortal } from \"react-dom\";\nimport { useTooltipTriggerState } from \"react-stately\";\nimport { cn } from \"../../utils/cn\";\n\nexport type TooltipPosition = \"top\" | \"bottom\" | \"left\" | \"right\";\n\nexport interface TooltipProps {\n content: ReactNode;\n /** Preferred position. May flip to the opposite side if it would overflow. */\n position?: TooltipPosition;\n /** Open-delay in milliseconds (react-aria's warmup). Defaults to 200. */\n delay?: number;\n /** Pixel gap between trigger and tooltip. Defaults to 8. */\n offset?: number;\n /** Suppress the tooltip entirely without removing the trigger from the tree. */\n disabled?: boolean;\n /** Stable id for the tooltip DOM node — useful for aria-describedby tests. */\n id?: string;\n children: ReactElement;\n className?: string;\n}\n\ninterface Coords {\n top: number;\n left: number;\n /** The actual side the tooltip ended up on after any flip. */\n position: TooltipPosition;\n}\n\nconst FLIP: Record<TooltipPosition, TooltipPosition> = {\n top: \"bottom\",\n bottom: \"top\",\n left: \"right\",\n right: \"left\",\n};\n\nfunction placeOn(\n rect: DOMRect,\n tipRect: DOMRect,\n position: TooltipPosition,\n offset: number,\n): { top: number; left: number } {\n const cx = rect.left + rect.width / 2;\n const cy = rect.top + rect.height / 2;\n switch (position) {\n case \"top\":\n return {\n top: rect.top - tipRect.height - offset,\n left: cx - tipRect.width / 2,\n };\n case \"bottom\":\n return { top: rect.bottom + offset, left: cx - tipRect.width / 2 };\n case \"left\":\n return {\n top: cy - tipRect.height / 2,\n left: rect.left - tipRect.width - offset,\n };\n case \"right\":\n return { top: cy - tipRect.height / 2, left: rect.right + offset };\n }\n}\n\n/** Resolve the final placement: flip if the preferred side overflows. */\nfunction computePosition(\n rect: DOMRect,\n tipRect: DOMRect,\n position: TooltipPosition,\n offset: number,\n viewport: { width: number; height: number },\n): Coords {\n const tryAt = (p: TooltipPosition) => {\n const c = placeOn(rect, tipRect, p, offset);\n const fits =\n c.top >= 0 &&\n c.left >= 0 &&\n c.top + tipRect.height <= viewport.height &&\n c.left + tipRect.width <= viewport.width;\n return { ...c, position: p, fits };\n };\n\n const preferred = tryAt(position);\n if (preferred.fits) return preferred;\n const flipped = tryAt(FLIP[position]);\n if (flipped.fits) return flipped;\n\n // Neither fits cleanly — fall back to the preferred side but clamp into\n // the viewport so the arrow target is still close to the trigger.\n const fallback = preferred;\n const clampedLeft = Math.max(\n 4,\n Math.min(fallback.left, viewport.width - tipRect.width - 4),\n );\n const clampedTop = Math.max(\n 4,\n Math.min(fallback.top, viewport.height - tipRect.height - 4),\n );\n return { top: clampedTop, left: clampedLeft, position: fallback.position };\n}\n\n// Framer-motion's `initial` / `animate` accept rich variant types we\n// don't need to spell out — plain objects with `opacity` + `x`/`y` are\n// the documented shorthand and avoid pulling in the library's union.\ntype MotionFrame = Record<string, number | string>;\nconst animVariants: Record<\n TooltipPosition,\n { initial: MotionFrame; animate: MotionFrame }\n> = {\n top: { initial: { opacity: 0, y: 4 }, animate: { opacity: 1, y: 0 } },\n bottom: { initial: { opacity: 0, y: -4 }, animate: { opacity: 1, y: 0 } },\n left: { initial: { opacity: 0, x: 4 }, animate: { opacity: 1, x: 0 } },\n right: { initial: { opacity: 0, x: -4 }, animate: { opacity: 1, x: 0 } },\n};\n\ninterface ContentProps {\n state: ReturnType<typeof useTooltipTriggerState>;\n content: ReactNode;\n position: TooltipPosition;\n triggerRef: RefObject<HTMLElement | null>;\n className?: string;\n offset: number;\n tooltipId: string;\n}\n\nfunction TooltipContent({\n state,\n content,\n position,\n triggerRef,\n className,\n offset,\n tooltipId,\n}: ContentProps) {\n const { tooltipProps } = useTooltip({ isOpen: state.isOpen }, state);\n const tipRef = useRef<HTMLDivElement | null>(null);\n const [coords, setCoords] = useState<Coords | null>(null);\n\n const reposition = useCallback(() => {\n if (!triggerRef.current || !tipRef.current) return;\n const trigRect = triggerRef.current.getBoundingClientRect();\n const tipRect = tipRef.current.getBoundingClientRect();\n const viewport = {\n width: window.innerWidth || document.documentElement.clientWidth,\n height: window.innerHeight || document.documentElement.clientHeight,\n };\n setCoords(computePosition(trigRect, tipRect, position, offset, viewport));\n }, [triggerRef, position, offset]);\n\n // The first measure happens before the tip has rendered its content, so\n // its rect is empty. Measure again on the next frame for accurate placement.\n useLayoutEffect(() => {\n if (!state.isOpen) return;\n reposition();\n const id = requestAnimationFrame(reposition);\n return () => cancelAnimationFrame(id);\n }, [state.isOpen, reposition]);\n\n useEffect(() => {\n if (!state.isOpen) return;\n const handler = () => reposition();\n window.addEventListener(\"scroll\", handler, true);\n window.addEventListener(\"resize\", handler);\n return () => {\n window.removeEventListener(\"scroll\", handler, true);\n window.removeEventListener(\"resize\", handler);\n };\n }, [state.isOpen, reposition]);\n\n const resolvedPos = coords?.position ?? position;\n const variants = animVariants[resolvedPos];\n\n // react-aria's tooltip props include onMouseEnter/onMouseLeave for the\n // tooltip itself plus drag-related handlers that conflict with framer-\n // motion's prop signatures. Strip the ones framer-motion claims so the\n // intersection is type-clean.\n const {\n onDrag: _onDrag,\n onDragStart: _onDragStart,\n onDragEnd: _onDragEnd,\n onAnimationStart: _onAnimationStart,\n ...safeTipProps\n } = tooltipProps as DOMAttributes<HTMLDivElement> & Record<string, unknown>;\n\n const portalContent = (\n <AnimatePresence>\n {state.isOpen && (\n <div\n className=\"ods-tooltip__wrapper\"\n style={{\n position: \"fixed\",\n zIndex: 1500,\n top: coords?.top ?? -9999,\n left: coords?.left ?? -9999,\n visibility: coords ? \"visible\" : \"hidden\",\n pointerEvents: \"none\",\n }}\n >\n <motion.div\n ref={tipRef}\n {...safeTipProps}\n id={tooltipId}\n role=\"tooltip\"\n data-position={resolvedPos}\n className={cn(\"ods-tooltip\", className)}\n initial={variants.initial}\n animate={variants.animate}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15, ease: \"easeOut\" }}\n >\n {content}\n <span className=\"ods-tooltip__arrow\" aria-hidden=\"true\" />\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n );\n\n if (typeof document === \"undefined\") return null;\n return createPortal(portalContent, document.body);\n}\n\n/** Compose two refs into one — preserves the child's existing ref. */\nfunction mergeRefs<T>(...refs: Array<Ref<T> | undefined>): (node: T | null) => void {\n return (node) => {\n for (const r of refs) {\n if (!r) continue;\n if (typeof r === \"function\") r(node);\n else (r as { current: T | null }).current = node;\n }\n };\n}\n\n/** Compose a child handler with one from react-aria — both fire, child first. */\nfunction mergeHandler<E extends React.SyntheticEvent>(\n childHandler: ((e: E) => void) | undefined,\n ariaHandler: ((e: E) => void) | undefined,\n): ((e: E) => void) | undefined {\n if (!childHandler && !ariaHandler) return undefined;\n return (e: E) => {\n childHandler?.(e);\n if (!e.defaultPrevented) ariaHandler?.(e);\n };\n}\n\nexport function Tooltip({\n content,\n position = \"top\",\n delay = 200,\n offset = 8,\n disabled = false,\n id: providedId,\n children,\n className,\n}: TooltipProps) {\n const reactId = useId();\n const tooltipId = providedId ?? `ods-tooltip-${reactId}`;\n const triggerRef = useRef<HTMLElement>(null);\n const state = useTooltipTriggerState({ delay });\n const { triggerProps } = useTooltipTrigger(\n { delay, isDisabled: disabled },\n state,\n triggerRef,\n );\n\n if (!isValidElement(children)) {\n // Bail out gracefully — without a valid element child there's nothing\n // to clone props onto. Render the children as-is so we don't crash\n // consumer trees that pass a string by mistake.\n return <>{children}</>;\n }\n\n // Pull the existing ref + handlers off the child so we can compose them\n // with react-aria's. Without this merge the child loses its ref\n // (e.g. ref forwarding in a wrapped Button) and any user-supplied\n // onMouseEnter / onFocus etc. is silently overwritten.\n const childProps = children.props as ComponentPropsWithRef<\"button\"> &\n Record<string, unknown>;\n // React 19: `ref` is a regular prop on the child's props. We still\n // fall back to the legacy `element.ref` to support intermediates that\n // re-emit the older shape.\n const childRef =\n (childProps as { ref?: Ref<HTMLElement> }).ref ??\n (children as unknown as { ref?: Ref<HTMLElement> }).ref;\n\n // Merge every handler prop from react-aria with whatever the child\n // already had, so a child that passes its own onFocus/onMouseEnter\n // doesn't lose them when we attach the trigger props.\n const merged: Record<string, unknown> = { ...childProps };\n for (const [key, value] of Object.entries(\n triggerProps as Record<string, unknown>,\n )) {\n if (key.startsWith(\"on\") && typeof value === \"function\") {\n merged[key] = mergeHandler(\n childProps[key] as never,\n value as never,\n );\n } else {\n merged[key] = value;\n }\n }\n merged.ref = mergeRefs<HTMLElement>(triggerRef, childRef);\n merged[\"aria-describedby\"] =\n [childProps[\"aria-describedby\"], tooltipId].filter(Boolean).join(\" \");\n\n return (\n <>\n {cloneElement(children, merged)}\n {!disabled && (\n <TooltipContent\n state={state}\n content={content}\n position={position}\n triggerRef={triggerRef}\n offset={offset}\n className={className}\n tooltipId={tooltipId}\n />\n )}\n </>\n );\n}\n\nTooltip.displayName = \"Tooltip\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type SpinnerSize = \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type SpinnerTone =\n | \"accent\"\n | \"muted\"\n | \"primary\"\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"inverse\";\n\ntype SvgPropsBase = Omit<\n ComponentPropsWithoutRef<\"svg\">,\n \"color\" | \"viewBox\" | \"fill\" | \"size\"\n>;\n\nexport interface SpinnerProps extends SvgPropsBase {\n /** Keyword size OR custom pixel number. Default `\"md\"`. */\n size?: SpinnerSize | number;\n /** Token-driven colour. Defaults to `\"accent\"`. Consumers can also\n * set `color` directly via `style` if they need a one-off. */\n tone?: SpinnerTone;\n /** Accessible label. Default `\"Loading\"`. */\n label?: string;\n}\n\nconst SIZE_PX: Record<SpinnerSize, number> = {\n sm: 16,\n md: 24,\n lg: 32,\n xl: 48,\n};\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Spinner = forwardRef<SVGSVGElement, SpinnerProps>(function Spinner(\n {\n size = \"md\",\n tone = \"accent\",\n label = \"Loading\",\n className,\n style,\n ...rest\n },\n ref,\n) {\n const px = typeof size === \"number\" ? size : SIZE_PX[size];\n const isKeyword = typeof size === \"string\";\n\n return (\n <svg\n {...rest}\n ref={ref}\n className={cn(\n \"ods-spinner\",\n isKeyword && `ods-spinner--${size}`,\n `ods-spinner--${tone}`,\n className,\n )}\n width={px}\n height={px}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n role=\"status\"\n aria-label={label}\n style={style}\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeDasharray=\"31.4 31.4\"\n className=\"ods-spinner__circle\"\n />\n </svg>\n );\n});\n\nSpinner.displayName = \"Spinner\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useRef,\n} from \"react\";\nimport { useSwitch } from \"react-aria\";\nimport { useToggleState } from \"react-stately\";\nimport { getRenderableText, resolveAccessibleName } from \"../../utils/a11y\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type SwitchSize = \"sm\" | \"md\" | \"lg\";\n\ntype InputPropsBase = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"type\" | \"onChange\" | \"size\" | \"checked\" | \"defaultChecked\"\n>;\n\nexport interface SwitchProps extends InputPropsBase {\n checked?: boolean;\n defaultChecked?: boolean;\n onChange?: (isSelected: boolean) => void;\n disabled?: boolean;\n size?: SwitchSize;\n /** Visible label — accepts rich content. */\n label?: ReactNode;\n /** Optional sublabel rendered below the label. */\n description?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(\n {\n checked,\n defaultChecked,\n onChange,\n disabled = false,\n size = \"md\",\n label,\n description,\n className,\n ...props\n },\n forwardedRef,\n) {\n const innerRef = useRef<HTMLInputElement>(null);\n // Compose forwarded ref + internal ref so consumers can `.focus()`\n // while react-aria's plumbing still works.\n const setRef = (node: HTMLInputElement | null) => {\n (innerRef as { current: HTMLInputElement | null }).current = node;\n if (typeof forwardedRef === \"function\") forwardedRef(node);\n else if (forwardedRef)\n (forwardedRef as { current: HTMLInputElement | null }).current = node;\n };\n\n const state = useToggleState({\n isSelected: checked,\n defaultSelected: defaultChecked,\n onChange,\n });\n\n // Derive the accessible name from the label's TEXT — including a rich\n // ReactNode label (icon + text, custom JSX), not just a bare string. Without\n // this, a non-string `label` was dropped here and the switch tripped a false\n // \"no accessible name\" warning + a bogus aria-label=\"Unlabeled Switch\" that\n // overrode the real visible label. A genuinely nameless switch (no label,\n // no aria-*) still warns, which is correct.\n const labelText = getRenderableText(label).trim();\n const ariaNameProps = resolveAccessibleName({\n label: labelText || undefined,\n ariaLabel: (props as Record<string, unknown>)[\"aria-label\"] as\n | string\n | undefined,\n ariaLabelledby: (props as Record<string, unknown>)[\"aria-labelledby\"] as\n | string\n | undefined,\n componentName: \"Switch\",\n });\n\n const { inputProps } = useSwitch(\n {\n isSelected: state.isSelected,\n isDisabled: disabled,\n onChange,\n ...ariaNameProps,\n },\n state,\n innerRef,\n );\n\n const isOn = state.isSelected;\n\n // React Aria owns the interactive event handlers + aria-* on the\n // input. Strip them from the caller's props so we don't double-bind;\n // native form attrs (name/value/form/id/etc.) flow through.\n const {\n onClick: _onClick,\n onKeyDown: _onKeyDown,\n onKeyUp: _onKeyUp,\n onFocus: _onFocus,\n onBlur: _onBlur,\n ...passthroughProps\n } = props as Record<string, unknown>;\n\n return (\n <label\n className={cn(\n \"ods-switch\",\n `ods-switch--${size}`,\n disabled && \"ods-switch--disabled\",\n description && \"ods-switch--with-description\",\n className,\n )}\n >\n <input\n {...(passthroughProps as ComponentPropsWithoutRef<\"input\">)}\n {...inputProps}\n ref={setRef}\n className=\"ods-switch__input\"\n />\n <div\n className={cn(\"ods-switch__track\", isOn && \"ods-switch__track--on\")}\n aria-hidden=\"true\"\n >\n <div className=\"ods-switch__thumb\" />\n </div>\n {(label || description) && (\n <div className=\"ods-switch__text\">\n {label && <span className=\"ods-switch__label\">{label}</span>}\n {description && (\n <span className=\"ods-switch__description\">{description}</span>\n )}\n </div>\n )}\n </label>\n );\n});\n\nSwitch.displayName = \"Switch\";\n","\"use client\";\nimport { motion } from \"framer-motion\";\nimport { type ReactNode, useCallback, useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { useTab, useTabList, useTabPanel } from \"react-aria\";\nimport { Item, type TabListStateOptions, useTabListState } from \"react-stately\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface TabItem {\n value: string;\n label: string;\n icon?: ReactNode;\n disabled?: boolean;\n children?: ReactNode;\n}\n\nexport interface TabsProps {\n items: TabItem[];\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n orientation?: \"horizontal\" | \"vertical\";\n className?: string;\n}\n\n// Each Tabs instance gets its own layoutId via React's `useId()`. Without\n// the per-instance scope, multiple Tabs mounted on the same page share the\n// same shared layout group, which makes the indicator chase the most recent\n// re-mount (visually it \"disappears\" or jumps between tabs). The id is\n// forwarded into the indicator's `layoutId` so the animation is bounded.\nfunction TabButton({\n item,\n state,\n indicatorLayoutId,\n}: {\n item: any;\n state: any;\n indicatorLayoutId: string;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const { tabProps } = useTab({ key: item.key }, state, ref);\n const isSelected = state.selectedKey === item.key;\n const isDisabled = state.disabledKeys.has(item.key);\n\n // When a tab becomes selected (pointer OR keyboard), bring it fully into\n // view in the horizontally-scrollable strip — clicking a half-clipped or\n // last tab previously left it partly hidden behind the overflow edge.\n // `inline: \"nearest\"` no-ops when the tab is already fully visible, and\n // `block: \"nearest\"` keeps it from scrolling the surrounding page.\n useEffect(() => {\n // `scrollIntoView` is absent in jsdom (tests) — optional-chain the method\n // so the effect is a safe no-op there and in any non-DOM environment.\n if (isSelected) {\n ref.current?.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\" });\n }\n }, [isSelected]);\n\n // Remove motion-conflicting props\n const { onDrag, onDragStart, onDragEnd, onAnimationStart, ...safeTabProps } = tabProps as any;\n\n return (\n <motion.div\n {...safeTabProps}\n ref={ref}\n className={cn(\n \"ods-tabs__tab\",\n isSelected && \"ods-tabs__tab--selected\",\n isDisabled && \"ods-tabs__tab--disabled\",\n )}\n >\n {item.rendered}\n {isSelected && (\n <motion.div\n className={\"ods-tabs__indicator\"}\n layoutId={indicatorLayoutId}\n transition={{ type: \"spring\", damping: 30, stiffness: 400 }}\n />\n )}\n </motion.div>\n );\n}\n\nfunction TabPanelContent({ state, panelContent, ...props }: any) {\n const ref = useRef<HTMLDivElement>(null);\n const { tabPanelProps } = useTabPanel(props, state, ref);\n return (\n <div {...tabPanelProps} ref={ref} className={\"ods-tabs__panel\"}>\n {panelContent}\n </div>\n );\n}\n\n// Threshold below which we consider the strip \"fully scrolled\" — covers\n// fractional pixel rounding so chevrons hide cleanly at the ends.\nconst SCROLL_EDGE_EPSILON = 1;\n// Step size for the chevron buttons. ~200 px clears two or three average\n// tabs without overshooting on narrow strips.\nconst SCROLL_STEP_PX = 200;\n\nexport function Tabs({\n items,\n value,\n defaultValue,\n onChange,\n orientation = \"horizontal\",\n className,\n}: TabsProps) {\n const reactId = useId();\n const indicatorLayoutId = `ods-tabs-indicator-${reactId}`;\n const [internalValue, setInternalValue] = useState(defaultValue || items[0]?.value);\n const selectedKey = value ?? internalValue;\n\n const handleSelectionChange = (key: any) => {\n const keyStr = String(key);\n if (!value) setInternalValue(keyStr);\n onChange?.(keyStr);\n };\n\n // Build a map of value -> panel content\n const panelContentMap = useMemo(() => {\n const map = new Map<string, ReactNode>();\n items.forEach((item) => {\n map.set(item.value, item.children);\n });\n return map;\n }, [items]);\n\n const stateProps: TabListStateOptions<any> = {\n children: items.map((item) => (\n <Item key={item.value} textValue={item.label}>\n {item.icon && <span className={\"ods-tabs__icon\"}>{item.icon}</span>}\n <span>{item.label}</span>\n </Item>\n )),\n selectedKey,\n onSelectionChange: handleSelectionChange,\n disabledKeys: items.filter((i) => i.disabled).map((i) => i.value),\n };\n\n const state = useTabListState(stateProps);\n const ref = useRef<HTMLDivElement>(null);\n const { tabListProps } = useTabList({ ...stateProps, orientation }, state, ref);\n\n // ── Horizontal-overflow scroll ────────────────────────────────────────\n // When the tab strip is wider than its viewport (typical when the host\n // pins it inside a narrow column), we surface left/right chevron\n // buttons that programmatically scroll the strip. The native scrollbar\n // is hidden via SCSS so the chevrons remain the only affordance.\n //\n // We only enable the overflow chrome for horizontal orientation; the\n // vertical layout already scrolls naturally via the parent overflow.\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const measureOverflow = useCallback(() => {\n const el = scrollContainerRef.current;\n if (!el || orientation !== \"horizontal\") {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n const max = el.scrollWidth - el.clientWidth;\n setCanScrollLeft(el.scrollLeft > SCROLL_EDGE_EPSILON);\n setCanScrollRight(el.scrollLeft < max - SCROLL_EDGE_EPSILON);\n }, [orientation]);\n\n // Recompute on mount + when items change. The ResizeObserver covers the\n // case where the container itself resizes (responsive parent layouts).\n useEffect(() => {\n measureOverflow();\n const el = scrollContainerRef.current;\n if (!el || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => measureOverflow());\n ro.observe(el);\n return () => ro.disconnect();\n }, [items, measureOverflow]);\n\n const onScroll = () => measureOverflow();\n\n const scrollBy = (dir: -1 | 1) => {\n const el = scrollContainerRef.current;\n if (!el) return;\n el.scrollBy({ left: dir * SCROLL_STEP_PX, behavior: \"smooth\" });\n };\n\n const currentPanelContent = panelContentMap.get(String(selectedKey));\n\n return (\n <div className={cn(\"ods-tabs\", `ods-tabs--${orientation}`, className)}>\n <div className=\"ods-tabs__list-wrap\">\n {orientation === \"horizontal\" && canScrollLeft && (\n <button\n type=\"button\"\n className=\"ods-tabs__scroll-btn ods-tabs__scroll-btn--left\"\n onClick={() => scrollBy(-1)}\n aria-label=\"Scroll tabs left\"\n tabIndex={-1}\n >\n <ChevronSvg dir=\"left\" />\n </button>\n )}\n <div\n className=\"ods-tabs__scroller\"\n ref={scrollContainerRef}\n onScroll={orientation === \"horizontal\" ? onScroll : undefined}\n >\n <div {...tabListProps} ref={ref} className={\"ods-tabs__list\"}>\n {[...state.collection].map((item) => (\n <TabButton\n key={item.key}\n item={item}\n state={state}\n indicatorLayoutId={indicatorLayoutId}\n />\n ))}\n </div>\n </div>\n {orientation === \"horizontal\" && canScrollRight && (\n <button\n type=\"button\"\n className=\"ods-tabs__scroll-btn ods-tabs__scroll-btn--right\"\n onClick={() => scrollBy(1)}\n aria-label=\"Scroll tabs right\"\n tabIndex={-1}\n >\n <ChevronSvg dir=\"right\" />\n </button>\n )}\n </div>\n <TabPanelContent key={state.selectedKey} state={state} panelContent={currentPanelContent} />\n </div>\n );\n}\n\nfunction ChevronSvg({ dir }: { dir: \"left\" | \"right\" }) {\n // Inline chevron; rotates via CSS-friendly `d` so we don't need to ship\n // an icon dep just for the scroll chrome.\n const d = dir === \"left\" ? \"M11 4L5 10l6 6\" : \"M9 4l6 6-6 6\";\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d={d} />\n </svg>\n );\n}\n","/* ---------------------------------------------------------------------------\n * HttpActionPanel engine — config model + pure logic, no React.\n *\n * The config shape is wire-compatible with the engine's HTTP action: hosts\n * can mount the panel on an existing step config with zero migration. All\n * behavior that can be tested without a DOM lives here: normalization,\n * validation, cURL import/export, effective-URL assembly and response\n * schema inference.\n * ------------------------------------------------------------------------- */\n\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"HEAD\" | \"OPTIONS\";\n\nexport const HTTP_METHODS: HttpMethod[] = [\n \"GET\",\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\",\n \"HEAD\",\n \"OPTIONS\",\n];\n\nexport interface HttpKeyValue {\n key: string;\n value: string;\n description?: string;\n enabled?: boolean;\n}\n\nexport interface HttpAuthConfig {\n type: \"none\" | \"basic\" | \"bearer\" | \"apikey\";\n username?: string;\n password?: string;\n token?: string;\n apiKeyName?: string;\n apiKeyValue?: string;\n apiKeyLocation?: \"header\" | \"query\";\n}\n\nexport interface HttpRetryConfig {\n maxAttempts: number;\n retryOn: number[];\n initialDelayMs: number;\n backoffFactor: number;\n maxDelayMs: number;\n}\n\nexport type HttpPaginationType = \"none\" | \"offset\" | \"cursor\" | \"link_header\" | \"next_url\";\n\nexport interface HttpPaginationConfig {\n type: HttpPaginationType;\n limitParam?: string;\n limitValue?: number;\n offsetParam?: string;\n cursorResponsePath?: string;\n cursorRequestParam?: string;\n nextUrlResponsePath?: string;\n maxPages?: number;\n mergeKey?: string;\n}\n\nexport type HttpBodyType = \"none\" | \"json\" | \"raw\" | \"form-data\" | \"xml\";\nexport type HttpResponseType = \"json\" | \"text\" | \"binary\";\n\nexport interface HttpActionConfig {\n /** Saved API connection to inherit base URL + auth from. */\n connectionId?: string;\n /** \"graphql\" flags the GraphQL body mode (engine-compatible). */\n apiType?: \"rest\" | \"graphql\";\n method?: HttpMethod;\n baseUrl?: string;\n url: string;\n queryParams?: HttpKeyValue[];\n headers?: HttpKeyValue[] | Record<string, string>;\n bodyType?: HttpBodyType;\n body?: unknown;\n formData?: HttpKeyValue[];\n graphqlQuery?: string;\n graphqlVariables?: Record<string, unknown> | string;\n auth?: HttpAuthConfig;\n timeout?: number;\n failOnError?: boolean;\n followRedirects?: boolean;\n retry?: HttpRetryConfig;\n pagination?: HttpPaginationConfig;\n extract?: Record<string, string>;\n responseType?: HttpResponseType;\n expectedContentTypes?: string[];\n /** Inferred response schema (written after a successful test send). */\n _outputSchema?: unknown;\n}\n\nexport const HTTP_ACTION_DEFAULTS: HttpActionConfig = {\n apiType: \"rest\",\n method: \"GET\",\n url: \"\",\n queryParams: [],\n headers: [],\n bodyType: \"json\",\n formData: [],\n graphqlQuery: \"\",\n graphqlVariables: {},\n auth: { type: \"none\" },\n timeout: 30000,\n failOnError: true,\n followRedirects: true,\n retry: {\n maxAttempts: 1,\n retryOn: [429, 500, 502, 503, 504],\n initialDelayMs: 1000,\n backoffFactor: 2,\n maxDelayMs: 30000,\n },\n pagination: { type: \"none\" },\n extract: {},\n responseType: \"json\",\n expectedContentTypes: [],\n};\n\n/* ── Normalization ─────────────────────────────────────────────────────── */\n\n/** Array-or-record key/values → uniform array. */\nexport function normalizeKeyValues(raw: unknown): HttpKeyValue[] {\n if (Array.isArray(raw)) {\n return raw.map((r) => ({\n key: String((r as HttpKeyValue).key ?? \"\"),\n value: String((r as HttpKeyValue).value ?? \"\"),\n description: (r as HttpKeyValue).description,\n enabled: (r as HttpKeyValue).enabled !== false,\n }));\n }\n if (raw && typeof raw === \"object\") {\n return Object.entries(raw as Record<string, string>).map(([key, value]) => ({\n key,\n value: String(value),\n enabled: true,\n }));\n }\n return [];\n}\n\n/**\n * Normalize a persisted auth blob. The legacy inline \"oauth2\" type was only\n * ever a pasted static token (identical to bearer) — map it to bearer,\n * preserving tokens stored as `accessToken`. The engine keeps its alias\n * branch, so the wire output for legacy nodes is unchanged.\n */\nexport function normalizeAuth(raw: unknown): HttpAuthConfig {\n const r = (raw ?? {}) as Record<string, unknown>;\n const rawType = (r.type as string) ?? \"none\";\n const type = (rawType === \"oauth2\" ? \"bearer\" : rawType) as HttpAuthConfig[\"type\"];\n return {\n type: [\"none\", \"basic\", \"bearer\", \"apikey\"].includes(type) ? type : \"none\",\n username: (r.username as string) ?? \"\",\n password: (r.password as string) ?? \"\",\n token: ((r.token ?? r.accessToken) as string) ?? \"\",\n apiKeyName: (r.apiKeyName as string) ?? \"X-API-Key\",\n apiKeyValue: (r.apiKeyValue as string) ?? \"\",\n apiKeyLocation: r.apiKeyLocation === \"query\" ? \"query\" : \"header\",\n };\n}\n\n/** Base + path → full URL (\"https://a.com/\" + \"/v1\" → \"https://a.com/v1\"). */\nexport function effectiveUrl(baseUrl: string | undefined, url: string): string {\n const base = (baseUrl ?? \"\").trim();\n if (!base) return url;\n return `${base.replace(/\\/$/, \"\")}/${url.replace(/^\\//, \"\")}`;\n}\n\n/** Serialize KV rows for persistence, dropping fully empty rows. */\nexport function serializeKeyValues(rows: HttpKeyValue[]): HttpKeyValue[] {\n return rows\n .filter((r) => r.key || r.value)\n .map((r) => ({\n key: r.key,\n value: r.value,\n enabled: r.enabled !== false,\n ...(r.description ? { description: r.description } : {}),\n }));\n}\n\n/* ── Validation ────────────────────────────────────────────────────────── */\n\nexport interface HttpValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nexport function validateHttpConfig(config: Partial<HttpActionConfig>): HttpValidationResult {\n const errors: string[] = [];\n const apiType = config.apiType ?? \"rest\";\n if (apiType === \"rest\" && !config.method) errors.push(\"Method is required\");\n if (apiType === \"graphql\" && !String(config.graphqlQuery ?? \"\").trim()) {\n errors.push(\"GraphQL query is required\");\n }\n const hasConnection = Boolean(config.connectionId);\n if (!config.url && !hasConnection) {\n errors.push(\"URL is required\");\n } else if (config.url && !hasConnection && !config.baseUrl && !config.url.includes(\"{{\")) {\n try {\n new URL(config.url);\n } catch {\n errors.push(\"Invalid URL format\");\n }\n }\n if (typeof config.timeout === \"number\" && config.timeout < 1000) {\n errors.push(\"Timeout must be at least 1000ms\");\n }\n return { valid: errors.length === 0, errors };\n}\n\n/** Number of distinct `$variables` declared in a GraphQL document. */\nexport function countGraphqlVariables(query: string): number {\n return new Set(query.match(/\\$[A-Za-z_][A-Za-z0-9_]*/g) ?? []).size;\n}\n\n/* ── cURL import / export ──────────────────────────────────────────────── */\n\n/** Split a shell command into tokens, honoring single/double quotes. */\nfunction shellTokens(input: string): string[] {\n const tokens: string[] = [];\n // Strip line continuations first so multi-line cURL pastes flatten.\n const flat = input.replace(/\\\\\\r?\\n/g, \" \");\n const re = /'([^']*)'|\"((?:[^\"\\\\]|\\\\.)*)\"|(\\S+)/g;\n let m: RegExpExecArray | null = re.exec(flat);\n while (m !== null) {\n if (m[1] !== undefined) tokens.push(m[1]);\n else if (m[2] !== undefined) tokens.push(m[2].replace(/\\\\([\"\\\\])/g, \"$1\"));\n else tokens.push(m[3]);\n m = re.exec(flat);\n }\n return tokens;\n}\n\n/**\n * Parse a pasted cURL command into a config patch. Returns null when the\n * input is not a cURL invocation. Understands the flags people actually\n * paste: -X/--request, --url, -H/--header, -d/--data(-raw/-binary/\n * -urlencode), -F/--form, -u/--user, -L, -k, --compressed (ignored).\n */\nexport function parseCurl(input: string): Partial<HttpActionConfig> | null {\n const tokens = shellTokens(input.trim());\n if (!tokens.length || !/^curl$/i.test(tokens[0])) return null;\n\n let method: HttpMethod | undefined;\n let url = \"\";\n const headers: HttpKeyValue[] = [];\n const formData: HttpKeyValue[] = [];\n let bodyRaw: string | undefined;\n let basicUser: string | undefined;\n let followRedirects: boolean | undefined;\n\n for (let i = 1; i < tokens.length; i++) {\n const t = tokens[i];\n const next = () => tokens[++i] ?? \"\";\n if (t === \"-X\" || t === \"--request\") {\n const m = next().toUpperCase();\n if ((HTTP_METHODS as string[]).includes(m)) method = m as HttpMethod;\n } else if (t === \"-H\" || t === \"--header\") {\n const raw = next();\n const idx = raw.indexOf(\":\");\n if (idx > 0) {\n headers.push({\n key: raw.slice(0, idx).trim(),\n value: raw.slice(idx + 1).trim(),\n enabled: true,\n });\n }\n } else if (\n t === \"-d\" ||\n t === \"--data\" ||\n t === \"--data-raw\" ||\n t === \"--data-binary\" ||\n t === \"--data-urlencode\"\n ) {\n bodyRaw = next();\n } else if (t === \"-F\" || t === \"--form\") {\n const raw = next();\n const idx = raw.indexOf(\"=\");\n if (idx > 0) {\n formData.push({ key: raw.slice(0, idx), value: raw.slice(idx + 1), enabled: true });\n }\n } else if (t === \"-u\" || t === \"--user\") {\n basicUser = next();\n } else if (t === \"--url\") {\n url = next();\n } else if (t === \"-L\" || t === \"--location\") {\n followRedirects = true;\n } else if (t.startsWith(\"-\")) {\n // Flags with an argument we don't map — skip their value so it isn't\n // mistaken for the URL.\n if (\n [\n \"-o\",\n \"--output\",\n \"-A\",\n \"--user-agent\",\n \"-e\",\n \"--referer\",\n \"-b\",\n \"--cookie\",\n \"--connect-timeout\",\n \"-m\",\n \"--max-time\",\n ].includes(t)\n ) {\n next();\n }\n // Bare boolean flags (-s, -k, --compressed, …) need nothing.\n } else if (!url) {\n url = t;\n }\n }\n\n if (!url) return null;\n\n const patch: Partial<HttpActionConfig> = { url, apiType: \"rest\" };\n\n // Split query string into queryParams so the panel shows them structured.\n const qIdx = url.indexOf(\"?\");\n if (qIdx >= 0) {\n const query = url.slice(qIdx + 1);\n patch.url = url.slice(0, qIdx);\n patch.queryParams = query\n .split(\"&\")\n .filter(Boolean)\n .map((pair) => {\n const eq = pair.indexOf(\"=\");\n const rawKey = eq >= 0 ? pair.slice(0, eq) : pair;\n const rawValue = eq >= 0 ? pair.slice(eq + 1) : \"\";\n const decode = (s: string) => {\n try {\n return decodeURIComponent(s.replace(/\\+/g, \"%20\"));\n } catch {\n return s;\n }\n };\n return { key: decode(rawKey), value: decode(rawValue), enabled: true };\n });\n }\n\n // Auth: Authorization header → bearer; -u → basic. The header row is\n // consumed by the auth config rather than kept as a plain header.\n const authHeaderIdx = headers.findIndex((h) => h.key.toLowerCase() === \"authorization\");\n if (authHeaderIdx >= 0 && /^bearer\\s+/i.test(headers[authHeaderIdx].value)) {\n patch.auth = {\n type: \"bearer\",\n token: headers[authHeaderIdx].value.replace(/^bearer\\s+/i, \"\"),\n };\n headers.splice(authHeaderIdx, 1);\n } else if (basicUser) {\n const sep = basicUser.indexOf(\":\");\n patch.auth = {\n type: \"basic\",\n username: sep >= 0 ? basicUser.slice(0, sep) : basicUser,\n password: sep >= 0 ? basicUser.slice(sep + 1) : \"\",\n };\n }\n\n if (headers.length) patch.headers = headers;\n if (followRedirects !== undefined) patch.followRedirects = followRedirects;\n\n if (formData.length) {\n patch.bodyType = \"form-data\";\n patch.formData = formData;\n patch.method = method ?? \"POST\";\n } else if (bodyRaw !== undefined) {\n try {\n patch.body = JSON.parse(bodyRaw);\n patch.bodyType = \"json\";\n } catch {\n patch.body = bodyRaw;\n patch.bodyType = \"raw\";\n }\n patch.method = method ?? \"POST\";\n } else {\n patch.method = method ?? \"GET\";\n patch.bodyType = \"none\";\n }\n\n return patch;\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/** Build a copy-pastable cURL command from the current config. */\nexport function buildCurl(config: HttpActionConfig): string {\n const parts: string[] = [\"curl\"];\n const method = config.apiType === \"graphql\" ? \"POST\" : (config.method ?? \"GET\");\n if (method !== \"GET\") parts.push(`-X ${method}`);\n\n let url = effectiveUrl(config.baseUrl, config.url);\n const params = normalizeKeyValues(config.queryParams).filter((p) => p.enabled !== false && p.key);\n if (params.length) {\n const qs = params\n .map((p) => `${encodeURIComponent(p.key)}=${encodeURIComponent(p.value)}`)\n .join(\"&\");\n url += (url.includes(\"?\") ? \"&\" : \"?\") + qs;\n }\n parts.push(shellQuote(url));\n\n for (const h of normalizeKeyValues(config.headers).filter((h) => h.enabled !== false && h.key)) {\n parts.push(`-H ${shellQuote(`${h.key}: ${h.value}`)}`);\n }\n\n const auth = config.auth;\n if (auth?.type === \"bearer\" && auth.token) {\n parts.push(`-H ${shellQuote(`Authorization: Bearer ${auth.token}`)}`);\n } else if (auth?.type === \"basic\" && auth.username) {\n parts.push(`-u ${shellQuote(`${auth.username}:${auth.password ?? \"\"}`)}`);\n } else if (auth?.type === \"apikey\" && auth.apiKeyName && auth.apiKeyValue) {\n if ((auth.apiKeyLocation ?? \"header\") === \"header\") {\n parts.push(`-H ${shellQuote(`${auth.apiKeyName}: ${auth.apiKeyValue}`)}`);\n }\n }\n\n if (config.apiType === \"graphql\") {\n const payload = JSON.stringify({\n query: config.graphqlQuery ?? \"\",\n variables:\n typeof config.graphqlVariables === \"string\"\n ? config.graphqlVariables\n : (config.graphqlVariables ?? {}),\n });\n parts.push(`-H ${shellQuote(\"Content-Type: application/json\")}`);\n parts.push(`-d ${shellQuote(payload)}`);\n } else if (config.bodyType === \"form-data\") {\n for (const f of normalizeKeyValues(config.formData).filter(\n (f) => f.enabled !== false && f.key,\n )) {\n parts.push(`-F ${shellQuote(`${f.key}=${f.value}`)}`);\n }\n } else if (config.bodyType && config.bodyType !== \"none\" && config.body != null) {\n const raw = typeof config.body === \"string\" ? config.body : JSON.stringify(config.body);\n if (raw) {\n if (config.bodyType === \"json\") {\n parts.push(`-H ${shellQuote(\"Content-Type: application/json\")}`);\n }\n parts.push(`-d ${shellQuote(raw)}`);\n }\n }\n\n if (config.followRedirects !== false) parts.push(\"-L\");\n return parts.join(\" \");\n}\n\n/* ── Response schema inference ─────────────────────────────────────────── */\n\ninterface InferredSchema {\n type: string;\n properties?: Record<string, InferredSchema>;\n items?: InferredSchema;\n}\n\n/** JSON-schema-shaped inference from a sample value (depth-capped). */\nexport function inferJsonSchema(value: unknown, depth = 0): InferredSchema {\n if (value === null || value === undefined) return { type: \"null\" };\n if (Array.isArray(value)) {\n if (!value.length || depth > 6) return { type: \"array\" };\n return { type: \"array\", items: inferJsonSchema(value[0], depth + 1) };\n }\n if (typeof value === \"object\") {\n if (depth > 6) return { type: \"object\" };\n const properties: Record<string, InferredSchema> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n properties[k] = inferJsonSchema(v, depth + 1);\n }\n return { type: \"object\", properties };\n }\n return { type: typeof value };\n}\n\n/** Count leaf+branch paths in an inferred schema (for the schema badge). */\nexport function countSchemaPaths(schema: unknown, depth = 0): number {\n if (!schema || typeof schema !== \"object\" || depth > 8) return 0;\n const s = schema as InferredSchema;\n let count = 0;\n if (s.type === \"object\" && s.properties) {\n for (const child of Object.values(s.properties)) {\n count += 1 + countSchemaPaths(child, depth + 1);\n }\n } else if (s.type === \"array\" && s.items) {\n count += countSchemaPaths(s.items, depth + 1);\n }\n return count;\n}\n\n/* ── Test-send (preview) contract ──────────────────────────────────────── */\n\nexport interface HttpPreviewRequest {\n method: HttpMethod;\n url: string;\n connectionId?: string;\n headers: HttpKeyValue[];\n queryParams: HttpKeyValue[];\n bodyType: HttpBodyType;\n body?: string;\n formData?: HttpKeyValue[];\n graphqlQuery?: string;\n graphqlVariables?: string;\n auth: HttpAuthConfig;\n timeout: number;\n}\n\nexport interface HttpPreviewResponse {\n status: number;\n statusText: string;\n ok: boolean;\n headers: Record<string, string>;\n /** Parsed body (object for JSON) or raw string; binary hosts pass metadata only. */\n body: unknown;\n bodyRaw?: string;\n /** Response size in bytes. */\n size: number;\n /** Round-trip time in ms. */\n duration: number;\n}\n\nexport function statusTone(status: number): \"success\" | \"info\" | \"warning\" | \"error\" {\n if (status < 300) return \"success\";\n if (status < 400) return \"info\";\n if (status < 500) return \"warning\";\n return \"error\";\n}\n\nexport function formatBytes(size: number): string {\n return size < 1024 ? `${size} B` : `${(size / 1024).toFixed(1)} KB`;\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FlowCanvas v2 — the editor kernel.\n// ════════════════════════════════════════════════════════════════════════\n// Responsibilities:\n// 1. Mount the per-canvas store + handle registry; provide their contexts.\n// 2. Render the viewport (transform: translate(x,y) scale(zoom)).\n// 3. Own Pointer Events for pan, zoom, drag, and connect; route to the\n// right middleware via a single pointermove handler installed on the\n// window during an active gesture.\n// 4. Emit batched onNodesChange / onEdgesChange / onConnect / ...\n// 5. Mirror controlled `nodes` / `edges` props into the store each render\n// so descendants read fresh data via selectors.\n\nimport {\n type CSSProperties,\n memo,\n type PointerEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type WheelEvent,\n} from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport type {\n ConnectEndState,\n Connection,\n ConnectStartParams,\n EdgeChange,\n NodeChange,\n Position,\n Viewport,\n WorkflowEdge,\n WorkflowNode,\n} from \"../../editor\";\nimport { type FlowInstance, FlowInstanceContext } from \"../../hooks/useFlow\";\nimport { change } from \"../../store/changes\";\nimport { FlowStoreContext } from \"../../store/context\";\nimport { createFlowStore } from \"../../store/createFlowStore\";\nimport { resolveNodeCollisions } from \"../../utils/collision\";\nimport {\n DEFAULT_NODE_HEIGHT,\n DEFAULT_NODE_WIDTH,\n effectiveHeight,\n flowToScreen,\n handleCentre,\n screenToFlow,\n} from \"../../utils/geometry\";\nimport {\n clampToParentExtent,\n descendantsOf,\n findContainingGroup,\n isContainerType,\n} from \"../../utils/parenting\";\nimport { FlowEdge } from \"../FlowEdge/FlowEdge\";\nimport { FlowNode } from \"../FlowNode/FlowNode\";\nimport { buildNodeKindRegistry, type NodeKindRegistry } from \"../FlowNode/nodeKinds\";\nimport {\n createHandleRegistry,\n type HandleDescriptor,\n HandleRegistryContext,\n} from \"../Handle/handleRegistry\";\nimport { type BuiltInNodeData, DEFAULT_NODE_KINDS } from \"../kinds\";\nimport {\n type FlowDispatch,\n type FlowDispatchAction,\n FlowDispatchContext,\n type FlowNodeBridge,\n FlowNodeBridgeContext,\n} from \"./FlowCanvasContext\";\n\nexport interface FlowCanvasProps {\n nodes: WorkflowNode[];\n edges: WorkflowEdge[];\n onNodesChange?: (changes: NodeChange[]) => void;\n onEdgesChange?: (changes: EdgeChange[]) => void;\n\n // Viewport\n viewport?: Viewport;\n defaultViewport?: Viewport;\n onViewportChange?: (viewport: Viewport) => void;\n minZoom?: number;\n maxZoom?: number;\n /**\n * Auto-frame the existing nodes on first mount so the canvas opens\n * centered on content rather than at the {0,0,1} origin. Defaults to\n * `true` when no explicit `viewport` or `defaultViewport` is supplied;\n * when the consumer pins either prop the canvas honours that and skips\n * the auto-fit. Pass `false` to opt out unconditionally. Pass\n * `{ padding, minZoom, maxZoom }` to tune the framing.\n */\n fitViewOnInit?: boolean | { padding?: number; minZoom?: number; maxZoom?: number };\n\n // Node kinds\n nodeKinds?: NodeKindRegistry;\n\n // Connection\n onConnect?: (connection: Connection) => void;\n onConnectStart?: (\n event: PointerEvent | globalThis.PointerEvent,\n params: ConnectStartParams,\n ) => void;\n onConnectEnd?: (event: PointerEvent | globalThis.PointerEvent, state: ConnectEndState) => void;\n isValidConnection?: (connection: Connection) => boolean;\n\n // Selection\n onSelectionChange?: (selection: { nodes: WorkflowNode[]; edges: WorkflowEdge[] }) => void;\n onPaneClick?: () => void;\n onNodeClick?: (node: WorkflowNode) => void;\n onEdgeClick?: (edge: WorkflowEdge) => void;\n /** Double-clicking an edge label opens an inline editor; commit fires\n * this callback. When omitted, labels are not editable. */\n onEdgeLabelChange?: (id: string, label: string) => void;\n /** Fires once when the canvas mounts. Hand-off for the imperative\n * instance — consumers store it to call `fitView`, `addNodes`, etc. */\n onInit?: (instance: FlowInstance) => void;\n /** Async veto for deletions. Return `false` (or a Promise resolving\n * false) to block. Fires from `instance.deleteElements`, Backspace,\n * and the edge X button. */\n onBeforeDelete?: (params: {\n nodes: WorkflowNode[];\n edges: WorkflowEdge[];\n }) => boolean | Promise<boolean>;\n /** Right-click on a node. Consumer must `preventDefault()` to suppress\n * the browser's native menu. */\n onNodeContextMenu?: (event: React.MouseEvent, node: WorkflowNode) => void;\n /** Right-click on an edge. */\n onEdgeContextMenu?: (event: React.MouseEvent, edge: WorkflowEdge) => void;\n /** Right-click on the empty pane. */\n onPaneContextMenu?: (event: React.MouseEvent) => void;\n\n // Policies\n nodesDraggable?: boolean;\n nodesConnectable?: boolean;\n panOnDrag?: boolean;\n zoomOnScroll?: boolean;\n /**\n * Trackpad / touch behaviour preset.\n *\n * - `\"mouse\"` (default): mouse-first. Drag the pane to pan;\n * wheel zooms; pinch zooms.\n * - `\"trackpad\"`: two-finger trackpad scroll pans; pinch zooms;\n * wheel-with-Ctrl zooms. Drag the pane is still pan (`panOnDrag`).\n * - `\"touch\"`: same as trackpad but with enlarged hit areas (44 px\n * on coarse pointers via `@media (pointer: coarse)`) and no pan\n * on plain drag — single-finger drag selects, two-finger pans.\n *\n * Override individual policies (`panOnDrag`, `zoomOnScroll`, etc.)\n * after picking a preset to fine-tune.\n */\n preset?: \"mouse\" | \"trackpad\" | \"touch\";\n /** Pixels of pointer travel during a pane-press before it stops counting\n * as a click (used to decide whether to clear selection on pointerup). */\n paneClickDistance?: number;\n /**\n * Whether a click on the empty canvas pane clears the current node /\n * edge selection. Defaults to `true` (the design-tool standard:\n * \"click background to deselect\"). Set to `false` when selection\n * should persist through pane clicks — e.g. when a side ConfigPanel\n * stays open until the user dismisses it explicitly.\n *\n * `onPaneClick` still fires regardless; this only controls whether\n * the canvas also clears its internal selection state.\n */\n paneClickClearsSelection?: boolean;\n\n // Visual canvas options\n /** Background grid style. Defaults to `\"dots\"`. */\n background?: \"dots\" | \"lines\" | \"cross\" | \"none\";\n /** Grid pitch in flow-space pixels. Defaults to 20. Also used for snap. */\n gridSize?: number;\n /** Snap node positions to the grid on drag-end. Defaults to false. */\n snapToGrid?: boolean;\n /**\n * Minimum gap (px) between sibling nodes during drag. When >= 0, a\n * dragged node is \"magnet snapped\" so it stays at least `nodeCollisionGap`\n * pixels from every other sibling — siblings share the same `parentId`\n * (or are both top-level). `0` means \"no overlap allowed, zero buffer.\"\n * Pass `-1` (the default) to disable collision avoidance entirely.\n */\n nodeCollisionGap?: number;\n /**\n * Same as `nodeCollisionGap` but applied to subflow containers\n * (`isContainerType` — i.e. `group`; `forEach` is a simple node). Lets you\n * keep groups visually separated without applying the rule to the action\n * nodes inside. Default falls back to `nodeCollisionGap`.\n */\n subflowCollisionGap?: number;\n\n /**\n * When `true`, dragging a node into another container's bbox sets\n * the dragged node's `parentId`; dragging out clears it — without\n * requiring the Alt modifier key. Default `false` preserves the\n * legacy Alt-drag-to-reparent behaviour for backward compatibility.\n *\n * Pairs with `autoResizeContainers` to deliver the full \"drop nodes\n * inside a group\" UX consumers usually want from a subflow editor.\n */\n reparentOnDrag?: boolean;\n\n /**\n * When `true`, container kinds (`group` / `forEach`) auto-resize at\n * drag-end so the frame encloses all current children plus padding.\n * The reposition + dimension update is folded into the same\n * `onNodesChange` call as the drag-end position change, so a child\n * dropped near the edge of a container can't miss the parent's\n * post-resize bbox in a follow-up render tick (the host-side race\n * the parented-on-drop UX would otherwise hit).\n *\n * Default `false`. Pair with `reparentOnDrag` for the full flow.\n */\n autoResizeContainers?: boolean;\n\n /**\n * Padding (in flow-space pixels) added around children's bbox when\n * `autoResizeContainers` recomputes a container's frame. Default 32.\n */\n containerAutoResizePadding?: number;\n\n /**\n * Floor size for `autoResizeContainers`. A container that fits its\n * children in less than this stops shrinking here — it never collapses\n * below the size a freshly-dropped (empty) container would have.\n * Defaults: 320 × 200.\n */\n containerMinWidth?: number;\n containerMinHeight?: number;\n\n // Layout\n height?: number | string;\n width?: number | string;\n className?: string;\n style?: CSSProperties;\n children?: ReactNode;\n emptyState?: ReactNode;\n}\n\nconst DEFAULT_VIEWPORT: Viewport = { x: 0, y: 0, zoom: 1 };\n\nexport function FlowCanvas(props: FlowCanvasProps) {\n // Capture whether the consumer explicitly handed us either viewport\n // prop. We can't tell from the destructured value alone (the default\n // assignment below would obscure an undefined explicit pass), and the\n // auto-fit fallback needs to know \"did the consumer pin the viewport,\n // or are we free to frame the nodes?\".\n const viewportPropProvided = props.viewport !== undefined || props.defaultViewport !== undefined;\n const {\n nodes,\n edges,\n onNodesChange,\n onEdgesChange,\n viewport: controlledViewport,\n defaultViewport = DEFAULT_VIEWPORT,\n onViewportChange,\n minZoom = 0.25,\n maxZoom = 2,\n fitViewOnInit,\n nodeKinds,\n onConnect,\n onConnectStart,\n onConnectEnd,\n isValidConnection,\n onSelectionChange,\n onPaneClick,\n onNodeClick,\n onEdgeClick,\n onEdgeLabelChange,\n onInit,\n onBeforeDelete,\n onNodeContextMenu,\n onEdgeContextMenu,\n onPaneContextMenu,\n nodesDraggable = true,\n nodesConnectable = true,\n panOnDrag: panOnDragProp,\n zoomOnScroll: zoomOnScrollProp,\n preset = \"mouse\",\n paneClickDistance = 4,\n paneClickClearsSelection = true,\n background = \"dots\",\n gridSize = 20,\n snapToGrid = false,\n nodeCollisionGap = -1,\n subflowCollisionGap,\n reparentOnDrag = false,\n autoResizeContainers = false,\n containerAutoResizePadding = 32,\n containerMinWidth = 320,\n containerMinHeight = 200,\n height = \"100%\",\n width = \"100%\",\n className,\n style,\n children,\n emptyState,\n } = props;\n // Resolve the preset defaults — individual props override. The presets\n // map to the documented interaction modes:\n // - mouse: pan-on-drag, wheel zoom\n // - trackpad: pan-on-drag still on (so users can grab the pane), but\n // two-finger trackpad scroll also pans (translated as wheel delta);\n // pinch zooms; wheel-zoom remains on for Ctrl+scroll.\n // - touch: drag the pane = box-select intent, no auto-pan\n // (single-finger drag is reserved for selection on touch surfaces).\n const presetDefaults = {\n mouse: { panOnDrag: true, zoomOnScroll: true },\n trackpad: { panOnDrag: true, zoomOnScroll: true },\n touch: { panOnDrag: false, zoomOnScroll: true },\n } as const;\n const panOnDrag = panOnDragProp ?? presetDefaults[preset].panOnDrag;\n const zoomOnScroll = zoomOnScrollProp ?? presetDefaults[preset].zoomOnScroll;\n\n // ── Singletons that live for the lifetime of this canvas ──\n const store = useState(() =>\n createFlowStore({\n initialNodes: nodes,\n initialEdges: edges,\n initialViewport: controlledViewport ?? defaultViewport,\n }),\n )[0];\n const handleRegistry = useState(() => createHandleRegistry())[0];\n\n // Subscribe to handle (un)registrations. Each Handle's `useEffect`\n // commits AFTER the surrounding render, so edges rendered in the same\n // commit as a node remount (typical for subflow collapse/uncollapse)\n // resolve against a stale registry and fall back to default ports.\n // Bumping this counter forces a follow-up render once the effects fire.\n const [handleVersion, setHandleVersion] = useState(0);\n useEffect(() => {\n const unsub = handleRegistry.subscribe(() => {\n setHandleVersion((v) => v + 1);\n });\n return unsub;\n }, [handleRegistry]);\n\n // Merge built-in kinds with consumer overrides. Frozen so consumers\n // can't mutate the registry mid-flight.\n const kinds = useMemo(() => buildNodeKindRegistry(DEFAULT_NODE_KINDS, nodeKinds), [nodeKinds]);\n\n const containerRef = useRef<HTMLDivElement>(null);\n\n // ── Mirror controlled props → store ───────────────────────────────────\n useEffect(() => store.setNodes(nodes), [store, nodes]);\n useEffect(() => store.setEdges(edges), [store, edges]);\n\n // ── Viewport (controlled or uncontrolled) ─────────────────────────────\n const [uncontrolledVp, setUncontrolledVp] = useState(controlledViewport ?? defaultViewport);\n const viewport = controlledViewport ?? uncontrolledVp;\n useEffect(() => store.setViewport(viewport), [store, viewport]);\n const setViewport = useCallback(\n (next: Viewport) => {\n if (controlledViewport === undefined) setUncontrolledVp(next);\n onViewportChange?.(next);\n },\n [controlledViewport, onViewportChange],\n );\n\n // ── Selection — derived from `node.selected` / `edge.selected` in props.\n // We do NOT keep a parallel ref because that would drift the moment a\n // consumer set a node.selected = true via their own state. The single\n // source of truth is the props.\n const selectedNodeIds = useMemo(() => {\n const s = new Set<string>();\n for (const n of nodes) if (n.selected) s.add(n.id);\n return s;\n }, [nodes]);\n const selectedEdgeIds = useMemo(() => {\n const s = new Set<string>();\n for (const e of edges) if (e.selected) s.add(e.id);\n return s;\n }, [edges]);\n\n // Sync resolved selection into the store so descendants can read it.\n useEffect(() => {\n store.setSelection(selectedNodeIds, selectedEdgeIds);\n if (onSelectionChange) {\n onSelectionChange({\n nodes: nodes.filter((n) => selectedNodeIds.has(n.id)),\n edges: edges.filter((e) => selectedEdgeIds.has(e.id)),\n });\n }\n }, [store, selectedNodeIds, selectedEdgeIds, nodes, edges, onSelectionChange]);\n\n // Selection state only — does NOT fire `onNodeClick`. The click event\n // is dispatched separately from the click path in FlowNode, so drag\n // starts (which need to select the node so it carries selection styles)\n // don't accidentally fire the consumer's click handler.\n const selectNode = useCallback(\n (id: string, additive: boolean) => {\n const next: NodeChange[] = [];\n const nextEdges: EdgeChange[] = [];\n if (!additive) {\n for (const n of nodes) {\n if (n.selected && n.id !== id) next.push(change.node.select(n.id, false));\n }\n for (const e of edges) {\n if (e.selected) nextEdges.push(change.edge.select(e.id, false));\n }\n }\n const isSelected = selectedNodeIds.has(id);\n if (additive && isSelected) {\n // Toggle off when meta-clicking an already-selected node.\n next.push(change.node.select(id, false));\n } else if (!isSelected) {\n next.push(change.node.select(id, true));\n }\n if (next.length) onNodesChange?.(next);\n if (nextEdges.length) onEdgesChange?.(nextEdges);\n },\n [nodes, edges, selectedNodeIds, onNodesChange, onEdgesChange],\n );\n\n // Click notification — fires the consumer's `onNodeClick`. FlowNode\n // calls this AFTER `selectNode` only when the gesture was a click,\n // not a drag. Separating the two lets drag-start update selection\n // without firing the click event.\n const notifyNodeClick = useCallback(\n (id: string) => {\n const node = nodes.find((n) => n.id === id);\n if (node) onNodeClick?.(node);\n },\n [nodes, onNodeClick],\n );\n\n const selectEdge = useCallback(\n (id: string, additive: boolean) => {\n const next: EdgeChange[] = [];\n const nextNodes: NodeChange[] = [];\n if (!additive) {\n for (const e of edges) {\n if (e.selected && e.id !== id) next.push(change.edge.select(e.id, false));\n }\n for (const n of nodes) {\n if (n.selected) nextNodes.push(change.node.select(n.id, false));\n }\n }\n const isSelected = selectedEdgeIds.has(id);\n if (additive && isSelected) {\n next.push(change.edge.select(id, false));\n } else if (!isSelected) {\n next.push(change.edge.select(id, true));\n }\n if (next.length) onEdgesChange?.(next);\n if (nextNodes.length) onNodesChange?.(nextNodes);\n const edge = edges.find((e) => e.id === id);\n if (edge) onEdgeClick?.(edge);\n },\n [nodes, edges, selectedEdgeIds, onEdgesChange, onNodesChange, onEdgeClick],\n );\n\n const clearSelection = useCallback(() => {\n const ns: NodeChange[] = [];\n const es: EdgeChange[] = [];\n for (const n of nodes) if (n.selected) ns.push(change.node.select(n.id, false));\n for (const e of edges) if (e.selected) es.push(change.edge.select(e.id, false));\n if (ns.length) onNodesChange?.(ns);\n if (es.length) onEdgesChange?.(es);\n }, [nodes, edges, onNodesChange, onEdgesChange]);\n\n // ── Node drag middleware ──────────────────────────────────────────────\n // Drag also moves transitive descendants (children of a parent move with\n // the parent), respects `extent: 'parent'` clamping, and supports\n // Alt-detach for re-parenting subflow children.\n type DragState = {\n pointerId: number;\n nodeId: string;\n startClientX: number;\n startClientY: number;\n startPosition: Position;\n /** Captured at drag-start so each pointermove can reposition all\n * descendants by the same delta without re-walking the tree. */\n descendants: { id: string; startPosition: Position }[];\n /** Skip the `extent: 'parent'` clamp for this drag. True only when\n * the node is genuinely free to leave its parent: an explicit\n * Alt-detach, or a top-level node (no parent) that `reparentOnDrag`\n * lets travel into a container. A parented child on a plain drag\n * stays clamped — that's what keeps a subflow child in its frame. */\n skipClamp: boolean;\n /** Hit-test for a new parent at drag-end (Alt held OR the consumer\n * opted into `reparentOnDrag`). */\n evaluateReparent: boolean;\n rafScheduled: boolean;\n nextDelta: { dx: number; dy: number } | null;\n };\n const dragRef = useRef<DragState | null>(null);\n const [draggingId, setDraggingId] = useState<string | null>(null);\n\n const beginNodeDrag = useCallback(\n (nodeId: string, pointerId: number, clientX: number, clientY: number, altKey = false) => {\n if (!nodesDraggable) return;\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return;\n const kids = descendantsOf(nodeId, nodes).map((d) => ({\n id: d.id,\n startPosition: d.position,\n }));\n // Reparenting is \"in play\" when the user held Alt OR the consumer\n // set `reparentOnDrag`. That decides whether we hit-test for a new\n // parent at drag-end.\n const evaluateReparent = altKey || reparentOnDragRef.current;\n // The extent clamp is short-circuited ONLY when the node is truly\n // free to leave its parent:\n // • Alt held → explicit detach gesture.\n // • reparentOnDrag + node has no parent → a top-level node that\n // should be able to travel INTO a container.\n // A parented child on a plain drag keeps its clamp even with\n // `reparentOnDrag` on, so subflow children can't slide out of the\n // frame by accident — detaching one is a deliberate Alt-drag.\n const hasParent = !!node.parentId;\n const skipClamp = altKey || (reparentOnDragRef.current && !hasParent);\n dragRef.current = {\n pointerId,\n nodeId,\n startClientX: clientX,\n startClientY: clientY,\n startPosition: node.position,\n descendants: kids,\n skipClamp,\n evaluateReparent,\n rafScheduled: false,\n nextDelta: null,\n };\n setDraggingId(nodeId);\n selectNode(nodeId, false);\n },\n [nodes, nodesDraggable, selectNode],\n );\n\n // ── Connection middleware ─────────────────────────────────────────────\n // `connection` is local state. The ghost-line component subscribes here\n // (via prop), the rest of the canvas does not — so a connection drag\n // does NOT re-render every node. Setting state inside the global\n // pointermove handler still triggers a re-render of FlowCanvas itself,\n // but that's just the SVG ghost; the node list and edges are memoised.\n const [conn, setConn] = useState<{\n pointerId: number;\n from: ConnectStartParams;\n start: Position;\n end: Position;\n } | null>(null);\n // We keep a ref mirror so the global pointermove handler can read the\n // latest value without re-attaching listeners on every state change.\n const connRef = useRef<typeof conn>(null);\n useEffect(() => {\n connRef.current = conn;\n }, [conn]);\n\n const beginConnection = useCallback(\n (\n nodeId: string,\n handleId: string,\n handleType: \"source\" | \"target\",\n pointerId: number,\n clientX: number,\n clientY: number,\n ) => {\n if (!nodesConnectable) return;\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return;\n // Compute the originating handle's flow-space centre so the ghost\n // line is visible from the very first frame (no flicker).\n const desc = handleRegistry.resolve(nodeId, handleType, handleId);\n const side = desc?.side ?? (handleType === \"source\" ? \"bottom\" : \"top\");\n const index = desc?.index ?? 0;\n const total = desc?.total ?? 1;\n const ratio = (index + 1) / (total + 1);\n // Default width matches the BaseNode body (368 px) so the ghost\n // line origin lands ON the handle dot even before the ResizeObserver\n // has reported the real measured width back through `onNodesChange`.\n const w = node.width ?? 368;\n // Use the effective height — collapsed containers render a tiny\n // strip; without this the ghost line would start far below the\n // visible group when dragging from a perimeter handle.\n const h = effectiveHeight(node);\n const start: Position = (() => {\n switch (side) {\n case \"top\":\n return { x: node.position.x + w * ratio, y: node.position.y };\n case \"bottom\":\n return { x: node.position.x + w * ratio, y: node.position.y + h };\n case \"left\":\n return { x: node.position.x, y: node.position.y + h * ratio };\n case \"right\":\n return { x: node.position.x + w, y: node.position.y + h * ratio };\n }\n })();\n const from: ConnectStartParams = { nodeId, handleId, handleType };\n const rect = containerRef.current?.getBoundingClientRect();\n const end = rect\n ? screenToFlow({ x: clientX - rect.left, y: clientY - rect.top }, viewport)\n : start;\n setConn({ pointerId, from, start, end });\n store.setConnection(from);\n onConnectStart?.({ clientX, clientY, pointerId } as unknown as globalThis.PointerEvent, from);\n },\n [nodes, nodesConnectable, handleRegistry, viewport, store, onConnectStart],\n );\n\n // ── Refs that the global pointer listeners read so they don't depend\n // ── on captured callback identity (avoids listener re-attach storms).\n const viewportRef = useRef(viewport);\n const nodesRef = useRef(nodes);\n const edgesRef = useRef(edges);\n const onNodesChangeRefForInstance = useRef(onNodesChange);\n const onEdgesChangeRefForInstance = useRef(onEdgesChange);\n const onBeforeDeleteRef = useRef(onBeforeDelete);\n const snapToGridRef = useRef(snapToGrid);\n const gridSizeRef = useRef(gridSize);\n const nodeCollisionGapRef = useRef(nodeCollisionGap);\n const subflowCollisionGapRef = useRef(subflowCollisionGap ?? nodeCollisionGap);\n const reparentOnDragRef = useRef(reparentOnDrag);\n const autoResizeContainersRef = useRef(autoResizeContainers);\n const containerAutoResizePaddingRef = useRef(containerAutoResizePadding);\n const containerMinWidthRef = useRef(containerMinWidth);\n const containerMinHeightRef = useRef(containerMinHeight);\n useEffect(() => {\n edgesRef.current = edges;\n }, [edges]);\n useEffect(() => {\n onNodesChangeRefForInstance.current = onNodesChange;\n }, [onNodesChange]);\n useEffect(() => {\n onEdgesChangeRefForInstance.current = onEdgesChange;\n }, [onEdgesChange]);\n useEffect(() => {\n onBeforeDeleteRef.current = onBeforeDelete;\n }, [onBeforeDelete]);\n useEffect(() => {\n snapToGridRef.current = snapToGrid;\n }, [snapToGrid]);\n useEffect(() => {\n gridSizeRef.current = gridSize;\n }, [gridSize]);\n useEffect(() => {\n nodeCollisionGapRef.current = nodeCollisionGap;\n }, [nodeCollisionGap]);\n useEffect(() => {\n subflowCollisionGapRef.current = subflowCollisionGap ?? nodeCollisionGap;\n }, [subflowCollisionGap, nodeCollisionGap]);\n useEffect(() => {\n reparentOnDragRef.current = reparentOnDrag;\n }, [reparentOnDrag]);\n useEffect(() => {\n autoResizeContainersRef.current = autoResizeContainers;\n }, [autoResizeContainers]);\n useEffect(() => {\n containerAutoResizePaddingRef.current = containerAutoResizePadding;\n }, [containerAutoResizePadding]);\n useEffect(() => {\n containerMinWidthRef.current = containerMinWidth;\n }, [containerMinWidth]);\n useEffect(() => {\n containerMinHeightRef.current = containerMinHeight;\n }, [containerMinHeight]);\n const onNodesChangeRef = useRef(onNodesChange);\n const onConnectRef = useRef(onConnect);\n const onConnectEndRef = useRef(onConnectEnd);\n const isValidConnectionRef = useRef(isValidConnection);\n useEffect(() => {\n viewportRef.current = viewport;\n }, [viewport]);\n useEffect(() => {\n nodesRef.current = nodes;\n }, [nodes]);\n useEffect(() => {\n onNodesChangeRef.current = onNodesChange;\n }, [onNodesChange]);\n useEffect(() => {\n onConnectRef.current = onConnect;\n }, [onConnect]);\n useEffect(() => {\n onConnectEndRef.current = onConnectEnd;\n }, [onConnectEnd]);\n useEffect(() => {\n isValidConnectionRef.current = isValidConnection;\n }, [isValidConnection]);\n\n // ── Pointer dispatch — single window-level listener installed ONCE.\n // All gesture deps come through refs, so this effect runs once per\n // mount and never re-attaches.\n useEffect(() => {\n const onPointerMove = (e: globalThis.PointerEvent) => {\n const vp = viewportRef.current;\n // Node drag\n const drag = dragRef.current;\n if (drag && drag.pointerId === e.pointerId) {\n const dx = (e.clientX - drag.startClientX) / vp.zoom;\n const dy = (e.clientY - drag.startClientY) / vp.zoom;\n drag.nextDelta = { dx, dy };\n if (!drag.rafScheduled) {\n drag.rafScheduled = true;\n requestAnimationFrame(() => {\n const d = dragRef.current;\n if (!d) return;\n d.rafScheduled = false;\n const delta = d.nextDelta;\n if (!delta) return;\n // Compute the proposed new position for the dragged node.\n const dragNode = nodesRef.current.find((n) => n.id === d.nodeId);\n if (!dragNode) return;\n const proposed = {\n x: d.startPosition.x + delta.dx,\n y: d.startPosition.y + delta.dy,\n };\n // Apply extent:'parent' clamping unless this drag is allowed\n // to leave the parent (Alt-detach, or a top-level node free\n // to roam). A clamped child can't be dragged out of frame.\n const clamped = d.skipClamp\n ? proposed\n : clampToParentExtent(dragNode, proposed, nodesRef.current);\n // Magnet collision — push out of any sibling we're overlapping\n // (or sitting closer than `gap` to). Subflow containers use\n // `subflowCollisionGap`; regular nodes use `nodeCollisionGap`.\n // Descendants of the dragged node never participate, so a\n // parent can move freely through the space its children occupy.\n const isContainer = isContainerType(dragNode.type);\n const gap = isContainer ? subflowCollisionGapRef.current : nodeCollisionGapRef.current;\n const excludeIds = new Set<string>([d.nodeId, ...d.descendants.map((kid) => kid.id)]);\n const finalPos = resolveNodeCollisions(dragNode, clamped, nodesRef.current, {\n gap,\n exclude: excludeIds,\n });\n // The realised delta may differ from the proposed delta after\n // clamping and collision — use it for shifting descendants so\n // they stay glued to the parent.\n const realDx = finalPos.x - d.startPosition.x;\n const realDy = finalPos.y - d.startPosition.y;\n const changes: NodeChange[] = [change.node.position(d.nodeId, finalPos, true)];\n for (const kid of d.descendants) {\n changes.push(\n change.node.position(\n kid.id,\n { x: kid.startPosition.x + realDx, y: kid.startPosition.y + realDy },\n true,\n ),\n );\n }\n onNodesChangeRef.current?.(changes);\n });\n }\n }\n\n // Connection drag — only this branch sets React state, so the\n // re-render is limited to FlowCanvas itself (nodes + edges memoised).\n const c = connRef.current;\n if (c && c.pointerId === e.pointerId) {\n const rect = containerRef.current?.getBoundingClientRect();\n if (rect) {\n const end = screenToFlow({ x: e.clientX - rect.left, y: e.clientY - rect.top }, vp);\n setConn({ ...c, end });\n }\n }\n };\n\n const onPointerUp = (e: globalThis.PointerEvent) => {\n const vp = viewportRef.current;\n const drag = dragRef.current;\n if (drag && drag.pointerId === e.pointerId) {\n const dx = (e.clientX - drag.startClientX) / vp.zoom;\n const dy = (e.clientY - drag.startClientY) / vp.zoom;\n const dragNode = nodesRef.current.find((n) => n.id === drag.nodeId);\n if (dragNode) {\n let proposed = {\n x: drag.startPosition.x + dx,\n y: drag.startPosition.y + dy,\n };\n // Snap to grid on commit only — during drag the node follows\n // the pointer freely, but releases land on the nearest grid\n // intersection. UX is \"smooth move, satisfying click.\"\n if (snapToGridRef.current) {\n const g = gridSizeRef.current;\n proposed = {\n x: Math.round(proposed.x / g) * g,\n y: Math.round(proposed.y / g) * g,\n };\n }\n const clamped = drag.skipClamp\n ? proposed\n : clampToParentExtent(dragNode, proposed, nodesRef.current);\n // Run collision once more on commit — guards against a fast\n // pointer-up that bypassed the last rAF tick.\n const isContainer = isContainerType(dragNode.type);\n const gap = isContainer ? subflowCollisionGapRef.current : nodeCollisionGapRef.current;\n const excludeIds = new Set<string>([\n drag.nodeId,\n ...drag.descendants.map((kid) => kid.id),\n ]);\n const finalPos = resolveNodeCollisions(dragNode, clamped, nodesRef.current, {\n gap,\n exclude: excludeIds,\n });\n const realDx = finalPos.x - drag.startPosition.x;\n const realDy = finalPos.y - drag.startPosition.y;\n\n // Build the final commit. Dragging now becomes false.\n const changes: NodeChange[] = [change.node.position(drag.nodeId, finalPos, false)];\n for (const kid of drag.descendants) {\n changes.push(\n change.node.position(\n kid.id,\n { x: kid.startPosition.x + realDx, y: kid.startPosition.y + realDy },\n false,\n ),\n );\n }\n\n // Reparent evaluation: when `evaluateReparent` is set (Alt-held\n // OR `reparentOnDrag` prop enabled), hit-test the drop point\n // against existing containers. Three outcomes:\n // • Was parented, dropped outside any container → detach.\n // • Was parented, dropped inside a different container → reparent.\n // • Was top-level, dropped inside a container → adopt.\n // The replace-change is appended to the same `onNodesChange`\n // batch as the position change, so the consumer sees one\n // atomic update — no parentId/position race.\n if (drag.evaluateReparent) {\n // Hit-test the child's CENTRE. Fall back to the default\n // footprint (not 0) for unmeasured nodes — `?? 0` made the\n // centre collapse onto the top-left corner, so a node dropped\n // squarely on a container could miss it (DEV-200).\n const dragW = dragNode.width ?? DEFAULT_NODE_WIDTH;\n const dragH = effectiveHeight(dragNode);\n const targetGroup = findContainingGroup(\n {\n x: finalPos.x + dragW / 2,\n y: finalPos.y + dragH / 2,\n },\n nodesRef.current,\n [drag.nodeId, ...drag.descendants.map((d) => d.id)],\n );\n const nextParentId = targetGroup?.id;\n // Only emit a replace if parentage actually changed —\n // dragging a child around inside its own parent should NOT\n // re-emit the whole node every frame.\n if (nextParentId !== dragNode.parentId) {\n const updated: WorkflowNode = {\n ...dragNode,\n position: finalPos,\n parentId: nextParentId,\n // Adopting into a container always pins the child with\n // `extent: 'parent'` so it's clamped from the next drag\n // on. Detaching clears it.\n extent: nextParentId ? \"parent\" : undefined,\n };\n changes.push(change.node.replace(drag.nodeId, updated));\n\n // Grow-only fit on ADOPT: make sure the target container is\n // at least large enough to show the freshly-adopted child in\n // full. Otherwise the child overhangs the frame and then\n // \"jumps\" inside on the next drag when `extent: 'parent'`\n // clamps it. We only GROW (never shrink or reposition) so a\n // manually-sized frame is preserved — full auto-fit remains\n // opt-in via `autoResizeContainers`. DEV-200.\n if (targetGroup) {\n const pad = containerAutoResizePaddingRef.current;\n const curW = targetGroup.width ?? DEFAULT_NODE_WIDTH;\n const curH = targetGroup.height ?? effectiveHeight(targetGroup);\n const needW = finalPos.x + dragW + pad - targetGroup.position.x;\n const needH = finalPos.y + dragH + pad - targetGroup.position.y;\n const grownW = Math.max(curW, needW);\n const grownH = Math.max(curH, needH);\n if (grownW !== curW || grownH !== curH) {\n changes.push(\n change.node.dimensions(targetGroup.id, { width: grownW, height: grownH }),\n );\n }\n }\n }\n }\n\n // Container auto-resize: recompute each container's bbox from\n // its (post-drag, post-reparent) children + padding. Folded\n // into the same change batch so the consumer can't see a\n // half-resized frame between renders.\n if (autoResizeContainersRef.current) {\n const containerChanges = computeContainerAutoResize(\n nodesRef.current,\n // Projected children: apply the position + reparent\n // changes we just built before measuring bboxes.\n changes,\n containerAutoResizePaddingRef.current,\n containerMinWidthRef.current,\n containerMinHeightRef.current,\n );\n for (const c of containerChanges) changes.push(c);\n }\n\n onNodesChangeRef.current?.(changes);\n }\n dragRef.current = null;\n setDraggingId(null);\n }\n\n const c = connRef.current;\n if (c && c.pointerId === e.pointerId) {\n // ── Geometric drop-target resolution ──────────────────────────\n // We do NOT hit-test the DOM (`e.target.closest` /\n // `elementsFromPoint`). Inside a subflow the container frame,\n // the child nodes and their ports overlap and stack in ways\n // that make DOM hit-testing miss the intended port entirely.\n // Instead we project the pointer into flow-space and pick the\n // nearest registered handle within a snap radius — the same\n // source of truth edges already use for their geometry. This\n // is immune to z-index, pointer-events and overlapping frames.\n const rect = containerRef.current?.getBoundingClientRect();\n const flowPos = rect\n ? screenToFlow({ x: e.clientX - rect.left, y: e.clientY - rect.top }, vp)\n : { x: 0, y: 0 };\n\n // Snap radius: ~26 on-screen px, converted to flow-space so the\n // tolerance feels constant regardless of zoom.\n const snapRadius = 26 / Math.max(0.1, vp.zoom);\n let bestDesc: HandleDescriptor | null = null;\n let bestDist = snapRadius;\n for (const desc of handleRegistry.all()) {\n // Can't end on the source node itself, and the target must be\n // the OPPOSITE role — a `source` connects to a `target`.\n if (desc.nodeId === c.from.nodeId) continue;\n if (desc.type === c.from.handleType) continue;\n if (!desc.canEnd) continue;\n const targetNode = nodesRef.current.find((n) => n.id === desc.nodeId);\n if (!targetNode || targetNode.hidden) continue;\n const centre = handleCentre(targetNode, desc.side, desc.index, desc.total);\n const dist = Math.hypot(centre.x - flowPos.x, centre.y - flowPos.y);\n if (dist < bestDist) {\n bestDist = dist;\n bestDesc = desc;\n }\n }\n\n let connection: Connection | null = null;\n let connectedTo: ConnectStartParams | undefined;\n if (bestDesc) {\n const source =\n c.from.handleType === \"source\"\n ? c.from\n : {\n nodeId: bestDesc.nodeId,\n handleId: bestDesc.handleId,\n handleType: \"source\" as const,\n };\n const target2 =\n c.from.handleType === \"target\"\n ? c.from\n : {\n nodeId: bestDesc.nodeId,\n handleId: bestDesc.handleId,\n handleType: \"target\" as const,\n };\n connection = {\n source: source.nodeId,\n sourceHandle: source.handleId,\n target: target2.nodeId,\n targetHandle: target2.handleId,\n };\n connectedTo = {\n nodeId: bestDesc.nodeId,\n handleId: bestDesc.handleId,\n handleType: bestDesc.type,\n };\n const validator = isValidConnectionRef.current;\n if (validator && !validator(connection)) {\n connection = null;\n connectedTo = undefined;\n }\n }\n const endState: ConnectEndState = {\n cancelled: !connection,\n position: { x: e.clientX, y: e.clientY },\n flowPosition: flowPos,\n from: c.from,\n to: connectedTo,\n };\n if (connection) onConnectRef.current?.(connection);\n onConnectEndRef.current?.(e, endState);\n setConn(null);\n store.setConnection(null);\n }\n };\n\n const onPointerCancel = () => {\n if (dragRef.current) {\n dragRef.current = null;\n setDraggingId(null);\n }\n if (connRef.current) {\n setConn(null);\n store.setConnection(null);\n }\n };\n\n window.addEventListener(\"pointermove\", onPointerMove);\n window.addEventListener(\"pointerup\", onPointerUp);\n window.addEventListener(\"pointercancel\", onPointerCancel);\n return () => {\n window.removeEventListener(\"pointermove\", onPointerMove);\n window.removeEventListener(\"pointerup\", onPointerUp);\n window.removeEventListener(\"pointercancel\", onPointerCancel);\n };\n }, [store]); // mount-only\n\n // ── Container auto-resize — catch-all ─────────────────────────────────\n // The drag-end commit resizes containers atomically for the drag case.\n // This effect covers every OTHER way a container's children change:\n // a node dropped in from an action drawer, a child deleted, a paste.\n // It's a no-op during an active drag (the commit path owns that) and\n // `computeContainerAutoResize` returns [] when nothing is dirty, so a\n // settled graph can't loop.\n useEffect(() => {\n if (!autoResizeContainers || draggingId) return;\n const resizeChanges = computeContainerAutoResize(\n nodes,\n [],\n containerAutoResizePadding,\n containerMinWidth,\n containerMinHeight,\n );\n if (resizeChanges.length > 0) onNodesChange?.(resizeChanges);\n }, [\n nodes,\n draggingId,\n autoResizeContainers,\n containerAutoResizePadding,\n containerMinWidth,\n containerMinHeight,\n onNodesChange,\n ]);\n\n // ── Pan (canvas drag) ─────────────────────────────────────────────────\n // We DON'T clear selection on pan-start (issue #4 from the audit). The\n // pointerup handler decides whether this was a click (no movement) and\n // only clears selection then.\n const panRef = useRef<{\n pointerId: number;\n startClientX: number;\n startClientY: number;\n startVp: Viewport;\n moved: boolean;\n } | null>(null);\n const onCanvasPointerDown = (e: PointerEvent<HTMLDivElement>) => {\n if (e.button !== 0) return;\n const t = e.target as HTMLElement;\n if (\n t.closest(\"[data-node-id]\") ||\n t.closest(\"[data-edge-id]\") ||\n t.closest(\"[data-handle-id]\")\n ) {\n return;\n }\n if (!panOnDrag) {\n // Even without pan, a click on the pane should clear selection.\n panRef.current = {\n pointerId: e.pointerId,\n startClientX: e.clientX,\n startClientY: e.clientY,\n startVp: viewport,\n moved: false,\n };\n return;\n }\n panRef.current = {\n pointerId: e.pointerId,\n startClientX: e.clientX,\n startClientY: e.clientY,\n startVp: viewport,\n moved: false,\n };\n };\n\n useEffect(() => {\n const onMove = (e: globalThis.PointerEvent) => {\n const pan = panRef.current;\n if (!pan || pan.pointerId !== e.pointerId) return;\n const dx = e.clientX - pan.startClientX;\n const dy = e.clientY - pan.startClientY;\n if (Math.abs(dx) > paneClickDistance || Math.abs(dy) > paneClickDistance) {\n if (!pan.moved) setPanGesture(true);\n pan.moved = true;\n }\n if (pan.moved && panOnDrag) {\n setViewport({ ...pan.startVp, x: pan.startVp.x + dx, y: pan.startVp.y + dy });\n }\n };\n const onUp = () => {\n const pan = panRef.current;\n if (!pan) return;\n // A genuine \"click\" on the pane (no significant movement) fires\n // onPaneClick. Selection is cleared only when the consumer opts in\n // — consumers that keep a side-panel open through pane clicks pass\n // `paneClickClearsSelection={false}`. A drag-pan does neither.\n if (!pan.moved) {\n onPaneClick?.();\n if (paneClickClearsSelection) clearSelection();\n }\n panRef.current = null;\n setPanGesture(false);\n };\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n window.addEventListener(\"pointercancel\", onUp);\n return () => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n window.removeEventListener(\"pointercancel\", onUp);\n };\n }, [\n setViewport,\n paneClickDistance,\n panOnDrag,\n onPaneClick,\n clearSelection,\n paneClickClearsSelection,\n ]);\n\n // ── Wheel-zoom ────────────────────────────────────────────────────────\n // Attached as a NON-PASSIVE native listener (see effect below) rather than\n // via React's `onWheel`. React registers wheel handlers as passive, so\n // `preventDefault()` inside a React onWheel is silently ignored — the\n // trackpad pinch (ctrl+wheel) then zoomed the whole browser page instead\n // of the canvas (DEV-206). A native listener with `{ passive: false }`\n // lets preventDefault actually take effect.\n const handleWheel = (e: globalThis.WheelEvent) => {\n if (!zoomOnScroll) return;\n e.preventDefault();\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect) return;\n const px = e.clientX - rect.left;\n const py = e.clientY - rect.top;\n const factor = Math.exp(-e.deltaY * 0.001);\n const nextZoom = Math.max(minZoom, Math.min(maxZoom, viewport.zoom * factor));\n const k = nextZoom / viewport.zoom;\n setViewport({\n zoom: nextZoom,\n x: px - (px - viewport.x) * k,\n y: py - (py - viewport.y) * k,\n });\n };\n // Keep the freshest handler in a ref so the native listener (attached once)\n // always sees the current viewport/zoom without re-binding every render.\n const handleWheelRef = useRef(handleWheel);\n handleWheelRef.current = handleWheel;\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const listener = (e: globalThis.WheelEvent) => handleWheelRef.current(e);\n el.addEventListener(\"wheel\", listener, { passive: false });\n return () => el.removeEventListener(\"wheel\", listener);\n }, []);\n\n // Zoom around the VIEWPORT CENTRE (not the flow-space origin). The toolbar\n // zoom buttons keep `x`/`y` unchanged, which anchors the scale at flow\n // (0,0) — so the workflow flew toward/away from the top-left corner and\n // could shoot off-screen. Pin the flow point currently under the container\n // centre instead (DEV-206).\n const zoomAroundCentre = (nextZoom: number) => {\n const rect = containerRef.current?.getBoundingClientRect();\n const vp = viewportRef.current;\n const cx = rect ? rect.width / 2 : 0;\n const cy = rect ? rect.height / 2 : 0;\n const k = nextZoom / vp.zoom;\n setViewport({\n zoom: nextZoom,\n x: cx - (cx - vp.x) * k,\n y: cy - (cy - vp.y) * k,\n });\n };\n\n // ── Dispatch contract for Handle ──────────────────────────────────────\n const dispatch = useCallback<FlowDispatch>(\n (a: FlowDispatchAction) => {\n if (a.type === \"connection/start\") {\n beginConnection(a.nodeId, a.handleId, a.handleType, a.pointerId, a.clientX, a.clientY);\n }\n },\n [beginConnection],\n );\n\n // Dimensions reporter — FlowNode's ResizeObserver calls this on size\n // change. We compare against `nodes[]` (current props) and only emit a\n // change when the value actually differs, so we don't trigger an\n // infinite render loop (dimensions change → parent re-renders nodes →\n // ResizeObserver may fire again from style updates).\n const reportDimensions = useCallback(\n (nodeId: string, width: number, height: number) => {\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return;\n if (node.width === width && node.height === height) return;\n onNodesChange?.([change.node.dimensions(nodeId, { width, height })]);\n },\n [nodes, onNodesChange],\n );\n\n // Toggle data.collapsed on a container node. Exposed via the bridge so\n // the chevron rendered inside GroupNode / ForEachNode can flip the\n // subflow state from inside the kind component, no external toolbar\n // wiring needed.\n const toggleNodeCollapseImpl = useCallback(\n (nodeId: string) => {\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return;\n const prevData = (node.data ?? {}) as { collapsed?: boolean } & Record<string, unknown>;\n const nextNode = {\n ...node,\n data: { ...prevData, collapsed: !prevData.collapsed },\n } as WorkflowNode;\n onNodesChange?.([change.node.replace(nodeId, nextNode)]);\n },\n [nodes, onNodesChange],\n );\n\n // Delete one node + its incident edges. Exposed via the FlowNodeBridge\n // so a node-rendered delete button (BaseNode corner [×]) can fire\n // without going through the keyboard / context-menu path.\n const deleteNodeImpl = useCallback(\n (nodeId: string) => {\n const incidentEdgeIds = edgesRef.current\n .filter((e) => e.source === nodeId || e.target === nodeId)\n .map((e) => e.id);\n if (incidentEdgeIds.length > 0) {\n onEdgesChange?.(incidentEdgeIds.map((id) => change.edge.remove(id)));\n }\n onNodesChange?.([change.node.remove(nodeId)]);\n },\n [onNodesChange, onEdgesChange],\n );\n\n // ── Imperative instance — useFlow() and onInit ───────────────────────\n // Methods read through refs each call so they always see fresh state,\n // even though the instance itself is stable across renders. Mutating\n // methods round-trip through the consumer's onNodesChange/onEdgesChange\n // so the canonical state stays single-source-of-truth.\n const instance = useMemo<FlowInstance>(\n () => ({\n // viewport\n getViewport: () => viewportRef.current,\n setViewport: (vp) => setViewport(vp),\n setCenter: (x, y, opts) => {\n const z = opts?.zoom ?? viewportRef.current.zoom;\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect) return;\n setViewport({\n zoom: z,\n x: rect.width / 2 - x * z,\n y: rect.height / 2 - y * z,\n });\n },\n fitView: async (opts) => {\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect) return false;\n const padding = opts?.padding ?? 80;\n const targetNodes = opts?.nodes\n ? nodesRef.current.filter((n) => opts.nodes!.some((x) => x.id === n.id))\n : nodesRef.current.filter((n) => !n.hidden);\n if (targetNodes.length === 0) return false;\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (const n of targetNodes) {\n const w = n.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(n);\n if (n.position.x < minX) minX = n.position.x;\n if (n.position.y < minY) minY = n.position.y;\n if (n.position.x + w > maxX) maxX = n.position.x + w;\n if (n.position.y + h > maxY) maxY = n.position.y + h;\n }\n const cw = maxX - minX;\n const ch = maxY - minY;\n const zx = (rect.width - padding * 2) / cw;\n const zy = (rect.height - padding * 2) / ch;\n const zoom = Math.max(\n opts?.minZoom ?? 0.25,\n Math.min(opts?.maxZoom ?? 1.5, Math.min(zx, zy)),\n );\n setViewport({\n zoom,\n x: rect.width / 2 - ((minX + maxX) / 2) * zoom,\n y: rect.height / 2 - ((minY + maxY) / 2) * zoom,\n });\n return true;\n },\n zoomIn: (opts) => {\n const step = opts?.step ?? 0.2;\n const next = Math.min(maxZoom, viewportRef.current.zoom * (1 + step));\n zoomAroundCentre(next);\n },\n zoomOut: (opts) => {\n const step = opts?.step ?? 0.2;\n const next = Math.max(minZoom, viewportRef.current.zoom / (1 + step));\n zoomAroundCentre(next);\n },\n zoomTo: (level) => {\n zoomAroundCentre(Math.max(minZoom, Math.min(maxZoom, level)));\n },\n\n // transforms\n screenToFlowPosition: (p) => screenToFlow(p, viewportRef.current),\n flowToScreenPosition: (p) => flowToScreen(p, viewportRef.current),\n\n // reads\n getNodes: () => nodesRef.current.slice(),\n getEdges: () => edgesRef.current.slice(),\n getNode: (id) => nodesRef.current.find((n) => n.id === id),\n getEdge: (id) => edgesRef.current.find((e) => e.id === id),\n getNodesBounds: (subset) => {\n const pool = subset\n ? nodesRef.current.filter((n) => subset.some((x) => x.id === n.id))\n : nodesRef.current.filter((n) => !n.hidden);\n if (pool.length === 0) return { x: 0, y: 0, width: 0, height: 0 };\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (const n of pool) {\n const w = n.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(n);\n minX = Math.min(minX, n.position.x);\n minY = Math.min(minY, n.position.y);\n maxX = Math.max(maxX, n.position.x + w);\n maxY = Math.max(maxY, n.position.y + h);\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n },\n getIntersectingNodes: (area, partially = true) => {\n return nodesRef.current.filter((n) => {\n if (n.hidden) return false;\n const w = n.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(n);\n if (partially) {\n // Any overlap counts.\n return (\n n.position.x < area.x + area.width &&\n n.position.x + w > area.x &&\n n.position.y < area.y + area.height &&\n n.position.y + h > area.y\n );\n }\n // Strict containment — node bbox sits entirely inside area.\n return (\n n.position.x >= area.x &&\n n.position.y >= area.y &&\n n.position.x + w <= area.x + area.width &&\n n.position.y + h <= area.y + area.height\n );\n });\n },\n\n // mutations\n addNodes: (nodes) => {\n const arr = Array.isArray(nodes) ? nodes : [nodes];\n onNodesChangeRefForInstance.current?.(arr.map((item) => change.node.add(item)));\n },\n addEdges: (edges) => {\n const arr = Array.isArray(edges) ? edges : [edges];\n onEdgesChangeRefForInstance.current?.(arr.map((item) => change.edge.add(item)));\n },\n updateNodeData: (id, partial) => {\n const cur = nodesRef.current.find((n) => n.id === id);\n if (!cur) return;\n // Merge partial into existing data; the consumer's reducer will\n // apply the resulting `replace` and emit fresh nodes.\n const nextData = { ...((cur.data ?? {}) as object), ...partial } as typeof cur.data;\n onNodesChangeRefForInstance.current?.([\n change.node.replace(id, { ...cur, data: nextData }),\n ]);\n },\n updateNode: (id, partial) => {\n const cur = nodesRef.current.find((n) => n.id === id);\n if (!cur) return;\n onNodesChangeRefForInstance.current?.([change.node.replace(id, { ...cur, ...partial })]);\n },\n deleteElements: async ({ nodes: ns, edges: es }) => {\n const nodesToDelete = (ns ?? [])\n .map((x) => nodesRef.current.find((n) => n.id === x.id))\n .filter((n): n is WorkflowNode => !!n);\n const edgesToDelete = (es ?? [])\n .map((x) => edgesRef.current.find((e) => e.id === x.id))\n .filter((e): e is WorkflowEdge => !!e);\n // Async veto — host can return a Promise<boolean> to confirm\n // (\"this node is referenced by a running execution; really delete?\").\n const before = onBeforeDeleteRef.current;\n if (before) {\n const ok = await before({ nodes: nodesToDelete, edges: edgesToDelete });\n if (!ok) return false;\n }\n if (nodesToDelete.length > 0) {\n onNodesChangeRefForInstance.current?.(nodesToDelete.map((n) => change.node.remove(n.id)));\n }\n if (edgesToDelete.length > 0) {\n onEdgesChangeRefForInstance.current?.(edgesToDelete.map((e) => change.edge.remove(e.id)));\n }\n return true;\n },\n }),\n [setViewport, minZoom, maxZoom],\n );\n\n // Hand the instance to the consumer once on mount. We don't refire on\n // every render because consumers typically stash the ref once. The\n // instance itself is stable (closures read fresh values via refs).\n const initFiredRef = useRef(false);\n useEffect(() => {\n if (initFiredRef.current) return;\n initFiredRef.current = true;\n onInit?.(instance);\n }, [instance, onInit]);\n\n // Auto-frame the existing nodes on first mount. Without this, a\n // canvas that opens with nodes at positions like (1200, 800) shows\n // an empty viewport at the {0,0,1} origin and the user has to pan to\n // find their workflow. The default kicks in only when the consumer\n // didn't pin a viewport themselves and didn't explicitly disable it.\n //\n // Fires on the first frame where `nodes.length > 0` AND the container\n // has measured dimensions (a 0×0 container would yield NaN bounds).\n // The bounding-box math falls back to DEFAULT_NODE_WIDTH / height for\n // un-measured nodes, so the framing is correct even before ResizeObservers\n // have reported real dimensions.\n const fitOnInitFiredRef = useRef(false);\n useEffect(() => {\n if (fitOnInitFiredRef.current) return;\n const opt = fitViewOnInit;\n const shouldFit = opt === false ? false : opt !== undefined ? true : !viewportPropProvided;\n if (!shouldFit) return;\n // Wait until the container has real dimensions — a 0×0 container yields\n // NaN bounds. We do NOT latch while unmeasured so the fit still fires\n // once the container lays out.\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect || rect.width === 0 || rect.height === 0) return;\n // Container is measured → this is our single initialization opportunity.\n // \"Fit on init\" means \"frame the content present at initialization\", NOT\n // \"fit whenever the first node ever appears\". If the canvas mounted empty\n // there is nothing to frame, but we still latch here so that a node the\n // user later drops onto the blank canvas is NOT mistaken for hydration\n // and does not recenter + reset zoom onto itself (DEV-203).\n if (nodes.length === 0) {\n fitOnInitFiredRef.current = true;\n return;\n }\n const fitOpts = typeof opt === \"object\" && opt !== null ? opt : undefined;\n // Defer one frame so any layout effects (e.g. ResizeObservers reporting\n // node dimensions) have settled before we compute bounds. Latch INSIDE\n // the rAF (not before scheduling it) so React StrictMode's\n // mount → cleanup → remount cycle — whose cleanup cancels the first\n // frame — cannot leave us permanently \"fired\" without ever fitting\n // (DEV-206). Each effect re-run cancels the prior frame via cleanup, so\n // there is no double-fit.\n const raf = requestAnimationFrame(() => {\n fitOnInitFiredRef.current = true;\n void instance.fitView(fitOpts);\n });\n return () => cancelAnimationFrame(raf);\n }, [fitViewOnInit, viewportPropProvided, nodes.length, instance]);\n\n // ── Keyboard: Backspace / Delete removes the current selection ────────\n // Goes through `instance.deleteElements` so `onBeforeDelete` veto, edge\n // re-routing, and the same change pipeline as the X button fire\n // consistently. We only act when focus is on the canvas (or its\n // children) — typing in a real input shouldn't delete the workflow.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Backspace\" && e.key !== \"Delete\") return;\n const target = e.target as HTMLElement | null;\n // Don't hijack typing in form fields. `contentEditable` covers the\n // edge label inline editor.\n if (\n target &&\n (target.tagName === \"INPUT\" ||\n target.tagName === \"TEXTAREA\" ||\n target.tagName === \"SELECT\" ||\n target.isContentEditable)\n ) {\n return;\n }\n // Only fire when the canvas (or something inside it) currently\n // owns focus / pointer interaction. Bare `keydown` on document\n // would steal Backspace from other widgets on the page.\n if (!containerRef.current?.contains(target) && document.activeElement !== document.body) {\n return;\n }\n const sel = store.getSnapshot();\n if (sel.selectedNodeIds.size === 0 && sel.selectedEdgeIds.size === 0) return;\n e.preventDefault();\n void instance.deleteElements({\n nodes: Array.from(sel.selectedNodeIds, (id) => ({ id })),\n edges: Array.from(sel.selectedEdgeIds, (id) => ({ id })),\n });\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [instance, store]);\n\n const bridge = useMemo<FlowNodeBridge>(\n () => ({\n beginNodeDrag,\n selectNode,\n notifyNodeClick,\n selectEdge,\n reportDimensions,\n deleteNode: deleteNodeImpl,\n toggleNodeCollapse: toggleNodeCollapseImpl,\n }),\n [\n beginNodeDrag,\n selectNode,\n notifyNodeClick,\n selectEdge,\n reportDimensions,\n deleteNodeImpl,\n toggleNodeCollapseImpl,\n ],\n );\n\n // ── Cursor feedback ───────────────────────────────────────────────────\n // The user gets immediate visual cues for which gesture they're in:\n // - idle on empty canvas → \"grab\" (or default if panOnDrag = false)\n // - dragging the pane → \"grabbing\"\n // - dragging a connection → \"crosshair\"\n // - dragging a node → handled by FlowNode CSS (\"grabbing\")\n // We use a state-driven class so the cursor flips synchronously with\n // the gesture (vs CSS :active which lags behind pointer-capture).\n const [panGesture, setPanGesture] = useState(false);\n\n // ── Render ────────────────────────────────────────────────────────────\n const isEmpty = nodes.length === 0 && edges.length === 0;\n const isConnecting = conn !== null;\n\n // Filter out hidden nodes + their incident edges. Hidden is a runtime\n // flag (e.g. set by a \"collapse group\" toggle). Edges that reference a\n // hidden node would otherwise dangle in space.\n const visibleNodes = useMemo(() => nodes.filter((n) => !n.hidden), [nodes]);\n const visibleEdges = useMemo(() => {\n if (visibleNodes.length === nodes.length) return edges;\n const visibleIds = new Set(visibleNodes.map((n) => n.id));\n return edges.filter((e) => visibleIds.has(e.source) && visibleIds.has(e.target));\n }, [edges, nodes, visibleNodes]);\n\n // Sort so containers render before their children (lower in DOM = under\n // children when zIndex ties). For NESTED containers (group inside group)\n // we order by depth — outermost first — so an inner group's children\n // can still draw on top of the outer group's frame. Non-container nodes\n // sort last in original-array order.\n //\n // Containers: `group` only (see `isContainerType`). `forEach` is a simple\n // node, not a child-hosting frame.\n const orderedNodes = useMemo(() => {\n const isContainer = (n: WorkflowNode) => isContainerType(n.type);\n // Cache parent chain depth for stable ordering. Cycles return Infinity.\n const depth = (n: WorkflowNode): number => {\n let d = 0;\n let cursor = n.parentId;\n const seen = new Set<string>();\n while (cursor) {\n if (seen.has(cursor)) return Number.POSITIVE_INFINITY;\n seen.add(cursor);\n d++;\n cursor = visibleNodes.find((x) => x.id === cursor)?.parentId;\n }\n return d;\n };\n const containers = visibleNodes.filter(isContainer);\n const others = visibleNodes.filter((n) => !isContainer(n));\n containers.sort((a, b) => depth(a) - depth(b));\n return [...containers, ...others];\n }, [visibleNodes]);\n\n return (\n <FlowStoreContext.Provider value={store}>\n <FlowInstanceContext.Provider value={instance}>\n <HandleRegistryContext.Provider value={handleRegistry}>\n <FlowDispatchContext.Provider value={dispatch}>\n <FlowNodeBridgeContext.Provider value={bridge}>\n <div\n ref={containerRef}\n className={cn(\n \"ods-flow-canvas-v2\",\n panGesture && \"ods-flow-canvas-v2--panning\",\n isConnecting && \"ods-flow-canvas-v2--connecting\",\n draggingId && \"ods-flow-canvas-v2--dragging\",\n className,\n )}\n style={{\n position: \"relative\",\n width,\n height,\n overflow: \"hidden\",\n userSelect: \"none\",\n touchAction: \"none\",\n // Cursor: state-driven so it flips instantly with the\n // gesture. CSS `:active` would lag behind pointer-capture.\n cursor: panGesture\n ? \"grabbing\"\n : isConnecting\n ? \"crosshair\"\n : panOnDrag\n ? \"grab\"\n : \"default\",\n ...style,\n }}\n onPointerDown={onCanvasPointerDown}\n onContextMenu={(e) => {\n // Route the right-click to the per-surface handler based on\n // where the pointer landed. Consumers `preventDefault()` to\n // suppress the browser's native menu; we don't do it for\n // them because some workflows prefer the OS menu on pane.\n const t = e.target as HTMLElement;\n const nodeEl = t.closest(\"[data-node-id]\") as HTMLElement | null;\n if (nodeEl && onNodeContextMenu) {\n const id = nodeEl.dataset.nodeId!;\n const node = nodes.find((n) => n.id === id);\n if (node) onNodeContextMenu(e, node);\n return;\n }\n const edgeEl = t.closest(\"[data-edge-id]\") as HTMLElement | null;\n if (edgeEl && onEdgeContextMenu) {\n const id = edgeEl.dataset.edgeId!;\n const edge = edges.find((x) => x.id === id);\n if (edge) onEdgeContextMenu(e, edge);\n return;\n }\n onPaneContextMenu?.(e);\n }}\n data-empty={isEmpty ? \"true\" : undefined}\n >\n {background !== \"none\" && (\n <div\n className={cn(\n \"ods-flow-canvas-v2__grid\",\n `ods-flow-canvas-v2__grid--${background}`,\n )}\n style={\n {\n // Custom property drives the four variants' SCSS.\n \"--ods-flow-grid-size\": `${gridSize * viewport.zoom}px`,\n backgroundPosition: `${viewport.x}px ${viewport.y}px`,\n } as CSSProperties\n }\n />\n )}\n\n <div\n className=\"ods-flow-canvas-v2__viewport\"\n style={{\n position: \"absolute\",\n inset: 0,\n transform: `translate(${viewport.x}px, ${viewport.y}px) scale(${viewport.zoom})`,\n transformOrigin: \"0 0\",\n }}\n >\n <EdgesLayer\n edges={visibleEdges}\n nodes={visibleNodes}\n onSelect={(id) => bridge.selectEdge(id, false)}\n onDelete={(id) => onEdgesChangeRef(id, onEdgesChange)}\n onLabelChange={onEdgeLabelChange}\n ghost={conn ? { start: conn.start, end: conn.end } : null}\n // Bust EdgesLayer's memo when the handle registry\n // changes, so edges recompute geometry against the\n // newly-mounted handles.\n handleVersion={handleVersion}\n />\n\n {orderedNodes.map((node) => {\n const Kind = kinds[node.type] ?? kinds.action;\n if (!Kind) return null;\n return (\n <FlowNode\n key={node.id}\n node={node}\n selected={selectedNodeIds.has(node.id)}\n dragging={draggingId === node.id}\n isConnecting={isConnecting}\n Kind={Kind}\n />\n );\n })}\n </div>\n\n {isEmpty && emptyState && (\n <div className=\"ods-flow-canvas-v2__empty\">{emptyState}</div>\n )}\n\n {children}\n </div>\n </FlowNodeBridgeContext.Provider>\n </FlowDispatchContext.Provider>\n </HandleRegistryContext.Provider>\n </FlowInstanceContext.Provider>\n </FlowStoreContext.Provider>\n );\n}\n\n// Tiny helper — keeps the JSX above clean.\nfunction onEdgesChangeRef(id: string, cb?: (changes: EdgeChange[]) => void) {\n cb?.([change.edge.remove(id)]);\n}\n\n/**\n * Compute auto-resize updates for every container in the graph so each\n * frame encloses its current children + padding.\n *\n * `pending` carries the position / replace changes the canvas is\n * about to dispatch — we PROJECT them onto the current node list\n * before measuring so a drag that just moved a child uses the new\n * position, not the stale committed one. That makes the auto-resize\n * atomic with the drag commit: a single `onNodesChange` call carries\n * both the child's new position AND the parent's new frame.\n *\n * Container frames track their children's bbox in BOTH directions —\n * they grow to fit and shrink when children are removed, floored at\n * `minWidth/minHeight` (the default empty-container size) so a frame\n * never collapses to nothing. A fixed `CONTAINER_DROP_HEADROOM` is\n * kept past the content so there's always room to drop ~2 more nodes\n * before the next grow. The frame also re-positions its top-left to\n * follow the children bbox so children stay visually inside.\n */\n// Spare room the auto-resize keeps PAST the children's bbox so a couple\n// more nodes can be dropped before the frame has to grow again. Sized to\n// roughly two default node rows tall and one node-width of slack wide —\n// the \"+2 nodes of drop room\" a subflow container should always offer.\nconst CONTAINER_DROP_HEADROOM_W = 220;\nconst CONTAINER_DROP_HEADROOM_H = 2 * 128;\n\nfunction computeContainerAutoResize(\n nodes: WorkflowNode[],\n pending: NodeChange[],\n padding: number,\n minWidth: number,\n minHeight: number,\n): NodeChange[] {\n // Apply pending changes to a transient view of the node list. We\n // care about: `position` (child moves), `replace` (reparent), and\n // `add` (newly-inserted nodes are projected too). Other change\n // types don't affect bbox math.\n const projected = new Map<string, WorkflowNode>();\n for (const n of nodes) projected.set(n.id, n);\n for (const c of pending) {\n if (c.type === \"position\" && c.position) {\n const cur = projected.get(c.id);\n if (cur) projected.set(c.id, { ...cur, position: c.position });\n } else if (c.type === \"replace\" && c.item) {\n projected.set(c.id, { ...projected.get(c.id), ...c.item } as WorkflowNode);\n } else if (c.type === \"add\" && c.item) {\n projected.set((c.item as WorkflowNode).id, c.item as WorkflowNode);\n }\n }\n\n const HEADER = 56; // breathing room above the first child\n const out: NodeChange[] = [];\n for (const parent of projected.values()) {\n if (!isContainerType(parent.type)) continue;\n const children: WorkflowNode[] = [];\n for (const n of projected.values()) {\n if (n.parentId === parent.id) children.push(n);\n }\n if (children.length === 0) {\n // Emptied container — collapse it back to the default floor size.\n // Position is left alone (no children to track).\n const curW = parent.width ?? 480;\n const curH = parent.height ?? 240;\n if (curW !== minWidth || curH !== minHeight) {\n out.push(change.node.dimensions(parent.id, { width: minWidth, height: minHeight }));\n }\n continue;\n }\n\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (const c of children) {\n const cw = c.width ?? 240;\n const ch = c.height ?? 96;\n if (c.position.x < minX) minX = c.position.x;\n if (c.position.y < minY) minY = c.position.y;\n if (c.position.x + cw > maxX) maxX = c.position.x + cw;\n if (c.position.y + ch > maxY) maxY = c.position.y + ch;\n }\n const targetX = minX - padding;\n const targetY = minY - padding - HEADER;\n const curW = parent.width ?? 480;\n const curH = parent.height ?? 240;\n // Fit children + padding + drop headroom, floored at the container's\n // default size. This both GROWS and SHRINKS: a frame that's lost\n // children collapses back toward `minWidth/minHeight`, and one that's\n // gained them grows to keep ~2 nodes of empty drop room. The headroom\n // is what makes \"drop two more before it resizes\" hold.\n const fitW = maxX - minX + padding * 2 + CONTAINER_DROP_HEADROOM_W;\n const fitH = maxY - minY + padding * 2 + HEADER + CONTAINER_DROP_HEADROOM_H;\n const nextW = Math.max(minWidth, fitW);\n const nextH = Math.max(minHeight, fitH);\n const positionDirty = parent.position.x !== targetX || parent.position.y !== targetY;\n const sizeDirty = curW !== nextW || curH !== nextH;\n if (positionDirty) {\n out.push(change.node.position(parent.id, { x: targetX, y: targetY }, false));\n }\n if (sizeDirty) {\n out.push(change.node.dimensions(parent.id, { width: nextW, height: nextH }));\n }\n }\n return out;\n}\n\n// ────────────────────────────────────────────────────────────────────────\n// EdgesLayer — memoised. Re-renders only when edges/nodes arrays or ghost\n// position change. Edges within use memo on (edge, source/target position,\n// edge.selected/animated) so dragging one node only re-renders edges\n// connected to that node.\n// ────────────────────────────────────────────────────────────────────────\nconst EdgesLayer = memo(function EdgesLayer({\n edges,\n nodes,\n onSelect,\n onDelete,\n onLabelChange,\n ghost,\n handleVersion: _handleVersion,\n}: {\n edges: WorkflowEdge[];\n nodes: WorkflowNode[];\n onSelect: (id: string) => void;\n onDelete: (id: string) => void;\n onLabelChange?: (id: string, label: string) => void;\n ghost: { start: Position; end: Position } | null;\n /** Bust-cache token that flips whenever the handle registry mutates.\n * React.memo's default shallow compare picks up the change and re-\n * renders the layer; FlowEdge inside reads the now-up-to-date\n * registry on the re-render. */\n handleVersion: number;\n}) {\n return (\n <svg\n className=\"ods-flow-canvas-v2__edges\"\n style={{ position: \"absolute\", inset: 0, overflow: \"visible\", pointerEvents: \"none\" }}\n width=\"100%\"\n height=\"100%\"\n >\n <g style={{ pointerEvents: \"auto\" }}>\n {edges.map((edge) => (\n <FlowEdge\n key={edge.id}\n edge={edge}\n nodes={nodes}\n onSelect={onSelect}\n onDelete={onDelete}\n onLabelChange={onLabelChange}\n handleVersion={_handleVersion}\n />\n ))}\n </g>\n {ghost && (\n <path\n d={`M ${ghost.start.x} ${ghost.start.y} L ${ghost.end.x} ${ghost.end.y}`}\n stroke=\"var(--ods-accent, #4f46e5)\"\n strokeWidth={1.5}\n strokeDasharray=\"4 4\"\n fill=\"none\"\n />\n )}\n </svg>\n );\n});\n\n// Type re-export so consumers don't need to import from a deeper path.\nexport type { BuiltInNodeData };\n","// ════════════════════════════════════════════════════════════════════════\n// FlowStore — per-canvas state, exposed only via narrow selector hooks.\n// ════════════════════════════════════════════════════════════════════════\n// We deliberately do NOT export the store instance (see ADR-005). The\n// store lives behind a React context; descendants read via\n// `useFlowSelector(selector)` which under the hood is\n// `useSyncExternalStore` against a single `subscribe` channel.\n//\n// The store is the single source of truth for runtime state\n// (selection, viewport, in-flight connection). Node/edge data is mirrored\n// from the controlled props each render; the store keeps a frozen\n// snapshot so descendants don't have to thread `nodes` / `edges` through\n// component trees.\n\nimport type {\n ConnectStartParams,\n FlowStoreSnapshot,\n Viewport,\n WorkflowEdge,\n WorkflowNode,\n} from \"../editor\";\n\ntype Listener = () => void;\n\nexport interface FlowStore {\n /** React subscription hook contract — used by `useSyncExternalStore`. */\n subscribe(listener: Listener): () => void;\n /** Cheap snapshot getter — must return the same ref between mutations. */\n getSnapshot(): FlowStoreSnapshot;\n /** Imperative setters — called by the canvas internals, never by consumers. */\n setNodes(nodes: WorkflowNode[]): void;\n setEdges(edges: WorkflowEdge[]): void;\n setViewport(viewport: Viewport): void;\n setSelection(nodes: ReadonlySet<string>, edges: ReadonlySet<string>): void;\n setConnection(connection: ConnectStartParams | null): void;\n}\n\nexport interface CreateFlowStoreOptions {\n initialNodes?: WorkflowNode[];\n initialEdges?: WorkflowEdge[];\n initialViewport?: Viewport;\n}\n\nconst DEFAULT_VIEWPORT: Viewport = { x: 0, y: 0, zoom: 1 };\n\n/**\n * Build a FlowStore for one canvas instance. Designed to be created in\n * `useState(() => createFlowStore())` inside FlowCanvas so a single\n * `<FlowCanvas>` owns exactly one store and unmounting cleans it up.\n */\nexport function createFlowStore({\n initialNodes = [],\n initialEdges = [],\n initialViewport = DEFAULT_VIEWPORT,\n}: CreateFlowStoreOptions = {}): FlowStore {\n let snapshot: FlowStoreSnapshot = {\n nodes: initialNodes,\n edges: initialEdges,\n viewport: initialViewport,\n selectedNodeIds: EMPTY_SET,\n selectedEdgeIds: EMPTY_SET,\n connection: null,\n };\n\n const listeners = new Set<Listener>();\n const emit = () => {\n for (const l of listeners) l();\n };\n\n const subscribe = (listener: Listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n };\n\n // Replace the snapshot reference on every change so React's\n // `useSyncExternalStore` triggers a re-render. We never mutate in place.\n const replace = (patch: Partial<FlowStoreSnapshot>) => {\n snapshot = { ...snapshot, ...patch };\n emit();\n };\n\n return {\n subscribe,\n getSnapshot: () => snapshot,\n setNodes(nodes) {\n if (nodes === snapshot.nodes) return;\n replace({ nodes });\n },\n setEdges(edges) {\n if (edges === snapshot.edges) return;\n replace({ edges });\n },\n setViewport(viewport) {\n if (\n viewport.x === snapshot.viewport.x &&\n viewport.y === snapshot.viewport.y &&\n viewport.zoom === snapshot.viewport.zoom\n ) {\n return;\n }\n replace({ viewport });\n },\n setSelection(selectedNodeIds, selectedEdgeIds) {\n replace({ selectedNodeIds, selectedEdgeIds });\n },\n setConnection(connection) {\n if (connection === snapshot.connection) return;\n replace({ connection });\n },\n };\n}\n\nconst EMPTY_SET: ReadonlySet<string> = new Set();\n","// ════════════════════════════════════════════════════════════════════════\n// Collision avoidance — keep nodes from overlapping each other (or from\n// landing closer than a configurable minimum gap).\n// ════════════════════════════════════════════════════════════════════════\n//\n// The function below is a pure axis-aligned bounding-box (AABB) \"minimum\n// translation vector\" resolver. Given a proposed position for one node\n// and a set of other nodes, it shifts the proposed position along the\n// axis of *smallest* overlap correction until either (a) no node is\n// closer than `gap` pixels, or (b) the iteration cap is reached.\n//\n// Why MTV? It produces the smoothest \"magnet snap\" UX — when you nudge a\n// node toward a neighbour, it slides along the contact edge rather than\n// flinging away. The iteration cap (8 by default) handles cascading\n// resolutions where pushing out of one node lands in another.\n\nimport type { Position, WorkflowNode } from \"../editor\";\nimport { DEFAULT_NODE_WIDTH, effectiveHeight } from \"./geometry\";\n\nexport interface CollisionOptions {\n /** Minimum gap (px) the dragged node must keep from each other node.\n *\n * - `gap >= 0` — the resolver is **enabled**. `gap === 0` means\n * \"no overlap, zero buffer\" (strict no-overlap). `gap > 0` enforces\n * a buffer of that many pixels.\n * - `gap < 0` — the resolver is **disabled** (returns the proposed\n * position unchanged). This is the no-op sentinel used by\n * consumers that haven't opted into magnet behaviour. */\n gap: number;\n /** Cap iterative resolutions — prevents infinite loops in pathological\n * geometries (e.g. four nodes hugging a single corner). Default 8. */\n maxIterations?: number;\n /** Node ids that the resolver should ignore — typically the dragged\n * node itself plus its descendants (so a parent doesn't collide with\n * its own children) and its ancestors (so a child doesn't collide\n * with its containing group). */\n exclude?: Set<string>;\n /** When true, only consider nodes that share the same `parentId` as\n * the dragged node (i.e. its siblings). When false, all non-excluded\n * nodes participate. Defaults to true — this is the \"rooms\" model\n * where children of group A never collide with children of group B\n * even if their bboxes overlap in flow space. */\n scopeToSiblings?: boolean;\n}\n\n/**\n * Adjust a proposed (flow-space) position so the node's bbox stays at\n * least `gap` pixels away from every other (non-excluded) node's bbox.\n *\n * The function does NOT mutate the input nodes; it returns a new\n * `Position`. The caller is responsible for emitting the resulting\n * change via `onNodesChange` — collision resolution doesn't dispatch\n * anything on its own.\n */\nexport function resolveNodeCollisions(\n node: WorkflowNode,\n proposed: Position,\n others: WorkflowNode[],\n opts: CollisionOptions,\n): Position {\n const { gap, maxIterations = 8, exclude, scopeToSiblings = true } = opts;\n if (gap < 0 || others.length === 0) return proposed;\n\n const w = node.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(node);\n const parentId = node.parentId;\n\n // Pre-filter the candidate list once — keeps the per-iteration loop tight.\n const candidates = others.filter((o) => {\n if (o.id === node.id) return false;\n if (o.hidden) return false;\n if (exclude?.has(o.id)) return false;\n if (scopeToSiblings && (o.parentId ?? undefined) !== (parentId ?? undefined)) {\n return false;\n }\n return true;\n });\n if (candidates.length === 0) return proposed;\n\n let cur = proposed;\n\n for (let iter = 0; iter < maxIterations; iter++) {\n // Find the colliding pair with the SMALLEST overlap correction and\n // resolve that one this iteration. Doing one push per iteration keeps\n // the displacement minimal and lets cascading shifts settle naturally.\n let bestOverlap = Number.POSITIVE_INFINITY;\n let bestPushX = 0;\n let bestPushY = 0;\n let hit = false;\n\n // Inflate our rect by `gap` so any node within `gap` registers as\n // overlap. We add the full gap to one side (rather than gap/2 to\n // both sides) so the resulting min-distance matches user intuition:\n // \"at least `gap` pixels between the two visual edges.\"\n const aLeft = cur.x - gap;\n const aRight = cur.x + w + gap;\n const aTop = cur.y - gap;\n const aBottom = cur.y + h + gap;\n\n for (const o of candidates) {\n const ow = o.width ?? DEFAULT_NODE_WIDTH;\n const oh = effectiveHeight(o);\n const bLeft = o.position.x;\n const bRight = o.position.x + ow;\n const bTop = o.position.y;\n const bBottom = o.position.y + oh;\n\n const overlapX = Math.min(aRight, bRight) - Math.max(aLeft, bLeft);\n const overlapY = Math.min(aBottom, bBottom) - Math.max(aTop, bTop);\n if (overlapX <= 0 || overlapY <= 0) continue;\n\n // Pick the axis with the smaller overlap — that's the cheaper push.\n // Direction: if our centre is \"before\" their centre on that axis,\n // push backward; otherwise push forward.\n let pushX = 0;\n let pushY = 0;\n let overlap: number;\n if (overlapX < overlapY) {\n const aCx = cur.x + w / 2;\n const bCx = o.position.x + ow / 2;\n pushX = aCx < bCx ? -overlapX : overlapX;\n overlap = overlapX;\n } else {\n const aCy = cur.y + h / 2;\n const bCy = o.position.y + oh / 2;\n pushY = aCy < bCy ? -overlapY : overlapY;\n overlap = overlapY;\n }\n\n if (overlap < bestOverlap) {\n bestOverlap = overlap;\n bestPushX = pushX;\n bestPushY = pushY;\n hit = true;\n }\n }\n\n if (!hit) break;\n cur = { x: cur.x + bestPushX, y: cur.y + bestPushY };\n }\n\n return cur;\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Parenting helpers — descendant traversal, extent clamping, descendant\n// position recompute. Used by FlowCanvas's drag middleware to keep\n// subflow semantics consistent.\n// ════════════════════════════════════════════════════════════════════════\n\nimport type { NodeKind, Position, WorkflowNode } from \"../editor\";\nimport { DEFAULT_NODE_WIDTH, effectiveHeight } from \"./geometry\";\n\n/**\n * Node types that behave as containers — subflow frames whose children nest\n * via `parentId` and render inside the frame.\n *\n * `forEach` is intentionally NOT a container. The DS renders it as a SIMPLE\n * node (1 input on top, Each / Done outputs on the bottom) whose loop body is\n * wired by EDGES, not nested by `parentId` (see ForEachNode). Treating it as\n * a container let drag-to-reparent adopt nodes INTO a forEach; the host then\n * silently dropped those \"children\" on save because its wire contract has no\n * forEach-children concept — real data loss (DEV-200). Keep this list in sync\n * with the kinds that actually render a child-hosting frame.\n */\nexport const CONTAINER_NODE_TYPES: readonly NodeKind[] = [\"group\"];\n\n/** True when a node type hosts nested children via `parentId`. */\nexport function isContainerType(type: NodeKind | undefined): boolean {\n return type !== undefined && CONTAINER_NODE_TYPES.includes(type);\n}\n\n/**\n * Returns the transitive descendants of a node — i.e. every node whose\n * `parentId` chain ends at `nodeId`. Stable order (DFS). The root node\n * is NOT included.\n */\nexport function descendantsOf(nodeId: string, nodes: WorkflowNode[]): WorkflowNode[] {\n const childrenByParent = new Map<string, WorkflowNode[]>();\n for (const n of nodes) {\n if (!n.parentId) continue;\n const arr = childrenByParent.get(n.parentId);\n if (arr) arr.push(n);\n else childrenByParent.set(n.parentId, [n]);\n }\n const out: WorkflowNode[] = [];\n const stack = [nodeId];\n // Guard against malformed cycles (a → b → a) which can sneak in via\n // hand-crafted fixtures. Without this the walk is unbounded.\n const visited = new Set<string>([nodeId]);\n while (stack.length) {\n const cur = stack.pop();\n if (cur === undefined) break;\n const list = childrenByParent.get(cur);\n if (!list) continue;\n for (const c of list) {\n if (visited.has(c.id)) continue;\n visited.add(c.id);\n out.push(c);\n stack.push(c.id);\n }\n }\n return out;\n}\n\n/**\n * Walk up the parent chain. Returns the first ancestor that satisfies\n * `predicate`, or undefined.\n */\nexport function findAncestor(\n node: WorkflowNode,\n nodes: WorkflowNode[],\n predicate: (n: WorkflowNode) => boolean,\n): WorkflowNode | undefined {\n let cursor: WorkflowNode | undefined = node;\n const seen = new Set<string>();\n while (cursor?.parentId) {\n if (seen.has(cursor.parentId)) return undefined; // cycle guard\n seen.add(cursor.parentId);\n const parent = nodes.find((n) => n.id === cursor!.parentId);\n if (!parent) return undefined;\n if (predicate(parent)) return parent;\n cursor = parent;\n }\n return undefined;\n}\n\n/**\n * Clamp a proposed child position to its parent's bounding box. The\n * child is kept fully inside the parent — child's bottom-right corner\n * cannot exceed the parent's bottom-right.\n *\n * Returns the original position if the node has no parent or extent\n * isn't `'parent'`.\n */\nexport function clampToParentExtent(\n node: WorkflowNode,\n proposed: Position,\n nodes: WorkflowNode[],\n): Position {\n if (node.extent !== \"parent\" || !node.parentId) return proposed;\n const parent = nodes.find((n) => n.id === node.parentId);\n if (!parent) return proposed;\n const pw = parent.width ?? DEFAULT_NODE_WIDTH;\n const ph = effectiveHeight(parent);\n const w = node.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(node);\n const minX = parent.position.x;\n const minY = parent.position.y;\n const maxX = parent.position.x + pw - w;\n const maxY = parent.position.y + ph - h;\n return {\n x: Math.max(minX, Math.min(maxX, proposed.x)),\n y: Math.max(minY, Math.min(maxY, proposed.y)),\n };\n}\n\n/**\n * Hit-test which container node (if any) contains the given point. Used by\n * drag-to-reparent and drop-to-add to scope a node. Only `group` is a\n * container (see `isContainerType` — `forEach` is a simple node).\n *\n * When containers overlap or nest, the SMALLEST-area container under the\n * point wins. That's the most specific / deepest-nested frame, and it\n * matches the host's own drop hit-test (which picked the deepest container).\n * The previous \"last in array order\" rule disagreed with the host, so a drag\n * and a drop over the same nested groups could adopt into different parents\n * (DEV-200).\n */\nexport function findContainingGroup(\n point: Position,\n nodes: WorkflowNode[],\n exclude: string[] = [],\n): WorkflowNode | undefined {\n let best: WorkflowNode | undefined;\n let bestArea = Number.POSITIVE_INFINITY;\n for (const n of nodes) {\n if (exclude.includes(n.id)) continue;\n if (!isContainerType(n.type)) continue;\n if (n.data && typeof n.data === \"object\" && (n.data as { collapsed?: boolean }).collapsed) {\n continue;\n }\n const w = n.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(n);\n if (\n point.x >= n.position.x &&\n point.y >= n.position.y &&\n point.x <= n.position.x + w &&\n point.y <= n.position.y + h\n ) {\n const area = w * h;\n if (area < bestArea) {\n best = n;\n bestArea = area;\n }\n }\n }\n return best;\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FlowEdge v2 — port-aware path, four routing modes, editable label.\n// ════════════════════════════════════════════════════════════════════════\n// Routing modes: bezier (default), step, smoothstep, straight.\n// Semantic types: default / conditional / loop / error — drive stroke\n// colour and dash pattern, orthogonal to routing.\n//\n// Label + delete chrome are stacked vertically at the midpoint so they\n// don't overlap. Double-clicking the label opens an inline editor;\n// changes commit via `onLabelChange`.\n\nimport {\n memo,\n type KeyboardEvent as ReactKeyboardEvent,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport type { EdgeKind, WorkflowEdge as WorkflowEdgeType, WorkflowNode } from \"../../editor\";\nimport { handleCentre } from \"../../utils/geometry\";\nimport { buildEdgePath, type EdgeRouting } from \"../../utils/paths\";\nimport { useHandleRegistry } from \"../Handle/handleRegistry\";\n\nexport interface FlowEdgeProps {\n edge: WorkflowEdgeType;\n nodes: WorkflowNode[];\n onSelect?: (id: string) => void;\n onDelete?: (id: string) => void;\n /** Commit a label edit. When omitted, double-click is a no-op. */\n onLabelChange?: (id: string, label: string) => void;\n /** Show the X delete affordance at the midpoint on hover/select. */\n showDelete?: boolean;\n /** Curvature for bezier routing (0–1). Smaller = tighter. Default 0.25. */\n curvature?: number;\n /** Corner radius for smoothstep routing. Default 8 px. */\n borderRadius?: number;\n /**\n * Bust-cache token from FlowCanvas. Bumps whenever the handle registry\n * mutates so this edge re-renders against fresh handle descriptors —\n * fixes stale geometry after collapse/uncollapse of a subflow whose\n * children mount their Handles in a follow-up effect tick.\n */\n handleVersion?: number;\n}\n\nfunction FlowEdgeImpl({\n edge,\n nodes,\n onSelect,\n onDelete,\n onLabelChange,\n showDelete = true,\n curvature = 0.25,\n borderRadius = 8,\n}: FlowEdgeProps) {\n const uid = useId();\n const markerId = `ods-flow-edge-arrow-${uid.replace(/:/g, \"\")}`;\n const registry = useHandleRegistry();\n const [hovered, setHovered] = useState(false);\n const [editing, setEditing] = useState(false);\n const [draftLabel, setDraftLabel] = useState<string>(edge.label ?? \"\");\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Sync the draft when the edge's label changes externally (e.g. after a\n // commit). The local state survives blur/Enter cleanly.\n useEffect(() => {\n if (!editing) setDraftLabel(edge.label ?? \"\");\n }, [edge.label, editing]);\n\n const sourceNode = nodes.find((n) => n.id === edge.source);\n const targetNode = nodes.find((n) => n.id === edge.target);\n\n if (!sourceNode || !targetNode) return null;\n\n // Compute on every render — handle registrations may arrive after the\n // first paint, and the math is cheap.\n const sourceHandleId = edge.sourceHandle ?? \"default\";\n const targetHandleId = edge.targetHandle ?? \"default\";\n const sourceDesc = registry.resolve(sourceNode.id, \"source\", sourceHandleId);\n const targetDesc = registry.resolve(targetNode.id, \"target\", targetHandleId);\n const sourceSide = sourceDesc?.side ?? sourceNode.sourcePosition ?? \"bottom\";\n const targetSide = targetDesc?.side ?? targetNode.targetPosition ?? \"top\";\n // The handle dot's physical edge (`side`) places the endpoint; the\n // `routeSide` decides which way the curve leaves/enters it. They differ\n // for a subflow's inner-facing ports — a dot on the frame's `top` edge\n // whose wire must curve `down` into the frame.\n const sourceRoute = sourceDesc?.routeSide ?? sourceSide;\n const targetRoute = targetDesc?.routeSide ?? targetSide;\n const sourceIndex = sourceDesc?.index ?? 0;\n const sourceTotal = sourceDesc?.total ?? 1;\n const targetIndex = targetDesc?.index ?? 0;\n const targetTotal = targetDesc?.total ?? 1;\n const rawStart = handleCentre(sourceNode, sourceSide, sourceIndex, sourceTotal);\n const rawEnd = handleCentre(targetNode, targetSide, targetIndex, targetTotal);\n // Pull the visible path back from each handle dot a few pixels so\n // the arrowhead lands ON the port circle (overlapping its centre)\n // rather than floating in space above it. The hitbox path still\n // uses the raw points so the click hit area extends right up to\n // the dot. Port circle is 12 px / radius 6; a 2 px pull-back puts\n // the arrow's visual tip at the port centre.\n const HANDLE_GAP = 2;\n const start = offsetAlongSide(rawStart, sourceRoute, HANDLE_GAP);\n const end = offsetAlongSide(rawEnd, targetRoute, HANDLE_GAP);\n const routing: EdgeRouting = edge.routing ?? \"bezier\";\n const { d, midX, midY } = buildEdgePath(routing, start, sourceRoute, end, targetRoute, {\n curvature,\n borderRadius,\n });\n const { d: hitD } = buildEdgePath(routing, rawStart, sourceRoute, rawEnd, targetRoute, {\n curvature,\n borderRadius,\n });\n\n const type: EdgeKind = edge.type ?? \"default\";\n const isHot = hovered || edge.selected;\n const stroke =\n type === \"error\"\n ? \"var(--ods-status-failed, #dc2626)\"\n : isHot\n ? \"var(--ods-accent, #4f46e5)\"\n : \"var(--ods-border-strong, #6b7280)\";\n // Explicit `edge.style.strokeDasharray` wins over the type's default —\n // this is what `collapseFor` uses to render boundary edges (sparse-dotted)\n // so the user sees they're a \"summary\" rather than a real connection.\n const typeDash = type === \"conditional\" ? \"6 4\" : type === \"loop\" ? \"4 4\" : undefined;\n const dash = edge.style?.strokeDasharray ?? typeDash;\n const strokeWidth = edge.style?.strokeWidth ?? (isHot ? 2 : 1.4);\n const animateDash = edge.animated === true;\n const label = edge.label;\n const hasDelete = showDelete && (isHot || edge.selected) && !!onDelete;\n\n // Lay label + delete affordance side by side at the midpoint:\n //\n // ┌─────────┐ ⓧ ← inline chrome, both on midY\n // │ label │\n // └─────────┘\n //\n // The foreignObject sits on the bezier's midpoint and holds a flex row\n // that centres its children horizontally. Either child may be absent;\n // remaining child stays centred.\n const showChrome = !!label || editing || hasDelete;\n\n const commitLabel = (next: string) => {\n setEditing(false);\n if (next !== edge.label) onLabelChange?.(edge.id, next);\n };\n\n const onLabelKey = (e: ReactKeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commitLabel(draftLabel);\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n setEditing(false);\n setDraftLabel(edge.label ?? \"\");\n }\n };\n\n return (\n <g\n className={cn(\n \"ods-flow-edge-v2\",\n `ods-flow-edge-v2--${type}`,\n `ods-flow-edge-v2--routing-${routing}`,\n edge.selected && \"ods-flow-edge-v2--selected\",\n hovered && \"ods-flow-edge-v2--hovered\",\n edge.className,\n )}\n data-edge-id={edge.id}\n data-edge-routing={routing}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n onClick={(e) => {\n e.stopPropagation();\n onSelect?.(edge.id);\n }}\n onDoubleClick={(e) => {\n // Double-clicking anywhere on the edge opens the label editor —\n // this is the only way to ADD a description to an edge that\n // doesn't have one yet (the label chip only renders once a\n // label exists, so there'd otherwise be nothing to double-click).\n if (!onLabelChange) return;\n e.stopPropagation();\n setDraftLabel(edge.label ?? \"\");\n setEditing(true);\n }}\n >\n <defs>\n <marker\n id={markerId}\n viewBox=\"0 0 10 10\"\n refX=\"9\"\n refY=\"5\"\n markerWidth=\"7\"\n markerHeight=\"7\"\n orient=\"auto-start-reverse\"\n >\n <path d=\"M0 0L10 5L0 10z\" fill={stroke} />\n </marker>\n </defs>\n\n {/* Hitbox — wider stroke than the visible path so the edge is easy\n to click even when zoomed out or routed with sharp corners. Uses\n the un-shortened path so the click target reaches the port. */}\n <path d={hitD} stroke=\"transparent\" strokeWidth={20} fill=\"none\" />\n\n {/* Visible path. */}\n <path\n d={d}\n stroke={stroke}\n strokeWidth={strokeWidth}\n strokeDasharray={dash}\n fill=\"none\"\n markerEnd={`url(#${markerId})`}\n style={\n animateDash\n ? {\n strokeDasharray: dash ?? \"6 4\",\n animation: \"ods-flow-edge-flow 0.6s linear infinite\",\n }\n : undefined\n }\n />\n\n {showChrome && (\n <foreignObject\n x={midX - 140}\n y={midY - 16}\n width={280}\n height={32}\n style={{ overflow: \"visible\", pointerEvents: \"none\" }}\n >\n <div className=\"ods-flow-edge-v2__chrome\">\n {(label || editing) &&\n (editing ? (\n <input\n ref={inputRef}\n className=\"ods-flow-edge-v2__label-input\"\n value={draftLabel}\n autoFocus\n onChange={(e) => setDraftLabel(e.target.value)}\n onBlur={() => commitLabel(draftLabel)}\n onKeyDown={onLabelKey}\n onClick={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n aria-label=\"Edit edge label\"\n />\n ) : (\n <button\n type=\"button\"\n className=\"ods-flow-edge-v2__label-chip\"\n onDoubleClick={(e) => {\n if (!onLabelChange) return;\n e.stopPropagation();\n setDraftLabel(edge.label ?? \"\");\n setEditing(true);\n }}\n onClick={(e) => {\n e.stopPropagation();\n onSelect?.(edge.id);\n }}\n title={onLabelChange ? \"Double-click to edit\" : undefined}\n tabIndex={onLabelChange ? 0 : -1}\n >\n <span>{label}</span>\n </button>\n ))}\n\n {hasDelete && (\n <button\n type=\"button\"\n className=\"ods-flow-edge-v2__delete-btn\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete?.(edge.id);\n }}\n aria-label=\"Delete edge\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path\n d=\"M2 2l6 6M8 2l-6 6\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n )}\n </div>\n </foreignObject>\n )}\n </g>\n );\n}\n\n/**\n * Pull a handle anchor point inward by `gap` px along the side it sits\n * on. Used to leave space between the arrowhead and the open-circle\n * port — the path stops just outside the dot so the arrow stays visible.\n *\n * \"top\" → end is at the node's top edge, pull it UP (smaller y)\n * \"bottom\" → pull DOWN (larger y)\n * \"left\" → pull LEFT (smaller x)\n * \"right\" → pull RIGHT (larger x)\n */\nfunction offsetAlongSide(\n p: { x: number; y: number },\n side: \"top\" | \"right\" | \"bottom\" | \"left\",\n gap: number,\n): { x: number; y: number } {\n switch (side) {\n case \"top\":\n return { x: p.x, y: p.y - gap };\n case \"bottom\":\n return { x: p.x, y: p.y + gap };\n case \"left\":\n return { x: p.x - gap, y: p.y };\n case \"right\":\n return { x: p.x + gap, y: p.y };\n }\n}\n\nexport const FlowEdge = memo(FlowEdgeImpl, (prev, next) => {\n if (prev.edge !== next.edge) return false;\n if (prev.onSelect !== next.onSelect || prev.onDelete !== next.onDelete) return false;\n if (prev.onLabelChange !== next.onLabelChange) return false;\n if (prev.showDelete !== next.showDelete) return false;\n if (prev.curvature !== next.curvature || prev.borderRadius !== next.borderRadius) return false;\n // Bust the cache when the handle registry mutates — otherwise edges\n // referring to handles that mount in a follow-up effect tick (e.g.\n // children inside a subflow that just un-collapsed) freeze at the\n // first-render-with-stale-registry geometry.\n if (prev.handleVersion !== next.handleVersion) return false;\n const ps = prev.nodes.find((n) => n.id === prev.edge.source);\n const pt = prev.nodes.find((n) => n.id === prev.edge.target);\n const ns = next.nodes.find((n) => n.id === next.edge.source);\n const nt = next.nodes.find((n) => n.id === next.edge.target);\n if (ps !== ns || pt !== nt) return false;\n return true;\n});\n","// ════════════════════════════════════════════════════════════════════════\n// Edge-path builders — bezier, step, smoothstep, straight.\n// ════════════════════════════════════════════════════════════════════════\n// All builders take two oriented endpoints (a position + the side of the\n// node that the port faces) and return:\n// - `d` — the SVG path attribute\n// - `midX`, `midY` — analytic midpoint used by the label + delete chrome\n//\n// Path style is selected via `edge.routing`. The choice does NOT affect\n// the `edge.type` semantic (default/conditional/loop/error) which still\n// drives stroke colour and dash. They're orthogonal.\n\nimport type { HandlePosition, Position } from \"../editor\";\n\nexport type EdgeRouting = \"bezier\" | \"step\" | \"smoothstep\" | \"straight\";\n\nexport interface PathGeometry {\n d: string;\n midX: number;\n midY: number;\n /** Tangent angle (radians) at the midpoint — useful when callers want\n * to offset the label/delete chrome along or perpendicular to the path. */\n midAngle: number;\n}\n\n// ── Public dispatcher ──────────────────────────────────────────────────\nexport function buildEdgePath(\n routing: EdgeRouting,\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n options: { borderRadius?: number; curvature?: number } = {},\n): PathGeometry {\n switch (routing) {\n case \"step\":\n return stepPath(start, startSide, end, endSide);\n case \"smoothstep\":\n return smoothStepPath(start, startSide, end, endSide, options.borderRadius ?? 8);\n case \"straight\":\n return straightPath(start, end);\n default:\n return bezierPath(start, startSide, end, endSide, options.curvature ?? 0.25);\n }\n}\n\n// ── Bezier — React-Flow-style control-offset algorithm ────────────────\n// `curvature` ∈ [0, 1]. Smaller = tighter; 0.25 is a comfortable default.\n// When the target is *in the port's forward direction*, offset is a linear\n// fraction of axis distance. When *behind* (target is in the opposite\n// direction from where the port faces), offset uses a square-root falloff\n// so the curve fans out without overshooting wildly.\nexport function bezierPath(\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n curvature = 0.25,\n): PathGeometry {\n const sourceOffset = calcControlOffset(start, startSide, end, curvature);\n const targetOffset = calcControlOffset(end, endSide, start, curvature);\n const c1 = offsetAlongSide(start, startSide, sourceOffset);\n const c2 = offsetAlongSide(end, endSide, targetOffset);\n\n const d = `M ${start.x},${start.y} C ${c1.x},${c1.y} ${c2.x},${c2.y} ${end.x},${end.y}`;\n\n // Analytic midpoint of a cubic bezier at t=0.5.\n const midX = 0.125 * start.x + 0.375 * c1.x + 0.375 * c2.x + 0.125 * end.x;\n const midY = 0.125 * start.y + 0.375 * c1.y + 0.375 * c2.y + 0.125 * end.y;\n // Tangent at t=0.5 = 3 * ((c2 - c1) + 0.5 * ((c1 - start) - (end - c2))).\n // Simplified: derivative of the bezier polynomial at 0.5.\n const tx =\n 3 *\n ((1 - 0.5) ** 2 * (c1.x - start.x) +\n 2 * (1 - 0.5) * 0.5 * (c2.x - c1.x) +\n 0.5 ** 2 * (end.x - c2.x));\n const ty =\n 3 *\n ((1 - 0.5) ** 2 * (c1.y - start.y) +\n 2 * (1 - 0.5) * 0.5 * (c2.y - c1.y) +\n 0.5 ** 2 * (end.y - c2.y));\n const midAngle = Math.atan2(ty, tx);\n\n return { d, midX, midY, midAngle };\n}\n\n/**\n * Distance from `from` to `to` along the axis the `side` points in.\n * Positive = `to` is in front of the port; negative = behind.\n */\nfunction axisDistance(from: Position, side: HandlePosition, to: Position): number {\n switch (side) {\n case \"top\":\n return from.y - to.y;\n case \"bottom\":\n return to.y - from.y;\n case \"left\":\n return from.x - to.x;\n case \"right\":\n return to.x - from.x;\n }\n}\n\nfunction calcControlOffset(\n from: Position,\n side: HandlePosition,\n to: Position,\n curvature: number,\n): number {\n const distance = axisDistance(from, side, to);\n if (distance >= 0) {\n // Linear fraction of axis distance — produces gentle S-curves.\n return distance * 0.5 * (1 + curvature);\n }\n // Backward — square-root falloff so the curve fans wide without\n // shooting off into space at extreme distances. The 25-multiplier is\n // tuned to match React Flow's visual behaviour.\n return curvature * 25 * Math.sqrt(-distance);\n}\n\nfunction offsetAlongSide(p: Position, side: HandlePosition, magnitude: number): Position {\n switch (side) {\n case \"top\":\n return { x: p.x, y: p.y - magnitude };\n case \"bottom\":\n return { x: p.x, y: p.y + magnitude };\n case \"left\":\n return { x: p.x - magnitude, y: p.y };\n case \"right\":\n return { x: p.x + magnitude, y: p.y };\n }\n}\n\n// ── Step routing — orthogonal Z/U-bend ────────────────────────────────\n// For top/bottom ports: vertical-horizontal-vertical (Z). For left/right\n// ports: horizontal-vertical-horizontal. Mixed sides produce an L.\nexport function stepPath(\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n): PathGeometry {\n const corners = computeStepCorners(start, startSide, end, endSide);\n const pts = [start, ...corners, end];\n const d = pts.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x},${p.y}`).join(\" \");\n // Midpoint along the longest segment so label/delete don't overlap a corner.\n const { midX, midY, midAngle } = midpointOnPolyline(pts);\n return { d, midX, midY, midAngle };\n}\n\n// ── Smoothstep — step with rounded corners ────────────────────────────\nexport function smoothStepPath(\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n borderRadius = 8,\n): PathGeometry {\n const corners = computeStepCorners(start, startSide, end, endSide);\n const pts = [start, ...corners, end];\n if (corners.length === 0) {\n return straightPath(start, end);\n }\n // Build SVG path with `Q` arcs at each interior corner.\n const segments: string[] = [`M ${pts[0].x},${pts[0].y}`];\n for (let i = 1; i < pts.length - 1; i++) {\n const prev = pts[i - 1];\n const here = pts[i];\n const next = pts[i + 1];\n // Cap the radius so it never exceeds half of the adjacent segments.\n const r = Math.min(borderRadius, distance(prev, here) / 2, distance(here, next) / 2);\n const enter = pointTowards(here, prev, r);\n const exit = pointTowards(here, next, r);\n segments.push(`L ${enter.x},${enter.y}`);\n segments.push(`Q ${here.x},${here.y} ${exit.x},${exit.y}`);\n }\n const last = pts[pts.length - 1];\n segments.push(`L ${last.x},${last.y}`);\n const d = segments.join(\" \");\n const { midX, midY, midAngle } = midpointOnPolyline(pts);\n return { d, midX, midY, midAngle };\n}\n\n// ── Straight ─────────────────────────────────────────────────────────\nexport function straightPath(start: Position, end: Position): PathGeometry {\n const d = `M ${start.x},${start.y} L ${end.x},${end.y}`;\n return {\n d,\n midX: (start.x + end.x) / 2,\n midY: (start.y + end.y) / 2,\n midAngle: Math.atan2(end.y - start.y, end.x - start.x),\n };\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────\nfunction computeStepCorners(\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n): Position[] {\n const sourceVertical = startSide === \"top\" || startSide === \"bottom\";\n const targetVertical = endSide === \"top\" || endSide === \"bottom\";\n\n if (sourceVertical && targetVertical) {\n // Z-shape: vertical → horizontal → vertical.\n const midY = (start.y + end.y) / 2;\n return [\n { x: start.x, y: midY },\n { x: end.x, y: midY },\n ];\n }\n if (!sourceVertical && !targetVertical) {\n // Same idea horizontally.\n const midX = (start.x + end.x) / 2;\n return [\n { x: midX, y: start.y },\n { x: midX, y: end.y },\n ];\n }\n // Mixed — L-shape (single corner at the intersection).\n if (sourceVertical) {\n return [{ x: end.x, y: start.y }];\n }\n return [{ x: start.x, y: end.y }];\n}\n\nfunction midpointOnPolyline(pts: Position[]): {\n midX: number;\n midY: number;\n midAngle: number;\n} {\n if (pts.length === 2) {\n return {\n midX: (pts[0].x + pts[1].x) / 2,\n midY: (pts[0].y + pts[1].y) / 2,\n midAngle: Math.atan2(pts[1].y - pts[0].y, pts[1].x - pts[0].x),\n };\n }\n // Walk segments accumulating length; pick the segment whose midpoint\n // is closest to the half-length mark. Anchoring the label to the\n // longest segment keeps it readable.\n let totalLen = 0;\n const lens: number[] = [];\n for (let i = 0; i < pts.length - 1; i++) {\n const l = distance(pts[i], pts[i + 1]);\n lens.push(l);\n totalLen += l;\n }\n const half = totalLen / 2;\n let acc = 0;\n for (let i = 0; i < lens.length; i++) {\n if (acc + lens[i] >= half) {\n const seg = lens[i];\n const remaining = half - acc;\n const t = seg === 0 ? 0 : remaining / seg;\n const a = pts[i];\n const b = pts[i + 1];\n return {\n midX: a.x + (b.x - a.x) * t,\n midY: a.y + (b.y - a.y) * t,\n midAngle: Math.atan2(b.y - a.y, b.x - a.x),\n };\n }\n acc += lens[i];\n }\n // Fallback — unreachable in practice.\n return { midX: pts[0].x, midY: pts[0].y, midAngle: 0 };\n}\n\nfunction distance(a: Position, b: Position): number {\n return Math.hypot(b.x - a.x, b.y - a.y);\n}\n\nfunction pointTowards(from: Position, to: Position, dist: number): Position {\n const d = distance(from, to);\n if (d === 0) return from;\n const t = dist / d;\n return { x: from.x + (to.x - from.x) * t, y: from.y + (to.y - from.y) * t };\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Per-canvas handle registry — Edge components look up handle positions\n// via this registry so they don't need to thread DOM refs around.\n// ════════════════════════════════════════════════════════════════════════\n// The Handle component registers itself on mount with its (nodeId,\n// handleId, type, side, index, total) tuple. FlowEdge derives the absolute\n// flow-space centre via `handleCentre()` using `node.position +\n// node.dimensions + side + index/total`.\n//\n// Keys are `(nodeId, type, handleId)` — note the `type`! Input and\n// output handles can legitimately share an id (the default is `\"default\"`\n// for both), and the type disambiguates. Without this, a node with one\n// input + one output (both with id `\"default\"`) would collide and edges\n// would resolve the wrong side.\n\nimport { createContext, useContext } from \"react\";\nimport type { HandlePosition, HandleType } from \"../../editor\";\n\nexport interface HandleDescriptor {\n nodeId: string;\n handleId: string;\n type: HandleType;\n /** Physical edge the handle dot sits on — drives placement + the\n * handle's flow-space centre. */\n side: HandlePosition;\n /**\n * Edge-routing direction. The bezier leaves/enters along THIS side,\n * which is normally the same as `side`. A subflow's inner-facing port\n * sits on the frame's outer edge (`side`) but must route INWARD — e.g.\n * a port physically on `top` whose wire should curve `down` into the\n * frame sets `routeSide: \"bottom\"`. Defaults to `side`.\n */\n routeSide: HandlePosition;\n /** 0-based position among same-(node, side, type) handles. */\n index: number;\n /** Total handles on the same (node, side, type). */\n total: number;\n /** May this handle START a connection? Defaults true. */\n canStart: boolean;\n /** May this handle END a connection? Defaults true. */\n canEnd: boolean;\n}\n\nexport interface HandleRegistry {\n register(d: HandleDescriptor): () => void;\n resolve(nodeId: string, type: HandleType, handleId: string): HandleDescriptor | undefined;\n /** Every currently-registered handle. Used by the connection drag to\n * resolve a drop target geometrically (nearest handle within snap\n * radius) rather than relying on DOM hit-testing, which is fragile\n * against z-index / pointer-events / overlapping subflow frames. */\n all(): HandleDescriptor[];\n /**\n * Subscribe to registry mutations. Fires after every register /\n * unregister so listeners (typically the EdgesLayer) can re-render\n * once the new handles are present. Without this, edges resolved\n * during the same React commit as a node remount fall back to default\n * positions because the Handle's `useEffect` hasn't yet written its\n * descriptor — which is what caused the post-collapse stale-edge bug\n * inside subflows.\n */\n subscribe(listener: () => void): () => void;\n}\n\nexport const HandleRegistryContext = createContext<HandleRegistry | null>(null);\n\nexport function useHandleRegistry(): HandleRegistry {\n const r = useContext(HandleRegistryContext);\n if (!r) {\n throw new Error(\"[@octaviaflow/core/workflow] Handle must be used inside <FlowCanvas>.\");\n }\n return r;\n}\n\n/**\n * Build a registry. One per FlowCanvas instance.\n */\nexport function createHandleRegistry(): HandleRegistry {\n const map = new Map<string, HandleDescriptor>();\n const key = (n: string, t: HandleType, h: string) => `${n}::${t}::${h}`;\n const listeners = new Set<() => void>();\n const notify = () => {\n for (const l of listeners) l();\n };\n return {\n register(d) {\n map.set(key(d.nodeId, d.type, d.handleId), d);\n notify();\n return () => {\n // Only delete if our descriptor is still the registered one — guards\n // against races when a node unmounts a Handle and immediately\n // remounts it with the same id during a quick re-render.\n const k = key(d.nodeId, d.type, d.handleId);\n if (map.get(k) === d) {\n map.delete(k);\n notify();\n }\n };\n },\n resolve(nodeId, type, handleId) {\n return map.get(key(nodeId, type, handleId));\n },\n all() {\n return Array.from(map.values());\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FlowNode — wrapper for any node in the v2 editor.\n// ════════════════════════════════════════════════════════════════════════\n// Responsibilities:\n// 1. Position itself absolutely at `node.position` (in flow space).\n// 2. Provide FlowNodeContext so descendants (Handle, NodeToolbar) know\n// which node they live in.\n// 3. Begin drag on pointerdown (the canvas-level pointermove takes over).\n// 4. Begin selection on click.\n// 5. Dispatch to the kind component for the actual chrome.\n//\n// The wrapper does NOT subscribe to its own selected state via the store;\n// instead the parent NodesLayer passes the resolved `selected` flag down\n// — keeps re-render fan-out predictable.\n\nimport { type PointerEvent, useEffect, useMemo, useRef } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport type { WorkflowNode } from \"../../editor\";\nimport { useFlowNodeBridge } from \"../FlowCanvas/FlowCanvasContext\";\nimport { FlowNodeContext, type FlowNodeContextValue } from \"./FlowNodeContext\";\nimport type { NodeKindComponent } from \"./nodeKinds\";\n\nexport interface FlowNodeProps {\n node: WorkflowNode;\n selected: boolean;\n dragging: boolean;\n isConnecting: boolean;\n Kind: NodeKindComponent;\n /** Optional fallback width for un-measured nodes — defaults to 240. */\n defaultWidth?: number;\n}\n\nexport function FlowNode({\n node,\n selected,\n dragging,\n isConnecting,\n Kind,\n // Match the BaseNode body's fixed 368 px width so the wrapper bbox and\n // the rendered card line up on the first paint — before the\n // ResizeObserver has had a chance to write back the measured size.\n // Container kinds (group / forEach) opt out by setting `node.width`.\n defaultWidth = 368,\n}: FlowNodeProps) {\n const bridge = useFlowNodeBridge();\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n // ── ResizeObserver — feed real dimensions back through onNodesChange so\n // edges can compute endpoints against the actual rendered footprint.\n // Without this, every node looks 96px tall to the edge layer and arrows\n // land mid-air below tall nodes.\n //\n // Container kinds (`group`, `forEach`) are EXEMPT. Why: when a group is\n // collapsed its rendered height shrinks to 36px; if we measure that the\n // 36px gets written back into `node.height` and the group never restores\n // its expanded height on un-collapse. Container size is consumer-driven\n // (set explicitly via `node.width` / `node.height`) — no measurement.\n useEffect(() => {\n const el = wrapperRef.current;\n if (!el || typeof ResizeObserver === \"undefined\") return;\n if (node.type === \"group\" || node.type === \"forEach\") return;\n const ro = new ResizeObserver(() => {\n // `offsetWidth/Height` are un-affected by ancestor CSS transforms\n // (the canvas viewport applies `scale(zoom)`). `getBoundingClientRect`\n // would scale with zoom and give us wildly wrong values when zoomed\n // in/out.\n bridge.reportDimensions(node.id, el.offsetWidth, el.offsetHeight);\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, [bridge, node.id, node.type]);\n\n const ctx = useMemo<FlowNodeContextValue>(\n () => ({ id: node.id, node, selected }),\n [node, selected],\n );\n\n // Track pointerdown coordinates so we can decide post-pointerup whether\n // this was a click or a drag. DOM fires `click` after a drag too, which\n // would otherwise re-open the config panel when the user only moved the\n // node. 5 px matches the platform's canvas `paneClickDistance` default.\n const downPosRef = useRef<{ x: number; y: number } | null>(null);\n const draggedRef = useRef(false);\n const CLICK_VS_DRAG_PX = 5;\n\n const handlePointerDown = (e: PointerEvent<HTMLDivElement>) => {\n // Only the primary (left) button starts a node drag. A right/middle\n // press must fall through to the context menu (and not stopPropagation),\n // so it can't begin a drag or collapse the selection (DEV-206).\n if (e.button !== 0) return;\n // Skip drag if the pointerdown originated on a handle — that gesture\n // is owned by the connect middleware.\n if ((e.target as HTMLElement).closest(\"[data-handle-id]\")) return;\n // Skip drag inside opt-out regions (allows form controls inside nodes).\n if ((e.target as HTMLElement).closest(\"[data-flow-no-drag='true']\")) return;\n e.stopPropagation();\n downPosRef.current = { x: e.clientX, y: e.clientY };\n draggedRef.current = false;\n // Pass through altKey — the canvas's drag middleware uses it for\n // Alt-detach (drop out of a parent group, or rebind into a new one).\n bridge.beginNodeDrag(node.id, e.pointerId, e.clientX, e.clientY, e.altKey);\n };\n\n const handlePointerMove = (e: PointerEvent<HTMLDivElement>) => {\n const start = downPosRef.current;\n if (!start || draggedRef.current) return;\n if (\n Math.abs(e.clientX - start.x) > CLICK_VS_DRAG_PX ||\n Math.abs(e.clientY - start.y) > CLICK_VS_DRAG_PX\n ) {\n draggedRef.current = true;\n }\n };\n\n const handleClick = (e: PointerEvent<HTMLDivElement>) => {\n if ((e.target as HTMLElement).closest(\"[data-handle-id]\")) return;\n e.stopPropagation();\n // Click that arrives after a drag is a synthetic side-effect — DO NOT\n // re-fire selection or notify the consumer (would re-open the panel\n // they were trying to keep on the original node).\n if (draggedRef.current) {\n draggedRef.current = false;\n downPosRef.current = null;\n return;\n }\n downPosRef.current = null;\n // Selection state was already updated at pointerdown by beginNodeDrag.\n // Here we re-assert it (handles meta-key toggle on already-selected\n // nodes) and ALSO notify the consumer of the click — which `selectNode`\n // intentionally no longer does on its own.\n bridge.selectNode(node.id, e.metaKey || e.ctrlKey || e.shiftKey);\n bridge.notifyNodeClick(node.id);\n };\n\n return (\n <div\n ref={wrapperRef}\n data-node-id={node.id}\n data-node-type={node.type}\n data-node-selected={selected ? \"true\" : \"false\"}\n className={cn(\n \"ods-flow-node-v2\",\n `ods-flow-node-v2--kind-${node.type}`,\n selected && \"ods-flow-node-v2--selected\",\n dragging && \"ods-flow-node-v2--dragging\",\n isConnecting && \"ods-flow-node-v2--connecting\",\n node.className,\n )}\n style={{\n position: \"absolute\",\n left: node.position.x,\n top: node.position.y,\n width: node.width ?? defaultWidth,\n // Z-stack (per architecture doc): groups (20) sit below normal\n // nodes (30) so children render visually on top of their parent\n // frame. Selection raises by 10. Consumer override wins.\n zIndex:\n node.zIndex ??\n (selected ? (node.type === \"group\" ? 35 : 40) : node.type === \"group\" ? 20 : 30),\n ...node.style,\n }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onClick={handleClick}\n >\n <FlowNodeContext.Provider value={ctx}>\n <Kind node={node} selected={selected} dragging={dragging} isConnecting={isConnecting} />\n </FlowNodeContext.Provider>\n </div>\n );\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FlowCanvasContext — imperative entry points used by Handle + FlowNode.\n// ════════════════════════════════════════════════════════════════════════\n// Each `<FlowCanvas>` creates a private context value containing the\n// callbacks needed by its descendants. We expose these via a \"dispatch\"\n// hook in the spirit of useReducer; the action payload is opaque to\n// descendants — they just know which method to call.\n\nimport { createContext, useContext } from \"react\";\n\nexport interface FlowDispatchAction {\n type: \"connection/start\";\n nodeId: string;\n handleId: string;\n handleType: \"source\" | \"target\";\n pointerId: number;\n clientX: number;\n clientY: number;\n}\n\nexport type FlowDispatch = (action: FlowDispatchAction) => void;\n\nexport const FlowDispatchContext = createContext<FlowDispatch | null>(null);\n\nexport function useFlowDispatch(): FlowDispatch {\n const dispatch = useContext(FlowDispatchContext);\n if (!dispatch) {\n throw new Error(\n \"[@octaviaflow/core/workflow] useFlowDispatch must be called inside <FlowCanvas>.\",\n );\n }\n return dispatch;\n}\n\n/**\n * Internal-only callbacks shared with FlowNode. Not part of the public\n * surface; node renderers use the `useFlowNodeContext` hook instead.\n */\nexport interface FlowNodeBridge {\n beginNodeDrag(\n nodeId: string,\n pointerId: number,\n clientX: number,\n clientY: number,\n altKey?: boolean,\n ): void;\n selectNode(nodeId: string, additive: boolean): void;\n /**\n * Fire the consumer's `onNodeClick` for this node. Split from\n * `selectNode` so drag-start (which selects the node so it carries the\n * selection style) does NOT also fire the click event — otherwise a\n * drag would re-open the config panel.\n */\n notifyNodeClick(nodeId: string): void;\n selectEdge(edgeId: string, additive: boolean): void;\n /**\n * Reports measured DOM dimensions back to the canvas. FlowNode observes\n * itself via ResizeObserver and calls this on size changes. The canvas\n * de-dupes (skips when w/h unchanged) and emits a `dimensions`\n * NodeChange so edges can recompute against the real footprint.\n */\n reportDimensions(nodeId: string, width: number, height: number): void;\n /** Removes a single node. Edges that reference it are dropped too. */\n deleteNode(nodeId: string): void;\n /**\n * Toggle the `data.collapsed` flag on a group / forEach container.\n * Used by the chevron in the GroupNode / ForEachNode header so the\n * user can expand/collapse the subflow without an external toolbar.\n * No-op for non-container kinds.\n */\n toggleNodeCollapse(nodeId: string): void;\n}\n\nexport const FlowNodeBridgeContext = createContext<FlowNodeBridge | null>(null);\n\nexport function useFlowNodeBridge(): FlowNodeBridge {\n const b = useContext(FlowNodeBridgeContext);\n if (!b) {\n throw new Error(\"[@octaviaflow/core/workflow] FlowNode must be a child of <FlowCanvas>.\");\n }\n return b;\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FlowNodeContext — descendants of a node (Handle, NodeToolbar, …) read\n// the node id and basic state through this context.\n// ════════════════════════════════════════════════════════════════════════\n\nimport { createContext, useContext } from \"react\";\nimport type { WorkflowNode } from \"../../editor\";\n\nexport interface FlowNodeContextValue {\n id: string;\n node: WorkflowNode;\n selected: boolean;\n}\n\nexport const FlowNodeContext = createContext<FlowNodeContextValue | null>(null);\n\nexport function useFlowNodeContext(): FlowNodeContextValue {\n const v = useContext(FlowNodeContext);\n if (!v) {\n throw new Error(\n \"[@octaviaflow/core/workflow] Handle / NodeToolbar must be inside a node renderer.\",\n );\n }\n return v;\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Node-kind registry — maps a `node.type` string to a React component.\n// ════════════════════════════════════════════════════════════════════════\n// We deliberately avoid the \"pass a `nodeTypes` map prop and pray the\n// caller memoises it\" anti-pattern. The registry is a stable map managed\n// internally; consumers can extend it via `useRegisterNodeKind()` or by\n// passing an override prop that is *frozen* by the canvas the first time\n// it sees it.\n\nimport type { ComponentType } from \"react\";\nimport type { WorkflowNode } from \"../../editor\";\n\n/**\n * Props passed to every kind renderer. Matches the public `NodeProps`\n * shape we expose to consumers; we deliberately do NOT duplicate\n * coordinate fields (see ADR-003).\n */\nexport interface NodeKindProps<TData = unknown> {\n /** The full node — kinds read `data`, can mutate via `updateNodeData`. */\n node: WorkflowNode<TData>;\n /** True when this node is the focus of selection. */\n selected: boolean;\n /** True while a drag is in progress on this node. */\n dragging: boolean;\n /** True when any connection drag is in flight and could end here. */\n isConnecting: boolean;\n}\n\nexport type NodeKindComponent<TData = unknown> = ComponentType<NodeKindProps<TData>>;\n\nexport type NodeKindRegistry = Record<string, NodeKindComponent>;\n\n/**\n * Build a registry from a default set plus optional overrides. The result\n * is a frozen object so consumers can't mutate it post-hoc.\n */\nexport function buildNodeKindRegistry(\n defaults: NodeKindRegistry,\n overrides?: NodeKindRegistry,\n): NodeKindRegistry {\n return Object.freeze({ ...defaults, ...(overrides ?? {}) });\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// Handle — a port primitive that custom node renderers drop in.\n// ════════════════════════════════════════════════════════════════════════\n// Responsibilities:\n// 1. Register its descriptor (nodeId, handleId, type, side, index, total)\n// so edges can resolve its absolute centre.\n// 2. Render a visible dot at the configured side.\n// 3. Initiate connection drags via Pointer Events.\n//\n// The Handle does NOT own pointermove / pointerup — those live on the\n// FlowCanvas-level connect middleware, which sees the gesture all the\n// way through even if the pointer leaves the handle.\n\nimport { type CSSProperties, type PointerEvent, useEffect, useRef } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport type { HandlePosition, HandleType } from \"../../editor\";\nimport { useFlowDispatch } from \"../FlowCanvas/FlowCanvasContext\";\nimport { useFlowNodeContext } from \"../FlowNode/FlowNodeContext\";\nimport { useHandleRegistry } from \"./handleRegistry\";\n\nexport interface HandleProps {\n /** `source` = connections start here; `target` = connections end here. */\n type: HandleType;\n /** Which side of the node the handle sits on. */\n position: HandlePosition;\n /**\n * Direction the edge should route from this handle. Defaults to\n * `position`. Override it when the handle dot sits on one edge but the\n * wire must leave/enter from another — e.g. a subflow's inner-facing\n * port lives on the frame's `top` edge yet its wire curves `down` into\n * the frame: `position=\"top\" routeSide=\"bottom\"`.\n */\n routeSide?: HandlePosition;\n /** Stable id within the node. Default `\"default\"`; required when >1 handle of same type. */\n id?: string;\n /** Defaults to true. Setting false disables both starting and ending here. */\n isConnectable?: boolean;\n /** Allow this handle to *start* a connection. Defaults to `isConnectable`. */\n isConnectableStart?: boolean;\n /** Allow this handle to *end* a connection. Defaults to `isConnectable`. */\n isConnectableEnd?: boolean;\n /** 0-based position among same-(node, side) handles. Defaults to 0. */\n index?: number;\n /** Total handles on the same (node, side). Defaults to 1. */\n total?: number;\n /** Optional caption rendered next to the dot (e.g. \"true\"/\"false\"). */\n label?: string;\n className?: string;\n style?: CSSProperties;\n}\n\nconst DEFAULT_HANDLE_ID = \"default\";\n\nexport function Handle({\n type,\n position,\n routeSide,\n id = DEFAULT_HANDLE_ID,\n isConnectable = true,\n isConnectableStart,\n isConnectableEnd,\n index = 0,\n total = 1,\n label,\n className,\n style,\n}: HandleProps) {\n const registry = useHandleRegistry();\n const node = useFlowNodeContext();\n const dispatch = useFlowDispatch();\n const ref = useRef<HTMLDivElement>(null);\n\n const canStart = isConnectableStart ?? isConnectable;\n const canEnd = isConnectableEnd ?? isConnectable;\n\n // Register on every render so changes to side/index/total are visible\n // immediately to edges. The registry de-dupes by (nodeId, handleId).\n useEffect(() => {\n const dispose = registry.register({\n nodeId: node.id,\n handleId: id,\n type,\n side: position,\n routeSide: routeSide ?? position,\n index,\n total,\n canStart,\n canEnd,\n });\n return dispose;\n }, [registry, node.id, id, type, position, routeSide, index, total, canStart, canEnd]);\n\n const handlePointerDown = (e: PointerEvent<HTMLDivElement>) => {\n if (!canStart) return;\n // Only the primary (left) button starts a connection drag (DEV-206).\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n dispatch({\n type: \"connection/start\",\n nodeId: node.id,\n handleId: id,\n handleType: type,\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n });\n };\n\n // Pointerup on a Handle is the \"drop on this handle\" gesture. The\n // FlowCanvas-level pointerup also fires; the canvas resolves the target\n // handle by hit-testing `e.target.closest('[data-handle-id]')`.\n return (\n <div\n ref={ref}\n data-handle-id={id}\n data-handle-node-id={node.id}\n data-handle-type={type}\n data-handle-side={position}\n data-handle-connectable-end={canEnd ? \"true\" : \"false\"}\n className={cn(\n \"ods-flow-handle\",\n `ods-flow-handle--${type}`,\n `ods-flow-handle--side-${position}`,\n !isConnectable && \"ods-flow-handle--disabled\",\n className,\n )}\n style={{\n ...handleSideStyle(position, index, total),\n ...style,\n }}\n onPointerDown={handlePointerDown}\n >\n <div className=\"ods-flow-handle__dot\" />\n {label && <span className=\"ods-flow-handle__label\">{label}</span>}\n </div>\n );\n}\n\n// Position the handle along its side. The visual element is small\n// (12 px), so we offset by half its size so the dot's centre lands on\n// the node's edge. Index/total spread multiple handles evenly.\nfunction handleSideStyle(side: HandlePosition, index: number, total: number): CSSProperties {\n const ratio = ((index + 1) / (total + 1)) * 100;\n switch (side) {\n case \"top\":\n return { position: \"absolute\", top: -6, left: `${ratio}%`, transform: \"translateX(-50%)\" };\n case \"bottom\":\n return { position: \"absolute\", bottom: -6, left: `${ratio}%`, transform: \"translateX(-50%)\" };\n case \"left\":\n return { position: \"absolute\", left: -6, top: `${ratio}%`, transform: \"translateY(-50%)\" };\n case \"right\":\n return { position: \"absolute\", right: -6, top: `${ratio}%`, transform: \"translateY(-50%)\" };\n }\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// NodeResizer — drag-to-resize handles attached to a node.\n// ════════════════════════════════════════════════════════════════════════\n// Dropped inside a custom node renderer. Four corner handles each adjust\n// width/height (and, where appropriate, position so the OPPOSITE corner\n// stays pinned). Width/height changes flow back through the imperative\n// instance via `updateNode`.\n//\n// Visible by default only when the host node is selected. Min/max sizes\n// + aspect-ratio lock keep the resize sensible. We deliberately do NOT\n// ship a `shouldResize` veto (yet) — that's a follow-on.\n\nimport { type CSSProperties, type PointerEvent, useRef } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport { useFlow } from \"../../hooks/useFlow\";\nimport { useViewport } from \"../../store/selectors\";\nimport { DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH } from \"../../utils/geometry\";\nimport { useFlowNodeContext } from \"../FlowNode/FlowNodeContext\";\n\nexport interface NodeResizerProps {\n /** Force-visible. Default: visible iff the host node is selected. */\n isVisible?: boolean;\n /** Lower bound for the resize. Defaults to 80×60. */\n minWidth?: number;\n minHeight?: number;\n /** Upper bound for the resize. Defaults unbounded. */\n maxWidth?: number;\n maxHeight?: number;\n /** Lock width:height ratio at the value computed from the node's\n * current dimensions on resize-start. */\n keepAspectRatio?: boolean;\n /** Fired on every pointermove during resize. */\n onResize?: (size: { width: number; height: number }) => void;\n /** Fired on pointerup (the committed size). */\n onResizeEnd?: (size: { width: number; height: number }) => void;\n /** Override handle colour. */\n color?: string;\n}\n\ntype Corner = \"nw\" | \"ne\" | \"sw\" | \"se\";\n\ninterface DragState {\n pointerId: number;\n corner: Corner;\n startClientX: number;\n startClientY: number;\n startWidth: number;\n startHeight: number;\n startX: number;\n startY: number;\n aspect: number; // w / h\n}\n\nexport function NodeResizer({\n isVisible,\n minWidth = 80,\n minHeight = 60,\n maxWidth,\n maxHeight,\n keepAspectRatio = false,\n onResize,\n onResizeEnd,\n color,\n}: NodeResizerProps) {\n const { node, selected } = useFlowNodeContext();\n const viewport = useViewport();\n const flow = useFlow();\n const dragRef = useRef<DragState | null>(null);\n\n const show = isVisible ?? selected;\n if (!show) return null;\n\n const beginResize = (e: PointerEvent<HTMLDivElement>, corner: Corner) => {\n // Only the primary (left) button resizes — a right/middle press must not\n // start a resize gesture (DEV-206).\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n const w = node.width ?? DEFAULT_NODE_WIDTH;\n const h = node.height ?? DEFAULT_NODE_HEIGHT;\n dragRef.current = {\n pointerId: e.pointerId,\n corner,\n startClientX: e.clientX,\n startClientY: e.clientY,\n startWidth: w,\n startHeight: h,\n startX: node.position.x,\n startY: node.position.y,\n aspect: w / Math.max(1, h),\n };\n };\n\n const onMove = (e: PointerEvent<HTMLDivElement>) => {\n const drag = dragRef.current;\n if (!drag || drag.pointerId !== e.pointerId) return;\n const dx = (e.clientX - drag.startClientX) / viewport.zoom;\n const dy = (e.clientY - drag.startClientY) / viewport.zoom;\n // The edges OPPOSITE the dragged corner are anchored — they must not\n // move. Capture them up front so we can re-derive the top-left from the\n // CLAMPED size below. Deriving position from the raw pointer delta made\n // the node slide across the canvas once a corner hit its min/max clamp:\n // the size stopped changing but the position kept tracking the pointer\n // (DEV-206).\n const fixedRight = drag.startX + drag.startWidth;\n const fixedBottom = drag.startY + drag.startHeight;\n let nextW = drag.startWidth;\n let nextH = drag.startHeight;\n switch (drag.corner) {\n case \"se\":\n nextW = drag.startWidth + dx;\n nextH = drag.startHeight + dy;\n break;\n case \"sw\":\n nextW = drag.startWidth - dx;\n nextH = drag.startHeight + dy;\n break;\n case \"ne\":\n nextW = drag.startWidth + dx;\n nextH = drag.startHeight - dy;\n break;\n case \"nw\":\n nextW = drag.startWidth - dx;\n nextH = drag.startHeight - dy;\n break;\n }\n if (keepAspectRatio) {\n // Maintain the original ratio — fit height to width.\n nextH = nextW / drag.aspect;\n }\n nextW = Math.max(minWidth, maxWidth ? Math.min(maxWidth, nextW) : nextW);\n nextH = Math.max(minHeight, maxHeight ? Math.min(maxHeight, nextH) : nextH);\n // Re-derive the top-left from the CLAMPED size so the anchored edges stay\n // put. `se` keeps the top-left fixed; the others anchor the opposite\n // right/bottom edge.\n let nextX = drag.startX;\n let nextY = drag.startY;\n switch (drag.corner) {\n case \"se\":\n break;\n case \"sw\":\n nextX = fixedRight - nextW;\n break;\n case \"ne\":\n nextY = fixedBottom - nextH;\n break;\n case \"nw\":\n nextX = fixedRight - nextW;\n nextY = fixedBottom - nextH;\n break;\n }\n flow.updateNode(node.id, {\n width: nextW,\n height: nextH,\n position: { x: nextX, y: nextY },\n });\n onResize?.({ width: nextW, height: nextH });\n };\n\n const onUp = (e: PointerEvent<HTMLDivElement>) => {\n if (dragRef.current?.pointerId === e.pointerId) {\n const cur = flow.getNode(node.id);\n if (cur) {\n onResizeEnd?.({\n width: cur.width ?? DEFAULT_NODE_WIDTH,\n height: cur.height ?? DEFAULT_NODE_HEIGHT,\n });\n }\n dragRef.current = null;\n }\n };\n\n const handleColor = color ?? \"var(--ods-accent)\";\n const handleStyle = (corner: Corner): CSSProperties => {\n const base: CSSProperties = {\n position: \"absolute\",\n width: 12,\n height: 12,\n background: \"var(--ods-surface-canvas)\",\n border: `2px solid ${handleColor}`,\n borderRadius: 2,\n cursor: cursorFor(corner),\n touchAction: \"none\",\n // Place each handle so its CENTRE sits on the corresponding corner.\n transform: \"translate(-50%, -50%)\",\n };\n switch (corner) {\n case \"nw\":\n return { ...base, top: 0, left: 0 };\n case \"ne\":\n return { ...base, top: 0, left: \"100%\" };\n case \"sw\":\n return { ...base, top: \"100%\", left: 0 };\n case \"se\":\n return { ...base, top: \"100%\", left: \"100%\" };\n }\n };\n\n return (\n <div className={cn(\"ods-node-resizer\")} data-flow-no-drag=\"true\">\n {([\"nw\", \"ne\", \"sw\", \"se\"] as Corner[]).map((corner) => (\n <div\n key={corner}\n style={handleStyle(corner)}\n onPointerDown={(e) => beginResize(e, corner)}\n onPointerMove={onMove}\n onPointerUp={onUp}\n onPointerCancel={onUp}\n aria-label={`Resize ${corner}`}\n />\n ))}\n </div>\n );\n}\n\nfunction cursorFor(corner: Corner): string {\n // Standard 8-direction resize cursors. We only ship corners for v1; the\n // edge handles (n/s/e/w) can come later.\n switch (corner) {\n case \"nw\":\n case \"se\":\n return \"nwse-resize\";\n case \"ne\":\n case \"sw\":\n return \"nesw-resize\";\n }\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// BaseNode — shared chrome for built-in kinds.\n// ════════════════════════════════════════════════════════════════════════\n// Visual structure (mirrors the finalised platform node):\n//\n// ┌─[ KIND ]──────────────────────────────────┐ ← external pill = node TYPE\n// │ ╭──╮ Title (node NAME) │\n// │ │● │ ▸ [CHIP] description-value │ ← chip + value (config-driven)\n// │ ╰──╯ │\n// │ [×] │ ← delete bottom-right\n// └──────────────────────────────────────────[●] ← status top-right\n//\n// The pill is the node TYPE label (e.g. \"HTTP\", \"WEBHOOK\", \"ACTION\") —\n// not the node name. The name lives in the body title. The body's info\n// line takes an optional `chip` (small inline badge) plus a value, which\n// is the canonical pattern for showing the most-relevant config value\n// (HTTP method + path, condition operator + expression, etc.).\n\nimport { TrashCanIcon } from \"@octaviaflow/icons\";\nimport { type ReactNode, useContext } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport { FlowNodeBridgeContext } from \"../FlowCanvas/FlowCanvasContext\";\nimport { FlowNodeContext } from \"../FlowNode/FlowNodeContext\";\n\nexport type BaseNodeStatus = \"idle\" | \"running\" | \"success\" | \"error\" | \"warning\";\n\nexport interface BaseNodeProps {\n /** Pill label — the node TYPE/category (e.g. \"HTTP\", \"WEBHOOK\", \"ACTION\"). */\n kind: ReactNode;\n /** Optional small icon inside the pill, left of the kind label. */\n kindIcon?: ReactNode;\n /** Icon shown in the body bubble (32px circle). */\n icon?: ReactNode;\n /** Bold name shown in the body — this is the user-facing instance name. */\n title: ReactNode;\n /**\n * Optional chip rendered before the description text — used for\n * configuration values like HTTP method (\"GET\"), condition operator\n * (\"==\"), execution mode, etc. Inherits the accent colour.\n */\n chip?: ReactNode;\n /**\n * The body description / value — typically the most-relevant config\n * field (path, url, expression). Clamps to two lines.\n */\n description?: ReactNode;\n /**\n * Generic right-aligned chip slot. Renders inside the info row to the\n * right of the description (e.g. an `/v1/orders/:id` path chip next to\n * a `GET` method `chip`). Inherits the kind accent like `chip` does.\n */\n valueChip?: ReactNode;\n /** Per-kind accent — paints the pill background and the chip. */\n accent?: \"blue\" | \"violet\" | \"amber\" | \"green\" | \"red\" | \"slate\";\n /** Status dot in the top-right corner (config / runtime). */\n status?: BaseNodeStatus;\n /**\n * Delete button click — when set, the corner [×] button uses this. If\n * omitted, BaseNode auto-wires it through the FlowCanvas bridge so the\n * default behaviour is \"this button deletes me\". Pass `false` to hide.\n */\n onDelete?: (() => void) | false;\n /** Footer slot below the description (e.g. additional metadata). */\n footer?: ReactNode;\n className?: string;\n /** Handles + extras — positioned absolutely by the caller. */\n children?: ReactNode;\n}\n\nexport function BaseNode({\n kind,\n kindIcon,\n icon,\n title,\n chip,\n description,\n valueChip,\n accent = \"green\",\n status,\n onDelete,\n footer,\n className,\n children,\n}: BaseNodeProps) {\n // Auto-wire delete via the canvas bridge when the kind didn't pass an\n // explicit handler. `onDelete={false}` disables the button entirely.\n const ctx = useContext(FlowNodeContext);\n const bridge = useContext(FlowNodeBridgeContext);\n const deleteHandler: (() => void) | undefined =\n onDelete === false\n ? undefined\n : (onDelete ?? (ctx && bridge ? () => bridge.deleteNode(ctx.id) : undefined));\n return (\n <div\n className={cn(\n \"ods-flow-base-node\",\n `ods-flow-base-node--accent-${accent}`,\n status && `ods-flow-base-node--status-${status}`,\n className,\n )}\n >\n {/* External pill — the node TYPE label, not the name. */}\n <div className=\"ods-flow-base-node__pill\">\n {kindIcon && (\n <span className=\"ods-flow-base-node__pill-icon\" aria-hidden=\"true\">\n {kindIcon}\n </span>\n )}\n <span className=\"ods-flow-base-node__pill-label\">{kind}</span>\n </div>\n\n {/* Status indicator — top-right of the card. */}\n {status && status !== \"idle\" && (\n <span\n className={cn(\"ods-flow-base-node__status\", `ods-flow-base-node__status--${status}`)}\n aria-hidden=\"true\"\n />\n )}\n\n {/* Body */}\n <div className=\"ods-flow-base-node__body\">\n <div className=\"ods-flow-base-node__content\">\n <div className=\"ods-flow-base-node__bubble\" aria-hidden=\"true\">\n {icon}\n </div>\n <div className=\"ods-flow-base-node__content-text\">\n <div className=\"ods-flow-base-node__content-title\">{title}</div>\n {(chip !== undefined || description !== undefined || valueChip !== undefined) && (\n <div className=\"ods-flow-base-node__content-info\">\n {chip !== undefined && <span className=\"ods-flow-base-node__chip\">{chip}</span>}\n {description !== undefined && (\n <span className=\"ods-flow-base-node__description\">{description}</span>\n )}\n {valueChip !== undefined && (\n <span className=\"ods-flow-base-node__value-chip\">{valueChip}</span>\n )}\n </div>\n )}\n </div>\n </div>\n\n {footer && <div className=\"ods-flow-base-node__footer\">{footer}</div>}\n\n {deleteHandler && (\n <button\n type=\"button\"\n className=\"ods-flow-base-node__delete\"\n onClick={(e) => {\n e.stopPropagation();\n deleteHandler();\n }}\n aria-label=\"Delete node\"\n data-flow-no-drag=\"true\"\n title=\"Delete node\"\n >\n <TrashCanIcon size={16} aria-hidden />\n </button>\n )}\n </div>\n\n {/* Handles + extras slot. */}\n {children}\n </div>\n );\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// Built-in node kinds — Action / Trigger / Condition / Group.\n// ════════════════════════════════════════════════════════════════════════\n// Each kind is a small functional component that composes BaseNode and\n// adds its own Handle layout. Additional kinds (Loop, Parallel, Wait,\n// Output, Error, Sticky) will land in a follow-up pass.\n\nimport type { PointerEvent } from \"react\";\nimport { useFlowNodeBridge } from \"../FlowCanvas/FlowCanvasContext\";\nimport type { NodeKindComponent, NodeKindProps, NodeKindRegistry } from \"../FlowNode/nodeKinds\";\nimport { Handle } from \"../Handle/Handle\";\nimport { NodeResizer } from \"../NodeResizer/NodeResizer\";\nimport { BaseNode, type BaseNodeStatus } from \"./BaseNode\";\n\n// Common payload shape that built-in kinds expect. Consumers can extend\n// `data` with their own fields; the renderer just reads the named slots.\nexport interface BuiltInNodeData {\n /** Pill label override — defaults to the kind's canonical type label\n * (e.g. \"HTTP\", \"WEBHOOK\", \"ACTION\"). Rarely needed; mostly here so\n * consumers can rename \"HTTP\" → \"REST\" without forking the kind. */\n kind?: import(\"react\").ReactNode;\n /** Body name — the user-facing instance label (e.g. \"Fetch Order\"). */\n title?: string;\n /**\n * Optional chip rendered before the description value, used for\n * configuration metadata that should read at a glance — HTTP method,\n * condition operator, schedule frequency, etc. Renders as a coloured\n * inline badge that inherits the kind accent.\n */\n chip?: import(\"react\").ReactNode;\n /** Description / config value — the most-relevant config field (path,\n * url, expression). Clamped to two lines in the body. */\n description?: import(\"react\").ReactNode;\n /**\n * Generic right-aligned chip slot — used when a node has a secondary\n * config value to surface (e.g. the path `/v1/orders/:id` next to an\n * HTTP `GET` method chip). Inherits the kind accent.\n */\n valueChip?: import(\"react\").ReactNode;\n /** Legacy alias for `description` — older fixtures still pass this. */\n subtitle?: import(\"react\").ReactNode;\n /** Legacy alias for `chip` — older fixtures still pass this. */\n badge?: import(\"react\").ReactNode;\n /** Runtime status — drives the pulsing dot in the top-right corner. */\n status?: BaseNodeStatus;\n /** Body bubble icon (32px circle). */\n icon?: import(\"react\").ReactNode;\n // Condition-specific:\n branches?: { id: string; label: string }[];\n // Group-specific:\n collapsed?: boolean;\n /** Populated by `collapseFor()` — number of descendants hidden under\n * this collapsed group; the renderer shows it as a \"N steps\" badge. */\n hiddenCount?: number;\n /** Dim the container's frame to signal \"the engine will skip this\n * subflow + all descendants\". Visual only — semantics enforced by\n * the consumer's execution layer. */\n disabled?: boolean;\n // ForEach-specific:\n iterator?: string;\n // Wait-specific (not yet implemented; reserved):\n waitMs?: number;\n // Webhook / HttpRequest-specific helpers — populate `chip` + `description`\n // automatically when present.\n method?: string;\n path?: string;\n url?: string;\n}\n\n// ────────────────────────────────────────────────────────────────────────\n// ActionNode — generic action; 1 input on top + 1 output on bottom.\n// ────────────────────────────────────────────────────────────────────────\nexport const ActionNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"ACTION\"}\n icon={d.icon}\n title={d.title ?? \"Action\"}\n chip={d.chip ?? d.badge}\n description={d.description ?? d.subtitle}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"green\"\n >\n <Handle type=\"target\" position=\"top\" />\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// TriggerNode — no input port; green accent matches the platform.\n// ────────────────────────────────────────────────────────────────────────\nexport const TriggerNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"TRIGGER\"}\n icon={d.icon}\n title={d.title ?? \"Trigger\"}\n chip={d.chip}\n description={d.description ?? \"Manually triggered\"}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"green\"\n >\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// ConditionNode — single input on top; multiple labelled outputs along\n// the bottom edge. Default branches: true / false.\n// ────────────────────────────────────────────────────────────────────────\nexport const ConditionNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n const branches = d.branches ?? [\n { id: \"true\", label: \"true\" },\n { id: \"false\", label: \"false\" },\n ];\n return (\n <BaseNode\n kind={d.kind ?? \"CONDITION\"}\n icon={d.icon}\n title={d.title ?? \"Condition\"}\n chip={d.chip ?? d.badge}\n description={d.description ?? d.subtitle}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"amber\"\n >\n <Handle type=\"target\" position=\"top\" />\n {branches.map((b, i) => (\n <Handle\n key={b.id}\n type=\"source\"\n position=\"bottom\"\n id={b.id}\n index={i}\n total={branches.length}\n label={b.label}\n />\n ))}\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// GroupNode — frame container for sub-flows. Children render absolutely\n// positioned (per ADR-003) on top of the frame.\n//\n// When `data.collapsed === true`:\n// - Body collapses to the header strip.\n// - Two perimeter handles are registered (`__group_in` on top,\n// `__group_out` on bottom). The `collapseFor()` helper rewrites\n// edges that cross the boundary so they terminate at these handles\n// instead of dangling at hidden children.\n// - A count badge (\"N steps\") is rendered next to the title.\n// ────────────────────────────────────────────────────────────────────────\nexport const GroupNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n const collapsed = !!d.collapsed;\n const disabled = !!d.disabled;\n // The host (or `collapseFor`) reports the descendant count via\n // `node.data.hiddenCount`. We fall back to undefined → no badge.\n const hiddenCount = (d as { hiddenCount?: number }).hiddenCount;\n const bridge = useFlowNodeBridge();\n // The chevron is a button — clicking it (and only it) toggles collapse.\n // We stop propagation so the click doesn't also bubble up to the node\n // wrapper's selection / drag-start gestures. `data-flow-no-drag` keeps\n // pointerdown from starting a node drag.\n const onChevronClick = (e: PointerEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n bridge.toggleNodeCollapse(node.id);\n };\n return (\n <div\n className=\"ods-flow-group\"\n data-collapsed={collapsed ? \"true\" : \"false\"}\n data-disabled={disabled ? \"true\" : undefined}\n style={{\n width: node.width ?? 360,\n height: collapsed ? 36 : (node.height ?? 200),\n }}\n >\n {/* Built-in corner-resize handles. Hidden when collapsed (resize\n a 36px-tall strip makes no sense). Visibility otherwise\n defaults to \"node is selected\" — driven by FlowNodeContext. */}\n {!collapsed && <NodeResizer minWidth={240} minHeight={120} />}\n\n <div className=\"ods-flow-group__header\" data-flow-no-drag=\"false\">\n <button\n type=\"button\"\n className=\"ods-flow-group__chevron\"\n data-flow-no-drag=\"true\"\n aria-label={collapsed ? \"Expand group\" : \"Collapse group\"}\n aria-expanded={!collapsed}\n onClick={onChevronClick}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {collapsed ? \"▸\" : \"▾\"}\n </button>\n <span className=\"ods-flow-group__title\">{d.title ?? \"Group\"}</span>\n {d.subtitle && <span className=\"ods-flow-group__subtitle\">{d.subtitle}</span>}\n {disabled && (\n <span className=\"ods-flow-group__disabled-badge\" aria-label=\"Disabled subflow\">\n Disabled\n </span>\n )}\n {collapsed && hiddenCount !== undefined && hiddenCount > 0 && (\n <span className=\"ods-flow-group__count\" aria-label={`${hiddenCount} hidden steps`}>\n {hiddenCount} steps\n </span>\n )}\n </div>\n\n {/* Canonical perimeter handles — 1 input on top, 1 output on\n bottom. Visible primary interaction surface (was previously\n muted on expanded mode; now they ARE the user-facing ports).\n Ids stay stable for `collapseFor()` edge rewriting. */}\n <Handle type=\"target\" position=\"top\" id=\"__group_in\" />\n <Handle type=\"source\" position=\"bottom\" id=\"__group_out\" />\n </div>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// ForEachNode — iteration step. A SIMPLE node (NOT a container), shaped\n// like ConditionNode: 1 input on top, 2 labelled outputs on the bottom:\n//\n// - \"Each\" — the loop body; the subgraph wired here runs once per item.\n// - \"Done\" — the post-iteration exit; runs after every item completes.\n//\n// Branch handle ids come from `data.branches` (the consumer's port ids,\n// e.g. `…_output_each` / `…_output_done`) so saved edges anchor exactly;\n// falls back to `each` / `done` when none are supplied. The engine\n// resolves the loop body by following edges from the `…_each` port — no\n// `parentId` nesting, so forEach is a plain node in the chain.\n// ────────────────────────────────────────────────────────────────────────\nexport const ForEachNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n const branches = d.branches ?? [\n { id: \"each\", label: \"Each\" },\n { id: \"done\", label: \"Done\" },\n ];\n return (\n <BaseNode\n kind={d.kind ?? \"FOR EACH\"}\n icon={d.icon}\n title={d.title ?? \"For each\"}\n chip={d.chip ?? d.badge}\n description={d.description ?? d.subtitle ?? d.iterator}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"amber\"\n >\n <Handle type=\"target\" position=\"top\" />\n {branches.map((b, i) => (\n <Handle\n key={b.id}\n type=\"source\"\n position=\"bottom\"\n id={b.id}\n index={i}\n total={branches.length}\n label={b.label}\n />\n ))}\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// OutputNode — terminal node; no output port. Pill reads \"OUTPUT\".\n// ────────────────────────────────────────────────────────────────────────\nexport const OutputNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"OUTPUT\"}\n icon={d.icon}\n title={d.title ?? \"Output\"}\n chip={d.chip ?? d.badge}\n description={d.description ?? d.subtitle}\n status={d.status}\n accent=\"green\"\n >\n <Handle type=\"target\" position=\"top\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// ErrorNode — failure handler; red accent.\n// ────────────────────────────────────────────────────────────────────────\nexport const ErrorNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"ERROR\"}\n icon={d.icon}\n title={d.title ?? \"On error\"}\n chip={d.chip ?? d.badge}\n description={d.description ?? d.subtitle}\n status={d.status ?? \"error\"}\n accent=\"red\"\n >\n <Handle type=\"target\" position=\"top\" />\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// WaitNode — pause execution. Chip surfaces the duration when provided.\n// ────────────────────────────────────────────────────────────────────────\nexport const WaitNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n const waitMs = (d as { waitMs?: number }).waitMs;\n const durationChip = waitMs ? `${Math.round(waitMs / 100) / 10}s` : undefined;\n return (\n <BaseNode\n kind={d.kind ?? \"WAIT\"}\n icon={d.icon}\n title={d.title ?? \"Wait\"}\n chip={d.chip ?? durationChip}\n description={d.description ?? (durationChip ? \"Pause execution\" : undefined)}\n status={d.status}\n accent=\"violet\"\n >\n <Handle type=\"target\" position=\"top\" />\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// ParallelNode — fan-out: one input, N parallel outputs.\n// ────────────────────────────────────────────────────────────────────────\nexport const ParallelNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n const branches = d.branches ?? [\n { id: \"a\", label: \"a\" },\n { id: \"b\", label: \"b\" },\n ];\n return (\n <BaseNode\n kind={d.kind ?? \"PARALLEL\"}\n icon={d.icon}\n title={d.title ?? \"Parallel\"}\n chip={d.chip ?? `${branches.length}×`}\n description={d.description ?? \"Fan-out branches\"}\n status={d.status}\n accent=\"blue\"\n >\n <Handle type=\"target\" position=\"top\" />\n {branches.map((b, i) => (\n <Handle\n key={b.id}\n type=\"source\"\n position=\"bottom\"\n id={b.id}\n index={i}\n total={branches.length}\n label={b.label}\n />\n ))}\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// StickyNode — non-executing annotation. No ports. Renders behind nodes.\n// Multi-line `data.description` is the body.\n// ────────────────────────────────────────────────────────────────────────\nexport const StickyNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <div\n className=\"ods-flow-sticky\"\n style={{\n width: node.width ?? 240,\n minHeight: node.height ?? 120,\n }}\n >\n {d.title && <div className=\"ods-flow-sticky__title\">{d.title}</div>}\n {d.description && <div className=\"ods-flow-sticky__body\">{d.description}</div>}\n </div>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// WebhookNode — specialised Trigger. Pill = \"WEBHOOK\"; chip = HTTP\n// method; description = path (the most-relevant config value).\n// ────────────────────────────────────────────────────────────────────────\nexport const WebhookNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"WEBHOOK\"}\n icon={d.icon}\n title={d.title ?? \"Webhook\"}\n chip={d.chip ?? d.method ?? \"POST\"}\n description={d.description ?? d.path ?? \"/hooks/incoming\"}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"blue\"\n >\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// HttpRequestNode — Action variant. Pill = \"HTTP\"; chip = HTTP method;\n// description = url (the most-relevant config value).\n// ────────────────────────────────────────────────────────────────────────\nexport const HttpRequestNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"HTTP\"}\n icon={d.icon}\n title={d.title ?? \"HTTP Request\"}\n chip={d.chip ?? d.method ?? \"GET\"}\n description={d.description ?? d.url ?? \"Call an API\"}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"blue\"\n >\n <Handle type=\"target\" position=\"top\" />\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// Default registry — the canvas merges this with any consumer overrides.\n// ────────────────────────────────────────────────────────────────────────\nexport const DEFAULT_NODE_KINDS: NodeKindRegistry = {\n action: ActionNode as NodeKindComponent,\n trigger: TriggerNode as NodeKindComponent,\n condition: ConditionNode as NodeKindComponent,\n group: GroupNode as NodeKindComponent,\n forEach: ForEachNode as NodeKindComponent,\n output: OutputNode as NodeKindComponent,\n error: ErrorNode as NodeKindComponent,\n wait: WaitNode as NodeKindComponent,\n parallel: ParallelNode as NodeKindComponent,\n sticky: StickyNode as NodeKindComponent,\n webhook: WebhookNode as NodeKindComponent,\n httpRequest: HttpRequestNode as NodeKindComponent,\n};\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FxPanel — the Data References catalogue that docks beside the ConfigPanel.\n// ════════════════════════════════════════════════════════════════════════\n// A searchable catalogue of expression building-blocks:\n// - Functions — flat lists (CONCAT, UPPER, …).\n// - Variables — flat lists of system/session tokens.\n// - Source Data — an n-th-level NESTED TREE of upstream-node output\n// fields. Objects + arrays-of-objects are expandable branches;\n// primitives are leaves.\n//\n// Every item is draggable into any field, click-to-insert. The component\n// is data-driven: the consumer supplies `categories`; FxPanel owns\n// search, the accordion, the tree expansion, keyboard navigation, and\n// the drag affordances.\n\nimport {\n type CSSProperties,\n type DragEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n ChevronDownIcon,\n ChevronRightIcon,\n CloseIcon,\n CollapseAllIcon,\n DraggableIcon,\n ExpandAllIcon,\n FunctionMathIcon,\n SearchIcon,\n ValueVariableIcon,\n} from \"@octaviaflow/icons\";\nimport { cn } from \"../../../utils/cn\";\n\nexport type FxItemKind = \"function\" | \"variable\";\n\n/** Data type of a Source-Data field — drives the colour-coded badge. */\nexport type FxValueType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"object\"\n | \"array\"\n | \"date\"\n | \"any\";\n\nexport interface FxPanelItem {\n /** Stable key + tree/keyboard identity. */\n id: string;\n /** Display label — a function signature, variable name, or field key. */\n label: string;\n /**\n * The string handed to `dataTransfer` / inserted into a field.\n * Branches may still set it (drag the whole object/array reference).\n */\n insertValue?: string;\n /** Short one-line description shown under the label. */\n description?: string;\n /** Data type — renders a colour-coded badge. Source-Data fields only. */\n valueType?: FxValueType;\n /**\n * Nested children. When present the item renders as an expandable\n * branch — this is what powers the n-th-level Source-Data tree.\n */\n children?: FxPanelItem[];\n}\n\nexport interface FxPanelCategory {\n /** Stable key + accordion identity. */\n id: string;\n /** Section heading. */\n label: string;\n /** Drives the badge glyph + drag payload. Defaults to \"function\". */\n kind?: FxItemKind;\n /** Items — flat for functions/variables, nested for Source Data. */\n items: FxPanelItem[];\n}\n\nexport interface FxPanelProps {\n /** Categorised entries. Empty categories are dropped from render. */\n categories: FxPanelCategory[];\n /** Header title. Default \"Data References\". */\n title?: ReactNode;\n /** Instructional line under the search. Pass `null` to hide it. */\n hint?: ReactNode;\n /** Controlled search term. */\n search?: string;\n /** Initial search term when uncontrolled. */\n defaultSearch?: string;\n onSearchChange?: (next: string) => void;\n /** Controlled open category (single-open accordion). `null` = closed. */\n expandedCategory?: string | null;\n /** Initial open category when uncontrolled. */\n defaultExpandedCategory?: string | null;\n onExpandedCategoryChange?: (id: string | null) => void;\n /** Close (✕) handler. Omit to hide the close button. */\n onClose?: () => void;\n /**\n * Fires when an item begins dragging. Use it to populate\n * `e.dataTransfer`. When omitted, FxPanel writes a sensible default:\n * - `text/plain` → insertValue\n * - `application/x-fx-insert` → insertValue\n * - `application/x-fx-type` → category kind\n */\n onItemDragStart?: (\n item: FxPanelItem,\n category: FxPanelCategory,\n e: DragEvent<HTMLElement>,\n ) => void;\n /** Fires on click / Enter of an item (insert at cursor). */\n onItemSelect?: (item: FxPanelItem, category: FxPanelCategory) => void;\n /** Panel width (px). Default 300. */\n width?: number;\n /** Message shown when a search matches nothing. Default \"No matches\". */\n emptyLabel?: ReactNode;\n /** Placeholder for the search box. */\n searchPlaceholder?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n// Category badge icon — a relatable glyph per kind (functions get the\n// math-function mark, variables/data get the value-variable mark).\nconst KIND_ICON: Record<FxItemKind, typeof FunctionMathIcon> = {\n function: FunctionMathIcon,\n variable: ValueVariableIcon,\n};\n\n// ── Tree helpers ─────────────────────────────────────────────────────────\n\n/** Recursively count leaf items (primitives — the drag end-points). */\nfunction countLeaves(items: FxPanelItem[]): number {\n let n = 0;\n for (const it of items) {\n if (it.children && it.children.length > 0) n += countLeaves(it.children);\n else n += 1;\n }\n return n;\n}\n\n/** Collect the ids of every branch (has children) under `items`. */\nfunction collectBranchIds(items: FxPanelItem[], out: Set<string>): void {\n for (const it of items) {\n if (it.children && it.children.length > 0) {\n out.add(it.id);\n collectBranchIds(it.children, out);\n }\n }\n}\n\ninterface FlatRow {\n item: FxPanelItem;\n depth: number;\n hasChildren: boolean;\n expanded: boolean;\n}\n\n/** Flatten the visible tree (respecting `expandedItems`) into draw rows. */\nfunction flattenTree(\n items: FxPanelItem[],\n depth: number,\n expandedItems: Set<string>,\n out: FlatRow[],\n): void {\n for (const it of items) {\n const hasChildren = !!it.children && it.children.length > 0;\n const expanded = hasChildren && expandedItems.has(it.id);\n out.push({ item: it, depth, hasChildren, expanded });\n if (expanded) flattenTree(it.children!, depth + 1, expandedItems, out);\n }\n}\n\ninterface SearchHit {\n item: FxPanelItem;\n /** Ancestor labels (excluding the item itself) for the path crumb. */\n ancestors: string[];\n}\n\n/** Collect leaf items whose label / description / path matches `q`. */\nfunction collectHits(\n items: FxPanelItem[],\n ancestors: string[],\n q: string,\n out: SearchHit[],\n): void {\n for (const it of items) {\n if (it.children && it.children.length > 0) {\n collectHits(it.children, [...ancestors, it.label], q, out);\n } else {\n const path = [...ancestors, it.label].join(\" / \");\n const hay =\n `${it.label} ${it.description ?? \"\"} ${path} ${it.insertValue ?? \"\"}`.toLowerCase();\n if (hay.includes(q)) out.push({ item: it, ancestors });\n }\n }\n}\n\n// ════════════════════════════════════════════════════════════════════════\n\nexport function FxPanel({\n categories,\n title = \"Data References\",\n hint = \"Drag onto a field, or click an item to insert it.\",\n search: controlledSearch,\n defaultSearch = \"\",\n onSearchChange,\n expandedCategory: controlledExpanded,\n defaultExpandedCategory,\n onExpandedCategoryChange,\n onClose,\n onItemDragStart,\n onItemSelect,\n width = 300,\n emptyLabel = \"No matches\",\n searchPlaceholder = \"Search fields, functions & variables…\",\n className,\n style,\n}: FxPanelProps) {\n // ── Search — controlled or uncontrolled ─────────────────────────────\n const [internalSearch, setInternalSearch] = useState(defaultSearch);\n const search = controlledSearch ?? internalSearch;\n const query = search.trim().toLowerCase();\n const setSearch = (next: string) => {\n if (controlledSearch === undefined) setInternalSearch(next);\n onSearchChange?.(next);\n };\n\n // Non-empty categories only — empty ones never render.\n const visibleCategories = useMemo(\n () => categories.filter((c) => c.items.length > 0),\n [categories],\n );\n\n // ── Category accordion — controlled or uncontrolled ────────────────\n const [internalCat, setInternalCat] = useState<string | null>(\n defaultExpandedCategory !== undefined\n ? defaultExpandedCategory\n : (visibleCategories[0]?.id ?? null),\n );\n const openCategoryId = controlledExpanded ?? internalCat;\n const setOpenCategory = (id: string | null) => {\n if (controlledExpanded === undefined) setInternalCat(id);\n onExpandedCategoryChange?.(id);\n };\n\n // ── Tree expansion — branch ids that are open. Defaults to every\n // depth-0 branch so the first level of each tree shows on open. ──\n const [expandedItems, setExpandedItems] = useState<Set<string>>(() => {\n const ids = new Set<string>();\n for (const cat of categories) {\n for (const item of cat.items) {\n if (item.children && item.children.length > 0) ids.add(item.id);\n }\n }\n return ids;\n });\n const toggleItem = (id: string) => {\n setExpandedItems((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n const setCategoryExpansion = (cat: FxPanelCategory, expand: boolean) => {\n const branchIds = new Set<string>();\n collectBranchIds(cat.items, branchIds);\n setExpandedItems((prev) => {\n const next = new Set(prev);\n for (const id of branchIds) {\n if (expand) next.add(id);\n else next.delete(id);\n }\n return next;\n });\n };\n\n // ── Transient UI state ──────────────────────────────────────────────\n const [draggingId, setDraggingId] = useState<string | null>(null);\n const [focusedId, setFocusedId] = useState<string | null>(null);\n\n // ── Search results ──────────────────────────────────────────────────\n const hits = useMemo(() => {\n if (!query) return null;\n const all: { category: FxPanelCategory; hit: SearchHit }[] = [];\n for (const cat of visibleCategories) {\n const out: SearchHit[] = [];\n collectHits(cat.items, [], query, out);\n for (const hit of out) all.push({ category: cat, hit });\n }\n return all;\n }, [query, visibleCategories]);\n\n // ── Drag / copy / insert ────────────────────────────────────────────\n const handleDragStart =\n (item: FxPanelItem, category: FxPanelCategory) =>\n (e: DragEvent<HTMLElement>) => {\n setDraggingId(item.id);\n if (onItemDragStart) {\n onItemDragStart(item, category, e);\n } else if (item.insertValue) {\n e.dataTransfer.setData(\"text/plain\", item.insertValue);\n e.dataTransfer.setData(\"application/x-fx-insert\", item.insertValue);\n e.dataTransfer.setData(\n \"application/x-fx-type\",\n category.kind ?? \"function\",\n );\n e.dataTransfer.effectAllowed = \"copy\";\n }\n };\n\n // ── Keyboard navigation over the open category's visible rows ───────\n const listRef = useRef<HTMLDivElement>(null);\n const focusRow = (id: string) => {\n setFocusedId(id);\n requestAnimationFrame(() => {\n listRef.current\n ?.querySelector<HTMLElement>(`[data-fx-row=\"${CSS.escape(id)}\"]`)\n ?.focus();\n });\n };\n const onRowKeyDown = (\n e: ReactKeyboardEvent<HTMLDivElement>,\n rows: FlatRow[],\n row: FlatRow,\n category: FxPanelCategory,\n ) => {\n const idx = rows.findIndex((r) => r.item.id === row.item.id);\n if (idx < 0) return;\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n if (idx < rows.length - 1) focusRow(rows[idx + 1].item.id);\n break;\n case \"ArrowUp\":\n e.preventDefault();\n if (idx > 0) focusRow(rows[idx - 1].item.id);\n break;\n case \"ArrowRight\":\n if (row.hasChildren) {\n e.preventDefault();\n if (!row.expanded) toggleItem(row.item.id);\n else if (idx < rows.length - 1) focusRow(rows[idx + 1].item.id);\n }\n break;\n case \"ArrowLeft\":\n if (row.hasChildren && row.expanded) {\n e.preventDefault();\n toggleItem(row.item.id);\n } else {\n // Walk back to the parent (first shallower row).\n for (let i = idx - 1; i >= 0; i--) {\n if (rows[i].depth < row.depth) {\n e.preventDefault();\n focusRow(rows[i].item.id);\n break;\n }\n }\n }\n break;\n case \"Home\":\n e.preventDefault();\n if (rows.length) focusRow(rows[0].item.id);\n break;\n case \"End\":\n e.preventDefault();\n if (rows.length) focusRow(rows[rows.length - 1].item.id);\n break;\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (row.hasChildren) toggleItem(row.item.id);\n else onItemSelect?.(row.item, category);\n break;\n default:\n break;\n }\n };\n\n // Flat draw-rows for the active search results — drives keyboard nav.\n const searchRows = useMemo<FlatRow[]>(\n () =>\n hits\n ? hits.map(({ hit }) => ({\n item: hit.item,\n depth: 0,\n hasChildren: false,\n expanded: false,\n }))\n : [],\n [hits],\n );\n\n // ── Row renderer ────────────────────────────────────────────────────\n const renderRow = (\n row: FlatRow,\n category: FxPanelCategory,\n rows: FlatRow[],\n crumb?: string,\n ) => {\n const { item, depth, hasChildren, expanded } = row;\n const mono = category.kind === \"function\";\n const draggable = !!item.insertValue;\n const isFocused = focusedId === item.id;\n return (\n <div\n key={item.id}\n data-fx-row={item.id}\n className={cn(\n \"ods-flow-fx-panel__row\",\n hasChildren\n ? \"ods-flow-fx-panel__row--branch\"\n : \"ods-flow-fx-panel__row--leaf\",\n draggingId === item.id && \"ods-flow-fx-panel__row--dragging\",\n isFocused && \"ods-flow-fx-panel__row--focused\",\n )}\n role=\"treeitem\"\n aria-expanded={hasChildren ? expanded : undefined}\n aria-level={depth + 1}\n tabIndex={\n isFocused || (focusedId === null && rows[0]?.item.id === item.id)\n ? 0\n : -1\n }\n draggable={draggable}\n onDragStart={draggable ? handleDragStart(item, category) : undefined}\n onDragEnd={() => setDraggingId(null)}\n onFocus={() => setFocusedId(item.id)}\n onKeyDown={(e) => onRowKeyDown(e, rows, row, category)}\n onClick={() => {\n if (hasChildren) toggleItem(item.id);\n else onItemSelect?.(item, category);\n }}\n title={item.insertValue}\n >\n {/* Indent guides — one per ancestor depth. */}\n {Array.from({ length: depth }, (_, i) => (\n <span key={i} className=\"ods-flow-fx-panel__indent\" aria-hidden=\"true\" />\n ))}\n\n {/* Twisty (branches) or drag handle (leaves). */}\n {hasChildren ? (\n <span className=\"ods-flow-fx-panel__twisty\" aria-hidden=\"true\">\n {expanded ? (\n <ChevronDownIcon size=\"sm\" />\n ) : (\n <ChevronRightIcon size=\"sm\" />\n )}\n </span>\n ) : (\n <span className=\"ods-flow-fx-panel__grip\" aria-hidden=\"true\">\n <DraggableIcon size=\"sm\" />\n </span>\n )}\n\n <span className=\"ods-flow-fx-panel__row-main\">\n <span className=\"ods-flow-fx-panel__row-line\">\n {mono ? (\n <code className=\"ods-flow-fx-panel__row-label ods-flow-fx-panel__row-label--mono\">\n {item.label}\n </code>\n ) : (\n <span className=\"ods-flow-fx-panel__row-label\">{item.label}</span>\n )}\n {item.valueType && (\n <span\n className={cn(\n \"ods-flow-fx-panel__type\",\n `ods-flow-fx-panel__type--${item.valueType}`,\n )}\n >\n {item.valueType}\n </span>\n )}\n </span>\n {(item.description || crumb) && (\n <span className=\"ods-flow-fx-panel__row-sub\">\n {crumb && (\n <span className=\"ods-flow-fx-panel__crumb\">{crumb}</span>\n )}\n {item.description}\n </span>\n )}\n </span>\n </div>\n );\n };\n\n // ── Render ──────────────────────────────────────────────────────────\n return (\n <aside\n className={cn(\"ods-flow-fx-panel\", className)}\n style={{ width, ...style }}\n aria-label={typeof title === \"string\" ? title : \"Data References\"}\n >\n <header className=\"ods-flow-fx-panel__header\">\n <h3 className=\"ods-flow-fx-panel__title\">{title}</h3>\n {onClose && (\n <button\n type=\"button\"\n className=\"ods-flow-fx-panel__close\"\n onClick={onClose}\n aria-label=\"Close data references\"\n >\n <CloseIcon size=\"sm\" />\n </button>\n )}\n </header>\n\n <div className=\"ods-flow-fx-panel__search\">\n <span className=\"ods-flow-fx-panel__search-icon\" aria-hidden=\"true\">\n <SearchIcon size=\"sm\" />\n </span>\n <input\n type=\"text\"\n className=\"ods-flow-fx-panel__search-input\"\n placeholder={searchPlaceholder}\n aria-label=\"Search fields, functions and variables\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n {search && (\n <button\n type=\"button\"\n className=\"ods-flow-fx-panel__search-clear\"\n onClick={() => setSearch(\"\")}\n aria-label=\"Clear search\"\n >\n <CloseIcon size=\"sm\" />\n </button>\n )}\n </div>\n\n {hint && !query && <p className=\"ods-flow-fx-panel__hint\">{hint}</p>}\n\n <div className=\"ods-flow-fx-panel__list\" ref={listRef} role=\"tree\">\n {/* ── Search mode — flat, path-crumbed leaf matches. ── */}\n {query &&\n hits &&\n (hits.length > 0 ? (\n <div className=\"ods-flow-fx-panel__results\">\n <div className=\"ods-flow-fx-panel__results-count\">\n {hits.length} {hits.length === 1 ? \"match\" : \"matches\"}\n </div>\n {hits.map(({ category, hit }, i) =>\n renderRow(\n searchRows[i],\n category,\n searchRows,\n hit.ancestors.length\n ? hit.ancestors.join(\" / \")\n : category.label,\n ),\n )}\n </div>\n ) : (\n <div className=\"ods-flow-fx-panel__empty\">{emptyLabel}</div>\n ))}\n\n {/* ── Browse mode — category accordion + per-branch tree. ── */}\n {!query &&\n visibleCategories.map((cat) => {\n const isOpen = openCategoryId === cat.id;\n const kind = cat.kind ?? \"function\";\n const KindIcon = KIND_ICON[kind];\n const branchIds = new Set<string>();\n collectBranchIds(cat.items, branchIds);\n const hasTree = branchIds.size > 0;\n const rows: FlatRow[] = [];\n if (isOpen) flattenTree(cat.items, 0, expandedItems, rows);\n const allExpanded =\n hasTree &&\n [...branchIds].every((id) => expandedItems.has(id));\n\n return (\n <div className=\"ods-flow-fx-panel__category\" key={cat.id}>\n <div\n className={cn(\n \"ods-flow-fx-panel__cat-header\",\n isOpen && \"ods-flow-fx-panel__cat-header--open\",\n )}\n >\n <button\n type=\"button\"\n className=\"ods-flow-fx-panel__cat-toggle\"\n aria-expanded={isOpen}\n onClick={() => setOpenCategory(isOpen ? null : cat.id)}\n >\n <ChevronRightIcon\n size=\"sm\"\n className={cn(\n \"ods-flow-fx-panel__chevron\",\n isOpen && \"ods-flow-fx-panel__chevron--open\",\n )}\n />\n <span\n className={cn(\n \"ods-flow-fx-panel__badge\",\n `ods-flow-fx-panel__badge--${kind}`,\n )}\n >\n <KindIcon\n size=\"sm\"\n className=\"ods-flow-fx-panel__badge-icon\"\n />\n {cat.label}\n </span>\n <span className=\"ods-flow-fx-panel__count\">\n {countLeaves(cat.items)}\n </span>\n </button>\n {/* Expand / collapse the whole tree of this category. */}\n {isOpen && hasTree && (\n <button\n type=\"button\"\n className=\"ods-flow-fx-panel__cat-action\"\n aria-label={\n allExpanded ? \"Collapse all\" : \"Expand all\"\n }\n title={allExpanded ? \"Collapse all\" : \"Expand all\"}\n onClick={() => setCategoryExpansion(cat, !allExpanded)}\n >\n {allExpanded ? (\n <CollapseAllIcon size=\"sm\" />\n ) : (\n <ExpandAllIcon size=\"sm\" />\n )}\n </button>\n )}\n </div>\n\n {isOpen && (\n <div\n className=\"ods-flow-fx-panel__rows\"\n role=\"group\"\n aria-label={cat.label}\n >\n {rows.map((row) => renderRow(row, cat, rows))}\n </div>\n )}\n </div>\n );\n })}\n </div>\n </aside>\n );\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// DataRefButton — the trigger that opens/closes the FxPanel.\n// ════════════════════════════════════════════════════════════════════════\n// A compact toggle in the ConfigPanel header's modular action slot. It\n// carries the data-reference icon + label and reflects the panel's open\n// state through `aria-pressed` + an `--active` visual.\n\nimport { type ButtonHTMLAttributes, type ReactNode } from \"react\";\nimport { DataReferenceIcon } from \"@octaviaflow/icons\";\nimport { cn } from \"../../../utils/cn\";\n\nexport interface DataRefButtonProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n /** Whether the FxPanel is currently open. Drives `aria-pressed`. */\n active?: boolean;\n /** Visible label beside the icon. Default \"Data ref\". `null` = icon-only. */\n label?: ReactNode;\n}\n\nexport function DataRefButton({\n active = false,\n label = \"Data ref\",\n className,\n type = \"button\",\n ...rest\n}: DataRefButtonProps) {\n return (\n <button\n {...rest}\n type={type}\n className={cn(\n \"ods-flow-dataref-button\",\n active && \"ods-flow-dataref-button--active\",\n label == null && \"ods-flow-dataref-button--icon-only\",\n className,\n )}\n aria-pressed={active}\n title={active ? \"Hide data references\" : \"Show data references\"}\n >\n <DataReferenceIcon\n size=\"sm\"\n className=\"ods-flow-dataref-button__icon\"\n />\n {label != null && (\n <span className=\"ods-flow-dataref-button__label\">{label}</span>\n )}\n </button>\n );\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// NodeToolbar — floating action bar attached to a node.\n// ════════════════════════════════════════════════════════════════════════\n// Dropped inside a custom node renderer (or anywhere with a\n// `FlowNodeContext`). Visible by default only when the host node is\n// selected; consumers can force it on with `isVisible`. Position-stable\n// across zoom — the bar applies `scale(1 / zoom)` to counter the viewport\n// transform so the buttons stay at constant pixel size.\n//\n// Pointer events on the toolbar are isolated from the node's drag /\n// connection gestures via `data-flow-no-drag=\"true\"` on the wrapper.\n\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport type { HandlePosition } from \"../../editor\";\nimport { useViewport } from \"../../store/selectors\";\nimport { useFlowNodeContext } from \"../FlowNode/FlowNodeContext\";\n\nexport interface NodeToolbarProps {\n /** Force-visible state. Defaults to `undefined` → auto (visible iff\n * the host node is selected). Pass `true`/`false` to override. */\n isVisible?: boolean;\n /** Where the toolbar sits relative to the node. Defaults to `top`. */\n position?: HandlePosition;\n /** Pixel offset from the node's edge. Default 10. */\n offset?: number;\n /** Horizontal/vertical alignment along the chosen edge. Default center. */\n align?: \"start\" | \"center\" | \"end\";\n /** Toolbar contents (typically a row of `<button>` elements). */\n children: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function NodeToolbar({\n isVisible,\n position = \"top\",\n offset = 10,\n align = \"center\",\n children,\n className,\n style,\n}: NodeToolbarProps) {\n const node = useFlowNodeContext();\n const viewport = useViewport();\n const show = isVisible ?? node.selected;\n if (!show) return null;\n\n // Counter the canvas's `scale(zoom)` so the toolbar reads at constant\n // pixel size at any zoom level. Translation is in flow-space units; the\n // inverse-scale wraps the visible content so children also stay crisp.\n const inverseScale = 1 / viewport.zoom;\n\n return (\n <div\n className={cn(\"ods-node-toolbar\", `ods-node-toolbar--${position}`, className)}\n data-flow-no-drag=\"true\"\n style={{\n ...positionStyle(position, offset, align),\n ...style,\n }}\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Inner element absorbs the inverse zoom so the toolbar's\n children stay screen-stable. */}\n <div\n className=\"ods-node-toolbar__inner\"\n style={{\n transform: `scale(${inverseScale})`,\n transformOrigin: transformOriginFor(position, align),\n }}\n >\n {children}\n </div>\n </div>\n );\n}\n\nfunction positionStyle(\n side: HandlePosition,\n offset: number,\n align: NodeToolbarProps[\"align\"],\n): CSSProperties {\n const center = align === \"center\";\n const start = align === \"start\";\n switch (side) {\n case \"top\":\n return {\n position: \"absolute\",\n bottom: \"100%\",\n marginBottom: offset,\n left: start ? 0 : center ? \"50%\" : undefined,\n right: align === \"end\" ? 0 : undefined,\n transform: center ? \"translateX(-50%)\" : undefined,\n };\n case \"bottom\":\n return {\n position: \"absolute\",\n top: \"100%\",\n marginTop: offset,\n left: start ? 0 : center ? \"50%\" : undefined,\n right: align === \"end\" ? 0 : undefined,\n transform: center ? \"translateX(-50%)\" : undefined,\n };\n case \"left\":\n return {\n position: \"absolute\",\n right: \"100%\",\n marginRight: offset,\n top: start ? 0 : center ? \"50%\" : undefined,\n bottom: align === \"end\" ? 0 : undefined,\n transform: center ? \"translateY(-50%)\" : undefined,\n };\n case \"right\":\n return {\n position: \"absolute\",\n left: \"100%\",\n marginLeft: offset,\n top: start ? 0 : center ? \"50%\" : undefined,\n bottom: align === \"end\" ? 0 : undefined,\n transform: center ? \"translateY(-50%)\" : undefined,\n };\n }\n}\n\nfunction transformOriginFor(side: HandlePosition, align: NodeToolbarProps[\"align\"]): string {\n // Choose an origin that visually attaches the bar to the node edge,\n // even after inverse-scaling. Defaults match the `position*` styles.\n if (side === \"top\")\n return align === \"start\" ? \"left bottom\" : align === \"end\" ? \"right bottom\" : \"center bottom\";\n if (side === \"bottom\")\n return align === \"start\" ? \"left top\" : align === \"end\" ? \"right top\" : \"center top\";\n if (side === \"left\")\n return align === \"start\" ? \"right top\" : align === \"end\" ? \"right bottom\" : \"right center\";\n return align === \"start\" ? \"left top\" : align === \"end\" ? \"left bottom\" : \"left center\";\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Collapse helpers — when a group's `data.collapsed === true`, hide its\n// descendants AND re-route any edges that crossed the collapse boundary\n// so they terminate at the group instead of dangling at a hidden child.\n// ════════════════════════════════════════════════════════════════════════\n//\n// Consumers feed `nodes` + `edges` (their canonical state) through\n// `collapseFor()` and pass the result to <FlowCanvas>. The helpers are\n// pure — no React state, no DOM. They run in O(N + E) so they're cheap\n// to call on every render.\n\nimport type { WorkflowEdge, WorkflowNode } from \"../editor\";\n\ninterface CollapseResult {\n nodes: WorkflowNode[];\n edges: WorkflowEdge[];\n /** Per-collapsed-group: how many descendants got hidden. The host UI\n * reads this to render a \"N steps\" badge. */\n hiddenCountByGroupId: Map<string, number>;\n}\n\n/**\n * Given the canonical graph, return a derived graph that respects the\n * `collapsed` flag on every group node:\n *\n * - Descendants of a collapsed group are marked `hidden`.\n * - Edges that crossed the collapse boundary are rewritten: their\n * source (or target) becomes the collapsed group's id, and the\n * handle is reset to a synthetic perimeter handle (`__group_out` /\n * `__group_in`). Internal-to-internal edges are dropped.\n */\nexport function collapseFor(nodes: WorkflowNode[], edges: WorkflowEdge[]): CollapseResult {\n // Map child → topmost collapsed ancestor (if any).\n // If a node has multiple collapsed ancestors, the OUTERMOST wins so the\n // edge terminates at the visible boundary.\n const collapsedAncestorOf = new Map<string, string>();\n const parents = new Map<string, string>();\n for (const n of nodes) if (n.parentId) parents.set(n.id, n.parentId);\n\n // ANY node with `data.collapsed === true` collapses its descendants —\n // not just `group`. This lets `forEach` (and consumer-defined container\n // kinds) opt into the same collapse model without each one being\n // hard-coded in this helper.\n const isCollapsed = (node: WorkflowNode | undefined): boolean => {\n const d = node?.data as { collapsed?: boolean } | undefined;\n return !!d?.collapsed;\n };\n\n for (const n of nodes) {\n let cursor: string | undefined = n.id;\n let outermostCollapsed: string | undefined;\n const seen = new Set<string>([cursor]);\n while (cursor) {\n const p = parents.get(cursor);\n if (!p || seen.has(p)) break;\n seen.add(p);\n const parentNode = nodes.find((x) => x.id === p);\n if (isCollapsed(parentNode)) outermostCollapsed = p;\n cursor = p;\n }\n if (outermostCollapsed && outermostCollapsed !== n.id) {\n collapsedAncestorOf.set(n.id, outermostCollapsed);\n }\n }\n\n // Hide every descendant of a collapsed group.\n const outNodes: WorkflowNode[] = nodes.map((n) => {\n const anc = collapsedAncestorOf.get(n.id);\n if (anc) return { ...n, hidden: true };\n return n;\n });\n\n // Rewrite edges: any endpoint that sits inside a collapsed group gets\n // hoisted to the group itself. Edges entirely within a collapsed group\n // are dropped. Edges that start at the group and end inside it (or\n // vice versa) become self-loops that we also drop.\n //\n // **Boundary marker** — edges that get rewritten to terminate at a\n // collapsed group's perimeter are stroked with a sparse dot pattern so\n // the user immediately sees they're a \"summary\" of one or more hidden\n // inner connections rather than a real handle-to-handle edge. The\n // original `edge.style` is preserved; only `strokeDasharray` is\n // overlaid. FlowEdge gives `edge.style.strokeDasharray` precedence\n // over the type's default dash.\n const BOUNDARY_DASH = \"2 4\";\n const outEdges: WorkflowEdge[] = [];\n const hiddenCount = new Map<string, number>();\n for (const e of edges) {\n const srcAnc = collapsedAncestorOf.get(e.source);\n const tgtAnc = collapsedAncestorOf.get(e.target);\n if (srcAnc && tgtAnc && srcAnc === tgtAnc) continue; // wholly inside one collapsed group — drop\n let src = e.source;\n let srcHandle = e.sourceHandle;\n let tgt = e.target;\n let tgtHandle = e.targetHandle;\n const rewritten = !!(srcAnc || tgtAnc);\n if (srcAnc) {\n src = srcAnc;\n // Synthetic perimeter handle — the GroupNode renderer registers\n // matching `__group_out` / `__group_in` handles when collapsed.\n srcHandle = \"__group_out\";\n }\n if (tgtAnc) {\n tgt = tgtAnc;\n tgtHandle = \"__group_in\";\n }\n if (src === tgt) continue; // collapsed self-loop\n const nextEdge: WorkflowEdge = {\n ...e,\n source: src,\n sourceHandle: srcHandle,\n target: tgt,\n targetHandle: tgtHandle,\n };\n if (rewritten) {\n nextEdge.style = { ...(e.style ?? {}), strokeDasharray: BOUNDARY_DASH };\n }\n outEdges.push(nextEdge);\n }\n\n // Count hidden descendants per collapsed group for the badge.\n for (const [_id, anc] of collapsedAncestorOf) {\n hiddenCount.set(anc, (hiddenCount.get(anc) ?? 0) + 1);\n }\n\n return { nodes: outNodes, edges: outEdges, hiddenCountByGroupId: hiddenCount };\n}\n\n/**\n * Toggle the `data.collapsed` flag on a group node. Returns the patched\n * nodes array (immutable). Useful in event handlers.\n */\nexport function toggleGroupCollapse(groupId: string, nodes: WorkflowNode[]): WorkflowNode[] {\n return nodes.map((n) => {\n if (n.id !== groupId) return n;\n const data = (n.data ?? {}) as { collapsed?: boolean } & Record<string, unknown>;\n return { ...n, data: { ...data, collapsed: !data.collapsed } };\n });\n}\n"],"mappings":"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","names":["bezierPath","change","import_react","import_react","distance","import_react","import_react","import_react","import_icons","import_react","import_react","import_jsx_runtime","Accordion","import_react","import_react","Slot","import_jsx_runtime","Badge","import_framer_motion","import_react","import_jsx_runtime","Banner","import_framer_motion","import_react","import_react","import_jsx_runtime","Button","import_icons","import_react","import_jsx_runtime","CodeEditor","import_icons","import_react","import_jsx_runtime","import_icons","import_react","import_jsx_runtime","import_icons","import_react","import_jsx_runtime","import_icons","import_react","import_icons","import_react","import_jsx_runtime","InlineMessage","import_jsx_runtime","JsonViewer","import_icons","import_react","import_react_aria","$1CcWn$react","$1CcWn$useState","$1CcWn$useRef","$1CcWn$useEffect","$1CcWn$useReducer","$1CcWn$useCallback","value","$8AuPP$createContext","$8AuPP$useMemo","$8AuPP$useContext","name","$8AuPP$useState","$8AuPP$useRef","$8AuPP$useEffect","value","a","a","$7w3VE$useRef","$7w3VE$useState","$7w3VE$useMemo","$7w3VE$useEffect","$jO8i1$react","items","node","$emYU7$useMemo","$3yt54$useMemo","$3yt54$useCallback","$3yt54$useRef","$3yt54$useEffect","$kE40A$useCallback","$dJmKC$react","$jhfZc$useMemo","$5t5rb$useState","$5t5rb$useMemo","value","focusStrategy","$eOo4G$useRef","$eOo4G$useEffect","$dAajM$useState","$auOuY$useMemo","$auOuY$useRef","$auOuY$useEffect","import_jsx_runtime","Checkbox","import_jsx_runtime","import_react","import_icons","import_jsx_runtime","NumberInput","import_react","import_icons","import_react","import_jsx_runtime","PasswordInput","import_framer_motion","import_react","import_jsx_runtime","import_framer_motion","import_react","import_react_aria","import_react_dom","import_icons","import_framer_motion","import_react","import_react_aria","import_react_dom","import_jsx_runtime","import_jsx_runtime","Select","import_react","import_jsx_runtime","Spinner","import_react","import_react_aria","import_jsx_runtime","Switch","import_framer_motion","import_react","import_react_aria","import_jsx_runtime","h","f","import_jsx_runtime","import_react","import_react","bezierPath","distance","import_react","import_jsx_runtime","offsetAlongSide","import_react","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_icons","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","DEFAULT_VIEWPORT","c","width","height","nodes","edges","curW","curH","EdgesLayer","import_react","import_icons","import_jsx_runtime","import_icons","import_jsx_runtime","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/workflow/index.ts","../src/workflow/hooks/useAutoLayout.ts","../src/workflow/store/changes.ts","../src/workflow/hooks/useFlow.ts","../src/workflow/hooks/useFlowState.ts","../src/workflow/utils/geometry.ts","../src/workflow/layout/dagre.ts","../src/workflow/layout/elk.ts","../src/workflow/store/selectors.ts","../src/workflow/store/context.ts","../src/workflow/components/ConfigPanel/ConfigPanel.tsx","../src/utils/cn.ts","../src/workflow/components/HttpActionPanel/HttpActionPanel.tsx","../src/components/Accordion/Accordion.tsx","../src/components/Badge/Badge.tsx","../src/utils/Slot.tsx","../src/utils/composeRefs.ts","../src/components/Banner/Banner.tsx","../src/components/Button/Button.tsx","../src/utils/a11y.ts","../src/components/CodeEditor/CodeEditor.tsx","../src/components/Combobox/Combobox.tsx","../src/components/Disclosure/Disclosure.tsx","../src/components/Input/Input.tsx","../src/components/JsonViewer/JsonViewer.tsx","../src/components/InlineMessage/InlineMessage.tsx","../src/components/KeyValueEditor/KeyValueEditor.tsx","../src/components/Checkbox/Checkbox.tsx","../../../node_modules/react-stately/dist/private/utils/packages/react-stately/src/utils/useControlledState.ts","../../../node_modules/react-stately/dist/private/form/packages/react-stately/src/form/useFormValidationState.ts","../../../node_modules/react-stately/dist/private/collections/packages/react-stately/src/collections/getChildNodes.ts","../../../node_modules/react-stately/dist/private/list/packages/react-stately/src/list/ListCollection.ts","../../../node_modules/react-stately/dist/private/selection/packages/react-stately/src/selection/Selection.ts","../../../node_modules/react-stately/dist/private/selection/packages/react-stately/src/selection/useMultipleSelectionState.ts","../../../node_modules/react-stately/dist/private/selection/packages/react-stately/src/selection/SelectionManager.ts","../../../node_modules/react-stately/dist/private/collections/packages/react-stately/src/collections/CollectionBuilder.ts","../../../node_modules/react-stately/dist/private/collections/packages/react-stately/src/collections/useCollection.ts","../../../node_modules/react-stately/dist/private/list/packages/react-stately/src/list/useListState.ts","../../../node_modules/react-stately/dist/private/overlays/packages/react-stately/src/overlays/useOverlayTriggerState.ts","../../../node_modules/react-stately/dist/private/collections/packages/react-stately/src/collections/Item.ts","../../../node_modules/react-stately/dist/private/list/packages/react-stately/src/list/useSingleSelectListState.ts","../../../node_modules/react-stately/dist/private/select/packages/react-stately/src/select/useSelectState.ts","../../../node_modules/react-stately/dist/private/tabs/packages/react-stately/src/tabs/useTabListState.ts","../../../node_modules/react-stately/dist/private/toggle/packages/react-stately/src/toggle/useToggleState.ts","../../../node_modules/react-stately/dist/private/tooltip/packages/react-stately/src/tooltip/useTooltipTriggerState.ts","../src/components/NumberInput/NumberInput.tsx","../src/components/PasswordInput/PasswordInput.tsx","../src/hooks/usePasswordStrength.ts","../src/components/SegmentedControl/SegmentedControl.tsx","../src/components/Select/Select.tsx","../src/components/Tooltip/Tooltip.tsx","../src/components/Spinner/Spinner.tsx","../src/components/Switch/Switch.tsx","../src/components/Tabs/Tabs.tsx","../src/workflow/components/HttpActionPanel/httpActionTypes.ts","../src/workflow/components/FlowCanvas/FlowCanvas.tsx","../src/workflow/store/createFlowStore.ts","../src/workflow/utils/collision.ts","../src/workflow/utils/parenting.ts","../src/workflow/components/FlowEdge/FlowEdge.tsx","../src/workflow/utils/paths.ts","../src/workflow/components/Handle/handleRegistry.ts","../src/workflow/components/FlowNode/FlowNode.tsx","../src/workflow/components/FlowCanvas/FlowCanvasContext.tsx","../src/workflow/components/FlowNode/FlowNodeContext.tsx","../src/workflow/components/FlowNode/nodeKinds.ts","../src/workflow/components/Handle/Handle.tsx","../src/workflow/components/NodeResizer/NodeResizer.tsx","../src/workflow/components/kinds/BaseNode.tsx","../src/workflow/components/kinds/index.tsx","../src/workflow/components/FxPanel/FxPanel.tsx","../src/workflow/components/FxPanel/DataRefButton.tsx","../src/workflow/components/NodeToolbar/NodeToolbar.tsx","../src/workflow/utils/collapse.ts"],"sourcesContent":["// ════════════════════════════════════════════════════════════════════════\n// `@octaviaflow/core/workflow` — public surface for the new editor.\n// ════════════════════════════════════════════════════════════════════════\n// The legacy editor stays at `@octaviaflow/core` (root) for one minor\n// release. Consumers migrate by switching their import path.\n\n// ── Types ───────────────────────────────────────────────────────────────\nexport type {\n BuiltInEdgeKind,\n BuiltInNodeKind,\n ConnectEndState,\n Connection,\n ConnectStartParams,\n Dimensions,\n EdgeChange,\n EdgeKind,\n FitViewOptions,\n HandlePosition,\n HandleType,\n LayoutDirection,\n LayoutEngine,\n LayoutOptions,\n NodeChange,\n NodeKind,\n Position,\n Rect,\n SelectionState,\n Viewport,\n WorkflowEdge,\n WorkflowNode,\n} from \"./editor\";\nexport {\n type UseAutoLayoutOptions,\n type UseAutoLayoutResult,\n useAutoLayout,\n} from \"./hooks/useAutoLayout\";\nexport { type FlowInstance, useFlow } from \"./hooks/useFlow\";\n// ── Hooks ───────────────────────────────────────────────────────────────\nexport {\n type FlowStateBag,\n type NodeDataPatch,\n type UseFlowStateOptions,\n useFlowState,\n} from \"./hooks/useFlowState\";\n// ── Layout engine adapters ─────────────────────────────────────────────\n// Consumers install `dagre` and/or `elkjs` themselves, then pass the\n// module to these factories. See ADR-001 — the DS never bundles the\n// underlying library.\nexport { type CreateDagreEngineOptions, createDagreEngine } from \"./layout/dagre\";\nexport { type CreateElkEngineOptions, createElkEngine } from \"./layout/elk\";\nexport type {\n DagreGraph,\n DagreLike,\n ElkEdge,\n ElkGraph,\n ElkLike,\n} from \"./layout/types\";\n// ── Change reducers ─────────────────────────────────────────────────────\nexport { applyEdgeChanges, applyNodeChanges, change } from \"./store/changes\";\n// ── Selectors (descendants of <FlowCanvas>) ─────────────────────────────\nexport {\n useConnection,\n useEdgeById,\n useEdges,\n useFlowSelector,\n useIsEdgeSelected,\n useIsNodeSelected,\n useNodeById,\n useNodeData,\n useNodes,\n useSelection,\n useViewport,\n useViewportOrNull,\n} from \"./store/selectors\";\n\n// Store creation + context are intentionally NOT exported — they are\n// canvas internals (see ADR-005).\n\n// ── Components ─────────────────────────────────────────────────────────\nexport {\n ConfigPanel,\n type ConfigPanelProps,\n type ConfigPanelSaveState,\n type ConfigPanelTab,\n} from \"./components/ConfigPanel/ConfigPanel\";\nexport {\n HttpActionPanel,\n type HttpActionPanelProps,\n type HttpConnectionEndpoint,\n type HttpConnectionOption,\n} from \"./components/HttpActionPanel/HttpActionPanel\";\nexport {\n buildCurl,\n countGraphqlVariables,\n countSchemaPaths,\n effectiveUrl,\n HTTP_ACTION_DEFAULTS,\n HTTP_METHODS,\n type HttpActionConfig,\n type HttpAuthConfig,\n type HttpBodyType,\n type HttpKeyValue,\n type HttpMethod,\n type HttpPaginationConfig,\n type HttpPaginationType,\n type HttpPreviewRequest,\n type HttpPreviewResponse,\n type HttpResponseType,\n type HttpRetryConfig,\n type HttpValidationResult,\n inferJsonSchema,\n normalizeAuth,\n normalizeKeyValues,\n parseCurl,\n serializeKeyValues,\n validateHttpConfig,\n} from \"./components/HttpActionPanel/httpActionTypes\";\nexport { FlowCanvas, type FlowCanvasProps } from \"./components/FlowCanvas/FlowCanvas\";\nexport { FlowEdge, type FlowEdgeProps } from \"./components/FlowEdge/FlowEdge\";\nexport { FlowNode, type FlowNodeProps } from \"./components/FlowNode/FlowNode\";\nexport {\n FxPanel,\n type FxItemKind,\n type FxPanelCategory,\n type FxPanelItem,\n type FxPanelProps,\n type FxValueType,\n} from \"./components/FxPanel/FxPanel\";\nexport {\n DataRefButton,\n type DataRefButtonProps,\n} from \"./components/FxPanel/DataRefButton\";\nexport {\n type FlowNodeContextValue,\n useFlowNodeContext,\n} from \"./components/FlowNode/FlowNodeContext\";\nexport {\n buildNodeKindRegistry,\n type NodeKindComponent,\n type NodeKindProps,\n type NodeKindRegistry,\n} from \"./components/FlowNode/nodeKinds\";\nexport { Handle, type HandleProps } from \"./components/Handle/Handle\";\n// ── Built-in node kinds + their default registry ──────────────────────\nexport {\n ActionNode,\n type BuiltInNodeData,\n ConditionNode,\n DEFAULT_NODE_KINDS,\n ErrorNode,\n ForEachNode,\n GroupNode,\n HttpRequestNode,\n OutputNode,\n ParallelNode,\n StickyNode,\n TriggerNode,\n WaitNode,\n WebhookNode,\n} from \"./components/kinds\";\nexport { NodeResizer, type NodeResizerProps } from \"./components/NodeResizer/NodeResizer\";\nexport { NodeToolbar, type NodeToolbarProps } from \"./components/NodeToolbar/NodeToolbar\";\n// Re-export the public EdgeRouting type alias from the type module.\nexport type { EdgeRouting } from \"./editor\";\n// ── Collapse helpers ───────────────────────────────────────────────────\n// Re-route edges that cross a collapsed group's boundary so they\n// terminate at the group's perimeter handles instead of dangling.\nexport { collapseFor, toggleGroupCollapse } from \"./utils/collapse\";\n// ── Geometry helpers ───────────────────────────────────────────────────\nexport {\n bezierPath,\n DEFAULT_NODE_HEIGHT,\n DEFAULT_NODE_WIDTH,\n flowToScreen,\n handleCentre,\n screenToFlow,\n} from \"./utils/geometry\";\n// ── Parenting helpers ──────────────────────────────────────────────────\n// Useful for consumers that build their own drag UX (e.g. dragging from\n// a palette directly onto a group).\nexport {\n clampToParentExtent,\n descendantsOf,\n findAncestor,\n findContainingGroup,\n} from \"./utils/parenting\";\n// ── Path builders (advanced — for custom edge renderers) ───────────────\nexport {\n bezierPath as bezierPathFn,\n buildEdgePath,\n type EdgeRouting as EdgeRoutingMode,\n type PathGeometry,\n smoothStepPath,\n stepPath,\n straightPath,\n} from \"./utils/paths\";\n","// ════════════════════════════════════════════════════════════════════════\n// useAutoLayout — run a layout engine and apply its output via the\n// canvas's `onNodesChange` callback.\n// ════════════════════════════════════════════════════════════════════════\n// Two trigger modes:\n//\n// 1. Imperative — call the returned `runLayout()` function (e.g. from a\n// toolbar button). This is the recommended default; users press\n// \"Auto-arrange\" and the engine runs once.\n//\n// 2. Reactive — pass `auto: true`. The hook debounces 250ms on every\n// node/edge add/remove and runs the engine. Useful for \"always\n// auto-layout\" surfaces; expensive in graphs where users drag nodes\n// around (their positions get clobbered).\n//\n// The hook does NOT subscribe to selection / drag / viewport — it watches\n// only the *shape* of the graph (node ids + edge connections). That\n// keeps reactive mode from re-running on every pointermove.\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type {\n LayoutEngine,\n LayoutOptions,\n NodeChange,\n WorkflowEdge,\n WorkflowNode,\n} from \"../editor\";\nimport { change } from \"../store/changes\";\n\nexport interface UseAutoLayoutOptions {\n /** The engine. Required. */\n engine: LayoutEngine | null | undefined;\n /** Current nodes (controlled). */\n nodes: WorkflowNode[];\n /** Current edges (controlled). */\n edges: WorkflowEdge[];\n /** Where to send position changes. Required. */\n onNodesChange?: (changes: NodeChange[]) => void;\n /** Layout options forwarded to the engine. */\n options?: LayoutOptions;\n /** Re-run on every graph-shape change (debounced 250ms). Default false. */\n auto?: boolean;\n /** Debounce delay for `auto` mode (ms). Default 250. */\n debounceMs?: number;\n /** Called after each successful run. */\n onLayout?: (positions: { id: string; position: { x: number; y: number } }[]) => void;\n /** Called when the engine throws (network / worker / library). */\n onError?: (err: unknown) => void;\n}\n\nexport interface UseAutoLayoutResult {\n /** Manually trigger a layout pass. Returns the promise of the engine. */\n runLayout(): Promise<void>;\n /** True while a layout pass is in flight. */\n isLaying: boolean;\n}\n\n/**\n * Build a stable graph-shape signature so reactive mode only re-runs when\n * the structure (node ids + edges) changes, not on position/select/drag.\n */\nfunction signature(nodes: WorkflowNode[], edges: WorkflowEdge[]): string {\n // Sorted to be invariant under array re-ordering.\n const nodeKeys = nodes\n .map((n) => `${n.id}:${n.parentId ?? \"\"}`)\n .sort()\n .join(\"|\");\n const edgeKeys = edges\n .map((e) => `${e.id}:${e.source}>${e.target}`)\n .sort()\n .join(\"|\");\n return `${nodeKeys}::${edgeKeys}`;\n}\n\nexport function useAutoLayout({\n engine,\n nodes,\n edges,\n onNodesChange,\n options,\n auto = false,\n debounceMs = 250,\n onLayout,\n onError,\n}: UseAutoLayoutOptions): UseAutoLayoutResult {\n const [isLaying, setIsLaying] = useState(false);\n const runningRef = useRef(false);\n const optionsRef = useRef(options);\n const onLayoutRef = useRef(onLayout);\n const onErrorRef = useRef(onError);\n const onNodesChangeRef = useRef(onNodesChange);\n useEffect(() => {\n optionsRef.current = options;\n }, [options]);\n useEffect(() => {\n onLayoutRef.current = onLayout;\n }, [onLayout]);\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n useEffect(() => {\n onNodesChangeRef.current = onNodesChange;\n }, [onNodesChange]);\n\n // Snapshot refs of nodes/edges so the runLayout callback can read fresh\n // data without re-creating itself on every render.\n const nodesRef = useRef(nodes);\n const edgesRef = useRef(edges);\n useEffect(() => {\n nodesRef.current = nodes;\n }, [nodes]);\n useEffect(() => {\n edgesRef.current = edges;\n }, [edges]);\n\n const runLayout = useCallback(async () => {\n if (!engine) return;\n if (runningRef.current) return;\n runningRef.current = true;\n setIsLaying(true);\n try {\n const positions = await engine.layout(nodesRef.current, edgesRef.current, optionsRef.current);\n\n // Index engine output by id + remember per-node deltas so we can\n // transitively apply them to descendants (children move with the\n // parent — otherwise a parent moves and its children get stranded\n // outside the new bbox, which is the v1 subflow auto-layout bug).\n const positionedIds = new Set(positions.map((p) => p.id));\n const deltas = new Map<string, { dx: number; dy: number }>();\n\n const cs: NodeChange[] = [];\n for (const p of positions) {\n const cur = nodesRef.current.find((n) => n.id === p.id);\n if (!cur) continue;\n if (cur.position.x === p.position.x && cur.position.y === p.position.y) continue;\n cs.push(change.node.position(p.id, p.position, false));\n deltas.set(p.id, {\n dx: p.position.x - cur.position.x,\n dy: p.position.y - cur.position.y,\n });\n }\n\n // For every node the engine did NOT reposition (typically because\n // it sat in a sub-flow that the engine treated as opaque), walk up\n // the parentId chain to find the nearest moved ancestor. Shift the\n // descendant by that ancestor's delta. The first moved ancestor\n // wins — we don't sum deltas because each child's position is\n // already relative to its ancestor's old position.\n const findParent = (id: string): WorkflowNode | undefined =>\n nodesRef.current.find((x) => x.id === id);\n\n for (const n of nodesRef.current) {\n if (positionedIds.has(n.id)) continue;\n if (!n.parentId) continue;\n let cursor: string | undefined = n.parentId;\n const seen = new Set<string>();\n let delta: { dx: number; dy: number } | undefined;\n while (cursor) {\n if (seen.has(cursor)) break; // cycle guard\n seen.add(cursor);\n const found = deltas.get(cursor);\n if (found) {\n delta = found;\n break;\n }\n cursor = findParent(cursor)?.parentId;\n }\n if (!delta) continue;\n cs.push(\n change.node.position(\n n.id,\n { x: n.position.x + delta.dx, y: n.position.y + delta.dy },\n false,\n ),\n );\n }\n\n if (cs.length) onNodesChangeRef.current?.(cs);\n onLayoutRef.current?.(positions);\n } catch (err) {\n onErrorRef.current?.(err);\n } finally {\n runningRef.current = false;\n setIsLaying(false);\n }\n }, [engine]);\n\n // Reactive auto-mode — debounce on graph-shape changes.\n const sig = signature(nodes, edges);\n const sigRef = useRef(sig);\n useEffect(() => {\n if (!auto) return;\n if (sigRef.current === sig) return; // first render after toggling auto\n sigRef.current = sig;\n const timer = setTimeout(() => void runLayout(), debounceMs);\n return () => clearTimeout(timer);\n }, [sig, auto, debounceMs, runLayout]);\n\n return { runLayout, isLaying };\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Change reducers — apply node/edge change arrays in one immutable pass.\n// ════════════════════════════════════════════════════════════════════════\n// Consumers in controlled mode write:\n//\n// <FlowCanvas\n// nodes={nodes}\n// edges={edges}\n// onNodesChange={(changes) => setNodes((ns) => applyNodeChanges(ns, changes))}\n// onEdgesChange={(changes) => setEdges((es) => applyEdgeChanges(es, changes))}\n// />\n//\n// The helpers run in O(n + m) where n is the existing list and m the\n// change count, with one shallow clone per touched item. Add / remove\n// short-circuit when the array is unchanged, so React's reconciler\n// happily reuses references.\n\nimport type { EdgeChange, NodeChange, WorkflowEdge, WorkflowNode } from \"../editor\";\n\n/**\n * Apply a batch of node changes to an existing node list. Returns a\n * **new array** if anything changed, the **same array** otherwise (so\n * React.memo'd children don't re-render unnecessarily).\n */\nexport function applyNodeChanges<TData = unknown>(\n nodes: WorkflowNode<TData>[],\n changes: NodeChange<TData>[],\n): WorkflowNode<TData>[] {\n if (changes.length === 0) return nodes;\n\n // Bucket changes by id for O(1) lookup during the single map pass.\n const byId = new Map<string, NodeChange<TData>[]>();\n const adds: WorkflowNode<TData>[] = [];\n const removes = new Set<string>();\n let touched = false;\n\n for (const change of changes) {\n switch (change.type) {\n case \"add\":\n adds.push(change.item);\n touched = true;\n break;\n case \"remove\":\n removes.add(change.id);\n touched = true;\n break;\n default: {\n const id = change.id;\n const arr = byId.get(id);\n if (arr) arr.push(change);\n else byId.set(id, [change]);\n touched = true;\n break;\n }\n }\n }\n\n if (!touched) return nodes;\n\n const next: WorkflowNode<TData>[] = [];\n for (const node of nodes) {\n if (removes.has(node.id)) continue;\n const patches = byId.get(node.id);\n if (!patches) {\n next.push(node);\n continue;\n }\n let n: WorkflowNode<TData> = node;\n for (const patch of patches) {\n switch (patch.type) {\n case \"position\":\n n = {\n ...n,\n position: patch.position,\n dragging: patch.dragging,\n };\n break;\n case \"dimensions\":\n n = {\n ...n,\n width: patch.dimensions.width,\n height: patch.dimensions.height,\n };\n break;\n case \"select\":\n // Skip if already in the target state — keeps reference stable.\n if (n.selected === patch.selected) break;\n n = { ...n, selected: patch.selected };\n break;\n case \"replace\":\n n = patch.item;\n break;\n }\n }\n next.push(n);\n }\n\n // Adds go to the end. Parents must precede children (caller's\n // responsibility; we don't reorder mid-application because that would\n // make `replace` unpredictable when a child already exists).\n for (const add of adds) next.push(add);\n\n return next;\n}\n\n/**\n * Apply a batch of edge changes. Same shape as `applyNodeChanges`.\n */\nexport function applyEdgeChanges<TData = unknown>(\n edges: WorkflowEdge<TData>[],\n changes: EdgeChange<TData>[],\n): WorkflowEdge<TData>[] {\n if (changes.length === 0) return edges;\n\n const byId = new Map<string, EdgeChange<TData>[]>();\n const adds: WorkflowEdge<TData>[] = [];\n const removes = new Set<string>();\n let touched = false;\n\n for (const change of changes) {\n switch (change.type) {\n case \"add\":\n adds.push(change.item);\n touched = true;\n break;\n case \"remove\":\n removes.add(change.id);\n touched = true;\n break;\n default: {\n const arr = byId.get(change.id);\n if (arr) arr.push(change);\n else byId.set(change.id, [change]);\n touched = true;\n break;\n }\n }\n }\n\n if (!touched) return edges;\n\n const next: WorkflowEdge<TData>[] = [];\n for (const edge of edges) {\n if (removes.has(edge.id)) continue;\n const patches = byId.get(edge.id);\n if (!patches) {\n next.push(edge);\n continue;\n }\n let e: WorkflowEdge<TData> = edge;\n for (const patch of patches) {\n switch (patch.type) {\n case \"select\":\n if (e.selected === patch.selected) break;\n e = { ...e, selected: patch.selected };\n break;\n case \"replace\":\n e = patch.item;\n break;\n }\n }\n next.push(e);\n }\n\n for (const add of adds) next.push(add);\n return next;\n}\n\n// ── Convenience builders ────────────────────────────────────────────────\n// Used by the store / hooks internally. Public consumers usually let the\n// canvas emit changes; these are handy for tests + custom interactions.\n\nexport const change = {\n node: {\n add<TData>(item: WorkflowNode<TData>): NodeChange<TData> {\n return { type: \"add\", item };\n },\n remove<TData>(id: string): NodeChange<TData> {\n return { type: \"remove\", id };\n },\n position<TData>(\n id: string,\n position: { x: number; y: number },\n dragging: boolean,\n ): NodeChange<TData> {\n return { type: \"position\", id, position, dragging };\n },\n dimensions<TData>(\n id: string,\n dimensions: { width: number; height: number },\n ): NodeChange<TData> {\n return { type: \"dimensions\", id, dimensions };\n },\n select<TData>(id: string, selected: boolean): NodeChange<TData> {\n return { type: \"select\", id, selected };\n },\n replace<TData>(id: string, item: WorkflowNode<TData>): NodeChange<TData> {\n return { type: \"replace\", id, item };\n },\n },\n edge: {\n add<TData>(item: WorkflowEdge<TData>): EdgeChange<TData> {\n return { type: \"add\", item };\n },\n remove<TData>(id: string): EdgeChange<TData> {\n return { type: \"remove\", id };\n },\n select<TData>(id: string, selected: boolean): EdgeChange<TData> {\n return { type: \"select\", id, selected };\n },\n replace<TData>(id: string, item: WorkflowEdge<TData>): EdgeChange<TData> {\n return { type: \"replace\", id, item };\n },\n },\n};\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// useFlow — imperative instance for the workflow editor.\n// ════════════════════════════════════════════════════════════════════════\n// Consumers reach inside `<FlowCanvas>` via this hook to do things that\n// React's declarative API can't express cleanly:\n//\n// - convert between screen and flow coordinates (drag-from-palette\n// needs to know where the pointer landed in flow space)\n// - imperatively fit the viewport to a set of nodes (\"zoom to error\")\n// - query intersecting nodes for marquee select / dragover hits\n// - patch node data without round-tripping through the parent reducer\n// - request a delete that respects `onBeforeDelete` veto\n//\n// All methods read from the FlowStore via narrow selectors, so the hook\n// itself doesn't trigger re-renders when state changes. The instance\n// reference is stable for the lifetime of the canvas.\n\nimport { createContext, useContext } from \"react\";\nimport type {\n FitViewOptions,\n Position,\n Rect,\n Viewport,\n WorkflowEdge,\n WorkflowNode,\n} from \"../editor\";\n\nexport interface FlowInstance {\n // ── Viewport ───────────────────────────────────────────────────────\n getViewport(): Viewport;\n setViewport(viewport: Viewport, opts?: { duration?: number }): void;\n setCenter(x: number, y: number, opts?: { duration?: number; zoom?: number }): void;\n fitView(opts?: FitViewOptions): Promise<boolean>;\n zoomIn(opts?: { step?: number }): void;\n zoomOut(opts?: { step?: number }): void;\n zoomTo(level: number): void;\n\n // ── Coordinate transforms ──────────────────────────────────────────\n /** Convert a pointer position (relative to the canvas container) into\n * flow-space coordinates. */\n screenToFlowPosition(p: Position): Position;\n /** Inverse of `screenToFlowPosition`. */\n flowToScreenPosition(p: Position): Position;\n\n // ── Data access (snapshot reads) ───────────────────────────────────\n getNodes(): WorkflowNode[];\n getEdges(): WorkflowEdge[];\n getNode(id: string): WorkflowNode | undefined;\n getEdge(id: string): WorkflowEdge | undefined;\n /** Axis-aligned bounding box of the given nodes (or every node when omitted). */\n getNodesBounds(nodes?: { id: string }[]): Rect;\n /** Find every node whose bbox overlaps the given rect.\n * `partially=true` includes partial overlaps; `false` requires full containment. */\n getIntersectingNodes(area: Rect, partially?: boolean): WorkflowNode[];\n\n // ── Mutation (round-tripped through onNodesChange/onEdgesChange) ──\n addNodes(nodes: WorkflowNode | WorkflowNode[]): void;\n addEdges(edges: WorkflowEdge | WorkflowEdge[]): void;\n /** Merge a partial into the node's existing `data` field. Cheap shorthand\n * for the common case of editing a node's payload without rebuilding it. */\n updateNodeData<TData = unknown>(id: string, partial: Partial<TData>): void;\n /** Replace the node entirely (use sparingly — usually `updateNodeData` is enough). */\n updateNode(id: string, partial: Partial<WorkflowNode>): void;\n /** Imperatively remove nodes and/or edges. Returns false if the host's\n * `onBeforeDelete` vetoed; true otherwise. Synchronous for non-async\n * vetoes; awaits the promise when the host returns one. */\n deleteElements(params: { nodes?: { id: string }[]; edges?: { id: string }[] }): Promise<boolean>;\n}\n\nexport const FlowInstanceContext = createContext<FlowInstance | null>(null);\n\n/**\n * Imperative handle for `<FlowCanvas>`. Throws if called outside the\n * canvas — the instance is canvas-scoped (not a global singleton) so\n * multiple canvases on the same page each have their own.\n */\nexport function useFlow(): FlowInstance {\n const instance = useContext(FlowInstanceContext);\n if (!instance) {\n throw new Error(\"[@octaviaflow/core/workflow] useFlow() must be called inside <FlowCanvas>.\");\n }\n return instance;\n}\n","// ════════════════════════════════════════════════════════════════════════\n// useFlowState — the uncontrolled-mode convenience.\n// ════════════════════════════════════════════════════════════════════════\n// Consumers that don't want to thread state through their own reducer\n// can use this hook and spread the result into <FlowCanvas>:\n//\n// const flow = useFlowState({ initialNodes, initialEdges });\n// <FlowCanvas {...flow} />\n//\n// In addition to the canonical change-stream contract, `useFlowState`\n// exposes per-node helpers — `updateNodeData(id, patch)` and the\n// companion `useNodeData(state, id)` selector — so individual node\n// updates can be expressed without re-mapping the entire nodes array\n// in caller code. Each helper writes ONLY the targeted node's slice;\n// React.memo'd kind components for other nodes never re-render.\n\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { EdgeChange, NodeChange, WorkflowEdge, WorkflowNode } from \"../editor\";\nimport { applyEdgeChanges, applyNodeChanges } from \"../store/changes\";\n\nexport interface UseFlowStateOptions<TNData = unknown, TEData = unknown> {\n initialNodes?: WorkflowNode<TNData>[];\n initialEdges?: WorkflowEdge<TEData>[];\n}\n\n/**\n * Patch type for `updateNodeData` — accepts a partial object that gets\n * shallow-merged, or a producer function `(prev) => next`.\n */\nexport type NodeDataPatch<TNData> =\n | Partial<TNData>\n | ((prev: TNData | undefined) => TNData | undefined);\n\nexport interface FlowStateBag<TNData = unknown, TEData = unknown> {\n nodes: WorkflowNode<TNData>[];\n edges: WorkflowEdge<TEData>[];\n onNodesChange: (changes: NodeChange<TNData>[]) => void;\n onEdgesChange: (changes: EdgeChange<TEData>[]) => void;\n setNodes: (\n update: WorkflowNode<TNData>[] | ((prev: WorkflowNode<TNData>[]) => WorkflowNode<TNData>[]),\n ) => void;\n setEdges: (\n update: WorkflowEdge<TEData>[] | ((prev: WorkflowEdge<TEData>[]) => WorkflowEdge<TEData>[]),\n ) => void;\n /**\n * Update the `data` slice of a single node by id. Only that node's\n * reference changes — every other node keeps its previous reference,\n * so React.memo'd kind components for unrelated nodes do not re-render.\n * No-ops when `id` is not present in the current nodes array.\n */\n updateNodeData: (id: string, patch: NodeDataPatch<TNData>) => void;\n /**\n * Read a single node by id from the latest snapshot. Returns undefined\n * if the id is unknown. Useful inside imperative callbacks that need\n * the freshest value without subscribing to re-renders.\n */\n getNode: (id: string) => WorkflowNode<TNData> | undefined;\n}\n\nexport function useFlowState<TNData = unknown, TEData = unknown>(\n options: UseFlowStateOptions<TNData, TEData> = {},\n): FlowStateBag<TNData, TEData> {\n const [nodes, setNodes] = useState<WorkflowNode<TNData>[]>(options.initialNodes ?? []);\n const [edges, setEdges] = useState<WorkflowEdge<TEData>[]>(options.initialEdges ?? []);\n\n // Ref-mirror of the latest nodes array. `getNode` reads through it so\n // imperative callers see fresh values without depending on render scope.\n const nodesRef = useRef(nodes);\n nodesRef.current = nodes;\n\n const onNodesChange = useCallback((changes: NodeChange<TNData>[]) => {\n setNodes((prev) => applyNodeChanges(prev, changes));\n }, []);\n\n const onEdgesChange = useCallback((changes: EdgeChange<TEData>[]) => {\n setEdges((prev) => applyEdgeChanges(prev, changes));\n }, []);\n\n const updateNodeData = useCallback((id: string, patch: NodeDataPatch<TNData>) => {\n setNodes((prev) => {\n let touched = false;\n const next: WorkflowNode<TNData>[] = prev.map((n) => {\n if (n.id !== id) return n;\n const nextData =\n typeof patch === \"function\"\n ? (patch as (p: TNData | undefined) => TNData | undefined)(n.data)\n : ({ ...(n.data ?? ({} as TNData)), ...patch } as TNData);\n if (Object.is(nextData, n.data)) return n;\n touched = true;\n return { ...n, data: nextData as TNData };\n });\n return touched ? next : prev;\n });\n }, []);\n\n const getNode = useCallback((id: string) => nodesRef.current.find((n) => n.id === id), []);\n\n return useMemo(\n () => ({\n nodes,\n edges,\n onNodesChange,\n onEdgesChange,\n setNodes,\n setEdges,\n updateNodeData,\n getNode,\n }),\n [nodes, edges, onNodesChange, onEdgesChange, updateNodeData, getNode],\n );\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Shared geometry helpers used by FlowNode, FlowEdge, and the connection\n// drag middleware. Pure functions — no state, no DOM.\n// ════════════════════════════════════════════════════════════════════════\n\nimport type { HandlePosition, Position, Viewport, WorkflowNode } from \"../editor\";\n\n// Default node footprint when the renderer hasn't yet measured a custom\n// node. Kept in lockstep with the BaseNode body width (368 px) so the\n// pre-measurement edge math anchors precisely on the handle dot. Height\n// stays 96 — the body min-height clamps the real measurement past that.\nexport const DEFAULT_NODE_WIDTH = 368;\nexport const DEFAULT_NODE_HEIGHT = 96;\n\n// Collapsed container heights — kept in lockstep with the values in\n// `kinds/index.tsx` (GroupNode renders `collapsed ? 36 : ...`,\n// ForEachNode renders `collapsed ? 40 : ...`). When a container is\n// collapsed its visual footprint shrinks to this header strip; edges to\n// the perimeter handles must use the same height or they'll terminate\n// hundreds of pixels below the visible node.\nexport const COLLAPSED_GROUP_HEIGHT = 36;\nexport const COLLAPSED_FOREACH_HEIGHT = 40;\n\n/**\n * The height the node *actually renders at* — accounts for collapsed\n * containers whose visual height differs from `node.height`. All edge\n * geometry should go through this helper instead of reading\n * `node.height` directly.\n */\nexport function effectiveHeight(node: WorkflowNode): number {\n const data = node.data as { collapsed?: boolean } | undefined;\n if (data?.collapsed) {\n if (node.type === \"group\") return COLLAPSED_GROUP_HEIGHT;\n if (node.type === \"forEach\") return COLLAPSED_FOREACH_HEIGHT;\n }\n return node.height ?? DEFAULT_NODE_HEIGHT;\n}\n\n/**\n * Compute the absolute (flow-space) centre of one of a node's handles.\n *\n * The handle's logical position (`top`/`right`/`bottom`/`left`) plus its\n * index among same-side handles determines a deterministic spread along\n * the relevant edge of the node bbox. We do NOT consult the DOM — the\n * source of truth is the node's measured (or default) dimensions.\n *\n * `total` is the count of handles on that side, `index` is this handle's\n * 0-based position among them. A single handle centres; multiple spread\n * evenly with equal margins.\n */\nexport function handleCentre(\n node: WorkflowNode,\n side: HandlePosition,\n index: number,\n total: number,\n): Position {\n const w = node.width ?? DEFAULT_NODE_WIDTH;\n // Use the EFFECTIVE rendered height — collapsed containers report a\n // tall `node.height` but visually render a 36-40px strip. Without this,\n // edges to a collapsed group's perimeter handle terminate hundreds of\n // pixels below the visible pill.\n const h = effectiveHeight(node);\n const x0 = node.position.x;\n const y0 = node.position.y;\n const denom = total + 1;\n const ratio = (index + 1) / denom;\n\n switch (side) {\n case \"top\":\n return { x: x0 + w * ratio, y: y0 };\n case \"bottom\":\n return { x: x0 + w * ratio, y: y0 + h };\n case \"left\":\n return { x: x0, y: y0 + h * ratio };\n case \"right\":\n return { x: x0 + w, y: y0 + h * ratio };\n }\n}\n\n/**\n * Cubic bezier path between two oriented points. The control points are\n * offset along each port's facing direction so the curve leaves and\n * enters along the port's axis (the same routing model as v1).\n */\nexport function bezierPath(\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n): { d: string; midX: number; midY: number } {\n const distance = Math.hypot(end.x - start.x, end.y - start.y);\n const magnitude = Math.max(40, Math.min(160, distance * 0.45));\n const c1 = offsetBySide(start, startSide, magnitude);\n const c2 = offsetBySide(end, endSide, magnitude);\n const d = `M ${start.x},${start.y} C ${c1.x},${c1.y} ${c2.x},${c2.y} ${end.x},${end.y}`;\n // Analytic midpoint of a cubic bezier at t = 0.5.\n const midX = 0.125 * start.x + 0.375 * c1.x + 0.375 * c2.x + 0.125 * end.x;\n const midY = 0.125 * start.y + 0.375 * c1.y + 0.375 * c2.y + 0.125 * end.y;\n return { d, midX, midY };\n}\n\nfunction offsetBySide(p: Position, side: HandlePosition, m: number): Position {\n switch (side) {\n case \"top\":\n return { x: p.x, y: p.y - m };\n case \"bottom\":\n return { x: p.x, y: p.y + m };\n case \"left\":\n return { x: p.x - m, y: p.y };\n case \"right\":\n return { x: p.x + m, y: p.y };\n }\n}\n\n/**\n * Convert a screen-space point (pixels relative to the viewport\n * container's top-left) to flow-space coordinates, given the current\n * viewport.\n */\nexport function screenToFlow(p: Position, vp: Viewport): Position {\n return {\n x: (p.x - vp.x) / vp.zoom,\n y: (p.y - vp.y) / vp.zoom,\n };\n}\n\n/**\n * Inverse of `screenToFlow`.\n */\nexport function flowToScreen(p: Position, vp: Viewport): Position {\n return {\n x: p.x * vp.zoom + vp.x,\n y: p.y * vp.zoom + vp.y,\n };\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Dagre adapter — wraps a consumer-supplied `dagre` module.\n// ════════════════════════════════════════════════════════════════════════\n// Usage:\n//\n// import dagre from \"dagre\";\n// import { createDagreEngine } from \"@octaviaflow/core/workflow\";\n//\n// const engine = createDagreEngine(dagre);\n// useAutoLayout({ engine, onLayout });\n//\n// Dagre is synchronous — `layout()` blocks the main thread. Good for\n// small graphs (≤ ~200 nodes). For larger graphs, see `createElkEngine`.\n\nimport type { LayoutEngine, LayoutOptions, Position, WorkflowEdge, WorkflowNode } from \"../editor\";\nimport { DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH } from \"../utils/geometry\";\nimport type { DagreLike } from \"./types\";\n\nexport interface CreateDagreEngineOptions {\n /** Default spacing between nodes within a rank (default 60). */\n nodeSpacing?: number;\n /** Default spacing between ranks (default 80). */\n rankSpacing?: number;\n /** Default direction — TB, BT, LR, RL. Defaults to TB. */\n direction?: LayoutOptions[\"direction\"];\n}\n\n/**\n * Build a `LayoutEngine` backed by a consumer-supplied `dagre` module.\n *\n * `dagre` can be passed as either the default export or the namespace\n * import (`import * as dagre from \"dagre\"`). The adapter probes both\n * shapes so consumers don't have to think about it.\n */\nexport function createDagreEngine(\n dagre:\n | DagreLike\n | { default: DagreLike }\n | { graphlib: DagreLike[\"graphlib\"]; layout: DagreLike[\"layout\"] },\n defaults: CreateDagreEngineOptions = {},\n): LayoutEngine {\n const lib = resolveDagre(dagre);\n const defaultDir = defaults.direction ?? \"TB\";\n const defaultNodeSpacing = defaults.nodeSpacing ?? 60;\n const defaultRankSpacing = defaults.rankSpacing ?? 80;\n\n return {\n name: \"dagre\",\n async layout(nodes: WorkflowNode[], edges: WorkflowEdge[], options?: LayoutOptions) {\n const direction = options?.direction ?? defaultDir;\n const nodesep = options?.nodeSpacing ?? defaultNodeSpacing;\n const ranksep = options?.rankSpacing ?? defaultRankSpacing;\n\n // Dagre requires every node to have width/height. Use the measured\n // values from the canvas; fall back to our default footprint.\n const g = new lib.graphlib.Graph({ multigraph: true, compound: true });\n g.setGraph({\n rankdir: direction,\n nodesep,\n ranksep,\n ...(options?.engine ?? {}),\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n for (const n of nodes) {\n if (n.hidden) continue;\n g.setNode(n.id, {\n width: n.width ?? DEFAULT_NODE_WIDTH,\n height: n.height ?? DEFAULT_NODE_HEIGHT,\n ...(n.parentId ? { parent: n.parentId } : {}),\n });\n // Compound graph: register the parent–child relationship.\n if (n.parentId) {\n // `setParent` is on the graph but not strongly typed in our\n // narrow surface — call via index access. dagre tolerates a\n // missing parent node (it auto-creates).\n (g as unknown as { setParent: (id: string, parent: string) => void }).setParent(\n n.id,\n n.parentId,\n );\n }\n }\n\n for (const e of edges) {\n if (e.hidden) continue;\n // Pass `e.id` as the multigraph edge NAME so parallel edges (e.g. a\n // condition's true + false branches both pointing at the same\n // downstream node) don't collapse into a single layout constraint.\n g.setEdge(e.source, e.target, { id: e.id }, e.id);\n }\n\n lib.layout(g);\n\n // Dagre stores node centres; our model uses top-left. Translate.\n const result: { id: string; position: Position }[] = [];\n for (const id of g.nodes()) {\n const out = g.node(id);\n if (!out) continue;\n result.push({\n id,\n position: { x: out.x - out.width / 2, y: out.y - out.height / 2 },\n });\n }\n return result;\n },\n };\n}\n\nfunction resolveDagre(input: unknown): DagreLike {\n const asAny = input as Partial<DagreLike> & { default?: DagreLike };\n if (asAny && typeof asAny.layout === \"function\" && asAny.graphlib?.Graph) {\n return asAny as DagreLike;\n }\n if (asAny?.default && typeof asAny.default.layout === \"function\") {\n return asAny.default;\n }\n throw new Error(\n \"[@octaviaflow/core/workflow] createDagreEngine: input does not look like the dagre module. \" +\n \"Pass `dagre` (the default export) or `import * as dagre from 'dagre'`.\",\n );\n}\n","// ════════════════════════════════════════════════════════════════════════\n// ELK adapter — wraps a consumer-supplied `elkjs` instance.\n// ════════════════════════════════════════════════════════════════════════\n// Usage (Web Worker — recommended for large graphs):\n//\n// import ELK from \"elkjs/lib/elk-api\";\n// import { createElkEngine } from \"@octaviaflow/core/workflow\";\n//\n// const elk = new ELK({ workerUrl: \"/elk-worker.min.js\" });\n// const engine = createElkEngine(elk);\n//\n// Usage (in-process, no worker):\n//\n// import ELK from \"elkjs/lib/elk.bundled\";\n// const elk = new ELK();\n// const engine = createElkEngine(elk);\n//\n// ELK supports compound graphs natively — nodes with `parentId` get\n// nested into the right `children[]` so subflow layouts just work.\n\nimport type { LayoutEngine, LayoutOptions, Position, WorkflowEdge, WorkflowNode } from \"../editor\";\nimport { DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH } from \"../utils/geometry\";\nimport type { ElkEdge, ElkGraph, ElkLike } from \"./types\";\n\nexport interface CreateElkEngineOptions {\n /** Default direction — TB / BT / LR / RL. Defaults to TB. */\n direction?: LayoutOptions[\"direction\"];\n /** Default node-to-node spacing within a layer (default 60). */\n nodeSpacing?: number;\n /** Default layer-to-layer spacing (default 80). */\n rankSpacing?: number;\n /** Override the algorithm. Defaults to `layered` (Sugiyama). */\n algorithm?:\n | \"layered\"\n | \"mrtree\"\n | \"force\"\n | \"stress\"\n | \"radial\"\n | \"disco\"\n | \"rectpacking\"\n | \"box\";\n}\n\nconst ELK_DIRECTION: Record<NonNullable<LayoutOptions[\"direction\"]>, string> = {\n TB: \"DOWN\",\n BT: \"UP\",\n LR: \"RIGHT\",\n RL: \"LEFT\",\n};\n\n/**\n * Build a `LayoutEngine` backed by a consumer-supplied `elkjs` instance.\n *\n * The consumer is responsible for constructing the ELK instance (which\n * may or may not run in a Web Worker — that's a `workerUrl` constructor\n * option on their end). Our adapter just calls `elk.layout(graph)` and\n * patches positions back.\n */\nexport function createElkEngine(elk: ElkLike, defaults: CreateElkEngineOptions = {}): LayoutEngine {\n const algorithm = defaults.algorithm ?? \"layered\";\n const defaultDir = defaults.direction ?? \"TB\";\n const defaultNodeSpacing = defaults.nodeSpacing ?? 60;\n const defaultRankSpacing = defaults.rankSpacing ?? 80;\n\n return {\n name: \"elk\",\n async layout(nodes: WorkflowNode[], edges: WorkflowEdge[], options?: LayoutOptions) {\n const direction = options?.direction ?? defaultDir;\n const nodeSpacing = options?.nodeSpacing ?? defaultNodeSpacing;\n const rankSpacing = options?.rankSpacing ?? defaultRankSpacing;\n\n // Build a nested ELK graph respecting `parentId` so compound layout\n // works. We walk the node list once into a parent → children map,\n // then recursively build ElkGraph.children[].\n const childrenByParent = new Map<string | undefined, WorkflowNode[]>();\n for (const n of nodes) {\n if (n.hidden) continue;\n const key = n.parentId ?? undefined;\n const list = childrenByParent.get(key);\n if (list) list.push(n);\n else childrenByParent.set(key, [n]);\n }\n\n // Engine options the consumer passed at the root, normalised to\n // strings. We propagate them onto every compound node too —\n // options like `elk.padding` apply per-node, so setting them only\n // on the root leaves nested compounds using ELK defaults.\n const engineOptions: Record<string, string> = Object.fromEntries(\n Object.entries(options?.engine ?? {}).map(([k, v]) => [k, String(v)]),\n );\n\n // Base layered options shared by the root graph and every compound\n // node. `considerModelOrder` makes ELK respect the INPUT ORDER of a\n // node's outgoing edges when it orders siblings within a layer — so a\n // condition's true/false branches and a forEach's each/done branches\n // land in the order the caller declared them (left → right) instead of\n // on whichever side crossing-minimisation happened to pick. That is\n // what stops branch wires from crossing back over each other at the\n // source node (DEV-201). The caller's `engine` options still win — we\n // spread `engineOptions` last everywhere.\n const baseLayeredOptions: Record<string, string> = {\n \"elk.algorithm\": algorithm,\n \"elk.direction\": ELK_DIRECTION[direction],\n \"elk.spacing.nodeNode\": String(nodeSpacing),\n \"elk.layered.spacing.nodeNodeBetweenLayers\": String(rankSpacing),\n \"elk.layered.considerModelOrder.strategy\": \"NODES_AND_EDGES\",\n };\n\n const buildChildren = (parentId: string | undefined): ElkGraph[] => {\n const list = childrenByParent.get(parentId) ?? [];\n return list.map<ElkGraph>((n) => ({\n id: n.id,\n width: n.width ?? DEFAULT_NODE_WIDTH,\n height: n.height ?? DEFAULT_NODE_HEIGHT,\n children: childrenByParent.has(n.id) ? buildChildren(n.id) : undefined,\n layoutOptions: childrenByParent.has(n.id)\n ? {\n ...baseLayeredOptions,\n ...engineOptions,\n }\n : undefined,\n }));\n };\n\n const elkEdges: ElkEdge[] = edges\n .filter((e) => !e.hidden)\n .map((e) => ({\n id: e.id,\n sources: [e.source],\n targets: [e.target],\n }));\n\n const graph: ElkGraph = {\n id: \"root\",\n layoutOptions: {\n ...baseLayeredOptions,\n ...engineOptions,\n },\n children: buildChildren(undefined),\n edges: elkEdges,\n };\n\n const laidOut = await elk.layout(graph);\n\n // Walk the resulting graph and collect (id, position). ELK returns\n // positions relative to the parent — we walk parents to flatten\n // back to absolute flow-space coordinates (matches our ADR-003\n // \"positions are always absolute\" rule).\n const result: { id: string; position: Position }[] = [];\n const walk = (g: ElkGraph, ox: number, oy: number) => {\n const ax = ox + (g.x ?? 0);\n const ay = oy + (g.y ?? 0);\n if (g.id !== \"root\") {\n result.push({ id: g.id, position: { x: ax, y: ay } });\n }\n if (g.children) {\n for (const c of g.children) walk(c, ax, ay);\n }\n };\n walk(laidOut, 0, 0);\n return result;\n },\n };\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Narrow selector hooks — the only sanctioned way to read from the store.\n// Each hook does one thing and subscribes to the smallest possible slice\n// so re-renders are surgical.\n// ════════════════════════════════════════════════════════════════════════\n\nimport { useContext, useMemo, useSyncExternalStore } from \"react\";\nimport type {\n ConnectStartParams,\n FlowStoreSnapshot,\n Viewport,\n WorkflowEdge,\n WorkflowNode,\n} from \"../editor\";\nimport { FlowStoreContext, useFlowStore } from \"./context\";\n\n/**\n * Generic selector hook. Use for one-off reads in tests or rare cases.\n * Public hooks below cover the common paths.\n *\n * NB: `selector` must be stable (referentially equal across renders) or\n * memoised — otherwise it re-subscribes every render. We do NOT do this\n * automatically because it would mask the bug.\n */\nexport function useFlowSelector<T>(\n selector: (snapshot: FlowStoreSnapshot) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n // Note: useSyncExternalStore uses Object.is internally for change\n // detection. The `isEqual` arg is reserved for a future patch that adds\n // structural equality (e.g. for array selectors); reference it so the\n // arg isn't dead.\n void isEqual;\n const store = useFlowStore();\n return useSyncExternalStore(\n store.subscribe,\n () => selector(store.getSnapshot()),\n () => selector(store.getSnapshot()),\n );\n}\n\n// ── Reads ──────────────────────────────────────────────────────────────\n\nexport function useNodes(): WorkflowNode[] {\n return useFlowSelector((s) => s.nodes);\n}\n\nexport function useEdges(): WorkflowEdge[] {\n return useFlowSelector((s) => s.edges);\n}\n\nexport function useViewport(): Viewport {\n return useFlowSelector((s) => s.viewport);\n}\n\nconst VIEWPORT_OR_NULL_NO_STORE_SUBSCRIBE = (_cb: () => void) => () => {};\nconst VIEWPORT_OR_NULL_NO_STORE_SNAPSHOT = (): Viewport | null => null;\n\n/**\n * Like `useViewport()` but returns `null` when called outside a\n * `<FlowCanvas>`. Useful for shared chrome components (FlowToolbarZoom,\n * minimap previews) that want to auto-subscribe when mounted inside the\n * canvas, but still render correctly in isolation (Storybook, design\n * docs) when no store is present.\n *\n * The subscribe/getSnapshot pair is memoised so React subscribes once per\n * mounted `<FlowCanvas>` ancestor — flipping in/out is rare (only when a\n * canvas is unmounted around the consumer).\n */\nexport function useViewportOrNull(): Viewport | null {\n const store = useContext(FlowStoreContext);\n const { sub, snap } = useMemo(\n () =>\n store\n ? {\n sub: store.subscribe,\n snap: (): Viewport | null => store.getSnapshot().viewport,\n }\n : {\n sub: VIEWPORT_OR_NULL_NO_STORE_SUBSCRIBE,\n snap: VIEWPORT_OR_NULL_NO_STORE_SNAPSHOT,\n },\n [store],\n );\n return useSyncExternalStore(sub, snap, snap);\n}\n\nexport function useNodeById(id: string): WorkflowNode | undefined {\n return useFlowSelector((s) => s.nodes.find((n) => n.id === id));\n}\n\n/**\n * Subscribe to the `data` slice of a single node by id. Re-renders only\n * when this specific node's `data` reference changes — no cross-node\n * leakage. Pair with `FlowStateBag.updateNodeData(id, patch)` to write.\n *\n * Returns undefined when the node is not present; consumers should\n * branch on that. Typed via the generic so callers get their `TData`\n * shape back without casting.\n */\nexport function useNodeData<TData = unknown>(id: string): TData | undefined {\n return useFlowSelector(\n (s) => (s.nodes.find((n) => n.id === id)?.data as TData | undefined) ?? undefined,\n );\n}\n\nexport function useEdgeById(id: string): WorkflowEdge | undefined {\n return useFlowSelector((s) => s.edges.find((e) => e.id === id));\n}\n\nexport function useIsNodeSelected(id: string): boolean {\n return useFlowSelector((s) => s.selectedNodeIds.has(id));\n}\n\nexport function useIsEdgeSelected(id: string): boolean {\n return useFlowSelector((s) => s.selectedEdgeIds.has(id));\n}\n\nexport function useConnection(): ConnectStartParams | null {\n return useFlowSelector((s) => s.connection);\n}\n\nexport function useSelection(): { nodes: WorkflowNode[]; edges: WorkflowEdge[] } {\n // Subscribe to each underlying slice separately so useSyncExternalStore\n // sees stable references — building a fresh object inside the selector\n // would force a re-render every render (snapshot-cache violation).\n const nodes = useNodes();\n const edges = useEdges();\n const selectedNodeIds = useFlowSelector((s) => s.selectedNodeIds);\n const selectedEdgeIds = useFlowSelector((s) => s.selectedEdgeIds);\n return useMemo(\n () => ({\n nodes: nodes.filter((n) => selectedNodeIds.has(n.id)),\n edges: edges.filter((e) => selectedEdgeIds.has(e.id)),\n }),\n [nodes, edges, selectedNodeIds, selectedEdgeIds],\n );\n}\n","// ════════════════════════════════════════════════════════════════════════\n// FlowStoreContext — descendants reach the store through this React\n// context. The store itself is NOT a context value (that would tank\n// perf); only the store *handle* is. Consumers read state via the\n// selector hooks in `./selectors.ts`.\n// ════════════════════════════════════════════════════════════════════════\n\nimport { createContext, useContext } from \"react\";\nimport type { FlowStore } from \"./createFlowStore\";\n\nexport const FlowStoreContext = createContext<FlowStore | null>(null);\n\nexport function useFlowStore(): FlowStore {\n const store = useContext(FlowStoreContext);\n if (!store) {\n throw new Error(\n \"[@octaviaflow/core/workflow] useFlowStore must be called inside a <FlowCanvas>.\",\n );\n }\n return store;\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// ConfigPanel v2 — right-side editor for the selected node.\n// ════════════════════════════════════════════════════════════════════════\n// Improvements over v1:\n// - Tabbed body (config / input / output schema; consumer can override)\n// - Resizable width (drag the left edge)\n// - Pinned vs floating modes\n// - Breadcrumb header showing node kind → title\n// - Footer with save-state pill (dirty / saving / saved)\n// - Slot for inline status banner (validation errors, etc.)\n// - Inline-edit-the-title affordance (double-click)\n// - Sticky footer with save / cancel buttons\n\nimport {\n type CSSProperties,\n type PointerEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../../utils/cn\";\n\nexport type ConfigPanelSaveState = \"clean\" | \"dirty\" | \"saving\" | \"saved\" | \"error\";\n\nexport interface ConfigPanelTab {\n id: string;\n label: ReactNode;\n /** Optional badge (e.g. count of errors). */\n badge?: ReactNode;\n /** When true, the tab is rendered but disabled. */\n disabled?: boolean;\n content: ReactNode;\n}\n\nexport interface ConfigPanelProps {\n open?: boolean;\n /** Title shown in the header — the action name. Double-click opens\n * the inline editor. The header shows this single line only. */\n title?: string;\n /** Optional icon rendered before the title. */\n icon?: ReactNode;\n /**\n * Modular header action slot — buttons rendered between the title and\n * the close (✕). Use it for per-action affordances like the FX\n * toggle; omit entirely for actions that don't need them.\n */\n headerActions?: ReactNode;\n /** Inline status banner — error / warning / hint, shown at the top of the body. */\n banner?: ReactNode;\n /** Tab definitions. When omitted, `children` renders directly (no tabs). */\n tabs?: ConfigPanelTab[];\n /** Initial active tab. Controlled if `onTabChange` is provided. */\n activeTab?: string;\n defaultActiveTab?: string;\n onTabChange?: (id: string) => void;\n /** Save-state pill in the footer. Omit it entirely to hide the pill —\n * the footer then shows only its action buttons. */\n saveState?: ConfigPanelSaveState;\n /** Fires on the title editor's commit. Omit to disable title editing. */\n onTitleChange?: (next: string) => void;\n onClose?: () => void;\n onSave?: () => void;\n onCancel?: () => void;\n /**\n * Padding (px, all sides) applied to the scrollable body — the work\n * area that holds the active tab's content. Default 12. Pass `0` when\n * the consumer's tab content already pads itself.\n */\n padding?: number;\n /** Resizable width — pass `resizable: false` to lock. */\n resizable?: boolean;\n /** Initial width (px). Defaults to 400. */\n defaultWidth?: number;\n /** Lower clamp during resize. Defaults to 400 — the panel can be\n * widened but never narrowed past its default. */\n minWidth?: number;\n /**\n * Upper clamp during resize. Defaults to 720. The panel ALSO clamps\n * to its parent container's measured width minus\n * `maxWidthContainerInset` (default 80 px) so the panel can never\n * cover the whole canvas — whichever is smaller wins.\n */\n maxWidth?: number;\n /**\n * How much of the parent container to leave visible at the panel's\n * widest. Subtracted from the parent's clientWidth before clamping\n * `maxWidth`. Defaults to 80 px.\n */\n maxWidthContainerInset?: number;\n /** \"pinned\" sits flush against the canvas; \"floating\" raises with shadow. */\n variant?: \"pinned\" | \"floating\";\n /** Body slot used only when `tabs` is omitted. */\n children?: ReactNode;\n /**\n * Modular footer action buttons — replaces the built-in Cancel/Save\n * pair. The footer bar itself stays static and pinned; this slot just\n * decides which buttons live in it, so a consumer can add, remove, or\n * reorder actions freely.\n */\n footerActions?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nconst SAVE_STATE_LABEL: Record<ConfigPanelSaveState, string> = {\n clean: \"Saved\",\n dirty: \"Unsaved changes\",\n saving: \"Saving…\",\n saved: \"Saved\",\n error: \"Save failed\",\n};\n\nconst SAVE_STATE_DOT: Record<ConfigPanelSaveState, string> = {\n clean: \"var(--ods-text-tertiary)\",\n dirty: \"var(--ods-status-warning, #d97706)\",\n saving: \"var(--ods-status-running, #2563eb)\",\n saved: \"var(--ods-status-success, #16a34a)\",\n error: \"var(--ods-status-failed, #dc2626)\",\n};\n\nexport function ConfigPanel({\n open = true,\n title,\n icon,\n headerActions,\n banner,\n tabs,\n activeTab: controlledActive,\n defaultActiveTab,\n onTabChange,\n saveState,\n onTitleChange,\n onClose,\n onSave,\n onCancel,\n padding = 12,\n resizable = true,\n defaultWidth = 400,\n minWidth = 400,\n maxWidth = 720,\n maxWidthContainerInset = 80,\n variant = \"pinned\",\n children,\n footerActions,\n className,\n style,\n}: ConfigPanelProps) {\n const [width, setWidth] = useState(defaultWidth);\n // Effective upper bound — `min(maxWidth, parentClientWidth - inset)`.\n // Recomputed on every parent resize so the panel can never cover the\n // canvas. Starts at `maxWidth` so the first paint is sane; the\n // ResizeObserver below tightens it as soon as the layout settles.\n const [effectiveMax, setEffectiveMax] = useState(maxWidth);\n const panelRef = useRef<HTMLElement>(null);\n useEffect(() => {\n const el = panelRef.current;\n if (!el) return;\n const parent = el.parentElement;\n if (!parent || typeof ResizeObserver === \"undefined\") return;\n const update = () => {\n const room = parent.clientWidth - maxWidthContainerInset;\n const next = Math.max(minWidth, Math.min(maxWidth, room));\n setEffectiveMax(next);\n // If the current width exceeds the new ceiling (window shrank),\n // snap the panel down so it remains inside the canvas.\n setWidth((w) => (w > next ? next : w));\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(parent);\n return () => ro.disconnect();\n }, [maxWidth, minWidth, maxWidthContainerInset]);\n const [internalActive, setInternalActive] = useState<string | undefined>(\n defaultActiveTab ?? tabs?.[0]?.id,\n );\n const activeTabId = controlledActive ?? internalActive;\n const selectTab = (id: string) => {\n if (controlledActive === undefined) setInternalActive(id);\n onTabChange?.(id);\n };\n\n // ── Title editor ────────────────────────────────────────────────────\n const [editingTitle, setEditingTitle] = useState(false);\n const [draftTitle, setDraftTitle] = useState(title ?? \"\");\n useEffect(() => {\n if (!editingTitle) setDraftTitle(title ?? \"\");\n }, [title, editingTitle]);\n const commitTitle = (next: string) => {\n setEditingTitle(false);\n if (next !== title) onTitleChange?.(next);\n };\n const titleKeyDown = (e: ReactKeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commitTitle(draftTitle);\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n setEditingTitle(false);\n setDraftTitle(title ?? \"\");\n }\n };\n\n // ── Resize handle ───────────────────────────────────────────────────\n // We capture pointer events on the drag handle; the panel width is\n // updated on every pointermove. Width is clamped to [min, max].\n const resizeRef = useRef<{ pointerId: number; startX: number; startWidth: number } | null>(null);\n const onResizeDown = useCallback(\n (e: PointerEvent<HTMLDivElement>) => {\n if (!resizable) return;\n e.preventDefault();\n e.stopPropagation();\n resizeRef.current = { pointerId: e.pointerId, startX: e.clientX, startWidth: width };\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n },\n [resizable, width],\n );\n const onResizeMove = (e: PointerEvent<HTMLDivElement>) => {\n const r = resizeRef.current;\n if (!r || r.pointerId !== e.pointerId) return;\n // Dragging LEFT widens the panel (it sticks to the right edge of\n // the canvas). Upper bound is `effectiveMax` — the smaller of the\n // consumer's `maxWidth` and the parent container's available room,\n // so the panel can never grow past the canvas itself.\n const delta = r.startX - e.clientX;\n const next = Math.max(minWidth, Math.min(effectiveMax, r.startWidth + delta));\n setWidth(next);\n };\n const onResizeUp = (e: PointerEvent<HTMLDivElement>) => {\n if (resizeRef.current?.pointerId === e.pointerId) resizeRef.current = null;\n };\n\n if (!open) return null;\n\n const activeTab = tabs?.find((t) => t.id === activeTabId);\n\n return (\n <aside\n ref={panelRef}\n className={cn(\n \"ods-flow-config-panel\",\n `ods-flow-config-panel--${variant}`,\n editingTitle && \"ods-flow-config-panel--editing-title\",\n className,\n )}\n style={{ width, ...style }}\n aria-label={title ?? \"Configuration\"}\n >\n {resizable && (\n <div\n className=\"ods-flow-config-panel__resize\"\n onPointerDown={onResizeDown}\n onPointerMove={onResizeMove}\n onPointerUp={onResizeUp}\n onPointerCancel={onResizeUp}\n aria-hidden=\"true\"\n />\n )}\n\n <header className=\"ods-flow-config-panel__header\">\n <div className=\"ods-flow-config-panel__title-row\">\n {icon && <span className=\"ods-flow-config-panel__icon\">{icon}</span>}\n {editingTitle ? (\n <input\n className=\"ods-flow-config-panel__title-input\"\n value={draftTitle}\n autoFocus\n onChange={(e) => setDraftTitle(e.target.value)}\n onBlur={() => commitTitle(draftTitle)}\n onKeyDown={titleKeyDown}\n aria-label=\"Edit title\"\n />\n ) : (\n <button\n type=\"button\"\n className=\"ods-flow-config-panel__title\"\n onDoubleClick={() => {\n if (!onTitleChange) return;\n setDraftTitle(title ?? \"\");\n setEditingTitle(true);\n }}\n title={onTitleChange ? \"Double-click to rename\" : undefined}\n >\n {title ?? \"Untitled\"}\n </button>\n )}\n {headerActions && (\n <div className=\"ods-flow-config-panel__header-actions\">\n {headerActions}\n </div>\n )}\n {onClose && (\n <button\n type=\"button\"\n className=\"ods-flow-config-panel__close\"\n onClick={onClose}\n aria-label=\"Close panel\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\">\n <path\n d=\"M3 3l8 8M11 3l-8 8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n )}\n </div>\n </header>\n\n {tabs && tabs.length > 1 && (\n <nav className=\"ods-flow-config-panel__tabs\" role=\"tablist\">\n {tabs.map((t) => (\n <button\n key={t.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeTabId === t.id}\n disabled={t.disabled}\n className={cn(\n \"ods-flow-config-panel__tab\",\n activeTabId === t.id && \"ods-flow-config-panel__tab--active\",\n )}\n onClick={() => selectTab(t.id)}\n >\n <span>{t.label}</span>\n {t.badge !== undefined && t.badge !== null && (\n <span className=\"ods-flow-config-panel__tab-badge\">{t.badge}</span>\n )}\n </button>\n ))}\n </nav>\n )}\n\n {banner && <div className=\"ods-flow-config-panel__banner\">{banner}</div>}\n\n <div\n className=\"ods-flow-config-panel__body\"\n role=\"tabpanel\"\n style={{ padding }}\n >\n {tabs ? activeTab?.content : children}\n </div>\n\n <footer className=\"ods-flow-config-panel__footer\">\n {saveState && (\n <span\n className={cn(\n \"ods-flow-config-panel__save-state\",\n `ods-flow-config-panel__save-state--${saveState}`,\n )}\n >\n <span\n className=\"ods-flow-config-panel__save-dot\"\n style={{ background: SAVE_STATE_DOT[saveState] }}\n aria-hidden=\"true\"\n />\n {SAVE_STATE_LABEL[saveState]}\n </span>\n )}\n <div className=\"ods-flow-config-panel__footer-actions\">\n {footerActions ?? (\n <>\n {onCancel && (\n <button\n type=\"button\"\n className=\"ods-flow-config-panel__btn ods-flow-config-panel__btn--ghost\"\n onClick={onCancel}\n >\n Cancel\n </button>\n )}\n {onSave && (\n <button\n type=\"button\"\n className=\"ods-flow-config-panel__btn ods-flow-config-panel__btn--primary\"\n onClick={onSave}\n disabled={saveState === \"saving\"}\n >\n {saveState === \"saving\" ? \"Saving…\" : \"Save\"}\n </button>\n )}\n </>\n )}\n </div>\n </footer>\n </aside>\n );\n}\n","import { type ClassValue, clsx } from \"clsx\";\n\nexport function cn(...inputs: ClassValue[]): string {\n return clsx(inputs);\n}\n","\"use client\";\n\nimport {\n CheckmarkIcon,\n CodeIcon,\n CopyIcon,\n DataViewAltIcon,\n GlobeIcon,\n ListIcon,\n LockedIcon,\n PlayIcon,\n RenewIcon,\n TagIcon,\n} from \"@octaviaflow/icons\";\nimport { type ReactNode, useCallback, useId, useMemo, useRef, useState } from \"react\";\nimport { Accordion } from \"../../../components/Accordion/Accordion\";\nimport { Badge } from \"../../../components/Badge/Badge\";\nimport { Banner } from \"../../../components/Banner/Banner\";\nimport { Button } from \"../../../components/Button/Button\";\nimport { CodeEditor } from \"../../../components/CodeEditor/CodeEditor\";\nimport { Combobox } from \"../../../components/Combobox/Combobox\";\nimport { Disclosure } from \"../../../components/Disclosure/Disclosure\";\nimport { Input } from \"../../../components/Input/Input\";\nimport { JsonViewer } from \"../../../components/JsonViewer/JsonViewer\";\nimport {\n KeyValueEditor,\n type KeyValuePair,\n} from \"../../../components/KeyValueEditor/KeyValueEditor\";\nimport { NumberInput } from \"../../../components/NumberInput/NumberInput\";\nimport { PasswordInput } from \"../../../components/PasswordInput/PasswordInput\";\nimport { SegmentedControl } from \"../../../components/SegmentedControl/SegmentedControl\";\nimport { Select } from \"../../../components/Select/Select\";\nimport { Spinner } from \"../../../components/Spinner/Spinner\";\nimport { Switch } from \"../../../components/Switch/Switch\";\nimport { Tabs } from \"../../../components/Tabs/Tabs\";\nimport { cn } from \"../../../utils/cn\";\nimport {\n buildCurl,\n countGraphqlVariables,\n countSchemaPaths,\n effectiveUrl,\n formatBytes,\n HTTP_ACTION_DEFAULTS,\n HTTP_METHODS,\n type HttpActionConfig,\n type HttpAuthConfig,\n type HttpBodyType,\n type HttpKeyValue,\n type HttpMethod,\n type HttpPaginationConfig,\n type HttpPreviewRequest,\n type HttpPreviewResponse,\n type HttpResponseType,\n inferJsonSchema,\n normalizeAuth,\n normalizeKeyValues,\n parseCurl,\n statusTone,\n} from \"./httpActionTypes\";\n\n/* ---------------------------------------------------------------------------\n * HttpActionPanel — the redesigned HTTP-request action configuration.\n *\n * Design intent: SIMPLER by default, MORE powerful when needed.\n * - One promoted request bar (method · URL · Send) — testing lives where you\n * type, not at the bottom of a settings pile.\n * - Five tabs for the request itself (Params / Headers / Body / Auth /\n * Response); everything operational (timeout, retry, pagination,\n * extraction) sits behind ONE collapsed \"Advanced options\" section.\n * - Power tools: cURL import (paste any curl command → full config) and\n * copy-as-cURL; a test console with status/time/size, headers/body\n * viewers and automatic response-schema inference for downstream binding.\n *\n * The panel is host-agnostic: connections and the actual test transport are\n * injected (`connections`, `onSendPreview`), state is emitted as the full\n * engine-compatible config on every change.\n * ------------------------------------------------------------------------- */\n\nexport interface HttpConnectionEndpoint {\n method: string;\n path: string;\n summary?: string;\n}\n\nexport interface HttpConnectionOption {\n id: string;\n name: string;\n icon?: ReactNode;\n /** Endpoint catalog discovered from an imported API spec, when available. */\n endpoints?: HttpConnectionEndpoint[];\n}\n\nexport interface HttpActionPanelProps {\n /** Current step config (engine-compatible). Missing keys get defaults. */\n value?: Partial<HttpActionConfig>;\n /** Fires with the FULL merged config on every edit. */\n onChange?: (config: HttpActionConfig) => void;\n disabled?: boolean;\n /** Saved API connections for the Source picker. Omit to hide the picker. */\n connections?: HttpConnectionOption[];\n connectionsLoading?: boolean;\n /** Test-send transport. Omit to hide the Send button. */\n onSendPreview?: (request: HttpPreviewRequest) => Promise<HttpPreviewResponse>;\n className?: string;\n}\n\ntype PreviewPhase =\n | { phase: \"idle\" }\n | { phase: \"loading\" }\n | { phase: \"success\"; response: HttpPreviewResponse }\n | { phase: \"error\"; message: string };\n\nfunction toPairs(rows: HttpKeyValue[]): KeyValuePair[] {\n return rows.map((r) => ({\n key: r.key,\n value: r.value,\n enabled: r.enabled !== false,\n description: r.description,\n }));\n}\n\nfunction textOf(raw: unknown): string {\n if (typeof raw === \"string\") return raw;\n if (raw == null) return \"\";\n try {\n return JSON.stringify(raw, null, 2);\n } catch {\n return \"\";\n }\n}\n\nexport function HttpActionPanel({\n value,\n onChange,\n disabled = false,\n connections,\n connectionsLoading = false,\n onSendPreview,\n className,\n}: HttpActionPanelProps) {\n const uid = useId();\n\n /* ── config state (initialized once from `value`, emitted in full) ──── */\n const cfgRef = useRef<HttpActionConfig>({\n ...HTTP_ACTION_DEFAULTS,\n ...value,\n queryParams: normalizeKeyValues(value?.queryParams),\n headers: normalizeKeyValues(value?.headers),\n formData: normalizeKeyValues(value?.formData),\n auth: normalizeAuth(value?.auth),\n retry: {\n ...HTTP_ACTION_DEFAULTS.retry,\n ...(value?.retry as object),\n } as HttpActionConfig[\"retry\"],\n pagination: {\n ...HTTP_ACTION_DEFAULTS.pagination,\n ...(value?.pagination as object),\n } as HttpActionConfig[\"pagination\"],\n });\n const [, force] = useState(0);\n const emit = useCallback(\n (patch: Partial<HttpActionConfig>) => {\n cfgRef.current = { ...cfgRef.current, ...patch };\n force((n) => n + 1);\n onChange?.(cfgRef.current);\n },\n [onChange],\n );\n const cfg = cfgRef.current;\n\n const connectionId = cfg.connectionId ?? \"\";\n const selectedConnection = connections?.find((c) => c.id === connectionId) ?? null;\n const endpoints = selectedConnection?.endpoints ?? [];\n const method = cfg.method ?? \"GET\";\n const url = cfg.url ?? \"\";\n const baseUrl = cfg.baseUrl ?? \"\";\n const fullUrl = connectionId ? url : effectiveUrl(baseUrl, url);\n const queryParams = normalizeKeyValues(cfg.queryParams);\n const headers = normalizeKeyValues(cfg.headers);\n const formData = normalizeKeyValues(cfg.formData);\n const auth = normalizeAuth(cfg.auth);\n const retry = cfg.retry ?? HTTP_ACTION_DEFAULTS.retry;\n const pagination = cfg.pagination ?? { type: \"none\" as const };\n const responseType = cfg.responseType ?? \"json\";\n\n /* ── text buffers (kept as typed, parsed on emit) ─────────────────── */\n const [bodyText, setBodyText] = useState(() => textOf(cfg.body));\n const [bodyError, setBodyError] = useState<string | undefined>();\n const [gqlVarsText, setGqlVarsText] = useState(() => textOf(cfg.graphqlVariables));\n const [gqlVarsError, setGqlVarsError] = useState<string | undefined>();\n const [retryOnText, setRetryOnText] = useState(() => (retry?.retryOn ?? []).join(\", \"));\n const [expectedCtText, setExpectedCtText] = useState(() =>\n (cfg.expectedContentTypes ?? []).join(\", \"),\n );\n const [urlError, setUrlError] = useState<string | undefined>();\n const [extractRows, setExtractRows] = useState<HttpKeyValue[]>(() =>\n Object.entries(cfg.extract ?? {}).map(([key, v]) => ({ key, value: v, enabled: true })),\n );\n\n /* ── cURL import/export ───────────────────────────────────────────── */\n const [curlOpen, setCurlOpen] = useState(false);\n const [curlText, setCurlText] = useState(\"\");\n const [curlError, setCurlError] = useState<string | undefined>();\n // Copy affordances follow the CodeEditor/JsonViewer convention:\n // CopyIcon → CheckmarkIcon + success tint for a beat, never a \"✓\" char.\n const [copiedCurl, setCopiedCurl] = useState(false);\n const [copiedResult, setCopiedResult] = useState(false);\n // Per-section copy (URL / response headers / raw body) — keyed so only the\n // clicked section flips to its \"copied\" state for a beat.\n const [copiedSection, setCopiedSection] = useState<string | null>(null);\n\n const applyCurl = () => {\n const patch = parseCurl(curlText);\n if (!patch) {\n setCurlError(\n \"That doesn't look like a cURL command — it should start with `curl` and include a URL.\",\n );\n return;\n }\n setCurlError(undefined);\n setCurlText(\"\");\n setCurlOpen(false);\n setBodyText(textOf(patch.body));\n setBodyError(undefined);\n emit({ ...patch, connectionId: undefined, baseUrl: undefined });\n };\n\n const copyCurl = async () => {\n try {\n await navigator.clipboard?.writeText(buildCurl(cfg));\n setCopiedCurl(true);\n setTimeout(() => setCopiedCurl(false), 1600);\n } catch {\n /* clipboard unavailable (permissions / insecure context) — no-op */\n }\n };\n\n /** Copy the last test result as a shareable/debuggable JSON bundle. */\n const copyResult = async () => {\n if (preview.phase !== \"success\") return;\n const r = preview.response;\n const bundle = {\n request: {\n method: cfg.apiType === \"graphql\" ? \"POST\" : method,\n url: connectionId ? `${selectedConnection?.name ?? connectionId} · ${url}` : fullUrl,\n },\n response: {\n status: r.status,\n statusText: r.statusText,\n ok: r.ok,\n durationMs: r.duration,\n sizeBytes: r.size,\n headers: r.headers,\n body: r.body,\n },\n };\n try {\n await navigator.clipboard?.writeText(JSON.stringify(bundle, null, 2));\n setCopiedResult(true);\n setTimeout(() => setCopiedResult(false), 1600);\n } catch {\n /* clipboard unavailable — no-op */\n }\n };\n\n /** Copy an individual console section (request URL / response headers / raw body). */\n const copySection = async (text: string, key: string) => {\n try {\n await navigator.clipboard?.writeText(text);\n setCopiedSection(key);\n setTimeout(() => setCopiedSection(null), 1600);\n } catch {\n /* clipboard unavailable — no-op */\n }\n };\n\n /** Icon-only ghost copy button used per console section. */\n const sectionCopyButton = (text: string, key: string, label: string) => (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label={copiedSection === key ? `${label} copied` : `Copy ${label}`}\n leftIcon={copiedSection === key ? <CheckmarkIcon size=\"sm\" /> : <CopyIcon size=\"sm\" />}\n className={cn(copiedSection === key && \"ods-http-panel__copy-done\")}\n onClick={(e) => {\n e.stopPropagation();\n void copySection(text, key);\n }}\n />\n );\n\n /* ── URL handling ─────────────────────────────────────────────────── */\n const validateUrl = (nextUrl: string, nextBase: string, hasConnection: boolean) => {\n if (!nextUrl && !nextBase && !hasConnection) {\n setUrlError(\"URL is required\");\n return;\n }\n if (!nextUrl || hasConnection || nextBase || nextUrl.includes(\"{{\")) {\n setUrlError(undefined);\n return;\n }\n try {\n new URL(nextUrl);\n setUrlError(undefined);\n } catch {\n setUrlError(\"URL does not look valid\");\n }\n };\n\n /* ── body mode (GraphQL is a body mode persisted as apiType) ──────── */\n const bodyMode = cfg.apiType === \"graphql\" ? \"graphql\" : (cfg.bodyType ?? \"json\");\n const gqlVarCount = useMemo(\n () => countGraphqlVariables(cfg.graphqlQuery ?? \"\"),\n [cfg.graphqlQuery],\n );\n const handleBodyMode = (next: string) => {\n if (next === \"graphql\") {\n // Coach (don't force) POST for GraphQL; stays editable for persisted-query GETs.\n emit(method === \"GET\" ? { apiType: \"graphql\", method: \"POST\" } : { apiType: \"graphql\" });\n return;\n }\n emit({ apiType: \"rest\", bodyType: next as HttpBodyType });\n };\n\n /* ── preview / test console ───────────────────────────────────────── */\n const [preview, setPreview] = useState<PreviewPhase>({ phase: \"idle\" });\n const [schemaInfo, setSchemaInfo] = useState<{ pathCount: number; topKeys: string[] } | null>(\n null,\n );\n const lastSchemaKey = useRef(\"\");\n\n const inferAndEmitSchema = useCallback(\n (response: HttpPreviewResponse, forceRefresh = false) => {\n if (responseType === \"binary\") return;\n const snapshot = {\n status: response.status,\n statusText: response.statusText,\n ok: response.ok,\n headers: response.headers,\n body: response.body,\n duration: response.duration,\n attempts: 1,\n extracted: {},\n };\n const inferred = inferJsonSchema(snapshot);\n const key = JSON.stringify(inferred);\n if (!forceRefresh && key === lastSchemaKey.current) return;\n lastSchemaKey.current = key;\n emit({ _outputSchema: inferred });\n const bodySchema = inferred.properties?.body;\n const topKeys = Object.keys(bodySchema?.properties ?? inferred.properties ?? {});\n setSchemaInfo({ pathCount: countSchemaPaths(inferred), topKeys });\n },\n [emit, responseType],\n );\n\n const sendPreview = async () => {\n if (!onSendPreview) return;\n setPreview({ phase: \"loading\" });\n try {\n const response = await onSendPreview({\n method: (cfg.apiType === \"graphql\" ? \"POST\" : method) as HttpMethod,\n url: connectionId ? url : fullUrl,\n connectionId: connectionId || undefined,\n headers,\n queryParams,\n bodyType: (cfg.bodyType ?? \"json\") as HttpBodyType,\n body: bodyText,\n formData,\n graphqlQuery: cfg.apiType === \"graphql\" ? (cfg.graphqlQuery ?? \"\") : undefined,\n graphqlVariables: cfg.apiType === \"graphql\" ? gqlVarsText : undefined,\n auth,\n timeout: cfg.timeout ?? 30000,\n });\n setPreview({ phase: \"success\", response });\n inferAndEmitSchema(response);\n } catch (err) {\n setPreview({\n phase: \"error\",\n message: err instanceof Error ? err.message : \"Request failed\",\n });\n }\n };\n\n const previewUrlOk = Boolean(fullUrl) && !fullUrl.includes(\"{{\");\n const canSend =\n Boolean(onSendPreview) && previewUrlOk && preview.phase !== \"loading\" && !disabled;\n\n /* ── counts / badges ──────────────────────────────────────────────── */\n const paramCount = queryParams.filter((r) => r.enabled !== false && r.key).length;\n const headerCount = headers.filter((r) => r.enabled !== false && r.key).length;\n const extractCount = extractRows.filter((r) => r.key).length;\n const advancedSummary: string[] = [];\n if ((cfg.timeout ?? 30000) !== 30000) advancedSummary.push(`${(cfg.timeout ?? 0) / 1000}s`);\n if ((retry?.maxAttempts ?? 1) > 1) advancedSummary.push(`retry ×${retry?.maxAttempts}`);\n if (pagination.type !== \"none\") advancedSummary.push(pagination.type.replace(\"_\", \" \"));\n if (extractCount > 0) advancedSummary.push(`${extractCount} extracted`);\n\n /* ── shared sub-renderers ─────────────────────────────────────────── */\n const kvTab = (\n rows: HttpKeyValue[],\n key: \"queryParams\" | \"headers\",\n desc: ReactNode,\n keyPlaceholder: string,\n ) => (\n <div className=\"ods-http-panel__tab\">\n <p className=\"ods-http-panel__desc\">{desc}</p>\n <KeyValueEditor\n pairs={toPairs(rows)}\n // Keep the rows RAW (incl. the blank row that \"Add\" appends). Running\n // serializeKeyValues here dropped fully-empty rows on every change, so\n // clicking Add produced a row that was immediately stripped and never\n // rendered. Empty rows are harmless on the wire — the engine (and the\n // preview path) skip any row with no key.\n onChange={(pairs) => emit({ [key]: pairs as HttpKeyValue[] })}\n rowToggle\n showDescription\n keyPlaceholder={keyPlaceholder}\n valuePlaceholder=\"value or {{var}}\"\n emptyLabel=\"No entries yet — click Add to begin.\"\n addLabel=\"Add\"\n size=\"sm\"\n disabled={disabled}\n />\n </div>\n );\n\n const paramsTab = kvTab(\n queryParams,\n \"queryParams\",\n <>\n Query parameters appended to the URL. Supports <code>{\"{{variable}}\"}</code> interpolation.\n </>,\n \"param name\",\n );\n\n const headersTab = kvTab(\n headers,\n \"headers\",\n <>\n Request headers. Auth headers are injected automatically from the Auth tab. Supports{\" \"}\n <code>{\"{{variable}}\"}</code> interpolation.\n </>,\n \"Header-Name\",\n );\n\n const bodyTab = (\n <div className=\"ods-http-panel__tab\">\n <SegmentedControl\n size=\"sm\"\n aria-label=\"Body type\"\n options={[\n { value: \"none\", label: \"None\" },\n { value: \"json\", label: \"JSON\" },\n { value: \"graphql\", label: \"GraphQL\" },\n { value: \"raw\", label: \"Raw\" },\n { value: \"form-data\", label: \"Form\" },\n { value: \"xml\", label: \"XML\" },\n ]}\n value={bodyMode}\n onChange={handleBodyMode}\n />\n\n {bodyMode === \"none\" && (\n <p className=\"ods-http-panel__empty\">No request body will be sent.</p>\n )}\n\n {(bodyMode === \"json\" || bodyMode === \"raw\" || bodyMode === \"xml\") && (\n <>\n <CodeEditor\n value={bodyText}\n language={bodyMode === \"json\" ? \"json\" : \"plain\"}\n onChange={(next) => {\n setBodyText(next);\n if (bodyMode === \"json\" && next.trim()) {\n try {\n emit({ body: JSON.parse(next) });\n setBodyError(undefined);\n } catch {\n setBodyError(\"Invalid JSON\");\n emit({ body: next });\n }\n } else {\n setBodyError(undefined);\n emit({ body: next || undefined });\n }\n }}\n readOnly={disabled}\n minHeight={180}\n ariaLabel=\"Request body\"\n />\n {bodyError && <p className=\"ods-http-panel__error\">⚠ {bodyError}</p>}\n <p className=\"ods-http-panel__desc\">\n Supports <code>{\"{{variable}}\"}</code> interpolation.\n </p>\n </>\n )}\n\n {bodyMode === \"graphql\" && (\n <>\n <CodeEditor\n value={cfg.graphqlQuery ?? \"\"}\n language=\"plain\"\n onChange={(next) => emit({ graphqlQuery: next })}\n readOnly={disabled}\n minHeight={160}\n placeholder={\"query ($id: ID!) {\\n node(id: $id) { id }\\n}\"}\n ariaLabel=\"GraphQL query\"\n />\n <Disclosure\n size=\"sm\"\n title=\"Variables\"\n defaultOpen={Boolean(gqlVarsText.trim()) || gqlVarCount > 0}\n trailing={\n gqlVarCount > 0 ? (\n <Badge size=\"sm\" variant=\"neutral\">\n {gqlVarCount}\n </Badge>\n ) : undefined\n }\n >\n <CodeEditor\n value={gqlVarsText}\n language=\"json\"\n onChange={(next) => {\n setGqlVarsText(next);\n if (!next.trim()) {\n setGqlVarsError(undefined);\n emit({ graphqlVariables: {} });\n return;\n }\n try {\n emit({ graphqlVariables: JSON.parse(next) });\n setGqlVarsError(undefined);\n } catch {\n setGqlVarsError(\"Invalid JSON\");\n }\n }}\n readOnly={disabled}\n minHeight={100}\n ariaLabel=\"GraphQL variables (JSON)\"\n />\n {gqlVarsError && <p className=\"ods-http-panel__error\">⚠ {gqlVarsError}</p>}\n </Disclosure>\n </>\n )}\n\n {bodyMode === \"form-data\" && (\n <>\n <p className=\"ods-http-panel__desc\">\n Multipart form fields. Content-Type is set automatically with the boundary.\n </p>\n <KeyValueEditor\n pairs={toPairs(formData)}\n onChange={(pairs) =>\n // Raw rows — see the params/headers note; serializing here ate\n // the blank row that Add appends.\n emit({ formData: pairs as HttpKeyValue[], bodyType: \"form-data\" })\n }\n rowToggle\n keyPlaceholder=\"field name\"\n valuePlaceholder=\"value or {{var}}\"\n emptyLabel=\"No fields yet — click Add to begin.\"\n addLabel=\"Add\"\n size=\"sm\"\n disabled={disabled}\n />\n </>\n )}\n </div>\n );\n\n const authTab = (\n <div className=\"ods-http-panel__tab\">\n {connectionId ? (\n <Banner variant=\"success\" appearance=\"subtle\" size=\"sm\">\n Authentication is inherited from <strong>{selectedConnection?.name}</strong> and refreshed\n automatically. Choose a type below only to override it for this step.\n </Banner>\n ) : (\n <Banner variant=\"info\" appearance=\"subtle\" size=\"sm\">\n For OAuth 2.0 APIs that need a login screen, create an API connection and select it as the\n Source — the token is obtained once and refreshed automatically. Inline auth here is for\n non-interactive credentials only.\n </Banner>\n )}\n\n <Select\n id={`${uid}-auth-type`}\n label={connectionId ? \"Override authentication\" : \"Authentication\"}\n value={auth.type}\n onChange={(next) => emit({ auth: { ...auth, type: next as HttpAuthConfig[\"type\"] } })}\n disabled={disabled}\n options={[\n { value: \"none\", label: connectionId ? \"Inherit from connection\" : \"No auth\" },\n { value: \"basic\", label: \"Basic auth (username + password)\" },\n { value: \"bearer\", label: \"Bearer token\" },\n { value: \"apikey\", label: \"API key\" },\n ]}\n />\n\n {auth.type === \"basic\" && (\n <div className=\"ods-http-panel__grid\">\n <Input\n id={`${uid}-auth-user`}\n label=\"Username\"\n value={auth.username ?? \"\"}\n placeholder=\"username or {{var}}\"\n onChange={(e) => emit({ auth: { ...auth, username: e.target.value } })}\n disabled={disabled}\n />\n <PasswordInput\n id={`${uid}-auth-pass`}\n label=\"Password\"\n value={auth.password ?? \"\"}\n placeholder=\"password or {{var}}\"\n onChange={(next: string) => emit({ auth: { ...auth, password: next } })}\n disabled={disabled}\n />\n </div>\n )}\n\n {auth.type === \"bearer\" && (\n <PasswordInput\n id={`${uid}-auth-token`}\n label=\"Token\"\n value={auth.token ?? \"\"}\n placeholder=\"your-token or {{step.token}}\"\n onChange={(next: string) => emit({ auth: { ...auth, token: next } })}\n disabled={disabled}\n />\n )}\n\n {auth.type === \"apikey\" && (\n <div className=\"ods-http-panel__grid\">\n <Input\n id={`${uid}-auth-keyname`}\n label=\"Key name\"\n value={auth.apiKeyName ?? \"\"}\n placeholder=\"X-API-Key\"\n onChange={(e) => emit({ auth: { ...auth, apiKeyName: e.target.value } })}\n disabled={disabled}\n />\n <PasswordInput\n id={`${uid}-auth-keyval`}\n label=\"Key value\"\n value={auth.apiKeyValue ?? \"\"}\n placeholder=\"your-api-key or {{var}}\"\n onChange={(next: string) => emit({ auth: { ...auth, apiKeyValue: next } })}\n disabled={disabled}\n />\n <Select\n id={`${uid}-auth-keyloc`}\n label=\"Send in\"\n value={auth.apiKeyLocation ?? \"header\"}\n onChange={(next) =>\n emit({ auth: { ...auth, apiKeyLocation: next as \"header\" | \"query\" } })\n }\n disabled={disabled}\n options={[\n { value: \"header\", label: \"Request header\" },\n { value: \"query\", label: \"Query parameter\" },\n ]}\n />\n </div>\n )}\n\n {auth.type === \"none\" && (\n <p className=\"ods-http-panel__empty\">\n {connectionId\n ? \"This step uses the connection's authentication.\"\n : \"No authentication will be added to this request.\"}\n </p>\n )}\n </div>\n );\n\n const responseTab = (\n <div className=\"ods-http-panel__tab\">\n <SegmentedControl\n size=\"sm\"\n aria-label=\"Response type\"\n options={[\n { value: \"json\", label: \"JSON\" },\n { value: \"text\", label: \"Text\" },\n { value: \"binary\", label: \"Binary\" },\n ]}\n value={responseType}\n onChange={(next) => emit({ responseType: next as HttpResponseType })}\n />\n <p className=\"ods-http-panel__desc\">\n {responseType === \"json\" &&\n \"Tries to parse the response body as JSON; falls back to raw text on parse failure.\"}\n {responseType === \"text\" && \"Returns the raw response body as a string. No JSON parsing.\"}\n {responseType === \"binary\" && (\n <>\n Returns the response as bytes with <code>fileName</code>, <code>contentType</code> and{\" \"}\n <code>size</code> on the step output — for downloads feeding file actions. Pagination is\n not compatible with binary responses.\n </>\n )}\n </p>\n\n <Input\n id={`${uid}-expected-ct`}\n label=\"Expected content-types (optional)\"\n value={expectedCtText}\n placeholder=\"application/pdf, application/json\"\n helperText=\"Comma-separated. A warning is logged when the response Content-Type matches none of these.\"\n onChange={(e) => {\n setExpectedCtText(e.target.value);\n const parts = e.target.value\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n emit({ expectedContentTypes: parts.length ? parts : undefined });\n }}\n disabled={disabled}\n />\n\n <div className=\"ods-http-panel__schema\">\n <span className=\"ods-http-panel__schema-label\">Data stream schema</span>\n {schemaInfo ? (\n <p className=\"ods-http-panel__desc\">\n <Badge size=\"sm\" variant=\"success\">\n {schemaInfo.pathCount} paths\n </Badge>{\" \"}\n Inferred from the last test send. Top-level keys:{\" \"}\n <code>{schemaInfo.topKeys.join(\", \")}</code>. Downstream binding (Field Mapper,\n Transform, ForEach) sees this shape immediately; Save persists it.\n </p>\n ) : (\n <p className=\"ods-http-panel__desc\">\n No schema yet — hit <strong>Send</strong> in the request bar. On success the response\n shape is inferred so downstream steps bind against real field names.\n </p>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={preview.phase !== \"success\" || responseType === \"binary\" || disabled}\n onClick={() => {\n if (preview.phase === \"success\") inferAndEmitSchema(preview.response, true);\n }}\n >\n Refresh schema from last send\n </Button>\n </div>\n </div>\n );\n\n const tabItems = [\n {\n value: \"params\",\n label: paramCount ? `Params · ${paramCount}` : \"Params\",\n icon: <ListIcon size=\"sm\" />,\n children: paramsTab,\n },\n {\n value: \"headers\",\n label: headerCount ? `Headers · ${headerCount}` : \"Headers\",\n icon: <TagIcon size=\"sm\" />,\n children: headersTab,\n },\n {\n value: \"body\",\n label:\n bodyMode === \"none\" ? \"Body\" : `Body · ${bodyMode === \"form-data\" ? \"form\" : bodyMode}`,\n icon: <CodeIcon size=\"sm\" />,\n children: bodyTab,\n },\n {\n value: \"auth\",\n label: auth.type === \"none\" ? \"Auth\" : `Auth · ${auth.type}`,\n icon: <LockedIcon size=\"sm\" />,\n children: authTab,\n },\n {\n value: \"response\",\n label: responseType === \"json\" ? \"Response\" : `Response · ${responseType}`,\n icon: <DataViewAltIcon size=\"sm\" />,\n children: responseTab,\n },\n ];\n\n /* ── render ───────────────────────────────────────────────────────── */\n return (\n <div className={cn(\"ods-http-panel\", className)}>\n {/* Source connection + endpoint picker */}\n {connections && (\n <div className=\"ods-http-panel__source\">\n <Select\n id={`${uid}-connection`}\n label=\"Source\"\n placeholder={connectionsLoading ? \"Loading…\" : \"No connection (manual config)\"}\n options={connections.map((c) => ({ value: c.id, label: c.name, icon: c.icon }))}\n value={connectionId}\n onChange={(next) => emit({ connectionId: next || undefined })}\n disabled={disabled || connectionsLoading}\n helperText={\n connectionId\n ? `Base URL and auth are inherited from \"${selectedConnection?.name}\" at runtime.`\n : \"Select a saved API connection to inherit base URL and auth, or configure manually.\"\n }\n />\n {connectionId && endpoints.length > 0 && (\n <Combobox\n ariaLabel=\"Endpoint\"\n placeholder={`Search ${endpoints.length} discovered endpoints…`}\n value={url}\n creatable\n options={endpoints.map((e) => ({\n value: e.path,\n label: `${e.method} ${e.path}`,\n description: e.summary,\n }))}\n onChange={(nextPath) => {\n const match = endpoints.find((e) => e.path === nextPath);\n validateUrl(nextPath, baseUrl, true);\n emit(\n match && (HTTP_METHODS as string[]).includes(match.method.toUpperCase())\n ? { url: nextPath, method: match.method.toUpperCase() as HttpMethod }\n : { url: nextPath },\n );\n }}\n />\n )}\n </div>\n )}\n\n {/* Request bar: method · URL · Send */}\n <div className=\"ods-http-panel__bar\">\n <Select\n id={`${uid}-method`}\n aria-label=\"HTTP method\"\n className={cn(\n \"ods-http-panel__method\",\n `ods-http-panel__method--${method.toLowerCase()}`,\n )}\n value={method}\n onChange={(next) => emit({ method: next as HttpMethod })}\n disabled={disabled}\n options={HTTP_METHODS.map((m) => ({ value: m, label: m }))}\n />\n <Input\n id={`${uid}-url`}\n aria-label={connectionId ? \"Path\" : \"URL\"}\n data-fx-droppable=\"true\"\n className=\"ods-http-panel__url\"\n value={url}\n placeholder={connectionId ? \"/v1/users\" : \"https://api.example.com/v1/users or {{var}}\"}\n error={Boolean(urlError)}\n errorMessage={urlError}\n onChange={(e) => {\n validateUrl(e.target.value, baseUrl, Boolean(connectionId));\n emit({ url: e.target.value });\n }}\n disabled={disabled}\n />\n {onSendPreview && (\n <Button\n variant=\"primary\"\n size=\"md\"\n leftIcon={preview.phase === \"loading\" ? undefined : <PlayIcon size=\"sm\" />}\n onClick={sendPreview}\n disabled={!canSend}\n >\n {preview.phase === \"loading\" ? \"Sending…\" : \"Send\"}\n </Button>\n )}\n </div>\n\n {/* Bar footnotes */}\n {!connectionId && baseUrl && (\n <p className=\"ods-http-panel__effective\">\n <span>Effective URL:</span> <code>{fullUrl || \"—\"}</code>\n </p>\n )}\n {fullUrl.includes(\"{{\") && (\n <p className=\"ods-http-panel__desc\">\n ⚠ URL contains <code>{\"{{variables}}\"}</code> — they resolve at run time; testing needs\n literal values.\n </p>\n )}\n <div className=\"ods-http-panel__tools\">\n <span className=\"ods-http-panel__hint\">\n Use <code>{\"{{stepName.fieldPath}}\"}</code> to insert data from upstream steps.\n </span>\n <span className=\"ods-http-panel__tools-actions\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setCurlOpen((o) => !o)}>\n Import cURL\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className={cn(copiedCurl && \"ods-http-panel__copy-done\")}\n leftIcon={copiedCurl ? <CheckmarkIcon size=\"sm\" /> : <CopyIcon size=\"sm\" />}\n onClick={copyCurl}\n >\n {copiedCurl ? \"Copied\" : \"Copy as cURL\"}\n </Button>\n </span>\n </div>\n\n {curlOpen && (\n <div className=\"ods-http-panel__curl\">\n <CodeEditor\n value={curlText}\n language=\"plain\"\n onChange={setCurlText}\n minHeight={90}\n showLineNumbers={false}\n placeholder=\"curl -X POST 'https://api.example.com/v1/users' -H 'Authorization: Bearer …' -d '{…}'\"\n ariaLabel=\"cURL command\"\n />\n {curlError && <p className=\"ods-http-panel__error\">⚠ {curlError}</p>}\n <div className=\"ods-http-panel__curl-actions\">\n <Button variant=\"secondary\" size=\"sm\" onClick={() => setCurlOpen(false)}>\n Cancel\n </Button>\n <Button variant=\"primary\" size=\"sm\" onClick={applyCurl} disabled={!curlText.trim()}>\n Apply to request\n </Button>\n </div>\n </div>\n )}\n\n {/* Request tabs */}\n <Tabs items={tabItems} defaultValue=\"params\" className=\"ods-http-panel__tabs\" />\n\n {/* ONE advanced section — everything operational */}\n <Disclosure\n size=\"sm\"\n icon={<GlobeIcon size=\"sm\" />}\n title=\"Advanced options\"\n description=\"Base URL, timeout, retries, pagination, response extraction\"\n trailing={\n advancedSummary.length ? (\n <Badge size=\"sm\" variant=\"info\">\n {advancedSummary.join(\" · \")}\n </Badge>\n ) : undefined\n }\n >\n <div className=\"ods-http-panel__grid\">\n {!connectionId && (\n <Input\n id={`${uid}-base-url`}\n label=\"Base URL (optional)\"\n value={baseUrl}\n placeholder=\"https://api.example.com\"\n helperText=\"Combined with the request path to form the full URL.\"\n onChange={(e) => {\n validateUrl(url, e.target.value, Boolean(connectionId));\n emit({ baseUrl: e.target.value || undefined });\n }}\n disabled={disabled}\n />\n )}\n <NumberInput\n label=\"Timeout (ms)\"\n helperText=\"Minimum 1000 ms\"\n value={cfg.timeout ?? 30000}\n min={1000}\n step={1000}\n onChange={(next) => {\n if (!Number.isNaN(next) && next >= 1000) emit({ timeout: next });\n }}\n disabled={disabled}\n />\n <div className=\"ods-http-panel__switches\">\n <Switch\n id={`${uid}-fail`}\n label=\"Fail on non-2xx\"\n checked={cfg.failOnError !== false}\n onChange={(next) => emit({ failOnError: next })}\n disabled={disabled}\n size=\"sm\"\n />\n <Switch\n id={`${uid}-redirects`}\n label=\"Follow redirects\"\n checked={cfg.followRedirects !== false}\n onChange={(next) => emit({ followRedirects: next })}\n disabled={disabled}\n size=\"sm\"\n />\n </div>\n </div>\n\n <Disclosure\n size=\"sm\"\n title=\"Retry\"\n trailing={\n (retry?.maxAttempts ?? 1) > 1 ? (\n <Badge size=\"sm\" variant=\"info\">\n {retry?.maxAttempts} attempts\n </Badge>\n ) : undefined\n }\n >\n <div className=\"ods-http-panel__grid\">\n <NumberInput\n label=\"Max attempts\"\n helperText=\"1 = no retry\"\n value={retry?.maxAttempts ?? 1}\n min={1}\n max={10}\n onChange={(next) => {\n if (!Number.isNaN(next) && next >= 1 && retry) {\n emit({ retry: { ...retry, maxAttempts: next } });\n }\n }}\n disabled={disabled}\n />\n <Input\n id={`${uid}-retry-on`}\n label=\"Retry on (status codes)\"\n value={retryOnText}\n placeholder=\"429, 500, 502, 503, 504\"\n helperText=\"Comma-separated HTTP status codes\"\n onChange={(e) => {\n setRetryOnText(e.target.value);\n const codes = e.target.value\n .split(\",\")\n .map((s) => Number.parseInt(s.trim(), 10))\n .filter((n) => !Number.isNaN(n));\n if (retry) emit({ retry: { ...retry, retryOn: codes } });\n }}\n disabled={disabled}\n />\n <NumberInput\n label=\"Initial delay (ms)\"\n value={retry?.initialDelayMs ?? 1000}\n min={100}\n step={100}\n onChange={(next) => {\n if (!Number.isNaN(next) && retry)\n emit({ retry: { ...retry, initialDelayMs: next } });\n }}\n disabled={disabled}\n />\n <NumberInput\n label=\"Backoff factor\"\n helperText=\"Delay multiplies by this each retry\"\n value={retry?.backoffFactor ?? 2}\n min={1}\n step={0.5}\n onChange={(next) => {\n if (!Number.isNaN(next) && retry)\n emit({ retry: { ...retry, backoffFactor: next } });\n }}\n disabled={disabled}\n />\n <NumberInput\n label=\"Max delay (ms)\"\n value={retry?.maxDelayMs ?? 30000}\n min={1000}\n step={1000}\n onChange={(next) => {\n if (!Number.isNaN(next) && retry) emit({ retry: { ...retry, maxDelayMs: next } });\n }}\n disabled={disabled}\n />\n </div>\n </Disclosure>\n\n <Disclosure\n size=\"sm\"\n title=\"Pagination\"\n trailing={\n pagination.type !== \"none\" ? (\n <Badge size=\"sm\" variant=\"success\">\n {pagination.type.replace(\"_\", \" \")}\n </Badge>\n ) : undefined\n }\n >\n <Select\n id={`${uid}-pag-type`}\n label=\"Strategy\"\n value={pagination.type}\n onChange={(next) =>\n emit({\n pagination: { ...pagination, type: next as HttpPaginationConfig[\"type\"] },\n })\n }\n disabled={disabled}\n options={[\n { value: \"none\", label: \"None (single request)\" },\n { value: \"offset\", label: \"Offset / page number\" },\n { value: \"cursor\", label: \"Cursor-based\" },\n { value: \"link_header\", label: 'Link header (rel=\"next\")' },\n { value: \"next_url\", label: \"Next URL in response body\" },\n ]}\n />\n {pagination.type !== \"none\" && (\n <div className=\"ods-http-panel__grid\">\n <NumberInput\n label=\"Max pages\"\n helperText=\"Safety cap against infinite loops\"\n value={pagination.maxPages ?? 20}\n min={1}\n onChange={(next) => {\n if (!Number.isNaN(next)) emit({ pagination: { ...pagination, maxPages: next } });\n }}\n disabled={disabled}\n />\n <Input\n id={`${uid}-pag-merge`}\n label=\"Merge key (dot path)\"\n value={pagination.mergeKey ?? \"\"}\n placeholder=\"data.items\"\n helperText=\"Array to merge across pages\"\n onChange={(e) => emit({ pagination: { ...pagination, mergeKey: e.target.value } })}\n disabled={disabled}\n />\n {(pagination.type === \"offset\" || pagination.type === \"cursor\") && (\n <>\n <Input\n id={`${uid}-pag-limitp`}\n label=\"Limit param\"\n value={pagination.limitParam ?? \"limit\"}\n onChange={(e) =>\n emit({ pagination: { ...pagination, limitParam: e.target.value } })\n }\n disabled={disabled}\n />\n <NumberInput\n label=\"Page size\"\n value={pagination.limitValue ?? 100}\n min={1}\n onChange={(next) => {\n if (!Number.isNaN(next)) {\n emit({ pagination: { ...pagination, limitValue: next } });\n }\n }}\n disabled={disabled}\n />\n </>\n )}\n {pagination.type === \"offset\" && (\n <Input\n id={`${uid}-pag-offset`}\n label=\"Offset param\"\n value={pagination.offsetParam ?? \"offset\"}\n onChange={(e) =>\n emit({ pagination: { ...pagination, offsetParam: e.target.value } })\n }\n disabled={disabled}\n />\n )}\n {pagination.type === \"cursor\" && (\n <>\n <Input\n id={`${uid}-pag-cres`}\n label=\"Cursor in response (dot path)\"\n value={pagination.cursorResponsePath ?? \"\"}\n placeholder=\"meta.next_cursor\"\n onChange={(e) =>\n emit({ pagination: { ...pagination, cursorResponsePath: e.target.value } })\n }\n disabled={disabled}\n />\n <Input\n id={`${uid}-pag-creq`}\n label=\"Cursor request param\"\n value={pagination.cursorRequestParam ?? \"cursor\"}\n onChange={(e) =>\n emit({ pagination: { ...pagination, cursorRequestParam: e.target.value } })\n }\n disabled={disabled}\n />\n </>\n )}\n {pagination.type === \"next_url\" && (\n <Input\n id={`${uid}-pag-next`}\n label=\"Next URL in response (dot path)\"\n value={pagination.nextUrlResponsePath ?? \"\"}\n placeholder=\"links.next\"\n onChange={(e) =>\n emit({ pagination: { ...pagination, nextUrlResponsePath: e.target.value } })\n }\n disabled={disabled}\n />\n )}\n </div>\n )}\n </Disclosure>\n\n <Disclosure\n size=\"sm\"\n title=\"Response field extraction\"\n trailing={\n extractCount > 0 ? (\n <Badge size=\"sm\" variant=\"info\">\n {extractCount} field{extractCount === 1 ? \"\" : \"s\"}\n </Badge>\n ) : undefined\n }\n >\n <p className=\"ods-http-panel__desc\">\n Extract fields from the response with dot paths — available downstream as{\" \"}\n <code>{\"{{extracted.keyName}}\"}</code>.\n </p>\n <KeyValueEditor\n pairs={extractRows.map((r) => ({ key: r.key, value: r.value }))}\n onChange={(pairs) => {\n const rows = pairs.map((p) => ({ key: p.key, value: p.value, enabled: true }));\n setExtractRows(rows);\n const extract: Record<string, string> = {};\n for (const r of rows) if (r.key && r.value) extract[r.key] = r.value;\n emit({ extract: Object.keys(extract).length ? extract : undefined });\n }}\n keyPlaceholder=\"outputKey\"\n valuePlaceholder=\"data.user.id\"\n emptyLabel=\"No extractions yet — click Add to begin.\"\n addLabel=\"Add\"\n size=\"sm\"\n disabled={disabled}\n />\n </Disclosure>\n </Disclosure>\n\n {/* Test console */}\n {preview.phase !== \"idle\" && (\n <div className=\"ods-http-panel__console\">\n <div className=\"ods-http-panel__console-head\">\n <code\n className={cn(\n \"ods-http-panel__console-method\",\n `ods-http-panel__method--${method.toLowerCase()}`,\n )}\n >\n {cfg.apiType === \"graphql\" ? \"POST\" : method}\n </code>\n <code className=\"ods-http-panel__console-url\">\n {connectionId\n ? `${selectedConnection?.name ?? connectionId} · ${url || \"—\"}`\n : fullUrl || \"—\"}\n </code>\n {sectionCopyButton(fullUrl || url, \"url\", \"request URL\")}\n {preview.phase === \"success\" && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className={cn(copiedResult && \"ods-http-panel__copy-done\")}\n leftIcon={copiedResult ? <CheckmarkIcon size=\"sm\" /> : <CopyIcon size=\"sm\" />}\n onClick={copyResult}\n >\n {copiedResult ? \"Copied\" : \"Copy result\"}\n </Button>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n leftIcon={<RenewIcon size=\"sm\" />}\n onClick={() => {\n setPreview({ phase: \"idle\" });\n }}\n disabled={preview.phase === \"loading\"}\n >\n Clear\n </Button>\n </div>\n\n {preview.phase === \"loading\" && (\n <div className=\"ods-http-panel__console-loading\">\n <Spinner size=\"sm\" />\n <span>Sending request…</span>\n </div>\n )}\n\n {preview.phase === \"error\" && (\n <Banner variant=\"error\" appearance=\"subtle\" size=\"sm\">\n <strong>Request failed.</strong> {preview.message}\n </Banner>\n )}\n\n {preview.phase === \"success\" && (\n <div className=\"ods-http-panel__console-result\">\n <div className=\"ods-http-panel__console-status\">\n <Badge size=\"sm\" variant={statusTone(preview.response.status)}>\n {preview.response.status} {preview.response.statusText}\n </Badge>\n <span className=\"ods-http-panel__meta\">{preview.response.duration}ms</span>\n <span className=\"ods-http-panel__meta\">{formatBytes(preview.response.size)}</span>\n </div>\n <Accordion\n size=\"sm\"\n mode=\"multiple\"\n defaultValue={[\"res-body\"]}\n items={[\n {\n id: \"res-headers\",\n label: \"Response headers\",\n trailing: (\n <>\n {sectionCopyButton(\n Object.entries(preview.response.headers)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"\\n\"),\n \"res-headers\",\n \"response headers\",\n )}\n <Badge size=\"sm\" variant=\"neutral\">\n {Object.keys(preview.response.headers).length}\n </Badge>\n </>\n ),\n content: (\n <div className=\"ods-http-panel__res-headers\">\n {Object.entries(preview.response.headers).map(([k, v]) => (\n <div key={k} className=\"ods-http-panel__res-header\">\n <span className=\"ods-http-panel__res-header-key\">{k}</span>\n <span className=\"ods-http-panel__res-header-val\">{v}</span>\n </div>\n ))}\n </div>\n ),\n },\n {\n id: \"res-body\",\n label: \"Response body\",\n trailing: (\n <>\n {sectionCopyButton(\n typeof preview.response.body === \"object\"\n ? JSON.stringify(preview.response.body, null, 2)\n : String(preview.response.bodyRaw ?? preview.response.body ?? \"\"),\n \"res-body\",\n \"response body\",\n )}\n {!preview.response.ok && (\n <Badge size=\"sm\" variant=\"error\">\n Error\n </Badge>\n )}\n </>\n ),\n content:\n // Size guard: the tree view renders recursively (no\n // virtualization) — very large bodies fall back to text.\n preview.response.body !== null &&\n typeof preview.response.body === \"object\" &&\n preview.response.size <= 1_500_000 ? (\n <JsonViewer\n data={preview.response.body}\n mode=\"view\"\n maxHeight={320}\n copyable\n />\n ) : (\n <pre className=\"ods-http-panel__res-body\">\n {typeof preview.response.body === \"object\"\n ? JSON.stringify(preview.response.body, null, 2)\n : String(\n preview.response.bodyRaw ?? preview.response.body ?? \"(empty body)\",\n )}\n </pre>\n ),\n },\n ]}\n />\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\nimport { ChevronDownIcon } from \"@octaviaflow/icons\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useId,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Accordion — collapsible content sections.\n *\n * Used in ConfigPanel-style settings surfaces, FAQ blocks, runbook\n * docs, advanced-options sections. Two selection modes:\n * - `single` (default): only one item open at a time\n * - `multiple`: any combination of items can be open\n *\n * Controlled OR uncontrolled. Animated expand/collapse via\n * framer-motion (respects reduced-motion). Keyboard nav follows the\n * WAI-ARIA accordion pattern: ↑↓ moves between triggers, Home/End\n * jump to first/last, Enter/Space toggles.\n *\n * A11y: each item is `<div>` with a `<button aria-expanded>` header\n * and a `<div role=\"region\" aria-labelledby>` content panel.\n * ------------------------------------------------------------------------- */\n\nexport type AccordionMode = \"single\" | \"multiple\";\nexport type AccordionVariant = \"default\" | \"bordered\" | \"separated\";\n\nexport interface AccordionItem {\n /** Stable identifier. */\n id: string;\n /** Header label. */\n label: ReactNode;\n /** Optional secondary line below the label. */\n description?: ReactNode;\n /** Optional leading icon. */\n icon?: ReactNode;\n /** Optional trailing slot in the header (badge, count, action). */\n trailing?: ReactNode;\n /** Panel content. */\n content: ReactNode;\n /** Disable interaction for this item. */\n disabled?: boolean;\n}\n\nexport interface AccordionProps\n extends Omit<\n ComponentPropsWithoutRef<\"div\">,\n | \"onChange\"\n | \"defaultValue\"\n | \"children\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onAnimationStart\"\n > {\n /** Items to render. */\n items: AccordionItem[];\n /** Single vs multiple expansion. Default `\"single\"`. */\n mode?: AccordionMode;\n /** Controlled expanded item ids. */\n value?: string[];\n /** Uncontrolled initial expanded ids. */\n defaultValue?: string[];\n /** Fires when the expanded set changes. */\n onValueChange?: (value: string[]) => void;\n /**\n * Allow the last open item to be closed (single mode). Default\n * `true`. When `false`, one item is always open — useful for tabbed-\n * like surfaces.\n */\n collapsible?: boolean;\n /** Visual variant. Default `\"default\"`. */\n variant?: AccordionVariant;\n /** Visual size. Default `\"md\"`. */\n size?: \"sm\" | \"md\" | \"lg\";\n /** Disable the entire accordion. */\n disabled?: boolean;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Accordion = forwardRef<HTMLDivElement, AccordionProps>(\n function Accordion(\n {\n items,\n mode = \"single\",\n value: controlledValue,\n defaultValue,\n onValueChange,\n collapsible = true,\n variant = \"default\",\n size = \"md\",\n disabled = false,\n id: providedId,\n className,\n ...rest\n },\n ref,\n ) {\n const reactId = useId();\n const baseId = providedId ?? `ods-accordion-${reactId}`;\n const reducedMotion = useReducedMotion();\n\n const [internalValue, setInternalValue] = useState<string[]>(\n defaultValue ?? [],\n );\n const isControlled = controlledValue !== undefined;\n const value = isControlled ? controlledValue : internalValue;\n const valueSet = new Set(value);\n\n const setValue = useCallback(\n (next: string[]) => {\n if (!isControlled) setInternalValue(next);\n onValueChange?.(next);\n },\n [isControlled, onValueChange],\n );\n\n const toggleItem = useCallback(\n (id: string) => {\n const isOpen = valueSet.has(id);\n if (mode === \"multiple\") {\n const next = isOpen\n ? value.filter((v) => v !== id)\n : [...value, id];\n setValue(next);\n return;\n }\n // single\n if (isOpen) {\n // Only close if collapsible — otherwise no-op.\n if (collapsible) setValue([]);\n return;\n }\n setValue([id]);\n },\n [collapsible, mode, setValue, value, valueSet],\n );\n\n const handleKeyDown = (\n e: KeyboardEvent<HTMLButtonElement>,\n index: number,\n ) => {\n const enabledIdx = items\n .map((it, i) => (it.disabled ? -1 : i))\n .filter((i) => i !== -1);\n const curr = enabledIdx.indexOf(index);\n const focusIdx = (i: number) => {\n const target = enabledIdx[i];\n if (target === undefined) return;\n const btn = document.getElementById(\n `${baseId}-trigger-${items[target]!.id}`,\n );\n (btn as HTMLButtonElement | null)?.focus();\n };\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n focusIdx((curr + 1) % enabledIdx.length);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n focusIdx((curr - 1 + enabledIdx.length) % enabledIdx.length);\n } else if (e.key === \"Home\") {\n e.preventDefault();\n focusIdx(0);\n } else if (e.key === \"End\") {\n e.preventDefault();\n focusIdx(enabledIdx.length - 1);\n }\n };\n\n return (\n <div\n {...rest}\n ref={ref}\n id={baseId}\n className={cn(\n \"ods-accordion\",\n `ods-accordion--${variant}`,\n `ods-accordion--${size}`,\n disabled && \"ods-accordion--disabled\",\n className,\n )}\n >\n {items.map((item, i) => {\n const isOpen = valueSet.has(item.id);\n const itemDisabled = item.disabled || disabled;\n const triggerId = `${baseId}-trigger-${item.id}`;\n const panelId = `${baseId}-panel-${item.id}`;\n return (\n <div\n key={item.id}\n className={cn(\n \"ods-accordion__item\",\n isOpen && \"ods-accordion__item--open\",\n itemDisabled && \"ods-accordion__item--disabled\",\n )}\n >\n <button\n id={triggerId}\n type=\"button\"\n className=\"ods-accordion__trigger\"\n aria-expanded={isOpen}\n aria-controls={panelId}\n disabled={itemDisabled}\n onClick={() => toggleItem(item.id)}\n onKeyDown={(e) => handleKeyDown(e, i)}\n >\n {item.icon && (\n <span\n className=\"ods-accordion__icon\"\n aria-hidden=\"true\"\n >\n {item.icon}\n </span>\n )}\n <span className=\"ods-accordion__label-wrap\">\n <span className=\"ods-accordion__label\">{item.label}</span>\n {item.description && (\n <span className=\"ods-accordion__description\">\n {item.description}\n </span>\n )}\n </span>\n {item.trailing && (\n <span\n className=\"ods-accordion__trailing\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.trailing}\n </span>\n )}\n <span\n className={cn(\n \"ods-accordion__chevron\",\n isOpen && \"ods-accordion__chevron--open\",\n )}\n aria-hidden=\"true\"\n >\n <ChevronDownIcon size=\"sm\" aria-hidden />\n </span>\n </button>\n\n <AnimatePresence initial={false}>\n {isOpen && (\n <motion.div\n role=\"region\"\n id={panelId}\n aria-labelledby={triggerId}\n className=\"ods-accordion__panel\"\n initial={\n reducedMotion\n ? false\n : { height: 0, opacity: 0 }\n }\n animate={\n reducedMotion\n ? undefined\n : { height: \"auto\", opacity: 1 }\n }\n exit={\n reducedMotion\n ? undefined\n : { height: 0, opacity: 0 }\n }\n transition={\n reducedMotion\n ? { duration: 0 }\n : { duration: 0.18 }\n }\n style={{ overflow: \"hidden\" }}\n >\n <div className=\"ods-accordion__content\">\n {item.content}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n })}\n </div>\n );\n },\n);\n\nAccordion.displayName = \"Accordion\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n type ElementType,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Slot } from \"../../utils/Slot\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type BadgeVariant =\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"info\"\n | \"neutral\"\n | \"accent\";\n\nexport type BadgeSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface BadgeProps\n extends Omit<ComponentPropsWithoutRef<\"span\">, \"color\" | \"onClick\"> {\n variant?: BadgeVariant;\n size?: BadgeSize;\n\n /** Render a colored dot before the text. Mutually exclusive with `icon`. */\n dot?: boolean;\n /** Custom icon node rendered before the text. If both `icon` and `dot`\n * are passed, `icon` wins. */\n icon?: ReactNode;\n\n /** Render a `×` button to remove the badge. */\n closable?: boolean;\n /** @deprecated Use `closable`. Kept as an alias for back-compat. */\n closeable?: boolean;\n /** Fires when the user clicks (or activates via keyboard) the close\n * button. Receives the MouseEvent so callers can `stopPropagation` /\n * `preventDefault` as needed. */\n onClose?: (event: MouseEvent<HTMLButtonElement>) => void;\n /** Accessible label for the close button. Defaults to \"Remove\". Override\n * for localization or contextual reads (\"Remove tag 'cdc'\"). */\n closeLabel?: string;\n\n /** Thin outline + transparent background instead of the filled chip. */\n outlined?: boolean;\n\n /** Truncate long text with an ellipsis and surface the full content as a\n * `title` tooltip. `true` uses the design default (200 px); a number sets\n * an explicit max-width in px. */\n truncate?: boolean | number;\n\n /** Numeric badge convenience. Renders the value (or \"99+\" if > 99).\n * Ignored when `children` is also set. */\n count?: number;\n\n /** Click handler for the entire badge. Sets `role=\"button\"` and wires\n * Enter / Space keyboard activation. */\n onClick?: (event: MouseEvent<HTMLSpanElement>) => void;\n\n /** Render Badge's styling onto a custom child element (Radix-style Slot).\n * Useful for letting Badge own the chrome while a router link / tooltip\n * trigger / etc. owns the actual element semantics.\n *\n * Example:\n * <Badge asChild variant=\"accent\">\n * <NextLink href=\"/pricing\">Beta</NextLink>\n * </Badge>\n *\n * When `asChild` is true, Badge does NOT render its internal `dot`,\n * `icon`, or close-button slots — the consumer fully owns the content.\n * For chips with built-in slots, use the regular form without asChild. */\n asChild?: boolean;\n\n children?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers\n * ------------------------------------------------------------------------- */\n\nfunction formatCount(value: number): string {\n if (!Number.isFinite(value)) return \"\";\n if (value < 0) return \"0\";\n if (value > 99) return \"99+\";\n return String(Math.floor(value));\n}\n\n/** Inline close glyph — kept self-contained so Badge has no runtime dep on\n * `@octaviaflow/icons` (Badge is imported by very low-level surfaces that\n * shouldn't pull the icon package). */\nfunction CloseGlyph() {\n return (\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 10 10\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M2 2 L8 8 M8 2 L2 8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n {\n variant = \"neutral\",\n size = \"md\",\n dot = false,\n icon,\n closable,\n closeable, // deprecated alias\n onClose,\n closeLabel = \"Remove\",\n outlined = false,\n truncate = false,\n count,\n onClick,\n asChild = false,\n className,\n children,\n style,\n ...rest\n },\n ref,\n) {\n // Back-compat: prefer `closable` when set; fall back to legacy `closeable`.\n const isClosable = closable ?? closeable ?? false;\n const isClickable = Boolean(onClick);\n\n // `count` is short-hand for numeric content. Real `children` always wins\n // — that's the spec for filter chips that happen to also carry a count.\n const displayChildren =\n children ?? (count !== undefined ? formatCount(count) : undefined);\n\n // Truncation: turn the bool/number into a concrete style on the text span.\n // We attach `title` on the root for the hover-tooltip when content is a\n // plain string (so AT and mouse users both get the full label).\n const maxWidth =\n truncate === true ? \"var(--ods-badge-max-width, 200px)\" : typeof truncate === \"number\" ? `${truncate}px` : undefined;\n const truncateTitle =\n truncate && typeof displayChildren === \"string\" ? displayChildren : undefined;\n\n const handleKeyDown = (e: KeyboardEvent<HTMLSpanElement>) => {\n if (!isClickable) return;\n if ((e.key === \"Enter\" || e.key === \" \") && !e.repeat) {\n e.preventDefault();\n onClick?.(e as unknown as MouseEvent<HTMLSpanElement>);\n }\n };\n\n const handleCloseClick = (e: MouseEvent<HTMLButtonElement>) => {\n // Stop propagation so a Badge nested inside a clickable surface (card,\n // row, tag-input) doesn't fire the parent's onClick when the user is\n // removing the chip. Callers can still observe the event via onClose.\n e.stopPropagation();\n onClose?.(e);\n };\n\n const rootClassName = cn(\n \"ods-badge\",\n `ods-badge--${variant}`,\n `ods-badge--${size}`,\n outlined && \"ods-badge--outlined\",\n isClickable && \"ods-badge--interactive\",\n truncate && \"ods-badge--truncate\",\n className,\n );\n\n // asChild mode: clone the consumer's element and apply Badge's styling /\n // accessibility surface onto it. Internal slots (dot, icon, close) are\n // not rendered — the consumer's element fully owns the content.\n if (asChild) {\n return (\n <Slot\n {...(rest as ComponentPropsWithoutRef<ElementType>)}\n ref={ref as Ref<HTMLElement>}\n className={rootClassName}\n style={style}\n role={isClickable ? \"button\" : rest.role}\n tabIndex={isClickable ? (rest.tabIndex ?? 0) : rest.tabIndex}\n onClick={onClick as ((e: MouseEvent<HTMLElement>) => void) | undefined}\n onKeyDown={isClickable ? handleKeyDown : rest.onKeyDown}\n title={truncateTitle ?? rest.title}\n >\n {children as React.ReactElement}\n </Slot>\n );\n }\n\n return (\n <span\n {...rest}\n ref={ref}\n className={rootClassName}\n style={style}\n // The whole badge becomes a button when onClick is set. Otherwise we\n // leave the role unset so it stays a plain inline element.\n role={isClickable ? \"button\" : rest.role}\n tabIndex={isClickable ? (rest.tabIndex ?? 0) : rest.tabIndex}\n onClick={onClick as MouseEvent<HTMLSpanElement> extends MouseEvent<HTMLSpanElement> ? typeof onClick : never}\n onKeyDown={isClickable ? handleKeyDown : rest.onKeyDown}\n title={truncateTitle ?? rest.title}\n >\n {icon ? (\n <span className=\"ods-badge__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n ) : dot ? (\n <span className=\"ods-badge__dot\" aria-hidden=\"true\" />\n ) : null}\n <span\n className=\"ods-badge__text\"\n style={maxWidth ? { maxWidth } : undefined}\n >\n {displayChildren}\n </span>\n {isClosable && (\n <button\n type=\"button\"\n className=\"ods-badge__close\"\n onClick={handleCloseClick}\n aria-label={closeLabel}\n >\n <CloseGlyph />\n </button>\n )}\n </span>\n );\n});\n\nBadge.displayName = \"Badge\";\n","\"use client\";\nimport {\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n type CSSProperties,\n type HTMLAttributes,\n type ReactElement,\n type Ref,\n} from \"react\";\nimport { composeRefs } from \"./composeRefs\";\n\n/* ---------------------------------------------------------------------------\n * Slot — the `asChild` primitive\n *\n * Takes exactly one React element child and clones it, merging the Slot's\n * own props onto the child:\n * - `className` concatenates (slot's classes follow child's)\n * - `style` merges (child's keys win on overlap)\n * - Event handlers chain (slot's handler runs first; if it calls\n * `event.preventDefault()` the child's handler is short-circuited —\n * matching React's own synthetic-event default-handling convention)\n * - Refs compose so both the forwarded ref and the child's own ref point\n * at the rendered DOM node.\n *\n * This is what powers `asChild` across our primitives: it lets consumers\n * swap the rendered element (e.g., to a router Link) without losing the\n * component's styling, accessibility, or behavioural contract.\n * ------------------------------------------------------------------------- */\n\ntype AnyProps = Record<string, unknown>;\n\ninterface SlotProps extends HTMLAttributes<HTMLElement> {\n children?: React.ReactNode;\n}\n\nexport const Slot = forwardRef<HTMLElement, SlotProps>(function Slot(\n { children, ...slotProps },\n forwardedRef,\n) {\n if (!isValidElement(children)) {\n // Slot requires exactly one React element child. Returning null is\n // safer than throwing — callers that conditionally use `asChild` are\n // common, and we don't want stories / SSR to crash on an empty pass.\n return null;\n }\n const child = Children.only(children) as ReactElement<AnyProps>;\n const childProps = child.props ?? {};\n const childRef = (child as unknown as { ref?: Ref<HTMLElement> }).ref;\n\n return cloneElement(child, {\n ...mergeProps(slotProps as AnyProps, childProps),\n ref: forwardedRef ? composeRefs(forwardedRef, childRef) : childRef,\n });\n});\n\nfunction mergeProps(slotProps: AnyProps, childProps: AnyProps): AnyProps {\n // Start with the slot's props, then layer the child's on top. We then\n // walk back over the overlapping keys to apply per-key merge rules.\n const merged: AnyProps = { ...slotProps, ...childProps };\n\n for (const key of Object.keys(slotProps)) {\n const slotValue = slotProps[key];\n const childValue = childProps[key];\n\n // Event handlers — chain. Slot's handler runs first; if it invokes\n // event.preventDefault() the child's is skipped, matching the React\n // norm. Both being functions is the trigger.\n if (\n /^on[A-Z]/.test(key) &&\n typeof slotValue === \"function\" &&\n typeof childValue === \"function\"\n ) {\n merged[key] = (...args: unknown[]) => {\n (slotValue as (...a: unknown[]) => void)(...args);\n const event = args[0] as { defaultPrevented?: boolean } | undefined;\n if (event?.defaultPrevented) return;\n (childValue as (...a: unknown[]) => void)(...args);\n };\n continue;\n }\n\n // className — concatenate (slot's classes come first so child's can\n // visually override on direct conflict, which matches authoring intent).\n if (key === \"className\") {\n merged.className = [slotValue, childValue].filter(Boolean).join(\" \");\n continue;\n }\n\n // style — merge; child's keys win on overlap so consumers' inline\n // styles can override our defaults.\n if (key === \"style\") {\n merged.style = {\n ...(slotValue as CSSProperties | undefined),\n ...(childValue as CSSProperties | undefined),\n };\n continue;\n }\n }\n\n return merged;\n}\n","import type { MutableRefObject, Ref, RefCallback } from \"react\";\n\n/** Compose any number of refs (callback or object) into a single ref-callback.\n * Each underlying ref receives the node when React assigns it. Useful for the\n * `asChild` pattern where both the forwarded ref and the child's own ref need\n * to point at the same DOM node. */\nexport function composeRefs<T>(...refs: Array<Ref<T> | undefined | null>): RefCallback<T> {\n return (node: T) => {\n for (const ref of refs) {\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref != null) {\n (ref as MutableRefObject<T | null>).current = node;\n }\n }\n };\n}\n","\"use client\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport {\n type ComponentPropsWithoutRef,\n type ElementType,\n forwardRef,\n type ReactElement,\n type ReactNode,\n type Ref,\n useEffect,\n useRef,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Slot } from \"../../utils/Slot\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type BannerVariant = \"info\" | \"success\" | \"warning\" | \"error\" | \"promo\" | \"neutral\";\nexport type BannerSize = \"sm\" | \"md\" | \"lg\";\n\n/** Direction the banner slides in / out from. Default = `down` (enters\n * slightly above its final position, settles down + fades in). */\nexport type BannerAnimateFrom = \"top\" | \"bottom\" | \"left\" | \"right\" | \"none\";\nexport type BannerAppearance = \"filled\" | \"outlined\" | \"subtle\";\n\nexport interface BannerProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"color\" | \"title\"> {\n /** Visual / semantic variant. `error` defaults to `role=\"alert\"`; the rest\n * default to `role=\"status\"` (polite live region). */\n variant?: BannerVariant;\n /** Size variant. */\n size?: BannerSize;\n /** Appearance treatment. `filled` (default) uses the variant's bg/border;\n * `outlined` keeps the border but drops the fill; `subtle` mutes both. */\n appearance?: BannerAppearance;\n\n /** Leading icon. If omitted, Banner renders a sensible default per\n * variant (info/success/warning/error/promo). Pass `null` explicitly to\n * suppress the default. */\n icon?: ReactNode | null;\n title?: ReactNode;\n description?: ReactNode;\n\n /** Trailing action slot (typically a Button). */\n action?: ReactNode;\n /** Renders a dismiss `×` button on the trailing edge. */\n dismissible?: boolean;\n /** Fires when the dismiss button is clicked. */\n onDismiss?: () => void;\n /** Accessible label for the dismiss button. Defaults to \"Dismiss\". */\n dismissLabel?: string;\n\n /** Override the inferred role. Pass explicitly for non-default\n * announcements (\"alert\", \"alertdialog\", \"region\", etc.). */\n role?: ComponentPropsWithoutRef<\"div\">[\"role\"];\n\n /** Auto-focus the banner when it first mounts. Useful for error banners\n * that should grab focus on appearance so AT users notice them. */\n autoFocus?: boolean;\n\n /** Controls whether the banner is mounted. Pair with `useBanner()` for\n * declarative show/hide state, or wire to your own state. When omitted,\n * the banner is always mounted (the regular, animation-free shape). */\n open?: boolean;\n /** Direction the enter/exit animation slides from. Defaults to `top`.\n * `none` disables the slide entirely (still fades). */\n animateFrom?: BannerAnimateFrom;\n /** Disable all enter/exit motion. Use when the banner is part of a\n * larger animation managed externally. */\n disableAnimation?: boolean;\n\n /** Render Banner's styling onto a custom child element (Radix-style Slot).\n *\n * Example — a clickable banner-as-link:\n * <Banner asChild variant=\"promo\">\n * <a href=\"/changelog\">New release! See what's new →</a>\n * </Banner>\n *\n * When `asChild` is true, Banner does NOT render its internal icon /\n * title / description / action / dismiss slots. The consumer's element\n * fully owns the content. */\n asChild?: boolean;\n\n children?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Default per-variant icons — self-contained SVGs so Banner has no runtime\n * dependency on @octaviaflow/icons. They inherit color via `currentColor`\n * so the variant's icon color applies.\n * ------------------------------------------------------------------------- */\n\nfunction InfoIcon() {\n return (\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <circle cx=\"9\" cy=\"9\" r=\"7.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M9 8v4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"9\" cy=\"5.5\" r=\"0.9\" fill=\"currentColor\" />\n </svg>\n );\n}\nfunction SuccessIcon() {\n return (\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <circle cx=\"9\" cy=\"9\" r=\"7.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M5.5 9.2 8 11.5 12.5 6.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n}\nfunction WarningIcon() {\n return (\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M9 2 L16 15 H2 Z\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinejoin=\"round\" />\n <path d=\"M9 7v4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"9\" cy=\"13\" r=\"0.9\" fill=\"currentColor\" />\n </svg>\n );\n}\nfunction ErrorIcon() {\n return (\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <circle cx=\"9\" cy=\"9\" r=\"7.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M6.5 6.5 11.5 11.5 M11.5 6.5 6.5 11.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n );\n}\nfunction PromoIcon() {\n return (\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <path\n d=\"M9 1.5 L11 6.5 L16.5 7 L12.4 10.7 L13.7 16 L9 13 L4.3 16 L5.6 10.7 L1.5 7 L7 6.5 Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nconst DEFAULT_ICONS: Record<BannerVariant, () => ReactElement> = {\n info: InfoIcon,\n success: SuccessIcon,\n warning: WarningIcon,\n error: ErrorIcon,\n promo: PromoIcon,\n neutral: InfoIcon,\n};\n\nfunction DismissGlyph() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n <path\n d=\"M3.5 3.5 L10.5 10.5 M10.5 3.5 L3.5 10.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\n/* ---------------------------------------------------------------------------\n * Enter/exit motion offsets per direction. Subtle by design — banners\n * shouldn't fly across the viewport on appear; ~8 px is enough to read as\n * \"arrived\" without distracting from the content. Under reduced-motion we\n * zero out the transform and just cross-fade.\n * ------------------------------------------------------------------------- */\nconst MOTION_OFFSETS: Record<BannerAnimateFrom, { x: number; y: number }> = {\n top: { x: 0, y: -8 },\n bottom: { x: 0, y: 8 },\n left: { x: -8, y: 0 },\n right: { x: 8, y: 0 },\n none: { x: 0, y: 0 },\n};\n\nexport const Banner = forwardRef<HTMLDivElement, BannerProps>(function Banner(\n {\n variant = \"info\",\n size = \"md\",\n appearance = \"filled\",\n icon,\n title,\n description,\n action,\n dismissible = false,\n onDismiss,\n dismissLabel = \"Dismiss\",\n role,\n autoFocus = false,\n asChild = false,\n open,\n animateFrom = \"top\",\n disableAnimation = false,\n className,\n children,\n ...rest\n },\n ref,\n) {\n // Variant → default ARIA role. `error` is announced as an alert so AT\n // interrupts; everything else is a polite live status region.\n const resolvedRole = role ?? (variant === \"error\" ? \"alert\" : \"status\");\n\n // Resolve the icon: explicit `null` → suppress; undefined → variant default;\n // anything else → as passed.\n const DefaultIconComponent = DEFAULT_ICONS[variant];\n const resolvedIcon =\n icon === null ? null : icon === undefined ? <DefaultIconComponent /> : icon;\n\n // Hooks must run unconditionally (rules of hooks). Compose them up here\n // even though some render paths below don't use them.\n const reducedMotion = useReducedMotion();\n const internalRef = useRef<HTMLDivElement | null>(null);\n const setRef = (node: HTMLDivElement | null) => {\n internalRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as { current: HTMLDivElement | null }).current = node;\n };\n\n useEffect(() => {\n if (autoFocus && internalRef.current) {\n // Banner is not normally focusable; ensure tabIndex=-1 so focus() is\n // programmatically valid without exposing the banner to Tab traversal.\n internalRef.current.focus({ preventScroll: false });\n }\n }, [autoFocus]);\n\n const rootClassName = cn(\n \"ods-banner\",\n `ods-banner--${variant}`,\n `ods-banner--${size}`,\n `ods-banner--${appearance}`,\n className,\n );\n\n // asChild mode — clone the consumer's element and project Banner's chrome\n // onto it. Internal slots aren't rendered.\n if (asChild) {\n return (\n <Slot\n {...(rest as ComponentPropsWithoutRef<ElementType>)}\n ref={ref as Ref<HTMLElement>}\n className={rootClassName}\n role={resolvedRole}\n >\n {children as ReactElement}\n </Slot>\n );\n }\n\n // Inner slots shared by every render path (plain / animated / static\n // closed). Pulled out so the animation wrapper doesn't duplicate JSX.\n const innerSlots = (\n <>\n {resolvedIcon && (\n <span className=\"ods-banner__icon\" aria-hidden=\"true\">\n {resolvedIcon}\n </span>\n )}\n <div className=\"ods-banner__body\">\n {title && <div className=\"ods-banner__title\">{title}</div>}\n {description && <div className=\"ods-banner__description\">{description}</div>}\n {children}\n </div>\n {action && <div className=\"ods-banner__action\">{action}</div>}\n {dismissible && (\n <button\n type=\"button\"\n className=\"ods-banner__dismiss\"\n onClick={onDismiss}\n aria-label={dismissLabel}\n >\n <DismissGlyph />\n </button>\n )}\n </>\n );\n\n // Uncontrolled mode (no `open` prop): always rendered, no animation.\n // Keeps the legacy / static shape working for consumers that don't need\n // mount/unmount behaviour.\n if (open === undefined) {\n return (\n <div\n {...rest}\n ref={setRef}\n className={rootClassName}\n role={resolvedRole}\n tabIndex={autoFocus ? -1 : rest.tabIndex}\n >\n {innerSlots}\n </div>\n );\n }\n\n // Controlled mode without animation — plain mount/unmount.\n if (disableAnimation) {\n if (!open) return null;\n return (\n <div\n {...rest}\n ref={setRef}\n className={rootClassName}\n role={resolvedRole}\n tabIndex={autoFocus ? -1 : rest.tabIndex}\n >\n {innerSlots}\n </div>\n );\n }\n\n // Controlled mode with animation: AnimatePresence drives enter/exit.\n // Under prefers-reduced-motion we zero out the transform and rely on the\n // opacity cross-fade only — which is well under perceptual thresholds.\n const offset = reducedMotion\n ? { x: 0, y: 0 }\n : MOTION_OFFSETS[animateFrom];\n\n return (\n <AnimatePresence initial={false}>\n {open && (\n <motion.div\n {...(rest as Omit<typeof rest, \"onDrag\" | \"onDragStart\" | \"onDragEnd\" | \"onAnimationStart\" | \"onAnimationEnd\">)}\n ref={setRef}\n className={rootClassName}\n role={resolvedRole}\n tabIndex={autoFocus ? -1 : rest.tabIndex}\n initial={{ opacity: 0, x: offset.x, y: offset.y }}\n animate={{ opacity: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, x: offset.x, y: offset.y }}\n transition={{ duration: 0.18, ease: [0.16, 1, 0.3, 1] }}\n >\n {innerSlots}\n </motion.div>\n )}\n </AnimatePresence>\n );\n});\n\nBanner.displayName = \"Banner\";\n","\"use client\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport {\n type ButtonHTMLAttributes,\n type CSSProperties,\n forwardRef,\n type ReactElement,\n type ReactNode,\n type Ref,\n useImperativeHandle,\n useRef,\n} from \"react\";\nimport { useButton } from \"react-aria\";\nimport { resolveAccessibleName, hasRenderableText } from \"../../utils/a11y\";\nimport { cn } from \"../../utils/cn\";\nimport { Slot } from \"../../utils/Slot\";\n\nexport interface ButtonProps\n extends Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"onDrag\" | \"onDragStart\" | \"onDragEnd\" | \"onAnimationStart\"\n > {\n variant?: \"primary\" | \"secondary\" | \"ghost\" | \"danger\" | \"icon\";\n size?: \"sm\" | \"md\" | \"lg\";\n loading?: boolean;\n /** Override the rendered label while loading. Useful for action verbs that\n * change form mid-request — e.g. `\"Sign in\"` → `\"Signing in…\"`. */\n loadingText?: ReactNode;\n /** Accessible label for the spinner (announced by AT during loading).\n * Defaults to `\"Loading\"`. Customize for localization or context. */\n loadingLabel?: string;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n fullWidth?: boolean;\n /** Toggle-button state. When defined, the button advertises\n * `aria-pressed` and adds `--pressed` styling. */\n pressed?: boolean;\n children?: ReactNode;\n /**\n * Override the cursor shown on hover. When omitted, the cursor auto-resolves:\n * - `not-allowed` when disabled (CSS handles this — see Button.module.scss)\n * - `progress` when loading (request in flight)\n * - `pointer` when the button has an action (onClick, type=\"submit\",\n * or type=\"reset\"). Anchors (href) get pointer too.\n * - `default` otherwise (decorative / placeholder buttons)\n * Pass an explicit value (e.g. `\"text\"`, `\"grab\"`) to override the\n * auto-resolve for the specific story / use case.\n */\n cursor?: CSSProperties[\"cursor\"];\n /** Render Button's styling onto a custom child element (Radix-style Slot).\n *\n * <Button asChild variant=\"primary\">\n * <NextLink href=\"/checkout\">Continue</NextLink>\n * </Button>\n *\n * When `asChild` is true, Button does NOT render its internal icon /\n * label / spinner slots — the consumer's element fully owns content. Use\n * the regular form (without `asChild`) when you want the built-in\n * slots / loading spinner / size-scaled icons. */\n asChild?: boolean;\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n variant = \"primary\",\n size = \"md\",\n loading = false,\n loadingText,\n loadingLabel = \"Loading\",\n disabled = false,\n leftIcon,\n rightIcon,\n fullWidth = false,\n pressed,\n asChild = false,\n className,\n children,\n type,\n cursor,\n style,\n ...props\n },\n forwardedRef,\n) {\n const ref = useRef<HTMLButtonElement>(null);\n useImperativeHandle(forwardedRef, () => ref.current as HTMLButtonElement);\n const isDisabled = disabled || loading;\n // Respect users who've asked for reduced motion (OS-level a11y setting).\n // When true we skip the whileTap scale animation entirely — Framer's own\n // hook reads `prefers-reduced-motion: reduce` and stays reactive.\n const prefersReducedMotion = useReducedMotion();\n\n // Cursor resolution (centralised in JS so inline-style specificity wins\n // over any CSS cursor rule). Order of precedence:\n // 1. Caller's explicit `cursor` prop.\n // 2. `not-allowed` when disabled (and not also loading — see below).\n // 3. `progress` when loading (button is intentionally non-interactive\n // but the user should see we're working on it).\n // 4. `pointer` when the button has an action.\n // 5. `default` for decorative buttons.\n // Disabled takes precedence over loading when BOTH are set: explicit\n // disabled is a stronger intent than \"currently busy\".\n // Button always renders a native <button>; anchor semantics live on\n // LinkButton. No href branch needed here.\n const hasAction = Boolean(props.onClick) || type === \"submit\" || type === \"reset\";\n const resolvedCursor: string =\n cursor ?? (disabled ? \"not-allowed\" : loading ? \"progress\" : hasAction ? \"pointer\" : \"default\");\n // Forms rely on `type=\"submit\"` to trigger submission. React Aria's useButton\n // defaults type to \"button\" when omitted, so we always pass the caller's type\n // through (defaulting to \"button\" only when truly unspecified).\n const resolvedType: \"button\" | \"submit\" | \"reset\" = type ?? \"button\";\n\n // Buttons get their accessible name from children. Icon-only buttons\n // (variant=\"icon\" or empty children + iconLeft/Right) MUST provide\n // aria-label or aria-labelledby — we resolve it here so react-aria's\n // useButton receives a guaranteed string-or-id, and dev-mode console.error\n // surfaces the missing-name case.\n //\n // `hasVisibleText` counts any renderable TEXT in children — including text\n // inside arrays/fragments/elements (e.g. `{cond && \"Connect\"}` which React\n // passes as an array, or `<span>Save</span>`). SVG/icon-only subtrees carry\n // no readable text, so genuinely icon-only buttons still require an explicit\n // aria-label. (A glyph string like \"×\" counts — announced verbatim.) This\n // must NOT be a bare `typeof children === \"string\"` check: conditional or\n // interpolated text children are arrays, and missing them here forces a\n // bogus `aria-label=\"Unlabeled Button\"` that overrides the real label.\n const hasVisibleText = hasRenderableText(children);\n // In `asChild` mode the consumer's element owns its own accessible name\n // (e.g., the anchor's text content). Suppress Button's own a11y check\n // to avoid false-positive dev warnings.\n const needsAriaName = !hasVisibleText && !asChild;\n const ariaNameProps = needsAriaName\n ? resolveAccessibleName({\n ariaLabel: (props as any)[\"aria-label\"],\n ariaLabelledby: (props as any)[\"aria-labelledby\"],\n componentName: \"Button\",\n })\n : undefined;\n\n const { buttonProps } = useButton(\n {\n isDisabled,\n onPress: props.onClick as any,\n type: resolvedType,\n ...(ariaNameProps ?? {}),\n },\n ref,\n );\n\n // Strip Framer-conflicting props from React Aria output\n const { onDrag, onDragStart, onDragEnd, onAnimationStart, ...safeButtonProps } =\n buttonProps as any;\n\n // Native HTML button attributes the caller passed (form, name, value,\n // aria-*, data-*, etc.) must reach the DOM. We strip the ones React Aria\n // already manages from buttonProps to avoid double-binding event handlers.\n const {\n onClick: _onClick,\n onKeyDown: _onKeyDown,\n onKeyUp: _onKeyUp,\n onMouseDown: _onMouseDown,\n onPointerDown: _onPointerDown,\n onPointerUp: _onPointerUp,\n onFocus: _onFocus,\n onBlur: _onBlur,\n ...passthroughProps\n } = props as Record<string, unknown>;\n\n const rootClassName = cn(\n \"ods-btn\",\n `ods-btn--${variant}`,\n `ods-btn--${size}`,\n loading && \"ods-btn--loading\",\n fullWidth && \"ods-btn--full\",\n pressed && \"ods-btn--pressed\",\n className,\n );\n\n // asChild mode — project Button's chrome onto the consumer's element.\n // Internal slots (icons, spinner, label) are NOT rendered — consumer\n // owns the content. react-aria event wiring is also skipped because\n // the consumer's element handles its own activation semantics.\n if (asChild) {\n return (\n <Slot\n {...(passthroughProps as Record<string, unknown>)}\n ref={forwardedRef as unknown as Ref<HTMLElement>}\n className={rootClassName}\n style={{ cursor: resolvedCursor, ...(style as CSSProperties) }}\n aria-pressed={pressed}\n aria-disabled={isDisabled || undefined}\n >\n {children as ReactElement}\n </Slot>\n );\n }\n\n // The visible label — `loadingText` overrides `children` while loading\n // so the in-progress verb form (\"Signing in…\") replaces the idle one.\n const visibleLabel = loading && loadingText !== undefined ? loadingText : children;\n\n return (\n <motion.button\n {...(passthroughProps as any)}\n {...safeButtonProps}\n type={resolvedType}\n ref={ref}\n className={rootClassName}\n // Disabled state CSS rule (cursor: not-allowed) outranks this inline\n // value — see Button.module.scss. So `style.cursor` only applies to\n // idle/loading/active states, exactly what we want.\n style={{ cursor: resolvedCursor, ...(style as any) }}\n data-loading={loading || undefined}\n aria-busy={loading || undefined}\n aria-pressed={pressed}\n whileTap={isDisabled || prefersReducedMotion ? undefined : { scale: 0.97 }}\n transition={{ duration: 0.1 }}\n >\n {/* Content layer. When loading, the leftIcon slot is replaced by an\n inline spinner — both spinner AND label stay visible so the user\n sees the in-progress text (e.g. \"Signing in…\") next to the\n activity indicator. */}\n <span className=\"ods-btn__content\">\n {loading ? (\n <span\n className=\"ods-btn__icon ods-btn__icon--left ods-btn__icon--spinner\"\n role=\"status\"\n aria-label={loadingLabel}\n >\n {/* viewBox is 1em-scaled by CSS (.ods-btn__icon svg → 1em) so\n the spinner tracks the per-size icon scale (12 / 14 / 16 px)\n without needing per-size width attributes. */}\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeDasharray=\"32\"\n strokeDashoffset=\"12\"\n />\n </svg>\n </span>\n ) : (\n leftIcon && <span className=\"ods-btn__icon ods-btn__icon--left\">{leftIcon}</span>\n )}\n {visibleLabel != null && visibleLabel !== false && (\n <span className=\"ods-btn__label\">{visibleLabel}</span>\n )}\n {rightIcon && !loading && (\n <span className=\"ods-btn__icon ods-btn__icon--right\">{rightIcon}</span>\n )}\n </span>\n </motion.button>\n );\n});\n\nButton.displayName = \"Button\";\n","/**\n * a11y — shared helpers for resolving an accessible name from the union of\n * props every form/interactive component accepts.\n *\n * Why this exists:\n * react-aria's hooks (useCheckbox, useSwitch, useRadio, useTextField,\n * useButton, etc.) emit a runtime warning to the browser console when\n * none of the following is present on the underlying element:\n * - aria-label\n * - aria-labelledby\n * - a visible <label> with htmlFor pointing to the element id\n *\n * Many of our components accept `label` as `string | ReactNode`. When\n * `label` is a ReactNode (icon + text, custom JSX), react-aria can't see\n * a text label and the warning fires. This helper centralizes the\n * derivation: it returns a single { 'aria-label' or 'aria-labelledby' }\n * shape that react-aria will accept, and — in development only — it\n * surfaces a focused console.error pointing the developer at the prop\n * they're missing instead of the generic react-aria warning.\n *\n * Usage:\n * const ariaProps = resolveAccessibleName({\n * label,\n * ariaLabel: props['aria-label'],\n * ariaLabelledby: props['aria-labelledby'],\n * componentName: 'Checkbox',\n * });\n * // → { 'aria-label': string } | { 'aria-labelledby': string } | { 'aria-label': string }\n *\n * useCheckbox({ ...otherProps, ...ariaProps }, state, ref);\n */\n\nimport { isValidElement, type ReactNode } from \"react\";\n\n/**\n * True when a ReactNode renders any non-empty, human-readable text.\n *\n * Used by controls whose accessible name comes from their CHILDREN (e.g.\n * Button). Recurses through arrays, fragments, and element children so that\n * conditionally-rendered or wrapped text is detected — e.g.\n * `{cond && \"Save\"}`, `[\"Connect with \", name]`, or `<span>Save</span>`.\n *\n * Returns false for icon/SVG-only subtrees (no string content), so genuinely\n * icon-only controls still trip the missing-accessible-name check. Numbers\n * count (they render as announced text, including 0); booleans / null /\n * undefined do not render and so don't count.\n */\nexport function hasRenderableText(node: ReactNode): boolean {\n if (node === null || node === undefined || typeof node === \"boolean\") return false;\n if (typeof node === \"string\") return node.trim().length > 0;\n if (typeof node === \"number\") return true;\n if (Array.isArray(node)) return node.some(hasRenderableText);\n if (isValidElement(node)) {\n return hasRenderableText((node.props as { children?: ReactNode }).children);\n }\n return false;\n}\n\n/**\n * Extract the concatenated visible text from a ReactNode — used to derive an\n * accessible name when a control accepts a rich `label` (icon + text, custom\n * JSX). Mirrors `hasRenderableText`'s traversal: strings/numbers contribute,\n * arrays/fragments/elements recurse into their children, and\n * booleans/null/undefined contribute nothing. Returns '' when there is no text.\n */\nexport function getRenderableText(node: ReactNode): string {\n if (node === null || node === undefined || typeof node === \"boolean\") return \"\";\n if (typeof node === \"string\") return node;\n if (typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(getRenderableText).join(\"\");\n if (isValidElement(node)) {\n return getRenderableText((node.props as { children?: ReactNode }).children);\n }\n return \"\";\n}\n\nexport interface ResolveAccessibleNameInput {\n /** The visible label, if any. Strings are auto-used as aria-label. */\n label?: ReactNode;\n /** Caller-provided aria-label override. Highest priority when present. */\n ariaLabel?: string;\n /** Caller-provided aria-labelledby. Wins over label-derived values. */\n ariaLabelledby?: string;\n /**\n * Component name used in dev-mode error messages. Helps the developer\n * locate which usage needs a label.\n */\n componentName: string;\n /**\n * Optional secondary fallbacks the component knows about — e.g. a Radio\n * can fall back to its `value` so radios in a group are at least\n * distinguishable. The first non-empty string is used.\n */\n fallbacks?: Array<string | undefined>;\n}\n\nexport type ResolvedAccessibleName = { \"aria-label\": string } | { \"aria-labelledby\": string };\n\n/**\n * Resolve the accessible-name props that should be spread onto the\n * underlying element. Guarantees at least one of aria-label / aria-labelledby\n * is present so react-aria won't warn at runtime.\n *\n * Priority order:\n * 1. aria-labelledby (caller-provided)\n * 2. aria-label (caller-provided)\n * 3. label (when string)\n * 4. fallbacks (when string)\n * 5. component-name placeholder + dev-mode console.error\n */\nexport function resolveAccessibleName(input: ResolveAccessibleNameInput): ResolvedAccessibleName {\n if (input.ariaLabelledby) {\n return { \"aria-labelledby\": input.ariaLabelledby };\n }\n if (input.ariaLabel) {\n return { \"aria-label\": input.ariaLabel };\n }\n if (typeof input.label === \"string\" && input.label.trim().length > 0) {\n return { \"aria-label\": input.label };\n }\n for (const candidate of input.fallbacks ?? []) {\n if (typeof candidate === \"string\" && candidate.trim().length > 0) {\n return { \"aria-label\": candidate };\n }\n }\n\n // Last resort — emit a placeholder so react-aria stays quiet in\n // production, but loudly point at the missing prop in development so the\n // developer fixes the real bug rather than ignoring a global warning.\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line no-console\n console.error(\n `[@octaviaflow/core ${input.componentName}] No accessible name. ` +\n `Pass a string \\`label\\`, or \\`aria-label\\`, or \\`aria-labelledby\\` ` +\n `so screen readers can announce this control.`,\n );\n }\n return { \"aria-label\": `Unlabeled ${input.componentName}` };\n}\n","\"use client\";\nimport {\n CheckmarkIcon,\n CopyIcon,\n MagicWandIcon,\n SearchIcon,\n TextWrapIcon,\n} from \"@octaviaflow/icons\";\nimport {\n forwardRef,\n type ReactNode,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport type CodeEditorLanguage = \"sql\" | \"json\" | \"javascript\" | \"typescript\" | \"yaml\" | \"plain\";\n\nexport interface CodeEditorProps {\n value: string;\n onChange?: (value: string) => void;\n language?: CodeEditorLanguage;\n /** Read-only mode. */\n readOnly?: boolean;\n /** Hide the gutter (line numbers). */\n showLineNumbers?: boolean;\n /** Highlight the active line. */\n highlightActiveLine?: boolean;\n /** Number of spaces a Tab inserts. */\n tabSize?: number;\n /** Minimum height in pixels. */\n minHeight?: number;\n /** Maximum height in pixels. */\n maxHeight?: number;\n placeholder?: string;\n ariaLabel?: string;\n /** Optional toolbar slot above the editor. */\n toolbar?: ReactNode;\n /** Status pill on the right side of the toolbar. */\n status?: ReactNode;\n className?: string;\n /** Show built-in Copy button. Default true. */\n showCopy?: boolean;\n /** Show built-in Format button (JSON only by default). */\n showFormat?: boolean;\n /** Word wrap (controlled). */\n wordWrap?: boolean;\n /** Show built-in word-wrap toggle. Default true (only when uncontrolled). */\n showWordWrapToggle?: boolean;\n /** Enable auto-pair brackets and quotes. Default true. */\n autoPair?: boolean;\n /** Show character/selection counter at bottom. Default true. */\n showCounter?: boolean;\n /** Enable Cmd+F search bar. Default true. */\n searchable?: boolean;\n\n /** Form integration — passes through to the underlying <textarea>. */\n name?: string;\n /** Form attribute (for buttons rendered outside their parent form). */\n form?: string;\n /** Mark as required for native form validation. */\n required?: boolean;\n /** Native id (replaces the auto-generated one if you need to pair a\n * <label htmlFor> with this editor). */\n id?: string;\n}\n\nconst COMMENT_PREFIX: Record<CodeEditorLanguage, string> = {\n sql: \"-- \",\n json: \"// \",\n javascript: \"// \",\n typescript: \"// \",\n yaml: \"# \",\n plain: \"// \",\n};\n\nconst OPEN_PAIRS: Record<string, string> = {\n \"{\": \"}\",\n \"[\": \"]\",\n \"(\": \")\",\n '\"': '\"',\n \"'\": \"'\",\n \"`\": \"`\",\n};\nconst CLOSE_PAIRS = new Set(Object.values(OPEN_PAIRS));\n\nfunction tryFormat(value: string, language: CodeEditorLanguage): string | null {\n if (language === \"json\") {\n try {\n return JSON.stringify(JSON.parse(value), null, 2);\n } catch {\n return null;\n }\n }\n return null;\n}\n\nexport const CodeEditor = forwardRef<HTMLTextAreaElement, CodeEditorProps>(\n function CodeEditor(\n {\n value,\n onChange,\n language = \"plain\",\n readOnly = false,\n showLineNumbers = true,\n highlightActiveLine = true,\n tabSize = 2,\n minHeight = 120,\n maxHeight,\n placeholder = \"Type code here…\",\n ariaLabel = \"Code editor\",\n toolbar,\n status,\n className,\n showCopy = true,\n showFormat,\n wordWrap: wordWrapProp,\n showWordWrapToggle = true,\n autoPair = true,\n showCounter = true,\n searchable = true,\n name,\n form,\n required,\n id,\n },\n forwardedRef,\n ) {\n const taRef = useRef<HTMLTextAreaElement>(null);\n // Bridge the local ref to the forwarded one so consumers can access the\n // underlying textarea (focus, select, scrollIntoView, etc.).\n useImperativeHandle(forwardedRef, () => taRef.current as HTMLTextAreaElement);\n const gutterRef = useRef<HTMLDivElement>(null);\n const [activeLine, setActiveLine] = useState(1);\n const [copied, setCopied] = useState(false);\n const [internalWrap, setInternalWrap] = useState<boolean>(wordWrapProp ?? false);\n const wordWrap = wordWrapProp ?? internalWrap;\n const [selectionLen, setSelectionLen] = useState(0);\n const [selectionLines, setSelectionLines] = useState(0);\n const [findOpen, setFindOpen] = useState(false);\n const [findQuery, setFindQuery] = useState(\"\");\n const [findIndex, setFindIndex] = useState(0);\n const findInputRef = useRef<HTMLInputElement>(null);\n\n const lines = value.split(\"\\n\");\n const lineCount = lines.length;\n\n const matches = useMemo(() => {\n if (!findQuery) return [] as Array<{ start: number; end: number }>;\n const out: Array<{ start: number; end: number }> = [];\n const lower = value.toLowerCase();\n const q = findQuery.toLowerCase();\n let i = 0;\n while (i <= lower.length - q.length) {\n const idx = lower.indexOf(q, i);\n if (idx < 0) break;\n out.push({ start: idx, end: idx + q.length });\n i = idx + Math.max(1, q.length);\n }\n return out;\n }, [findQuery, value]);\n\n useEffect(() => {\n const ta = taRef.current;\n const gut = gutterRef.current;\n if (!ta || !gut) return;\n const onScroll = () => {\n gut.scrollTop = ta.scrollTop;\n };\n ta.addEventListener(\"scroll\", onScroll);\n return () => ta.removeEventListener(\"scroll\", onScroll);\n }, []);\n\n const updateSelection = () => {\n const ta = taRef.current;\n if (!ta) return;\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const upTo = ta.value.slice(0, start);\n setActiveLine(upTo.split(\"\\n\").length);\n const selLen = end - start;\n setSelectionLen(selLen);\n if (selLen > 0) {\n const slice = ta.value.slice(start, end);\n setSelectionLines(slice.split(\"\\n\").length);\n } else {\n setSelectionLines(0);\n }\n };\n\n const setCaret = (start: number, end?: number) => {\n requestAnimationFrame(() => {\n const ta = taRef.current;\n if (!ta) return;\n ta.selectionStart = start;\n ta.selectionEnd = end ?? start;\n updateSelection();\n });\n };\n\n const replaceRange = (start: number, end: number, replacement: string, caretAt?: number) => {\n const next = value.slice(0, start) + replacement + value.slice(end);\n onChange?.(next);\n setCaret(caretAt ?? start + replacement.length);\n };\n\n const lineBounds = (text: string, caret: number) => {\n const before = text.lastIndexOf(\"\\n\", caret - 1);\n const after = text.indexOf(\"\\n\", caret);\n return {\n lineStart: before === -1 ? 0 : before + 1,\n lineEnd: after === -1 ? text.length : after,\n };\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n const ta = e.currentTarget;\n if (readOnly) return;\n const isMac = typeof navigator !== \"undefined\" && /Mac/.test(navigator.platform);\n const mod = isMac ? e.metaKey : e.ctrlKey;\n\n // Cmd+F → open find bar\n if (mod && (e.key === \"f\" || e.key === \"F\")) {\n if (!searchable) return;\n e.preventDefault();\n setFindOpen(true);\n requestAnimationFrame(() => findInputRef.current?.focus());\n return;\n }\n\n // Escape closes find\n if (e.key === \"Escape\" && findOpen) {\n e.preventDefault();\n setFindOpen(false);\n return;\n }\n\n // Cmd+/ → toggle comment for current line or selection\n if (mod && e.key === \"/\") {\n e.preventDefault();\n const prefix = COMMENT_PREFIX[language];\n const trimmedPrefix = prefix.trim();\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const firstStart = lineBounds(value, start).lineStart;\n const lastEnd = lineBounds(value, end).lineEnd;\n const slice = value.slice(firstStart, lastEnd);\n const partLines = slice.split(\"\\n\");\n const allCommented = partLines.every(\n (l) => l.trim() === \"\" || l.trimStart().startsWith(trimmedPrefix),\n );\n const updated = partLines\n .map((l) => {\n if (l.trim() === \"\") return l;\n if (allCommented) {\n const idx = l.indexOf(trimmedPrefix);\n if (idx >= 0) return l.slice(0, idx) + l.slice(idx + prefix.length);\n return l;\n }\n const leading = l.match(/^\\s*/)?.[0] ?? \"\";\n return `${leading}${prefix}${l.slice(leading.length)}`;\n })\n .join(\"\\n\");\n const next = value.slice(0, firstStart) + updated + value.slice(lastEnd);\n onChange?.(next);\n const delta = updated.length - slice.length;\n setCaret(start + (allCommented ? -prefix.length : prefix.length), end + delta);\n return;\n }\n\n // Cmd+D → duplicate current line (or selection)\n if (mod && (e.key === \"d\" || e.key === \"D\")) {\n e.preventDefault();\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n if (start === end) {\n const { lineStart, lineEnd } = lineBounds(value, start);\n const line = value.slice(lineStart, lineEnd);\n const next = value.slice(0, lineEnd) + \"\\n\" + line + value.slice(lineEnd);\n onChange?.(next);\n setCaret(start + line.length + 1);\n } else {\n const slice = value.slice(start, end);\n const next = value.slice(0, end) + slice + value.slice(end);\n onChange?.(next);\n setCaret(end + slice.length);\n }\n return;\n }\n\n // Alt+ArrowUp/Down → move line up/down\n if (e.altKey && (e.key === \"ArrowUp\" || e.key === \"ArrowDown\")) {\n e.preventDefault();\n const direction = e.key === \"ArrowUp\" ? -1 : 1;\n const caret = ta.selectionStart;\n const linesArr = value.split(\"\\n\");\n let acc = 0;\n let lineIdx = 0;\n let lineStart = 0;\n for (let i = 0; i < linesArr.length; i++) {\n const lineLen = linesArr[i].length;\n if (caret <= acc + lineLen) {\n lineIdx = i;\n lineStart = acc;\n break;\n }\n acc += lineLen + 1;\n lineIdx = i;\n lineStart = acc;\n }\n const target = lineIdx + direction;\n if (target < 0 || target >= linesArr.length) return;\n const swap = linesArr[lineIdx];\n linesArr[lineIdx] = linesArr[target];\n linesArr[target] = swap;\n const next = linesArr.join(\"\\n\");\n onChange?.(next);\n let newStart = 0;\n for (let i = 0; i < target; i++) newStart += linesArr[i].length + 1;\n const col = caret - lineStart;\n setCaret(newStart + Math.min(col, linesArr[target].length));\n return;\n }\n\n // Tab → spaces (or indent block when multi-line selection)\n if (e.key === \"Tab\") {\n e.preventDefault();\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n if (start !== end && value.slice(start, end).includes(\"\\n\")) {\n const firstStart = lineBounds(value, start).lineStart;\n const lastEnd = lineBounds(value, end).lineEnd;\n const block = value.slice(firstStart, lastEnd);\n let updated: string;\n if (e.shiftKey) {\n updated = block\n .split(\"\\n\")\n .map((l) => l.replace(new RegExp(`^ {1,${tabSize}}`), \"\"))\n .join(\"\\n\");\n } else {\n const pad = \" \".repeat(tabSize);\n updated = block\n .split(\"\\n\")\n .map((l) => `${pad}${l}`)\n .join(\"\\n\");\n }\n const next = value.slice(0, firstStart) + updated + value.slice(lastEnd);\n onChange?.(next);\n setCaret(firstStart, firstStart + updated.length);\n return;\n }\n const spaces = \" \".repeat(tabSize);\n replaceRange(start, end, spaces);\n return;\n }\n\n // Enter → auto-indent (+ expanded block when between auto-pair)\n if (e.key === \"Enter\") {\n const start = ta.selectionStart;\n const before = value[start - 1];\n const after = value[start];\n const upTo = value.slice(0, start);\n const currentLine = upTo.split(\"\\n\").pop() ?? \"\";\n const indent = currentLine.match(/^\\s*/)?.[0] ?? \"\";\n\n if (autoPair && before && after && OPEN_PAIRS[before] === after) {\n e.preventDefault();\n const inner = `\\n${indent}${\" \".repeat(tabSize)}\\n${indent}`;\n const next = value.slice(0, start) + inner + value.slice(ta.selectionEnd);\n onChange?.(next);\n setCaret(start + 1 + indent.length + tabSize);\n return;\n }\n\n if (indent.length > 0) {\n e.preventDefault();\n const next = value.slice(0, start) + \"\\n\" + indent + value.slice(ta.selectionEnd);\n onChange?.(next);\n setCaret(start + 1 + indent.length);\n return;\n }\n }\n\n // Auto-pair: opening bracket/quote\n if (autoPair && !e.metaKey && !e.ctrlKey && !e.altKey && OPEN_PAIRS[e.key]) {\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n if (start !== end) {\n e.preventDefault();\n const selected = value.slice(start, end);\n const wrapped = `${e.key}${selected}${OPEN_PAIRS[e.key]}`;\n replaceRange(start, end, wrapped, end + 2);\n return;\n }\n const nextChar = value[start];\n // Skip pairing if we'd just stack identical quotes\n if ((e.key === '\"' || e.key === \"'\" || e.key === \"`\") && nextChar === e.key) {\n e.preventDefault();\n setCaret(start + 1);\n return;\n }\n e.preventDefault();\n const insert = `${e.key}${OPEN_PAIRS[e.key]}`;\n const next = value.slice(0, start) + insert + value.slice(start);\n onChange?.(next);\n setCaret(start + 1);\n return;\n }\n\n // Auto-skip closing bracket when next char already matches\n if (autoPair && CLOSE_PAIRS.has(e.key)) {\n const start = ta.selectionStart;\n if (start === ta.selectionEnd && value[start] === e.key) {\n e.preventDefault();\n setCaret(start + 1);\n return;\n }\n }\n\n // Backspace inside an empty pair → delete both\n if (autoPair && e.key === \"Backspace\") {\n const start = ta.selectionStart;\n if (start === ta.selectionEnd && start > 0) {\n const left = value[start - 1];\n const right = value[start];\n if (left && right && OPEN_PAIRS[left] === right) {\n e.preventDefault();\n const next = value.slice(0, start - 1) + value.slice(start + 1);\n onChange?.(next);\n setCaret(start - 1);\n return;\n }\n }\n }\n };\n\n const doFindNext = (dir: 1 | -1 = 1) => {\n if (matches.length === 0) return;\n const next = (findIndex + dir + matches.length) % matches.length;\n setFindIndex(next);\n const m = matches[next];\n setCaret(m.start, m.end);\n requestAnimationFrame(() => taRef.current?.focus());\n };\n\n const handleCopy = async () => {\n if (typeof navigator === \"undefined\") return;\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n } catch {\n /* ignore */\n }\n };\n\n const handleFormat = () => {\n const formatted = tryFormat(value, language);\n if (formatted) onChange?.(formatted);\n };\n\n const showFormatBtn = (showFormat ?? language === \"json\") && !readOnly;\n const showWrapToggle = showWordWrapToggle && wordWrapProp === undefined;\n\n return (\n <div\n className={cn(\n \"ods-code-editor\",\n `ods-code-editor--${language}`,\n readOnly && \"ods-code-editor--readonly\",\n wordWrap && \"ods-code-editor--wrap\",\n className,\n )}\n >\n <div className=\"ods-code-editor__toolbar\">\n <div className=\"ods-code-editor__toolbar-left\">\n <span className=\"ods-code-editor__lang\">{language.toUpperCase()}</span>\n {toolbar}\n </div>\n <div className=\"ods-code-editor__toolbar-right\">\n <span className=\"ods-code-editor__lines\">\n {lineCount} line{lineCount === 1 ? \"\" : \"s\"}\n </span>\n {status && <span className=\"ods-code-editor__status\">{status}</span>}\n {showWrapToggle && (\n <button\n type=\"button\"\n className={cn(\"ods-code-editor__btn\", wordWrap && \"ods-code-editor__btn--active\")}\n onClick={() => setInternalWrap((w) => !w)}\n aria-pressed={wordWrap}\n aria-label=\"Toggle word wrap\"\n title=\"Word wrap\"\n >\n <TextWrapIcon aria-hidden=\"true\" />\n </button>\n )}\n {showFormatBtn && (\n <button\n type=\"button\"\n className=\"ods-code-editor__btn\"\n onClick={handleFormat}\n aria-label=\"Format\"\n title=\"Format (JSON)\"\n >\n <MagicWandIcon aria-hidden=\"true\" />\n </button>\n )}\n {showCopy && (\n <button\n type=\"button\"\n className={cn(\"ods-code-editor__btn\", copied && \"ods-code-editor__btn--success\")}\n onClick={handleCopy}\n aria-label=\"Copy\"\n title=\"Copy\"\n >\n {copied ? (\n <CheckmarkIcon aria-hidden=\"true\" />\n ) : (\n <CopyIcon aria-hidden=\"true\" />\n )}\n </button>\n )}\n </div>\n </div>\n\n {findOpen && (\n <div className=\"ods-code-editor__find\" role=\"search\">\n <SearchIcon aria-hidden=\"true\" />\n <input\n ref={findInputRef}\n className=\"ods-code-editor__find-input\"\n type=\"text\"\n placeholder=\"Find…\"\n value={findQuery}\n onChange={(e) => {\n setFindQuery(e.target.value);\n setFindIndex(0);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n doFindNext(e.shiftKey ? -1 : 1);\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n setFindOpen(false);\n taRef.current?.focus();\n }\n }}\n />\n <span className=\"ods-code-editor__find-count\">\n {matches.length > 0 ? `${findIndex + 1} of ${matches.length}` : \"0\"}\n </span>\n <button\n type=\"button\"\n className=\"ods-code-editor__btn\"\n onClick={() => doFindNext(-1)}\n aria-label=\"Previous match\"\n disabled={matches.length === 0}\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3 6.5 5 4.5l2 2\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n className=\"ods-code-editor__btn\"\n onClick={() => doFindNext(1)}\n aria-label=\"Next match\"\n disabled={matches.length === 0}\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3 3.5 5 5.5l2-2\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n className=\"ods-code-editor__btn\"\n onClick={() => {\n setFindOpen(false);\n taRef.current?.focus();\n }}\n aria-label=\"Close find\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"m3 3 4 4M7 3l-4 4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n )}\n\n <div className=\"ods-code-editor__body\" style={{ minHeight, maxHeight }}>\n {showLineNumbers && (\n <div ref={gutterRef} className=\"ods-code-editor__gutter\" aria-hidden=\"true\">\n {lines.map((_, i) => (\n <span\n key={i}\n className={cn(\n \"ods-code-editor__line-no\",\n highlightActiveLine && activeLine === i + 1 && \"ods-code-editor__line-no--active\",\n )}\n >\n {i + 1}\n </span>\n ))}\n </div>\n )}\n <textarea\n ref={taRef}\n id={id}\n name={name}\n form={form}\n required={required}\n className=\"ods-code-editor__textarea\"\n value={value}\n onChange={(e) => onChange?.(e.target.value)}\n onKeyDown={handleKeyDown}\n onKeyUp={updateSelection}\n onClick={updateSelection}\n onSelect={updateSelection}\n placeholder={placeholder}\n readOnly={readOnly}\n spellCheck={false}\n aria-label={ariaLabel}\n aria-required={required || undefined}\n wrap={wordWrap ? \"soft\" : \"off\"}\n />\n </div>\n\n {showCounter && (\n <div className=\"ods-code-editor__footer\">\n <span className=\"ods-code-editor__pos\">\n Ln {activeLine}\n {selectionLen > 0 && (\n <>\n {\" \"}\n · {selectionLen} char{selectionLen === 1 ? \"\" : \"s\"}\n {selectionLines > 1 && ` · ${selectionLines} lines`}\n </>\n )}\n </span>\n <span className=\"ods-code-editor__shortcut-hint\">\n <kbd className=\"ods-code-editor__kbd\">⌘/</kbd> comment\n <span className=\"ods-code-editor__sep\">·</span>\n <kbd className=\"ods-code-editor__kbd\">⌘D</kbd> duplicate\n <span className=\"ods-code-editor__sep\">·</span>\n <kbd className=\"ods-code-editor__kbd\">⌥↑↓</kbd> move\n {searchable && (\n <>\n <span className=\"ods-code-editor__sep\">·</span>\n <kbd className=\"ods-code-editor__kbd\">⌘F</kbd> find\n </>\n )}\n </span>\n </div>\n )}\n </div>\n );\n },\n);\n\nCodeEditor.displayName = \"CodeEditor\";\n","\"use client\";\nimport { ChevronDownIcon } from \"@octaviaflow/icons\";\nimport {\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface ComboboxOption {\n value: string;\n label: string;\n /** Secondary line under the label (e.g. the underlying token/expression). */\n description?: string;\n /** Optional leading glyph. */\n icon?: ReactNode;\n disabled?: boolean;\n}\n\nexport interface ComboboxProps {\n /** Current text value. Free text is always allowed — options are suggestions. */\n value: string;\n onChange: (value: string) => void;\n options: ComboboxOption[];\n placeholder?: string;\n /** Accessible name when no visible `label` is rendered. */\n ariaLabel?: string;\n /** Optional visible label rendered above the field. */\n label?: ReactNode;\n helperText?: ReactNode;\n size?: \"sm\" | \"md\" | \"lg\";\n disabled?: boolean;\n /** Shows a loading row in the panel instead of options (async option fetch). */\n loading?: boolean;\n error?: boolean;\n errorMessage?: ReactNode;\n /**\n * When true, a typed value that isn't an exact option match surfaces a\n * leading \"Use «value»\" row so users see free entry is allowed. Free typing\n * works regardless; this is purely an affordance.\n */\n creatable?: boolean;\n /** Message shown when no options match the typed text. */\n emptyMessage?: ReactNode;\n /** Override the default substring match. Receives the option and typed query. */\n filter?: (option: ComboboxOption, query: string) => boolean;\n id?: string;\n name?: string;\n required?: boolean;\n className?: string;\n onBlur?: () => void;\n}\n\nconst defaultFilter = (option: ComboboxOption, query: string) => {\n const q = query.trim().toLowerCase();\n return (\n option.label.toLowerCase().includes(q) || option.value.toLowerCase().includes(q)\n );\n};\n\n/**\n * Editable combobox: a free-text input with an attached dropdown button. The\n * button (or ArrowDown) reveals the option list; picking an option fills the\n * input, and the user can also type any value not in the list. Options filter\n * by the typed text. The panel is portal-positioned so it escapes parent\n * `overflow: hidden` clipping (side panels, drawers, scrollable sections).\n *\n * Free-type-OR-pick is the core behaviour — use it wherever a field accepts\n * both known values and arbitrary input (dynamic tokens, custom identifiers).\n */\nexport function Combobox({\n value,\n onChange,\n options,\n placeholder = \"Select or type…\",\n ariaLabel,\n label,\n helperText,\n size = \"md\",\n disabled = false,\n loading = false,\n error = false,\n errorMessage,\n creatable = false,\n emptyMessage = \"Type a custom value\",\n filter = defaultFilter,\n id,\n name,\n required,\n className,\n onBlur,\n}: ComboboxProps) {\n const [open, setOpen] = useState(false);\n const [activeIdx, setActiveIdx] = useState(0);\n const wrapRef = useRef<HTMLDivElement>(null);\n const fieldRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const reactId = useId();\n const inputId = id ?? `${reactId}-combobox`;\n const listboxId = `${reactId}-listbox`;\n const errorId = `${reactId}-err`;\n const helperId = `${reactId}-help`;\n\n const [panelPos, setPanelPos] = useState<{ top: number; left: number; width: number } | null>(\n null,\n );\n const updatePanelPos = useCallback(() => {\n if (!fieldRef.current) return;\n const r = fieldRef.current.getBoundingClientRect();\n setPanelPos({ top: r.bottom + 4, left: r.left, width: r.width });\n }, []);\n useLayoutEffect(() => {\n if (!open) return;\n updatePanelPos();\n window.addEventListener(\"scroll\", updatePanelPos, true);\n window.addEventListener(\"resize\", updatePanelPos);\n return () => {\n window.removeEventListener(\"scroll\", updatePanelPos, true);\n window.removeEventListener(\"resize\", updatePanelPos);\n };\n }, [open, updatePanelPos]);\n\n // When the value exactly matches a known option (i.e. a committed selection)\n // or is empty, show ALL options so reopening reveals the full list. Only when\n // the text diverges from any option do we treat it as a search query.\n const isExactMatch = useMemo(\n () => value !== \"\" && options.some((o) => o.value === value),\n [options, value],\n );\n const filtered = useMemo(() => {\n if (!value.trim() || isExactMatch) return options;\n return options.filter((o) => filter(o, value));\n }, [options, value, isExactMatch, filter]);\n\n // The optional \"Use «typed»\" creatable row precedes the filtered options.\n const showCreate = creatable && value.trim() !== \"\" && !isExactMatch;\n const rowCount = filtered.length + (showCreate ? 1 : 0);\n\n useEffect(() => {\n setActiveIdx(0);\n }, [value, open]);\n\n // Click outside closes.\n useEffect(() => {\n if (!open) return;\n const onDoc = (e: MouseEvent) => {\n const t = e.target as Node;\n if (!wrapRef.current?.contains(t) && !panelRef.current?.contains(t)) setOpen(false);\n };\n document.addEventListener(\"mousedown\", onDoc);\n return () => document.removeEventListener(\"mousedown\", onDoc);\n }, [open]);\n\n const commit = (v: string) => {\n onChange(v);\n setOpen(false);\n inputRef.current?.focus();\n };\n\n // ArrowDown/Up navigate the visible rows (create row is index 0 when present);\n // Enter commits the active row; Escape closes.\n const activeValueAt = (idx: number): string | undefined => {\n if (showCreate && idx === 0) return value;\n const optIdx = showCreate ? idx - 1 : idx;\n return filtered[optIdx]?.value;\n };\n\n const handleKey = (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return;\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n if (!open) {\n setOpen(true);\n return;\n }\n setActiveIdx((i) => Math.min(i + 1, Math.max(rowCount - 1, 0)));\n } else if (e.key === \"ArrowUp\") {\n if (!open) return;\n e.preventDefault();\n setActiveIdx((i) => Math.max(i - 1, 0));\n } else if (e.key === \"Enter\") {\n if (open && rowCount > 0) {\n const v = activeValueAt(activeIdx);\n if (v !== undefined) {\n e.preventDefault();\n commit(v);\n }\n }\n } else if (e.key === \"Escape\") {\n if (open) {\n e.preventDefault();\n setOpen(false);\n }\n }\n };\n\n const describedBy = error && errorMessage ? errorId : helperText ? helperId : undefined;\n const activeDescendant = open && rowCount > 0 ? `${listboxId}-opt-${activeIdx}` : undefined;\n\n return (\n <div\n ref={wrapRef}\n className={cn(\n \"ods-combobox\",\n `ods-combobox--${size}`,\n error && \"ods-combobox--error\",\n disabled && \"ods-combobox--disabled\",\n className,\n )}\n onBlur={(e) => {\n // Fire consumer onBlur only when focus leaves the whole widget.\n if (!wrapRef.current?.contains(e.relatedTarget as Node)) onBlur?.();\n }}\n >\n {label && (\n <label htmlFor={inputId} className=\"ods-combobox__label\">\n {label}\n {required && (\n <span className=\"ods-combobox__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n <div ref={fieldRef} className=\"ods-combobox__field\">\n <input\n ref={inputRef}\n id={inputId}\n name={name}\n type=\"text\"\n className=\"ods-combobox__input\"\n value={value}\n disabled={disabled}\n required={required}\n placeholder={placeholder}\n onChange={(e) => {\n onChange(e.target.value);\n if (!open) setOpen(true);\n }}\n onKeyDown={handleKey}\n onFocus={() => !disabled && setOpen(true)}\n role=\"combobox\"\n aria-expanded={open}\n aria-controls={open ? listboxId : undefined}\n aria-activedescendant={activeDescendant}\n aria-autocomplete=\"list\"\n aria-label={!label ? ariaLabel : undefined}\n aria-invalid={error || undefined}\n aria-required={required || undefined}\n aria-describedby={describedBy}\n />\n <button\n type=\"button\"\n className={cn(\"ods-combobox__toggle\", open && \"ods-combobox__toggle--open\")}\n onClick={() => {\n if (disabled) return;\n setOpen((o) => !o);\n inputRef.current?.focus();\n }}\n aria-label={`${ariaLabel ?? \"Options\"}`}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n disabled={disabled}\n tabIndex={-1}\n >\n <ChevronDownIcon aria-hidden=\"true\" className=\"ods-combobox__chev\" />\n </button>\n </div>\n\n {open && panelPos && typeof document !== \"undefined\" &&\n createPortal(\n <div\n ref={panelRef}\n data-ods-floating=\"\"\n className=\"ods-combobox__panel\"\n role=\"presentation\"\n style={{\n position: \"fixed\",\n top: panelPos.top,\n left: panelPos.left,\n minWidth: panelPos.width,\n }}\n >\n {loading ? (\n <div className=\"ods-combobox__status\" role=\"status\">\n <span className=\"ods-combobox__spinner\" aria-hidden=\"true\" />\n Loading…\n </div>\n ) : (\n <ul id={listboxId} role=\"listbox\" aria-label={ariaLabel} className=\"ods-combobox__list\">\n {showCreate && (\n <li>\n <button\n type=\"button\"\n id={`${listboxId}-opt-0`}\n role=\"option\"\n aria-selected={false}\n className={cn(\n \"ods-combobox__opt ods-combobox__opt--create\",\n activeIdx === 0 && \"ods-combobox__opt--active\",\n )}\n onClick={() => commit(value)}\n onMouseEnter={() => setActiveIdx(0)}\n >\n Use “<strong>{value}</strong>”\n </button>\n </li>\n )}\n {filtered.length === 0 && !showCreate && (\n <li className=\"ods-combobox__empty\">{emptyMessage}</li>\n )}\n {filtered.map((opt, i) => {\n const idx = showCreate ? i + 1 : i;\n return (\n <li key={opt.value}>\n <button\n type=\"button\"\n id={`${listboxId}-opt-${idx}`}\n role=\"option\"\n aria-selected={opt.value === value}\n disabled={opt.disabled}\n className={cn(\n \"ods-combobox__opt\",\n opt.value === value && \"ods-combobox__opt--selected\",\n idx === activeIdx && \"ods-combobox__opt--active\",\n opt.disabled && \"ods-combobox__opt--disabled\",\n )}\n onClick={() => !opt.disabled && commit(opt.value)}\n onMouseEnter={() => setActiveIdx(idx)}\n >\n {opt.icon && (\n <span className=\"ods-combobox__opt-icon\" aria-hidden=\"true\">\n {opt.icon}\n </span>\n )}\n <span className=\"ods-combobox__opt-body\">\n <span className=\"ods-combobox__opt-text\">{opt.label}</span>\n {opt.description && (\n <span className=\"ods-combobox__opt-desc\">{opt.description}</span>\n )}\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </div>,\n document.body,\n )}\n\n {error && errorMessage && (\n <div id={errorId} className=\"ods-combobox__error-message\" role=\"alert\">\n {errorMessage}\n </div>\n )}\n {!error && helperText && (\n <div id={helperId} className=\"ods-combobox__helper\">\n {helperText}\n </div>\n )}\n </div>\n );\n}\n\nCombobox.displayName = \"Combobox\";\n","\"use client\";\nimport { ChevronRightIcon } from \"@octaviaflow/icons\";\nimport { type ReactNode, useId, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface DisclosureProps {\n /** Header text (the clickable toggle). */\n title: ReactNode;\n children: ReactNode;\n /** Optional secondary line under the title. */\n description?: ReactNode;\n /** Optional leading icon in the header. */\n icon?: ReactNode;\n /** Optional trailing slot in the header (e.g. a count Badge). */\n trailing?: ReactNode;\n /** Uncontrolled initial open state. Default false. */\n defaultOpen?: boolean;\n /** Controlled open state. When set, `onOpenChange` drives changes. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n size?: \"sm\" | \"md\";\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Disclosure — a single collapsible section toggled by a button header. Use for\n * \"Advanced options\" / \"Properties\" reveals where a full Accordion (grouped\n * multi-section) is overkill. Controlled or uncontrolled. Keyboard + ARIA\n * disclosure semantics (button `aria-expanded` + `aria-controls` → region).\n */\nexport function Disclosure({\n title,\n children,\n description,\n icon,\n trailing,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n size = \"md\",\n disabled = false,\n className,\n}: DisclosureProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);\n const isControlled = controlledOpen !== undefined;\n const open = isControlled ? controlledOpen : uncontrolledOpen;\n const reactId = useId();\n const regionId = `${reactId}-region`;\n\n const toggle = () => {\n if (disabled) return;\n const next = !open;\n if (!isControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n };\n\n return (\n <div\n className={cn(\n \"ods-disclosure\",\n `ods-disclosure--${size}`,\n open && \"ods-disclosure--open\",\n disabled && \"ods-disclosure--disabled\",\n className,\n )}\n >\n <button\n type=\"button\"\n className=\"ods-disclosure__trigger\"\n onClick={toggle}\n disabled={disabled}\n aria-expanded={open}\n aria-controls={regionId}\n >\n <ChevronRightIcon aria-hidden=\"true\" className=\"ods-disclosure__chev\" />\n {icon && (\n <span className=\"ods-disclosure__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"ods-disclosure__head\">\n <span className=\"ods-disclosure__title\">{title}</span>\n {description && <span className=\"ods-disclosure__desc\">{description}</span>}\n </span>\n {trailing && <span className=\"ods-disclosure__trailing\">{trailing}</span>}\n </button>\n {open && (\n <div id={regionId} role=\"region\" className=\"ods-disclosure__content\">\n {children}\n </div>\n )}\n </div>\n );\n}\n\nDisclosure.displayName = \"Disclosure\";\n","\"use client\";\nimport { CloseIcon } from \"@octaviaflow/icons\";\nimport {\n forwardRef,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n useId,\n useImperativeHandle,\n useRef,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\"> {\n type?:\n | \"text\"\n | \"email\"\n | \"password\"\n | \"search\"\n | \"number\"\n | \"tel\"\n | \"url\"\n | \"color\"\n | \"date\"\n | \"datetime-local\"\n | \"month\"\n | \"time\"\n | \"week\";\n size?: \"sm\" | \"md\" | \"lg\";\n error?: boolean;\n errorMessage?: string;\n label?: ReactNode;\n helperText?: ReactNode;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n /**\n * Show a clear button on the right while the input has a value.\n * Auto-enabled when `type=\"search\"`; explicitly toggle for other types.\n */\n clearable?: boolean;\n onClear?: () => void;\n /**\n * Right-side keyboard shortcut hint (e.g. \"⌘K\"). Rendered as a kbd-style chip.\n * Hidden while a clear button is showing (clear takes precedence).\n */\n shortcutHint?: ReactNode;\n}\n\nconst CLEAR_GLYPH = <CloseIcon width={12} height={12} aria-hidden=\"true\" />;\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n type = \"text\",\n size = \"md\",\n error = false,\n errorMessage,\n label,\n helperText,\n leftIcon,\n rightIcon,\n clearable,\n onClear,\n shortcutHint,\n disabled = false,\n required,\n id,\n className,\n value,\n defaultValue,\n onChange,\n onKeyDown,\n ...props\n },\n forwardedRef,\n ) => {\n const innerRef = useRef<HTMLInputElement>(null);\n useImperativeHandle(forwardedRef, () => innerRef.current as HTMLInputElement);\n\n const reactId = useId();\n const inputId = id ?? `${reactId}-input`;\n const errorId = `${reactId}-err`;\n const helperId = `${reactId}-help`;\n\n const isControlled = value !== undefined;\n const isClearable = (clearable ?? type === \"search\") && !disabled;\n const isSearch = type === \"search\";\n\n const currentValue = isControlled\n ? String(value ?? \"\")\n : (innerRef.current?.value ?? String(defaultValue ?? \"\"));\n const showClear = isClearable && currentValue.length > 0;\n\n const clearValue = () => {\n const el = innerRef.current;\n if (el && !isControlled) {\n const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, \"value\")?.set;\n setter?.call(el, \"\");\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n }\n onClear?.();\n el?.focus();\n };\n\n const handleClear = (e: MouseEvent<HTMLButtonElement>) => {\n e.preventDefault();\n e.stopPropagation();\n clearValue();\n };\n\n // Esc clears the value for search inputs — standard browser-search UX.\n // Consumer's own onKeyDown still runs first; preventDefault from theirs\n // short-circuits ours.\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (isClearable && isSearch && e.key === \"Escape\" && currentValue) {\n e.preventDefault();\n clearValue();\n }\n };\n\n const describedBy = error && errorMessage ? errorId : helperText ? helperId : undefined;\n\n return (\n <div\n className={cn(\n \"ods-input\",\n `ods-input--${size}`,\n error && \"ods-input--error\",\n disabled && \"ods-input--disabled\",\n isSearch && \"ods-input--search\",\n className,\n )}\n >\n {label && (\n <label htmlFor={inputId} className=\"ods-input__label\">\n {label}\n {required && (\n <span className=\"ods-input__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n <div className=\"ods-input__wrapper\">\n {leftIcon && (\n <span className=\"ods-input__icon--left\" aria-hidden=\"true\">\n {leftIcon}\n </span>\n )}\n <input\n {...props}\n id={inputId}\n ref={innerRef}\n type={type}\n disabled={disabled}\n required={required}\n value={value}\n defaultValue={defaultValue}\n onChange={onChange}\n onKeyDown={handleKeyDown}\n className={cn(\n \"ods-input__field\",\n leftIcon && \"ods-input__field--with-left-icon\",\n (rightIcon || showClear || shortcutHint) && \"ods-input__field--with-right-icon\",\n showClear && shortcutHint && \"ods-input__field--with-right-actions\",\n )}\n aria-invalid={error || undefined}\n aria-required={required || undefined}\n aria-describedby={describedBy}\n />\n <span className=\"ods-input__right\">\n {showClear && (\n <button\n type=\"button\"\n className=\"ods-input__clear\"\n onClick={handleClear}\n aria-label=\"Clear\"\n tabIndex={-1}\n >\n {CLEAR_GLYPH}\n </button>\n )}\n {shortcutHint && !showClear && (\n <span className=\"ods-input__kbd\" aria-hidden=\"true\">\n {shortcutHint}\n </span>\n )}\n {rightIcon && !showClear && !shortcutHint && (\n <span className=\"ods-input__icon--right\" aria-hidden=\"true\">\n {rightIcon}\n </span>\n )}\n </span>\n </div>\n {error && errorMessage && (\n <div id={errorId} className=\"ods-input__error-message\" role=\"alert\">\n {errorMessage}\n </div>\n )}\n {!error && helperText && (\n <div id={helperId} className=\"ods-input__helper\">\n {helperText}\n </div>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n","\"use client\";\nimport { CheckmarkIcon, ChevronRightIcon, CopyIcon } from \"@octaviaflow/icons\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { CodeEditor } from \"../CodeEditor\";\nimport { InlineMessage } from \"../InlineMessage\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/** Result reported through `onValidate` after each edit-mode keystroke. */\nexport interface JsonViewerValidationResult {\n /** True when the current editor text parses as valid JSON. */\n valid: boolean;\n /** Parse error details — only present when `valid` is false. */\n error?: {\n /** 1-indexed line number from the parser. */\n line: number;\n /** 1-indexed column number from the parser. */\n col: number;\n /** Human-readable error message from the JSON parser. */\n message: string;\n };\n}\n\nexport interface JsonViewerProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"title\" | \"onChange\"> {\n data: unknown;\n /**\n * `view` (default) — read-only collapsible tree view of `data`.\n * `edit` — switches to a CodeEditor primed with the JSON text of `data`.\n * In edit mode `onChange` fires on every keystroke with the raw text;\n * `onValidate` reports parse success/failure (Monaco's built-in JSON\n * language service also renders inline red squiggles).\n */\n mode?: \"view\" | \"edit\";\n /** Fires on every keystroke in `mode='edit'` with the raw editor text.\n * Always fires — even when the text is currently invalid JSON. */\n onChange?: (rawText: string) => void;\n /** Fires after each parse attempt in `mode='edit'`. Consumers gate the\n * save button on `result.valid`. */\n onValidate?: (result: JsonViewerValidationResult) => void;\n /** Initially expand to N levels deep (view mode only). Default 2. */\n defaultExpandDepth?: number;\n /** Show array indexes (view mode only). Default true. */\n showIndexes?: boolean;\n /** Show a copy button on hover for each leaf value (view mode only). */\n copyable?: boolean;\n /** Optional title. */\n title?: ReactNode;\n /** Optional status pill next to title. */\n status?: ReactNode;\n /** Limit each string value display length (view mode only). */\n truncateAt?: number;\n /** Fixed body height — number → pixels, string → any CSS length.\n * The inner tree scrolls vertically when content exceeds the bound. */\n height?: number | string;\n /** Upper bound on body height. Same shape as `height`; lets the body\n * grow up to the cap before scrolling kicks in. Ignored when `height`\n * is set (height takes precedence). */\n maxHeight?: number | string;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\n/**\n * JSON viewer with two modes:\n *\n * - `view` (default) — collapsible tree of `data` with type-tinted\n * values, mono font for keys, optional copy buttons on leaves.\n * - `edit` — CodeEditor primed with JSON-stringified `data`.\n * Monaco's built-in JSON language service renders inline parse-error\n * squiggles. Consumers wire `onChange` (raw text) + `onValidate`\n * (parse result) — typical pattern is `disabled={!isValid}` on a\n * save button driven by `onValidate`.\n */\nexport const JsonViewer = forwardRef<HTMLDivElement, JsonViewerProps>(\n function JsonViewer(\n {\n data,\n mode = \"view\",\n onChange,\n onValidate,\n defaultExpandDepth = 2,\n showIndexes = true,\n copyable = false,\n title,\n status,\n truncateAt = 200,\n height,\n maxHeight,\n className,\n ...rest\n },\n ref,\n ) {\n // Constrain the scrollable body. Numbers get the `px` unit; strings\n // pass through (so consumers can use vh / clamp() / etc.). `height`\n // is the hard size; `maxHeight` is the upper bound when content fits\n // naturally — either one switches the body to a real scroll surface.\n const bodyStyle: React.CSSProperties | undefined =\n height !== undefined\n ? { height: typeof height === \"number\" ? `${height}px` : height }\n : maxHeight !== undefined\n ? { maxHeight: typeof maxHeight === \"number\" ? `${maxHeight}px` : maxHeight }\n : undefined;\n\n return (\n <div {...rest} ref={ref} className={cn(\"ods-json-viewer\", className)} data-mode={mode}>\n {(title || status) && (\n <div className=\"ods-json-viewer__head\">\n {title && <span className=\"ods-json-viewer__title\">{title}</span>}\n {status && <span className=\"ods-json-viewer__status\">{status}</span>}\n </div>\n )}\n <div className=\"ods-json-viewer__body\" style={bodyStyle}>\n {mode === \"edit\" ? (\n <JsonEditBody data={data} onChange={onChange} onValidate={onValidate} />\n ) : (\n <JsonNode\n value={data}\n depth={0}\n defaultExpandDepth={defaultExpandDepth}\n showIndexes={showIndexes}\n copyable={copyable}\n truncateAt={truncateAt}\n />\n )}\n </div>\n </div>\n );\n },\n);\n\nJsonViewer.displayName = \"JsonViewer\";\n\n/* ---------------------------------------------------------------------------\n * Inner tree node — recursive\n * ------------------------------------------------------------------------- */\n\nfunction JsonNode({\n name,\n value,\n depth,\n defaultExpandDepth,\n showIndexes,\n copyable,\n truncateAt,\n isLast = true,\n}: {\n name?: string | number;\n value: unknown;\n depth: number;\n defaultExpandDepth: number;\n showIndexes: boolean;\n copyable: boolean;\n truncateAt: number;\n isLast?: boolean;\n}) {\n const [open, setOpen] = useState(depth < defaultExpandDepth);\n\n const isObject = value !== null && typeof value === \"object\" && !Array.isArray(value);\n const isArray = Array.isArray(value);\n const isContainer = isObject || isArray;\n\n const renderKey = useMemo(() => {\n if (name === undefined) return null;\n if (typeof name === \"number\") {\n return showIndexes ? (\n <span className=\"ods-json-viewer__key ods-json-viewer__key--index\">{name}</span>\n ) : null;\n }\n return <span className=\"ods-json-viewer__key\">{`\"${name}\"`}</span>;\n }, [name, showIndexes]);\n\n if (!isContainer) {\n return (\n <div className=\"ods-json-viewer__row\" style={{ paddingLeft: depth * 14 }}>\n <span className=\"ods-json-viewer__caret-spacer\" />\n {renderKey}\n {renderKey != null && <span className=\"ods-json-viewer__colon\">:</span>}\n <Leaf value={value} truncateAt={truncateAt} copyable={copyable} />\n {!isLast && <span className=\"ods-json-viewer__comma\">,</span>}\n </div>\n );\n }\n\n const entries = isArray\n ? (value as unknown[]).map((v, i) => [i, v] as const)\n : Object.entries(value as Record<string, unknown>);\n\n const openBracket = isArray ? \"[\" : \"{\";\n const closeBracket = isArray ? \"]\" : \"}\";\n\n return (\n <div>\n <div\n className=\"ods-json-viewer__row ods-json-viewer__row--container\"\n style={{ paddingLeft: depth * 14 }}\n onClick={() => setOpen((o) => !o)}\n >\n <button\n type=\"button\"\n className={cn(\"ods-json-viewer__caret\", open && \"ods-json-viewer__caret--open\")}\n aria-expanded={open}\n aria-label={open ? \"Collapse\" : \"Expand\"}\n onClick={(e) => {\n e.stopPropagation();\n setOpen((o) => !o);\n }}\n >\n <ChevronRightIcon aria-hidden=\"true\" />\n </button>\n {renderKey}\n {renderKey != null && <span className=\"ods-json-viewer__colon\">:</span>}\n <span className=\"ods-json-viewer__bracket\">{openBracket}</span>\n {!open && (\n <>\n <span className=\"ods-json-viewer__preview\">\n {isArray\n ? entries.length === 0\n ? \"\"\n : `${entries.length} item${entries.length === 1 ? \"\" : \"s\"}`\n : entries.length === 0\n ? \"\"\n : `${entries.length} key${entries.length === 1 ? \"\" : \"s\"}`}\n </span>\n <span className=\"ods-json-viewer__bracket\">{closeBracket}</span>\n </>\n )}\n {!isLast && !open && <span className=\"ods-json-viewer__comma\">,</span>}\n </div>\n {open && (\n <>\n {entries.map(([k, v], i) => (\n <JsonNode\n key={String(k)}\n name={isArray ? (k as number) : (k as string)}\n value={v}\n depth={depth + 1}\n defaultExpandDepth={defaultExpandDepth}\n showIndexes={showIndexes}\n copyable={copyable}\n truncateAt={truncateAt}\n isLast={i === entries.length - 1}\n />\n ))}\n <div\n className=\"ods-json-viewer__row ods-json-viewer__row--close\"\n style={{ paddingLeft: depth * 14 }}\n >\n <span className=\"ods-json-viewer__caret-spacer\" />\n <span className=\"ods-json-viewer__bracket\">{closeBracket}</span>\n {!isLast && <span className=\"ods-json-viewer__comma\">,</span>}\n </div>\n </>\n )}\n </div>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Leaf value — type-tinted span + optional copy button\n * ------------------------------------------------------------------------- */\n\nfunction Leaf({\n value,\n truncateAt,\n copyable,\n}: {\n value: unknown;\n truncateAt: number;\n copyable: boolean;\n}) {\n const [copied, setCopied] = useState(false);\n\n let display: string;\n let variant: \"string\" | \"number\" | \"boolean\" | \"null\";\n if (value === null) {\n display = \"null\";\n variant = \"null\";\n } else if (typeof value === \"string\") {\n const t = value.length > truncateAt ? `${value.slice(0, truncateAt)}…` : value;\n display = `\"${t}\"`;\n variant = \"string\";\n } else if (typeof value === \"number\") {\n display = String(value);\n variant = \"number\";\n } else if (typeof value === \"boolean\") {\n display = String(value);\n variant = \"boolean\";\n } else {\n display = String(value);\n variant = \"string\";\n }\n\n const handleCopy = async () => {\n if (!copyable || typeof navigator === \"undefined\") return;\n try {\n await navigator.clipboard.writeText(\n typeof value === \"string\" ? value : JSON.stringify(value),\n );\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n } catch {\n /* clipboard write rejected (older browser, permission policy) */\n }\n };\n\n return (\n <span className={cn(\"ods-json-viewer__value\", `ods-json-viewer__value--${variant}`)}>\n <span>{display}</span>\n {copyable && (\n <button\n type=\"button\"\n className={cn(\n \"ods-json-viewer__copy\",\n copied && \"ods-json-viewer__copy--success\",\n )}\n onClick={(e) => {\n e.stopPropagation();\n handleCopy();\n }}\n aria-label={copied ? \"Copied\" : \"Copy value\"}\n >\n {copied ? (\n <CheckmarkIcon width={10} height={10} aria-hidden=\"true\" />\n ) : (\n <CopyIcon width={10} height={10} aria-hidden=\"true\" />\n )}\n </button>\n )}\n </span>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Edit-mode body — CodeEditor + JSON parse validation\n * ------------------------------------------------------------------------- */\n\n/** Extract `line` / `col` from a native `SyntaxError` thrown by `JSON.parse`.\n * The browser-reported message format varies — we look for common shapes\n * (\"at position N\", \"line N column M\", \"JSON.parse: …line N column M\") and\n * fall back to deriving line/col from the position offset when the raw\n * text is available.\n *\n * Returns `{ line: 1, col: 1 }` when no position info is recoverable —\n * consumers always get a usable location to highlight. */\nfunction extractJsonErrorPosition(\n err: unknown,\n text: string,\n): { line: number; col: number; message: string } {\n const message = err instanceof Error ? err.message : String(err);\n\n // Pattern 1: \"JSON.parse: ... at line N column M ...\"\n // Pattern 2: \"Unexpected token X in JSON at position N\"\n // Pattern 3: \"Expected … in JSON at position N (line N column M)\"\n const lineColMatch = message.match(/line (\\d+) column (\\d+)/i);\n if (lineColMatch) {\n return {\n line: Number(lineColMatch[1]),\n col: Number(lineColMatch[2]),\n message,\n };\n }\n\n const posMatch = message.match(/position (\\d+)/i);\n if (posMatch) {\n const pos = Number(posMatch[1]);\n // Walk the text to convert absolute offset → (line, col).\n let line = 1;\n let col = 1;\n for (let i = 0; i < pos && i < text.length; i++) {\n if (text[i] === \"\\n\") {\n line++;\n col = 1;\n } else {\n col++;\n }\n }\n return { line, col, message };\n }\n\n return { line: 1, col: 1, message };\n}\n\ninterface JsonEditBodyProps {\n data: unknown;\n onChange?: (rawText: string) => void;\n onValidate?: (result: JsonViewerValidationResult) => void;\n}\n\n/** Edit-mode shell — JSON-stringifies `data` once on mount, then owns the\n * text state internally. Parsing happens on every keystroke so consumers\n * get fast validation feedback through `onValidate`. */\nfunction JsonEditBody({ data, onChange, onValidate }: JsonEditBodyProps) {\n // Initial serialization — pretty-printed with 2-space indent so it\n // matches the view-mode tree's visual rhythm. We initialize from `data`\n // once; the editor then becomes the source of truth (changes through\n // `data` prop after mount are ignored to avoid stomping the user's\n // edits mid-typing).\n const initial = useMemo(() => {\n try {\n return JSON.stringify(data, null, 2);\n } catch {\n // Circular refs / non-serializable values — fall back to an empty\n // object so the editor isn't broken.\n return \"{}\";\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const [text, setText] = useState(initial);\n const [parseError, setParseError] = useState<{\n line: number;\n col: number;\n message: string;\n } | null>(null);\n\n // Parse + reporting — extracted so the initial-mount effect and the\n // per-keystroke handler share identical behaviour.\n const validate = (next: string) => {\n try {\n JSON.parse(next);\n setParseError(null);\n onValidate?.({ valid: true });\n } catch (err) {\n const pos = extractJsonErrorPosition(err, next);\n setParseError(pos);\n onValidate?.({ valid: false, error: pos });\n }\n };\n\n const handleChange = (next: string) => {\n setText(next);\n onChange?.(next);\n validate(next);\n };\n\n // Initial validation report — consumers can disable their save button\n // from mount if the seed data happens to be invalid (rare but possible\n // when `data` was already a string of bad JSON).\n useEffect(() => {\n validate(initial);\n // Run once on mount to seed the consumer's validity flag.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div className=\"ods-json-viewer__edit\">\n {parseError && (\n <InlineMessage\n tone=\"danger\"\n size=\"sm\"\n className=\"ods-json-viewer__parse-error\"\n title={`Line ${parseError.line}, column ${parseError.col}`}\n >\n Line {parseError.line}, col {parseError.col} · {parseError.message}\n </InlineMessage>\n )}\n <CodeEditor\n value={text}\n onChange={handleChange}\n language=\"json\"\n ariaLabel=\"JSON editor\"\n showFormat\n showCopy\n />\n </div>\n );\n}\n","\"use client\";\nimport {\n CheckmarkFilledIcon,\n ErrorFilledIcon,\n InformationFilledIcon,\n WarningFilledIcon,\n} from \"@octaviaflow/icons\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * InlineMessage — small, lightweight status text.\n *\n * The middle-weight between a heavy `Banner` / `Callout` (page-level\n * card-like surface with title + description + actions) and a plain\n * `<span>` of muted text. Used for:\n *\n * - Form field validation (\"Required\", \"Min 8 characters\")\n * - DataTable cell errors (\"Failed to sync · retry?\")\n * - Inline status hints (\"Last saved 4 min ago\")\n * - Connector-row warnings (\"Lag exceeds SLA\")\n *\n * Renders as inline-flex text + optional leading icon. No padding,\n * no background, no border by default — it's text, not a card.\n *\n * A11y: `aria-live` is wired via the `live` prop. Default `\"off\"` for\n * static helper text; set `\"polite\"` for validation messages so screen\n * readers announce the change when the message replaces / appears.\n * ------------------------------------------------------------------------- */\n\nexport type InlineMessageTone = \"info\" | \"success\" | \"warning\" | \"danger\";\n\nexport type InlineMessageSize = \"sm\" | \"md\";\n\nexport interface InlineMessageProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /** Tone — drives text + icon color. Default `\"info\"`. */\n tone?: InlineMessageTone;\n /** Visual size. Default `\"md\"`. */\n size?: InlineMessageSize;\n /**\n * Leading icon. When omitted, a tone-appropriate filled icon is\n * used. Pass `false` to suppress the icon entirely (text-only).\n */\n icon?: ReactNode | false;\n /**\n * ARIA live-region politeness. Use `\"polite\"` for validation\n * messages, `\"assertive\"` for blocking errors. Default `\"off\"` —\n * static helper text that doesn't need to be announced.\n */\n live?: \"off\" | \"polite\" | \"assertive\";\n /** Message text. */\n children: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Tone → default icon\n * ------------------------------------------------------------------------- */\n\nconst TONE_ICON: Record<InlineMessageTone, React.ElementType> = {\n info: InformationFilledIcon,\n success: CheckmarkFilledIcon,\n warning: WarningFilledIcon,\n danger: ErrorFilledIcon,\n};\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const InlineMessage = forwardRef<HTMLDivElement, InlineMessageProps>(\n function InlineMessage(\n {\n tone = \"info\",\n size = \"md\",\n icon,\n live = \"off\",\n className,\n children,\n ...rest\n },\n ref,\n ) {\n const DefaultIcon = TONE_ICON[tone];\n const renderIcon = icon === false ? null : (icon ?? <DefaultIcon />);\n\n return (\n <div\n {...rest}\n ref={ref}\n className={cn(\n \"ods-inline-msg\",\n `ods-inline-msg--${tone}`,\n `ods-inline-msg--${size}`,\n className,\n )}\n // role + aria-live are paired so AT picks up the announcement\n // when the message appears / changes. When `live=\"off\"`,\n // neither attribute is set — the element reads as plain text.\n role={live !== \"off\" ? \"status\" : undefined}\n aria-live={live !== \"off\" ? live : undefined}\n >\n {renderIcon && (\n <span className=\"ods-inline-msg__icon\" aria-hidden=\"true\">\n {renderIcon}\n </span>\n )}\n <span className=\"ods-inline-msg__text\">{children}</span>\n </div>\n );\n },\n);\n\nInlineMessage.displayName = \"InlineMessage\";\n","\"use client\";\nimport { AddIcon, CloseIcon } from \"@octaviaflow/icons\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Checkbox } from \"../Checkbox\";\nimport { Combobox, type ComboboxOption } from \"../Combobox\";\n\nexport interface KeyValuePair {\n key: string;\n value: string;\n /** Per-row enable flag. Only meaningful when `rowToggle` is set; a missing\n * value is treated as enabled (backward-compatible). */\n enabled?: boolean;\n /** Optional per-row description. Only rendered when `showDescription` is set. */\n description?: string;\n}\n\nexport interface KeyValueEditorProps {\n pairs: KeyValuePair[];\n onChange: (pairs: KeyValuePair[]) => void;\n label?: ReactNode;\n helperText?: ReactNode;\n keyPlaceholder?: string;\n valuePlaceholder?: string;\n descriptionPlaceholder?: string;\n addLabel?: ReactNode;\n /** When set, the key field is a Combobox of these suggestions (free-type still allowed). */\n keyOptions?: ComboboxOption[];\n /** When set, the value field is a Combobox of these suggestions (free-type still allowed). */\n valueOptions?: ComboboxOption[];\n /** Render a per-row enable Checkbox; disabled rows dim and their fields go\n * read-only (the toggle + remove stay active). New rows default to enabled. */\n rowToggle?: boolean;\n /** Render a third description column per row. */\n showDescription?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n disabled?: boolean;\n error?: boolean;\n errorMessage?: ReactNode;\n /** Shown when there are no rows yet. */\n emptyLabel?: ReactNode;\n maxRows?: number;\n className?: string;\n}\n\n/** A row counts as enabled unless explicitly turned off (so legacy pairs with\n * no `enabled` field stay active). */\nconst isRowEnabled = (pair: KeyValuePair) => pair.enabled !== false;\n\n/**\n * KeyValueEditor — a list of key/value rows with add/remove. Drives field\n * defaults, request headers/params, and similar \"name → value\" maps. Either\n * field can become a Combobox (suggestions + free entry) by passing\n * `keyOptions` / `valueOptions`; otherwise both are plain text inputs.\n */\nexport function KeyValueEditor({\n pairs,\n onChange,\n label,\n helperText,\n keyPlaceholder = \"key\",\n valuePlaceholder = \"value\",\n descriptionPlaceholder = \"description\",\n addLabel = \"Add\",\n keyOptions,\n valueOptions,\n rowToggle = false,\n showDescription = false,\n size = \"md\",\n disabled = false,\n error = false,\n errorMessage,\n emptyLabel,\n maxRows,\n className,\n}: KeyValueEditorProps) {\n const setAt = (i: number, patch: Partial<KeyValuePair>) =>\n onChange(pairs.map((p, j) => (j === i ? { ...p, ...patch } : p)));\n const removeAt = (i: number) => onChange(pairs.filter((_, j) => j !== i));\n const add = () =>\n onChange([...pairs, { key: \"\", value: \"\", ...(rowToggle ? { enabled: true } : {}) }]);\n\n const canAdd = !disabled && (maxRows === undefined || pairs.length < maxRows);\n\n return (\n <div\n className={cn(\n \"ods-kv-editor\",\n `ods-kv-editor--${size}`,\n error && \"ods-kv-editor--error\",\n showDescription && \"ods-kv-editor--with-description\",\n className,\n )}\n >\n {label && <div className=\"ods-kv-editor__label\">{label}</div>}\n\n {pairs.length === 0 && emptyLabel && (\n <div className=\"ods-kv-editor__empty\">{emptyLabel}</div>\n )}\n\n {pairs.map((pair, i) => {\n // A row's fields are read-only when the editor is globally disabled OR\n // the row has been toggled off. The toggle + remove always stay active.\n const rowOff = rowToggle && !isRowEnabled(pair);\n const fieldsDisabled = disabled || rowOff;\n return (\n <div\n key={i}\n className={cn(\"ods-kv-editor__row\", rowOff && \"ods-kv-editor__row--disabled\")}\n >\n {rowToggle && (\n <Checkbox\n size={size === \"lg\" ? \"md\" : size}\n aria-label=\"Enable row\"\n checked={isRowEnabled(pair)}\n onChange={(on) => setAt(i, { enabled: on })}\n disabled={disabled}\n />\n )}\n {keyOptions ? (\n <Combobox\n ariaLabel=\"Key\"\n size={size}\n value={pair.key}\n options={keyOptions}\n onChange={(v) => setAt(i, { key: v })}\n placeholder={keyPlaceholder}\n disabled={fieldsDisabled}\n />\n ) : (\n <input\n className=\"ods-kv-editor__input\"\n aria-label=\"Key\"\n value={pair.key}\n onChange={(e) => setAt(i, { key: e.target.value })}\n placeholder={keyPlaceholder}\n disabled={fieldsDisabled}\n />\n )}\n {valueOptions ? (\n <Combobox\n ariaLabel=\"Value\"\n size={size}\n value={pair.value}\n options={valueOptions}\n onChange={(v) => setAt(i, { value: v })}\n placeholder={valuePlaceholder}\n disabled={fieldsDisabled}\n />\n ) : (\n <input\n className=\"ods-kv-editor__input\"\n aria-label=\"Value\"\n value={pair.value}\n onChange={(e) => setAt(i, { value: e.target.value })}\n placeholder={valuePlaceholder}\n disabled={fieldsDisabled}\n />\n )}\n {showDescription && (\n <input\n className=\"ods-kv-editor__input ods-kv-editor__input--description\"\n aria-label=\"Description\"\n value={pair.description ?? \"\"}\n onChange={(e) => setAt(i, { description: e.target.value })}\n placeholder={descriptionPlaceholder}\n disabled={fieldsDisabled}\n />\n )}\n <button\n type=\"button\"\n className=\"ods-kv-editor__remove\"\n aria-label=\"Remove row\"\n onClick={() => removeAt(i)}\n disabled={disabled}\n >\n <CloseIcon width={14} height={14} aria-hidden=\"true\" />\n </button>\n </div>\n );\n })}\n\n {canAdd && (\n <button type=\"button\" className=\"ods-kv-editor__add\" onClick={add}>\n <AddIcon width={14} height={14} aria-hidden=\"true\" />\n {addLabel}\n </button>\n )}\n\n {error && errorMessage && (\n <div className=\"ods-kv-editor__error-message\" role=\"alert\">\n {errorMessage}\n </div>\n )}\n {!error && helperText && <div className=\"ods-kv-editor__helper\">{helperText}</div>}\n </div>\n );\n}\n\nKeyValueEditor.displayName = \"KeyValueEditor\";\n","\"use client\";\nimport {\n type InputHTMLAttributes,\n type ReactNode,\n forwardRef,\n useId,\n useImperativeHandle,\n useRef,\n} from \"react\";\nimport { useCheckbox } from \"react-aria\";\nimport { useToggleState } from \"react-stately\";\nimport { resolveAccessibleName } from \"../../utils/a11y\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type CheckboxSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface CheckboxProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, \"onChange\" | \"size\"> {\n /** Controlled checked state. */\n checked?: boolean;\n /** Uncontrolled initial state. */\n defaultChecked?: boolean;\n /** Fires with the new selection state. */\n onChange?: (isSelected: boolean) => void;\n /** Mixed-state checkbox (for \"select all\" with partial children). */\n indeterminate?: boolean;\n disabled?: boolean;\n /** Visible label. Pair with `description` for \"label + helper text\" stacks. */\n label?: ReactNode;\n /** Optional helper text below the label. Linked via `aria-describedby` so\n * AT users hear the description after the label. */\n description?: ReactNode;\n /** Mark the field as invalid. Adds the error tint + `aria-invalid`. */\n error?: boolean;\n /** Error message rendered under the description. */\n errorMessage?: ReactNode;\n size?: CheckboxSize;\n className?: string;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(\n function Checkbox(\n {\n checked,\n defaultChecked,\n onChange,\n indeterminate = false,\n disabled = false,\n label,\n description,\n error = false,\n errorMessage,\n size = \"md\",\n required,\n className,\n ...props\n },\n forwardedRef,\n ) {\n const internalRef = useRef<HTMLInputElement>(null);\n useImperativeHandle(forwardedRef, () => internalRef.current as HTMLInputElement);\n\n const state = useToggleState({\n isSelected: checked,\n defaultSelected: defaultChecked,\n onChange,\n });\n\n // ─ Stable IDs for description / error message wiring ──────────────────\n const reactId = useId();\n const baseId = (props.id as string | undefined) ?? `ods-cb-${reactId}`;\n const descId = description ? `${baseId}-desc` : undefined;\n const errId = error && errorMessage ? `${baseId}-err` : undefined;\n const describedBy = [descId, errId].filter(Boolean).join(\" \") || undefined;\n\n // Resolve accessible name from {label, aria-label, aria-labelledby}.\n const ariaNameProps = resolveAccessibleName({\n label,\n ariaLabel: (props as any)[\"aria-label\"],\n ariaLabelledby: (props as any)[\"aria-labelledby\"],\n componentName: \"Checkbox\",\n });\n\n const { inputProps } = useCheckbox(\n {\n isSelected: state.isSelected,\n isIndeterminate: indeterminate,\n isDisabled: disabled,\n isRequired: required,\n isInvalid: error,\n onChange,\n // useCheckbox returns `name`/`value`/`form` in its `inputProps`. If\n // we let them fall through as `undefined`, the spread overwrites\n // the consumer's attrs. Pass them via the config so react-aria\n // emits real values.\n name: (props as { name?: string }).name,\n value: (props as { value?: string }).value,\n form: (props as { form?: string }).form,\n ...ariaNameProps,\n },\n state,\n internalRef,\n );\n\n const isChecked = state.isSelected;\n\n // React Aria owns the interactive event handlers. Strip those from the\n // caller's props so we don't double-bind, then let native form attrs\n // (name, value, form, required, autoFocus, etc.) flow to the DOM.\n const {\n onClick: _onClick,\n onKeyDown: _onKeyDown,\n onKeyUp: _onKeyUp,\n onFocus: _onFocus,\n onBlur: _onBlur,\n ...passthroughProps\n } = props as Record<string, unknown>;\n\n return (\n <label\n className={cn(\n \"ods-checkbox\",\n `ods-checkbox--${size}`,\n disabled && \"ods-checkbox--disabled\",\n error && \"ods-checkbox--error\",\n description && \"ods-checkbox--with-description\",\n className,\n )}\n >\n <input\n {...(passthroughProps as any)}\n {...inputProps}\n id={baseId}\n ref={internalRef}\n aria-describedby={describedBy}\n className=\"ods-checkbox__input\"\n />\n <span\n className={cn(\n \"ods-checkbox__box\",\n isChecked && !indeterminate && \"ods-checkbox__box--checked\",\n indeterminate && \"ods-checkbox__box--indeterminate\",\n )}\n aria-hidden=\"true\"\n >\n {indeterminate ? (\n <svg\n className=\"ods-checkbox__dash\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <line\n x1=\"2\"\n y1=\"6\"\n x2=\"10\"\n y2=\"6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n ) : (\n <svg\n className={cn(\n \"ods-checkbox__checkmark\",\n isChecked && \"ods-checkbox__checkmark--checked\",\n )}\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M2 6L5 9L10 3\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </span>\n {(label || description || errorMessage) && (\n <span className=\"ods-checkbox__text\">\n {label && (\n <span className=\"ods-checkbox__label\">\n {label}\n {required && (\n <span className=\"ods-checkbox__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n {description && (\n <span id={descId} className=\"ods-checkbox__description\">\n {description}\n </span>\n )}\n {error && errorMessage && (\n <span\n id={errId}\n className=\"ods-checkbox__error-message\"\n role=\"alert\"\n >\n {errorMessage}\n </span>\n )}\n </span>\n )}\n </label>\n );\n },\n);\n\nCheckbox.displayName = \"Checkbox\";\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport React, {SetStateAction, useCallback, useEffect, useReducer, useRef, useState} from 'react';\n\n// Use the earliest effect possible to reset the ref below.\nconst useEarlyEffect: typeof React.useLayoutEffect = typeof document !== 'undefined'\n ? React['useInsertionEffect'] ?? React.useLayoutEffect\n : () => {};\n\nexport function useControlledState<T, C = T>(value: Exclude<T, undefined>, defaultValue: Exclude<T, undefined> | undefined, onChange?: (v: C, ...args: any[]) => void): [T, (value: SetStateAction<T>, ...args: any[]) => void];\nexport function useControlledState<T, C = T>(value: Exclude<T, undefined> | undefined, defaultValue: Exclude<T, undefined>, onChange?: (v: C, ...args: any[]) => void): [T, (value: SetStateAction<T>, ...args: any[]) => void];\nexport function useControlledState<T, C = T>(value: T, defaultValue: T, onChange?: (v: C, ...args: any[]) => void): [T, (value: SetStateAction<T>, ...args: any[]) => void] {\n // Store the value in both state and a ref. The state value will only be used when uncontrolled.\n // The ref is used to track the most current value, which is passed to the function setState callback.\n let [stateValue, setStateValue] = useState(value || defaultValue);\n let valueRef = useRef(stateValue);\n\n let isControlledRef = useRef(value !== undefined);\n let isControlled = value !== undefined;\n useEffect(() => {\n let wasControlled = isControlledRef.current;\n if (wasControlled !== isControlled && process.env.NODE_ENV !== 'production') {\n console.warn(`WARN: A component changed from ${wasControlled ? 'controlled' : 'uncontrolled'} to ${isControlled ? 'controlled' : 'uncontrolled'}.`);\n }\n isControlledRef.current = isControlled;\n }, [isControlled]);\n\n // After each render, update the ref to the current value.\n // This ensures that the setState callback argument is reset.\n // Note: the effect should not have any dependencies so that controlled values always reset.\n let currentValue = isControlled ? value : stateValue;\n useEarlyEffect(() => {\n valueRef.current = currentValue;\n });\n\n let [, forceUpdate] = useReducer(() => ({}), {});\n let setValue = useCallback((value: SetStateAction<T>, ...args: any[]) => {\n // @ts-ignore - TS doesn't know that T cannot be a function.\n let newValue = typeof value === 'function' ? value(valueRef.current) : value;\n if (!Object.is(valueRef.current, newValue)) {\n // Update the ref so that the next setState callback has the most recent value.\n valueRef.current = newValue;\n\n setStateValue(newValue);\n\n // Always trigger a re-render, even when controlled, so that the layout effect above runs to reset the value.\n forceUpdate();\n\n // Trigger onChange. Note that if setState is called multiple times in a single event,\n // onChange will be called for each one instead of only once.\n onChange?.(newValue, ...args);\n }\n }, [onChange]);\n\n return [currentValue, setValue];\n}\n","/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Context, createContext, useContext, useEffect, useMemo, useRef, useState} from 'react';\nimport {Validation, ValidationErrors, ValidationFunction, ValidationResult} from '@react-types/shared';\n\nexport const VALID_VALIDITY_STATE: ValidityState = {\n badInput: false,\n customError: false,\n patternMismatch: false,\n rangeOverflow: false,\n rangeUnderflow: false,\n stepMismatch: false,\n tooLong: false,\n tooShort: false,\n typeMismatch: false,\n valueMissing: false,\n valid: true\n};\n\nconst CUSTOM_VALIDITY_STATE: ValidityState = {\n ...VALID_VALIDITY_STATE,\n customError: true,\n valid: false\n};\n\nexport const DEFAULT_VALIDATION_RESULT: ValidationResult = {\n isInvalid: false,\n validationDetails: VALID_VALIDITY_STATE,\n validationErrors: []\n};\n\nexport const FormValidationContext: Context<ValidationErrors> = createContext<ValidationErrors>({});\n\n// Private props that we pass from useFormValidationState to children.\n// Ideally we'd use a Symbol for this, but React doesn't support them: https://github.com/facebook/react/issues/7552\n// This needs to be stable across server and client module evaluation for SSR hydration.\nexport const privateValidationStateProp: string = '__reactAriaFormValidationState';\n\ninterface FormValidationProps<T> extends Validation<T> {\n builtinValidation?: ValidationResult,\n name?: string | string[],\n value: T | null\n}\n\nexport interface FormValidationState {\n /** Realtime validation results, updated as the user edits the value. */\n realtimeValidation: ValidationResult,\n /** Currently displayed validation results, updated when the user commits their changes. */\n displayValidation: ValidationResult,\n /** Updates the current validation result. Not displayed to the user until `commitValidation` is called. */\n updateValidation(result: ValidationResult): void,\n /** Resets the displayed validation state to valid when the user resets the form. */\n resetValidation(): void,\n /** Commits the realtime validation so it is displayed to the user. */\n commitValidation(): void\n}\n\nexport function useFormValidationState<T>(props: FormValidationProps<T>): FormValidationState {\n // Private prop for parent components to pass state to children.\n if (props[privateValidationStateProp]) {\n let {realtimeValidation, displayValidation, updateValidation, resetValidation, commitValidation} = props[privateValidationStateProp] as FormValidationState;\n return {realtimeValidation, displayValidation, updateValidation, resetValidation, commitValidation};\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useFormValidationStateImpl(props);\n}\n\nfunction useFormValidationStateImpl<T>(props: FormValidationProps<T>): FormValidationState {\n let {isInvalid, validationState, name, value, builtinValidation, validate, validationBehavior = 'aria'} = props;\n\n // backward compatibility.\n if (validationState) {\n isInvalid ||= validationState === 'invalid';\n }\n\n // If the isInvalid prop is controlled, update validation result in realtime.\n let controlledError: ValidationResult | null = isInvalid !== undefined ? {\n isInvalid,\n validationErrors: [],\n validationDetails: CUSTOM_VALIDITY_STATE\n } : null;\n\n // Perform custom client side validation.\n let clientError: ValidationResult | null = useMemo(() => {\n if (!validate || value == null) {\n return null;\n }\n let validateErrors = runValidate(validate, value);\n return getValidationResult(validateErrors);\n }, [validate, value]);\n\n if (builtinValidation?.validationDetails.valid) {\n builtinValidation = undefined;\n }\n\n // Get relevant server errors from the form.\n let serverErrors = useContext(FormValidationContext);\n let serverErrorMessages = useMemo(() => {\n if (name) {\n return Array.isArray(name) ? name.flatMap(name => asArray(serverErrors[name])) : asArray(serverErrors[name]);\n }\n return [];\n }, [serverErrors, name]);\n\n // Show server errors when the form gets a new value, and clear when the user changes the value.\n let [lastServerErrors, setLastServerErrors] = useState(serverErrors);\n let [isServerErrorCleared, setServerErrorCleared] = useState(false);\n if (serverErrors !== lastServerErrors) {\n setLastServerErrors(serverErrors);\n setServerErrorCleared(false);\n }\n\n let serverError: ValidationResult | null = useMemo(() =>\n getValidationResult(isServerErrorCleared ? [] : serverErrorMessages),\n [isServerErrorCleared, serverErrorMessages]\n );\n\n // Track the next validation state in a ref until commitValidation is called.\n let nextValidation = useRef(DEFAULT_VALIDATION_RESULT);\n let [currentValidity, setCurrentValidity] = useState(DEFAULT_VALIDATION_RESULT);\n\n let lastError = useRef(DEFAULT_VALIDATION_RESULT);\n let commitValidation = () => {\n if (!commitQueued) {\n return;\n }\n\n setCommitQueued(false);\n let error = clientError || builtinValidation || nextValidation.current;\n if (!isEqualValidation(error, lastError.current)) {\n lastError.current = error;\n setCurrentValidity(error);\n }\n };\n\n let [commitQueued, setCommitQueued] = useState(false);\n useEffect(commitValidation);\n\n // realtimeValidation is used to update the native input element's state based on custom validation logic.\n // displayValidation is the currently displayed validation state that the user sees (e.g. on input change/form submit).\n // With validationBehavior=\"aria\", all errors are displayed in realtime rather than on submit.\n let realtimeValidation = controlledError || serverError || clientError || builtinValidation || DEFAULT_VALIDATION_RESULT;\n let displayValidation = validationBehavior === 'native'\n ? controlledError || serverError || currentValidity\n : controlledError || serverError || clientError || builtinValidation || currentValidity;\n\n return {\n realtimeValidation,\n displayValidation,\n updateValidation(value) {\n // If validationBehavior is 'aria', update in realtime. Otherwise, store in a ref until commit.\n if (validationBehavior === 'aria' && !isEqualValidation(currentValidity, value)) {\n setCurrentValidity(value);\n } else {\n nextValidation.current = value;\n }\n },\n resetValidation() {\n // Update the currently displayed validation state to valid on form reset,\n // even if the native validity says it isn't. It'll show again on the next form submit.\n let error = DEFAULT_VALIDATION_RESULT;\n if (!isEqualValidation(error, lastError.current)) {\n lastError.current = error;\n setCurrentValidity(error);\n }\n\n // Do not commit validation after the next render. This avoids a condition where\n // useSelect calls commitValidation inside an onReset handler.\n if (validationBehavior === 'native') {\n setCommitQueued(false);\n }\n\n setServerErrorCleared(true);\n },\n commitValidation() {\n // Commit validation state so the user sees it on blur/change/submit. Also clear any server errors.\n // Wait until after the next render to commit so that the latest value has been validated.\n if (validationBehavior === 'native') {\n setCommitQueued(true);\n }\n setServerErrorCleared(true);\n }\n };\n}\n\nfunction asArray<T>(v: T | T[]): T[] {\n if (!v) {\n return [];\n }\n\n return Array.isArray(v) ? v : [v];\n}\n\nfunction runValidate<T>(validate: ValidationFunction<T>, value: T): string[] {\n if (typeof validate === 'function') {\n let e = validate(value);\n if (e && typeof e !== 'boolean') {\n return asArray(e);\n }\n }\n\n return [];\n}\n\nfunction getValidationResult(errors: string[]): ValidationResult | null {\n return errors.length ? {\n isInvalid: true,\n validationErrors: errors,\n validationDetails: CUSTOM_VALIDITY_STATE\n } : null;\n}\n\nfunction isEqualValidation(a: ValidationResult | null, b: ValidationResult | null): boolean {\n if (a === b) {\n return true;\n }\n\n return !!a && !!b\n && a.isInvalid === b.isInvalid\n && a.validationErrors.length === b.validationErrors.length\n && a.validationErrors.every((a, i) => a === b.validationErrors[i])\n && Object.entries(a.validationDetails).every(([k, v]) => b.validationDetails[k] === v);\n}\n\nexport function mergeValidation(...results: ValidationResult[]): ValidationResult {\n let errors = new Set<string>();\n let isInvalid = false;\n let validationDetails = {\n ...VALID_VALIDITY_STATE\n };\n\n for (let v of results) {\n for (let e of v.validationErrors) {\n errors.add(e);\n }\n\n // Only these properties apply for checkboxes.\n isInvalid ||= v.isInvalid;\n for (let key in validationDetails) {\n validationDetails[key] ||= v.validationDetails[key];\n }\n }\n\n validationDetails.valid = !isInvalid;\n return {\n isInvalid,\n validationErrors: [...errors],\n validationDetails\n };\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type {Collection, Node} from '@react-types/shared';\n\nexport function getChildNodes<T>(node: Node<T>, collection: Collection<Node<T>>): Iterable<Node<T>> {\n // New API: call collection.getChildren with the node key.\n if (typeof collection.getChildren === 'function') {\n return collection.getChildren(node.key);\n }\n\n // Old API: access childNodes directly.\n return node.childNodes;\n}\n\nexport function getFirstItem<T>(iterable: Iterable<T>): T | undefined {\n return getNthItem(iterable, 0);\n}\n\nexport function getNthItem<T>(iterable: Iterable<T>, index: number): T | undefined {\n if (index < 0) {\n return undefined;\n }\n\n let i = 0;\n for (let item of iterable) {\n if (i === index) {\n return item;\n }\n\n i++;\n }\n}\n\nexport function getLastItem<T>(iterable: Iterable<T>): T | undefined {\n let lastItem: T | undefined = undefined;\n for (let value of iterable) {\n lastItem = value;\n }\n\n return lastItem;\n}\n\nexport function compareNodeOrder<T>(collection: Collection<Node<T>>, a: Node<T>, b: Node<T>): number {\n // If the two nodes have the same parent, compare their indices.\n if (a.parentKey === b.parentKey) {\n return a.index - b.index;\n }\n\n // Otherwise, collect all of the ancestors from each node, and find the first one that doesn't match starting from the root.\n // Include the base nodes in case we are comparing nodes of different levels so that we can compare the higher node to the lower level node's\n // ancestor of the same level\n let aAncestors = [...getAncestors(collection, a), a];\n let bAncestors = [...getAncestors(collection, b), b];\n let firstNonMatchingAncestor = aAncestors.slice(0, bAncestors.length).findIndex((a, i) => a !== bAncestors[i]);\n if (firstNonMatchingAncestor !== -1) {\n // Compare the indices of two children within the common ancestor.\n a = aAncestors[firstNonMatchingAncestor];\n b = bAncestors[firstNonMatchingAncestor];\n return a.index - b.index;\n }\n\n // If there isn't a non matching ancestor, we might be in a case where one of the nodes is the ancestor of the other.\n if (aAncestors.findIndex(node => node === b) >= 0) {\n return 1;\n } else if (bAncestors.findIndex(node => node === a) >= 0) {\n return -1;\n }\n\n // 🤷\n return -1;\n}\n\nfunction getAncestors<T>(collection: Collection<Node<T>>, node: Node<T>): Node<T>[] {\n let parents: Node<T>[] = [];\n\n let currNode: Node<T> | null = node;\n while (currNode?.parentKey != null) {\n currNode = collection.getItem(currNode.parentKey);\n if (currNode) {\n parents.unshift(currNode);\n }\n }\n\n return parents;\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, Key, Node} from '@react-types/shared';\n\nexport class ListCollection<T> implements Collection<Node<T>> {\n private keyMap: Map<Key, Node<T>> = new Map();\n private iterable: Iterable<Node<T>>;\n private firstKey: Key | null = null;\n private lastKey: Key | null = null;\n private _size: number;\n\n constructor(nodes: Iterable<Node<T>>) {\n this.iterable = nodes;\n\n let visit = (node: Node<T>) => {\n this.keyMap.set(node.key, node);\n\n if (node.childNodes && node.type === 'section') {\n for (let child of node.childNodes) {\n visit(child);\n }\n }\n };\n\n for (let node of nodes) {\n visit(node);\n }\n\n let last: Node<T> | null = null;\n let index = 0;\n let size = 0;\n for (let [key, node] of this.keyMap) {\n if (last) {\n last.nextKey = key;\n node.prevKey = last.key;\n } else {\n this.firstKey = key;\n node.prevKey = undefined;\n }\n\n if (node.type === 'item') {\n node.index = index++;\n }\n\n // Only count sections and items when determining size so that\n // loaders and separators in RAC/S2 don't influence the emptyState determination\n if (node.type === 'section' || node.type === 'item') {\n size++;\n }\n\n last = node;\n\n // Set nextKey as undefined since this might be the last node\n // If it isn't the last node, last.nextKey will properly set at start of new loop\n last.nextKey = undefined;\n }\n this._size = size;\n this.lastKey = last?.key ?? null;\n }\n\n *[Symbol.iterator](): IterableIterator<Node<T>> {\n yield* this.iterable;\n }\n\n get size(): number {\n return this._size;\n }\n\n getKeys(): IterableIterator<Key> {\n return this.keyMap.keys();\n }\n\n getKeyBefore(key: Key): Key | null {\n let node = this.keyMap.get(key);\n return node ? node.prevKey ?? null : null;\n }\n\n getKeyAfter(key: Key): Key | null {\n let node = this.keyMap.get(key);\n return node ? node.nextKey ?? null : null;\n }\n\n getFirstKey(): Key | null {\n return this.firstKey;\n }\n\n getLastKey(): Key | null {\n return this.lastKey;\n }\n\n getItem(key: Key): Node<T> | null {\n return this.keyMap.get(key) ?? null;\n }\n\n at(idx: number): Node<T> | null {\n const keys = [...this.getKeys()];\n return this.getItem(keys[idx]);\n }\n\n getChildren(key: Key): Iterable<Node<T>> {\n let node = this.keyMap.get(key);\n return node?.childNodes || [];\n }\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Key} from '@react-types/shared';\n\n/**\n * A Selection is a special Set containing Keys, which also has an anchor\n * and current selected key for use when range selecting.\n */\nexport class Selection extends Set<Key> {\n anchorKey: Key | null;\n currentKey: Key | null;\n\n constructor(keys?: Iterable<Key> | Selection, anchorKey?: Key | null, currentKey?: Key | null) {\n super(keys);\n if (keys instanceof Selection) {\n this.anchorKey = anchorKey ?? keys.anchorKey;\n this.currentKey = currentKey ?? keys.currentKey;\n } else {\n this.anchorKey = anchorKey ?? null;\n this.currentKey = currentKey ?? null;\n }\n }\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DisabledBehavior, FocusStrategy, Key, MultipleSelection, SelectionBehavior, SelectionMode} from '@react-types/shared';\nimport {MultipleSelectionState} from './types';\nimport {Selection} from './Selection';\nimport {useControlledState} from '../utils/useControlledState';\nimport {useEffect, useMemo, useRef, useState} from 'react';\n\nfunction equalSets(setA, setB) {\n if (setA.size !== setB.size) {\n return false;\n }\n\n for (let item of setA) {\n if (!setB.has(item)) {\n return false;\n }\n }\n\n return true;\n}\n\nexport interface MultipleSelectionStateProps extends MultipleSelection {\n /**\n * How multiple selection should behave in the collection.\n * @default 'toggle'\n */\n selectionBehavior?: SelectionBehavior,\n /** Whether onSelectionChange should fire even if the new set of keys is the same as the last. */\n allowDuplicateSelectionEvents?: boolean,\n /**\n * Whether `disabledKeys` applies to all interactions, or only selection.\n * @default 'all'\n */\n disabledBehavior?: DisabledBehavior\n}\n\n/**\n * Manages state for multiple selection and focus in a collection.\n */\nexport function useMultipleSelectionState(props: MultipleSelectionStateProps): MultipleSelectionState {\n let {\n selectionMode = 'none' as SelectionMode,\n disallowEmptySelection = false,\n allowDuplicateSelectionEvents,\n selectionBehavior: selectionBehaviorProp = 'toggle',\n disabledBehavior = 'all'\n } = props;\n\n // We want synchronous updates to `isFocused` and `focusedKey` after their setters are called.\n // But we also need to trigger a react re-render. So, we have both a ref (sync) and state (async).\n let isFocusedRef = useRef(false);\n let [, setFocused] = useState(false);\n let focusedKeyRef = useRef<Key | null>(null);\n let childFocusStrategyRef = useRef<FocusStrategy | null>(null);\n let [, setFocusedKey] = useState<Key | null>(null);\n let selectedKeysProp = useMemo(() => convertSelection(props.selectedKeys), [props.selectedKeys]);\n let defaultSelectedKeys = useMemo(() => convertSelection(props.defaultSelectedKeys, new Selection()), [props.defaultSelectedKeys]);\n let [selectedKeys, setSelectedKeys] = useControlledState(\n selectedKeysProp,\n defaultSelectedKeys!,\n props.onSelectionChange\n );\n let disabledKeysProp = useMemo(() =>\n props.disabledKeys ? new Set(props.disabledKeys) : new Set<Key>()\n , [props.disabledKeys]);\n let [selectionBehavior, setSelectionBehavior] = useState(selectionBehaviorProp);\n\n // If the selectionBehavior prop is set to replace, but the current state is toggle (e.g. due to long press\n // to enter selection mode on touch), and the selection becomes empty, reset the selection behavior.\n if (selectionBehaviorProp === 'replace' && selectionBehavior === 'toggle' && typeof selectedKeys === 'object' && selectedKeys.size === 0) {\n setSelectionBehavior('replace');\n }\n\n // If the selectionBehavior prop changes, update the state as well.\n let lastSelectionBehavior = useRef(selectionBehaviorProp);\n useEffect(() => {\n if (selectionBehaviorProp !== lastSelectionBehavior.current) {\n setSelectionBehavior(selectionBehaviorProp);\n lastSelectionBehavior.current = selectionBehaviorProp;\n }\n }, [selectionBehaviorProp]);\n\n return {\n selectionMode,\n disallowEmptySelection,\n selectionBehavior,\n setSelectionBehavior,\n get isFocused() {\n return isFocusedRef.current;\n },\n setFocused(f) {\n isFocusedRef.current = f;\n setFocused(f);\n },\n get focusedKey() {\n return focusedKeyRef.current;\n },\n get childFocusStrategy() {\n return childFocusStrategyRef.current;\n },\n setFocusedKey(k, childFocusStrategy = 'first') {\n focusedKeyRef.current = k;\n childFocusStrategyRef.current = childFocusStrategy;\n setFocusedKey(k);\n },\n selectedKeys,\n setSelectedKeys(keys) {\n if (allowDuplicateSelectionEvents || !equalSets(keys, selectedKeys)) {\n setSelectedKeys(keys);\n }\n },\n disabledKeys: disabledKeysProp,\n disabledBehavior\n };\n}\n\nfunction convertSelection(selection: 'all' | Iterable<Key> | null | undefined, defaultValue?: Selection): 'all' | Set<Key> | undefined {\n if (!selection) {\n return defaultValue;\n }\n\n return selection === 'all'\n ? 'all'\n : new Selection(selection);\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n Collection, DisabledBehavior,\n FocusStrategy,\n Selection as ISelection,\n Key,\n LayoutDelegate,\n LongPressEvent,\n Node,\n PressEvent,\n SelectionBehavior,\n SelectionMode\n} from '@react-types/shared';\nimport {compareNodeOrder, getChildNodes, getFirstItem} from '../collections/getChildNodes';\nimport {MultipleSelectionManager, MultipleSelectionState} from './types';\nimport {Selection} from './Selection';\n\ninterface SelectionManagerOptions {\n allowsCellSelection?: boolean,\n layoutDelegate?: LayoutDelegate,\n fullCollection?: Collection<Node<unknown>>\n}\n\n/**\n * An interface for reading and updating multiple selection state.\n */\nexport class SelectionManager implements MultipleSelectionManager {\n collection: Collection<Node<unknown>>;\n private state: MultipleSelectionState;\n private allowsCellSelection: boolean;\n private _isSelectAll: boolean | null;\n private layoutDelegate: LayoutDelegate | null;\n private fullCollection: Collection<Node<unknown>> | null;\n\n constructor(collection: Collection<Node<unknown>>, state: MultipleSelectionState, options?: SelectionManagerOptions) {\n this.collection = collection;\n this.state = state;\n this.allowsCellSelection = options?.allowsCellSelection ?? false;\n this._isSelectAll = null;\n this.layoutDelegate = options?.layoutDelegate || null;\n this.fullCollection = options?.fullCollection || null;\n }\n\n /**\n * The type of selection that is allowed in the collection.\n */\n get selectionMode(): SelectionMode {\n return this.state.selectionMode;\n }\n\n /**\n * Whether the collection allows empty selection.\n */\n get disallowEmptySelection(): boolean {\n return this.state.disallowEmptySelection;\n }\n\n /**\n * The selection behavior for the collection.\n */\n get selectionBehavior(): SelectionBehavior {\n return this.state.selectionBehavior;\n }\n\n /**\n * Sets the selection behavior for the collection.\n */\n setSelectionBehavior(selectionBehavior: SelectionBehavior): void {\n this.state.setSelectionBehavior(selectionBehavior);\n }\n\n /**\n * Whether the collection is currently focused.\n */\n get isFocused(): boolean {\n return this.state.isFocused;\n }\n\n /**\n * Sets whether the collection is focused.\n */\n setFocused(isFocused: boolean): void {\n this.state.setFocused(isFocused);\n }\n\n /**\n * The current focused key in the collection.\n */\n get focusedKey(): Key | null {\n return this.state.focusedKey;\n }\n\n /** Whether the first or last child of the focused key should receive focus. */\n get childFocusStrategy(): FocusStrategy | null {\n return this.state.childFocusStrategy;\n }\n\n /**\n * Sets the focused key.\n */\n setFocusedKey(key: Key | null, childFocusStrategy?: FocusStrategy): void {\n if (key == null || this.collection.getItem(key)) {\n this.state.setFocusedKey(key, childFocusStrategy);\n }\n }\n\n /**\n * The currently selected keys in the collection.\n */\n get selectedKeys(): Set<Key> {\n return this.state.selectedKeys === 'all'\n ? new Set(this.getSelectAllKeys())\n : this.state.selectedKeys;\n }\n\n /**\n * The raw selection value for the collection.\n * Either 'all' for select all, or a set of keys.\n */\n get rawSelection(): ISelection {\n return this.state.selectedKeys;\n }\n\n /**\n * Returns whether a key is selected.\n */\n isSelected(key: Key): boolean {\n if (this.state.selectionMode === 'none') {\n return false;\n }\n\n let mappedKey = this.getKey(key);\n if (mappedKey == null) {\n return false;\n }\n return this.state.selectedKeys === 'all'\n ? this.canSelectItem(mappedKey)\n : this.state.selectedKeys.has(mappedKey);\n }\n\n /**\n * Whether the selection is empty.\n */\n get isEmpty(): boolean {\n return this.state.selectedKeys !== 'all' && this.state.selectedKeys.size === 0;\n }\n\n /**\n * Whether all items in the collection are selected.\n */\n get isSelectAll(): boolean {\n if (this.isEmpty) {\n return false;\n }\n\n if (this.state.selectedKeys === 'all') {\n return true;\n }\n\n if (this._isSelectAll != null) {\n return this._isSelectAll;\n }\n\n let allKeys = this.getSelectAllKeys();\n let selectedKeys = this.state.selectedKeys;\n this._isSelectAll = allKeys.every(k => selectedKeys.has(k));\n return this._isSelectAll;\n }\n\n get firstSelectedKey(): Key | null {\n let first: Node<unknown> | null = null;\n for (let key of this.state.selectedKeys) {\n let item = this.collection.getItem(key);\n if (!first || (item && compareNodeOrder(this.collection, item, first) < 0)) {\n first = item;\n }\n }\n\n return first?.key ?? null;\n }\n\n get lastSelectedKey(): Key | null {\n let last: Node<unknown> | null = null;\n for (let key of this.state.selectedKeys) {\n let item = this.collection.getItem(key);\n if (!last || (item && compareNodeOrder(this.collection, item, last) > 0)) {\n last = item;\n }\n }\n\n return last?.key ?? null;\n }\n\n get disabledKeys(): Set<Key> {\n return this.state.disabledKeys;\n }\n\n get disabledBehavior(): DisabledBehavior {\n return this.state.disabledBehavior;\n }\n\n /**\n * Extends the selection to the given key.\n */\n extendSelection(toKey: Key): void {\n if (this.selectionMode === 'none') {\n return;\n }\n\n if (this.selectionMode === 'single') {\n this.replaceSelection(toKey);\n return;\n }\n\n let mappedToKey = this.getKey(toKey);\n if (mappedToKey == null) {\n return;\n }\n\n let selection: Selection;\n\n // Only select the one key if coming from a select all.\n if (this.state.selectedKeys === 'all') {\n selection = new Selection([mappedToKey], mappedToKey, mappedToKey);\n } else {\n let selectedKeys = this.state.selectedKeys as Selection;\n let anchorKey = selectedKeys.anchorKey ?? mappedToKey;\n selection = new Selection(selectedKeys, anchorKey, mappedToKey);\n for (let key of this.getKeyRange(anchorKey, selectedKeys.currentKey ?? mappedToKey)) {\n selection.delete(key);\n }\n\n for (let key of this.getKeyRange(mappedToKey, anchorKey)) {\n if (this.canSelectItem(key)) {\n selection.add(key);\n }\n }\n }\n\n this.state.setSelectedKeys(selection);\n }\n\n private getKeyRange(from: Key, to: Key) {\n let fromItem = this.collection.getItem(from);\n let toItem = this.collection.getItem(to);\n if (fromItem && toItem) {\n if (compareNodeOrder(this.collection, fromItem, toItem) <= 0) {\n return this.getKeyRangeInternal(from, to);\n }\n\n return this.getKeyRangeInternal(to, from);\n }\n\n return [];\n }\n\n private getKeyRangeInternal(from: Key, to: Key) {\n if (this.layoutDelegate?.getKeyRange) {\n return this.layoutDelegate.getKeyRange(from, to);\n }\n\n let keys: Key[] = [];\n let key: Key | null = from;\n while (key != null) {\n let item = this.collection.getItem(key);\n if (item && (item.type === 'item' || (item.type === 'cell' && this.allowsCellSelection))) {\n keys.push(key);\n }\n\n if (key === to) {\n return keys;\n }\n\n key = this.collection.getKeyAfter(key);\n }\n\n return [];\n }\n\n private getKey(key: Key) {\n let item = this.collection.getItem(key);\n if (!item) {\n // ¯\\_(ツ)_/¯\n return key;\n }\n\n // If cell selection is allowed, just return the key.\n if (item.type === 'cell' && this.allowsCellSelection) {\n return key;\n }\n\n // Find a parent item to select\n while (item && item.type !== 'item' && item.parentKey != null) {\n item = this.collection.getItem(item.parentKey);\n }\n\n if (!item || item.type !== 'item') {\n return null;\n }\n\n return item.key;\n }\n\n /**\n * Toggles whether the given key is selected.\n */\n toggleSelection(key: Key): void {\n if (this.selectionMode === 'none') {\n return;\n }\n\n if (this.selectionMode === 'single' && !this.isSelected(key)) {\n this.replaceSelection(key);\n return;\n }\n\n let mappedKey = this.getKey(key);\n if (mappedKey == null) {\n return;\n }\n\n let keys = new Selection(this.state.selectedKeys === 'all' ? this.getSelectAllKeys() : this.state.selectedKeys);\n if (keys.has(mappedKey)) {\n keys.delete(mappedKey);\n // TODO: move anchor to last selected key...\n // Does `current` need to move here too?\n } else if (this.canSelectItem(mappedKey)) {\n keys.add(mappedKey);\n keys.anchorKey = mappedKey;\n keys.currentKey = mappedKey;\n }\n\n if (this.disallowEmptySelection && keys.size === 0) {\n return;\n }\n\n this.state.setSelectedKeys(keys);\n }\n\n /**\n * Replaces the selection with only the given key.\n */\n replaceSelection(key: Key): void {\n if (this.selectionMode === 'none') {\n return;\n }\n\n let mappedKey = this.getKey(key);\n if (mappedKey == null) {\n return;\n }\n\n let selection = this.canSelectItem(mappedKey)\n ? new Selection([mappedKey], mappedKey, mappedKey)\n : new Selection();\n\n this.state.setSelectedKeys(selection);\n }\n\n /**\n * Replaces the selection with the given keys.\n */\n setSelectedKeys(keys: Iterable<Key>): void {\n if (this.selectionMode === 'none') {\n return;\n }\n\n let selection = new Selection();\n for (let key of keys) {\n let mappedKey = this.getKey(key);\n if (mappedKey != null) {\n selection.add(mappedKey);\n if (this.selectionMode === 'single') {\n break;\n }\n }\n }\n\n this.state.setSelectedKeys(selection);\n }\n\n private getSelectAllKeys() {\n // Use the full (unfiltered) collection when available so that materializing\n // the 'all' selection includes items that are currently filtered out (e.g. by Autocomplete).\n let collection = this.fullCollection ?? this.collection;\n let keys: Key[] = [];\n let addKeys = (key: Key | null) => {\n while (key != null) {\n if (this.canSelectItemIn(key, collection)) {\n let item = collection.getItem(key);\n if (item?.type === 'item') {\n keys.push(key);\n }\n\n // Add child keys. If cell selection is allowed, then include item children too.\n if (item?.hasChildNodes && (this.allowsCellSelection || item.type !== 'item')) {\n addKeys(getFirstItem(getChildNodes(item, collection))?.key ?? null);\n }\n }\n\n key = collection.getKeyAfter(key);\n }\n };\n\n addKeys(collection.getFirstKey());\n return keys;\n }\n\n /**\n * Selects all items in the collection.\n */\n selectAll(): void {\n if (!this.isSelectAll && this.selectionMode === 'multiple') {\n this.state.setSelectedKeys('all');\n }\n }\n\n /**\n * Removes all keys from the selection.\n */\n clearSelection(): void {\n if (!this.disallowEmptySelection && (this.state.selectedKeys === 'all' || this.state.selectedKeys.size > 0)) {\n this.state.setSelectedKeys(new Selection());\n }\n }\n\n /**\n * Toggles between select all and an empty selection.\n */\n toggleSelectAll(): void {\n if (this.isSelectAll) {\n this.clearSelection();\n } else {\n this.selectAll();\n }\n }\n\n select(key: Key, e?: PressEvent | LongPressEvent | PointerEvent): void {\n if (this.selectionMode === 'none') {\n return;\n }\n\n if (this.selectionMode === 'single') {\n if (this.isSelected(key) && !this.disallowEmptySelection) {\n this.toggleSelection(key);\n } else {\n this.replaceSelection(key);\n }\n } else if (this.selectionBehavior === 'toggle' || (e && (e.pointerType === 'touch' || e.pointerType === 'virtual'))) {\n // if touch or virtual (VO) then we just want to toggle, otherwise it's impossible to multi select because they don't have modifier keys\n this.toggleSelection(key);\n } else {\n this.replaceSelection(key);\n }\n }\n\n /**\n * Returns whether the current selection is equal to the given selection.\n */\n isSelectionEqual(selection: Set<Key>): boolean {\n if (selection === this.state.selectedKeys) {\n return true;\n }\n\n // Check if the set of keys match.\n let selectedKeys = this.selectedKeys;\n if (selection.size !== selectedKeys.size) {\n return false;\n }\n\n for (let key of selection) {\n if (!selectedKeys.has(key)) {\n return false;\n }\n }\n\n for (let key of selectedKeys) {\n if (!selection.has(key)) {\n return false;\n }\n }\n\n return true;\n }\n\n canSelectItem(key: Key): boolean {\n return this.canSelectItemIn(key, this.collection);\n }\n\n private canSelectItemIn(key: Key, collection: Collection<Node<unknown>>): boolean {\n if (this.state.selectionMode === 'none' || this.state.disabledKeys.has(key)) {\n return false;\n }\n\n let item = collection.getItem(key);\n if (!item || item?.props?.isDisabled || (item.type === 'cell' && !this.allowsCellSelection)) {\n return false;\n }\n\n return true;\n }\n\n isDisabled(key: Key): boolean {\n return this.state.disabledBehavior === 'all' && (this.state.disabledKeys.has(key) || !!this.collection.getItem(key)?.props?.isDisabled);\n }\n\n isLink(key: Key): boolean {\n return !!this.collection.getItem(key)?.props?.href;\n }\n\n getItemProps(key: Key): any {\n return this.collection.getItem(key)?.props;\n }\n\n withCollection(collection: Collection<Node<unknown>>): SelectionManager {\n return new SelectionManager(collection, this.state, {\n allowsCellSelection: this.allowsCellSelection,\n layoutDelegate: this.layoutDelegate || undefined,\n fullCollection: this.fullCollection ?? this.collection\n });\n }\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {CollectionBase, CollectionElement, Key, Node} from '@react-types/shared';\nimport {PartialNode} from './types';\nimport React, {ReactElement} from 'react';\n\ninterface CollectionBuilderState {\n renderer?: (value: any) => ReactElement | null\n}\n\ninterface CollectReactElement<T> extends ReactElement {\n getCollectionNode(props: any, context: any): Generator<PartialNode<T>, void, Node<T>[]>\n}\n\nexport class CollectionBuilder<T extends object> {\n private context?: unknown;\n private cache: WeakMap<T, Node<T>> = new WeakMap();\n\n build(props: Partial<CollectionBase<T>>, context?: unknown): Iterable<Node<T>> {\n this.context = context;\n return iterable(() => this.iterateCollection(props));\n }\n\n private *iterateCollection(props: Partial<CollectionBase<T>>): Generator<Node<T>> {\n let {children, items} = props;\n\n if (React.isValidElement<{children: CollectionElement<T>}>(children) && children.type === React.Fragment) {\n yield* this.iterateCollection({\n children: children.props.children,\n items\n });\n } else if (typeof children === 'function') {\n if (!items) {\n throw new Error('props.children was a function but props.items is missing');\n }\n\n let index = 0;\n for (let item of items) {\n yield* this.getFullNode({\n value: item,\n index\n }, {renderer: children});\n index++;\n }\n } else {\n let items: CollectionElement<T>[] = [];\n React.Children.forEach(children, child => {\n if (child) {\n items.push(child);\n }\n });\n\n let index = 0;\n for (let item of items) {\n let nodes = this.getFullNode({\n element: item,\n index: index\n }, {});\n\n for (let node of nodes) {\n index++;\n yield node;\n }\n }\n }\n }\n\n private getKey(item: NonNullable<CollectionElement<T>>, partialNode: PartialNode<T>, state: CollectionBuilderState, parentKey?: Key | null): Key {\n if (item.key != null) {\n return item.key;\n }\n\n if (partialNode.type === 'cell' && partialNode.key != null) {\n return `${parentKey}${partialNode.key}`;\n }\n\n let v = partialNode.value as any;\n if (v != null) {\n let key = v.key ?? v.id;\n if (key == null) {\n throw new Error('No key found for item');\n }\n\n return key;\n }\n\n return parentKey ? `${parentKey}.${partialNode.index}` : `$.${partialNode.index}`;\n }\n\n private getChildState(state: CollectionBuilderState, partialNode: PartialNode<T>) {\n return {\n renderer: partialNode.renderer || state.renderer\n };\n }\n\n private *getFullNode(partialNode: PartialNode<T> & {index: number}, state: CollectionBuilderState, parentKey?: Key | null, parentNode?: Node<T>): Generator<Node<T>> {\n if (React.isValidElement<{children: CollectionElement<T>}>(partialNode.element) && partialNode.element.type === React.Fragment) {\n let children: CollectionElement<T>[] = [];\n\n React.Children.forEach(partialNode.element.props.children, child => {\n children.push(child);\n });\n\n let index = partialNode.index ?? 0;\n\n for (const child of children) {\n yield* this.getFullNode({\n element: child,\n index: index++\n }, state, parentKey, parentNode);\n }\n\n return;\n }\n\n // If there's a value instead of an element on the node, and a parent renderer function is available,\n // use it to render an element for the value.\n let element = partialNode.element;\n if (!element && partialNode.value && state && state.renderer) {\n let cached = this.cache.get(partialNode.value);\n if (cached && (!cached.shouldInvalidate || !cached.shouldInvalidate(this.context))) {\n cached.index = partialNode.index;\n cached.parentKey = parentNode ? parentNode.key : null;\n yield cached;\n return;\n }\n\n element = state.renderer(partialNode.value);\n }\n\n // If there's an element with a getCollectionNode function on its type, then it's a supported component.\n // Call this function to get a partial node, and recursively build a full node from there.\n if (React.isValidElement(element)) {\n let type = element.type as unknown as CollectReactElement<T>;\n if (typeof type !== 'function' && typeof type.getCollectionNode !== 'function') {\n let name = element.type;\n throw new Error(`Unknown element <${name}> in collection.`);\n }\n\n let childNodes = type.getCollectionNode(element.props, this.context) as Generator<PartialNode<T>, void, Node<T>[]>;\n let index = partialNode.index ?? 0;\n let result = childNodes.next();\n while (!result.done && result.value) {\n let childNode = result.value;\n\n partialNode.index = index;\n\n let nodeKey = childNode.key ?? null;\n if (nodeKey == null) {\n nodeKey = childNode.element ? null : this.getKey(element as NonNullable<CollectionElement<T>>, partialNode, state, parentKey);\n }\n\n let nodes = this.getFullNode({\n ...childNode,\n key: nodeKey,\n index,\n wrapper: compose(partialNode.wrapper, childNode.wrapper)\n }, this.getChildState(state, childNode), parentKey ? `${parentKey}${element.key}` : element.key, parentNode);\n\n let children = [...nodes];\n for (let node of children) {\n // Cache the node based on its value\n node.value = childNode.value ?? partialNode.value ?? null;\n if (node.value) {\n this.cache.set(node.value, node);\n }\n\n // The partial node may have specified a type for the child in order to specify a constraint.\n // Verify that the full node that was built recursively matches this type.\n if (partialNode.type && node.type !== partialNode.type) {\n throw new Error(`Unsupported type <${capitalize(node.type)}> in <${capitalize(parentNode?.type ?? 'unknown parent type')}>. Only <${capitalize(partialNode.type)}> is supported.`);\n }\n\n index++;\n yield node;\n }\n\n result = childNodes.next(children);\n }\n\n return;\n }\n\n // Ignore invalid elements\n if (partialNode.key == null || partialNode.type == null) {\n return;\n }\n\n // Create full node\n let builder = this;\n let node: Node<T> = {\n type: partialNode.type,\n props: partialNode.props,\n key: partialNode.key,\n parentKey: parentNode ? parentNode.key : null,\n value: partialNode.value ?? null,\n level: (parentNode?.level ?? 0) + (parentNode?.type === 'item' ? 1 : 0),\n index: partialNode.index,\n rendered: partialNode.rendered,\n textValue: partialNode.textValue ?? '',\n 'aria-label': partialNode['aria-label'],\n wrapper: partialNode.wrapper,\n shouldInvalidate: partialNode.shouldInvalidate,\n hasChildNodes: partialNode.hasChildNodes || false,\n childNodes: iterable(function *() {\n if (!partialNode.hasChildNodes || !partialNode.childNodes) {\n return;\n }\n\n let index = 0;\n for (let child of partialNode.childNodes()) {\n // Ensure child keys are globally unique by prepending the parent node's key\n if (child.key != null) {\n // TODO: Remove this line entirely and enforce that users always provide unique keys.\n // Currently this line will have issues when a parent has a key `a` and a child with key `bc`\n // but another parent has key `ab` and its child has a key `c`. The combined keys would result in both\n // children having a key of `abc`.\n child.key = `${node.key}${child.key}`;\n }\n\n let nodes = builder.getFullNode({...child, index}, builder.getChildState(state, child), node.key, node);\n for (let node of nodes) {\n index++;\n yield node;\n }\n }\n })\n };\n\n yield node;\n }\n}\n\n// Wraps an iterator function as an iterable object, and caches the results.\nfunction iterable<T>(iterator: () => IterableIterator<Node<T>>): Iterable<Node<T>> {\n let cache: Array<Node<T>> = [];\n let iterable: null | IterableIterator<Node<T>> = null;\n return {\n *[Symbol.iterator]() {\n for (let item of cache) {\n yield item;\n }\n\n if (!iterable) {\n iterable = iterator();\n }\n\n for (let item of iterable) {\n cache.push(item);\n yield item;\n }\n }\n };\n}\n\ntype Wrapper = (element: ReactElement) => ReactElement;\nfunction compose(outer: Wrapper | void, inner: Wrapper | void): Wrapper | undefined {\n if (outer && inner) {\n return (element) => outer(inner(element));\n }\n\n if (outer) {\n return outer;\n }\n\n if (inner) {\n return inner;\n }\n}\n\nfunction capitalize(str: string) {\n return str[0].toUpperCase() + str.slice(1);\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, CollectionStateBase, Node} from '@react-types/shared';\nimport {CollectionBuilder} from './CollectionBuilder';\nimport {ReactElement, useMemo} from 'react';\n\ninterface CollectionOptions<T, C extends Collection<Node<T>>> extends Omit<CollectionStateBase<T, C>, 'children'> {\n children?: ReactElement<any> | null | (ReactElement<any> | null)[] | ((item: T) => ReactElement<any> | null)\n}\n\ntype CollectionFactory<T, C extends Collection<Node<T>>> = (node: Iterable<Node<T>>) => C;\n\nexport function useCollection<T extends object, C extends Collection<Node<T>> = Collection<Node<T>>>(props: CollectionOptions<T, C>, factory: CollectionFactory<T, C>, context?: unknown): C {\n let builder = useMemo(() => new CollectionBuilder<T>(), []);\n let {children, items, collection} = props;\n let result = useMemo(() => {\n if (collection) {\n return collection;\n }\n let nodes = builder.build({children, items}, context);\n return factory(nodes);\n }, [builder, children, items, collection, context, factory]);\n return result;\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, CollectionStateBase, Key, LayoutDelegate, Node} from '@react-types/shared';\nimport {ListCollection} from './ListCollection';\nimport {MultipleSelectionStateProps, useMultipleSelectionState} from '../selection/useMultipleSelectionState';\nimport {SelectionManager} from '../selection/SelectionManager';\nimport {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {useCollection} from '../collections/useCollection';\n\nexport interface ListProps<T> extends CollectionStateBase<T>, MultipleSelectionStateProps {\n /** Filter function to generate a filtered list of nodes. */\n filter?: (nodes: Iterable<Node<T>>) => Iterable<Node<T>>,\n /** @private */\n suppressTextValueWarning?: boolean,\n /**\n * A delegate object that provides layout information for items in the collection.\n * This can be used to override the behavior of shift selection.\n */\n layoutDelegate?: LayoutDelegate\n}\n\nexport interface ListState<T> {\n /** A collection of items in the list. */\n collection: Collection<Node<T>>,\n\n /** A set of items that are disabled. */\n disabledKeys: Set<Key>,\n\n /** A selection manager to read and update multiple selection state. */\n selectionManager: SelectionManager\n}\n\n/**\n * Provides state management for list-like components. Handles building a collection\n * of items from props, and manages multiple selection state.\n */\nexport function useListState<T extends object>(props: ListProps<T>): ListState<T> {\n let {filter, layoutDelegate} = props;\n\n let selectionState = useMultipleSelectionState(props);\n let disabledKeys = useMemo(() =>\n props.disabledKeys ? new Set(props.disabledKeys) : new Set<Key>()\n , [props.disabledKeys]);\n\n let factory = useCallback(nodes => filter ? new ListCollection(filter(nodes)) : new ListCollection(nodes as Iterable<Node<T>>), [filter]);\n let context = useMemo(() => ({suppressTextValueWarning: props.suppressTextValueWarning}), [props.suppressTextValueWarning]);\n\n let collection = useCollection(props, factory, context);\n\n let selectionManager = useMemo(() =>\n new SelectionManager(collection, selectionState, {layoutDelegate})\n , [collection, selectionState, layoutDelegate]\n );\n\n useFocusedKeyReset(collection, selectionManager);\n\n return {\n collection,\n disabledKeys,\n selectionManager\n };\n}\n\n/**\n * Filters a collection using the provided filter function and returns a new ListState.\n */\nexport function UNSTABLE_useFilteredListState<T extends object>(state: ListState<T>, filterFn: ((nodeValue: string, node: Node<T>) => boolean) | null | undefined): ListState<T> {\n let collection = useMemo(() => filterFn ? state.collection.filter!(filterFn) : state.collection, [state.collection, filterFn]);\n let selectionManager = state.selectionManager.withCollection(collection);\n useFocusedKeyReset(collection, selectionManager);\n return {\n collection,\n selectionManager,\n disabledKeys: state.disabledKeys\n };\n}\n\nfunction useFocusedKeyReset<T>(collection: Collection<Node<T>>, selectionManager: SelectionManager) {\n // Reset focused key if that item is deleted from the collection.\n const cachedCollection = useRef<Collection<Node<T>> | null>(null);\n useEffect(() => {\n if (selectionManager.focusedKey != null && !collection.getItem(selectionManager.focusedKey) && cachedCollection.current) {\n // Walk forward in the old collection to find the next key that still exists in the new collection.\n let key = cachedCollection.current.getKeyAfter(selectionManager.focusedKey);\n let nextFocusedKey: Key | null = null;\n while (key != null) {\n let node = collection.getItem(key);\n if (node && node.type === 'item' && !selectionManager.isDisabled(key)) {\n nextFocusedKey = key;\n break;\n }\n\n key = cachedCollection.current.getKeyAfter(key);\n }\n\n // If no such key exists, walk backward.\n if (nextFocusedKey == null) {\n key = cachedCollection.current.getKeyBefore(selectionManager.focusedKey);\n while (key != null) {\n let node = collection.getItem(key);\n if (node && node.type === 'item' && !selectionManager.isDisabled(key)) {\n nextFocusedKey = key;\n break;\n }\n\n key = cachedCollection.current.getKeyBefore(key);\n }\n }\n\n selectionManager.setFocusedKey(nextFocusedKey);\n }\n cachedCollection.current = collection;\n }, [collection, selectionManager]);\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {useCallback} from 'react';\nimport {useControlledState} from '../utils/useControlledState';\n\nexport interface OverlayTriggerProps {\n /** Whether the overlay is open by default (controlled). */\n isOpen?: boolean,\n /** Whether the overlay is open by default (uncontrolled). */\n defaultOpen?: boolean,\n /** Handler that is called when the overlay's open state changes. */\n onOpenChange?: (isOpen: boolean) => void\n}\n\nexport interface OverlayTriggerState {\n /** Whether the overlay is currently open. */\n readonly isOpen: boolean,\n /** Sets whether the overlay is open. */\n setOpen(isOpen: boolean): void,\n /** Opens the overlay. */\n open(): void,\n /** Closes the overlay. */\n close(): void,\n /** Toggles the overlay's visibility. */\n toggle(): void\n}\n\n/**\n * Manages state for an overlay trigger. Tracks whether the overlay is open, and provides\n * methods to toggle this state.\n */\nexport function useOverlayTriggerState(props: OverlayTriggerProps): OverlayTriggerState {\n let [isOpen, setOpen] = useControlledState(props.isOpen, props.defaultOpen || false, props.onOpenChange);\n\n const open = useCallback(() => {\n setOpen(true);\n }, [setOpen]);\n\n const close = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n const toggle = useCallback(() => {\n setOpen(!isOpen);\n }, [setOpen, isOpen]);\n\n return {\n isOpen,\n setOpen,\n open,\n close,\n toggle\n };\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {ItemElement, ItemProps} from '@react-types/shared';\nimport {PartialNode} from './types';\nimport React, {JSX, ReactElement} from 'react';\n\nfunction Item<T>(props: ItemProps<T>): ReactElement | null { // eslint-disable-line @typescript-eslint/no-unused-vars\n return null;\n}\n\nItem.getCollectionNode = function* getCollectionNode<T>(props: ItemProps<T>, context: any): Generator<PartialNode<T>> {\n let {childItems, title, children} = props;\n\n let rendered = props.title || props.children;\n let textValue = props.textValue || (typeof rendered === 'string' ? rendered : '') || props['aria-label'] || '';\n\n // suppressTextValueWarning is used in components like Tabs, which don't have type to select support.\n if (!textValue && !context?.suppressTextValueWarning && process.env.NODE_ENV !== 'production') {\n console.warn('<Item> with non-plain text contents is unsupported by type to select for accessibility. Please add a `textValue` prop.');\n }\n\n yield {\n type: 'item',\n props: props,\n rendered,\n textValue,\n 'aria-label': props['aria-label'],\n hasChildNodes: hasChildItems(props),\n *childNodes() {\n if (childItems) {\n for (let child of childItems) {\n yield {\n type: 'item',\n value: child\n };\n }\n } else if (title) {\n let items: PartialNode<T>[] = [];\n React.Children.forEach(children, child => {\n items.push({\n type: 'item',\n element: child as ItemElement<T>\n });\n });\n\n yield* items;\n }\n }\n };\n};\n\nfunction hasChildItems<T>(props: ItemProps<T>) {\n if (props.hasChildItems != null) {\n return props.hasChildItems;\n }\n\n if (props.childItems) {\n return true;\n }\n\n if (props.title && React.Children.count(props.children) > 0) {\n return true;\n }\n\n return false;\n}\n\n// We don't want getCollectionNode to show up in the type definition\nlet _Item = Item as <T>(props: ItemProps<T>) => JSX.Element;\nexport {_Item as Item};\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {CollectionStateBase, Key, Node, Selection, SingleSelection} from '@react-types/shared';\nimport {ListState, useListState} from './useListState';\nimport {useControlledState} from '../utils/useControlledState';\nimport {useMemo} from 'react';\n\nexport interface SingleSelectListProps<T> extends CollectionStateBase<T>, Omit<SingleSelection, 'disallowEmptySelection'> {\n /** Filter function to generate a filtered list of nodes. */\n filter?: (nodes: Iterable<Node<T>>) => Iterable<Node<T>>,\n /** @private */\n suppressTextValueWarning?: boolean\n}\n\nexport interface SingleSelectListState<T> extends ListState<T> {\n /** The key for the currently selected item. */\n readonly selectedKey: Key | null,\n\n /** Sets the selected key. */\n setSelectedKey(key: Key | null): void,\n\n /** The value of the currently selected item. */\n readonly selectedItem: Node<T> | null\n}\n\n/**\n * Provides state management for list-like components with single selection.\n * Handles building a collection of items from props, and manages selection state.\n */\nexport function useSingleSelectListState<T extends object>(props: SingleSelectListProps<T>): SingleSelectListState<T> {\n let [selectedKey, setSelectedKey] = useControlledState(props.selectedKey, props.defaultSelectedKey ?? null, props.onSelectionChange);\n let selectedKeys = useMemo(() => selectedKey != null ? [selectedKey] : [], [selectedKey]);\n let {collection, disabledKeys, selectionManager} = useListState({\n ...props,\n selectionMode: 'single',\n disallowEmptySelection: true,\n allowDuplicateSelectionEvents: true,\n selectedKeys,\n onSelectionChange: (keys: Selection) => {\n // impossible, but TS doesn't know that\n if (keys === 'all') {\n return;\n }\n let key = keys.values().next().value ?? null;\n\n // Always fire onSelectionChange, even if the key is the same\n // as the current key (useControlledState does not).\n if (key === selectedKey && props.onSelectionChange) {\n props.onSelectionChange(key);\n }\n\n setSelectedKey(key);\n }\n });\n\n let selectedItem = selectedKey != null\n ? collection.getItem(selectedKey)\n : null;\n\n return {\n collection,\n disabledKeys,\n selectionManager,\n selectedKey,\n setSelectedKey,\n selectedItem\n };\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {CollectionBase, CollectionStateBase, FocusableProps, FocusStrategy, HelpTextProps, InputBase, Key, LabelableProps, Node, Selection, TextInputBase, Validation, ValueBase} from '@react-types/shared';\nimport {FormValidationState, useFormValidationState} from '../form/useFormValidationState';\nimport {ListState, useListState} from '../list/useListState';\nimport {OverlayTriggerState, useOverlayTriggerState} from '../overlays/useOverlayTriggerState';\nimport {useControlledState} from '../utils/useControlledState';\nimport {useMemo, useState} from 'react';\n\nexport type SelectionMode = 'single' | 'multiple';\nexport type ValueType<M extends SelectionMode> = M extends 'single' ? Key | null : readonly Key[];\nexport type ChangeValueType<M extends SelectionMode> = M extends 'single' ? Key | null : Key[];\ntype ValidationType<M extends SelectionMode> = M extends 'single' ? Key : Key[];\n\nexport interface SelectProps<T, M extends SelectionMode = 'single'> extends CollectionBase<T>, Omit<InputBase, 'isReadOnly'>, ValueBase<ValueType<M>, ChangeValueType<M>>, Validation<ValidationType<M>>, HelpTextProps, LabelableProps, TextInputBase, FocusableProps {\n /**\n * Whether single or multiple selection is enabled.\n * @default 'single'\n */\n selectionMode?: M,\n /**\n * The currently selected key in the collection (controlled).\n * @deprecated\n */\n selectedKey?: Key | null,\n /**\n * The initial selected key in the collection (uncontrolled).\n * @deprecated\n */\n defaultSelectedKey?: Key | null,\n /**\n * Handler that is called when the selection changes.\n * @deprecated\n */\n onSelectionChange?: (key: Key | null) => void,\n /** Sets the open state of the menu. */\n isOpen?: boolean,\n /** Sets the default open state of the menu. */\n defaultOpen?: boolean,\n /** Method that is called when the open state of the menu changes. */\n onOpenChange?: (isOpen: boolean) => void,\n /** Whether the Select should close when an item is selected. Defaults to true if selectionMode is single, false otherwise. */\n shouldCloseOnSelect?: boolean,\n /** Whether the select should be allowed to be open when the collection is empty. */\n allowsEmptyCollection?: boolean\n}\n\nexport interface SelectStateOptions<T, M extends SelectionMode = 'single'> extends Omit<SelectProps<T, M>, 'children'>, CollectionStateBase<T> {}\n\nexport interface SelectState<T, M extends SelectionMode = 'single'> extends ListState<T>, OverlayTriggerState, FormValidationState {\n /**\n * The key for the first selected item.\n * @deprecated\n */\n readonly selectedKey: Key | null,\n\n /**\n * The default selected key.\n * @deprecated\n */\n readonly defaultSelectedKey: Key | null,\n\n /**\n * Sets the selected key.\n * @deprecated\n */\n setSelectedKey(key: Key | null): void,\n\n /** The current select value. */\n readonly value: ValueType<M>,\n\n /** The default select value. */\n readonly defaultValue: ValueType<M>,\n\n /** Sets the select value. */\n setValue(value: Key | readonly Key[] | null): void,\n\n /**\n * The value of the first selected item.\n * @deprecated\n */\n readonly selectedItem: Node<T> | null,\n\n /** The value of the selected items. */\n readonly selectedItems: Node<T>[],\n\n /** Whether the select is currently focused. */\n readonly isFocused: boolean,\n\n /** Sets whether the select is focused. */\n setFocused(isFocused: boolean): void,\n\n /** Controls which item will be auto focused when the menu opens. */\n readonly focusStrategy: FocusStrategy | null,\n\n /** Opens the menu. */\n open(focusStrategy?: FocusStrategy | null): void,\n\n /** Toggles the menu. */\n toggle(focusStrategy?: FocusStrategy | null): void\n}\n\n/**\n * Provides state management for a select component. Handles building a collection\n * of items from props, handles the open state for the popup menu, and manages\n * multiple selection state.\n */\nexport function useSelectState<T extends object, M extends SelectionMode = 'single'>(props: SelectStateOptions<T, M>): SelectState<T, M> {\n let {\n selectionMode = 'single' as M,\n shouldCloseOnSelect = selectionMode === 'single'\n } = props;\n let triggerState = useOverlayTriggerState(props);\n let [focusStrategy, setFocusStrategy] = useState<FocusStrategy | null>(null);\n let defaultValue = useMemo(() => {\n return props.defaultValue !== undefined ? props.defaultValue : (selectionMode === 'single' ? props.defaultSelectedKey ?? null : []) as ValueType<M>;\n }, [props.defaultValue, props.defaultSelectedKey, selectionMode]);\n let value = useMemo(() => {\n return props.value !== undefined ? props.value : (selectionMode === 'single' ? props.selectedKey : undefined) as ValueType<M>;\n }, [props.value, props.selectedKey, selectionMode]);\n let [controlledValue, setControlledValue] = useControlledState<Key | readonly Key[] | null>(value, defaultValue, props.onChange as any);\n // Only display the first selected item if in single selection mode but the value is an array.\n let displayValue = selectionMode === 'single' && Array.isArray(controlledValue) ? controlledValue[0] : controlledValue;\n let setValue = (value: Key | Key[] | null) => {\n if (selectionMode === 'single') {\n let key = Array.isArray(value) ? value[0] ?? null : value;\n setControlledValue(key);\n if (key !== displayValue) {\n props.onSelectionChange?.(key);\n }\n } else {\n let keys: Key[] = [];\n if (Array.isArray(value)) {\n keys = value;\n } else if (value != null) {\n keys = [value];\n }\n\n setControlledValue(keys);\n }\n };\n\n let listState = useListState({\n ...props,\n selectionMode,\n disallowEmptySelection: selectionMode === 'single',\n allowDuplicateSelectionEvents: true,\n selectedKeys: useMemo(() => convertValue(displayValue), [displayValue]),\n onSelectionChange: (keys: Selection) => {\n // impossible, but TS doesn't know that\n if (keys === 'all') {\n return;\n }\n\n if (selectionMode === 'single') {\n let key = keys.values().next().value ?? null;\n setValue(key);\n } else {\n setValue([...keys]);\n }\n if (shouldCloseOnSelect) {\n triggerState.close();\n }\n\n validationState.commitValidation();\n }\n });\n\n let selectedKey = listState.selectionManager.firstSelectedKey;\n let selectedItems = useMemo(() => {\n return [...listState.selectionManager.selectedKeys].map(key => listState.collection.getItem(key)).filter(item => item != null);\n }, [listState.selectionManager.selectedKeys, listState.collection]);\n\n let validationState = useFormValidationState({\n ...props,\n value: Array.isArray(displayValue) && displayValue.length === 0 ? null : displayValue as any\n });\n\n let [isFocused, setFocused] = useState(false);\n let [initialValue] = useState(displayValue);\n\n return {\n ...validationState,\n ...listState,\n ...triggerState,\n value: displayValue as ValueType<M>,\n defaultValue: defaultValue ?? initialValue as ValueType<M>,\n setValue,\n selectedKey,\n setSelectedKey: setValue,\n selectedItem: selectedItems[0] ?? null,\n selectedItems,\n defaultSelectedKey: props.defaultSelectedKey ?? (props.selectionMode === 'single' ? initialValue as Key : null),\n focusStrategy,\n open(focusStrategy: FocusStrategy | null = null) {\n // Don't open if the collection is empty.\n if (listState.collection.size !== 0 || props.allowsEmptyCollection) {\n setFocusStrategy(focusStrategy);\n triggerState.open();\n }\n },\n toggle(focusStrategy: FocusStrategy | null = null) {\n if (listState.collection.size !== 0 || props.allowsEmptyCollection) {\n setFocusStrategy(focusStrategy);\n triggerState.toggle();\n }\n },\n isFocused,\n setFocused\n };\n}\n\nfunction convertValue(value: Key | Key[] | null | undefined) {\n if (value === undefined) {\n return undefined;\n }\n if (value === null) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, CollectionBase, CollectionStateBase, Key, Node, SingleSelection} from '@react-types/shared';\nimport {SingleSelectListState, useSingleSelectListState} from '../list/useSingleSelectListState';\nimport {useEffect, useRef} from 'react';\n\nexport interface TabListProps<T> extends CollectionBase<T>, Omit<SingleSelection, 'disallowEmptySelection' | 'selectedKey' | 'defaultSelectedKey' | 'onSelectionChange'> {\n /**\n * Whether the TabList is disabled.\n * Shows that a selection exists, but is not available in that circumstance.\n */\n isDisabled?: boolean,\n /** The currently selected key in the collection (controlled). */\n selectedKey?: Key,\n /** The initial selected keys in the collection (uncontrolled). */\n defaultSelectedKey?: Key,\n /** Handler that is called when the selection changes. */\n onSelectionChange?: (key: Key) => void\n}\n\nexport interface TabListStateOptions<T> extends Omit<TabListProps<T>, 'children'>, CollectionStateBase<T> {}\n\nexport interface TabListState<T> extends SingleSelectListState<T> {\n /** Whether the tab list is disabled. */\n isDisabled: boolean\n}\n\n/**\n * Provides state management for a Tabs component. Tabs include a TabList which tracks\n * which tab is currently selected and displays the content associated with that Tab in a TabPanel.\n */\nexport function useTabListState<T extends object>(props: TabListStateOptions<T>): TabListState<T> {\n let state = useSingleSelectListState<T>({\n ...props,\n onSelectionChange: props.onSelectionChange ? (key => {\n if (key != null) {\n props.onSelectionChange?.(key);\n }\n }) : undefined,\n suppressTextValueWarning: true,\n defaultSelectedKey: props.defaultSelectedKey ?? findDefaultSelectedKey(props.collection, props.disabledKeys ? new Set(props.disabledKeys) : new Set()) ?? undefined\n });\n\n let {\n selectionManager,\n collection,\n selectedKey: currentSelectedKey\n } = state;\n\n let lastSelectedKey = useRef(currentSelectedKey);\n useEffect(() => {\n // Ensure a tab is always selected (in case no selected key was specified or if selected item was deleted from collection)\n let selectedKey = currentSelectedKey;\n if (props.selectedKey == null && (selectionManager.isEmpty || selectedKey == null || !collection.getItem(selectedKey))) {\n selectedKey = findDefaultSelectedKey(collection, state.disabledKeys);\n if (selectedKey != null) {\n // directly set selection because replace/toggle selection won't consider disabled keys\n selectionManager.setSelectedKeys([selectedKey]);\n }\n }\n\n // If the tablist doesn't have focus and the selected key changes or if there isn't a focused key yet, change focused key to the selected key if it exists.\n if (selectedKey != null && selectionManager.focusedKey == null || (!selectionManager.isFocused && selectedKey !== lastSelectedKey.current)) {\n selectionManager.setFocusedKey(selectedKey);\n }\n lastSelectedKey.current = selectedKey;\n });\n\n return {\n ...state,\n isDisabled: props.isDisabled || false\n };\n}\n\nfunction findDefaultSelectedKey<T>(collection: Collection<Node<T>> | undefined, disabledKeys: Set<Key>) {\n let selectedKey: Key | null = null;\n if (collection) {\n selectedKey = collection.getFirstKey();\n // loop over tabs until we find one that isn't disabled and select that\n while (selectedKey != null && (disabledKeys.has(selectedKey) || collection.getItem(selectedKey)?.props?.isDisabled) && selectedKey !== collection.getLastKey()) {\n selectedKey = collection.getKeyAfter(selectedKey);\n }\n // if this check is true, then every item is disabled, it makes more sense to default to the first key than the last\n if (selectedKey != null && (disabledKeys.has(selectedKey) || collection.getItem(selectedKey)?.props?.isDisabled) && selectedKey === collection.getLastKey()) {\n selectedKey = collection.getFirstKey();\n }\n }\n\n return selectedKey;\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {FocusableProps, InputBase, Validation} from '@react-types/shared';\nimport {ReactNode, useState} from 'react';\nimport {useControlledState} from '../utils/useControlledState';\n\nexport interface ToggleStateOptions extends InputBase {\n /**\n * Whether the element should be selected (uncontrolled).\n */\n defaultSelected?: boolean,\n /**\n * Whether the element should be selected (controlled).\n */\n isSelected?: boolean,\n /**\n * Handler that is called when the element's selection state changes.\n */\n onChange?: (isSelected: boolean) => void\n}\n\nexport interface ToggleProps extends ToggleStateOptions, Validation<boolean>, FocusableProps {\n /**\n * The label for the element.\n */\n children?: ReactNode,\n /**\n * The value of the input element, used when submitting an HTML form. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefvalue).\n */\n value?: string\n}\n\nexport interface ToggleState {\n /** Whether the toggle is selected. */\n readonly isSelected: boolean,\n\n /** Whether the toggle is selected by default. */\n readonly defaultSelected: boolean,\n\n /** Updates selection state. */\n setSelected(isSelected: boolean): void,\n\n /** Toggle the selection state. */\n toggle(): void\n}\n\n/**\n * Provides state management for toggle components like checkboxes and switches.\n */\nexport function useToggleState(props: ToggleStateOptions = {}): ToggleState {\n let {isReadOnly} = props;\n\n // have to provide an empty function so useControlledState doesn't throw a fit\n // can't use useControlledState's prop calling because we need the event object from the change\n let [isSelected, setSelected] = useControlledState(props.isSelected, props.defaultSelected || false, props.onChange);\n let [initialValue] = useState(isSelected);\n\n function updateSelected(value) {\n if (!isReadOnly) {\n setSelected(value);\n }\n }\n\n function toggleState() {\n if (!isReadOnly) {\n setSelected(!isSelected);\n }\n }\n\n return {\n isSelected,\n defaultSelected: props.defaultSelected ?? initialValue,\n setSelected: updateSelected,\n toggle: toggleState\n };\n}\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {OverlayTriggerProps, useOverlayTriggerState} from '../overlays/useOverlayTriggerState';\nimport {useEffect, useMemo, useRef} from 'react';\n\nexport interface TooltipTriggerProps extends OverlayTriggerProps {\n /**\n * Whether the tooltip should be disabled, independent from the trigger.\n */\n isDisabled?: boolean,\n\n /**\n * The delay time for the tooltip to show up. [See guidelines](https://spectrum.adobe.com/page/tooltip/#Immediate-or-delayed-appearance).\n * @default 1500\n */\n delay?: number,\n\n /**\n * The delay time for the tooltip to close. [See guidelines](https://spectrum.adobe.com/page/tooltip/#Warmup-and-cooldown).\n * @default 500\n */\n closeDelay?: number,\n\n /**\n * By default, opens for both focus and hover. Can be made to open only for focus.\n * @default 'hover'\n */\n trigger?: 'hover' | 'focus',\n\n /**\n * Whether the tooltip should close when the trigger is pressed.\n * @default true\n */\n shouldCloseOnPress?: boolean\n}\n\nconst TOOLTIP_DELAY = 1500; // this seems to be a 1.5 second delay, check with design\nconst TOOLTIP_COOLDOWN = 500;\n\nexport interface TooltipTriggerState {\n /** Whether the tooltip is currently showing. */\n isOpen: boolean,\n /**\n * Shows the tooltip. By default, the tooltip becomes visible after a delay\n * depending on a global warmup timer. The `immediate` option shows the\n * tooltip immediately instead.\n */\n open(immediate?: boolean): void,\n /** Hides the tooltip. */\n close(immediate?: boolean): void\n}\n\nlet tooltips = {};\nlet tooltipId = 0;\nlet globalWarmedUp = false;\nlet globalWarmUpTimeout: ReturnType<typeof setTimeout> | null = null;\nlet globalCooldownTimeout: ReturnType<typeof setTimeout> | null = null;\n\n/**\n * Manages state for a tooltip trigger. Tracks whether the tooltip is open, and provides\n * methods to toggle this state. Ensures only one tooltip is open at a time and controls\n * the delay for showing a tooltip.\n */\nexport function useTooltipTriggerState(props: TooltipTriggerProps = {}): TooltipTriggerState {\n let {delay = TOOLTIP_DELAY, closeDelay = TOOLTIP_COOLDOWN} = props;\n let {isOpen, open, close} = useOverlayTriggerState(props);\n let id = useMemo(() => `${++tooltipId}`, []);\n let closeTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n let closeCallback = useRef<() => void>(close);\n\n let ensureTooltipEntry = () => {\n tooltips[id] = hideTooltip;\n };\n\n let closeOpenTooltips = () => {\n for (let hideTooltipId in tooltips) {\n if (hideTooltipId !== id) {\n tooltips[hideTooltipId](true);\n delete tooltips[hideTooltipId];\n }\n }\n };\n\n let showTooltip = () => {\n if (closeTimeout.current) {\n clearTimeout(closeTimeout.current);\n }\n closeTimeout.current = null;\n closeOpenTooltips();\n ensureTooltipEntry();\n globalWarmedUp = true;\n open();\n if (globalWarmUpTimeout) {\n clearTimeout(globalWarmUpTimeout);\n globalWarmUpTimeout = null;\n }\n if (globalCooldownTimeout) {\n clearTimeout(globalCooldownTimeout);\n globalCooldownTimeout = null;\n }\n };\n\n let hideTooltip = (immediate?: boolean) => {\n if (immediate || closeDelay <= 0) {\n if (closeTimeout.current) {\n clearTimeout(closeTimeout.current);\n }\n closeTimeout.current = null;\n closeCallback.current();\n } else if (!closeTimeout.current) {\n closeTimeout.current = setTimeout(() => {\n closeTimeout.current = null;\n closeCallback.current();\n }, closeDelay);\n }\n\n if (globalWarmUpTimeout) {\n clearTimeout(globalWarmUpTimeout);\n globalWarmUpTimeout = null;\n }\n if (globalWarmedUp) {\n if (globalCooldownTimeout) {\n clearTimeout(globalCooldownTimeout);\n }\n globalCooldownTimeout = setTimeout(() => {\n delete tooltips[id];\n globalCooldownTimeout = null;\n globalWarmedUp = false;\n }, Math.max(TOOLTIP_COOLDOWN, closeDelay));\n }\n };\n\n let warmupTooltip = () => {\n closeOpenTooltips();\n ensureTooltipEntry();\n if (!isOpen && !globalWarmedUp) {\n if (globalWarmUpTimeout) {\n clearTimeout(globalWarmUpTimeout);\n }\n\n globalWarmUpTimeout = setTimeout(() => {\n globalWarmUpTimeout = null;\n globalWarmedUp = true;\n showTooltip();\n }, delay);\n } else if (!isOpen) {\n showTooltip();\n }\n };\n\n useEffect(() => {\n closeCallback.current = close;\n }, [close]);\n\n\n useEffect(() => {\n return () => {\n if (closeTimeout.current) {\n clearTimeout(closeTimeout.current);\n }\n let tooltip = tooltips[id];\n if (tooltip) {\n delete tooltips[id];\n }\n };\n }, [id]);\n\n return {\n isOpen,\n open: (immediate) => {\n if (!immediate && delay > 0 && !closeTimeout.current) {\n warmupTooltip();\n } else {\n showTooltip();\n }\n },\n close: hideTooltip\n };\n}\n","\"use client\";\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useCallback,\n useId,\n} from \"react\";\nimport { AddIcon, SubtractIcon } from \"@octaviaflow/icons\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type NumberInputSize = \"sm\" | \"md\" | \"lg\";\n\n/** Native `<input>` props minus the ones the component owns. We also drop\n * the native `size` attribute because we redefine `size` as the visual\n * variant (\"sm\" | \"md\" | \"lg\"). */\ntype InputPropsBase = Omit<\n ComponentPropsWithoutRef<\"input\">,\n | \"type\"\n | \"value\"\n | \"onChange\"\n | \"min\"\n | \"max\"\n | \"step\"\n | \"size\"\n | \"prefix\"\n>;\n\nexport interface NumberInputProps extends InputPropsBase {\n label?: ReactNode;\n value: number;\n onChange?: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n prefix?: ReactNode;\n suffix?: ReactNode;\n size?: NumberInputSize;\n disabled?: boolean;\n error?: ReactNode;\n helperText?: ReactNode;\n /** Extra class on the wrapper (NOT the input — use `inputClassName` for\n * the underlying control's class). */\n wrapperClassName?: string;\n /** Hide the +/- stepper buttons — renders a plain numeric field. The\n * value can still be typed; native number-input arrow keys still work. */\n hideControls?: boolean;\n /** Horizontal alignment of the value. Defaults to \"center\" (the\n * stepper-flanked style); use \"left\" for a standard form-field look.\n * Implied when `hideControls` is set unless overridden. */\n align?: \"left\" | \"center\";\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(\n function NumberInput(\n {\n label,\n value,\n onChange,\n min,\n max,\n step = 1,\n prefix,\n suffix,\n size = \"md\",\n disabled = false,\n error,\n helperText,\n id: providedId,\n className,\n wrapperClassName,\n hideControls = false,\n align,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": consumerDescribedBy,\n ...rest\n },\n ref,\n ) {\n // When the steppers are hidden the field reads like a normal form\n // input, so default the value to left-aligned unless the consumer\n // explicitly asked for centre.\n const resolvedAlign = align ?? (hideControls ? \"left\" : \"center\");\n const reactId = useId();\n const inputId = providedId ?? `ods-num-${reactId}`;\n const labelId = label ? `${inputId}-label` : undefined;\n const hintId = error || helperText ? `${inputId}-hint` : undefined;\n\n const clamp = useCallback(\n (v: number) => {\n if (typeof min === \"number\") v = Math.max(min, v);\n if (typeof max === \"number\") v = Math.min(max, v);\n return v;\n },\n [min, max],\n );\n\n const dec = () => !disabled && onChange?.(clamp(value - step));\n const inc = () => !disabled && onChange?.(clamp(value + step));\n const handleInput = (e: ChangeEvent<HTMLInputElement>) => {\n // Empty string is a valid transient state while the user is typing\n // (e.g. erasing to retype) — preserve it via NaN so the caller can\n // decide whether to coerce. For a controlled component callers\n // typically just hold their last numeric value.\n const raw = e.target.value;\n if (raw === \"\") return;\n const num = Number(raw);\n if (!Number.isNaN(num)) onChange?.(clamp(num));\n };\n\n // Compose aria-describedby: consumer's value wins on conflict, then\n // our hint id is appended. Filter out empties to keep the attribute\n // tidy when nothing applies.\n const describedBy =\n [consumerDescribedBy, hintId].filter(Boolean).join(\" \") || undefined;\n\n return (\n <div\n className={cn(\n \"ods-num\",\n `ods-num--${size}`,\n disabled && \"ods-num--disabled\",\n error && \"ods-num--error\",\n hideControls && \"ods-num--no-controls\",\n resolvedAlign === \"left\" && \"ods-num--align-left\",\n wrapperClassName,\n )}\n >\n {label && (\n <label\n id={labelId}\n htmlFor={inputId}\n className=\"ods-num__label\"\n >\n {label}\n </label>\n )}\n <div className=\"ods-num__field\">\n {!hideControls && (\n <button\n type=\"button\"\n className=\"ods-num__step ods-num__step--dec\"\n onClick={dec}\n disabled={disabled || (typeof min === \"number\" && value <= min)}\n aria-label=\"Decrease\"\n tabIndex={-1}\n >\n <SubtractIcon />\n </button>\n )}\n {prefix && (\n <span className=\"ods-num__prefix\" aria-hidden=\"true\">\n {prefix}\n </span>\n )}\n <input\n {...rest}\n ref={ref}\n id={inputId}\n type=\"number\"\n className={cn(\"ods-num__input\", className)}\n value={Number.isFinite(value) ? value : \"\"}\n onChange={handleInput}\n disabled={disabled}\n min={min}\n max={max}\n step={step}\n aria-invalid={error ? true : undefined}\n aria-describedby={describedBy}\n // Accessible-name fallback chain: an explicit aria-labelledby\n // or aria-label always wins. Otherwise we fall back to the\n // visible <label> when one was rendered.\n aria-labelledby={ariaLabelledBy ?? labelId}\n aria-label={\n !labelId && !ariaLabelledBy ? ariaLabel : undefined\n }\n />\n {suffix && (\n <span className=\"ods-num__suffix\" aria-hidden=\"true\">\n {suffix}\n </span>\n )}\n {!hideControls && (\n <button\n type=\"button\"\n className=\"ods-num__step ods-num__step--inc\"\n onClick={inc}\n disabled={disabled || (typeof max === \"number\" && value >= max)}\n aria-label=\"Increase\"\n tabIndex={-1}\n >\n <AddIcon />\n </button>\n )}\n </div>\n {error ? (\n <div\n id={hintId}\n className=\"ods-num__hint ods-num__hint--error\"\n role=\"alert\"\n >\n {error}\n </div>\n ) : helperText ? (\n <div id={hintId} className=\"ods-num__hint\">\n {helperText}\n </div>\n ) : null}\n </div>\n );\n },\n);\n\nNumberInput.displayName = \"NumberInput\";\n","\"use client\";\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useId,\n useState,\n} from \"react\";\nimport { CheckmarkIcon, ViewIcon, ViewOffIcon } from \"@octaviaflow/icons\";\nimport {\n type PasswordRule,\n type PasswordStrengthScore,\n usePasswordStrength,\n} from \"../../hooks/usePasswordStrength\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type PasswordInputSize = \"sm\" | \"md\" | \"lg\";\n\ntype InputPropsBase = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"type\" | \"size\" | \"value\" | \"onChange\" | \"prefix\"\n>;\n\nexport interface PasswordInputProps extends InputPropsBase {\n label?: ReactNode;\n value: string;\n onChange?: (value: string) => void;\n size?: PasswordInputSize;\n error?: ReactNode;\n helperText?: ReactNode;\n /** 0–4 strength score. When set, renders the visual strength meter.\n * `strength` takes precedence over `strengthRules` so consumers can\n * always override what the rules computed (e.g. server-derived score). */\n strength?: PasswordStrengthScore;\n /** Rule set to evaluate the password against. When provided (and\n * `strength` is NOT), the component runs `usePasswordStrength`\n * internally and renders the meter from the derived score. */\n strengthRules?: PasswordRule[];\n /** Render the requirements checklist below the meter. Each rule shows\n * a met/unmet glyph + its label, and the list is wired via\n * `aria-describedby` so screen readers announce the state. */\n showRequirements?: boolean;\n /** Show the show/hide-password toggle. Default true. */\n showToggle?: boolean;\n leftIcon?: ReactNode;\n /** Extra class on the wrapper (NOT the input). */\n wrapperClassName?: string;\n}\n\nconst strengthLabels = [\n \"Very weak\",\n \"Weak\",\n \"Fair\",\n \"Strong\",\n \"Very strong\",\n] as const;\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const PasswordInput = forwardRef<HTMLInputElement, PasswordInputProps>(\n function PasswordInput(\n {\n label,\n value,\n onChange,\n size = \"md\",\n error,\n helperText,\n strength,\n strengthRules,\n showRequirements = false,\n showToggle = true,\n leftIcon,\n disabled,\n id: providedId,\n className,\n wrapperClassName,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": consumerDescribedBy,\n ...rest\n },\n ref,\n ) {\n const reactId = useId();\n const inputId = providedId ?? `ods-pwd-${reactId}`;\n const labelId = label ? `${inputId}-label` : undefined;\n const hintId = error || helperText ? `${inputId}-hint` : undefined;\n // strengthId is rendered only when the meter is actually displayed.\n // We resolve `effectiveScore` below; the id is built upfront so the\n // memoization order stays stable, and we strip it from describedBy\n // when there's nothing to describe.\n\n const [shown, setShown] = useState(false);\n const handle = (e: ChangeEvent<HTMLInputElement>) =>\n onChange?.(e.target.value);\n\n // Hook ALWAYS runs — pass an empty rule list when the consumer didn't\n // configure one to keep the call cheap. Manual `strength` wins over\n // the derived score so server-side / app-side computations override\n // the local heuristic. The meter renders whenever EITHER the manual\n // score or a non-empty rule set is provided.\n const derived = usePasswordStrength(value, strengthRules ?? []);\n const ruleDriven = (strengthRules?.length ?? 0) > 0;\n const effectiveScore: PasswordStrengthScore | undefined =\n typeof strength === \"number\"\n ? strength\n : ruleDriven\n ? derived.score\n : undefined;\n const strengthId =\n typeof effectiveScore === \"number\" ? `${inputId}-strength` : undefined;\n const requirementsId =\n showRequirements && ruleDriven ? `${inputId}-requirements` : undefined;\n\n // Compose aria-describedby — consumer's value wins, then our hint id,\n // then the strength meter so AT users hear \"Weak / Strong / …\", then\n // the requirements checklist so they hear \"3 of 4 met\".\n const describedBy =\n [consumerDescribedBy, hintId, strengthId, requirementsId]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n return (\n <div\n className={cn(\n \"ods-pwd\",\n `ods-pwd--${size}`,\n disabled && \"ods-pwd--disabled\",\n error && \"ods-pwd--error\",\n wrapperClassName,\n )}\n >\n {label && (\n <label\n id={labelId}\n htmlFor={inputId}\n className=\"ods-pwd__label\"\n >\n {label}\n </label>\n )}\n <div className=\"ods-pwd__field\">\n {leftIcon && (\n <span className=\"ods-pwd__icon\" aria-hidden=\"true\">\n {leftIcon}\n </span>\n )}\n <input\n {...rest}\n ref={ref}\n id={inputId}\n type={shown ? \"text\" : \"password\"}\n value={value}\n onChange={handle}\n disabled={disabled}\n className={cn(\"ods-pwd__input\", className)}\n aria-invalid={error ? true : undefined}\n aria-describedby={describedBy}\n aria-labelledby={ariaLabelledBy ?? labelId}\n aria-label={\n !labelId && !ariaLabelledBy ? ariaLabel : undefined\n }\n />\n {showToggle && (\n <button\n type=\"button\"\n className=\"ods-pwd__toggle\"\n onClick={() => setShown((s) => !s)}\n aria-label={shown ? \"Hide password\" : \"Show password\"}\n aria-pressed={shown}\n disabled={disabled}\n tabIndex={-1}\n >\n {shown ? <ViewOffIcon /> : <ViewIcon />}\n </button>\n )}\n </div>\n {typeof effectiveScore === \"number\" && (\n <div\n id={strengthId}\n className=\"ods-pwd__strength\"\n data-level={effectiveScore}\n >\n <span className=\"ods-pwd__meter\" aria-hidden=\"true\">\n <span\n className={cn(\n \"ods-pwd__bar\",\n `ods-pwd__bar--${effectiveScore}`,\n )}\n />\n </span>\n <span className=\"ods-pwd__strength-label\">\n {strengthLabels[effectiveScore]}\n </span>\n </div>\n )}\n {showRequirements && ruleDriven && (\n // The checklist is decorative for sighted users + announced via\n // `aria-describedby` for AT. Each <li>'s `aria-label` encodes\n // state inline so screen readers say \"At least 8 characters,\n // met\" without any visible SR-only span — bullet-proof across\n // CSS reset variations and stale build artifacts.\n <ul\n id={requirementsId}\n className=\"ods-pwd__requirements\"\n aria-label={`Password requirements (${derived.passed} of ${derived.total} met)`}\n >\n {derived.rules.map((r) => (\n <li\n key={r.id}\n className={cn(\n \"ods-pwd__requirement\",\n r.passed && \"ods-pwd__requirement--met\",\n )}\n aria-label={`${r.label}, ${r.passed ? \"met\" : \"not met\"}`}\n >\n {/* Custom dot+check morph — the dot is a CSS-drawn 14-px\n * circle so we don't fight an icon's intrinsic sizing,\n * and the check fades + scales in on state flip for a\n * crisp micro-interaction. `prefers-reduced-motion`\n * drops the transitions in SCSS. */}\n <span\n className=\"ods-pwd__requirement-dot\"\n aria-hidden=\"true\"\n >\n <CheckmarkIcon\n size=\"xs\"\n tone=\"inverse\"\n className=\"ods-pwd__requirement-check\"\n />\n </span>\n <span className=\"ods-pwd__requirement-label\">{r.label}</span>\n </li>\n ))}\n </ul>\n )}\n {error ? (\n <div\n id={hintId}\n className=\"ods-pwd__hint ods-pwd__hint--error\"\n role=\"alert\"\n >\n {error}\n </div>\n ) : helperText ? (\n <div id={hintId} className=\"ods-pwd__hint\">\n {helperText}\n </div>\n ) : null}\n </div>\n );\n },\n);\n\nPasswordInput.displayName = \"PasswordInput\";\n","\"use client\";\nimport { useMemo } from \"react\";\n\n/* ---------------------------------------------------------------------------\n * usePasswordStrength — declarative password-rule evaluation\n *\n * Evaluates a password value against an ordered list of rules and returns a\n * 0–4 score plus per-rule pass/fail metadata. The score is ratio-based so\n * it stays sensible regardless of how many rules the consumer configures\n * (a 4-of-4 rule set and an 8-of-8 rule set both top out at score 4).\n *\n * const { score, rules, passed, total, isValid } = usePasswordStrength(\n * value,\n * [\n * { id: \"len\", label: \"At least 8 chars\", test: /.{8,}/ },\n * { id: \"low\", label: \"A lower-case letter\", test: /[a-z]/ },\n * { id: \"up\", label: \"An upper-case letter\", test: /[A-Z]/ },\n * { id: \"num\", label: \"A digit\", test: /\\d/ },\n * ],\n * );\n *\n * Defaults: when `rules` is omitted, `DEFAULT_PASSWORD_RULES` is used\n * (4 rules: length-8, lower, upper, digit). Pass an empty array to\n * disable all rules (score will always be 0).\n * ------------------------------------------------------------------------- */\n\nexport interface PasswordRule {\n /** Stable id — keyed in the result for React rendering and useful for\n * driving per-rule a11y associations. */\n id: string;\n /** Human-readable description (\"At least 8 characters\"). Surfaced in\n * the PasswordInput requirements checklist. */\n label: string;\n /** Regex (preferred) or predicate function. Regexes are tested with\n * `.test(value)`; predicates receive the raw value. */\n test: RegExp | ((value: string) => boolean);\n}\n\nexport interface PasswordRuleResult {\n id: string;\n label: string;\n passed: boolean;\n}\n\nexport type PasswordStrengthScore = 0 | 1 | 2 | 3 | 4;\n\nexport interface PasswordStrengthResult {\n /** 0–4, derived from `passed / total` (ratio-scaled). 0 = very weak,\n * 4 = very strong. */\n score: PasswordStrengthScore;\n /** Per-rule pass/fail in the order rules were supplied. */\n rules: PasswordRuleResult[];\n /** Count of rules that passed. */\n passed: number;\n /** Total rules evaluated. */\n total: number;\n /** True iff every rule passed (or the rule set is empty — vacuously\n * satisfied; consumers should usually require a non-empty rule set). */\n isValid: boolean;\n}\n\n/* ---------------------------------------------------------------------------\n * Defaults\n * ------------------------------------------------------------------------- */\n\n/** Reasonable starter rule set — 8-char minimum + character-class diversity.\n * Consumers should override for any compliance regime (passphrases,\n * banking, etc.). */\nexport const DEFAULT_PASSWORD_RULES: PasswordRule[] = [\n { id: \"length-8\", label: \"At least 8 characters\", test: /.{8,}/ },\n { id: \"lowercase\", label: \"A lower-case letter\", test: /[a-z]/ },\n { id: \"uppercase\", label: \"An upper-case letter\", test: /[A-Z]/ },\n { id: \"digit\", label: \"A digit\", test: /\\d/ },\n];\n\n/* ---------------------------------------------------------------------------\n * Hook\n * ------------------------------------------------------------------------- */\n\nexport function usePasswordStrength(\n value: string,\n rules: PasswordRule[] = DEFAULT_PASSWORD_RULES,\n): PasswordStrengthResult {\n return useMemo(() => {\n const evaluated: PasswordRuleResult[] = rules.map((r) => ({\n id: r.id,\n label: r.label,\n passed: runRule(r.test, value),\n }));\n const passed = evaluated.filter((r) => r.passed).length;\n const total = evaluated.length;\n const score = computeScore(passed, total);\n return {\n score,\n rules: evaluated,\n passed,\n total,\n isValid: total === 0 || passed === total,\n };\n }, [value, rules]);\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers\n * ------------------------------------------------------------------------- */\n\nfunction runRule(\n test: PasswordRule[\"test\"],\n value: string,\n): boolean {\n if (typeof test === \"function\") return test(value);\n // Regexes used as rule predicates can be stateful (the `g` and `y` flags\n // hold a `lastIndex` between calls). Re-running `.test` on a stale regex\n // returns wrong results — reset before testing.\n test.lastIndex = 0;\n return test.test(value);\n}\n\nfunction computeScore(passed: number, total: number): PasswordStrengthScore {\n if (total === 0) return 0;\n // Ratio-based: 0/total → 0, total/total → 4, evenly stepped between.\n // `floor(ratio * 5)` maps to {0,1,2,3,4,5} — clamp the perfect score\n // back to 4 so the meter caps at \"Very strong\".\n const ratio = passed / total;\n return Math.min(4, Math.floor(ratio * 5)) as PasswordStrengthScore;\n}\n","\"use client\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useId,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * SegmentedControl — small mutually-exclusive view-mode toggle.\n *\n * Common ETL UI uses:\n * - View toggle: Grid | List | Table\n * - Time range: Day | Week | Month | Year\n * - Mode flip: Edit | Preview\n * - Direction: Source | Destination\n *\n * Each segment is a button; the radiogroup pattern is the WAI-ARIA\n * recommended approach. Keyboard nav: ← → cycles, Home / End jump to\n * boundaries. A motion-backed \"indicator\" slides between segments on\n * change for a tactile feel (respects reduced-motion).\n *\n * Controlled OR uncontrolled — pass `value` for controlled, omit and\n * let the component own state with `defaultValue`.\n * ------------------------------------------------------------------------- */\n\nexport type SegmentedControlSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface SegmentedControlOption<T extends string = string> {\n /** Stable value identifier. */\n value: T;\n /** Display label. */\n label: ReactNode;\n /** Optional leading icon. */\n icon?: ReactNode;\n /** Disable this segment. */\n disabled?: boolean;\n}\n\nexport interface SegmentedControlProps<T extends string = string>\n extends Omit<\n ComponentPropsWithoutRef<\"div\">,\n | \"onChange\"\n | \"defaultValue\"\n | \"children\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onAnimationStart\"\n > {\n /** Available segments. */\n options: SegmentedControlOption<T>[];\n /** Controlled: currently-selected value. */\n value?: T;\n /** Uncontrolled fallback. Default = first non-disabled option. */\n defaultValue?: T;\n /** Fires on selection change. */\n onChange?: (value: T) => void;\n /** Visual size. Default `\"md\"`. */\n size?: SegmentedControlSize;\n /** Stretch to fill the container. Default `false`. */\n fullWidth?: boolean;\n /** Hide labels (icon-only segments). Default `false`. */\n iconOnly?: boolean;\n /** Disable the entire control. */\n disabled?: boolean;\n /** Accessible label for the group (required when no visible label). */\n \"aria-label\"?: string;\n /** id of an element that labels the group. */\n \"aria-labelledby\"?: string;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nfunction SegmentedControlInner<T extends string>(\n {\n options,\n value: controlledValue,\n defaultValue,\n onChange,\n size = \"md\",\n fullWidth = false,\n iconOnly = false,\n disabled = false,\n id: providedId,\n className,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...rest\n }: SegmentedControlProps<T>,\n ref: React.Ref<HTMLDivElement>,\n) {\n const reactId = useId();\n const baseId = providedId ?? `ods-segmented-${reactId}`;\n const reducedMotion = useReducedMotion();\n\n // Initial value: explicit defaultValue → first non-disabled option.\n const fallback =\n defaultValue ?? options.find((o) => !o.disabled)?.value ?? options[0]?.value;\n const [internalValue, setInternalValue] = useState<T | undefined>(\n fallback as T | undefined,\n );\n const isControlled = controlledValue !== undefined;\n const value = isControlled ? controlledValue : internalValue;\n\n const setValue = useCallback(\n (next: T) => {\n if (!isControlled) setInternalValue(next);\n onChange?.(next);\n },\n [isControlled, onChange],\n );\n\n const handleClick =\n (option: SegmentedControlOption<T>) =>\n (e: MouseEvent<HTMLButtonElement>) => {\n if (disabled || option.disabled) return;\n e.preventDefault();\n if (option.value !== value) setValue(option.value);\n };\n\n const handleKeyDown = (\n e: KeyboardEvent<HTMLButtonElement>,\n index: number,\n ) => {\n if (disabled) return;\n const enabled = options.filter((o) => !o.disabled);\n const currentEnabledIdx = enabled.findIndex((o) => o.value === value);\n let nextIdx = currentEnabledIdx;\n if (e.key === \"ArrowRight\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n nextIdx = (currentEnabledIdx + 1) % enabled.length;\n } else if (e.key === \"ArrowLeft\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n nextIdx =\n (currentEnabledIdx - 1 + enabled.length) % enabled.length;\n } else if (e.key === \"Home\") {\n e.preventDefault();\n nextIdx = 0;\n } else if (e.key === \"End\") {\n e.preventDefault();\n nextIdx = enabled.length - 1;\n } else {\n return;\n }\n const next = enabled[nextIdx];\n if (next) {\n setValue(next.value);\n const btn = document.getElementById(`${baseId}-seg-${next.value}`);\n (btn as HTMLButtonElement | null)?.focus();\n }\n // index is kept for future per-segment handling; currently unused\n void index;\n };\n\n return (\n <div\n {...rest}\n ref={ref}\n id={baseId}\n role=\"radiogroup\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n className={cn(\n \"ods-segmented\",\n `ods-segmented--${size}`,\n fullWidth && \"ods-segmented--full\",\n iconOnly && \"ods-segmented--icon-only\",\n disabled && \"ods-segmented--disabled\",\n className,\n )}\n >\n {options.map((opt, i) => {\n const selected = opt.value === value;\n return (\n <button\n key={opt.value}\n id={`${baseId}-seg-${opt.value}`}\n type=\"button\"\n role=\"radio\"\n aria-checked={selected}\n aria-label={iconOnly && typeof opt.label === \"string\" ? opt.label : undefined}\n tabIndex={selected ? 0 : -1}\n disabled={disabled || opt.disabled}\n className={cn(\n \"ods-segmented__segment\",\n selected && \"ods-segmented__segment--selected\",\n )}\n onClick={handleClick(opt)}\n onKeyDown={(e) => handleKeyDown(e, i)}\n >\n {selected && (\n <motion.span\n layoutId={`${baseId}-indicator`}\n className=\"ods-segmented__indicator\"\n aria-hidden=\"true\"\n transition={\n reducedMotion\n ? { duration: 0 }\n : { type: \"spring\", stiffness: 480, damping: 38 }\n }\n />\n )}\n {opt.icon && (\n <span\n className=\"ods-segmented__icon\"\n aria-hidden=\"true\"\n >\n {opt.icon}\n </span>\n )}\n {!iconOnly && (\n <span className=\"ods-segmented__label\">{opt.label}</span>\n )}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport const SegmentedControl = forwardRef(SegmentedControlInner) as <\n T extends string = string,\n>(\n props: SegmentedControlProps<T> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement;\n","\"use client\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport {\n forwardRef,\n type MouseEvent as ReactMouseEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { HiddenSelect, useButton, useListBox, useOption, useSelect } from \"react-aria\";\nimport { createPortal } from \"react-dom\";\nimport { Item, useSelectState } from \"react-stately\";\nimport { CheckmarkIcon, ChevronDownIcon } from \"@octaviaflow/icons\";\nimport { resolveAccessibleName } from \"../../utils/a11y\";\nimport { cn } from \"../../utils/cn\";\nimport { Tooltip } from \"../Tooltip/Tooltip\";\n\nexport interface SelectOption {\n value: string;\n label: string;\n icon?: ReactNode;\n description?: string;\n disabled?: boolean;\n}\n\nexport interface SelectProps {\n options: SelectOption[];\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n searchable?: boolean;\n label?: string;\n error?: boolean;\n errorMessage?: string;\n disabled?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n /** Name for form submission (forwarded to the HiddenSelect element). */\n name?: string;\n /** Required flag for form submission (forwarded to HiddenSelect). */\n required?: boolean;\n /** Stable id for the trigger button (and the source for label htmlFor). */\n id?: string;\n /** Associate this control with an external <form id=\"...\"> element. */\n form?: string;\n /** Auto-focus the trigger on mount. */\n autoFocus?: boolean;\n /** Optional aria-label when no visible label is provided. */\n \"aria-label\"?: string;\n /** Optional aria-labelledby override. */\n \"aria-labelledby\"?: string;\n /** Optional aria-describedby (e.g. for helper text outside the component). */\n \"aria-describedby\"?: string;\n /** Helper text rendered below the trigger. Suppressed when `error`\n * is set (the error message takes the slot). */\n helperText?: ReactNode;\n /**\n * Render a check-mark glyph next to the currently selected option in\n * the dropdown. Defaults to `false` — the highlighted background is\n * already a strong visual cue, so doubling up reads as visual noise\n * in dense menus. Re-enable when the menu sits in a context where the\n * highlight isn't enough (e.g. extremely tall menus).\n */\n showCheckmark?: boolean;\n /**\n * Close the popover when the user clicks anywhere outside the trigger\n * + menu. Defaults to `true` — set to `false` for cases where the\n * caller manages dismissal explicitly (e.g. a modal that wraps the\n * select and owns its own close logic).\n */\n closeOnOutsideClick?: boolean;\n /** Show our design-system `<Tooltip>` on hover over options whose\n * label may be truncated. Default `false` — opt-in via this flag per\n * the platform's \"chrome stays quiet unless explicitly enabled\"\n * convention. The popover surfaces the full label plus the\n * description on a second line when present. */\n showOverflowTooltips?: boolean;\n /**\n * Floor for the dropdown popover width in pixels. The popover is\n * normally pinned to the trigger's width (visual alignment); pass\n * a number here when the trigger is narrow but option labels are\n * long — e.g. Calendar's compact `size=\"sm\"` month/year caption\n * where the trigger is ~70 px but month names like \"September\"\n * need ~110 px. Defaults to the trigger width (no override).\n */\n dropdownMinWidth?: number;\n}\n\n/* ------------------------------------------------------------------ */\n/* OverflowTooltip helper */\n/* ------------------------------------------------------------------ */\n\n/** Wraps `children` in our design-system Tooltip only when the flag is\n * on AND there's content to surface. Mirrors the MultiSelect pattern\n * so both pickers stay consistent. */\nfunction OverflowTooltip({\n enabled,\n content,\n children,\n}: {\n enabled: boolean;\n content: ReactNode;\n children: React.ReactElement;\n}) {\n if (!enabled || content == null || content === \"\") return children;\n return <Tooltip content={content}>{children}</Tooltip>;\n}\n\n/* ------------------------------------------------------------------ */\n/* Internal ListBox rendered inside the dropdown */\n/* ------------------------------------------------------------------ */\n\nfunction ListBox(props: any) {\n const ref = useRef<HTMLUListElement>(null);\n const {\n listBoxRef = ref,\n state,\n showCheckmark,\n showOverflowTooltips,\n } = props;\n const { listBoxProps } = useListBox(props, state, listBoxRef);\n\n return (\n <ul {...listBoxProps} ref={listBoxRef} className={\"ods-select__options\"}>\n {[...state.collection].map((item: any) => (\n <Option\n key={item.key}\n item={item}\n state={state}\n showCheckmark={showCheckmark}\n showOverflowTooltips={showOverflowTooltips}\n />\n ))}\n </ul>\n );\n}\n\nfunction Option({\n item,\n state,\n showCheckmark,\n showOverflowTooltips,\n}: {\n item: any;\n state: any;\n showCheckmark?: boolean;\n showOverflowTooltips?: boolean;\n}) {\n const ref = useRef<HTMLLIElement>(null);\n const { optionProps, isSelected, isFocused, isDisabled } = useOption(\n { key: item.key },\n state,\n ref,\n );\n\n // item.value is the items-array object; the actual SelectOption is nested inside\n const raw = item.value;\n const option: SelectOption | undefined = raw?.value ?? raw;\n\n // Tooltip content — label by itself, OR label + description on two\n // lines so the popover surfaces everything the row contains.\n const tooltipContent: ReactNode = option?.description ? (\n <>\n <span>{option.label}</span>\n <br />\n <span style={{ opacity: 0.75 }}>{option.description}</span>\n </>\n ) : (\n option?.label\n );\n\n return (\n <OverflowTooltip\n enabled={!!showOverflowTooltips}\n content={tooltipContent}\n >\n <li\n {...optionProps}\n ref={ref}\n className={cn(\n \"ods-select__option\",\n isFocused && \"ods-select__option--highlighted\",\n isSelected && \"ods-select__option--selected\",\n isDisabled && \"ods-select__option--disabled\",\n )}\n >\n {option?.icon && <span className={\"ods-select__option-icon\"}>{option.icon}</span>}\n <span className={\"ods-select__option-text\"}>\n <span className={\"ods-select__option-label\"}>{item.rendered}</span>\n {option?.description && (\n <span className={\"ods-select__option-desc\"}>{option.description}</span>\n )}\n </span>\n {isSelected && showCheckmark && (\n <span className={\"ods-select__check\"} aria-hidden=\"true\">\n <CheckmarkIcon size=\"xs\" tone=\"accent\" />\n </span>\n )}\n </li>\n </OverflowTooltip>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Main Select component */\n/* ------------------------------------------------------------------ */\n\n// Generic default placeholder. A select left on THIS placeholder with no\n// label is a genuine a11y gap (we still warn). But a CUSTOM placeholder\n// (e.g. \"Search channels and people…\") describes the control's purpose, so\n// it's used as the accessible-name fallback — see ariaNameProps below.\nconst DEFAULT_SELECT_PLACEHOLDER = \"Select an option...\";\n\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n options,\n value,\n defaultValue,\n onChange,\n placeholder = DEFAULT_SELECT_PLACEHOLDER,\n searchable = false,\n label,\n error = false,\n errorMessage,\n helperText,\n disabled = false,\n size = \"md\",\n className,\n name,\n required,\n id: providedId,\n form,\n autoFocus,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": consumerDescribedBy,\n showCheckmark = false,\n closeOnOutsideClick = true,\n showOverflowTooltips = false,\n dropdownMinWidth,\n },\n forwardedRef,\n) {\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listBoxRef = useRef<HTMLUListElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLInputElement>(null);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [dropdownPos, setDropdownPos] = useState<{\n top?: number;\n bottom?: number;\n left: number;\n width: number;\n maxHeight: number;\n /** \"down\" = popover hangs below the trigger; \"up\" = it stacks above. */\n direction: \"down\" | \"up\";\n }>({ left: 0, width: 0, maxHeight: 240, direction: \"down\" });\n\n // Compose the forwarded ref with our internal trigger ref so consumers\n // can `.focus()` the button while react-aria's internal needs still work.\n const setTriggerRef = (node: HTMLButtonElement | null) => {\n (triggerRef as { current: HTMLButtonElement | null }).current = node;\n if (typeof forwardedRef === \"function\") forwardedRef(node);\n else if (forwardedRef)\n (forwardedRef as { current: HTMLButtonElement | null }).current = node;\n };\n\n const reactId = useId();\n const baseId = providedId ?? `ods-select-${reactId}`;\n const hintId = error || helperText ? `${baseId}-hint` : undefined;\n const describedBy =\n [consumerDescribedBy, hintId].filter(Boolean).join(\" \") || undefined;\n\n // Build react-stately items from options, applying search filter\n const filteredOptions = useMemo(() => {\n if (!searchable || !searchQuery) return options;\n const q = searchQuery.toLowerCase();\n return options.filter(\n (o) => o.label.toLowerCase().includes(q) || o.description?.toLowerCase().includes(q),\n );\n }, [options, searchQuery, searchable]);\n\n // Build collection props for useSelectState\n // Resolve accessible name from {label, aria-label, aria-labelledby}. Removes\n // the literal \"Select\" fallback that was masking the real \"no label\" bug.\n // A CUSTOM placeholder is accepted as a last-resort accessible name (a\n // placeholder like \"Search channels and people…\" is a meaningful control\n // description); the generic default placeholder is NOT, so a truly\n // unlabeled select still trips the dev warning.\n const ariaNameProps = useMemo(\n () =>\n resolveAccessibleName({\n label,\n ariaLabel,\n ariaLabelledby: ariaLabelledBy,\n componentName: \"Select\",\n fallbacks: [\n placeholder && placeholder !== DEFAULT_SELECT_PLACEHOLDER ? placeholder : undefined,\n ],\n }),\n [label, ariaLabel, ariaLabelledBy, placeholder],\n );\n\n const ariaProps = useMemo(() => {\n const items = filteredOptions.map((o) => ({\n key: o.value,\n label: o.label,\n value: o,\n isDisabled: o.disabled,\n }));\n\n const props: any = {\n // Visible string label when present; otherwise rely on the aria-*\n // props for screen-reader name.\n label: typeof label === \"string\" ? label : undefined,\n ...ariaNameProps,\n items,\n children: (item: any) => (\n <Item key={item.key} textValue={item.label}>\n {item.label}\n </Item>\n ),\n isDisabled: disabled,\n onSelectionChange: (key: any) => {\n onChange?.(String(key));\n setSearchQuery(\"\");\n },\n };\n\n if (value !== undefined) {\n props.selectedKey = value;\n }\n if (defaultValue !== undefined) {\n props.defaultSelectedKey = defaultValue;\n }\n\n return props;\n }, [filteredOptions, label, disabled, value, defaultValue, onChange, ariaNameProps]);\n\n const state = useSelectState(ariaProps);\n\n const { triggerProps, menuProps } = useSelect(ariaProps, state, triggerRef);\n const { buttonProps } = useButton(triggerProps, triggerRef);\n\n // Position dropdown using getBoundingClientRect (fixed positioning to\n // escape stacking contexts). Now viewport-aware: when the trigger sits\n // near the bottom of the screen we flip the popover upward; either\n // way we cap its height to what's actually available so option lists\n // never spill off-screen (the prior behavior on tall pages).\n const updatePosition = useCallback(() => {\n if (!triggerRef.current) return;\n const rect = triggerRef.current.getBoundingClientRect();\n const viewportH = window.innerHeight;\n const margin = 8; // breathing room at the viewport edge\n const gap = 4; // gap between trigger and popover\n const spaceBelow = viewportH - rect.bottom - gap - margin;\n const spaceAbove = rect.top - gap - margin;\n // Prefer downward; flip up when below is cramped AND above has more\n // room. Falls back to whichever side has more space if both are tight.\n const PREFERRED_MIN = 200;\n const openUp =\n spaceBelow < PREFERRED_MIN && spaceAbove > spaceBelow;\n setDropdownPos({\n ...(openUp\n ? { bottom: viewportH - rect.top + gap }\n : { top: rect.bottom + gap }),\n left: rect.left,\n width: rect.width,\n maxHeight: Math.max(120, openUp ? spaceAbove : spaceBelow),\n direction: openUp ? \"up\" : \"down\",\n });\n }, []);\n\n useEffect(() => {\n if (state.isOpen) {\n updatePosition();\n window.addEventListener(\"scroll\", updatePosition, true);\n window.addEventListener(\"resize\", updatePosition);\n return () => {\n window.removeEventListener(\"scroll\", updatePosition, true);\n window.removeEventListener(\"resize\", updatePosition);\n };\n }\n }, [state.isOpen, updatePosition]);\n\n // Focus search input when dropdown opens\n useEffect(() => {\n if (state.isOpen && searchable && searchRef.current) {\n // Small delay to allow animation frame\n requestAnimationFrame(() => searchRef.current?.focus());\n }\n }, [state.isOpen, searchable]);\n\n // Outside-click + Escape close. react-aria's `useSelect` wires Escape\n // when the trigger keeps focus, but because the dropdown is portaled\n // to <body> and we move focus into the search input on open, the\n // built-in dismiss does not fire on document-level outside clicks.\n // Wire it here ourselves; the `closeOnOutsideClick` prop lets a\n // consumer opt out for modal-managed selects.\n useEffect(() => {\n if (!state.isOpen || !closeOnOutsideClick) return;\n const onPointer = (e: MouseEvent) => {\n const target = e.target as Node;\n if (dropdownRef.current?.contains(target)) return;\n if (triggerRef.current?.contains(target)) return;\n state.close();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") state.close();\n };\n document.addEventListener(\"mousedown\", onPointer);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onPointer);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [state.isOpen, state.close, closeOnOutsideClick]);\n\n // Find currently selected option for display\n const selectedOption = options.find((o) => o.value === String(state.selectedKey ?? \"\"));\n\n // ── Close-on-re-click ──────────────────────────────────────────────\n // react-aria's `useSelect` opens on press but does NOT toggle when\n // the trigger is pressed again with the menu open — that's the\n // \"click trigger again\" close pattern users expect from every other\n // select on the web. We restore it here: stash the open state right\n // before the press, and on the trailing click, if it was open AND\n // still is open (meaning react-aria didn't auto-close), force close.\n const wasOpenBeforePressRef = useRef(false);\n const handleTriggerPointerDown = (e: ReactPointerEvent<HTMLButtonElement>) => {\n wasOpenBeforePressRef.current = state.isOpen;\n // Forward to react-aria's own handler if present.\n const baseHandler = (buttonProps as { onPointerDown?: (e: ReactPointerEvent<HTMLButtonElement>) => void }).onPointerDown;\n baseHandler?.(e);\n };\n const handleTriggerClick = (e: ReactMouseEvent<HTMLButtonElement>) => {\n const baseHandler = (buttonProps as { onClick?: (e: ReactMouseEvent<HTMLButtonElement>) => void }).onClick;\n baseHandler?.(e);\n if (wasOpenBeforePressRef.current && state.isOpen) {\n state.close();\n }\n wasOpenBeforePressRef.current = false;\n };\n\n return (\n <div\n className={cn(\n \"ods-select\",\n `ods-select--${size}`,\n error && \"ods-select--error\",\n disabled && \"ods-select--disabled\",\n className,\n )}\n >\n {label && (\n <label className={\"ods-select__label\"} htmlFor={baseId}>\n {label}\n </label>\n )}\n\n <HiddenSelect state={state} triggerRef={triggerRef} label={label} name={name} />\n\n <button\n {...buttonProps}\n onPointerDown={handleTriggerPointerDown}\n onClick={handleTriggerClick}\n ref={setTriggerRef}\n id={baseId}\n form={form}\n autoFocus={autoFocus}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={describedBy}\n aria-required={required || undefined}\n aria-invalid={error ? true : undefined}\n className={cn(\"ods-select__trigger\", state.isOpen && \"ods-select__trigger--open\")}\n >\n <span className={\"ods-select__value\"}>\n {selectedOption ? (\n <>\n {selectedOption.icon && (\n <span className={\"ods-select__value-icon\"}>{selectedOption.icon}</span>\n )}\n {selectedOption.label}\n </>\n ) : (\n <span className={\"ods-select__placeholder\"}>{placeholder}</span>\n )}\n </span>\n <span\n className={cn(\n \"ods-select__chevron\",\n state.isOpen && \"ods-select__chevron--open\",\n )}\n aria-hidden=\"true\"\n >\n <ChevronDownIcon size=\"xs\" />\n </span>\n </button>\n\n {typeof document !== \"undefined\" &&\n createPortal(\n <AnimatePresence>\n {state.isOpen && (\n <motion.div\n ref={dropdownRef}\n data-ods-floating=\"\"\n className={\"ods-select__dropdown\"}\n style={{\n position: \"fixed\",\n ...(dropdownPos.top !== undefined && { top: dropdownPos.top }),\n ...(dropdownPos.bottom !== undefined && { bottom: dropdownPos.bottom }),\n left: dropdownPos.left,\n // `minWidth` (not `width`) keeps the popover at\n // least as wide as the trigger — preserves visual\n // alignment — but allows the consumer to widen it\n // explicitly when option labels demand more room\n // (pass `dropdownMinWidth` to set a higher floor).\n // Avoids the previous `max-content` recipe which\n // made the popover grow uncomfortably wide on\n // searchable / long-option menus.\n minWidth: Math.max(dropdownPos.width, dropdownMinWidth ?? 0),\n // Bound the popover to the available viewport edge so\n // it never spills off-screen on tall pages. Pairs with\n // `overflow-y: auto` from the .ods-select__dropdown\n // SCSS so long option lists scroll internally.\n maxHeight: dropdownPos.maxHeight,\n }}\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={{ duration: 0.2, ease: [0.16, 1, 0.3, 1] }}\n >\n {searchable && (\n <div className={\"ods-select__search-wrap\"}>\n <input\n ref={searchRef}\n className={\"ods-select__search\"}\n type=\"text\"\n placeholder=\"Search...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n aria-label=\"Search options\"\n onKeyDown={(e) => {\n // Allow Escape to close the dropdown\n if (e.key === \"Escape\") {\n state.close();\n }\n }}\n />\n </div>\n )}\n <ListBox\n {...menuProps}\n listBoxRef={listBoxRef}\n state={state}\n showCheckmark={showCheckmark}\n showOverflowTooltips={showOverflowTooltips}\n />\n {filteredOptions.length === 0 && (\n <div className={\"ods-select__empty\"}>No results found</div>\n )}\n </motion.div>\n )}\n </AnimatePresence>,\n document.body,\n )}\n\n {error && errorMessage ? (\n <span\n id={hintId}\n className={\"ods-select__error\"}\n role=\"alert\"\n >\n {errorMessage}\n </span>\n ) : helperText ? (\n <span id={hintId} className={\"ods-select__hint\"}>\n {helperText}\n </span>\n ) : null}\n </div>\n );\n});\n\nSelect.displayName = \"Select\";\n","\"use client\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport {\n cloneElement,\n type ComponentPropsWithRef,\n type DOMAttributes,\n isValidElement,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefObject,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useTooltip, useTooltipTrigger } from \"react-aria\";\nimport { createPortal } from \"react-dom\";\nimport { useTooltipTriggerState } from \"react-stately\";\nimport { cn } from \"../../utils/cn\";\n\nexport type TooltipPosition = \"top\" | \"bottom\" | \"left\" | \"right\";\n\nexport interface TooltipProps {\n content: ReactNode;\n /** Preferred position. May flip to the opposite side if it would overflow. */\n position?: TooltipPosition;\n /** Open-delay in milliseconds (react-aria's warmup). Defaults to 200. */\n delay?: number;\n /** Pixel gap between trigger and tooltip. Defaults to 8. */\n offset?: number;\n /** Suppress the tooltip entirely without removing the trigger from the tree. */\n disabled?: boolean;\n /** Stable id for the tooltip DOM node — useful for aria-describedby tests. */\n id?: string;\n children: ReactElement;\n className?: string;\n}\n\ninterface Coords {\n top: number;\n left: number;\n /** The actual side the tooltip ended up on after any flip. */\n position: TooltipPosition;\n}\n\nconst FLIP: Record<TooltipPosition, TooltipPosition> = {\n top: \"bottom\",\n bottom: \"top\",\n left: \"right\",\n right: \"left\",\n};\n\nfunction placeOn(\n rect: DOMRect,\n tipRect: DOMRect,\n position: TooltipPosition,\n offset: number,\n): { top: number; left: number } {\n const cx = rect.left + rect.width / 2;\n const cy = rect.top + rect.height / 2;\n switch (position) {\n case \"top\":\n return {\n top: rect.top - tipRect.height - offset,\n left: cx - tipRect.width / 2,\n };\n case \"bottom\":\n return { top: rect.bottom + offset, left: cx - tipRect.width / 2 };\n case \"left\":\n return {\n top: cy - tipRect.height / 2,\n left: rect.left - tipRect.width - offset,\n };\n case \"right\":\n return { top: cy - tipRect.height / 2, left: rect.right + offset };\n }\n}\n\n/** Resolve the final placement: flip if the preferred side overflows. */\nfunction computePosition(\n rect: DOMRect,\n tipRect: DOMRect,\n position: TooltipPosition,\n offset: number,\n viewport: { width: number; height: number },\n): Coords {\n const tryAt = (p: TooltipPosition) => {\n const c = placeOn(rect, tipRect, p, offset);\n const fits =\n c.top >= 0 &&\n c.left >= 0 &&\n c.top + tipRect.height <= viewport.height &&\n c.left + tipRect.width <= viewport.width;\n return { ...c, position: p, fits };\n };\n\n const preferred = tryAt(position);\n if (preferred.fits) return preferred;\n const flipped = tryAt(FLIP[position]);\n if (flipped.fits) return flipped;\n\n // Neither fits cleanly — fall back to the preferred side but clamp into\n // the viewport so the arrow target is still close to the trigger.\n const fallback = preferred;\n const clampedLeft = Math.max(\n 4,\n Math.min(fallback.left, viewport.width - tipRect.width - 4),\n );\n const clampedTop = Math.max(\n 4,\n Math.min(fallback.top, viewport.height - tipRect.height - 4),\n );\n return { top: clampedTop, left: clampedLeft, position: fallback.position };\n}\n\n// Framer-motion's `initial` / `animate` accept rich variant types we\n// don't need to spell out — plain objects with `opacity` + `x`/`y` are\n// the documented shorthand and avoid pulling in the library's union.\ntype MotionFrame = Record<string, number | string>;\nconst animVariants: Record<\n TooltipPosition,\n { initial: MotionFrame; animate: MotionFrame }\n> = {\n top: { initial: { opacity: 0, y: 4 }, animate: { opacity: 1, y: 0 } },\n bottom: { initial: { opacity: 0, y: -4 }, animate: { opacity: 1, y: 0 } },\n left: { initial: { opacity: 0, x: 4 }, animate: { opacity: 1, x: 0 } },\n right: { initial: { opacity: 0, x: -4 }, animate: { opacity: 1, x: 0 } },\n};\n\ninterface ContentProps {\n state: ReturnType<typeof useTooltipTriggerState>;\n content: ReactNode;\n position: TooltipPosition;\n triggerRef: RefObject<HTMLElement | null>;\n className?: string;\n offset: number;\n tooltipId: string;\n}\n\nfunction TooltipContent({\n state,\n content,\n position,\n triggerRef,\n className,\n offset,\n tooltipId,\n}: ContentProps) {\n const { tooltipProps } = useTooltip({ isOpen: state.isOpen }, state);\n const tipRef = useRef<HTMLDivElement | null>(null);\n const [coords, setCoords] = useState<Coords | null>(null);\n\n const reposition = useCallback(() => {\n if (!triggerRef.current || !tipRef.current) return;\n const trigRect = triggerRef.current.getBoundingClientRect();\n const tipRect = tipRef.current.getBoundingClientRect();\n const viewport = {\n width: window.innerWidth || document.documentElement.clientWidth,\n height: window.innerHeight || document.documentElement.clientHeight,\n };\n setCoords(computePosition(trigRect, tipRect, position, offset, viewport));\n }, [triggerRef, position, offset]);\n\n // The first measure happens before the tip has rendered its content, so\n // its rect is empty. Measure again on the next frame for accurate placement.\n useLayoutEffect(() => {\n if (!state.isOpen) return;\n reposition();\n const id = requestAnimationFrame(reposition);\n return () => cancelAnimationFrame(id);\n }, [state.isOpen, reposition]);\n\n useEffect(() => {\n if (!state.isOpen) return;\n const handler = () => reposition();\n window.addEventListener(\"scroll\", handler, true);\n window.addEventListener(\"resize\", handler);\n return () => {\n window.removeEventListener(\"scroll\", handler, true);\n window.removeEventListener(\"resize\", handler);\n };\n }, [state.isOpen, reposition]);\n\n const resolvedPos = coords?.position ?? position;\n const variants = animVariants[resolvedPos];\n\n // react-aria's tooltip props include onMouseEnter/onMouseLeave for the\n // tooltip itself plus drag-related handlers that conflict with framer-\n // motion's prop signatures. Strip the ones framer-motion claims so the\n // intersection is type-clean.\n const {\n onDrag: _onDrag,\n onDragStart: _onDragStart,\n onDragEnd: _onDragEnd,\n onAnimationStart: _onAnimationStart,\n ...safeTipProps\n } = tooltipProps as DOMAttributes<HTMLDivElement> & Record<string, unknown>;\n\n const portalContent = (\n <AnimatePresence>\n {state.isOpen && (\n <div\n className=\"ods-tooltip__wrapper\"\n style={{\n position: \"fixed\",\n zIndex: 1500,\n top: coords?.top ?? -9999,\n left: coords?.left ?? -9999,\n visibility: coords ? \"visible\" : \"hidden\",\n pointerEvents: \"none\",\n }}\n >\n <motion.div\n ref={tipRef}\n {...safeTipProps}\n id={tooltipId}\n role=\"tooltip\"\n data-position={resolvedPos}\n className={cn(\"ods-tooltip\", className)}\n initial={variants.initial}\n animate={variants.animate}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15, ease: \"easeOut\" }}\n >\n {content}\n <span className=\"ods-tooltip__arrow\" aria-hidden=\"true\" />\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n );\n\n if (typeof document === \"undefined\") return null;\n return createPortal(portalContent, document.body);\n}\n\n/** Compose two refs into one — preserves the child's existing ref. */\nfunction mergeRefs<T>(...refs: Array<Ref<T> | undefined>): (node: T | null) => void {\n return (node) => {\n for (const r of refs) {\n if (!r) continue;\n if (typeof r === \"function\") r(node);\n else (r as { current: T | null }).current = node;\n }\n };\n}\n\n/** Compose a child handler with one from react-aria — both fire, child first. */\nfunction mergeHandler<E extends React.SyntheticEvent>(\n childHandler: ((e: E) => void) | undefined,\n ariaHandler: ((e: E) => void) | undefined,\n): ((e: E) => void) | undefined {\n if (!childHandler && !ariaHandler) return undefined;\n return (e: E) => {\n childHandler?.(e);\n if (!e.defaultPrevented) ariaHandler?.(e);\n };\n}\n\nexport function Tooltip({\n content,\n position = \"top\",\n delay = 200,\n offset = 8,\n disabled = false,\n id: providedId,\n children,\n className,\n}: TooltipProps) {\n const reactId = useId();\n const tooltipId = providedId ?? `ods-tooltip-${reactId}`;\n const triggerRef = useRef<HTMLElement>(null);\n const state = useTooltipTriggerState({ delay });\n const { triggerProps } = useTooltipTrigger(\n { delay, isDisabled: disabled },\n state,\n triggerRef,\n );\n\n if (!isValidElement(children)) {\n // Bail out gracefully — without a valid element child there's nothing\n // to clone props onto. Render the children as-is so we don't crash\n // consumer trees that pass a string by mistake.\n return <>{children}</>;\n }\n\n // Pull the existing ref + handlers off the child so we can compose them\n // with react-aria's. Without this merge the child loses its ref\n // (e.g. ref forwarding in a wrapped Button) and any user-supplied\n // onMouseEnter / onFocus etc. is silently overwritten.\n const childProps = children.props as ComponentPropsWithRef<\"button\"> &\n Record<string, unknown>;\n // React 19: `ref` is a regular prop on the child's props. We still\n // fall back to the legacy `element.ref` to support intermediates that\n // re-emit the older shape.\n const childRef =\n (childProps as { ref?: Ref<HTMLElement> }).ref ??\n (children as unknown as { ref?: Ref<HTMLElement> }).ref;\n\n // Merge every handler prop from react-aria with whatever the child\n // already had, so a child that passes its own onFocus/onMouseEnter\n // doesn't lose them when we attach the trigger props.\n const merged: Record<string, unknown> = { ...childProps };\n for (const [key, value] of Object.entries(\n triggerProps as Record<string, unknown>,\n )) {\n if (key.startsWith(\"on\") && typeof value === \"function\") {\n merged[key] = mergeHandler(\n childProps[key] as never,\n value as never,\n );\n } else {\n merged[key] = value;\n }\n }\n merged.ref = mergeRefs<HTMLElement>(triggerRef, childRef);\n merged[\"aria-describedby\"] =\n [childProps[\"aria-describedby\"], tooltipId].filter(Boolean).join(\" \");\n\n return (\n <>\n {cloneElement(children, merged)}\n {!disabled && (\n <TooltipContent\n state={state}\n content={content}\n position={position}\n triggerRef={triggerRef}\n offset={offset}\n className={className}\n tooltipId={tooltipId}\n />\n )}\n </>\n );\n}\n\nTooltip.displayName = \"Tooltip\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type SpinnerSize = \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type SpinnerTone =\n | \"accent\"\n | \"muted\"\n | \"primary\"\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"inverse\";\n\ntype SvgPropsBase = Omit<\n ComponentPropsWithoutRef<\"svg\">,\n \"color\" | \"viewBox\" | \"fill\" | \"size\"\n>;\n\nexport interface SpinnerProps extends SvgPropsBase {\n /** Keyword size OR custom pixel number. Default `\"md\"`. */\n size?: SpinnerSize | number;\n /** Token-driven colour. Defaults to `\"accent\"`. Consumers can also\n * set `color` directly via `style` if they need a one-off. */\n tone?: SpinnerTone;\n /** Accessible label. Default `\"Loading\"`. */\n label?: string;\n}\n\nconst SIZE_PX: Record<SpinnerSize, number> = {\n sm: 16,\n md: 24,\n lg: 32,\n xl: 48,\n};\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Spinner = forwardRef<SVGSVGElement, SpinnerProps>(function Spinner(\n {\n size = \"md\",\n tone = \"accent\",\n label = \"Loading\",\n className,\n style,\n ...rest\n },\n ref,\n) {\n const px = typeof size === \"number\" ? size : SIZE_PX[size];\n const isKeyword = typeof size === \"string\";\n\n return (\n <svg\n {...rest}\n ref={ref}\n className={cn(\n \"ods-spinner\",\n isKeyword && `ods-spinner--${size}`,\n `ods-spinner--${tone}`,\n className,\n )}\n width={px}\n height={px}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n role=\"status\"\n aria-label={label}\n style={style}\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeDasharray=\"31.4 31.4\"\n className=\"ods-spinner__circle\"\n />\n </svg>\n );\n});\n\nSpinner.displayName = \"Spinner\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useRef,\n} from \"react\";\nimport { useSwitch } from \"react-aria\";\nimport { useToggleState } from \"react-stately\";\nimport { getRenderableText, resolveAccessibleName } from \"../../utils/a11y\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type SwitchSize = \"sm\" | \"md\" | \"lg\";\n\ntype InputPropsBase = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"type\" | \"onChange\" | \"size\" | \"checked\" | \"defaultChecked\"\n>;\n\nexport interface SwitchProps extends InputPropsBase {\n checked?: boolean;\n defaultChecked?: boolean;\n onChange?: (isSelected: boolean) => void;\n disabled?: boolean;\n size?: SwitchSize;\n /** Visible label — accepts rich content. */\n label?: ReactNode;\n /** Optional sublabel rendered below the label. */\n description?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(\n {\n checked,\n defaultChecked,\n onChange,\n disabled = false,\n size = \"md\",\n label,\n description,\n className,\n ...props\n },\n forwardedRef,\n) {\n const innerRef = useRef<HTMLInputElement>(null);\n // Compose forwarded ref + internal ref so consumers can `.focus()`\n // while react-aria's plumbing still works.\n const setRef = (node: HTMLInputElement | null) => {\n (innerRef as { current: HTMLInputElement | null }).current = node;\n if (typeof forwardedRef === \"function\") forwardedRef(node);\n else if (forwardedRef)\n (forwardedRef as { current: HTMLInputElement | null }).current = node;\n };\n\n const state = useToggleState({\n isSelected: checked,\n defaultSelected: defaultChecked,\n onChange,\n });\n\n // Derive the accessible name from the label's TEXT — including a rich\n // ReactNode label (icon + text, custom JSX), not just a bare string. Without\n // this, a non-string `label` was dropped here and the switch tripped a false\n // \"no accessible name\" warning + a bogus aria-label=\"Unlabeled Switch\" that\n // overrode the real visible label. A genuinely nameless switch (no label,\n // no aria-*) still warns, which is correct.\n const labelText = getRenderableText(label).trim();\n const ariaNameProps = resolveAccessibleName({\n label: labelText || undefined,\n ariaLabel: (props as Record<string, unknown>)[\"aria-label\"] as\n | string\n | undefined,\n ariaLabelledby: (props as Record<string, unknown>)[\"aria-labelledby\"] as\n | string\n | undefined,\n componentName: \"Switch\",\n });\n\n const { inputProps } = useSwitch(\n {\n isSelected: state.isSelected,\n isDisabled: disabled,\n onChange,\n ...ariaNameProps,\n },\n state,\n innerRef,\n );\n\n const isOn = state.isSelected;\n\n // React Aria owns the interactive event handlers + aria-* on the\n // input. Strip them from the caller's props so we don't double-bind;\n // native form attrs (name/value/form/id/etc.) flow through.\n const {\n onClick: _onClick,\n onKeyDown: _onKeyDown,\n onKeyUp: _onKeyUp,\n onFocus: _onFocus,\n onBlur: _onBlur,\n ...passthroughProps\n } = props as Record<string, unknown>;\n\n return (\n <label\n className={cn(\n \"ods-switch\",\n `ods-switch--${size}`,\n disabled && \"ods-switch--disabled\",\n description && \"ods-switch--with-description\",\n className,\n )}\n >\n <input\n {...(passthroughProps as ComponentPropsWithoutRef<\"input\">)}\n {...inputProps}\n ref={setRef}\n className=\"ods-switch__input\"\n />\n <div\n className={cn(\"ods-switch__track\", isOn && \"ods-switch__track--on\")}\n aria-hidden=\"true\"\n >\n <div className=\"ods-switch__thumb\" />\n </div>\n {(label || description) && (\n <div className=\"ods-switch__text\">\n {label && <span className=\"ods-switch__label\">{label}</span>}\n {description && (\n <span className=\"ods-switch__description\">{description}</span>\n )}\n </div>\n )}\n </label>\n );\n});\n\nSwitch.displayName = \"Switch\";\n","\"use client\";\nimport { motion } from \"framer-motion\";\nimport { type ReactNode, useCallback, useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { useTab, useTabList, useTabPanel } from \"react-aria\";\nimport { Item, type TabListStateOptions, useTabListState } from \"react-stately\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface TabItem {\n value: string;\n label: string;\n icon?: ReactNode;\n disabled?: boolean;\n children?: ReactNode;\n}\n\nexport interface TabsProps {\n items: TabItem[];\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n orientation?: \"horizontal\" | \"vertical\";\n className?: string;\n}\n\n// Each Tabs instance gets its own layoutId via React's `useId()`. Without\n// the per-instance scope, multiple Tabs mounted on the same page share the\n// same shared layout group, which makes the indicator chase the most recent\n// re-mount (visually it \"disappears\" or jumps between tabs). The id is\n// forwarded into the indicator's `layoutId` so the animation is bounded.\nfunction TabButton({\n item,\n state,\n indicatorLayoutId,\n}: {\n item: any;\n state: any;\n indicatorLayoutId: string;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const { tabProps } = useTab({ key: item.key }, state, ref);\n const isSelected = state.selectedKey === item.key;\n const isDisabled = state.disabledKeys.has(item.key);\n\n // When a tab becomes selected (pointer OR keyboard), bring it fully into\n // view in the horizontally-scrollable strip — clicking a half-clipped or\n // last tab previously left it partly hidden behind the overflow edge.\n // `inline: \"nearest\"` no-ops when the tab is already fully visible, and\n // `block: \"nearest\"` keeps it from scrolling the surrounding page.\n useEffect(() => {\n // `scrollIntoView` is absent in jsdom (tests) — optional-chain the method\n // so the effect is a safe no-op there and in any non-DOM environment.\n if (isSelected) {\n ref.current?.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\" });\n }\n }, [isSelected]);\n\n // Remove motion-conflicting props\n const { onDrag, onDragStart, onDragEnd, onAnimationStart, ...safeTabProps } = tabProps as any;\n\n return (\n <motion.div\n {...safeTabProps}\n ref={ref}\n className={cn(\n \"ods-tabs__tab\",\n isSelected && \"ods-tabs__tab--selected\",\n isDisabled && \"ods-tabs__tab--disabled\",\n )}\n >\n {item.rendered}\n {isSelected && (\n <motion.div\n className={\"ods-tabs__indicator\"}\n layoutId={indicatorLayoutId}\n transition={{ type: \"spring\", damping: 30, stiffness: 400 }}\n />\n )}\n </motion.div>\n );\n}\n\nfunction TabPanelContent({ state, panelContent, ...props }: any) {\n const ref = useRef<HTMLDivElement>(null);\n const { tabPanelProps } = useTabPanel(props, state, ref);\n return (\n <div {...tabPanelProps} ref={ref} className={\"ods-tabs__panel\"}>\n {panelContent}\n </div>\n );\n}\n\n// Threshold below which we consider the strip \"fully scrolled\" — covers\n// fractional pixel rounding so chevrons hide cleanly at the ends.\nconst SCROLL_EDGE_EPSILON = 1;\n// Step size for the chevron buttons. ~200 px clears two or three average\n// tabs without overshooting on narrow strips.\nconst SCROLL_STEP_PX = 200;\n\nexport function Tabs({\n items,\n value,\n defaultValue,\n onChange,\n orientation = \"horizontal\",\n className,\n}: TabsProps) {\n const reactId = useId();\n const indicatorLayoutId = `ods-tabs-indicator-${reactId}`;\n const [internalValue, setInternalValue] = useState(defaultValue || items[0]?.value);\n const selectedKey = value ?? internalValue;\n\n const handleSelectionChange = (key: any) => {\n const keyStr = String(key);\n if (!value) setInternalValue(keyStr);\n onChange?.(keyStr);\n };\n\n // Build a map of value -> panel content\n const panelContentMap = useMemo(() => {\n const map = new Map<string, ReactNode>();\n items.forEach((item) => {\n map.set(item.value, item.children);\n });\n return map;\n }, [items]);\n\n const stateProps: TabListStateOptions<any> = {\n children: items.map((item) => (\n <Item key={item.value} textValue={item.label}>\n {item.icon && <span className={\"ods-tabs__icon\"}>{item.icon}</span>}\n <span>{item.label}</span>\n </Item>\n )),\n selectedKey,\n onSelectionChange: handleSelectionChange,\n disabledKeys: items.filter((i) => i.disabled).map((i) => i.value),\n };\n\n const state = useTabListState(stateProps);\n const ref = useRef<HTMLDivElement>(null);\n const { tabListProps } = useTabList({ ...stateProps, orientation }, state, ref);\n\n // ── Horizontal-overflow scroll ────────────────────────────────────────\n // When the tab strip is wider than its viewport (typical when the host\n // pins it inside a narrow column), we surface left/right chevron\n // buttons that programmatically scroll the strip. The native scrollbar\n // is hidden via SCSS so the chevrons remain the only affordance.\n //\n // We only enable the overflow chrome for horizontal orientation; the\n // vertical layout already scrolls naturally via the parent overflow.\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const measureOverflow = useCallback(() => {\n const el = scrollContainerRef.current;\n if (!el || orientation !== \"horizontal\") {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n const max = el.scrollWidth - el.clientWidth;\n setCanScrollLeft(el.scrollLeft > SCROLL_EDGE_EPSILON);\n setCanScrollRight(el.scrollLeft < max - SCROLL_EDGE_EPSILON);\n }, [orientation]);\n\n // Recompute on mount + when items change. The ResizeObserver covers the\n // case where the container itself resizes (responsive parent layouts).\n useEffect(() => {\n measureOverflow();\n const el = scrollContainerRef.current;\n if (!el || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => measureOverflow());\n ro.observe(el);\n return () => ro.disconnect();\n }, [items, measureOverflow]);\n\n const onScroll = () => measureOverflow();\n\n const scrollBy = (dir: -1 | 1) => {\n const el = scrollContainerRef.current;\n if (!el) return;\n el.scrollBy({ left: dir * SCROLL_STEP_PX, behavior: \"smooth\" });\n };\n\n const currentPanelContent = panelContentMap.get(String(selectedKey));\n\n return (\n <div className={cn(\"ods-tabs\", `ods-tabs--${orientation}`, className)}>\n <div className=\"ods-tabs__list-wrap\">\n {orientation === \"horizontal\" && canScrollLeft && (\n <button\n type=\"button\"\n className=\"ods-tabs__scroll-btn ods-tabs__scroll-btn--left\"\n onClick={() => scrollBy(-1)}\n aria-label=\"Scroll tabs left\"\n tabIndex={-1}\n >\n <ChevronSvg dir=\"left\" />\n </button>\n )}\n <div\n className=\"ods-tabs__scroller\"\n ref={scrollContainerRef}\n onScroll={orientation === \"horizontal\" ? onScroll : undefined}\n >\n <div {...tabListProps} ref={ref} className={\"ods-tabs__list\"}>\n {[...state.collection].map((item) => (\n <TabButton\n key={item.key}\n item={item}\n state={state}\n indicatorLayoutId={indicatorLayoutId}\n />\n ))}\n </div>\n </div>\n {orientation === \"horizontal\" && canScrollRight && (\n <button\n type=\"button\"\n className=\"ods-tabs__scroll-btn ods-tabs__scroll-btn--right\"\n onClick={() => scrollBy(1)}\n aria-label=\"Scroll tabs right\"\n tabIndex={-1}\n >\n <ChevronSvg dir=\"right\" />\n </button>\n )}\n </div>\n <TabPanelContent key={state.selectedKey} state={state} panelContent={currentPanelContent} />\n </div>\n );\n}\n\nfunction ChevronSvg({ dir }: { dir: \"left\" | \"right\" }) {\n // Inline chevron; rotates via CSS-friendly `d` so we don't need to ship\n // an icon dep just for the scroll chrome.\n const d = dir === \"left\" ? \"M11 4L5 10l6 6\" : \"M9 4l6 6-6 6\";\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d={d} />\n </svg>\n );\n}\n","/* ---------------------------------------------------------------------------\n * HttpActionPanel engine — config model + pure logic, no React.\n *\n * The config shape is wire-compatible with the engine's HTTP action: hosts\n * can mount the panel on an existing step config with zero migration. All\n * behavior that can be tested without a DOM lives here: normalization,\n * validation, cURL import/export, effective-URL assembly and response\n * schema inference.\n * ------------------------------------------------------------------------- */\n\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"HEAD\" | \"OPTIONS\";\n\nexport const HTTP_METHODS: HttpMethod[] = [\n \"GET\",\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\",\n \"HEAD\",\n \"OPTIONS\",\n];\n\nexport interface HttpKeyValue {\n key: string;\n value: string;\n description?: string;\n enabled?: boolean;\n}\n\nexport interface HttpAuthConfig {\n type: \"none\" | \"basic\" | \"bearer\" | \"apikey\";\n username?: string;\n password?: string;\n token?: string;\n apiKeyName?: string;\n apiKeyValue?: string;\n apiKeyLocation?: \"header\" | \"query\";\n}\n\nexport interface HttpRetryConfig {\n maxAttempts: number;\n retryOn: number[];\n initialDelayMs: number;\n backoffFactor: number;\n maxDelayMs: number;\n}\n\nexport type HttpPaginationType = \"none\" | \"offset\" | \"cursor\" | \"link_header\" | \"next_url\";\n\nexport interface HttpPaginationConfig {\n type: HttpPaginationType;\n limitParam?: string;\n limitValue?: number;\n offsetParam?: string;\n cursorResponsePath?: string;\n cursorRequestParam?: string;\n nextUrlResponsePath?: string;\n maxPages?: number;\n mergeKey?: string;\n}\n\nexport type HttpBodyType = \"none\" | \"json\" | \"raw\" | \"form-data\" | \"xml\";\nexport type HttpResponseType = \"json\" | \"text\" | \"binary\";\n\nexport interface HttpActionConfig {\n /** Saved API connection to inherit base URL + auth from. */\n connectionId?: string;\n /** \"graphql\" flags the GraphQL body mode (engine-compatible). */\n apiType?: \"rest\" | \"graphql\";\n method?: HttpMethod;\n baseUrl?: string;\n url: string;\n queryParams?: HttpKeyValue[];\n headers?: HttpKeyValue[] | Record<string, string>;\n bodyType?: HttpBodyType;\n body?: unknown;\n formData?: HttpKeyValue[];\n graphqlQuery?: string;\n graphqlVariables?: Record<string, unknown> | string;\n auth?: HttpAuthConfig;\n timeout?: number;\n failOnError?: boolean;\n followRedirects?: boolean;\n retry?: HttpRetryConfig;\n pagination?: HttpPaginationConfig;\n extract?: Record<string, string>;\n responseType?: HttpResponseType;\n expectedContentTypes?: string[];\n /** Inferred response schema (written after a successful test send). */\n _outputSchema?: unknown;\n}\n\nexport const HTTP_ACTION_DEFAULTS: HttpActionConfig = {\n apiType: \"rest\",\n method: \"GET\",\n url: \"\",\n queryParams: [],\n headers: [],\n bodyType: \"json\",\n formData: [],\n graphqlQuery: \"\",\n graphqlVariables: {},\n auth: { type: \"none\" },\n timeout: 30000,\n failOnError: true,\n followRedirects: true,\n retry: {\n maxAttempts: 1,\n retryOn: [429, 500, 502, 503, 504],\n initialDelayMs: 1000,\n backoffFactor: 2,\n maxDelayMs: 30000,\n },\n pagination: { type: \"none\" },\n extract: {},\n responseType: \"json\",\n expectedContentTypes: [],\n};\n\n/* ── Normalization ─────────────────────────────────────────────────────── */\n\n/** Array-or-record key/values → uniform array. */\nexport function normalizeKeyValues(raw: unknown): HttpKeyValue[] {\n if (Array.isArray(raw)) {\n return raw.map((r) => ({\n key: String((r as HttpKeyValue).key ?? \"\"),\n value: String((r as HttpKeyValue).value ?? \"\"),\n description: (r as HttpKeyValue).description,\n enabled: (r as HttpKeyValue).enabled !== false,\n }));\n }\n if (raw && typeof raw === \"object\") {\n return Object.entries(raw as Record<string, string>).map(([key, value]) => ({\n key,\n value: String(value),\n enabled: true,\n }));\n }\n return [];\n}\n\n/**\n * Normalize a persisted auth blob. The legacy inline \"oauth2\" type was only\n * ever a pasted static token (identical to bearer) — map it to bearer,\n * preserving tokens stored as `accessToken`. The engine keeps its alias\n * branch, so the wire output for legacy nodes is unchanged.\n */\nexport function normalizeAuth(raw: unknown): HttpAuthConfig {\n const r = (raw ?? {}) as Record<string, unknown>;\n const rawType = (r.type as string) ?? \"none\";\n const type = (rawType === \"oauth2\" ? \"bearer\" : rawType) as HttpAuthConfig[\"type\"];\n return {\n type: [\"none\", \"basic\", \"bearer\", \"apikey\"].includes(type) ? type : \"none\",\n username: (r.username as string) ?? \"\",\n password: (r.password as string) ?? \"\",\n token: ((r.token ?? r.accessToken) as string) ?? \"\",\n apiKeyName: (r.apiKeyName as string) ?? \"X-API-Key\",\n apiKeyValue: (r.apiKeyValue as string) ?? \"\",\n apiKeyLocation: r.apiKeyLocation === \"query\" ? \"query\" : \"header\",\n };\n}\n\n/** Base + path → full URL (\"https://a.com/\" + \"/v1\" → \"https://a.com/v1\"). */\nexport function effectiveUrl(baseUrl: string | undefined, url: string): string {\n const base = (baseUrl ?? \"\").trim();\n if (!base) return url;\n return `${base.replace(/\\/$/, \"\")}/${url.replace(/^\\//, \"\")}`;\n}\n\n/** Serialize KV rows for persistence, dropping fully empty rows. */\nexport function serializeKeyValues(rows: HttpKeyValue[]): HttpKeyValue[] {\n return rows\n .filter((r) => r.key || r.value)\n .map((r) => ({\n key: r.key,\n value: r.value,\n enabled: r.enabled !== false,\n ...(r.description ? { description: r.description } : {}),\n }));\n}\n\n/* ── Validation ────────────────────────────────────────────────────────── */\n\nexport interface HttpValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nexport function validateHttpConfig(config: Partial<HttpActionConfig>): HttpValidationResult {\n const errors: string[] = [];\n const apiType = config.apiType ?? \"rest\";\n if (apiType === \"rest\" && !config.method) errors.push(\"Method is required\");\n if (apiType === \"graphql\" && !String(config.graphqlQuery ?? \"\").trim()) {\n errors.push(\"GraphQL query is required\");\n }\n const hasConnection = Boolean(config.connectionId);\n if (!config.url && !hasConnection) {\n errors.push(\"URL is required\");\n } else if (config.url && !hasConnection && !config.baseUrl && !config.url.includes(\"{{\")) {\n try {\n new URL(config.url);\n } catch {\n errors.push(\"Invalid URL format\");\n }\n }\n if (typeof config.timeout === \"number\" && config.timeout < 1000) {\n errors.push(\"Timeout must be at least 1000ms\");\n }\n return { valid: errors.length === 0, errors };\n}\n\n/** Number of distinct `$variables` declared in a GraphQL document. */\nexport function countGraphqlVariables(query: string): number {\n return new Set(query.match(/\\$[A-Za-z_][A-Za-z0-9_]*/g) ?? []).size;\n}\n\n/* ── cURL import / export ──────────────────────────────────────────────── */\n\n/** Split a shell command into tokens, honoring single/double quotes. */\nfunction shellTokens(input: string): string[] {\n const tokens: string[] = [];\n // Strip line continuations first so multi-line cURL pastes flatten.\n const flat = input.replace(/\\\\\\r?\\n/g, \" \");\n const re = /'([^']*)'|\"((?:[^\"\\\\]|\\\\.)*)\"|(\\S+)/g;\n let m: RegExpExecArray | null = re.exec(flat);\n while (m !== null) {\n if (m[1] !== undefined) tokens.push(m[1]);\n else if (m[2] !== undefined) tokens.push(m[2].replace(/\\\\([\"\\\\])/g, \"$1\"));\n else tokens.push(m[3]);\n m = re.exec(flat);\n }\n return tokens;\n}\n\n/**\n * Parse a pasted cURL command into a config patch. Returns null when the\n * input is not a cURL invocation. Understands the flags people actually\n * paste: -X/--request, --url, -H/--header, -d/--data(-raw/-binary/\n * -urlencode), -F/--form, -u/--user, -L, -k, --compressed (ignored).\n */\nexport function parseCurl(input: string): Partial<HttpActionConfig> | null {\n const tokens = shellTokens(input.trim());\n if (!tokens.length || !/^curl$/i.test(tokens[0])) return null;\n\n let method: HttpMethod | undefined;\n let url = \"\";\n const headers: HttpKeyValue[] = [];\n const formData: HttpKeyValue[] = [];\n let bodyRaw: string | undefined;\n let basicUser: string | undefined;\n let followRedirects: boolean | undefined;\n\n for (let i = 1; i < tokens.length; i++) {\n const t = tokens[i];\n const next = () => tokens[++i] ?? \"\";\n if (t === \"-X\" || t === \"--request\") {\n const m = next().toUpperCase();\n if ((HTTP_METHODS as string[]).includes(m)) method = m as HttpMethod;\n } else if (t === \"-H\" || t === \"--header\") {\n const raw = next();\n const idx = raw.indexOf(\":\");\n if (idx > 0) {\n headers.push({\n key: raw.slice(0, idx).trim(),\n value: raw.slice(idx + 1).trim(),\n enabled: true,\n });\n }\n } else if (\n t === \"-d\" ||\n t === \"--data\" ||\n t === \"--data-raw\" ||\n t === \"--data-binary\" ||\n t === \"--data-urlencode\"\n ) {\n bodyRaw = next();\n } else if (t === \"-F\" || t === \"--form\") {\n const raw = next();\n const idx = raw.indexOf(\"=\");\n if (idx > 0) {\n formData.push({ key: raw.slice(0, idx), value: raw.slice(idx + 1), enabled: true });\n }\n } else if (t === \"-u\" || t === \"--user\") {\n basicUser = next();\n } else if (t === \"--url\") {\n url = next();\n } else if (t === \"-L\" || t === \"--location\") {\n followRedirects = true;\n } else if (t.startsWith(\"-\")) {\n // Flags with an argument we don't map — skip their value so it isn't\n // mistaken for the URL.\n if (\n [\n \"-o\",\n \"--output\",\n \"-A\",\n \"--user-agent\",\n \"-e\",\n \"--referer\",\n \"-b\",\n \"--cookie\",\n \"--connect-timeout\",\n \"-m\",\n \"--max-time\",\n ].includes(t)\n ) {\n next();\n }\n // Bare boolean flags (-s, -k, --compressed, …) need nothing.\n } else if (!url) {\n url = t;\n }\n }\n\n if (!url) return null;\n\n const patch: Partial<HttpActionConfig> = { url, apiType: \"rest\" };\n\n // Split query string into queryParams so the panel shows them structured.\n const qIdx = url.indexOf(\"?\");\n if (qIdx >= 0) {\n const query = url.slice(qIdx + 1);\n patch.url = url.slice(0, qIdx);\n patch.queryParams = query\n .split(\"&\")\n .filter(Boolean)\n .map((pair) => {\n const eq = pair.indexOf(\"=\");\n const rawKey = eq >= 0 ? pair.slice(0, eq) : pair;\n const rawValue = eq >= 0 ? pair.slice(eq + 1) : \"\";\n const decode = (s: string) => {\n try {\n return decodeURIComponent(s.replace(/\\+/g, \"%20\"));\n } catch {\n return s;\n }\n };\n return { key: decode(rawKey), value: decode(rawValue), enabled: true };\n });\n }\n\n // Auth: Authorization header → bearer; -u → basic. The header row is\n // consumed by the auth config rather than kept as a plain header.\n const authHeaderIdx = headers.findIndex((h) => h.key.toLowerCase() === \"authorization\");\n if (authHeaderIdx >= 0 && /^bearer\\s+/i.test(headers[authHeaderIdx].value)) {\n patch.auth = {\n type: \"bearer\",\n token: headers[authHeaderIdx].value.replace(/^bearer\\s+/i, \"\"),\n };\n headers.splice(authHeaderIdx, 1);\n } else if (basicUser) {\n const sep = basicUser.indexOf(\":\");\n patch.auth = {\n type: \"basic\",\n username: sep >= 0 ? basicUser.slice(0, sep) : basicUser,\n password: sep >= 0 ? basicUser.slice(sep + 1) : \"\",\n };\n }\n\n if (headers.length) patch.headers = headers;\n if (followRedirects !== undefined) patch.followRedirects = followRedirects;\n\n if (formData.length) {\n patch.bodyType = \"form-data\";\n patch.formData = formData;\n patch.method = method ?? \"POST\";\n } else if (bodyRaw !== undefined) {\n try {\n patch.body = JSON.parse(bodyRaw);\n patch.bodyType = \"json\";\n } catch {\n patch.body = bodyRaw;\n patch.bodyType = \"raw\";\n }\n patch.method = method ?? \"POST\";\n } else {\n patch.method = method ?? \"GET\";\n patch.bodyType = \"none\";\n }\n\n return patch;\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/** Build a copy-pastable cURL command from the current config. */\nexport function buildCurl(config: HttpActionConfig): string {\n const parts: string[] = [\"curl\"];\n const method = config.apiType === \"graphql\" ? \"POST\" : (config.method ?? \"GET\");\n if (method !== \"GET\") parts.push(`-X ${method}`);\n\n let url = effectiveUrl(config.baseUrl, config.url);\n const params = normalizeKeyValues(config.queryParams).filter((p) => p.enabled !== false && p.key);\n if (params.length) {\n const qs = params\n .map((p) => `${encodeURIComponent(p.key)}=${encodeURIComponent(p.value)}`)\n .join(\"&\");\n url += (url.includes(\"?\") ? \"&\" : \"?\") + qs;\n }\n parts.push(shellQuote(url));\n\n for (const h of normalizeKeyValues(config.headers).filter((h) => h.enabled !== false && h.key)) {\n parts.push(`-H ${shellQuote(`${h.key}: ${h.value}`)}`);\n }\n\n const auth = config.auth;\n if (auth?.type === \"bearer\" && auth.token) {\n parts.push(`-H ${shellQuote(`Authorization: Bearer ${auth.token}`)}`);\n } else if (auth?.type === \"basic\" && auth.username) {\n parts.push(`-u ${shellQuote(`${auth.username}:${auth.password ?? \"\"}`)}`);\n } else if (auth?.type === \"apikey\" && auth.apiKeyName && auth.apiKeyValue) {\n if ((auth.apiKeyLocation ?? \"header\") === \"header\") {\n parts.push(`-H ${shellQuote(`${auth.apiKeyName}: ${auth.apiKeyValue}`)}`);\n }\n }\n\n if (config.apiType === \"graphql\") {\n const payload = JSON.stringify({\n query: config.graphqlQuery ?? \"\",\n variables:\n typeof config.graphqlVariables === \"string\"\n ? config.graphqlVariables\n : (config.graphqlVariables ?? {}),\n });\n parts.push(`-H ${shellQuote(\"Content-Type: application/json\")}`);\n parts.push(`-d ${shellQuote(payload)}`);\n } else if (config.bodyType === \"form-data\") {\n for (const f of normalizeKeyValues(config.formData).filter(\n (f) => f.enabled !== false && f.key,\n )) {\n parts.push(`-F ${shellQuote(`${f.key}=${f.value}`)}`);\n }\n } else if (config.bodyType && config.bodyType !== \"none\" && config.body != null) {\n const raw = typeof config.body === \"string\" ? config.body : JSON.stringify(config.body);\n if (raw) {\n if (config.bodyType === \"json\") {\n parts.push(`-H ${shellQuote(\"Content-Type: application/json\")}`);\n }\n parts.push(`-d ${shellQuote(raw)}`);\n }\n }\n\n if (config.followRedirects !== false) parts.push(\"-L\");\n return parts.join(\" \");\n}\n\n/* ── Response schema inference ─────────────────────────────────────────── */\n\ninterface InferredSchema {\n type: string;\n properties?: Record<string, InferredSchema>;\n items?: InferredSchema;\n}\n\n/** JSON-schema-shaped inference from a sample value (depth-capped). */\nexport function inferJsonSchema(value: unknown, depth = 0): InferredSchema {\n if (value === null || value === undefined) return { type: \"null\" };\n if (Array.isArray(value)) {\n if (!value.length || depth > 6) return { type: \"array\" };\n return { type: \"array\", items: inferJsonSchema(value[0], depth + 1) };\n }\n if (typeof value === \"object\") {\n if (depth > 6) return { type: \"object\" };\n const properties: Record<string, InferredSchema> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n properties[k] = inferJsonSchema(v, depth + 1);\n }\n return { type: \"object\", properties };\n }\n return { type: typeof value };\n}\n\n/** Count leaf+branch paths in an inferred schema (for the schema badge). */\nexport function countSchemaPaths(schema: unknown, depth = 0): number {\n if (!schema || typeof schema !== \"object\" || depth > 8) return 0;\n const s = schema as InferredSchema;\n let count = 0;\n if (s.type === \"object\" && s.properties) {\n for (const child of Object.values(s.properties)) {\n count += 1 + countSchemaPaths(child, depth + 1);\n }\n } else if (s.type === \"array\" && s.items) {\n count += countSchemaPaths(s.items, depth + 1);\n }\n return count;\n}\n\n/* ── Test-send (preview) contract ──────────────────────────────────────── */\n\nexport interface HttpPreviewRequest {\n method: HttpMethod;\n url: string;\n connectionId?: string;\n headers: HttpKeyValue[];\n queryParams: HttpKeyValue[];\n bodyType: HttpBodyType;\n body?: string;\n formData?: HttpKeyValue[];\n graphqlQuery?: string;\n graphqlVariables?: string;\n auth: HttpAuthConfig;\n timeout: number;\n}\n\nexport interface HttpPreviewResponse {\n status: number;\n statusText: string;\n ok: boolean;\n headers: Record<string, string>;\n /** Parsed body (object for JSON) or raw string; binary hosts pass metadata only. */\n body: unknown;\n bodyRaw?: string;\n /** Response size in bytes. */\n size: number;\n /** Round-trip time in ms. */\n duration: number;\n}\n\nexport function statusTone(status: number): \"success\" | \"info\" | \"warning\" | \"error\" {\n if (status < 300) return \"success\";\n if (status < 400) return \"info\";\n if (status < 500) return \"warning\";\n return \"error\";\n}\n\nexport function formatBytes(size: number): string {\n return size < 1024 ? `${size} B` : `${(size / 1024).toFixed(1)} KB`;\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FlowCanvas v2 — the editor kernel.\n// ════════════════════════════════════════════════════════════════════════\n// Responsibilities:\n// 1. Mount the per-canvas store + handle registry; provide their contexts.\n// 2. Render the viewport (transform: translate(x,y) scale(zoom)).\n// 3. Own Pointer Events for pan, zoom, drag, and connect; route to the\n// right middleware via a single pointermove handler installed on the\n// window during an active gesture.\n// 4. Emit batched onNodesChange / onEdgesChange / onConnect / ...\n// 5. Mirror controlled `nodes` / `edges` props into the store each render\n// so descendants read fresh data via selectors.\n\nimport {\n type CSSProperties,\n memo,\n type PointerEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type WheelEvent,\n} from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport type {\n ConnectEndState,\n Connection,\n ConnectStartParams,\n EdgeChange,\n NodeChange,\n Position,\n Viewport,\n WorkflowEdge,\n WorkflowNode,\n} from \"../../editor\";\nimport { type FlowInstance, FlowInstanceContext } from \"../../hooks/useFlow\";\nimport { change } from \"../../store/changes\";\nimport { FlowStoreContext } from \"../../store/context\";\nimport { createFlowStore } from \"../../store/createFlowStore\";\nimport { resolveNodeCollisions } from \"../../utils/collision\";\nimport {\n DEFAULT_NODE_HEIGHT,\n DEFAULT_NODE_WIDTH,\n effectiveHeight,\n flowToScreen,\n handleCentre,\n screenToFlow,\n} from \"../../utils/geometry\";\nimport {\n clampToParentExtent,\n descendantsOf,\n findContainingGroup,\n isContainerType,\n} from \"../../utils/parenting\";\nimport { FlowEdge } from \"../FlowEdge/FlowEdge\";\nimport { FlowNode } from \"../FlowNode/FlowNode\";\nimport { buildNodeKindRegistry, type NodeKindRegistry } from \"../FlowNode/nodeKinds\";\nimport {\n createHandleRegistry,\n type HandleDescriptor,\n HandleRegistryContext,\n} from \"../Handle/handleRegistry\";\nimport { type BuiltInNodeData, DEFAULT_NODE_KINDS } from \"../kinds\";\nimport {\n type FlowDispatch,\n type FlowDispatchAction,\n FlowDispatchContext,\n type FlowNodeBridge,\n FlowNodeBridgeContext,\n} from \"./FlowCanvasContext\";\n\nexport interface FlowCanvasProps {\n nodes: WorkflowNode[];\n edges: WorkflowEdge[];\n onNodesChange?: (changes: NodeChange[]) => void;\n onEdgesChange?: (changes: EdgeChange[]) => void;\n\n // Viewport\n viewport?: Viewport;\n defaultViewport?: Viewport;\n onViewportChange?: (viewport: Viewport) => void;\n minZoom?: number;\n maxZoom?: number;\n /**\n * Auto-frame the existing nodes on first mount so the canvas opens\n * centered on content rather than at the {0,0,1} origin. Defaults to\n * `true` when no explicit `viewport` or `defaultViewport` is supplied;\n * when the consumer pins either prop the canvas honours that and skips\n * the auto-fit. Pass `false` to opt out unconditionally. Pass\n * `{ padding, minZoom, maxZoom }` to tune the framing.\n */\n fitViewOnInit?: boolean | { padding?: number; minZoom?: number; maxZoom?: number };\n\n // Node kinds\n nodeKinds?: NodeKindRegistry;\n\n // Connection\n onConnect?: (connection: Connection) => void;\n onConnectStart?: (\n event: PointerEvent | globalThis.PointerEvent,\n params: ConnectStartParams,\n ) => void;\n onConnectEnd?: (event: PointerEvent | globalThis.PointerEvent, state: ConnectEndState) => void;\n isValidConnection?: (connection: Connection) => boolean;\n\n // Selection\n onSelectionChange?: (selection: { nodes: WorkflowNode[]; edges: WorkflowEdge[] }) => void;\n onPaneClick?: () => void;\n onNodeClick?: (node: WorkflowNode) => void;\n onEdgeClick?: (edge: WorkflowEdge) => void;\n /** Double-clicking an edge label opens an inline editor; commit fires\n * this callback. When omitted, labels are not editable. */\n onEdgeLabelChange?: (id: string, label: string) => void;\n /** Fires once when the canvas mounts. Hand-off for the imperative\n * instance — consumers store it to call `fitView`, `addNodes`, etc. */\n onInit?: (instance: FlowInstance) => void;\n /** Async veto for deletions. Return `false` (or a Promise resolving\n * false) to block. Fires from `instance.deleteElements`, Backspace,\n * and the edge X button. */\n onBeforeDelete?: (params: {\n nodes: WorkflowNode[];\n edges: WorkflowEdge[];\n }) => boolean | Promise<boolean>;\n /** Right-click on a node. Consumer must `preventDefault()` to suppress\n * the browser's native menu. */\n onNodeContextMenu?: (event: React.MouseEvent, node: WorkflowNode) => void;\n /** Right-click on an edge. */\n onEdgeContextMenu?: (event: React.MouseEvent, edge: WorkflowEdge) => void;\n /** Right-click on the empty pane. */\n onPaneContextMenu?: (event: React.MouseEvent) => void;\n\n // Policies\n nodesDraggable?: boolean;\n nodesConnectable?: boolean;\n panOnDrag?: boolean;\n zoomOnScroll?: boolean;\n /**\n * Trackpad / touch behaviour preset.\n *\n * - `\"mouse\"` (default): mouse-first. Drag the pane to pan;\n * wheel zooms; pinch zooms.\n * - `\"trackpad\"`: two-finger trackpad scroll pans; pinch zooms;\n * wheel-with-Ctrl zooms. Drag the pane is still pan (`panOnDrag`).\n * - `\"touch\"`: same as trackpad but with enlarged hit areas (44 px\n * on coarse pointers via `@media (pointer: coarse)`) and no pan\n * on plain drag — single-finger drag selects, two-finger pans.\n *\n * Override individual policies (`panOnDrag`, `zoomOnScroll`, etc.)\n * after picking a preset to fine-tune.\n */\n preset?: \"mouse\" | \"trackpad\" | \"touch\";\n /** Pixels of pointer travel during a pane-press before it stops counting\n * as a click (used to decide whether to clear selection on pointerup). */\n paneClickDistance?: number;\n /**\n * Whether a click on the empty canvas pane clears the current node /\n * edge selection. Defaults to `true` (the design-tool standard:\n * \"click background to deselect\"). Set to `false` when selection\n * should persist through pane clicks — e.g. when a side ConfigPanel\n * stays open until the user dismisses it explicitly.\n *\n * `onPaneClick` still fires regardless; this only controls whether\n * the canvas also clears its internal selection state.\n */\n paneClickClearsSelection?: boolean;\n\n // Visual canvas options\n /** Background grid style. Defaults to `\"dots\"`. */\n background?: \"dots\" | \"lines\" | \"cross\" | \"none\";\n /** Grid pitch in flow-space pixels. Defaults to 20. Also used for snap. */\n gridSize?: number;\n /** Snap node positions to the grid on drag-end. Defaults to false. */\n snapToGrid?: boolean;\n /**\n * Minimum gap (px) between sibling nodes during drag. When >= 0, a\n * dragged node is \"magnet snapped\" so it stays at least `nodeCollisionGap`\n * pixels from every other sibling — siblings share the same `parentId`\n * (or are both top-level). `0` means \"no overlap allowed, zero buffer.\"\n * Pass `-1` (the default) to disable collision avoidance entirely.\n */\n nodeCollisionGap?: number;\n /**\n * Same as `nodeCollisionGap` but applied to subflow containers\n * (`isContainerType` — i.e. `group`; `forEach` is a simple node). Lets you\n * keep groups visually separated without applying the rule to the action\n * nodes inside. Default falls back to `nodeCollisionGap`.\n */\n subflowCollisionGap?: number;\n\n /**\n * When `true`, dragging a node into another container's bbox sets\n * the dragged node's `parentId`; dragging out clears it — without\n * requiring the Alt modifier key. Default `false` preserves the\n * legacy Alt-drag-to-reparent behaviour for backward compatibility.\n *\n * Pairs with `autoResizeContainers` to deliver the full \"drop nodes\n * inside a group\" UX consumers usually want from a subflow editor.\n */\n reparentOnDrag?: boolean;\n\n /**\n * When `true`, container kinds (`group` / `forEach`) auto-resize at\n * drag-end so the frame encloses all current children plus padding.\n * The reposition + dimension update is folded into the same\n * `onNodesChange` call as the drag-end position change, so a child\n * dropped near the edge of a container can't miss the parent's\n * post-resize bbox in a follow-up render tick (the host-side race\n * the parented-on-drop UX would otherwise hit).\n *\n * Default `false`. Pair with `reparentOnDrag` for the full flow.\n */\n autoResizeContainers?: boolean;\n\n /**\n * Padding (in flow-space pixels) added around children's bbox when\n * `autoResizeContainers` recomputes a container's frame. Default 32.\n */\n containerAutoResizePadding?: number;\n\n /**\n * Floor size for `autoResizeContainers`. A container that fits its\n * children in less than this stops shrinking here — it never collapses\n * below the size a freshly-dropped (empty) container would have.\n * Defaults: 320 × 200.\n */\n containerMinWidth?: number;\n containerMinHeight?: number;\n\n // Layout\n height?: number | string;\n width?: number | string;\n className?: string;\n style?: CSSProperties;\n children?: ReactNode;\n emptyState?: ReactNode;\n}\n\nconst DEFAULT_VIEWPORT: Viewport = { x: 0, y: 0, zoom: 1 };\n\nexport function FlowCanvas(props: FlowCanvasProps) {\n // Capture whether the consumer explicitly handed us either viewport\n // prop. We can't tell from the destructured value alone (the default\n // assignment below would obscure an undefined explicit pass), and the\n // auto-fit fallback needs to know \"did the consumer pin the viewport,\n // or are we free to frame the nodes?\".\n const viewportPropProvided = props.viewport !== undefined || props.defaultViewport !== undefined;\n const {\n nodes,\n edges,\n onNodesChange,\n onEdgesChange,\n viewport: controlledViewport,\n defaultViewport = DEFAULT_VIEWPORT,\n onViewportChange,\n minZoom = 0.25,\n maxZoom = 2,\n fitViewOnInit,\n nodeKinds,\n onConnect,\n onConnectStart,\n onConnectEnd,\n isValidConnection,\n onSelectionChange,\n onPaneClick,\n onNodeClick,\n onEdgeClick,\n onEdgeLabelChange,\n onInit,\n onBeforeDelete,\n onNodeContextMenu,\n onEdgeContextMenu,\n onPaneContextMenu,\n nodesDraggable = true,\n nodesConnectable = true,\n panOnDrag: panOnDragProp,\n zoomOnScroll: zoomOnScrollProp,\n preset = \"mouse\",\n paneClickDistance = 4,\n paneClickClearsSelection = true,\n background = \"dots\",\n gridSize = 20,\n snapToGrid = false,\n nodeCollisionGap = -1,\n subflowCollisionGap,\n reparentOnDrag = false,\n autoResizeContainers = false,\n containerAutoResizePadding = 32,\n containerMinWidth = 320,\n containerMinHeight = 200,\n height = \"100%\",\n width = \"100%\",\n className,\n style,\n children,\n emptyState,\n } = props;\n // Resolve the preset defaults — individual props override. The presets\n // map to the documented interaction modes:\n // - mouse: pan-on-drag, wheel zoom\n // - trackpad: pan-on-drag still on (so users can grab the pane), but\n // two-finger trackpad scroll also pans (translated as wheel delta);\n // pinch zooms; wheel-zoom remains on for Ctrl+scroll.\n // - touch: drag the pane = box-select intent, no auto-pan\n // (single-finger drag is reserved for selection on touch surfaces).\n const presetDefaults = {\n mouse: { panOnDrag: true, zoomOnScroll: true },\n trackpad: { panOnDrag: true, zoomOnScroll: true },\n touch: { panOnDrag: false, zoomOnScroll: true },\n } as const;\n const panOnDrag = panOnDragProp ?? presetDefaults[preset].panOnDrag;\n const zoomOnScroll = zoomOnScrollProp ?? presetDefaults[preset].zoomOnScroll;\n\n // ── Singletons that live for the lifetime of this canvas ──\n const store = useState(() =>\n createFlowStore({\n initialNodes: nodes,\n initialEdges: edges,\n initialViewport: controlledViewport ?? defaultViewport,\n }),\n )[0];\n const handleRegistry = useState(() => createHandleRegistry())[0];\n\n // Subscribe to handle (un)registrations. Each Handle's `useEffect`\n // commits AFTER the surrounding render, so edges rendered in the same\n // commit as a node remount (typical for subflow collapse/uncollapse)\n // resolve against a stale registry and fall back to default ports.\n // Bumping this counter forces a follow-up render once the effects fire.\n const [handleVersion, setHandleVersion] = useState(0);\n useEffect(() => {\n const unsub = handleRegistry.subscribe(() => {\n setHandleVersion((v) => v + 1);\n });\n return unsub;\n }, [handleRegistry]);\n\n // Merge built-in kinds with consumer overrides. Frozen so consumers\n // can't mutate the registry mid-flight.\n const kinds = useMemo(() => buildNodeKindRegistry(DEFAULT_NODE_KINDS, nodeKinds), [nodeKinds]);\n\n const containerRef = useRef<HTMLDivElement>(null);\n\n // ── Mirror controlled props → store ───────────────────────────────────\n useEffect(() => store.setNodes(nodes), [store, nodes]);\n useEffect(() => store.setEdges(edges), [store, edges]);\n\n // ── Viewport (controlled or uncontrolled) ─────────────────────────────\n const [uncontrolledVp, setUncontrolledVp] = useState(controlledViewport ?? defaultViewport);\n const viewport = controlledViewport ?? uncontrolledVp;\n useEffect(() => store.setViewport(viewport), [store, viewport]);\n const setViewport = useCallback(\n (next: Viewport) => {\n if (controlledViewport === undefined) setUncontrolledVp(next);\n onViewportChange?.(next);\n },\n [controlledViewport, onViewportChange],\n );\n\n // ── Selection — derived from `node.selected` / `edge.selected` in props.\n // We do NOT keep a parallel ref because that would drift the moment a\n // consumer set a node.selected = true via their own state. The single\n // source of truth is the props.\n const selectedNodeIds = useMemo(() => {\n const s = new Set<string>();\n for (const n of nodes) if (n.selected) s.add(n.id);\n return s;\n }, [nodes]);\n const selectedEdgeIds = useMemo(() => {\n const s = new Set<string>();\n for (const e of edges) if (e.selected) s.add(e.id);\n return s;\n }, [edges]);\n\n // Sync resolved selection into the store so descendants can read it.\n useEffect(() => {\n store.setSelection(selectedNodeIds, selectedEdgeIds);\n if (onSelectionChange) {\n onSelectionChange({\n nodes: nodes.filter((n) => selectedNodeIds.has(n.id)),\n edges: edges.filter((e) => selectedEdgeIds.has(e.id)),\n });\n }\n }, [store, selectedNodeIds, selectedEdgeIds, nodes, edges, onSelectionChange]);\n\n // Selection state only — does NOT fire `onNodeClick`. The click event\n // is dispatched separately from the click path in FlowNode, so drag\n // starts (which need to select the node so it carries selection styles)\n // don't accidentally fire the consumer's click handler.\n const selectNode = useCallback(\n (id: string, additive: boolean) => {\n const next: NodeChange[] = [];\n const nextEdges: EdgeChange[] = [];\n if (!additive) {\n for (const n of nodes) {\n if (n.selected && n.id !== id) next.push(change.node.select(n.id, false));\n }\n for (const e of edges) {\n if (e.selected) nextEdges.push(change.edge.select(e.id, false));\n }\n }\n const isSelected = selectedNodeIds.has(id);\n if (additive && isSelected) {\n // Toggle off when meta-clicking an already-selected node.\n next.push(change.node.select(id, false));\n } else if (!isSelected) {\n next.push(change.node.select(id, true));\n }\n if (next.length) onNodesChange?.(next);\n if (nextEdges.length) onEdgesChange?.(nextEdges);\n },\n [nodes, edges, selectedNodeIds, onNodesChange, onEdgesChange],\n );\n\n // Click notification — fires the consumer's `onNodeClick`. FlowNode\n // calls this AFTER `selectNode` only when the gesture was a click,\n // not a drag. Separating the two lets drag-start update selection\n // without firing the click event.\n const notifyNodeClick = useCallback(\n (id: string) => {\n const node = nodes.find((n) => n.id === id);\n if (node) onNodeClick?.(node);\n },\n [nodes, onNodeClick],\n );\n\n const selectEdge = useCallback(\n (id: string, additive: boolean) => {\n const next: EdgeChange[] = [];\n const nextNodes: NodeChange[] = [];\n if (!additive) {\n for (const e of edges) {\n if (e.selected && e.id !== id) next.push(change.edge.select(e.id, false));\n }\n for (const n of nodes) {\n if (n.selected) nextNodes.push(change.node.select(n.id, false));\n }\n }\n const isSelected = selectedEdgeIds.has(id);\n if (additive && isSelected) {\n next.push(change.edge.select(id, false));\n } else if (!isSelected) {\n next.push(change.edge.select(id, true));\n }\n if (next.length) onEdgesChange?.(next);\n if (nextNodes.length) onNodesChange?.(nextNodes);\n const edge = edges.find((e) => e.id === id);\n if (edge) onEdgeClick?.(edge);\n },\n [nodes, edges, selectedEdgeIds, onEdgesChange, onNodesChange, onEdgeClick],\n );\n\n const clearSelection = useCallback(() => {\n const ns: NodeChange[] = [];\n const es: EdgeChange[] = [];\n for (const n of nodes) if (n.selected) ns.push(change.node.select(n.id, false));\n for (const e of edges) if (e.selected) es.push(change.edge.select(e.id, false));\n if (ns.length) onNodesChange?.(ns);\n if (es.length) onEdgesChange?.(es);\n }, [nodes, edges, onNodesChange, onEdgesChange]);\n\n // ── Node drag middleware ──────────────────────────────────────────────\n // Drag also moves transitive descendants (children of a parent move with\n // the parent), respects `extent: 'parent'` clamping, and supports\n // Alt-detach for re-parenting subflow children.\n type DragState = {\n pointerId: number;\n nodeId: string;\n startClientX: number;\n startClientY: number;\n startPosition: Position;\n /** Captured at drag-start so each pointermove can reposition all\n * descendants by the same delta without re-walking the tree. */\n descendants: { id: string; startPosition: Position }[];\n /** Skip the `extent: 'parent'` clamp for this drag. True only when\n * the node is genuinely free to leave its parent: an explicit\n * Alt-detach, or a top-level node (no parent) that `reparentOnDrag`\n * lets travel into a container. A parented child on a plain drag\n * stays clamped — that's what keeps a subflow child in its frame. */\n skipClamp: boolean;\n /** Hit-test for a new parent at drag-end (Alt held OR the consumer\n * opted into `reparentOnDrag`). */\n evaluateReparent: boolean;\n rafScheduled: boolean;\n nextDelta: { dx: number; dy: number } | null;\n };\n const dragRef = useRef<DragState | null>(null);\n const [draggingId, setDraggingId] = useState<string | null>(null);\n\n const beginNodeDrag = useCallback(\n (nodeId: string, pointerId: number, clientX: number, clientY: number, altKey = false) => {\n if (!nodesDraggable) return;\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return;\n const kids = descendantsOf(nodeId, nodes).map((d) => ({\n id: d.id,\n startPosition: d.position,\n }));\n // Reparenting is \"in play\" when the user held Alt OR the consumer\n // set `reparentOnDrag`. That decides whether we hit-test for a new\n // parent at drag-end.\n const evaluateReparent = altKey || reparentOnDragRef.current;\n // The extent clamp is short-circuited ONLY when the node is truly\n // free to leave its parent:\n // • Alt held → explicit detach gesture.\n // • reparentOnDrag + node has no parent → a top-level node that\n // should be able to travel INTO a container.\n // A parented child on a plain drag keeps its clamp even with\n // `reparentOnDrag` on, so subflow children can't slide out of the\n // frame by accident — detaching one is a deliberate Alt-drag.\n const hasParent = !!node.parentId;\n const skipClamp = altKey || (reparentOnDragRef.current && !hasParent);\n dragRef.current = {\n pointerId,\n nodeId,\n startClientX: clientX,\n startClientY: clientY,\n startPosition: node.position,\n descendants: kids,\n skipClamp,\n evaluateReparent,\n rafScheduled: false,\n nextDelta: null,\n };\n setDraggingId(nodeId);\n selectNode(nodeId, false);\n },\n [nodes, nodesDraggable, selectNode],\n );\n\n // ── Connection middleware ─────────────────────────────────────────────\n // `connection` is local state. The ghost-line component subscribes here\n // (via prop), the rest of the canvas does not — so a connection drag\n // does NOT re-render every node. Setting state inside the global\n // pointermove handler still triggers a re-render of FlowCanvas itself,\n // but that's just the SVG ghost; the node list and edges are memoised.\n const [conn, setConn] = useState<{\n pointerId: number;\n from: ConnectStartParams;\n start: Position;\n end: Position;\n } | null>(null);\n // We keep a ref mirror so the global pointermove handler can read the\n // latest value without re-attaching listeners on every state change.\n const connRef = useRef<typeof conn>(null);\n useEffect(() => {\n connRef.current = conn;\n }, [conn]);\n\n const beginConnection = useCallback(\n (\n nodeId: string,\n handleId: string,\n handleType: \"source\" | \"target\",\n pointerId: number,\n clientX: number,\n clientY: number,\n ) => {\n if (!nodesConnectable) return;\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return;\n // Compute the originating handle's flow-space centre so the ghost\n // line is visible from the very first frame (no flicker).\n const desc = handleRegistry.resolve(nodeId, handleType, handleId);\n const side = desc?.side ?? (handleType === \"source\" ? \"bottom\" : \"top\");\n const index = desc?.index ?? 0;\n const total = desc?.total ?? 1;\n const ratio = (index + 1) / (total + 1);\n // Default width matches the BaseNode body (368 px) so the ghost\n // line origin lands ON the handle dot even before the ResizeObserver\n // has reported the real measured width back through `onNodesChange`.\n const w = node.width ?? 368;\n // Use the effective height — collapsed containers render a tiny\n // strip; without this the ghost line would start far below the\n // visible group when dragging from a perimeter handle.\n const h = effectiveHeight(node);\n const start: Position = (() => {\n switch (side) {\n case \"top\":\n return { x: node.position.x + w * ratio, y: node.position.y };\n case \"bottom\":\n return { x: node.position.x + w * ratio, y: node.position.y + h };\n case \"left\":\n return { x: node.position.x, y: node.position.y + h * ratio };\n case \"right\":\n return { x: node.position.x + w, y: node.position.y + h * ratio };\n }\n })();\n const from: ConnectStartParams = { nodeId, handleId, handleType };\n const rect = containerRef.current?.getBoundingClientRect();\n const end = rect\n ? screenToFlow({ x: clientX - rect.left, y: clientY - rect.top }, viewport)\n : start;\n setConn({ pointerId, from, start, end });\n store.setConnection(from);\n onConnectStart?.({ clientX, clientY, pointerId } as unknown as globalThis.PointerEvent, from);\n },\n [nodes, nodesConnectable, handleRegistry, viewport, store, onConnectStart],\n );\n\n // ── Refs that the global pointer listeners read so they don't depend\n // ── on captured callback identity (avoids listener re-attach storms).\n const viewportRef = useRef(viewport);\n const nodesRef = useRef(nodes);\n const edgesRef = useRef(edges);\n const onNodesChangeRefForInstance = useRef(onNodesChange);\n const onEdgesChangeRefForInstance = useRef(onEdgesChange);\n const onBeforeDeleteRef = useRef(onBeforeDelete);\n const snapToGridRef = useRef(snapToGrid);\n const gridSizeRef = useRef(gridSize);\n const nodeCollisionGapRef = useRef(nodeCollisionGap);\n const subflowCollisionGapRef = useRef(subflowCollisionGap ?? nodeCollisionGap);\n const reparentOnDragRef = useRef(reparentOnDrag);\n const autoResizeContainersRef = useRef(autoResizeContainers);\n const containerAutoResizePaddingRef = useRef(containerAutoResizePadding);\n const containerMinWidthRef = useRef(containerMinWidth);\n const containerMinHeightRef = useRef(containerMinHeight);\n useEffect(() => {\n edgesRef.current = edges;\n }, [edges]);\n useEffect(() => {\n onNodesChangeRefForInstance.current = onNodesChange;\n }, [onNodesChange]);\n useEffect(() => {\n onEdgesChangeRefForInstance.current = onEdgesChange;\n }, [onEdgesChange]);\n useEffect(() => {\n onBeforeDeleteRef.current = onBeforeDelete;\n }, [onBeforeDelete]);\n useEffect(() => {\n snapToGridRef.current = snapToGrid;\n }, [snapToGrid]);\n useEffect(() => {\n gridSizeRef.current = gridSize;\n }, [gridSize]);\n useEffect(() => {\n nodeCollisionGapRef.current = nodeCollisionGap;\n }, [nodeCollisionGap]);\n useEffect(() => {\n subflowCollisionGapRef.current = subflowCollisionGap ?? nodeCollisionGap;\n }, [subflowCollisionGap, nodeCollisionGap]);\n useEffect(() => {\n reparentOnDragRef.current = reparentOnDrag;\n }, [reparentOnDrag]);\n useEffect(() => {\n autoResizeContainersRef.current = autoResizeContainers;\n }, [autoResizeContainers]);\n useEffect(() => {\n containerAutoResizePaddingRef.current = containerAutoResizePadding;\n }, [containerAutoResizePadding]);\n useEffect(() => {\n containerMinWidthRef.current = containerMinWidth;\n }, [containerMinWidth]);\n useEffect(() => {\n containerMinHeightRef.current = containerMinHeight;\n }, [containerMinHeight]);\n const onNodesChangeRef = useRef(onNodesChange);\n const onConnectRef = useRef(onConnect);\n const onConnectEndRef = useRef(onConnectEnd);\n const isValidConnectionRef = useRef(isValidConnection);\n useEffect(() => {\n viewportRef.current = viewport;\n }, [viewport]);\n useEffect(() => {\n nodesRef.current = nodes;\n }, [nodes]);\n useEffect(() => {\n onNodesChangeRef.current = onNodesChange;\n }, [onNodesChange]);\n useEffect(() => {\n onConnectRef.current = onConnect;\n }, [onConnect]);\n useEffect(() => {\n onConnectEndRef.current = onConnectEnd;\n }, [onConnectEnd]);\n useEffect(() => {\n isValidConnectionRef.current = isValidConnection;\n }, [isValidConnection]);\n\n // ── Pointer dispatch — single window-level listener installed ONCE.\n // All gesture deps come through refs, so this effect runs once per\n // mount and never re-attaches.\n useEffect(() => {\n const onPointerMove = (e: globalThis.PointerEvent) => {\n const vp = viewportRef.current;\n // Node drag\n const drag = dragRef.current;\n if (drag && drag.pointerId === e.pointerId) {\n const dx = (e.clientX - drag.startClientX) / vp.zoom;\n const dy = (e.clientY - drag.startClientY) / vp.zoom;\n drag.nextDelta = { dx, dy };\n if (!drag.rafScheduled) {\n drag.rafScheduled = true;\n requestAnimationFrame(() => {\n const d = dragRef.current;\n if (!d) return;\n d.rafScheduled = false;\n const delta = d.nextDelta;\n if (!delta) return;\n // Compute the proposed new position for the dragged node.\n const dragNode = nodesRef.current.find((n) => n.id === d.nodeId);\n if (!dragNode) return;\n const proposed = {\n x: d.startPosition.x + delta.dx,\n y: d.startPosition.y + delta.dy,\n };\n // Apply extent:'parent' clamping unless this drag is allowed\n // to leave the parent (Alt-detach, or a top-level node free\n // to roam). A clamped child can't be dragged out of frame.\n const clamped = d.skipClamp\n ? proposed\n : clampToParentExtent(dragNode, proposed, nodesRef.current);\n // Magnet collision — push out of any sibling we're overlapping\n // (or sitting closer than `gap` to). Subflow containers use\n // `subflowCollisionGap`; regular nodes use `nodeCollisionGap`.\n // Descendants of the dragged node never participate, so a\n // parent can move freely through the space its children occupy.\n const isContainer = isContainerType(dragNode.type);\n const gap = isContainer ? subflowCollisionGapRef.current : nodeCollisionGapRef.current;\n const excludeIds = new Set<string>([d.nodeId, ...d.descendants.map((kid) => kid.id)]);\n const finalPos = resolveNodeCollisions(dragNode, clamped, nodesRef.current, {\n gap,\n exclude: excludeIds,\n });\n // The realised delta may differ from the proposed delta after\n // clamping and collision — use it for shifting descendants so\n // they stay glued to the parent.\n const realDx = finalPos.x - d.startPosition.x;\n const realDy = finalPos.y - d.startPosition.y;\n const changes: NodeChange[] = [change.node.position(d.nodeId, finalPos, true)];\n for (const kid of d.descendants) {\n changes.push(\n change.node.position(\n kid.id,\n { x: kid.startPosition.x + realDx, y: kid.startPosition.y + realDy },\n true,\n ),\n );\n }\n onNodesChangeRef.current?.(changes);\n });\n }\n }\n\n // Connection drag — only this branch sets React state, so the\n // re-render is limited to FlowCanvas itself (nodes + edges memoised).\n const c = connRef.current;\n if (c && c.pointerId === e.pointerId) {\n const rect = containerRef.current?.getBoundingClientRect();\n if (rect) {\n const end = screenToFlow({ x: e.clientX - rect.left, y: e.clientY - rect.top }, vp);\n setConn({ ...c, end });\n }\n }\n };\n\n const onPointerUp = (e: globalThis.PointerEvent) => {\n const vp = viewportRef.current;\n const drag = dragRef.current;\n if (drag && drag.pointerId === e.pointerId) {\n const dx = (e.clientX - drag.startClientX) / vp.zoom;\n const dy = (e.clientY - drag.startClientY) / vp.zoom;\n const dragNode = nodesRef.current.find((n) => n.id === drag.nodeId);\n if (dragNode) {\n let proposed = {\n x: drag.startPosition.x + dx,\n y: drag.startPosition.y + dy,\n };\n // Snap to grid on commit only — during drag the node follows\n // the pointer freely, but releases land on the nearest grid\n // intersection. UX is \"smooth move, satisfying click.\"\n if (snapToGridRef.current) {\n const g = gridSizeRef.current;\n proposed = {\n x: Math.round(proposed.x / g) * g,\n y: Math.round(proposed.y / g) * g,\n };\n }\n const clamped = drag.skipClamp\n ? proposed\n : clampToParentExtent(dragNode, proposed, nodesRef.current);\n // Run collision once more on commit — guards against a fast\n // pointer-up that bypassed the last rAF tick.\n const isContainer = isContainerType(dragNode.type);\n const gap = isContainer ? subflowCollisionGapRef.current : nodeCollisionGapRef.current;\n const excludeIds = new Set<string>([\n drag.nodeId,\n ...drag.descendants.map((kid) => kid.id),\n ]);\n const finalPos = resolveNodeCollisions(dragNode, clamped, nodesRef.current, {\n gap,\n exclude: excludeIds,\n });\n const realDx = finalPos.x - drag.startPosition.x;\n const realDy = finalPos.y - drag.startPosition.y;\n\n // Build the final commit. Dragging now becomes false.\n const changes: NodeChange[] = [change.node.position(drag.nodeId, finalPos, false)];\n for (const kid of drag.descendants) {\n changes.push(\n change.node.position(\n kid.id,\n { x: kid.startPosition.x + realDx, y: kid.startPosition.y + realDy },\n false,\n ),\n );\n }\n\n // Reparent evaluation: when `evaluateReparent` is set (Alt-held\n // OR `reparentOnDrag` prop enabled), hit-test the drop point\n // against existing containers. Three outcomes:\n // • Was parented, dropped outside any container → detach.\n // • Was parented, dropped inside a different container → reparent.\n // • Was top-level, dropped inside a container → adopt.\n // The replace-change is appended to the same `onNodesChange`\n // batch as the position change, so the consumer sees one\n // atomic update — no parentId/position race.\n if (drag.evaluateReparent) {\n // Hit-test the child's CENTRE. Fall back to the default\n // footprint (not 0) for unmeasured nodes — `?? 0` made the\n // centre collapse onto the top-left corner, so a node dropped\n // squarely on a container could miss it (DEV-200).\n const dragW = dragNode.width ?? DEFAULT_NODE_WIDTH;\n const dragH = effectiveHeight(dragNode);\n const targetGroup = findContainingGroup(\n {\n x: finalPos.x + dragW / 2,\n y: finalPos.y + dragH / 2,\n },\n nodesRef.current,\n [drag.nodeId, ...drag.descendants.map((d) => d.id)],\n );\n const nextParentId = targetGroup?.id;\n // Only emit a replace if parentage actually changed —\n // dragging a child around inside its own parent should NOT\n // re-emit the whole node every frame.\n if (nextParentId !== dragNode.parentId) {\n const updated: WorkflowNode = {\n ...dragNode,\n position: finalPos,\n parentId: nextParentId,\n // Adopting into a container always pins the child with\n // `extent: 'parent'` so it's clamped from the next drag\n // on. Detaching clears it.\n extent: nextParentId ? \"parent\" : undefined,\n };\n changes.push(change.node.replace(drag.nodeId, updated));\n\n // Grow-only fit on ADOPT: make sure the target container is\n // at least large enough to show the freshly-adopted child in\n // full. Otherwise the child overhangs the frame and then\n // \"jumps\" inside on the next drag when `extent: 'parent'`\n // clamps it. We only GROW (never shrink or reposition) so a\n // manually-sized frame is preserved — full auto-fit remains\n // opt-in via `autoResizeContainers`. DEV-200.\n if (targetGroup) {\n const pad = containerAutoResizePaddingRef.current;\n const curW = targetGroup.width ?? DEFAULT_NODE_WIDTH;\n const curH = targetGroup.height ?? effectiveHeight(targetGroup);\n const needW = finalPos.x + dragW + pad - targetGroup.position.x;\n const needH = finalPos.y + dragH + pad - targetGroup.position.y;\n const grownW = Math.max(curW, needW);\n const grownH = Math.max(curH, needH);\n if (grownW !== curW || grownH !== curH) {\n changes.push(\n change.node.dimensions(targetGroup.id, { width: grownW, height: grownH }),\n );\n }\n }\n }\n }\n\n // Container auto-resize: recompute each container's bbox from\n // its (post-drag, post-reparent) children + padding. Folded\n // into the same change batch so the consumer can't see a\n // half-resized frame between renders.\n if (autoResizeContainersRef.current) {\n const containerChanges = computeContainerAutoResize(\n nodesRef.current,\n // Projected children: apply the position + reparent\n // changes we just built before measuring bboxes.\n changes,\n containerAutoResizePaddingRef.current,\n containerMinWidthRef.current,\n containerMinHeightRef.current,\n );\n for (const c of containerChanges) changes.push(c);\n }\n\n onNodesChangeRef.current?.(changes);\n }\n dragRef.current = null;\n setDraggingId(null);\n }\n\n const c = connRef.current;\n if (c && c.pointerId === e.pointerId) {\n // ── Geometric drop-target resolution ──────────────────────────\n // We do NOT hit-test the DOM (`e.target.closest` /\n // `elementsFromPoint`). Inside a subflow the container frame,\n // the child nodes and their ports overlap and stack in ways\n // that make DOM hit-testing miss the intended port entirely.\n // Instead we project the pointer into flow-space and pick the\n // nearest registered handle within a snap radius — the same\n // source of truth edges already use for their geometry. This\n // is immune to z-index, pointer-events and overlapping frames.\n const rect = containerRef.current?.getBoundingClientRect();\n const flowPos = rect\n ? screenToFlow({ x: e.clientX - rect.left, y: e.clientY - rect.top }, vp)\n : { x: 0, y: 0 };\n\n // Snap radius: ~26 on-screen px, converted to flow-space so the\n // tolerance feels constant regardless of zoom.\n const snapRadius = 26 / Math.max(0.1, vp.zoom);\n let bestDesc: HandleDescriptor | null = null;\n let bestDist = snapRadius;\n for (const desc of handleRegistry.all()) {\n // Can't end on the source node itself, and the target must be\n // the OPPOSITE role — a `source` connects to a `target`.\n if (desc.nodeId === c.from.nodeId) continue;\n if (desc.type === c.from.handleType) continue;\n if (!desc.canEnd) continue;\n const targetNode = nodesRef.current.find((n) => n.id === desc.nodeId);\n if (!targetNode || targetNode.hidden) continue;\n const centre = handleCentre(targetNode, desc.side, desc.index, desc.total);\n const dist = Math.hypot(centre.x - flowPos.x, centre.y - flowPos.y);\n if (dist < bestDist) {\n bestDist = dist;\n bestDesc = desc;\n }\n }\n\n let connection: Connection | null = null;\n let connectedTo: ConnectStartParams | undefined;\n if (bestDesc) {\n const source =\n c.from.handleType === \"source\"\n ? c.from\n : {\n nodeId: bestDesc.nodeId,\n handleId: bestDesc.handleId,\n handleType: \"source\" as const,\n };\n const target2 =\n c.from.handleType === \"target\"\n ? c.from\n : {\n nodeId: bestDesc.nodeId,\n handleId: bestDesc.handleId,\n handleType: \"target\" as const,\n };\n connection = {\n source: source.nodeId,\n sourceHandle: source.handleId,\n target: target2.nodeId,\n targetHandle: target2.handleId,\n };\n connectedTo = {\n nodeId: bestDesc.nodeId,\n handleId: bestDesc.handleId,\n handleType: bestDesc.type,\n };\n const validator = isValidConnectionRef.current;\n if (validator && !validator(connection)) {\n connection = null;\n connectedTo = undefined;\n }\n }\n const endState: ConnectEndState = {\n cancelled: !connection,\n position: { x: e.clientX, y: e.clientY },\n flowPosition: flowPos,\n from: c.from,\n to: connectedTo,\n };\n if (connection) onConnectRef.current?.(connection);\n onConnectEndRef.current?.(e, endState);\n setConn(null);\n store.setConnection(null);\n }\n };\n\n const onPointerCancel = () => {\n if (dragRef.current) {\n dragRef.current = null;\n setDraggingId(null);\n }\n if (connRef.current) {\n setConn(null);\n store.setConnection(null);\n }\n };\n\n window.addEventListener(\"pointermove\", onPointerMove);\n window.addEventListener(\"pointerup\", onPointerUp);\n window.addEventListener(\"pointercancel\", onPointerCancel);\n return () => {\n window.removeEventListener(\"pointermove\", onPointerMove);\n window.removeEventListener(\"pointerup\", onPointerUp);\n window.removeEventListener(\"pointercancel\", onPointerCancel);\n };\n }, [store]); // mount-only\n\n // ── Container auto-resize — catch-all ─────────────────────────────────\n // The drag-end commit resizes containers atomically for the drag case.\n // This effect covers every OTHER way a container's children change:\n // a node dropped in from an action drawer, a child deleted, a paste.\n // It's a no-op during an active drag (the commit path owns that) and\n // `computeContainerAutoResize` returns [] when nothing is dirty, so a\n // settled graph can't loop.\n useEffect(() => {\n if (!autoResizeContainers || draggingId) return;\n const resizeChanges = computeContainerAutoResize(\n nodes,\n [],\n containerAutoResizePadding,\n containerMinWidth,\n containerMinHeight,\n );\n if (resizeChanges.length > 0) onNodesChange?.(resizeChanges);\n }, [\n nodes,\n draggingId,\n autoResizeContainers,\n containerAutoResizePadding,\n containerMinWidth,\n containerMinHeight,\n onNodesChange,\n ]);\n\n // ── Pan (canvas drag) ─────────────────────────────────────────────────\n // We DON'T clear selection on pan-start (issue #4 from the audit). The\n // pointerup handler decides whether this was a click (no movement) and\n // only clears selection then.\n const panRef = useRef<{\n pointerId: number;\n startClientX: number;\n startClientY: number;\n startVp: Viewport;\n moved: boolean;\n } | null>(null);\n const onCanvasPointerDown = (e: PointerEvent<HTMLDivElement>) => {\n if (e.button !== 0) return;\n const t = e.target as HTMLElement;\n if (\n t.closest(\"[data-node-id]\") ||\n t.closest(\"[data-edge-id]\") ||\n t.closest(\"[data-handle-id]\")\n ) {\n return;\n }\n if (!panOnDrag) {\n // Even without pan, a click on the pane should clear selection.\n panRef.current = {\n pointerId: e.pointerId,\n startClientX: e.clientX,\n startClientY: e.clientY,\n startVp: viewport,\n moved: false,\n };\n return;\n }\n panRef.current = {\n pointerId: e.pointerId,\n startClientX: e.clientX,\n startClientY: e.clientY,\n startVp: viewport,\n moved: false,\n };\n };\n\n useEffect(() => {\n const onMove = (e: globalThis.PointerEvent) => {\n const pan = panRef.current;\n if (!pan || pan.pointerId !== e.pointerId) return;\n const dx = e.clientX - pan.startClientX;\n const dy = e.clientY - pan.startClientY;\n if (Math.abs(dx) > paneClickDistance || Math.abs(dy) > paneClickDistance) {\n if (!pan.moved) setPanGesture(true);\n pan.moved = true;\n }\n if (pan.moved && panOnDrag) {\n setViewport({ ...pan.startVp, x: pan.startVp.x + dx, y: pan.startVp.y + dy });\n }\n };\n const onUp = () => {\n const pan = panRef.current;\n if (!pan) return;\n // A genuine \"click\" on the pane (no significant movement) fires\n // onPaneClick. Selection is cleared only when the consumer opts in\n // — consumers that keep a side-panel open through pane clicks pass\n // `paneClickClearsSelection={false}`. A drag-pan does neither.\n if (!pan.moved) {\n onPaneClick?.();\n if (paneClickClearsSelection) clearSelection();\n }\n panRef.current = null;\n setPanGesture(false);\n };\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n window.addEventListener(\"pointercancel\", onUp);\n return () => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n window.removeEventListener(\"pointercancel\", onUp);\n };\n }, [\n setViewport,\n paneClickDistance,\n panOnDrag,\n onPaneClick,\n clearSelection,\n paneClickClearsSelection,\n ]);\n\n // ── Wheel-zoom ────────────────────────────────────────────────────────\n // Attached as a NON-PASSIVE native listener (see effect below) rather than\n // via React's `onWheel`. React registers wheel handlers as passive, so\n // `preventDefault()` inside a React onWheel is silently ignored — the\n // trackpad pinch (ctrl+wheel) then zoomed the whole browser page instead\n // of the canvas (DEV-206). A native listener with `{ passive: false }`\n // lets preventDefault actually take effect.\n const handleWheel = (e: globalThis.WheelEvent) => {\n if (!zoomOnScroll) return;\n e.preventDefault();\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect) return;\n const px = e.clientX - rect.left;\n const py = e.clientY - rect.top;\n const factor = Math.exp(-e.deltaY * 0.001);\n const nextZoom = Math.max(minZoom, Math.min(maxZoom, viewport.zoom * factor));\n const k = nextZoom / viewport.zoom;\n setViewport({\n zoom: nextZoom,\n x: px - (px - viewport.x) * k,\n y: py - (py - viewport.y) * k,\n });\n };\n // Keep the freshest handler in a ref so the native listener (attached once)\n // always sees the current viewport/zoom without re-binding every render.\n const handleWheelRef = useRef(handleWheel);\n handleWheelRef.current = handleWheel;\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const listener = (e: globalThis.WheelEvent) => handleWheelRef.current(e);\n el.addEventListener(\"wheel\", listener, { passive: false });\n return () => el.removeEventListener(\"wheel\", listener);\n }, []);\n\n // Zoom around the VIEWPORT CENTRE (not the flow-space origin). The toolbar\n // zoom buttons keep `x`/`y` unchanged, which anchors the scale at flow\n // (0,0) — so the workflow flew toward/away from the top-left corner and\n // could shoot off-screen. Pin the flow point currently under the container\n // centre instead (DEV-206).\n const zoomAroundCentre = (nextZoom: number) => {\n const rect = containerRef.current?.getBoundingClientRect();\n const vp = viewportRef.current;\n const cx = rect ? rect.width / 2 : 0;\n const cy = rect ? rect.height / 2 : 0;\n const k = nextZoom / vp.zoom;\n setViewport({\n zoom: nextZoom,\n x: cx - (cx - vp.x) * k,\n y: cy - (cy - vp.y) * k,\n });\n };\n\n // ── Dispatch contract for Handle ──────────────────────────────────────\n const dispatch = useCallback<FlowDispatch>(\n (a: FlowDispatchAction) => {\n if (a.type === \"connection/start\") {\n beginConnection(a.nodeId, a.handleId, a.handleType, a.pointerId, a.clientX, a.clientY);\n }\n },\n [beginConnection],\n );\n\n // Dimensions reporter — FlowNode's ResizeObserver calls this on size\n // change. We compare against `nodes[]` (current props) and only emit a\n // change when the value actually differs, so we don't trigger an\n // infinite render loop (dimensions change → parent re-renders nodes →\n // ResizeObserver may fire again from style updates).\n const reportDimensions = useCallback(\n (nodeId: string, width: number, height: number) => {\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return;\n if (node.width === width && node.height === height) return;\n onNodesChange?.([change.node.dimensions(nodeId, { width, height })]);\n },\n [nodes, onNodesChange],\n );\n\n // Toggle data.collapsed on a container node. Exposed via the bridge so\n // the chevron rendered inside GroupNode / ForEachNode can flip the\n // subflow state from inside the kind component, no external toolbar\n // wiring needed.\n const toggleNodeCollapseImpl = useCallback(\n (nodeId: string) => {\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return;\n const prevData = (node.data ?? {}) as { collapsed?: boolean } & Record<string, unknown>;\n const nextNode = {\n ...node,\n data: { ...prevData, collapsed: !prevData.collapsed },\n } as WorkflowNode;\n onNodesChange?.([change.node.replace(nodeId, nextNode)]);\n },\n [nodes, onNodesChange],\n );\n\n // Delete one node + its incident edges. Exposed via the FlowNodeBridge\n // so a node-rendered delete button (BaseNode corner [×]) can fire\n // without going through the keyboard / context-menu path.\n const deleteNodeImpl = useCallback(\n (nodeId: string) => {\n const incidentEdgeIds = edgesRef.current\n .filter((e) => e.source === nodeId || e.target === nodeId)\n .map((e) => e.id);\n if (incidentEdgeIds.length > 0) {\n onEdgesChange?.(incidentEdgeIds.map((id) => change.edge.remove(id)));\n }\n onNodesChange?.([change.node.remove(nodeId)]);\n },\n [onNodesChange, onEdgesChange],\n );\n\n // ── Imperative instance — useFlow() and onInit ───────────────────────\n // Methods read through refs each call so they always see fresh state,\n // even though the instance itself is stable across renders. Mutating\n // methods round-trip through the consumer's onNodesChange/onEdgesChange\n // so the canonical state stays single-source-of-truth.\n const instance = useMemo<FlowInstance>(\n () => ({\n // viewport\n getViewport: () => viewportRef.current,\n setViewport: (vp) => setViewport(vp),\n setCenter: (x, y, opts) => {\n const z = opts?.zoom ?? viewportRef.current.zoom;\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect) return;\n setViewport({\n zoom: z,\n x: rect.width / 2 - x * z,\n y: rect.height / 2 - y * z,\n });\n },\n fitView: async (opts) => {\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect) return false;\n const padding = opts?.padding ?? 80;\n const targetNodes = opts?.nodes\n ? nodesRef.current.filter((n) => opts.nodes!.some((x) => x.id === n.id))\n : nodesRef.current.filter((n) => !n.hidden);\n if (targetNodes.length === 0) return false;\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (const n of targetNodes) {\n const w = n.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(n);\n if (n.position.x < minX) minX = n.position.x;\n if (n.position.y < minY) minY = n.position.y;\n if (n.position.x + w > maxX) maxX = n.position.x + w;\n if (n.position.y + h > maxY) maxY = n.position.y + h;\n }\n const cw = maxX - minX;\n const ch = maxY - minY;\n const zx = (rect.width - padding * 2) / cw;\n const zy = (rect.height - padding * 2) / ch;\n const zoom = Math.max(\n opts?.minZoom ?? 0.25,\n Math.min(opts?.maxZoom ?? 1.5, Math.min(zx, zy)),\n );\n setViewport({\n zoom,\n x: rect.width / 2 - ((minX + maxX) / 2) * zoom,\n y: rect.height / 2 - ((minY + maxY) / 2) * zoom,\n });\n return true;\n },\n zoomIn: (opts) => {\n const step = opts?.step ?? 0.2;\n const next = Math.min(maxZoom, viewportRef.current.zoom * (1 + step));\n zoomAroundCentre(next);\n },\n zoomOut: (opts) => {\n const step = opts?.step ?? 0.2;\n const next = Math.max(minZoom, viewportRef.current.zoom / (1 + step));\n zoomAroundCentre(next);\n },\n zoomTo: (level) => {\n zoomAroundCentre(Math.max(minZoom, Math.min(maxZoom, level)));\n },\n\n // transforms\n screenToFlowPosition: (p) => screenToFlow(p, viewportRef.current),\n flowToScreenPosition: (p) => flowToScreen(p, viewportRef.current),\n\n // reads\n getNodes: () => nodesRef.current.slice(),\n getEdges: () => edgesRef.current.slice(),\n getNode: (id) => nodesRef.current.find((n) => n.id === id),\n getEdge: (id) => edgesRef.current.find((e) => e.id === id),\n getNodesBounds: (subset) => {\n const pool = subset\n ? nodesRef.current.filter((n) => subset.some((x) => x.id === n.id))\n : nodesRef.current.filter((n) => !n.hidden);\n if (pool.length === 0) return { x: 0, y: 0, width: 0, height: 0 };\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (const n of pool) {\n const w = n.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(n);\n minX = Math.min(minX, n.position.x);\n minY = Math.min(minY, n.position.y);\n maxX = Math.max(maxX, n.position.x + w);\n maxY = Math.max(maxY, n.position.y + h);\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n },\n getIntersectingNodes: (area, partially = true) => {\n return nodesRef.current.filter((n) => {\n if (n.hidden) return false;\n const w = n.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(n);\n if (partially) {\n // Any overlap counts.\n return (\n n.position.x < area.x + area.width &&\n n.position.x + w > area.x &&\n n.position.y < area.y + area.height &&\n n.position.y + h > area.y\n );\n }\n // Strict containment — node bbox sits entirely inside area.\n return (\n n.position.x >= area.x &&\n n.position.y >= area.y &&\n n.position.x + w <= area.x + area.width &&\n n.position.y + h <= area.y + area.height\n );\n });\n },\n\n // mutations\n addNodes: (nodes) => {\n const arr = Array.isArray(nodes) ? nodes : [nodes];\n onNodesChangeRefForInstance.current?.(arr.map((item) => change.node.add(item)));\n },\n addEdges: (edges) => {\n const arr = Array.isArray(edges) ? edges : [edges];\n onEdgesChangeRefForInstance.current?.(arr.map((item) => change.edge.add(item)));\n },\n updateNodeData: (id, partial) => {\n const cur = nodesRef.current.find((n) => n.id === id);\n if (!cur) return;\n // Merge partial into existing data; the consumer's reducer will\n // apply the resulting `replace` and emit fresh nodes.\n const nextData = { ...((cur.data ?? {}) as object), ...partial } as typeof cur.data;\n onNodesChangeRefForInstance.current?.([\n change.node.replace(id, { ...cur, data: nextData }),\n ]);\n },\n updateNode: (id, partial) => {\n const cur = nodesRef.current.find((n) => n.id === id);\n if (!cur) return;\n onNodesChangeRefForInstance.current?.([change.node.replace(id, { ...cur, ...partial })]);\n },\n deleteElements: async ({ nodes: ns, edges: es }) => {\n const nodesToDelete = (ns ?? [])\n .map((x) => nodesRef.current.find((n) => n.id === x.id))\n .filter((n): n is WorkflowNode => !!n);\n const edgesToDelete = (es ?? [])\n .map((x) => edgesRef.current.find((e) => e.id === x.id))\n .filter((e): e is WorkflowEdge => !!e);\n // Async veto — host can return a Promise<boolean> to confirm\n // (\"this node is referenced by a running execution; really delete?\").\n const before = onBeforeDeleteRef.current;\n if (before) {\n const ok = await before({ nodes: nodesToDelete, edges: edgesToDelete });\n if (!ok) return false;\n }\n if (nodesToDelete.length > 0) {\n onNodesChangeRefForInstance.current?.(nodesToDelete.map((n) => change.node.remove(n.id)));\n }\n if (edgesToDelete.length > 0) {\n onEdgesChangeRefForInstance.current?.(edgesToDelete.map((e) => change.edge.remove(e.id)));\n }\n return true;\n },\n }),\n [setViewport, minZoom, maxZoom],\n );\n\n // Hand the instance to the consumer once on mount. We don't refire on\n // every render because consumers typically stash the ref once. The\n // instance itself is stable (closures read fresh values via refs).\n const initFiredRef = useRef(false);\n useEffect(() => {\n if (initFiredRef.current) return;\n initFiredRef.current = true;\n onInit?.(instance);\n }, [instance, onInit]);\n\n // Auto-frame the existing nodes on first mount. Without this, a\n // canvas that opens with nodes at positions like (1200, 800) shows\n // an empty viewport at the {0,0,1} origin and the user has to pan to\n // find their workflow. The default kicks in only when the consumer\n // didn't pin a viewport themselves and didn't explicitly disable it.\n //\n // Fires on the first frame where `nodes.length > 0` AND the container\n // has measured dimensions (a 0×0 container would yield NaN bounds).\n // The bounding-box math falls back to DEFAULT_NODE_WIDTH / height for\n // un-measured nodes, so the framing is correct even before ResizeObservers\n // have reported real dimensions.\n const fitOnInitFiredRef = useRef(false);\n useEffect(() => {\n if (fitOnInitFiredRef.current) return;\n const opt = fitViewOnInit;\n const shouldFit = opt === false ? false : opt !== undefined ? true : !viewportPropProvided;\n if (!shouldFit) return;\n // Wait until the container has real dimensions — a 0×0 container yields\n // NaN bounds. We do NOT latch while unmeasured so the fit still fires\n // once the container lays out.\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect || rect.width === 0 || rect.height === 0) return;\n // Container is measured → this is our single initialization opportunity.\n // \"Fit on init\" means \"frame the content present at initialization\", NOT\n // \"fit whenever the first node ever appears\". If the canvas mounted empty\n // there is nothing to frame, but we still latch here so that a node the\n // user later drops onto the blank canvas is NOT mistaken for hydration\n // and does not recenter + reset zoom onto itself (DEV-203).\n if (nodes.length === 0) {\n fitOnInitFiredRef.current = true;\n return;\n }\n const fitOpts = typeof opt === \"object\" && opt !== null ? opt : undefined;\n // Defer one frame so any layout effects (e.g. ResizeObservers reporting\n // node dimensions) have settled before we compute bounds. Latch INSIDE\n // the rAF (not before scheduling it) so React StrictMode's\n // mount → cleanup → remount cycle — whose cleanup cancels the first\n // frame — cannot leave us permanently \"fired\" without ever fitting\n // (DEV-206). Each effect re-run cancels the prior frame via cleanup, so\n // there is no double-fit.\n const raf = requestAnimationFrame(() => {\n fitOnInitFiredRef.current = true;\n void instance.fitView(fitOpts);\n });\n return () => cancelAnimationFrame(raf);\n }, [fitViewOnInit, viewportPropProvided, nodes.length, instance]);\n\n // ── Keyboard: Backspace / Delete removes the current selection ────────\n // Goes through `instance.deleteElements` so `onBeforeDelete` veto, edge\n // re-routing, and the same change pipeline as the X button fire\n // consistently. We only act when focus is on the canvas (or its\n // children) — typing in a real input shouldn't delete the workflow.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Backspace\" && e.key !== \"Delete\") return;\n const target = e.target as HTMLElement | null;\n // Don't hijack typing in form fields. `contentEditable` covers the\n // edge label inline editor.\n if (\n target &&\n (target.tagName === \"INPUT\" ||\n target.tagName === \"TEXTAREA\" ||\n target.tagName === \"SELECT\" ||\n target.isContentEditable)\n ) {\n return;\n }\n // Only fire when the canvas (or something inside it) currently\n // owns focus / pointer interaction. Bare `keydown` on document\n // would steal Backspace from other widgets on the page.\n if (!containerRef.current?.contains(target) && document.activeElement !== document.body) {\n return;\n }\n const sel = store.getSnapshot();\n if (sel.selectedNodeIds.size === 0 && sel.selectedEdgeIds.size === 0) return;\n e.preventDefault();\n void instance.deleteElements({\n nodes: Array.from(sel.selectedNodeIds, (id) => ({ id })),\n edges: Array.from(sel.selectedEdgeIds, (id) => ({ id })),\n });\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [instance, store]);\n\n const bridge = useMemo<FlowNodeBridge>(\n () => ({\n beginNodeDrag,\n selectNode,\n notifyNodeClick,\n selectEdge,\n reportDimensions,\n deleteNode: deleteNodeImpl,\n toggleNodeCollapse: toggleNodeCollapseImpl,\n }),\n [\n beginNodeDrag,\n selectNode,\n notifyNodeClick,\n selectEdge,\n reportDimensions,\n deleteNodeImpl,\n toggleNodeCollapseImpl,\n ],\n );\n\n // ── Cursor feedback ───────────────────────────────────────────────────\n // The user gets immediate visual cues for which gesture they're in:\n // - idle on empty canvas → \"grab\" (or default if panOnDrag = false)\n // - dragging the pane → \"grabbing\"\n // - dragging a connection → \"crosshair\"\n // - dragging a node → handled by FlowNode CSS (\"grabbing\")\n // We use a state-driven class so the cursor flips synchronously with\n // the gesture (vs CSS :active which lags behind pointer-capture).\n const [panGesture, setPanGesture] = useState(false);\n\n // ── Render ────────────────────────────────────────────────────────────\n const isEmpty = nodes.length === 0 && edges.length === 0;\n const isConnecting = conn !== null;\n\n // Filter out hidden nodes + their incident edges. Hidden is a runtime\n // flag (e.g. set by a \"collapse group\" toggle). Edges that reference a\n // hidden node would otherwise dangle in space.\n const visibleNodes = useMemo(() => nodes.filter((n) => !n.hidden), [nodes]);\n const visibleEdges = useMemo(() => {\n if (visibleNodes.length === nodes.length) return edges;\n const visibleIds = new Set(visibleNodes.map((n) => n.id));\n return edges.filter((e) => visibleIds.has(e.source) && visibleIds.has(e.target));\n }, [edges, nodes, visibleNodes]);\n\n // Sort so containers render before their children (lower in DOM = under\n // children when zIndex ties). For NESTED containers (group inside group)\n // we order by depth — outermost first — so an inner group's children\n // can still draw on top of the outer group's frame. Non-container nodes\n // sort last in original-array order.\n //\n // Containers: `group` only (see `isContainerType`). `forEach` is a simple\n // node, not a child-hosting frame.\n const orderedNodes = useMemo(() => {\n const isContainer = (n: WorkflowNode) => isContainerType(n.type);\n // Cache parent chain depth for stable ordering. Cycles return Infinity.\n const depth = (n: WorkflowNode): number => {\n let d = 0;\n let cursor = n.parentId;\n const seen = new Set<string>();\n while (cursor) {\n if (seen.has(cursor)) return Number.POSITIVE_INFINITY;\n seen.add(cursor);\n d++;\n cursor = visibleNodes.find((x) => x.id === cursor)?.parentId;\n }\n return d;\n };\n const containers = visibleNodes.filter(isContainer);\n const others = visibleNodes.filter((n) => !isContainer(n));\n containers.sort((a, b) => depth(a) - depth(b));\n return [...containers, ...others];\n }, [visibleNodes]);\n\n return (\n <FlowStoreContext.Provider value={store}>\n <FlowInstanceContext.Provider value={instance}>\n <HandleRegistryContext.Provider value={handleRegistry}>\n <FlowDispatchContext.Provider value={dispatch}>\n <FlowNodeBridgeContext.Provider value={bridge}>\n <div\n ref={containerRef}\n className={cn(\n \"ods-flow-canvas-v2\",\n panGesture && \"ods-flow-canvas-v2--panning\",\n isConnecting && \"ods-flow-canvas-v2--connecting\",\n draggingId && \"ods-flow-canvas-v2--dragging\",\n className,\n )}\n style={{\n position: \"relative\",\n width,\n height,\n overflow: \"hidden\",\n userSelect: \"none\",\n touchAction: \"none\",\n // Cursor: state-driven so it flips instantly with the\n // gesture. CSS `:active` would lag behind pointer-capture.\n cursor: panGesture\n ? \"grabbing\"\n : isConnecting\n ? \"crosshair\"\n : panOnDrag\n ? \"grab\"\n : \"default\",\n ...style,\n }}\n onPointerDown={onCanvasPointerDown}\n onContextMenu={(e) => {\n // Route the right-click to the per-surface handler based on\n // where the pointer landed. Consumers `preventDefault()` to\n // suppress the browser's native menu; we don't do it for\n // them because some workflows prefer the OS menu on pane.\n const t = e.target as HTMLElement;\n const nodeEl = t.closest(\"[data-node-id]\") as HTMLElement | null;\n if (nodeEl && onNodeContextMenu) {\n const id = nodeEl.dataset.nodeId!;\n const node = nodes.find((n) => n.id === id);\n if (node) onNodeContextMenu(e, node);\n return;\n }\n const edgeEl = t.closest(\"[data-edge-id]\") as HTMLElement | null;\n if (edgeEl && onEdgeContextMenu) {\n const id = edgeEl.dataset.edgeId!;\n const edge = edges.find((x) => x.id === id);\n if (edge) onEdgeContextMenu(e, edge);\n return;\n }\n onPaneContextMenu?.(e);\n }}\n data-empty={isEmpty ? \"true\" : undefined}\n >\n {background !== \"none\" && (\n <div\n className={cn(\n \"ods-flow-canvas-v2__grid\",\n `ods-flow-canvas-v2__grid--${background}`,\n )}\n style={\n {\n // Custom property drives the four variants' SCSS.\n \"--ods-flow-grid-size\": `${gridSize * viewport.zoom}px`,\n backgroundPosition: `${viewport.x}px ${viewport.y}px`,\n } as CSSProperties\n }\n />\n )}\n\n <div\n className=\"ods-flow-canvas-v2__viewport\"\n style={{\n position: \"absolute\",\n inset: 0,\n transform: `translate(${viewport.x}px, ${viewport.y}px) scale(${viewport.zoom})`,\n transformOrigin: \"0 0\",\n }}\n >\n <EdgesLayer\n edges={visibleEdges}\n nodes={visibleNodes}\n onSelect={(id) => bridge.selectEdge(id, false)}\n onDelete={(id) => onEdgesChangeRef(id, onEdgesChange)}\n onLabelChange={onEdgeLabelChange}\n ghost={conn ? { start: conn.start, end: conn.end } : null}\n // Bust EdgesLayer's memo when the handle registry\n // changes, so edges recompute geometry against the\n // newly-mounted handles.\n handleVersion={handleVersion}\n />\n\n {orderedNodes.map((node) => {\n const Kind = kinds[node.type] ?? kinds.action;\n if (!Kind) return null;\n return (\n <FlowNode\n key={node.id}\n node={node}\n selected={selectedNodeIds.has(node.id)}\n dragging={draggingId === node.id}\n isConnecting={isConnecting}\n Kind={Kind}\n />\n );\n })}\n </div>\n\n {isEmpty && emptyState && (\n <div className=\"ods-flow-canvas-v2__empty\">{emptyState}</div>\n )}\n\n {children}\n </div>\n </FlowNodeBridgeContext.Provider>\n </FlowDispatchContext.Provider>\n </HandleRegistryContext.Provider>\n </FlowInstanceContext.Provider>\n </FlowStoreContext.Provider>\n );\n}\n\n// Tiny helper — keeps the JSX above clean.\nfunction onEdgesChangeRef(id: string, cb?: (changes: EdgeChange[]) => void) {\n cb?.([change.edge.remove(id)]);\n}\n\n/**\n * Compute auto-resize updates for every container in the graph so each\n * frame encloses its current children + padding.\n *\n * `pending` carries the position / replace changes the canvas is\n * about to dispatch — we PROJECT them onto the current node list\n * before measuring so a drag that just moved a child uses the new\n * position, not the stale committed one. That makes the auto-resize\n * atomic with the drag commit: a single `onNodesChange` call carries\n * both the child's new position AND the parent's new frame.\n *\n * Container frames track their children's bbox in BOTH directions —\n * they grow to fit and shrink when children are removed, floored at\n * `minWidth/minHeight` (the default empty-container size) so a frame\n * never collapses to nothing. A fixed `CONTAINER_DROP_HEADROOM` is\n * kept past the content so there's always room to drop ~2 more nodes\n * before the next grow. The frame also re-positions its top-left to\n * follow the children bbox so children stay visually inside.\n */\n// Spare room the auto-resize keeps PAST the children's bbox so a couple\n// more nodes can be dropped before the frame has to grow again. Sized to\n// roughly two default node rows tall and one node-width of slack wide —\n// the \"+2 nodes of drop room\" a subflow container should always offer.\nconst CONTAINER_DROP_HEADROOM_W = 220;\nconst CONTAINER_DROP_HEADROOM_H = 2 * 128;\n\nfunction computeContainerAutoResize(\n nodes: WorkflowNode[],\n pending: NodeChange[],\n padding: number,\n minWidth: number,\n minHeight: number,\n): NodeChange[] {\n // Apply pending changes to a transient view of the node list. We\n // care about: `position` (child moves), `replace` (reparent), and\n // `add` (newly-inserted nodes are projected too). Other change\n // types don't affect bbox math.\n const projected = new Map<string, WorkflowNode>();\n for (const n of nodes) projected.set(n.id, n);\n for (const c of pending) {\n if (c.type === \"position\" && c.position) {\n const cur = projected.get(c.id);\n if (cur) projected.set(c.id, { ...cur, position: c.position });\n } else if (c.type === \"replace\" && c.item) {\n projected.set(c.id, { ...projected.get(c.id), ...c.item } as WorkflowNode);\n } else if (c.type === \"add\" && c.item) {\n projected.set((c.item as WorkflowNode).id, c.item as WorkflowNode);\n }\n }\n\n const HEADER = 56; // breathing room above the first child\n const out: NodeChange[] = [];\n for (const parent of projected.values()) {\n if (!isContainerType(parent.type)) continue;\n const children: WorkflowNode[] = [];\n for (const n of projected.values()) {\n if (n.parentId === parent.id) children.push(n);\n }\n if (children.length === 0) {\n // Emptied container — collapse it back to the default floor size.\n // Position is left alone (no children to track).\n const curW = parent.width ?? 480;\n const curH = parent.height ?? 240;\n if (curW !== minWidth || curH !== minHeight) {\n out.push(change.node.dimensions(parent.id, { width: minWidth, height: minHeight }));\n }\n continue;\n }\n\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (const c of children) {\n const cw = c.width ?? 240;\n const ch = c.height ?? 96;\n if (c.position.x < minX) minX = c.position.x;\n if (c.position.y < minY) minY = c.position.y;\n if (c.position.x + cw > maxX) maxX = c.position.x + cw;\n if (c.position.y + ch > maxY) maxY = c.position.y + ch;\n }\n const targetX = minX - padding;\n const targetY = minY - padding - HEADER;\n const curW = parent.width ?? 480;\n const curH = parent.height ?? 240;\n // Fit children + padding + drop headroom, floored at the container's\n // default size. This both GROWS and SHRINKS: a frame that's lost\n // children collapses back toward `minWidth/minHeight`, and one that's\n // gained them grows to keep ~2 nodes of empty drop room. The headroom\n // is what makes \"drop two more before it resizes\" hold.\n const fitW = maxX - minX + padding * 2 + CONTAINER_DROP_HEADROOM_W;\n const fitH = maxY - minY + padding * 2 + HEADER + CONTAINER_DROP_HEADROOM_H;\n const nextW = Math.max(minWidth, fitW);\n const nextH = Math.max(minHeight, fitH);\n const positionDirty = parent.position.x !== targetX || parent.position.y !== targetY;\n const sizeDirty = curW !== nextW || curH !== nextH;\n if (positionDirty) {\n out.push(change.node.position(parent.id, { x: targetX, y: targetY }, false));\n }\n if (sizeDirty) {\n out.push(change.node.dimensions(parent.id, { width: nextW, height: nextH }));\n }\n }\n return out;\n}\n\n// ────────────────────────────────────────────────────────────────────────\n// EdgesLayer — memoised. Re-renders only when edges/nodes arrays or ghost\n// position change. Edges within use memo on (edge, source/target position,\n// edge.selected/animated) so dragging one node only re-renders edges\n// connected to that node.\n// ────────────────────────────────────────────────────────────────────────\nconst EdgesLayer = memo(function EdgesLayer({\n edges,\n nodes,\n onSelect,\n onDelete,\n onLabelChange,\n ghost,\n handleVersion: _handleVersion,\n}: {\n edges: WorkflowEdge[];\n nodes: WorkflowNode[];\n onSelect: (id: string) => void;\n onDelete: (id: string) => void;\n onLabelChange?: (id: string, label: string) => void;\n ghost: { start: Position; end: Position } | null;\n /** Bust-cache token that flips whenever the handle registry mutates.\n * React.memo's default shallow compare picks up the change and re-\n * renders the layer; FlowEdge inside reads the now-up-to-date\n * registry on the re-render. */\n handleVersion: number;\n}) {\n return (\n <svg\n className=\"ods-flow-canvas-v2__edges\"\n style={{ position: \"absolute\", inset: 0, overflow: \"visible\", pointerEvents: \"none\" }}\n width=\"100%\"\n height=\"100%\"\n >\n <g style={{ pointerEvents: \"auto\" }}>\n {edges.map((edge) => (\n <FlowEdge\n key={edge.id}\n edge={edge}\n nodes={nodes}\n onSelect={onSelect}\n onDelete={onDelete}\n onLabelChange={onLabelChange}\n handleVersion={_handleVersion}\n />\n ))}\n </g>\n {ghost && (\n <path\n d={`M ${ghost.start.x} ${ghost.start.y} L ${ghost.end.x} ${ghost.end.y}`}\n stroke=\"var(--ods-accent, #4f46e5)\"\n strokeWidth={1.5}\n strokeDasharray=\"4 4\"\n fill=\"none\"\n />\n )}\n </svg>\n );\n});\n\n// Type re-export so consumers don't need to import from a deeper path.\nexport type { BuiltInNodeData };\n","// ════════════════════════════════════════════════════════════════════════\n// FlowStore — per-canvas state, exposed only via narrow selector hooks.\n// ════════════════════════════════════════════════════════════════════════\n// We deliberately do NOT export the store instance (see ADR-005). The\n// store lives behind a React context; descendants read via\n// `useFlowSelector(selector)` which under the hood is\n// `useSyncExternalStore` against a single `subscribe` channel.\n//\n// The store is the single source of truth for runtime state\n// (selection, viewport, in-flight connection). Node/edge data is mirrored\n// from the controlled props each render; the store keeps a frozen\n// snapshot so descendants don't have to thread `nodes` / `edges` through\n// component trees.\n\nimport type {\n ConnectStartParams,\n FlowStoreSnapshot,\n Viewport,\n WorkflowEdge,\n WorkflowNode,\n} from \"../editor\";\n\ntype Listener = () => void;\n\nexport interface FlowStore {\n /** React subscription hook contract — used by `useSyncExternalStore`. */\n subscribe(listener: Listener): () => void;\n /** Cheap snapshot getter — must return the same ref between mutations. */\n getSnapshot(): FlowStoreSnapshot;\n /** Imperative setters — called by the canvas internals, never by consumers. */\n setNodes(nodes: WorkflowNode[]): void;\n setEdges(edges: WorkflowEdge[]): void;\n setViewport(viewport: Viewport): void;\n setSelection(nodes: ReadonlySet<string>, edges: ReadonlySet<string>): void;\n setConnection(connection: ConnectStartParams | null): void;\n}\n\nexport interface CreateFlowStoreOptions {\n initialNodes?: WorkflowNode[];\n initialEdges?: WorkflowEdge[];\n initialViewport?: Viewport;\n}\n\nconst DEFAULT_VIEWPORT: Viewport = { x: 0, y: 0, zoom: 1 };\n\n/**\n * Build a FlowStore for one canvas instance. Designed to be created in\n * `useState(() => createFlowStore())` inside FlowCanvas so a single\n * `<FlowCanvas>` owns exactly one store and unmounting cleans it up.\n */\nexport function createFlowStore({\n initialNodes = [],\n initialEdges = [],\n initialViewport = DEFAULT_VIEWPORT,\n}: CreateFlowStoreOptions = {}): FlowStore {\n let snapshot: FlowStoreSnapshot = {\n nodes: initialNodes,\n edges: initialEdges,\n viewport: initialViewport,\n selectedNodeIds: EMPTY_SET,\n selectedEdgeIds: EMPTY_SET,\n connection: null,\n };\n\n const listeners = new Set<Listener>();\n const emit = () => {\n for (const l of listeners) l();\n };\n\n const subscribe = (listener: Listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n };\n\n // Replace the snapshot reference on every change so React's\n // `useSyncExternalStore` triggers a re-render. We never mutate in place.\n const replace = (patch: Partial<FlowStoreSnapshot>) => {\n snapshot = { ...snapshot, ...patch };\n emit();\n };\n\n return {\n subscribe,\n getSnapshot: () => snapshot,\n setNodes(nodes) {\n if (nodes === snapshot.nodes) return;\n replace({ nodes });\n },\n setEdges(edges) {\n if (edges === snapshot.edges) return;\n replace({ edges });\n },\n setViewport(viewport) {\n if (\n viewport.x === snapshot.viewport.x &&\n viewport.y === snapshot.viewport.y &&\n viewport.zoom === snapshot.viewport.zoom\n ) {\n return;\n }\n replace({ viewport });\n },\n setSelection(selectedNodeIds, selectedEdgeIds) {\n replace({ selectedNodeIds, selectedEdgeIds });\n },\n setConnection(connection) {\n if (connection === snapshot.connection) return;\n replace({ connection });\n },\n };\n}\n\nconst EMPTY_SET: ReadonlySet<string> = new Set();\n","// ════════════════════════════════════════════════════════════════════════\n// Collision avoidance — keep nodes from overlapping each other (or from\n// landing closer than a configurable minimum gap).\n// ════════════════════════════════════════════════════════════════════════\n//\n// The function below is a pure axis-aligned bounding-box (AABB) \"minimum\n// translation vector\" resolver. Given a proposed position for one node\n// and a set of other nodes, it shifts the proposed position along the\n// axis of *smallest* overlap correction until either (a) no node is\n// closer than `gap` pixels, or (b) the iteration cap is reached.\n//\n// Why MTV? It produces the smoothest \"magnet snap\" UX — when you nudge a\n// node toward a neighbour, it slides along the contact edge rather than\n// flinging away. The iteration cap (8 by default) handles cascading\n// resolutions where pushing out of one node lands in another.\n\nimport type { Position, WorkflowNode } from \"../editor\";\nimport { DEFAULT_NODE_WIDTH, effectiveHeight } from \"./geometry\";\n\nexport interface CollisionOptions {\n /** Minimum gap (px) the dragged node must keep from each other node.\n *\n * - `gap >= 0` — the resolver is **enabled**. `gap === 0` means\n * \"no overlap, zero buffer\" (strict no-overlap). `gap > 0` enforces\n * a buffer of that many pixels.\n * - `gap < 0` — the resolver is **disabled** (returns the proposed\n * position unchanged). This is the no-op sentinel used by\n * consumers that haven't opted into magnet behaviour. */\n gap: number;\n /** Cap iterative resolutions — prevents infinite loops in pathological\n * geometries (e.g. four nodes hugging a single corner). Default 8. */\n maxIterations?: number;\n /** Node ids that the resolver should ignore — typically the dragged\n * node itself plus its descendants (so a parent doesn't collide with\n * its own children) and its ancestors (so a child doesn't collide\n * with its containing group). */\n exclude?: Set<string>;\n /** When true, only consider nodes that share the same `parentId` as\n * the dragged node (i.e. its siblings). When false, all non-excluded\n * nodes participate. Defaults to true — this is the \"rooms\" model\n * where children of group A never collide with children of group B\n * even if their bboxes overlap in flow space. */\n scopeToSiblings?: boolean;\n}\n\n/**\n * Adjust a proposed (flow-space) position so the node's bbox stays at\n * least `gap` pixels away from every other (non-excluded) node's bbox.\n *\n * The function does NOT mutate the input nodes; it returns a new\n * `Position`. The caller is responsible for emitting the resulting\n * change via `onNodesChange` — collision resolution doesn't dispatch\n * anything on its own.\n */\nexport function resolveNodeCollisions(\n node: WorkflowNode,\n proposed: Position,\n others: WorkflowNode[],\n opts: CollisionOptions,\n): Position {\n const { gap, maxIterations = 8, exclude, scopeToSiblings = true } = opts;\n if (gap < 0 || others.length === 0) return proposed;\n\n const w = node.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(node);\n const parentId = node.parentId;\n\n // Pre-filter the candidate list once — keeps the per-iteration loop tight.\n const candidates = others.filter((o) => {\n if (o.id === node.id) return false;\n if (o.hidden) return false;\n if (exclude?.has(o.id)) return false;\n if (scopeToSiblings && (o.parentId ?? undefined) !== (parentId ?? undefined)) {\n return false;\n }\n return true;\n });\n if (candidates.length === 0) return proposed;\n\n let cur = proposed;\n\n for (let iter = 0; iter < maxIterations; iter++) {\n // Find the colliding pair with the SMALLEST overlap correction and\n // resolve that one this iteration. Doing one push per iteration keeps\n // the displacement minimal and lets cascading shifts settle naturally.\n let bestOverlap = Number.POSITIVE_INFINITY;\n let bestPushX = 0;\n let bestPushY = 0;\n let hit = false;\n\n // Inflate our rect by `gap` so any node within `gap` registers as\n // overlap. We add the full gap to one side (rather than gap/2 to\n // both sides) so the resulting min-distance matches user intuition:\n // \"at least `gap` pixels between the two visual edges.\"\n const aLeft = cur.x - gap;\n const aRight = cur.x + w + gap;\n const aTop = cur.y - gap;\n const aBottom = cur.y + h + gap;\n\n for (const o of candidates) {\n const ow = o.width ?? DEFAULT_NODE_WIDTH;\n const oh = effectiveHeight(o);\n const bLeft = o.position.x;\n const bRight = o.position.x + ow;\n const bTop = o.position.y;\n const bBottom = o.position.y + oh;\n\n const overlapX = Math.min(aRight, bRight) - Math.max(aLeft, bLeft);\n const overlapY = Math.min(aBottom, bBottom) - Math.max(aTop, bTop);\n if (overlapX <= 0 || overlapY <= 0) continue;\n\n // Pick the axis with the smaller overlap — that's the cheaper push.\n // Direction: if our centre is \"before\" their centre on that axis,\n // push backward; otherwise push forward.\n let pushX = 0;\n let pushY = 0;\n let overlap: number;\n if (overlapX < overlapY) {\n const aCx = cur.x + w / 2;\n const bCx = o.position.x + ow / 2;\n pushX = aCx < bCx ? -overlapX : overlapX;\n overlap = overlapX;\n } else {\n const aCy = cur.y + h / 2;\n const bCy = o.position.y + oh / 2;\n pushY = aCy < bCy ? -overlapY : overlapY;\n overlap = overlapY;\n }\n\n if (overlap < bestOverlap) {\n bestOverlap = overlap;\n bestPushX = pushX;\n bestPushY = pushY;\n hit = true;\n }\n }\n\n if (!hit) break;\n cur = { x: cur.x + bestPushX, y: cur.y + bestPushY };\n }\n\n return cur;\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Parenting helpers — descendant traversal, extent clamping, descendant\n// position recompute. Used by FlowCanvas's drag middleware to keep\n// subflow semantics consistent.\n// ════════════════════════════════════════════════════════════════════════\n\nimport type { NodeKind, Position, WorkflowNode } from \"../editor\";\nimport { DEFAULT_NODE_WIDTH, effectiveHeight } from \"./geometry\";\n\n/**\n * Node types that behave as containers — subflow frames whose children nest\n * via `parentId` and render inside the frame.\n *\n * `forEach` is intentionally NOT a container. The DS renders it as a SIMPLE\n * node (1 input on top, Each / Done outputs on the bottom) whose loop body is\n * wired by EDGES, not nested by `parentId` (see ForEachNode). Treating it as\n * a container let drag-to-reparent adopt nodes INTO a forEach; the host then\n * silently dropped those \"children\" on save because its wire contract has no\n * forEach-children concept — real data loss (DEV-200). Keep this list in sync\n * with the kinds that actually render a child-hosting frame.\n */\nexport const CONTAINER_NODE_TYPES: readonly NodeKind[] = [\"group\"];\n\n/** True when a node type hosts nested children via `parentId`. */\nexport function isContainerType(type: NodeKind | undefined): boolean {\n return type !== undefined && CONTAINER_NODE_TYPES.includes(type);\n}\n\n/**\n * Returns the transitive descendants of a node — i.e. every node whose\n * `parentId` chain ends at `nodeId`. Stable order (DFS). The root node\n * is NOT included.\n */\nexport function descendantsOf(nodeId: string, nodes: WorkflowNode[]): WorkflowNode[] {\n const childrenByParent = new Map<string, WorkflowNode[]>();\n for (const n of nodes) {\n if (!n.parentId) continue;\n const arr = childrenByParent.get(n.parentId);\n if (arr) arr.push(n);\n else childrenByParent.set(n.parentId, [n]);\n }\n const out: WorkflowNode[] = [];\n const stack = [nodeId];\n // Guard against malformed cycles (a → b → a) which can sneak in via\n // hand-crafted fixtures. Without this the walk is unbounded.\n const visited = new Set<string>([nodeId]);\n while (stack.length) {\n const cur = stack.pop();\n if (cur === undefined) break;\n const list = childrenByParent.get(cur);\n if (!list) continue;\n for (const c of list) {\n if (visited.has(c.id)) continue;\n visited.add(c.id);\n out.push(c);\n stack.push(c.id);\n }\n }\n return out;\n}\n\n/**\n * Walk up the parent chain. Returns the first ancestor that satisfies\n * `predicate`, or undefined.\n */\nexport function findAncestor(\n node: WorkflowNode,\n nodes: WorkflowNode[],\n predicate: (n: WorkflowNode) => boolean,\n): WorkflowNode | undefined {\n let cursor: WorkflowNode | undefined = node;\n const seen = new Set<string>();\n while (cursor?.parentId) {\n if (seen.has(cursor.parentId)) return undefined; // cycle guard\n seen.add(cursor.parentId);\n const parent = nodes.find((n) => n.id === cursor!.parentId);\n if (!parent) return undefined;\n if (predicate(parent)) return parent;\n cursor = parent;\n }\n return undefined;\n}\n\n/**\n * Clamp a proposed child position to its parent's bounding box. The\n * child is kept fully inside the parent — child's bottom-right corner\n * cannot exceed the parent's bottom-right.\n *\n * Returns the original position if the node has no parent or extent\n * isn't `'parent'`.\n */\nexport function clampToParentExtent(\n node: WorkflowNode,\n proposed: Position,\n nodes: WorkflowNode[],\n): Position {\n if (node.extent !== \"parent\" || !node.parentId) return proposed;\n const parent = nodes.find((n) => n.id === node.parentId);\n if (!parent) return proposed;\n const pw = parent.width ?? DEFAULT_NODE_WIDTH;\n const ph = effectiveHeight(parent);\n const w = node.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(node);\n const minX = parent.position.x;\n const minY = parent.position.y;\n const maxX = parent.position.x + pw - w;\n const maxY = parent.position.y + ph - h;\n return {\n x: Math.max(minX, Math.min(maxX, proposed.x)),\n y: Math.max(minY, Math.min(maxY, proposed.y)),\n };\n}\n\n/**\n * Hit-test which container node (if any) contains the given point. Used by\n * drag-to-reparent and drop-to-add to scope a node. Only `group` is a\n * container (see `isContainerType` — `forEach` is a simple node).\n *\n * When containers overlap or nest, the SMALLEST-area container under the\n * point wins. That's the most specific / deepest-nested frame, and it\n * matches the host's own drop hit-test (which picked the deepest container).\n * The previous \"last in array order\" rule disagreed with the host, so a drag\n * and a drop over the same nested groups could adopt into different parents\n * (DEV-200).\n */\nexport function findContainingGroup(\n point: Position,\n nodes: WorkflowNode[],\n exclude: string[] = [],\n): WorkflowNode | undefined {\n let best: WorkflowNode | undefined;\n let bestArea = Number.POSITIVE_INFINITY;\n for (const n of nodes) {\n if (exclude.includes(n.id)) continue;\n if (!isContainerType(n.type)) continue;\n if (n.data && typeof n.data === \"object\" && (n.data as { collapsed?: boolean }).collapsed) {\n continue;\n }\n const w = n.width ?? DEFAULT_NODE_WIDTH;\n const h = effectiveHeight(n);\n if (\n point.x >= n.position.x &&\n point.y >= n.position.y &&\n point.x <= n.position.x + w &&\n point.y <= n.position.y + h\n ) {\n const area = w * h;\n if (area < bestArea) {\n best = n;\n bestArea = area;\n }\n }\n }\n return best;\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FlowEdge v2 — port-aware path, four routing modes, editable label.\n// ════════════════════════════════════════════════════════════════════════\n// Routing modes: bezier (default), step, smoothstep, straight.\n// Semantic types: default / conditional / loop / error — drive stroke\n// colour and dash pattern, orthogonal to routing.\n//\n// Label + delete chrome are stacked vertically at the midpoint so they\n// don't overlap. Double-clicking the label opens an inline editor;\n// changes commit via `onLabelChange`.\n\nimport {\n memo,\n type KeyboardEvent as ReactKeyboardEvent,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport type { EdgeKind, WorkflowEdge as WorkflowEdgeType, WorkflowNode } from \"../../editor\";\nimport { handleCentre } from \"../../utils/geometry\";\nimport { buildEdgePath, type EdgeRouting } from \"../../utils/paths\";\nimport { useHandleRegistry } from \"../Handle/handleRegistry\";\n\nexport interface FlowEdgeProps {\n edge: WorkflowEdgeType;\n nodes: WorkflowNode[];\n onSelect?: (id: string) => void;\n onDelete?: (id: string) => void;\n /** Commit a label edit. When omitted, double-click is a no-op. */\n onLabelChange?: (id: string, label: string) => void;\n /** Show the X delete affordance at the midpoint on hover/select. */\n showDelete?: boolean;\n /** Curvature for bezier routing (0–1). Smaller = tighter. Default 0.25. */\n curvature?: number;\n /** Corner radius for smoothstep routing. Default 8 px. */\n borderRadius?: number;\n /**\n * Bust-cache token from FlowCanvas. Bumps whenever the handle registry\n * mutates so this edge re-renders against fresh handle descriptors —\n * fixes stale geometry after collapse/uncollapse of a subflow whose\n * children mount their Handles in a follow-up effect tick.\n */\n handleVersion?: number;\n}\n\nfunction FlowEdgeImpl({\n edge,\n nodes,\n onSelect,\n onDelete,\n onLabelChange,\n showDelete = true,\n curvature = 0.25,\n borderRadius = 8,\n}: FlowEdgeProps) {\n const uid = useId();\n const markerId = `ods-flow-edge-arrow-${uid.replace(/:/g, \"\")}`;\n const registry = useHandleRegistry();\n const [hovered, setHovered] = useState(false);\n const [editing, setEditing] = useState(false);\n const [draftLabel, setDraftLabel] = useState<string>(edge.label ?? \"\");\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Sync the draft when the edge's label changes externally (e.g. after a\n // commit). The local state survives blur/Enter cleanly.\n useEffect(() => {\n if (!editing) setDraftLabel(edge.label ?? \"\");\n }, [edge.label, editing]);\n\n const sourceNode = nodes.find((n) => n.id === edge.source);\n const targetNode = nodes.find((n) => n.id === edge.target);\n\n if (!sourceNode || !targetNode) return null;\n\n // Compute on every render — handle registrations may arrive after the\n // first paint, and the math is cheap.\n const sourceHandleId = edge.sourceHandle ?? \"default\";\n const targetHandleId = edge.targetHandle ?? \"default\";\n const sourceDesc = registry.resolve(sourceNode.id, \"source\", sourceHandleId);\n const targetDesc = registry.resolve(targetNode.id, \"target\", targetHandleId);\n const sourceSide = sourceDesc?.side ?? sourceNode.sourcePosition ?? \"bottom\";\n const targetSide = targetDesc?.side ?? targetNode.targetPosition ?? \"top\";\n // The handle dot's physical edge (`side`) places the endpoint; the\n // `routeSide` decides which way the curve leaves/enters it. They differ\n // for a subflow's inner-facing ports — a dot on the frame's `top` edge\n // whose wire must curve `down` into the frame.\n const sourceRoute = sourceDesc?.routeSide ?? sourceSide;\n const targetRoute = targetDesc?.routeSide ?? targetSide;\n const sourceIndex = sourceDesc?.index ?? 0;\n const sourceTotal = sourceDesc?.total ?? 1;\n const targetIndex = targetDesc?.index ?? 0;\n const targetTotal = targetDesc?.total ?? 1;\n const rawStart = handleCentre(sourceNode, sourceSide, sourceIndex, sourceTotal);\n const rawEnd = handleCentre(targetNode, targetSide, targetIndex, targetTotal);\n // Pull the visible path back from each handle dot a few pixels so\n // the arrowhead lands ON the port circle (overlapping its centre)\n // rather than floating in space above it. The hitbox path still\n // uses the raw points so the click hit area extends right up to\n // the dot. Port circle is 12 px / radius 6; a 2 px pull-back puts\n // the arrow's visual tip at the port centre.\n const HANDLE_GAP = 2;\n const start = offsetAlongSide(rawStart, sourceRoute, HANDLE_GAP);\n const end = offsetAlongSide(rawEnd, targetRoute, HANDLE_GAP);\n const routing: EdgeRouting = edge.routing ?? \"bezier\";\n const { d, midX, midY } = buildEdgePath(routing, start, sourceRoute, end, targetRoute, {\n curvature,\n borderRadius,\n });\n const { d: hitD } = buildEdgePath(routing, rawStart, sourceRoute, rawEnd, targetRoute, {\n curvature,\n borderRadius,\n });\n\n const type: EdgeKind = edge.type ?? \"default\";\n const isHot = hovered || edge.selected;\n const stroke =\n type === \"error\"\n ? \"var(--ods-status-failed, #dc2626)\"\n : isHot\n ? \"var(--ods-accent, #4f46e5)\"\n : \"var(--ods-border-strong, #6b7280)\";\n // Explicit `edge.style.strokeDasharray` wins over the type's default —\n // this is what `collapseFor` uses to render boundary edges (sparse-dotted)\n // so the user sees they're a \"summary\" rather than a real connection.\n const typeDash = type === \"conditional\" ? \"6 4\" : type === \"loop\" ? \"4 4\" : undefined;\n const dash = edge.style?.strokeDasharray ?? typeDash;\n const strokeWidth = edge.style?.strokeWidth ?? (isHot ? 2 : 1.4);\n const animateDash = edge.animated === true;\n const label = edge.label;\n const hasDelete = showDelete && (isHot || edge.selected) && !!onDelete;\n\n // Lay label + delete affordance side by side at the midpoint:\n //\n // ┌─────────┐ ⓧ ← inline chrome, both on midY\n // │ label │\n // └─────────┘\n //\n // The foreignObject sits on the bezier's midpoint and holds a flex row\n // that centres its children horizontally. Either child may be absent;\n // remaining child stays centred.\n const showChrome = !!label || editing || hasDelete;\n\n const commitLabel = (next: string) => {\n setEditing(false);\n if (next !== edge.label) onLabelChange?.(edge.id, next);\n };\n\n const onLabelKey = (e: ReactKeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commitLabel(draftLabel);\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n setEditing(false);\n setDraftLabel(edge.label ?? \"\");\n }\n };\n\n return (\n <g\n className={cn(\n \"ods-flow-edge-v2\",\n `ods-flow-edge-v2--${type}`,\n `ods-flow-edge-v2--routing-${routing}`,\n edge.selected && \"ods-flow-edge-v2--selected\",\n hovered && \"ods-flow-edge-v2--hovered\",\n edge.className,\n )}\n data-edge-id={edge.id}\n data-edge-routing={routing}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n onClick={(e) => {\n e.stopPropagation();\n onSelect?.(edge.id);\n }}\n onDoubleClick={(e) => {\n // Double-clicking anywhere on the edge opens the label editor —\n // this is the only way to ADD a description to an edge that\n // doesn't have one yet (the label chip only renders once a\n // label exists, so there'd otherwise be nothing to double-click).\n if (!onLabelChange) return;\n e.stopPropagation();\n setDraftLabel(edge.label ?? \"\");\n setEditing(true);\n }}\n >\n <defs>\n <marker\n id={markerId}\n viewBox=\"0 0 10 10\"\n refX=\"9\"\n refY=\"5\"\n markerWidth=\"7\"\n markerHeight=\"7\"\n orient=\"auto-start-reverse\"\n >\n <path d=\"M0 0L10 5L0 10z\" fill={stroke} />\n </marker>\n </defs>\n\n {/* Hitbox — wider stroke than the visible path so the edge is easy\n to click even when zoomed out or routed with sharp corners. Uses\n the un-shortened path so the click target reaches the port. */}\n <path d={hitD} stroke=\"transparent\" strokeWidth={20} fill=\"none\" />\n\n {/* Visible path. */}\n <path\n d={d}\n stroke={stroke}\n strokeWidth={strokeWidth}\n strokeDasharray={dash}\n fill=\"none\"\n markerEnd={`url(#${markerId})`}\n style={\n animateDash\n ? {\n strokeDasharray: dash ?? \"6 4\",\n animation: \"ods-flow-edge-flow 0.6s linear infinite\",\n }\n : undefined\n }\n />\n\n {showChrome && (\n <foreignObject\n x={midX - 140}\n y={midY - 16}\n width={280}\n height={32}\n style={{ overflow: \"visible\", pointerEvents: \"none\" }}\n >\n <div className=\"ods-flow-edge-v2__chrome\">\n {(label || editing) &&\n (editing ? (\n <input\n ref={inputRef}\n className=\"ods-flow-edge-v2__label-input\"\n value={draftLabel}\n autoFocus\n onChange={(e) => setDraftLabel(e.target.value)}\n onBlur={() => commitLabel(draftLabel)}\n onKeyDown={onLabelKey}\n onClick={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n aria-label=\"Edit edge label\"\n />\n ) : (\n <button\n type=\"button\"\n className=\"ods-flow-edge-v2__label-chip\"\n onDoubleClick={(e) => {\n if (!onLabelChange) return;\n e.stopPropagation();\n setDraftLabel(edge.label ?? \"\");\n setEditing(true);\n }}\n onClick={(e) => {\n e.stopPropagation();\n onSelect?.(edge.id);\n }}\n title={onLabelChange ? \"Double-click to edit\" : undefined}\n tabIndex={onLabelChange ? 0 : -1}\n >\n <span>{label}</span>\n </button>\n ))}\n\n {hasDelete && (\n <button\n type=\"button\"\n className=\"ods-flow-edge-v2__delete-btn\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete?.(edge.id);\n }}\n aria-label=\"Delete edge\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path\n d=\"M2 2l6 6M8 2l-6 6\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n )}\n </div>\n </foreignObject>\n )}\n </g>\n );\n}\n\n/**\n * Pull a handle anchor point inward by `gap` px along the side it sits\n * on. Used to leave space between the arrowhead and the open-circle\n * port — the path stops just outside the dot so the arrow stays visible.\n *\n * \"top\" → end is at the node's top edge, pull it UP (smaller y)\n * \"bottom\" → pull DOWN (larger y)\n * \"left\" → pull LEFT (smaller x)\n * \"right\" → pull RIGHT (larger x)\n */\nfunction offsetAlongSide(\n p: { x: number; y: number },\n side: \"top\" | \"right\" | \"bottom\" | \"left\",\n gap: number,\n): { x: number; y: number } {\n switch (side) {\n case \"top\":\n return { x: p.x, y: p.y - gap };\n case \"bottom\":\n return { x: p.x, y: p.y + gap };\n case \"left\":\n return { x: p.x - gap, y: p.y };\n case \"right\":\n return { x: p.x + gap, y: p.y };\n }\n}\n\nexport const FlowEdge = memo(FlowEdgeImpl, (prev, next) => {\n if (prev.edge !== next.edge) return false;\n if (prev.onSelect !== next.onSelect || prev.onDelete !== next.onDelete) return false;\n if (prev.onLabelChange !== next.onLabelChange) return false;\n if (prev.showDelete !== next.showDelete) return false;\n if (prev.curvature !== next.curvature || prev.borderRadius !== next.borderRadius) return false;\n // Bust the cache when the handle registry mutates — otherwise edges\n // referring to handles that mount in a follow-up effect tick (e.g.\n // children inside a subflow that just un-collapsed) freeze at the\n // first-render-with-stale-registry geometry.\n if (prev.handleVersion !== next.handleVersion) return false;\n const ps = prev.nodes.find((n) => n.id === prev.edge.source);\n const pt = prev.nodes.find((n) => n.id === prev.edge.target);\n const ns = next.nodes.find((n) => n.id === next.edge.source);\n const nt = next.nodes.find((n) => n.id === next.edge.target);\n if (ps !== ns || pt !== nt) return false;\n return true;\n});\n","// ════════════════════════════════════════════════════════════════════════\n// Edge-path builders — bezier, step, smoothstep, straight.\n// ════════════════════════════════════════════════════════════════════════\n// All builders take two oriented endpoints (a position + the side of the\n// node that the port faces) and return:\n// - `d` — the SVG path attribute\n// - `midX`, `midY` — analytic midpoint used by the label + delete chrome\n//\n// Path style is selected via `edge.routing`. The choice does NOT affect\n// the `edge.type` semantic (default/conditional/loop/error) which still\n// drives stroke colour and dash. They're orthogonal.\n\nimport type { HandlePosition, Position } from \"../editor\";\n\nexport type EdgeRouting = \"bezier\" | \"step\" | \"smoothstep\" | \"straight\";\n\nexport interface PathGeometry {\n d: string;\n midX: number;\n midY: number;\n /** Tangent angle (radians) at the midpoint — useful when callers want\n * to offset the label/delete chrome along or perpendicular to the path. */\n midAngle: number;\n}\n\n// ── Public dispatcher ──────────────────────────────────────────────────\nexport function buildEdgePath(\n routing: EdgeRouting,\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n options: { borderRadius?: number; curvature?: number } = {},\n): PathGeometry {\n switch (routing) {\n case \"step\":\n return stepPath(start, startSide, end, endSide);\n case \"smoothstep\":\n return smoothStepPath(start, startSide, end, endSide, options.borderRadius ?? 8);\n case \"straight\":\n return straightPath(start, end);\n default:\n return bezierPath(start, startSide, end, endSide, options.curvature ?? 0.25);\n }\n}\n\n// ── Bezier — React-Flow-style control-offset algorithm ────────────────\n// `curvature` ∈ [0, 1]. Smaller = tighter; 0.25 is a comfortable default.\n// When the target is *in the port's forward direction*, offset is a linear\n// fraction of axis distance. When *behind* (target is in the opposite\n// direction from where the port faces), offset uses a square-root falloff\n// so the curve fans out without overshooting wildly.\nexport function bezierPath(\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n curvature = 0.25,\n): PathGeometry {\n const sourceOffset = calcControlOffset(start, startSide, end, curvature);\n const targetOffset = calcControlOffset(end, endSide, start, curvature);\n const c1 = offsetAlongSide(start, startSide, sourceOffset);\n const c2 = offsetAlongSide(end, endSide, targetOffset);\n\n const d = `M ${start.x},${start.y} C ${c1.x},${c1.y} ${c2.x},${c2.y} ${end.x},${end.y}`;\n\n // Analytic midpoint of a cubic bezier at t=0.5.\n const midX = 0.125 * start.x + 0.375 * c1.x + 0.375 * c2.x + 0.125 * end.x;\n const midY = 0.125 * start.y + 0.375 * c1.y + 0.375 * c2.y + 0.125 * end.y;\n // Tangent at t=0.5 = 3 * ((c2 - c1) + 0.5 * ((c1 - start) - (end - c2))).\n // Simplified: derivative of the bezier polynomial at 0.5.\n const tx =\n 3 *\n ((1 - 0.5) ** 2 * (c1.x - start.x) +\n 2 * (1 - 0.5) * 0.5 * (c2.x - c1.x) +\n 0.5 ** 2 * (end.x - c2.x));\n const ty =\n 3 *\n ((1 - 0.5) ** 2 * (c1.y - start.y) +\n 2 * (1 - 0.5) * 0.5 * (c2.y - c1.y) +\n 0.5 ** 2 * (end.y - c2.y));\n const midAngle = Math.atan2(ty, tx);\n\n return { d, midX, midY, midAngle };\n}\n\n/**\n * Distance from `from` to `to` along the axis the `side` points in.\n * Positive = `to` is in front of the port; negative = behind.\n */\nfunction axisDistance(from: Position, side: HandlePosition, to: Position): number {\n switch (side) {\n case \"top\":\n return from.y - to.y;\n case \"bottom\":\n return to.y - from.y;\n case \"left\":\n return from.x - to.x;\n case \"right\":\n return to.x - from.x;\n }\n}\n\nfunction calcControlOffset(\n from: Position,\n side: HandlePosition,\n to: Position,\n curvature: number,\n): number {\n const distance = axisDistance(from, side, to);\n if (distance >= 0) {\n // Linear fraction of axis distance — produces gentle S-curves.\n return distance * 0.5 * (1 + curvature);\n }\n // Backward — square-root falloff so the curve fans wide without\n // shooting off into space at extreme distances. The 25-multiplier is\n // tuned to match React Flow's visual behaviour.\n return curvature * 25 * Math.sqrt(-distance);\n}\n\nfunction offsetAlongSide(p: Position, side: HandlePosition, magnitude: number): Position {\n switch (side) {\n case \"top\":\n return { x: p.x, y: p.y - magnitude };\n case \"bottom\":\n return { x: p.x, y: p.y + magnitude };\n case \"left\":\n return { x: p.x - magnitude, y: p.y };\n case \"right\":\n return { x: p.x + magnitude, y: p.y };\n }\n}\n\n// ── Step routing — orthogonal Z/U-bend ────────────────────────────────\n// For top/bottom ports: vertical-horizontal-vertical (Z). For left/right\n// ports: horizontal-vertical-horizontal. Mixed sides produce an L.\nexport function stepPath(\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n): PathGeometry {\n const corners = computeStepCorners(start, startSide, end, endSide);\n const pts = [start, ...corners, end];\n const d = pts.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x},${p.y}`).join(\" \");\n // Midpoint along the longest segment so label/delete don't overlap a corner.\n const { midX, midY, midAngle } = midpointOnPolyline(pts);\n return { d, midX, midY, midAngle };\n}\n\n// ── Smoothstep — step with rounded corners ────────────────────────────\nexport function smoothStepPath(\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n borderRadius = 8,\n): PathGeometry {\n const corners = computeStepCorners(start, startSide, end, endSide);\n const pts = [start, ...corners, end];\n if (corners.length === 0) {\n return straightPath(start, end);\n }\n // Build SVG path with `Q` arcs at each interior corner.\n const segments: string[] = [`M ${pts[0].x},${pts[0].y}`];\n for (let i = 1; i < pts.length - 1; i++) {\n const prev = pts[i - 1];\n const here = pts[i];\n const next = pts[i + 1];\n // Cap the radius so it never exceeds half of the adjacent segments.\n const r = Math.min(borderRadius, distance(prev, here) / 2, distance(here, next) / 2);\n const enter = pointTowards(here, prev, r);\n const exit = pointTowards(here, next, r);\n segments.push(`L ${enter.x},${enter.y}`);\n segments.push(`Q ${here.x},${here.y} ${exit.x},${exit.y}`);\n }\n const last = pts[pts.length - 1];\n segments.push(`L ${last.x},${last.y}`);\n const d = segments.join(\" \");\n const { midX, midY, midAngle } = midpointOnPolyline(pts);\n return { d, midX, midY, midAngle };\n}\n\n// ── Straight ─────────────────────────────────────────────────────────\nexport function straightPath(start: Position, end: Position): PathGeometry {\n const d = `M ${start.x},${start.y} L ${end.x},${end.y}`;\n return {\n d,\n midX: (start.x + end.x) / 2,\n midY: (start.y + end.y) / 2,\n midAngle: Math.atan2(end.y - start.y, end.x - start.x),\n };\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────\nfunction computeStepCorners(\n start: Position,\n startSide: HandlePosition,\n end: Position,\n endSide: HandlePosition,\n): Position[] {\n const sourceVertical = startSide === \"top\" || startSide === \"bottom\";\n const targetVertical = endSide === \"top\" || endSide === \"bottom\";\n\n if (sourceVertical && targetVertical) {\n // Z-shape: vertical → horizontal → vertical.\n const midY = (start.y + end.y) / 2;\n return [\n { x: start.x, y: midY },\n { x: end.x, y: midY },\n ];\n }\n if (!sourceVertical && !targetVertical) {\n // Same idea horizontally.\n const midX = (start.x + end.x) / 2;\n return [\n { x: midX, y: start.y },\n { x: midX, y: end.y },\n ];\n }\n // Mixed — L-shape (single corner at the intersection).\n if (sourceVertical) {\n return [{ x: end.x, y: start.y }];\n }\n return [{ x: start.x, y: end.y }];\n}\n\nfunction midpointOnPolyline(pts: Position[]): {\n midX: number;\n midY: number;\n midAngle: number;\n} {\n if (pts.length === 2) {\n return {\n midX: (pts[0].x + pts[1].x) / 2,\n midY: (pts[0].y + pts[1].y) / 2,\n midAngle: Math.atan2(pts[1].y - pts[0].y, pts[1].x - pts[0].x),\n };\n }\n // Walk segments accumulating length; pick the segment whose midpoint\n // is closest to the half-length mark. Anchoring the label to the\n // longest segment keeps it readable.\n let totalLen = 0;\n const lens: number[] = [];\n for (let i = 0; i < pts.length - 1; i++) {\n const l = distance(pts[i], pts[i + 1]);\n lens.push(l);\n totalLen += l;\n }\n const half = totalLen / 2;\n let acc = 0;\n for (let i = 0; i < lens.length; i++) {\n if (acc + lens[i] >= half) {\n const seg = lens[i];\n const remaining = half - acc;\n const t = seg === 0 ? 0 : remaining / seg;\n const a = pts[i];\n const b = pts[i + 1];\n return {\n midX: a.x + (b.x - a.x) * t,\n midY: a.y + (b.y - a.y) * t,\n midAngle: Math.atan2(b.y - a.y, b.x - a.x),\n };\n }\n acc += lens[i];\n }\n // Fallback — unreachable in practice.\n return { midX: pts[0].x, midY: pts[0].y, midAngle: 0 };\n}\n\nfunction distance(a: Position, b: Position): number {\n return Math.hypot(b.x - a.x, b.y - a.y);\n}\n\nfunction pointTowards(from: Position, to: Position, dist: number): Position {\n const d = distance(from, to);\n if (d === 0) return from;\n const t = dist / d;\n return { x: from.x + (to.x - from.x) * t, y: from.y + (to.y - from.y) * t };\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Per-canvas handle registry — Edge components look up handle positions\n// via this registry so they don't need to thread DOM refs around.\n// ════════════════════════════════════════════════════════════════════════\n// The Handle component registers itself on mount with its (nodeId,\n// handleId, type, side, index, total) tuple. FlowEdge derives the absolute\n// flow-space centre via `handleCentre()` using `node.position +\n// node.dimensions + side + index/total`.\n//\n// Keys are `(nodeId, type, handleId)` — note the `type`! Input and\n// output handles can legitimately share an id (the default is `\"default\"`\n// for both), and the type disambiguates. Without this, a node with one\n// input + one output (both with id `\"default\"`) would collide and edges\n// would resolve the wrong side.\n\nimport { createContext, useContext } from \"react\";\nimport type { HandlePosition, HandleType } from \"../../editor\";\n\nexport interface HandleDescriptor {\n nodeId: string;\n handleId: string;\n type: HandleType;\n /** Physical edge the handle dot sits on — drives placement + the\n * handle's flow-space centre. */\n side: HandlePosition;\n /**\n * Edge-routing direction. The bezier leaves/enters along THIS side,\n * which is normally the same as `side`. A subflow's inner-facing port\n * sits on the frame's outer edge (`side`) but must route INWARD — e.g.\n * a port physically on `top` whose wire should curve `down` into the\n * frame sets `routeSide: \"bottom\"`. Defaults to `side`.\n */\n routeSide: HandlePosition;\n /** 0-based position among same-(node, side, type) handles. */\n index: number;\n /** Total handles on the same (node, side, type). */\n total: number;\n /** May this handle START a connection? Defaults true. */\n canStart: boolean;\n /** May this handle END a connection? Defaults true. */\n canEnd: boolean;\n}\n\nexport interface HandleRegistry {\n register(d: HandleDescriptor): () => void;\n resolve(nodeId: string, type: HandleType, handleId: string): HandleDescriptor | undefined;\n /** Every currently-registered handle. Used by the connection drag to\n * resolve a drop target geometrically (nearest handle within snap\n * radius) rather than relying on DOM hit-testing, which is fragile\n * against z-index / pointer-events / overlapping subflow frames. */\n all(): HandleDescriptor[];\n /**\n * Subscribe to registry mutations. Fires after every register /\n * unregister so listeners (typically the EdgesLayer) can re-render\n * once the new handles are present. Without this, edges resolved\n * during the same React commit as a node remount fall back to default\n * positions because the Handle's `useEffect` hasn't yet written its\n * descriptor — which is what caused the post-collapse stale-edge bug\n * inside subflows.\n */\n subscribe(listener: () => void): () => void;\n}\n\nexport const HandleRegistryContext = createContext<HandleRegistry | null>(null);\n\nexport function useHandleRegistry(): HandleRegistry {\n const r = useContext(HandleRegistryContext);\n if (!r) {\n throw new Error(\"[@octaviaflow/core/workflow] Handle must be used inside <FlowCanvas>.\");\n }\n return r;\n}\n\n/**\n * Build a registry. One per FlowCanvas instance.\n */\nexport function createHandleRegistry(): HandleRegistry {\n const map = new Map<string, HandleDescriptor>();\n const key = (n: string, t: HandleType, h: string) => `${n}::${t}::${h}`;\n const listeners = new Set<() => void>();\n const notify = () => {\n for (const l of listeners) l();\n };\n return {\n register(d) {\n map.set(key(d.nodeId, d.type, d.handleId), d);\n notify();\n return () => {\n // Only delete if our descriptor is still the registered one — guards\n // against races when a node unmounts a Handle and immediately\n // remounts it with the same id during a quick re-render.\n const k = key(d.nodeId, d.type, d.handleId);\n if (map.get(k) === d) {\n map.delete(k);\n notify();\n }\n };\n },\n resolve(nodeId, type, handleId) {\n return map.get(key(nodeId, type, handleId));\n },\n all() {\n return Array.from(map.values());\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FlowNode — wrapper for any node in the v2 editor.\n// ════════════════════════════════════════════════════════════════════════\n// Responsibilities:\n// 1. Position itself absolutely at `node.position` (in flow space).\n// 2. Provide FlowNodeContext so descendants (Handle, NodeToolbar) know\n// which node they live in.\n// 3. Begin drag on pointerdown (the canvas-level pointermove takes over).\n// 4. Begin selection on click.\n// 5. Dispatch to the kind component for the actual chrome.\n//\n// The wrapper does NOT subscribe to its own selected state via the store;\n// instead the parent NodesLayer passes the resolved `selected` flag down\n// — keeps re-render fan-out predictable.\n\nimport { type PointerEvent, useEffect, useMemo, useRef } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport type { WorkflowNode } from \"../../editor\";\nimport { useFlowNodeBridge } from \"../FlowCanvas/FlowCanvasContext\";\nimport { FlowNodeContext, type FlowNodeContextValue } from \"./FlowNodeContext\";\nimport type { NodeKindComponent } from \"./nodeKinds\";\n\nexport interface FlowNodeProps {\n node: WorkflowNode;\n selected: boolean;\n dragging: boolean;\n isConnecting: boolean;\n Kind: NodeKindComponent;\n /** Optional fallback width for un-measured nodes — defaults to 240. */\n defaultWidth?: number;\n}\n\nexport function FlowNode({\n node,\n selected,\n dragging,\n isConnecting,\n Kind,\n // Match the BaseNode body's fixed 368 px width so the wrapper bbox and\n // the rendered card line up on the first paint — before the\n // ResizeObserver has had a chance to write back the measured size.\n // Container kinds (group / forEach) opt out by setting `node.width`.\n defaultWidth = 368,\n}: FlowNodeProps) {\n const bridge = useFlowNodeBridge();\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n // ── ResizeObserver — feed real dimensions back through onNodesChange so\n // edges can compute endpoints against the actual rendered footprint.\n // Without this, every node looks 96px tall to the edge layer and arrows\n // land mid-air below tall nodes.\n //\n // Container kinds (`group`, `forEach`) are EXEMPT. Why: when a group is\n // collapsed its rendered height shrinks to 36px; if we measure that the\n // 36px gets written back into `node.height` and the group never restores\n // its expanded height on un-collapse. Container size is consumer-driven\n // (set explicitly via `node.width` / `node.height`) — no measurement.\n useEffect(() => {\n const el = wrapperRef.current;\n if (!el || typeof ResizeObserver === \"undefined\") return;\n if (node.type === \"group\" || node.type === \"forEach\") return;\n const ro = new ResizeObserver(() => {\n // `offsetWidth/Height` are un-affected by ancestor CSS transforms\n // (the canvas viewport applies `scale(zoom)`). `getBoundingClientRect`\n // would scale with zoom and give us wildly wrong values when zoomed\n // in/out.\n bridge.reportDimensions(node.id, el.offsetWidth, el.offsetHeight);\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, [bridge, node.id, node.type]);\n\n const ctx = useMemo<FlowNodeContextValue>(\n () => ({ id: node.id, node, selected }),\n [node, selected],\n );\n\n // Track pointerdown coordinates so we can decide post-pointerup whether\n // this was a click or a drag. DOM fires `click` after a drag too, which\n // would otherwise re-open the config panel when the user only moved the\n // node. 5 px matches the platform's canvas `paneClickDistance` default.\n const downPosRef = useRef<{ x: number; y: number } | null>(null);\n const draggedRef = useRef(false);\n const CLICK_VS_DRAG_PX = 5;\n\n const handlePointerDown = (e: PointerEvent<HTMLDivElement>) => {\n // Only the primary (left) button starts a node drag. A right/middle\n // press must fall through to the context menu (and not stopPropagation),\n // so it can't begin a drag or collapse the selection (DEV-206).\n if (e.button !== 0) return;\n // Skip drag if the pointerdown originated on a handle — that gesture\n // is owned by the connect middleware.\n if ((e.target as HTMLElement).closest(\"[data-handle-id]\")) return;\n // Skip drag inside opt-out regions (allows form controls inside nodes).\n if ((e.target as HTMLElement).closest(\"[data-flow-no-drag='true']\")) return;\n e.stopPropagation();\n downPosRef.current = { x: e.clientX, y: e.clientY };\n draggedRef.current = false;\n // Pass through altKey — the canvas's drag middleware uses it for\n // Alt-detach (drop out of a parent group, or rebind into a new one).\n bridge.beginNodeDrag(node.id, e.pointerId, e.clientX, e.clientY, e.altKey);\n };\n\n const handlePointerMove = (e: PointerEvent<HTMLDivElement>) => {\n const start = downPosRef.current;\n if (!start || draggedRef.current) return;\n if (\n Math.abs(e.clientX - start.x) > CLICK_VS_DRAG_PX ||\n Math.abs(e.clientY - start.y) > CLICK_VS_DRAG_PX\n ) {\n draggedRef.current = true;\n }\n };\n\n const handleClick = (e: PointerEvent<HTMLDivElement>) => {\n if ((e.target as HTMLElement).closest(\"[data-handle-id]\")) return;\n e.stopPropagation();\n // Click that arrives after a drag is a synthetic side-effect — DO NOT\n // re-fire selection or notify the consumer (would re-open the panel\n // they were trying to keep on the original node).\n if (draggedRef.current) {\n draggedRef.current = false;\n downPosRef.current = null;\n return;\n }\n downPosRef.current = null;\n // Selection state was already updated at pointerdown by beginNodeDrag.\n // Here we re-assert it (handles meta-key toggle on already-selected\n // nodes) and ALSO notify the consumer of the click — which `selectNode`\n // intentionally no longer does on its own.\n bridge.selectNode(node.id, e.metaKey || e.ctrlKey || e.shiftKey);\n bridge.notifyNodeClick(node.id);\n };\n\n return (\n <div\n ref={wrapperRef}\n data-node-id={node.id}\n data-node-type={node.type}\n data-node-selected={selected ? \"true\" : \"false\"}\n className={cn(\n \"ods-flow-node-v2\",\n `ods-flow-node-v2--kind-${node.type}`,\n selected && \"ods-flow-node-v2--selected\",\n dragging && \"ods-flow-node-v2--dragging\",\n isConnecting && \"ods-flow-node-v2--connecting\",\n node.className,\n )}\n style={{\n position: \"absolute\",\n left: node.position.x,\n top: node.position.y,\n width: node.width ?? defaultWidth,\n // Z-stack (per architecture doc): groups (20) sit below normal\n // nodes (30) so children render visually on top of their parent\n // frame. Selection raises by 10. Consumer override wins.\n zIndex:\n node.zIndex ??\n (selected ? (node.type === \"group\" ? 35 : 40) : node.type === \"group\" ? 20 : 30),\n ...node.style,\n }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onClick={handleClick}\n >\n <FlowNodeContext.Provider value={ctx}>\n <Kind node={node} selected={selected} dragging={dragging} isConnecting={isConnecting} />\n </FlowNodeContext.Provider>\n </div>\n );\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FlowCanvasContext — imperative entry points used by Handle + FlowNode.\n// ════════════════════════════════════════════════════════════════════════\n// Each `<FlowCanvas>` creates a private context value containing the\n// callbacks needed by its descendants. We expose these via a \"dispatch\"\n// hook in the spirit of useReducer; the action payload is opaque to\n// descendants — they just know which method to call.\n\nimport { createContext, useContext } from \"react\";\n\nexport interface FlowDispatchAction {\n type: \"connection/start\";\n nodeId: string;\n handleId: string;\n handleType: \"source\" | \"target\";\n pointerId: number;\n clientX: number;\n clientY: number;\n}\n\nexport type FlowDispatch = (action: FlowDispatchAction) => void;\n\nexport const FlowDispatchContext = createContext<FlowDispatch | null>(null);\n\nexport function useFlowDispatch(): FlowDispatch {\n const dispatch = useContext(FlowDispatchContext);\n if (!dispatch) {\n throw new Error(\n \"[@octaviaflow/core/workflow] useFlowDispatch must be called inside <FlowCanvas>.\",\n );\n }\n return dispatch;\n}\n\n/**\n * Internal-only callbacks shared with FlowNode. Not part of the public\n * surface; node renderers use the `useFlowNodeContext` hook instead.\n */\nexport interface FlowNodeBridge {\n beginNodeDrag(\n nodeId: string,\n pointerId: number,\n clientX: number,\n clientY: number,\n altKey?: boolean,\n ): void;\n selectNode(nodeId: string, additive: boolean): void;\n /**\n * Fire the consumer's `onNodeClick` for this node. Split from\n * `selectNode` so drag-start (which selects the node so it carries the\n * selection style) does NOT also fire the click event — otherwise a\n * drag would re-open the config panel.\n */\n notifyNodeClick(nodeId: string): void;\n selectEdge(edgeId: string, additive: boolean): void;\n /**\n * Reports measured DOM dimensions back to the canvas. FlowNode observes\n * itself via ResizeObserver and calls this on size changes. The canvas\n * de-dupes (skips when w/h unchanged) and emits a `dimensions`\n * NodeChange so edges can recompute against the real footprint.\n */\n reportDimensions(nodeId: string, width: number, height: number): void;\n /** Removes a single node. Edges that reference it are dropped too. */\n deleteNode(nodeId: string): void;\n /**\n * Toggle the `data.collapsed` flag on a group / forEach container.\n * Used by the chevron in the GroupNode / ForEachNode header so the\n * user can expand/collapse the subflow without an external toolbar.\n * No-op for non-container kinds.\n */\n toggleNodeCollapse(nodeId: string): void;\n}\n\nexport const FlowNodeBridgeContext = createContext<FlowNodeBridge | null>(null);\n\nexport function useFlowNodeBridge(): FlowNodeBridge {\n const b = useContext(FlowNodeBridgeContext);\n if (!b) {\n throw new Error(\"[@octaviaflow/core/workflow] FlowNode must be a child of <FlowCanvas>.\");\n }\n return b;\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FlowNodeContext — descendants of a node (Handle, NodeToolbar, …) read\n// the node id and basic state through this context.\n// ════════════════════════════════════════════════════════════════════════\n\nimport { createContext, useContext } from \"react\";\nimport type { WorkflowNode } from \"../../editor\";\n\nexport interface FlowNodeContextValue {\n id: string;\n node: WorkflowNode;\n selected: boolean;\n}\n\nexport const FlowNodeContext = createContext<FlowNodeContextValue | null>(null);\n\nexport function useFlowNodeContext(): FlowNodeContextValue {\n const v = useContext(FlowNodeContext);\n if (!v) {\n throw new Error(\n \"[@octaviaflow/core/workflow] Handle / NodeToolbar must be inside a node renderer.\",\n );\n }\n return v;\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Node-kind registry — maps a `node.type` string to a React component.\n// ════════════════════════════════════════════════════════════════════════\n// We deliberately avoid the \"pass a `nodeTypes` map prop and pray the\n// caller memoises it\" anti-pattern. The registry is a stable map managed\n// internally; consumers can extend it via `useRegisterNodeKind()` or by\n// passing an override prop that is *frozen* by the canvas the first time\n// it sees it.\n\nimport type { ComponentType } from \"react\";\nimport type { WorkflowNode } from \"../../editor\";\n\n/**\n * Props passed to every kind renderer. Matches the public `NodeProps`\n * shape we expose to consumers; we deliberately do NOT duplicate\n * coordinate fields (see ADR-003).\n */\nexport interface NodeKindProps<TData = unknown> {\n /** The full node — kinds read `data`, can mutate via `updateNodeData`. */\n node: WorkflowNode<TData>;\n /** True when this node is the focus of selection. */\n selected: boolean;\n /** True while a drag is in progress on this node. */\n dragging: boolean;\n /** True when any connection drag is in flight and could end here. */\n isConnecting: boolean;\n}\n\nexport type NodeKindComponent<TData = unknown> = ComponentType<NodeKindProps<TData>>;\n\nexport type NodeKindRegistry = Record<string, NodeKindComponent>;\n\n/**\n * Build a registry from a default set plus optional overrides. The result\n * is a frozen object so consumers can't mutate it post-hoc.\n */\nexport function buildNodeKindRegistry(\n defaults: NodeKindRegistry,\n overrides?: NodeKindRegistry,\n): NodeKindRegistry {\n return Object.freeze({ ...defaults, ...(overrides ?? {}) });\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// Handle — a port primitive that custom node renderers drop in.\n// ════════════════════════════════════════════════════════════════════════\n// Responsibilities:\n// 1. Register its descriptor (nodeId, handleId, type, side, index, total)\n// so edges can resolve its absolute centre.\n// 2. Render a visible dot at the configured side.\n// 3. Initiate connection drags via Pointer Events.\n//\n// The Handle does NOT own pointermove / pointerup — those live on the\n// FlowCanvas-level connect middleware, which sees the gesture all the\n// way through even if the pointer leaves the handle.\n\nimport { type CSSProperties, type PointerEvent, useEffect, useRef } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport type { HandlePosition, HandleType } from \"../../editor\";\nimport { useFlowDispatch } from \"../FlowCanvas/FlowCanvasContext\";\nimport { useFlowNodeContext } from \"../FlowNode/FlowNodeContext\";\nimport { useHandleRegistry } from \"./handleRegistry\";\n\nexport interface HandleProps {\n /** `source` = connections start here; `target` = connections end here. */\n type: HandleType;\n /** Which side of the node the handle sits on. */\n position: HandlePosition;\n /**\n * Direction the edge should route from this handle. Defaults to\n * `position`. Override it when the handle dot sits on one edge but the\n * wire must leave/enter from another — e.g. a subflow's inner-facing\n * port lives on the frame's `top` edge yet its wire curves `down` into\n * the frame: `position=\"top\" routeSide=\"bottom\"`.\n */\n routeSide?: HandlePosition;\n /** Stable id within the node. Default `\"default\"`; required when >1 handle of same type. */\n id?: string;\n /** Defaults to true. Setting false disables both starting and ending here. */\n isConnectable?: boolean;\n /** Allow this handle to *start* a connection. Defaults to `isConnectable`. */\n isConnectableStart?: boolean;\n /** Allow this handle to *end* a connection. Defaults to `isConnectable`. */\n isConnectableEnd?: boolean;\n /** 0-based position among same-(node, side) handles. Defaults to 0. */\n index?: number;\n /** Total handles on the same (node, side). Defaults to 1. */\n total?: number;\n /** Optional caption rendered next to the dot (e.g. \"true\"/\"false\"). */\n label?: string;\n className?: string;\n style?: CSSProperties;\n}\n\nconst DEFAULT_HANDLE_ID = \"default\";\n\nexport function Handle({\n type,\n position,\n routeSide,\n id = DEFAULT_HANDLE_ID,\n isConnectable = true,\n isConnectableStart,\n isConnectableEnd,\n index = 0,\n total = 1,\n label,\n className,\n style,\n}: HandleProps) {\n const registry = useHandleRegistry();\n const node = useFlowNodeContext();\n const dispatch = useFlowDispatch();\n const ref = useRef<HTMLDivElement>(null);\n\n const canStart = isConnectableStart ?? isConnectable;\n const canEnd = isConnectableEnd ?? isConnectable;\n\n // Register on every render so changes to side/index/total are visible\n // immediately to edges. The registry de-dupes by (nodeId, handleId).\n useEffect(() => {\n const dispose = registry.register({\n nodeId: node.id,\n handleId: id,\n type,\n side: position,\n routeSide: routeSide ?? position,\n index,\n total,\n canStart,\n canEnd,\n });\n return dispose;\n }, [registry, node.id, id, type, position, routeSide, index, total, canStart, canEnd]);\n\n const handlePointerDown = (e: PointerEvent<HTMLDivElement>) => {\n if (!canStart) return;\n // Only the primary (left) button starts a connection drag (DEV-206).\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n dispatch({\n type: \"connection/start\",\n nodeId: node.id,\n handleId: id,\n handleType: type,\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n });\n };\n\n // Pointerup on a Handle is the \"drop on this handle\" gesture. The\n // FlowCanvas-level pointerup also fires; the canvas resolves the target\n // handle by hit-testing `e.target.closest('[data-handle-id]')`.\n return (\n <div\n ref={ref}\n data-handle-id={id}\n data-handle-node-id={node.id}\n data-handle-type={type}\n data-handle-side={position}\n data-handle-connectable-end={canEnd ? \"true\" : \"false\"}\n className={cn(\n \"ods-flow-handle\",\n `ods-flow-handle--${type}`,\n `ods-flow-handle--side-${position}`,\n !isConnectable && \"ods-flow-handle--disabled\",\n className,\n )}\n style={{\n ...handleSideStyle(position, index, total),\n ...style,\n }}\n onPointerDown={handlePointerDown}\n >\n <div className=\"ods-flow-handle__dot\" />\n {label && <span className=\"ods-flow-handle__label\">{label}</span>}\n </div>\n );\n}\n\n// Position the handle along its side. The visual element is small\n// (12 px), so we offset by half its size so the dot's centre lands on\n// the node's edge. Index/total spread multiple handles evenly.\nfunction handleSideStyle(side: HandlePosition, index: number, total: number): CSSProperties {\n const ratio = ((index + 1) / (total + 1)) * 100;\n switch (side) {\n case \"top\":\n return { position: \"absolute\", top: -6, left: `${ratio}%`, transform: \"translateX(-50%)\" };\n case \"bottom\":\n return { position: \"absolute\", bottom: -6, left: `${ratio}%`, transform: \"translateX(-50%)\" };\n case \"left\":\n return { position: \"absolute\", left: -6, top: `${ratio}%`, transform: \"translateY(-50%)\" };\n case \"right\":\n return { position: \"absolute\", right: -6, top: `${ratio}%`, transform: \"translateY(-50%)\" };\n }\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// NodeResizer — drag-to-resize handles attached to a node.\n// ════════════════════════════════════════════════════════════════════════\n// Dropped inside a custom node renderer. Four corner handles each adjust\n// width/height (and, where appropriate, position so the OPPOSITE corner\n// stays pinned). Width/height changes flow back through the imperative\n// instance via `updateNode`.\n//\n// Visible by default only when the host node is selected. Min/max sizes\n// + aspect-ratio lock keep the resize sensible. We deliberately do NOT\n// ship a `shouldResize` veto (yet) — that's a follow-on.\n\nimport { type CSSProperties, type PointerEvent, useRef } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport { useFlow } from \"../../hooks/useFlow\";\nimport { useViewport } from \"../../store/selectors\";\nimport { DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH } from \"../../utils/geometry\";\nimport { useFlowNodeContext } from \"../FlowNode/FlowNodeContext\";\n\nexport interface NodeResizerProps {\n /** Force-visible. Default: visible iff the host node is selected. */\n isVisible?: boolean;\n /** Lower bound for the resize. Defaults to 80×60. */\n minWidth?: number;\n minHeight?: number;\n /** Upper bound for the resize. Defaults unbounded. */\n maxWidth?: number;\n maxHeight?: number;\n /** Lock width:height ratio at the value computed from the node's\n * current dimensions on resize-start. */\n keepAspectRatio?: boolean;\n /** Fired on every pointermove during resize. */\n onResize?: (size: { width: number; height: number }) => void;\n /** Fired on pointerup (the committed size). */\n onResizeEnd?: (size: { width: number; height: number }) => void;\n /** Override handle colour. */\n color?: string;\n}\n\ntype Corner = \"nw\" | \"ne\" | \"sw\" | \"se\";\n\ninterface DragState {\n pointerId: number;\n corner: Corner;\n startClientX: number;\n startClientY: number;\n startWidth: number;\n startHeight: number;\n startX: number;\n startY: number;\n aspect: number; // w / h\n}\n\nexport function NodeResizer({\n isVisible,\n minWidth = 80,\n minHeight = 60,\n maxWidth,\n maxHeight,\n keepAspectRatio = false,\n onResize,\n onResizeEnd,\n color,\n}: NodeResizerProps) {\n const { node, selected } = useFlowNodeContext();\n const viewport = useViewport();\n const flow = useFlow();\n const dragRef = useRef<DragState | null>(null);\n\n const show = isVisible ?? selected;\n if (!show) return null;\n\n const beginResize = (e: PointerEvent<HTMLDivElement>, corner: Corner) => {\n // Only the primary (left) button resizes — a right/middle press must not\n // start a resize gesture (DEV-206).\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n const w = node.width ?? DEFAULT_NODE_WIDTH;\n const h = node.height ?? DEFAULT_NODE_HEIGHT;\n dragRef.current = {\n pointerId: e.pointerId,\n corner,\n startClientX: e.clientX,\n startClientY: e.clientY,\n startWidth: w,\n startHeight: h,\n startX: node.position.x,\n startY: node.position.y,\n aspect: w / Math.max(1, h),\n };\n };\n\n const onMove = (e: PointerEvent<HTMLDivElement>) => {\n const drag = dragRef.current;\n if (!drag || drag.pointerId !== e.pointerId) return;\n const dx = (e.clientX - drag.startClientX) / viewport.zoom;\n const dy = (e.clientY - drag.startClientY) / viewport.zoom;\n // The edges OPPOSITE the dragged corner are anchored — they must not\n // move. Capture them up front so we can re-derive the top-left from the\n // CLAMPED size below. Deriving position from the raw pointer delta made\n // the node slide across the canvas once a corner hit its min/max clamp:\n // the size stopped changing but the position kept tracking the pointer\n // (DEV-206).\n const fixedRight = drag.startX + drag.startWidth;\n const fixedBottom = drag.startY + drag.startHeight;\n let nextW = drag.startWidth;\n let nextH = drag.startHeight;\n switch (drag.corner) {\n case \"se\":\n nextW = drag.startWidth + dx;\n nextH = drag.startHeight + dy;\n break;\n case \"sw\":\n nextW = drag.startWidth - dx;\n nextH = drag.startHeight + dy;\n break;\n case \"ne\":\n nextW = drag.startWidth + dx;\n nextH = drag.startHeight - dy;\n break;\n case \"nw\":\n nextW = drag.startWidth - dx;\n nextH = drag.startHeight - dy;\n break;\n }\n if (keepAspectRatio) {\n // Maintain the original ratio — fit height to width.\n nextH = nextW / drag.aspect;\n }\n nextW = Math.max(minWidth, maxWidth ? Math.min(maxWidth, nextW) : nextW);\n nextH = Math.max(minHeight, maxHeight ? Math.min(maxHeight, nextH) : nextH);\n // Re-derive the top-left from the CLAMPED size so the anchored edges stay\n // put. `se` keeps the top-left fixed; the others anchor the opposite\n // right/bottom edge.\n let nextX = drag.startX;\n let nextY = drag.startY;\n switch (drag.corner) {\n case \"se\":\n break;\n case \"sw\":\n nextX = fixedRight - nextW;\n break;\n case \"ne\":\n nextY = fixedBottom - nextH;\n break;\n case \"nw\":\n nextX = fixedRight - nextW;\n nextY = fixedBottom - nextH;\n break;\n }\n flow.updateNode(node.id, {\n width: nextW,\n height: nextH,\n position: { x: nextX, y: nextY },\n });\n onResize?.({ width: nextW, height: nextH });\n };\n\n const onUp = (e: PointerEvent<HTMLDivElement>) => {\n if (dragRef.current?.pointerId === e.pointerId) {\n const cur = flow.getNode(node.id);\n if (cur) {\n onResizeEnd?.({\n width: cur.width ?? DEFAULT_NODE_WIDTH,\n height: cur.height ?? DEFAULT_NODE_HEIGHT,\n });\n }\n dragRef.current = null;\n }\n };\n\n const handleColor = color ?? \"var(--ods-accent)\";\n const handleStyle = (corner: Corner): CSSProperties => {\n const base: CSSProperties = {\n position: \"absolute\",\n width: 12,\n height: 12,\n background: \"var(--ods-surface-canvas)\",\n border: `2px solid ${handleColor}`,\n borderRadius: 2,\n cursor: cursorFor(corner),\n touchAction: \"none\",\n // Place each handle so its CENTRE sits on the corresponding corner.\n transform: \"translate(-50%, -50%)\",\n };\n switch (corner) {\n case \"nw\":\n return { ...base, top: 0, left: 0 };\n case \"ne\":\n return { ...base, top: 0, left: \"100%\" };\n case \"sw\":\n return { ...base, top: \"100%\", left: 0 };\n case \"se\":\n return { ...base, top: \"100%\", left: \"100%\" };\n }\n };\n\n return (\n <div className={cn(\"ods-node-resizer\")} data-flow-no-drag=\"true\">\n {([\"nw\", \"ne\", \"sw\", \"se\"] as Corner[]).map((corner) => (\n <div\n key={corner}\n style={handleStyle(corner)}\n onPointerDown={(e) => beginResize(e, corner)}\n onPointerMove={onMove}\n onPointerUp={onUp}\n onPointerCancel={onUp}\n aria-label={`Resize ${corner}`}\n />\n ))}\n </div>\n );\n}\n\nfunction cursorFor(corner: Corner): string {\n // Standard 8-direction resize cursors. We only ship corners for v1; the\n // edge handles (n/s/e/w) can come later.\n switch (corner) {\n case \"nw\":\n case \"se\":\n return \"nwse-resize\";\n case \"ne\":\n case \"sw\":\n return \"nesw-resize\";\n }\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// BaseNode — shared chrome for built-in kinds.\n// ════════════════════════════════════════════════════════════════════════\n// Visual structure (mirrors the finalised platform node):\n//\n// ┌─[ KIND ]──────────────────────────────────┐ ← external pill = node TYPE\n// │ ╭──╮ Title (node NAME) │\n// │ │● │ ▸ [CHIP] description-value │ ← chip + value (config-driven)\n// │ ╰──╯ │\n// │ [×] │ ← delete bottom-right\n// └──────────────────────────────────────────[●] ← status top-right\n//\n// The pill is the node TYPE label (e.g. \"HTTP\", \"WEBHOOK\", \"ACTION\") —\n// not the node name. The name lives in the body title. The body's info\n// line takes an optional `chip` (small inline badge) plus a value, which\n// is the canonical pattern for showing the most-relevant config value\n// (HTTP method + path, condition operator + expression, etc.).\n\nimport { TrashCanIcon } from \"@octaviaflow/icons\";\nimport { type ReactNode, useContext } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport { FlowNodeBridgeContext } from \"../FlowCanvas/FlowCanvasContext\";\nimport { FlowNodeContext } from \"../FlowNode/FlowNodeContext\";\n\nexport type BaseNodeStatus = \"idle\" | \"running\" | \"success\" | \"error\" | \"warning\";\n\nexport interface BaseNodeProps {\n /** Pill label — the node TYPE/category (e.g. \"HTTP\", \"WEBHOOK\", \"ACTION\"). */\n kind: ReactNode;\n /** Optional small icon inside the pill, left of the kind label. */\n kindIcon?: ReactNode;\n /** Icon shown in the body bubble (32px circle). */\n icon?: ReactNode;\n /** Bold name shown in the body — this is the user-facing instance name. */\n title: ReactNode;\n /**\n * Optional chip rendered before the description text — used for\n * configuration values like HTTP method (\"GET\"), condition operator\n * (\"==\"), execution mode, etc. Inherits the accent colour.\n */\n chip?: ReactNode;\n /**\n * The body description / value — typically the most-relevant config\n * field (path, url, expression). Clamps to two lines.\n */\n description?: ReactNode;\n /**\n * Generic right-aligned chip slot. Renders inside the info row to the\n * right of the description (e.g. an `/v1/orders/:id` path chip next to\n * a `GET` method `chip`). Inherits the kind accent like `chip` does.\n */\n valueChip?: ReactNode;\n /** Per-kind accent — paints the pill background and the chip. */\n accent?: \"blue\" | \"violet\" | \"amber\" | \"green\" | \"red\" | \"slate\";\n /** Status dot in the top-right corner (config / runtime). */\n status?: BaseNodeStatus;\n /**\n * Delete button click — when set, the corner [×] button uses this. If\n * omitted, BaseNode auto-wires it through the FlowCanvas bridge so the\n * default behaviour is \"this button deletes me\". Pass `false` to hide.\n */\n onDelete?: (() => void) | false;\n /** Footer slot below the description (e.g. additional metadata). */\n footer?: ReactNode;\n className?: string;\n /** Handles + extras — positioned absolutely by the caller. */\n children?: ReactNode;\n}\n\nexport function BaseNode({\n kind,\n kindIcon,\n icon,\n title,\n chip,\n description,\n valueChip,\n accent = \"green\",\n status,\n onDelete,\n footer,\n className,\n children,\n}: BaseNodeProps) {\n // Auto-wire delete via the canvas bridge when the kind didn't pass an\n // explicit handler. `onDelete={false}` disables the button entirely.\n const ctx = useContext(FlowNodeContext);\n const bridge = useContext(FlowNodeBridgeContext);\n const deleteHandler: (() => void) | undefined =\n onDelete === false\n ? undefined\n : (onDelete ?? (ctx && bridge ? () => bridge.deleteNode(ctx.id) : undefined));\n return (\n <div\n className={cn(\n \"ods-flow-base-node\",\n `ods-flow-base-node--accent-${accent}`,\n status && `ods-flow-base-node--status-${status}`,\n className,\n )}\n >\n {/* External pill — the node TYPE label, not the name. */}\n <div className=\"ods-flow-base-node__pill\">\n {kindIcon && (\n <span className=\"ods-flow-base-node__pill-icon\" aria-hidden=\"true\">\n {kindIcon}\n </span>\n )}\n <span className=\"ods-flow-base-node__pill-label\">{kind}</span>\n </div>\n\n {/* Status indicator — top-right of the card. */}\n {status && status !== \"idle\" && (\n <span\n className={cn(\"ods-flow-base-node__status\", `ods-flow-base-node__status--${status}`)}\n aria-hidden=\"true\"\n />\n )}\n\n {/* Body */}\n <div className=\"ods-flow-base-node__body\">\n <div className=\"ods-flow-base-node__content\">\n <div className=\"ods-flow-base-node__bubble\" aria-hidden=\"true\">\n {icon}\n </div>\n <div className=\"ods-flow-base-node__content-text\">\n <div className=\"ods-flow-base-node__content-title\">{title}</div>\n {(chip !== undefined || description !== undefined || valueChip !== undefined) && (\n <div className=\"ods-flow-base-node__content-info\">\n {chip !== undefined && <span className=\"ods-flow-base-node__chip\">{chip}</span>}\n {description !== undefined && (\n <span className=\"ods-flow-base-node__description\">{description}</span>\n )}\n {valueChip !== undefined && (\n <span className=\"ods-flow-base-node__value-chip\">{valueChip}</span>\n )}\n </div>\n )}\n </div>\n </div>\n\n {footer && <div className=\"ods-flow-base-node__footer\">{footer}</div>}\n\n {deleteHandler && (\n <button\n type=\"button\"\n className=\"ods-flow-base-node__delete\"\n onClick={(e) => {\n e.stopPropagation();\n deleteHandler();\n }}\n aria-label=\"Delete node\"\n data-flow-no-drag=\"true\"\n title=\"Delete node\"\n >\n <TrashCanIcon size={16} aria-hidden />\n </button>\n )}\n </div>\n\n {/* Handles + extras slot. */}\n {children}\n </div>\n );\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// Built-in node kinds — Action / Trigger / Condition / Group.\n// ════════════════════════════════════════════════════════════════════════\n// Each kind is a small functional component that composes BaseNode and\n// adds its own Handle layout. Additional kinds (Loop, Parallel, Wait,\n// Output, Error, Sticky) will land in a follow-up pass.\n\nimport type { PointerEvent } from \"react\";\nimport { useFlowNodeBridge } from \"../FlowCanvas/FlowCanvasContext\";\nimport type { NodeKindComponent, NodeKindProps, NodeKindRegistry } from \"../FlowNode/nodeKinds\";\nimport { Handle } from \"../Handle/Handle\";\nimport { NodeResizer } from \"../NodeResizer/NodeResizer\";\nimport { BaseNode, type BaseNodeStatus } from \"./BaseNode\";\n\n// Common payload shape that built-in kinds expect. Consumers can extend\n// `data` with their own fields; the renderer just reads the named slots.\nexport interface BuiltInNodeData {\n /** Pill label override — defaults to the kind's canonical type label\n * (e.g. \"HTTP\", \"WEBHOOK\", \"ACTION\"). Rarely needed; mostly here so\n * consumers can rename \"HTTP\" → \"REST\" without forking the kind. */\n kind?: import(\"react\").ReactNode;\n /** Body name — the user-facing instance label (e.g. \"Fetch Order\"). */\n title?: string;\n /**\n * Optional chip rendered before the description value, used for\n * configuration metadata that should read at a glance — HTTP method,\n * condition operator, schedule frequency, etc. Renders as a coloured\n * inline badge that inherits the kind accent.\n */\n chip?: import(\"react\").ReactNode;\n /** Description / config value — the most-relevant config field (path,\n * url, expression). Clamped to two lines in the body. */\n description?: import(\"react\").ReactNode;\n /**\n * Generic right-aligned chip slot — used when a node has a secondary\n * config value to surface (e.g. the path `/v1/orders/:id` next to an\n * HTTP `GET` method chip). Inherits the kind accent.\n */\n valueChip?: import(\"react\").ReactNode;\n /** Legacy alias for `description` — older fixtures still pass this. */\n subtitle?: import(\"react\").ReactNode;\n /** Legacy alias for `chip` — older fixtures still pass this. */\n badge?: import(\"react\").ReactNode;\n /** Runtime status — drives the pulsing dot in the top-right corner. */\n status?: BaseNodeStatus;\n /** Body bubble icon (32px circle). */\n icon?: import(\"react\").ReactNode;\n // Condition-specific:\n branches?: { id: string; label: string }[];\n // Group-specific:\n collapsed?: boolean;\n /** Populated by `collapseFor()` — number of descendants hidden under\n * this collapsed group; the renderer shows it as a \"N steps\" badge. */\n hiddenCount?: number;\n /** Dim the container's frame to signal \"the engine will skip this\n * subflow + all descendants\". Visual only — semantics enforced by\n * the consumer's execution layer. */\n disabled?: boolean;\n // ForEach-specific:\n iterator?: string;\n // Wait-specific (not yet implemented; reserved):\n waitMs?: number;\n // Webhook / HttpRequest-specific helpers — populate `chip` + `description`\n // automatically when present.\n method?: string;\n path?: string;\n url?: string;\n}\n\n// ────────────────────────────────────────────────────────────────────────\n// ActionNode — generic action; 1 input on top + 1 output on bottom.\n// ────────────────────────────────────────────────────────────────────────\nexport const ActionNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"ACTION\"}\n icon={d.icon}\n title={d.title ?? \"Action\"}\n chip={d.chip ?? d.badge}\n description={d.description ?? d.subtitle}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"green\"\n >\n <Handle type=\"target\" position=\"top\" />\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// TriggerNode — no input port; green accent matches the platform.\n// ────────────────────────────────────────────────────────────────────────\nexport const TriggerNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"TRIGGER\"}\n icon={d.icon}\n title={d.title ?? \"Trigger\"}\n chip={d.chip}\n description={d.description ?? \"Manually triggered\"}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"green\"\n >\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// ConditionNode — single input on top; multiple labelled outputs along\n// the bottom edge. Default branches: true / false.\n// ────────────────────────────────────────────────────────────────────────\nexport const ConditionNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n const branches = d.branches ?? [\n { id: \"true\", label: \"true\" },\n { id: \"false\", label: \"false\" },\n ];\n return (\n <BaseNode\n kind={d.kind ?? \"CONDITION\"}\n icon={d.icon}\n title={d.title ?? \"Condition\"}\n chip={d.chip ?? d.badge}\n description={d.description ?? d.subtitle}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"amber\"\n >\n <Handle type=\"target\" position=\"top\" />\n {branches.map((b, i) => (\n <Handle\n key={b.id}\n type=\"source\"\n position=\"bottom\"\n id={b.id}\n index={i}\n total={branches.length}\n label={b.label}\n />\n ))}\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// GroupNode — frame container for sub-flows. Children render absolutely\n// positioned (per ADR-003) on top of the frame.\n//\n// When `data.collapsed === true`:\n// - Body collapses to the header strip.\n// - Two perimeter handles are registered (`__group_in` on top,\n// `__group_out` on bottom). The `collapseFor()` helper rewrites\n// edges that cross the boundary so they terminate at these handles\n// instead of dangling at hidden children.\n// - A count badge (\"N steps\") is rendered next to the title.\n// ────────────────────────────────────────────────────────────────────────\nexport const GroupNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n const collapsed = !!d.collapsed;\n const disabled = !!d.disabled;\n // The host (or `collapseFor`) reports the descendant count via\n // `node.data.hiddenCount`. We fall back to undefined → no badge.\n const hiddenCount = (d as { hiddenCount?: number }).hiddenCount;\n const bridge = useFlowNodeBridge();\n // The chevron is a button — clicking it (and only it) toggles collapse.\n // We stop propagation so the click doesn't also bubble up to the node\n // wrapper's selection / drag-start gestures. `data-flow-no-drag` keeps\n // pointerdown from starting a node drag.\n const onChevronClick = (e: PointerEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n bridge.toggleNodeCollapse(node.id);\n };\n return (\n <div\n className=\"ods-flow-group\"\n data-collapsed={collapsed ? \"true\" : \"false\"}\n data-disabled={disabled ? \"true\" : undefined}\n style={{\n width: node.width ?? 360,\n height: collapsed ? 36 : (node.height ?? 200),\n }}\n >\n {/* Built-in corner-resize handles. Hidden when collapsed (resize\n a 36px-tall strip makes no sense). Visibility otherwise\n defaults to \"node is selected\" — driven by FlowNodeContext. */}\n {!collapsed && <NodeResizer minWidth={240} minHeight={120} />}\n\n <div className=\"ods-flow-group__header\" data-flow-no-drag=\"false\">\n <button\n type=\"button\"\n className=\"ods-flow-group__chevron\"\n data-flow-no-drag=\"true\"\n aria-label={collapsed ? \"Expand group\" : \"Collapse group\"}\n aria-expanded={!collapsed}\n onClick={onChevronClick}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {collapsed ? \"▸\" : \"▾\"}\n </button>\n <span className=\"ods-flow-group__title\">{d.title ?? \"Group\"}</span>\n {d.subtitle && <span className=\"ods-flow-group__subtitle\">{d.subtitle}</span>}\n {disabled && (\n <span className=\"ods-flow-group__disabled-badge\" aria-label=\"Disabled subflow\">\n Disabled\n </span>\n )}\n {collapsed && hiddenCount !== undefined && hiddenCount > 0 && (\n <span className=\"ods-flow-group__count\" aria-label={`${hiddenCount} hidden steps`}>\n {hiddenCount} steps\n </span>\n )}\n </div>\n\n {/* Canonical perimeter handles — 1 input on top, 1 output on\n bottom. Visible primary interaction surface (was previously\n muted on expanded mode; now they ARE the user-facing ports).\n Ids stay stable for `collapseFor()` edge rewriting. */}\n <Handle type=\"target\" position=\"top\" id=\"__group_in\" />\n <Handle type=\"source\" position=\"bottom\" id=\"__group_out\" />\n </div>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// ForEachNode — iteration step. A SIMPLE node (NOT a container), shaped\n// like ConditionNode: 1 input on top, 2 labelled outputs on the bottom:\n//\n// - \"Each\" — the loop body; the subgraph wired here runs once per item.\n// - \"Done\" — the post-iteration exit; runs after every item completes.\n//\n// Branch handle ids come from `data.branches` (the consumer's port ids,\n// e.g. `…_output_each` / `…_output_done`) so saved edges anchor exactly;\n// falls back to `each` / `done` when none are supplied. The engine\n// resolves the loop body by following edges from the `…_each` port — no\n// `parentId` nesting, so forEach is a plain node in the chain.\n// ────────────────────────────────────────────────────────────────────────\nexport const ForEachNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n const branches = d.branches ?? [\n { id: \"each\", label: \"Each\" },\n { id: \"done\", label: \"Done\" },\n ];\n return (\n <BaseNode\n kind={d.kind ?? \"FOR EACH\"}\n icon={d.icon}\n title={d.title ?? \"For each\"}\n chip={d.chip ?? d.badge}\n description={d.description ?? d.subtitle ?? d.iterator}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"amber\"\n >\n <Handle type=\"target\" position=\"top\" />\n {branches.map((b, i) => (\n <Handle\n key={b.id}\n type=\"source\"\n position=\"bottom\"\n id={b.id}\n index={i}\n total={branches.length}\n label={b.label}\n />\n ))}\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// OutputNode — terminal node; no output port. Pill reads \"OUTPUT\".\n// ────────────────────────────────────────────────────────────────────────\nexport const OutputNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"OUTPUT\"}\n icon={d.icon}\n title={d.title ?? \"Output\"}\n chip={d.chip ?? d.badge}\n description={d.description ?? d.subtitle}\n status={d.status}\n accent=\"green\"\n >\n <Handle type=\"target\" position=\"top\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// ErrorNode — failure handler; red accent.\n// ────────────────────────────────────────────────────────────────────────\nexport const ErrorNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"ERROR\"}\n icon={d.icon}\n title={d.title ?? \"On error\"}\n chip={d.chip ?? d.badge}\n description={d.description ?? d.subtitle}\n status={d.status ?? \"error\"}\n accent=\"red\"\n >\n <Handle type=\"target\" position=\"top\" />\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// WaitNode — pause execution. Chip surfaces the duration when provided.\n// ────────────────────────────────────────────────────────────────────────\nexport const WaitNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n const waitMs = (d as { waitMs?: number }).waitMs;\n const durationChip = waitMs ? `${Math.round(waitMs / 100) / 10}s` : undefined;\n return (\n <BaseNode\n kind={d.kind ?? \"WAIT\"}\n icon={d.icon}\n title={d.title ?? \"Wait\"}\n chip={d.chip ?? durationChip}\n description={d.description ?? (durationChip ? \"Pause execution\" : undefined)}\n status={d.status}\n accent=\"violet\"\n >\n <Handle type=\"target\" position=\"top\" />\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// ParallelNode — fan-out: one input, N parallel outputs.\n// ────────────────────────────────────────────────────────────────────────\nexport const ParallelNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n const branches = d.branches ?? [\n { id: \"a\", label: \"a\" },\n { id: \"b\", label: \"b\" },\n ];\n return (\n <BaseNode\n kind={d.kind ?? \"PARALLEL\"}\n icon={d.icon}\n title={d.title ?? \"Parallel\"}\n chip={d.chip ?? `${branches.length}×`}\n description={d.description ?? \"Fan-out branches\"}\n status={d.status}\n accent=\"blue\"\n >\n <Handle type=\"target\" position=\"top\" />\n {branches.map((b, i) => (\n <Handle\n key={b.id}\n type=\"source\"\n position=\"bottom\"\n id={b.id}\n index={i}\n total={branches.length}\n label={b.label}\n />\n ))}\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// StickyNode — non-executing annotation. No ports. Renders behind nodes.\n// Multi-line `data.description` is the body.\n// ────────────────────────────────────────────────────────────────────────\nexport const StickyNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <div\n className=\"ods-flow-sticky\"\n style={{\n width: node.width ?? 240,\n minHeight: node.height ?? 120,\n }}\n >\n {d.title && <div className=\"ods-flow-sticky__title\">{d.title}</div>}\n {d.description && <div className=\"ods-flow-sticky__body\">{d.description}</div>}\n </div>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// WebhookNode — specialised Trigger. Pill = \"WEBHOOK\"; chip = HTTP\n// method; description = path (the most-relevant config value).\n// ────────────────────────────────────────────────────────────────────────\nexport const WebhookNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"WEBHOOK\"}\n icon={d.icon}\n title={d.title ?? \"Webhook\"}\n chip={d.chip ?? d.method ?? \"POST\"}\n description={d.description ?? d.path ?? \"/hooks/incoming\"}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"blue\"\n >\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// HttpRequestNode — Action variant. Pill = \"HTTP\"; chip = HTTP method;\n// description = url (the most-relevant config value).\n// ────────────────────────────────────────────────────────────────────────\nexport const HttpRequestNode: NodeKindComponent<BuiltInNodeData> = ({\n node,\n}: NodeKindProps<BuiltInNodeData>) => {\n const d = node.data ?? {};\n return (\n <BaseNode\n kind={d.kind ?? \"HTTP\"}\n icon={d.icon}\n title={d.title ?? \"HTTP Request\"}\n chip={d.chip ?? d.method ?? \"GET\"}\n description={d.description ?? d.url ?? \"Call an API\"}\n valueChip={d.valueChip}\n status={d.status}\n accent=\"blue\"\n >\n <Handle type=\"target\" position=\"top\" />\n <Handle type=\"source\" position=\"bottom\" />\n </BaseNode>\n );\n};\n\n// ────────────────────────────────────────────────────────────────────────\n// Default registry — the canvas merges this with any consumer overrides.\n// ────────────────────────────────────────────────────────────────────────\nexport const DEFAULT_NODE_KINDS: NodeKindRegistry = {\n action: ActionNode as NodeKindComponent,\n trigger: TriggerNode as NodeKindComponent,\n condition: ConditionNode as NodeKindComponent,\n group: GroupNode as NodeKindComponent,\n forEach: ForEachNode as NodeKindComponent,\n output: OutputNode as NodeKindComponent,\n error: ErrorNode as NodeKindComponent,\n wait: WaitNode as NodeKindComponent,\n parallel: ParallelNode as NodeKindComponent,\n sticky: StickyNode as NodeKindComponent,\n webhook: WebhookNode as NodeKindComponent,\n httpRequest: HttpRequestNode as NodeKindComponent,\n};\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// FxPanel — the Data References catalogue that docks beside the ConfigPanel.\n// ════════════════════════════════════════════════════════════════════════\n// A searchable catalogue of expression building-blocks:\n// - Functions — flat lists (CONCAT, UPPER, …).\n// - Variables — flat lists of system/session tokens.\n// - Source Data — an n-th-level NESTED TREE of upstream-node output\n// fields. Objects + arrays-of-objects are expandable branches;\n// primitives are leaves.\n//\n// Every item is draggable into any field, click-to-insert. The component\n// is data-driven: the consumer supplies `categories`; FxPanel owns\n// search, the accordion, the tree expansion, keyboard navigation, and\n// the drag affordances.\n\nimport {\n type CSSProperties,\n type DragEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n ChevronDownIcon,\n ChevronRightIcon,\n CloseIcon,\n CollapseAllIcon,\n DraggableIcon,\n ExpandAllIcon,\n FunctionMathIcon,\n SearchIcon,\n ValueVariableIcon,\n} from \"@octaviaflow/icons\";\nimport { cn } from \"../../../utils/cn\";\n\nexport type FxItemKind = \"function\" | \"variable\";\n\n/** Data type of a Source-Data field — drives the colour-coded badge. */\nexport type FxValueType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"object\"\n | \"array\"\n | \"date\"\n | \"any\";\n\nexport interface FxPanelItem {\n /** Stable key + tree/keyboard identity. */\n id: string;\n /** Display label — a function signature, variable name, or field key. */\n label: string;\n /**\n * The string handed to `dataTransfer` / inserted into a field.\n * Branches may still set it (drag the whole object/array reference).\n */\n insertValue?: string;\n /** Short one-line description shown under the label. */\n description?: string;\n /** Data type — renders a colour-coded badge. Source-Data fields only. */\n valueType?: FxValueType;\n /**\n * Nested children. When present the item renders as an expandable\n * branch — this is what powers the n-th-level Source-Data tree.\n */\n children?: FxPanelItem[];\n}\n\nexport interface FxPanelCategory {\n /** Stable key + accordion identity. */\n id: string;\n /** Section heading. */\n label: string;\n /** Drives the badge glyph + drag payload. Defaults to \"function\". */\n kind?: FxItemKind;\n /** Items — flat for functions/variables, nested for Source Data. */\n items: FxPanelItem[];\n}\n\nexport interface FxPanelProps {\n /** Categorised entries. Empty categories are dropped from render. */\n categories: FxPanelCategory[];\n /** Header title. Default \"Data References\". */\n title?: ReactNode;\n /** Instructional line under the search. Pass `null` to hide it. */\n hint?: ReactNode;\n /** Controlled search term. */\n search?: string;\n /** Initial search term when uncontrolled. */\n defaultSearch?: string;\n onSearchChange?: (next: string) => void;\n /** Controlled open category (single-open accordion). `null` = closed. */\n expandedCategory?: string | null;\n /** Initial open category when uncontrolled. */\n defaultExpandedCategory?: string | null;\n onExpandedCategoryChange?: (id: string | null) => void;\n /** Close (✕) handler. Omit to hide the close button. */\n onClose?: () => void;\n /**\n * Fires when an item begins dragging. Use it to populate\n * `e.dataTransfer`. When omitted, FxPanel writes a sensible default:\n * - `text/plain` → insertValue\n * - `application/x-fx-insert` → insertValue\n * - `application/x-fx-type` → category kind\n */\n onItemDragStart?: (\n item: FxPanelItem,\n category: FxPanelCategory,\n e: DragEvent<HTMLElement>,\n ) => void;\n /** Fires on click / Enter of an item (insert at cursor). */\n onItemSelect?: (item: FxPanelItem, category: FxPanelCategory) => void;\n /** Panel width (px). Default 300. */\n width?: number;\n /** Message shown when a search matches nothing. Default \"No matches\". */\n emptyLabel?: ReactNode;\n /** Placeholder for the search box. */\n searchPlaceholder?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n// Category badge icon — a relatable glyph per kind (functions get the\n// math-function mark, variables/data get the value-variable mark).\nconst KIND_ICON: Record<FxItemKind, typeof FunctionMathIcon> = {\n function: FunctionMathIcon,\n variable: ValueVariableIcon,\n};\n\n// ── Tree helpers ─────────────────────────────────────────────────────────\n\n/** Recursively count leaf items (primitives — the drag end-points). */\nfunction countLeaves(items: FxPanelItem[]): number {\n let n = 0;\n for (const it of items) {\n if (it.children && it.children.length > 0) n += countLeaves(it.children);\n else n += 1;\n }\n return n;\n}\n\n/** Collect the ids of every branch (has children) under `items`. */\nfunction collectBranchIds(items: FxPanelItem[], out: Set<string>): void {\n for (const it of items) {\n if (it.children && it.children.length > 0) {\n out.add(it.id);\n collectBranchIds(it.children, out);\n }\n }\n}\n\ninterface FlatRow {\n item: FxPanelItem;\n depth: number;\n hasChildren: boolean;\n expanded: boolean;\n}\n\n/** Flatten the visible tree (respecting `expandedItems`) into draw rows. */\nfunction flattenTree(\n items: FxPanelItem[],\n depth: number,\n expandedItems: Set<string>,\n out: FlatRow[],\n): void {\n for (const it of items) {\n const hasChildren = !!it.children && it.children.length > 0;\n const expanded = hasChildren && expandedItems.has(it.id);\n out.push({ item: it, depth, hasChildren, expanded });\n if (expanded) flattenTree(it.children!, depth + 1, expandedItems, out);\n }\n}\n\ninterface SearchHit {\n item: FxPanelItem;\n /** Ancestor labels (excluding the item itself) for the path crumb. */\n ancestors: string[];\n}\n\n/** Collect leaf items whose label / description / path matches `q`. */\nfunction collectHits(\n items: FxPanelItem[],\n ancestors: string[],\n q: string,\n out: SearchHit[],\n): void {\n for (const it of items) {\n if (it.children && it.children.length > 0) {\n collectHits(it.children, [...ancestors, it.label], q, out);\n } else {\n const path = [...ancestors, it.label].join(\" / \");\n const hay =\n `${it.label} ${it.description ?? \"\"} ${path} ${it.insertValue ?? \"\"}`.toLowerCase();\n if (hay.includes(q)) out.push({ item: it, ancestors });\n }\n }\n}\n\n// ════════════════════════════════════════════════════════════════════════\n\nexport function FxPanel({\n categories,\n title = \"Data References\",\n hint = \"Drag onto a field, or click an item to insert it.\",\n search: controlledSearch,\n defaultSearch = \"\",\n onSearchChange,\n expandedCategory: controlledExpanded,\n defaultExpandedCategory,\n onExpandedCategoryChange,\n onClose,\n onItemDragStart,\n onItemSelect,\n width = 300,\n emptyLabel = \"No matches\",\n searchPlaceholder = \"Search fields, functions & variables…\",\n className,\n style,\n}: FxPanelProps) {\n // ── Search — controlled or uncontrolled ─────────────────────────────\n const [internalSearch, setInternalSearch] = useState(defaultSearch);\n const search = controlledSearch ?? internalSearch;\n const query = search.trim().toLowerCase();\n const setSearch = (next: string) => {\n if (controlledSearch === undefined) setInternalSearch(next);\n onSearchChange?.(next);\n };\n\n // Non-empty categories only — empty ones never render.\n const visibleCategories = useMemo(\n () => categories.filter((c) => c.items.length > 0),\n [categories],\n );\n\n // ── Category accordion — controlled or uncontrolled ────────────────\n const [internalCat, setInternalCat] = useState<string | null>(\n defaultExpandedCategory !== undefined\n ? defaultExpandedCategory\n : (visibleCategories[0]?.id ?? null),\n );\n const openCategoryId = controlledExpanded ?? internalCat;\n const setOpenCategory = (id: string | null) => {\n if (controlledExpanded === undefined) setInternalCat(id);\n onExpandedCategoryChange?.(id);\n };\n\n // ── Tree expansion — branch ids that are open. Defaults to every\n // depth-0 branch so the first level of each tree shows on open. ──\n const [expandedItems, setExpandedItems] = useState<Set<string>>(() => {\n const ids = new Set<string>();\n for (const cat of categories) {\n for (const item of cat.items) {\n if (item.children && item.children.length > 0) ids.add(item.id);\n }\n }\n return ids;\n });\n const toggleItem = (id: string) => {\n setExpandedItems((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n const setCategoryExpansion = (cat: FxPanelCategory, expand: boolean) => {\n const branchIds = new Set<string>();\n collectBranchIds(cat.items, branchIds);\n setExpandedItems((prev) => {\n const next = new Set(prev);\n for (const id of branchIds) {\n if (expand) next.add(id);\n else next.delete(id);\n }\n return next;\n });\n };\n\n // ── Transient UI state ──────────────────────────────────────────────\n const [draggingId, setDraggingId] = useState<string | null>(null);\n const [focusedId, setFocusedId] = useState<string | null>(null);\n\n // ── Search results ──────────────────────────────────────────────────\n const hits = useMemo(() => {\n if (!query) return null;\n const all: { category: FxPanelCategory; hit: SearchHit }[] = [];\n for (const cat of visibleCategories) {\n const out: SearchHit[] = [];\n collectHits(cat.items, [], query, out);\n for (const hit of out) all.push({ category: cat, hit });\n }\n return all;\n }, [query, visibleCategories]);\n\n // ── Drag / copy / insert ────────────────────────────────────────────\n const handleDragStart =\n (item: FxPanelItem, category: FxPanelCategory) =>\n (e: DragEvent<HTMLElement>) => {\n setDraggingId(item.id);\n if (onItemDragStart) {\n onItemDragStart(item, category, e);\n } else if (item.insertValue) {\n e.dataTransfer.setData(\"text/plain\", item.insertValue);\n e.dataTransfer.setData(\"application/x-fx-insert\", item.insertValue);\n e.dataTransfer.setData(\n \"application/x-fx-type\",\n category.kind ?? \"function\",\n );\n e.dataTransfer.effectAllowed = \"copy\";\n }\n };\n\n // ── Keyboard navigation over the open category's visible rows ───────\n const listRef = useRef<HTMLDivElement>(null);\n const focusRow = (id: string) => {\n setFocusedId(id);\n requestAnimationFrame(() => {\n listRef.current\n ?.querySelector<HTMLElement>(`[data-fx-row=\"${CSS.escape(id)}\"]`)\n ?.focus();\n });\n };\n const onRowKeyDown = (\n e: ReactKeyboardEvent<HTMLDivElement>,\n rows: FlatRow[],\n row: FlatRow,\n category: FxPanelCategory,\n ) => {\n const idx = rows.findIndex((r) => r.item.id === row.item.id);\n if (idx < 0) return;\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n if (idx < rows.length - 1) focusRow(rows[idx + 1].item.id);\n break;\n case \"ArrowUp\":\n e.preventDefault();\n if (idx > 0) focusRow(rows[idx - 1].item.id);\n break;\n case \"ArrowRight\":\n if (row.hasChildren) {\n e.preventDefault();\n if (!row.expanded) toggleItem(row.item.id);\n else if (idx < rows.length - 1) focusRow(rows[idx + 1].item.id);\n }\n break;\n case \"ArrowLeft\":\n if (row.hasChildren && row.expanded) {\n e.preventDefault();\n toggleItem(row.item.id);\n } else {\n // Walk back to the parent (first shallower row).\n for (let i = idx - 1; i >= 0; i--) {\n if (rows[i].depth < row.depth) {\n e.preventDefault();\n focusRow(rows[i].item.id);\n break;\n }\n }\n }\n break;\n case \"Home\":\n e.preventDefault();\n if (rows.length) focusRow(rows[0].item.id);\n break;\n case \"End\":\n e.preventDefault();\n if (rows.length) focusRow(rows[rows.length - 1].item.id);\n break;\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (row.hasChildren) toggleItem(row.item.id);\n else onItemSelect?.(row.item, category);\n break;\n default:\n break;\n }\n };\n\n // Flat draw-rows for the active search results — drives keyboard nav.\n const searchRows = useMemo<FlatRow[]>(\n () =>\n hits\n ? hits.map(({ hit }) => ({\n item: hit.item,\n depth: 0,\n hasChildren: false,\n expanded: false,\n }))\n : [],\n [hits],\n );\n\n // ── Row renderer ────────────────────────────────────────────────────\n const renderRow = (\n row: FlatRow,\n category: FxPanelCategory,\n rows: FlatRow[],\n crumb?: string,\n ) => {\n const { item, depth, hasChildren, expanded } = row;\n const mono = category.kind === \"function\";\n const draggable = !!item.insertValue;\n const isFocused = focusedId === item.id;\n return (\n <div\n key={item.id}\n data-fx-row={item.id}\n className={cn(\n \"ods-flow-fx-panel__row\",\n hasChildren\n ? \"ods-flow-fx-panel__row--branch\"\n : \"ods-flow-fx-panel__row--leaf\",\n draggingId === item.id && \"ods-flow-fx-panel__row--dragging\",\n isFocused && \"ods-flow-fx-panel__row--focused\",\n )}\n role=\"treeitem\"\n aria-expanded={hasChildren ? expanded : undefined}\n aria-level={depth + 1}\n tabIndex={\n isFocused || (focusedId === null && rows[0]?.item.id === item.id)\n ? 0\n : -1\n }\n draggable={draggable}\n onDragStart={draggable ? handleDragStart(item, category) : undefined}\n onDragEnd={() => setDraggingId(null)}\n onFocus={() => setFocusedId(item.id)}\n onKeyDown={(e) => onRowKeyDown(e, rows, row, category)}\n onClick={() => {\n if (hasChildren) toggleItem(item.id);\n else onItemSelect?.(item, category);\n }}\n title={item.insertValue}\n >\n {/* Indent guides — one per ancestor depth. */}\n {Array.from({ length: depth }, (_, i) => (\n <span key={i} className=\"ods-flow-fx-panel__indent\" aria-hidden=\"true\" />\n ))}\n\n {/* Twisty (branches) or drag handle (leaves). */}\n {hasChildren ? (\n <span className=\"ods-flow-fx-panel__twisty\" aria-hidden=\"true\">\n {expanded ? (\n <ChevronDownIcon size=\"sm\" />\n ) : (\n <ChevronRightIcon size=\"sm\" />\n )}\n </span>\n ) : (\n <span className=\"ods-flow-fx-panel__grip\" aria-hidden=\"true\">\n <DraggableIcon size=\"sm\" />\n </span>\n )}\n\n <span className=\"ods-flow-fx-panel__row-main\">\n <span className=\"ods-flow-fx-panel__row-line\">\n {mono ? (\n <code className=\"ods-flow-fx-panel__row-label ods-flow-fx-panel__row-label--mono\">\n {item.label}\n </code>\n ) : (\n <span className=\"ods-flow-fx-panel__row-label\">{item.label}</span>\n )}\n {item.valueType && (\n <span\n className={cn(\n \"ods-flow-fx-panel__type\",\n `ods-flow-fx-panel__type--${item.valueType}`,\n )}\n >\n {item.valueType}\n </span>\n )}\n </span>\n {(item.description || crumb) && (\n <span className=\"ods-flow-fx-panel__row-sub\">\n {crumb && (\n <span className=\"ods-flow-fx-panel__crumb\">{crumb}</span>\n )}\n {item.description}\n </span>\n )}\n </span>\n </div>\n );\n };\n\n // ── Render ──────────────────────────────────────────────────────────\n return (\n <aside\n className={cn(\"ods-flow-fx-panel\", className)}\n style={{ width, ...style }}\n aria-label={typeof title === \"string\" ? title : \"Data References\"}\n >\n <header className=\"ods-flow-fx-panel__header\">\n <h3 className=\"ods-flow-fx-panel__title\">{title}</h3>\n {onClose && (\n <button\n type=\"button\"\n className=\"ods-flow-fx-panel__close\"\n onClick={onClose}\n aria-label=\"Close data references\"\n >\n <CloseIcon size=\"sm\" />\n </button>\n )}\n </header>\n\n <div className=\"ods-flow-fx-panel__search\">\n <span className=\"ods-flow-fx-panel__search-icon\" aria-hidden=\"true\">\n <SearchIcon size=\"sm\" />\n </span>\n <input\n type=\"text\"\n className=\"ods-flow-fx-panel__search-input\"\n placeholder={searchPlaceholder}\n aria-label=\"Search fields, functions and variables\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n {search && (\n <button\n type=\"button\"\n className=\"ods-flow-fx-panel__search-clear\"\n onClick={() => setSearch(\"\")}\n aria-label=\"Clear search\"\n >\n <CloseIcon size=\"sm\" />\n </button>\n )}\n </div>\n\n {hint && !query && <p className=\"ods-flow-fx-panel__hint\">{hint}</p>}\n\n <div className=\"ods-flow-fx-panel__list\" ref={listRef} role=\"tree\">\n {/* ── Search mode — flat, path-crumbed leaf matches. ── */}\n {query &&\n hits &&\n (hits.length > 0 ? (\n <div className=\"ods-flow-fx-panel__results\">\n <div className=\"ods-flow-fx-panel__results-count\">\n {hits.length} {hits.length === 1 ? \"match\" : \"matches\"}\n </div>\n {hits.map(({ category, hit }, i) =>\n renderRow(\n searchRows[i],\n category,\n searchRows,\n hit.ancestors.length\n ? hit.ancestors.join(\" / \")\n : category.label,\n ),\n )}\n </div>\n ) : (\n <div className=\"ods-flow-fx-panel__empty\">{emptyLabel}</div>\n ))}\n\n {/* ── Browse mode — category accordion + per-branch tree. ── */}\n {!query &&\n visibleCategories.map((cat) => {\n const isOpen = openCategoryId === cat.id;\n const kind = cat.kind ?? \"function\";\n const KindIcon = KIND_ICON[kind];\n const branchIds = new Set<string>();\n collectBranchIds(cat.items, branchIds);\n const hasTree = branchIds.size > 0;\n const rows: FlatRow[] = [];\n if (isOpen) flattenTree(cat.items, 0, expandedItems, rows);\n const allExpanded =\n hasTree &&\n [...branchIds].every((id) => expandedItems.has(id));\n\n return (\n <div className=\"ods-flow-fx-panel__category\" key={cat.id}>\n <div\n className={cn(\n \"ods-flow-fx-panel__cat-header\",\n isOpen && \"ods-flow-fx-panel__cat-header--open\",\n )}\n >\n <button\n type=\"button\"\n className=\"ods-flow-fx-panel__cat-toggle\"\n aria-expanded={isOpen}\n onClick={() => setOpenCategory(isOpen ? null : cat.id)}\n >\n <ChevronRightIcon\n size=\"sm\"\n className={cn(\n \"ods-flow-fx-panel__chevron\",\n isOpen && \"ods-flow-fx-panel__chevron--open\",\n )}\n />\n <span\n className={cn(\n \"ods-flow-fx-panel__badge\",\n `ods-flow-fx-panel__badge--${kind}`,\n )}\n >\n <KindIcon\n size=\"sm\"\n className=\"ods-flow-fx-panel__badge-icon\"\n />\n {cat.label}\n </span>\n <span className=\"ods-flow-fx-panel__count\">\n {countLeaves(cat.items)}\n </span>\n </button>\n {/* Expand / collapse the whole tree of this category. */}\n {isOpen && hasTree && (\n <button\n type=\"button\"\n className=\"ods-flow-fx-panel__cat-action\"\n aria-label={\n allExpanded ? \"Collapse all\" : \"Expand all\"\n }\n title={allExpanded ? \"Collapse all\" : \"Expand all\"}\n onClick={() => setCategoryExpansion(cat, !allExpanded)}\n >\n {allExpanded ? (\n <CollapseAllIcon size=\"sm\" />\n ) : (\n <ExpandAllIcon size=\"sm\" />\n )}\n </button>\n )}\n </div>\n\n {isOpen && (\n <div\n className=\"ods-flow-fx-panel__rows\"\n role=\"group\"\n aria-label={cat.label}\n >\n {rows.map((row) => renderRow(row, cat, rows))}\n </div>\n )}\n </div>\n );\n })}\n </div>\n </aside>\n );\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// DataRefButton — the trigger that opens/closes the FxPanel.\n// ════════════════════════════════════════════════════════════════════════\n// A compact toggle in the ConfigPanel header's modular action slot. It\n// carries the data-reference icon + label and reflects the panel's open\n// state through `aria-pressed` + an `--active` visual.\n\nimport { type ButtonHTMLAttributes, type ReactNode } from \"react\";\nimport { DataReferenceIcon } from \"@octaviaflow/icons\";\nimport { cn } from \"../../../utils/cn\";\n\nexport interface DataRefButtonProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n /** Whether the FxPanel is currently open. Drives `aria-pressed`. */\n active?: boolean;\n /** Visible label beside the icon. Default \"Data ref\". `null` = icon-only. */\n label?: ReactNode;\n}\n\nexport function DataRefButton({\n active = false,\n label = \"Data ref\",\n className,\n type = \"button\",\n ...rest\n}: DataRefButtonProps) {\n return (\n <button\n {...rest}\n type={type}\n className={cn(\n \"ods-flow-dataref-button\",\n active && \"ods-flow-dataref-button--active\",\n label == null && \"ods-flow-dataref-button--icon-only\",\n className,\n )}\n aria-pressed={active}\n title={active ? \"Hide data references\" : \"Show data references\"}\n >\n <DataReferenceIcon\n size=\"sm\"\n className=\"ods-flow-dataref-button__icon\"\n />\n {label != null && (\n <span className=\"ods-flow-dataref-button__label\">{label}</span>\n )}\n </button>\n );\n}\n","\"use client\";\n\n// ════════════════════════════════════════════════════════════════════════\n// NodeToolbar — floating action bar attached to a node.\n// ════════════════════════════════════════════════════════════════════════\n// Dropped inside a custom node renderer (or anywhere with a\n// `FlowNodeContext`). Visible by default only when the host node is\n// selected; consumers can force it on with `isVisible`. Position-stable\n// across zoom — the bar applies `scale(1 / zoom)` to counter the viewport\n// transform so the buttons stay at constant pixel size.\n//\n// Pointer events on the toolbar are isolated from the node's drag /\n// connection gestures via `data-flow-no-drag=\"true\"` on the wrapper.\n\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport type { HandlePosition } from \"../../editor\";\nimport { useViewport } from \"../../store/selectors\";\nimport { useFlowNodeContext } from \"../FlowNode/FlowNodeContext\";\n\nexport interface NodeToolbarProps {\n /** Force-visible state. Defaults to `undefined` → auto (visible iff\n * the host node is selected). Pass `true`/`false` to override. */\n isVisible?: boolean;\n /** Where the toolbar sits relative to the node. Defaults to `top`. */\n position?: HandlePosition;\n /** Pixel offset from the node's edge. Default 10. */\n offset?: number;\n /** Horizontal/vertical alignment along the chosen edge. Default center. */\n align?: \"start\" | \"center\" | \"end\";\n /** Toolbar contents (typically a row of `<button>` elements). */\n children: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function NodeToolbar({\n isVisible,\n position = \"top\",\n offset = 10,\n align = \"center\",\n children,\n className,\n style,\n}: NodeToolbarProps) {\n const node = useFlowNodeContext();\n const viewport = useViewport();\n const show = isVisible ?? node.selected;\n if (!show) return null;\n\n // Counter the canvas's `scale(zoom)` so the toolbar reads at constant\n // pixel size at any zoom level. Translation is in flow-space units; the\n // inverse-scale wraps the visible content so children also stay crisp.\n const inverseScale = 1 / viewport.zoom;\n\n return (\n <div\n className={cn(\"ods-node-toolbar\", `ods-node-toolbar--${position}`, className)}\n data-flow-no-drag=\"true\"\n style={{\n ...positionStyle(position, offset, align),\n ...style,\n }}\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Inner element absorbs the inverse zoom so the toolbar's\n children stay screen-stable. */}\n <div\n className=\"ods-node-toolbar__inner\"\n style={{\n transform: `scale(${inverseScale})`,\n transformOrigin: transformOriginFor(position, align),\n }}\n >\n {children}\n </div>\n </div>\n );\n}\n\nfunction positionStyle(\n side: HandlePosition,\n offset: number,\n align: NodeToolbarProps[\"align\"],\n): CSSProperties {\n const center = align === \"center\";\n const start = align === \"start\";\n switch (side) {\n case \"top\":\n return {\n position: \"absolute\",\n bottom: \"100%\",\n marginBottom: offset,\n left: start ? 0 : center ? \"50%\" : undefined,\n right: align === \"end\" ? 0 : undefined,\n transform: center ? \"translateX(-50%)\" : undefined,\n };\n case \"bottom\":\n return {\n position: \"absolute\",\n top: \"100%\",\n marginTop: offset,\n left: start ? 0 : center ? \"50%\" : undefined,\n right: align === \"end\" ? 0 : undefined,\n transform: center ? \"translateX(-50%)\" : undefined,\n };\n case \"left\":\n return {\n position: \"absolute\",\n right: \"100%\",\n marginRight: offset,\n top: start ? 0 : center ? \"50%\" : undefined,\n bottom: align === \"end\" ? 0 : undefined,\n transform: center ? \"translateY(-50%)\" : undefined,\n };\n case \"right\":\n return {\n position: \"absolute\",\n left: \"100%\",\n marginLeft: offset,\n top: start ? 0 : center ? \"50%\" : undefined,\n bottom: align === \"end\" ? 0 : undefined,\n transform: center ? \"translateY(-50%)\" : undefined,\n };\n }\n}\n\nfunction transformOriginFor(side: HandlePosition, align: NodeToolbarProps[\"align\"]): string {\n // Choose an origin that visually attaches the bar to the node edge,\n // even after inverse-scaling. Defaults match the `position*` styles.\n if (side === \"top\")\n return align === \"start\" ? \"left bottom\" : align === \"end\" ? \"right bottom\" : \"center bottom\";\n if (side === \"bottom\")\n return align === \"start\" ? \"left top\" : align === \"end\" ? \"right top\" : \"center top\";\n if (side === \"left\")\n return align === \"start\" ? \"right top\" : align === \"end\" ? \"right bottom\" : \"right center\";\n return align === \"start\" ? \"left top\" : align === \"end\" ? \"left bottom\" : \"left center\";\n}\n","// ════════════════════════════════════════════════════════════════════════\n// Collapse helpers — when a group's `data.collapsed === true`, hide its\n// descendants AND re-route any edges that crossed the collapse boundary\n// so they terminate at the group instead of dangling at a hidden child.\n// ════════════════════════════════════════════════════════════════════════\n//\n// Consumers feed `nodes` + `edges` (their canonical state) through\n// `collapseFor()` and pass the result to <FlowCanvas>. The helpers are\n// pure — no React state, no DOM. They run in O(N + E) so they're cheap\n// to call on every render.\n\nimport type { WorkflowEdge, WorkflowNode } from \"../editor\";\n\ninterface CollapseResult {\n nodes: WorkflowNode[];\n edges: WorkflowEdge[];\n /** Per-collapsed-group: how many descendants got hidden. The host UI\n * reads this to render a \"N steps\" badge. */\n hiddenCountByGroupId: Map<string, number>;\n}\n\n/**\n * Given the canonical graph, return a derived graph that respects the\n * `collapsed` flag on every group node:\n *\n * - Descendants of a collapsed group are marked `hidden`.\n * - Edges that crossed the collapse boundary are rewritten: their\n * source (or target) becomes the collapsed group's id, and the\n * handle is reset to a synthetic perimeter handle (`__group_out` /\n * `__group_in`). Internal-to-internal edges are dropped.\n */\nexport function collapseFor(nodes: WorkflowNode[], edges: WorkflowEdge[]): CollapseResult {\n // Map child → topmost collapsed ancestor (if any).\n // If a node has multiple collapsed ancestors, the OUTERMOST wins so the\n // edge terminates at the visible boundary.\n const collapsedAncestorOf = new Map<string, string>();\n const parents = new Map<string, string>();\n for (const n of nodes) if (n.parentId) parents.set(n.id, n.parentId);\n\n // ANY node with `data.collapsed === true` collapses its descendants —\n // not just `group`. This lets `forEach` (and consumer-defined container\n // kinds) opt into the same collapse model without each one being\n // hard-coded in this helper.\n const isCollapsed = (node: WorkflowNode | undefined): boolean => {\n const d = node?.data as { collapsed?: boolean } | undefined;\n return !!d?.collapsed;\n };\n\n for (const n of nodes) {\n let cursor: string | undefined = n.id;\n let outermostCollapsed: string | undefined;\n const seen = new Set<string>([cursor]);\n while (cursor) {\n const p = parents.get(cursor);\n if (!p || seen.has(p)) break;\n seen.add(p);\n const parentNode = nodes.find((x) => x.id === p);\n if (isCollapsed(parentNode)) outermostCollapsed = p;\n cursor = p;\n }\n if (outermostCollapsed && outermostCollapsed !== n.id) {\n collapsedAncestorOf.set(n.id, outermostCollapsed);\n }\n }\n\n // Hide every descendant of a collapsed group.\n const outNodes: WorkflowNode[] = nodes.map((n) => {\n const anc = collapsedAncestorOf.get(n.id);\n if (anc) return { ...n, hidden: true };\n return n;\n });\n\n // Rewrite edges: any endpoint that sits inside a collapsed group gets\n // hoisted to the group itself. Edges entirely within a collapsed group\n // are dropped. Edges that start at the group and end inside it (or\n // vice versa) become self-loops that we also drop.\n //\n // **Boundary marker** — edges that get rewritten to terminate at a\n // collapsed group's perimeter are stroked with a sparse dot pattern so\n // the user immediately sees they're a \"summary\" of one or more hidden\n // inner connections rather than a real handle-to-handle edge. The\n // original `edge.style` is preserved; only `strokeDasharray` is\n // overlaid. FlowEdge gives `edge.style.strokeDasharray` precedence\n // over the type's default dash.\n const BOUNDARY_DASH = \"2 4\";\n const outEdges: WorkflowEdge[] = [];\n const hiddenCount = new Map<string, number>();\n for (const e of edges) {\n const srcAnc = collapsedAncestorOf.get(e.source);\n const tgtAnc = collapsedAncestorOf.get(e.target);\n if (srcAnc && tgtAnc && srcAnc === tgtAnc) continue; // wholly inside one collapsed group — drop\n let src = e.source;\n let srcHandle = e.sourceHandle;\n let tgt = e.target;\n let tgtHandle = e.targetHandle;\n const rewritten = !!(srcAnc || tgtAnc);\n if (srcAnc) {\n src = srcAnc;\n // Synthetic perimeter handle — the GroupNode renderer registers\n // matching `__group_out` / `__group_in` handles when collapsed.\n srcHandle = \"__group_out\";\n }\n if (tgtAnc) {\n tgt = tgtAnc;\n tgtHandle = \"__group_in\";\n }\n if (src === tgt) continue; // collapsed self-loop\n const nextEdge: WorkflowEdge = {\n ...e,\n source: src,\n sourceHandle: srcHandle,\n target: tgt,\n targetHandle: tgtHandle,\n };\n if (rewritten) {\n nextEdge.style = { ...(e.style ?? {}), strokeDasharray: BOUNDARY_DASH };\n }\n outEdges.push(nextEdge);\n }\n\n // Count hidden descendants per collapsed group for the badge.\n for (const [_id, anc] of collapsedAncestorOf) {\n hiddenCount.set(anc, (hiddenCount.get(anc) ?? 0) + 1);\n }\n\n return { nodes: outNodes, edges: outEdges, hiddenCountByGroupId: hiddenCount };\n}\n\n/**\n * Toggle the `data.collapsed` flag on a group node. Returns the patched\n * nodes array (immutable). Useful in event handlers.\n */\nexport function toggleGroupCollapse(groupId: string, nodes: WorkflowNode[]): WorkflowNode[] {\n return nodes.map((n) => {\n if (n.id !== groupId) return n;\n const data = (n.data ?? {}) as { collapsed?: boolean } & Record<string, unknown>;\n return { ...n, data: { ...data, collapsed: !data.collapsed } };\n });\n}\n"],"mappings":"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","names":["bezierPath","change","import_react","import_react","distance","import_react","import_react","import_react","import_icons","import_react","import_react","import_jsx_runtime","Accordion","import_react","import_react","Slot","import_jsx_runtime","Badge","import_framer_motion","import_react","import_jsx_runtime","Banner","import_framer_motion","import_react","import_react","import_jsx_runtime","Button","import_icons","import_react","import_jsx_runtime","CodeEditor","import_icons","import_react","import_jsx_runtime","import_icons","import_react","import_jsx_runtime","import_icons","import_react","import_jsx_runtime","import_icons","import_react","import_icons","import_react","import_jsx_runtime","InlineMessage","import_jsx_runtime","JsonViewer","import_icons","import_react","import_react_aria","$1CcWn$react","$1CcWn$useState","$1CcWn$useRef","$1CcWn$useEffect","$1CcWn$useReducer","$1CcWn$useCallback","value","$8AuPP$createContext","$8AuPP$useMemo","$8AuPP$useContext","name","$8AuPP$useState","$8AuPP$useRef","$8AuPP$useEffect","value","a","a","$7w3VE$useRef","$7w3VE$useState","$7w3VE$useMemo","$7w3VE$useEffect","$jO8i1$react","items","node","$emYU7$useMemo","$3yt54$useMemo","$3yt54$useCallback","$3yt54$useRef","$3yt54$useEffect","$kE40A$useCallback","$dJmKC$react","$jhfZc$useMemo","$5t5rb$useState","$5t5rb$useMemo","value","focusStrategy","$eOo4G$useRef","$eOo4G$useEffect","$dAajM$useState","$auOuY$useMemo","$auOuY$useRef","$auOuY$useEffect","import_jsx_runtime","Checkbox","import_jsx_runtime","import_react","import_icons","import_jsx_runtime","NumberInput","import_react","import_icons","import_react","import_jsx_runtime","PasswordInput","import_framer_motion","import_react","import_jsx_runtime","import_framer_motion","import_react","import_react_aria","import_react_dom","import_icons","import_framer_motion","import_react","import_react_aria","import_react_dom","import_jsx_runtime","import_jsx_runtime","Select","import_react","import_jsx_runtime","Spinner","import_react","import_react_aria","import_jsx_runtime","Switch","import_framer_motion","import_react","import_react_aria","import_jsx_runtime","h","f","import_jsx_runtime","import_react","import_react","bezierPath","distance","import_react","import_jsx_runtime","offsetAlongSide","import_react","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_icons","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","DEFAULT_VIEWPORT","c","width","height","nodes","edges","curW","curH","EdgesLayer","import_react","import_icons","import_jsx_runtime","import_icons","import_jsx_runtime","import_jsx_runtime"]}
|