@signalsafe/tree-spec-editor-react 0.1.3 → 0.2.0

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.
Files changed (34) hide show
  1. package/README.md +14 -6
  2. package/dist/TreeSpecGraphEditor.d.ts +2 -2
  3. package/dist/TreeSpecGraphEditor.d.ts.map +1 -1
  4. package/dist/TreeSpecGraphEditor.js +2 -1
  5. package/dist/canvas/constants.d.ts +8 -7
  6. package/dist/canvas/constants.d.ts.map +1 -1
  7. package/dist/canvas/constants.js +10 -7
  8. package/dist/contextMenu/GraphCanvasContextMenu.d.ts.map +1 -1
  9. package/dist/contextMenu/GraphCanvasContextMenu.js +2 -2
  10. package/dist/hooks/useCanvasContextMenu.d.ts.map +1 -1
  11. package/dist/hooks/useEditorAdapter.d.ts.map +1 -1
  12. package/dist/hooks/useEditorAutosave.d.ts.map +1 -1
  13. package/dist/hooks/useTreeSpecEditor.d.ts.map +1 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/nodes/ChoiceCanvasRow.d.ts.map +1 -1
  16. package/dist/nodes/ChoiceCanvasRow.js +4 -4
  17. package/dist/nodes/EndNode.d.ts.map +1 -1
  18. package/dist/nodes/EndNode.js +3 -3
  19. package/dist/nodes/PromptNode.d.ts.map +1 -1
  20. package/dist/nodes/PromptNode.js +3 -3
  21. package/dist/nodes/PromptNodeChoicesList.d.ts.map +1 -1
  22. package/dist/nodes/PromptNodeChoicesList.js +2 -2
  23. package/dist/nodes/PromptNodeHeader.d.ts.map +1 -1
  24. package/dist/nodes/PromptNodeHeader.js +2 -1
  25. package/dist/nodes/PromptNodeIssueBadges.d.ts.map +1 -1
  26. package/dist/nodes/PromptNodeIssueBadges.js +2 -1
  27. package/dist/nodes/PromptNodeToolbar.d.ts.map +1 -1
  28. package/dist/nodes/PromptNodeToolbar.js +2 -1
  29. package/dist/ui/editorClasses.d.ts +53 -0
  30. package/dist/ui/editorClasses.d.ts.map +1 -0
  31. package/dist/ui/editorClasses.js +69 -0
  32. package/docs/UI_KIT_AGNOSTIC_CANVAS.md +65 -0
  33. package/package.json +11 -8
  34. package/README.standalone.md +0 -14
package/README.md CHANGED
@@ -6,7 +6,13 @@ Headless **React + React Flow** layer for the SignalSafe TreeSpec graph editor:
6
6
  |---|---|
7
7
  | **npm** | `@signalsafe/tree-spec-editor-react` |
8
8
  | **GitHub** | [SignalSafeSoftware/tree-spec-editor-react](https://github.com/SignalSafeSoftware/tree-spec-editor-react) |
9
- | **Peer deps** | `react`, `react-dom`, `reactflow` (^18 / ^11) |
9
+ | **Peer deps** | `react`, `react-dom`, `reactflow` (^18 / ^11) — **no UI library required** |
10
+
11
+ ## UI-kit agnostic canvas
12
+
13
+ The React Flow canvas uses **semantic HTML** and **`graph-editor-*` class hooks** only. It does **not** require Bootstrap CSS, Bootstrap Icons, or any component library.
14
+
15
+ **Host applications own styling.** Map `graph-editor-*` in your theme, or pass `className` on `TreeSpecGraphEditor` for layout/sizing. See [docs/UI_KIT_AGNOSTIC_CANVAS.md](./docs/UI_KIT_AGNOSTIC_CANVAS.md).
10
16
 
11
17
  ## What this package does
12
18
 
@@ -16,7 +22,7 @@ Headless **React + React Flow** layer for the SignalSafe TreeSpec graph editor:
16
22
 
17
23
  ## What this package does not do
18
24
 
19
- - Sidebar panels, modals, toolbars, or Bootstrap chrome — use `@signalsafe/tree-spec-editor` or your own UI shell.
25
+ - Sidebar panels, modals, toolbars, or UI-kit chrome — use `@signalsafe/tree-spec-editor` or your own UI shell.
20
26
  - Routing, HTTP, authentication, or persistence — host app provides adapter implementations.
21
27
  - Wire compile/publish to a backend without your adapter code.
22
28
 
@@ -36,7 +42,7 @@ Ensure your app loads React Flow styles, for example:
36
42
  import "reactflow/dist/style.css";
37
43
  ```
38
44
 
39
- If you use `@signalsafe/tree-spec-editor` (Bootstrap shell), the canvas still comes from this package consumers may need the CSS import in the app entry when tree-shaking.
45
+ If you use `@signalsafe/tree-spec-editor` as the authoring shell, map `graph-editor-*` canvas hooks in host CSS Bootstrap is optional and host-owned.
40
46
 
41
47
  ## Quick start
42
48
 
@@ -76,7 +82,7 @@ export function ExampleCanvas() {
76
82
  <TreeSpecGraphEditor
77
83
  tree={tree}
78
84
  onChange={setTree}
79
- className="h-[60vh] border rounded"
85
+ className="graph-editor-canvas-root my-canvas-host"
80
86
  />
81
87
  );
82
88
  }
@@ -102,7 +108,7 @@ Import from `@signalsafe/tree-spec-editor-react` only (no subpath exports).
102
108
  | Wire | `@signalsafe/tree-spec` |
103
109
  | Editor model | `@signalsafe/tree-spec-editor-core` |
104
110
  | **React canvas (this package)** | `@signalsafe/tree-spec-editor-react` |
105
- | Bootstrap shell | `@signalsafe/tree-spec-editor` |
111
+ | Authoring shell | `@signalsafe/tree-spec-editor` |
106
112
 
107
113
  ## Canvas selection behavior
108
114
 
@@ -116,6 +122,8 @@ Pass `contextualZoom={false}` to disable automatic viewport fitting.
116
122
 
117
123
  ## Development
118
124
 
125
+ Requires Node.js **>=22.12.0** (`engines.node`). CI runs checks, tests, and smoke on Node **22** and **24**; publish uses Node **24**.
126
+
119
127
  `yarn build` uses `tsconfig.build.json` and resolves `@signalsafe/*` from `node_modules`. Ecosystem sibling `paths` in `tsconfig.json` apply to local typecheck/tests only.
120
128
 
121
129
  ```bash
@@ -137,4 +145,4 @@ See [SECURITY.md](./SECURITY.md). Host applications must authenticate users, aut
137
145
  ## Related packages
138
146
 
139
147
  - [`@signalsafe/tree-spec-editor-core`](https://github.com/SignalSafeSoftware/tree-spec-editor-core) — framework-agnostic editor helpers.
140
- - [`@signalsafe/tree-spec-editor`](https://github.com/SignalSafeSoftware/tree-spec-editor) — full Bootstrap UI shell.
148
+ - [`@signalsafe/tree-spec-editor`](https://github.com/SignalSafeSoftware/tree-spec-editor) — UI-kit agnostic authoring shell (panels, modals, toolbar).
@@ -15,7 +15,7 @@ export type TreeSpecGraphEditorProps = {
15
15
  /** Focused choice on the currently selected node (canvas + inspector sync). */
16
16
  focusChoiceId?: string | null;
17
17
  fitViewNonce?: number;
18
- /** Optional class for the outer container (default includes h-70vh border rounded). */
18
+ /** Optional class for the outer container (default: `graph-editor-canvas-root`). */
19
19
  className?: string;
20
20
  /** When true, disables canvas editing affordances (toolbar, resize, context menu). */
21
21
  readOnly?: boolean;
@@ -30,7 +30,7 @@ export type TreeSpecGraphEditorProps = {
30
30
  * Skipped when `focusNodeId` already targets the same node.
31
31
  */
32
32
  contextualZoom?: boolean;
33
- /** Canvas chrome mode — host should pass Bootstrap `colorScheme` (`light` / `dark`). */
33
+ /** Canvas chrome mode — host theme hint (`light` / `dark`). */
34
34
  colorMode?: 'light' | 'dark';
35
35
  };
36
36
  export default function TreeSpecGraphEditor(props: Readonly<TreeSpecGraphEditorProps>): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"TreeSpecGraphEditor.d.ts","sourceRoot":"","sources":["../src/TreeSpecGraphEditor.tsx"],"names":[],"mappings":"AAYA,OAAO,0BAA0B,CAAC;AAElC,OAAO,EAKH,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACxB,MAAM,mCAAmC,CAAC;AAsB3C,MAAM,MAAM,wBAAwB,GAAG;IACnC,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,gGAAgG;IAChG,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,oFAAoF;IACpF,kBAAkB,CAAC,EAAE,CACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,KACd,IAAI,CAAC;IACV,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,oEAAoE;IACpE,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAChC,CAAC;AA4PF,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,wBAAwB,CAAC,+BAMpF"}
1
+ {"version":3,"file":"TreeSpecGraphEditor.d.ts","sourceRoot":"","sources":["../src/TreeSpecGraphEditor.tsx"],"names":[],"mappings":"AAYA,OAAO,0BAA0B,CAAC;AAElC,OAAO,EAKH,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACxB,MAAM,mCAAmC,CAAC;AAuB3C,MAAM,MAAM,wBAAwB,GAAG;IACnC,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,gGAAgG;IAChG,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,oFAAoF;IACpF,kBAAkB,CAAC,EAAE,CACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,KACd,IAAI,CAAC;IACV,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,oEAAoE;IACpE,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAChC,CAAC;AA4PF,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,wBAAwB,CAAC,+BAMpF"}
@@ -6,6 +6,7 @@ import { GRAPH_SELECTION_KIND, choiceIdFromHandle, resolveGraphViewport, LAYOUT_
6
6
  import { GraphEditorCanvasContext, } from './GraphEditorCanvasContext.js';
7
7
  import { buildEdgeMarker, getIssueEdgeStyle, resolveSelectedEdgeStroke } from './canvas/edgeStyle.js';
8
8
  import { CANVAS_CLASS } from './canvas/constants.js';
9
+ import { EDITOR_CANVAS_ROOT } from './ui/editorClasses.js';
9
10
  import { resolveCanvasFocusChoiceId } from './canvas/focusChoice.js';
10
11
  import { isChoiceRowClickTarget } from './canvas/typeGuards.js';
11
12
  import { GraphCanvasContextMenu } from './contextMenu/GraphCanvasContextMenu.js';
@@ -19,7 +20,7 @@ import { useCanvasNodeResize } from './hooks/useCanvasNodeResize.js';
19
20
  import { useCanvasViewport } from './hooks/useCanvasViewport.js';
20
21
  import { useChoiceDragDrop } from './hooks/useChoiceDragDrop.js';
21
22
  import { useGraphConnect } from './hooks/useGraphConnect.js';
22
- function TreeSpecGraphInner({ tree, onChange, issues = [], selected, onSelect, onChoiceSelect, onRepositionChoice, focusNodeId, focusChoiceId = null, showMiniMap = true, fitViewNonce, className = 'h-70vh border rounded', readOnly = false, onDuplicateNode, onDeleteNode, onAutoLayout, contextualZoom = true, colorMode = 'light', }) {
23
+ function TreeSpecGraphInner({ tree, onChange, issues = [], selected, onSelect, onChoiceSelect, onRepositionChoice, focusNodeId, focusChoiceId = null, showMiniMap = true, fitViewNonce, className = EDITOR_CANVAS_ROOT, readOnly = false, onDuplicateNode, onDeleteNode, onAutoLayout, contextualZoom = true, colorMode = 'light', }) {
23
24
  const rf = useReactFlow();
24
25
  const treeRef = useRef(tree);
25
26
  treeRef.current = tree;
@@ -1,6 +1,6 @@
1
1
  import { MarkerType } from 'reactflow';
2
2
  /** Background highlight when the node matches editor selection (sidebar / issues / canvas). */
3
- export declare const CANVAS_NODE_SELECTED_CLASS = "bg-primary-subtle";
3
+ export declare const CANVAS_NODE_SELECTED_CLASS = "graph-editor-canvas__selected";
4
4
  /** Dark readable text on selected canvas node cards. */
5
5
  export declare const CANVAS_NODE_SELECTED_TEXT_CLASS = "graph-editor-canvas-selected";
6
6
  export declare const CANVAS_CLASS = "graph-editor-canvas";
@@ -18,13 +18,14 @@ export declare const CHOICE_ROW_SELECTABLE_CLASS = "graph-editor-choice-row-sele
18
18
  export declare const CHOICE_HANDLE_CLASS = "graph-editor-handle graph-editor-choice-handle";
19
19
  export declare const NODE_DRAG_HANDLE_CLASS = "graph-editor-drag-handle";
20
20
  export declare const NODE_DRAG_HANDLE_SELECTOR = ".graph-editor-drag-handle";
21
- export declare const TARGET_HANDLE_CLASS_DEFAULT = "handle-bg-default graph-editor-target-handle";
22
- export declare const TARGET_HANDLE_CLASS_DANGER = "handle-bg-danger graph-editor-target-handle";
23
- export declare const CONTEXT_MENU_CLASS = "graph-editor-context-menu dropdown-menu show position-fixed shadow-sm";
21
+ export declare const TARGET_HANDLE_CLASS_DEFAULT = "graph-editor-target-handle graph-editor-target-handle--default";
22
+ export declare const TARGET_HANDLE_CLASS_DANGER = "graph-editor-target-handle graph-editor-target-handle--danger";
23
+ export declare const CONTEXT_MENU_CLASS: string;
24
24
  export declare const REACT_FLOW_PANE_CLASS = "react-flow__pane";
25
- export declare const BORDER_DANGER_CLASS = "border-danger";
26
- export declare const BORDER_WARNING_CLASS = "border-warning";
27
- export declare const END_NODE_WIDTH_CLASS = "w-180";
25
+ export declare const BORDER_DANGER_CLASS = "graph-editor-canvas-node--border-danger";
26
+ export declare const BORDER_WARNING_CLASS = "graph-editor-canvas-node--border-warning";
27
+ export declare const END_NODE_WIDTH_CLASS = "graph-editor-canvas-node--end-width";
28
+ export declare const CANVAS_NODE_CARD_CLASS: string;
28
29
  export declare const MIN_NODE_WIDTH = 180;
29
30
  export declare const MAX_NODE_WIDTH = 560;
30
31
  export declare const MIN_NODE_HEIGHT = 80;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/canvas/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,+FAA+F;AAC/F,eAAO,MAAM,0BAA0B,sBAAsB,CAAC;AAE9D,wDAAwD;AACxD,eAAO,MAAM,+BAA+B,iCAAiC,CAAC;AAE9E,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAClD,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAC5D,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AACtE,eAAO,MAAM,4BAA4B,wCAAwC,CAAC;AAElF,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAC1D,eAAO,MAAM,mBAAmB,6BAAyB,CAAC;AAC1D,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAC1E,eAAO,MAAM,2BAA2B,qCAAiC,CAAC;AAC1E,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAC1E,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAC1E,eAAO,MAAM,uBAAuB,mCAAmC,CAAC;AACxE,eAAO,MAAM,2BAA2B,uCAAuC,CAAC;AAChF,eAAO,MAAM,mBAAmB,mDAAmD,CAAC;AAEpF,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AACjE,eAAO,MAAM,yBAAyB,8BAA+B,CAAC;AAEtE,eAAO,MAAM,2BAA2B,iDAAiD,CAAC;AAC1F,eAAO,MAAM,0BAA0B,gDAAgD,CAAC;AAExF,eAAO,MAAM,kBAAkB,0EAA0E,CAAC;AAE1G,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,oBAAoB,mBAAmB,CAAC;AAErD,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,qGAAqG;AACrG,eAAO,MAAM,oBAAoB,SAAS,CAAC;AAE3C,eAAO,MAAM,iBAAiB;;;;CAI7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,oBAAoB,YAAY,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/canvas/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAKvC,+FAA+F;AAC/F,eAAO,MAAM,0BAA0B,kCAAkC,CAAC;AAE1E,wDAAwD;AACxD,eAAO,MAAM,+BAA+B,iCAAiC,CAAC;AAE9E,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAClD,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAC5D,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AACtE,eAAO,MAAM,4BAA4B,wCAAwC,CAAC;AAElF,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAC1D,eAAO,MAAM,mBAAmB,6BAAyB,CAAC;AAC1D,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAC1E,eAAO,MAAM,2BAA2B,qCAAiC,CAAC;AAC1E,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAC1E,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAC1E,eAAO,MAAM,uBAAuB,mCAAmC,CAAC;AACxE,eAAO,MAAM,2BAA2B,uCAAuC,CAAC;AAChF,eAAO,MAAM,mBAAmB,mDAAmD,CAAC;AAEpF,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AACjE,eAAO,MAAM,yBAAyB,8BAA+B,CAAC;AAEtE,eAAO,MAAM,2BAA2B,mEAAmE,CAAC;AAC5G,eAAO,MAAM,0BAA0B,kEAAkE,CAAC;AAE1G,eAAO,MAAM,kBAAkB,QAM9B,CAAC;AAEF,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,eAAO,MAAM,mBAAmB,4CAA4C,CAAC;AAC7E,eAAO,MAAM,oBAAoB,6CAA6C,CAAC;AAE/E,eAAO,MAAM,oBAAoB,wCAAwC,CAAC;AAE1E,eAAO,MAAM,sBAAsB,QAA8D,CAAC;AAElG,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,qGAAqG;AACrG,eAAO,MAAM,oBAAoB,SAAS,CAAC;AAE3C,eAAO,MAAM,iBAAiB;;;;CAI7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,oBAAoB,YAAY,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import { MarkerType } from 'reactflow';
2
+ import { joinClasses } from '../utils/joinClasses.js';
3
+ import { EDITOR_CARD, EDITOR_DROPDOWN_MENU, EDITOR_ROUNDED } from '../ui/editorClasses.js';
2
4
  /** Background highlight when the node matches editor selection (sidebar / issues / canvas). */
3
- export const CANVAS_NODE_SELECTED_CLASS = 'bg-primary-subtle';
5
+ export const CANVAS_NODE_SELECTED_CLASS = 'graph-editor-canvas__selected';
4
6
  /** Dark readable text on selected canvas node cards. */
5
7
  export const CANVAS_NODE_SELECTED_TEXT_CLASS = 'graph-editor-canvas-selected';
6
8
  export const CANVAS_CLASS = 'graph-editor-canvas';
@@ -18,13 +20,14 @@ export const CHOICE_ROW_SELECTABLE_CLASS = 'graph-editor-choice-row-selectable';
18
20
  export const CHOICE_HANDLE_CLASS = 'graph-editor-handle graph-editor-choice-handle';
19
21
  export const NODE_DRAG_HANDLE_CLASS = 'graph-editor-drag-handle';
20
22
  export const NODE_DRAG_HANDLE_SELECTOR = `.${NODE_DRAG_HANDLE_CLASS}`;
21
- export const TARGET_HANDLE_CLASS_DEFAULT = 'handle-bg-default graph-editor-target-handle';
22
- export const TARGET_HANDLE_CLASS_DANGER = 'handle-bg-danger graph-editor-target-handle';
23
- export const CONTEXT_MENU_CLASS = 'graph-editor-context-menu dropdown-menu show position-fixed shadow-sm';
23
+ export const TARGET_HANDLE_CLASS_DEFAULT = 'graph-editor-target-handle graph-editor-target-handle--default';
24
+ export const TARGET_HANDLE_CLASS_DANGER = 'graph-editor-target-handle graph-editor-target-handle--danger';
25
+ export const CONTEXT_MENU_CLASS = joinClasses('graph-editor-context-menu', EDITOR_DROPDOWN_MENU, 'graph-editor-dropdown__menu--open', 'graph-editor-context-menu--fixed', 'graph-editor-shadow--sm');
24
26
  export const REACT_FLOW_PANE_CLASS = 'react-flow__pane';
25
- export const BORDER_DANGER_CLASS = 'border-danger';
26
- export const BORDER_WARNING_CLASS = 'border-warning';
27
- export const END_NODE_WIDTH_CLASS = 'w-180';
27
+ export const BORDER_DANGER_CLASS = 'graph-editor-canvas-node--border-danger';
28
+ export const BORDER_WARNING_CLASS = 'graph-editor-canvas-node--border-warning';
29
+ export const END_NODE_WIDTH_CLASS = 'graph-editor-canvas-node--end-width';
30
+ export const CANVAS_NODE_CARD_CLASS = joinClasses(EDITOR_CARD, EDITOR_ROUNDED, CANVAS_NODE_CLASS);
28
31
  export const MIN_NODE_WIDTH = 180;
29
32
  export const MAX_NODE_WIDTH = 560;
30
33
  export const MIN_NODE_HEIGHT = 80;
@@ -1 +1 @@
1
- {"version":3,"file":"GraphCanvasContextMenu.d.ts","sourceRoot":"","sources":["../../src/contextMenu/GraphCanvasContextMenu.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD,wBAAgB,sBAAsB,CAAC,EACnC,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,eAAe,EACf,YAAY,EACZ,YAAY,GACf,EAAE,QAAQ,CAAC;IACR,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACpC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC,sCAwDD"}
1
+ {"version":3,"file":"GraphCanvasContextMenu.d.ts","sourceRoot":"","sources":["../../src/contextMenu/GraphCanvasContextMenu.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,wBAAgB,sBAAsB,CAAC,EACnC,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,eAAe,EACf,YAAY,EACZ,YAAY,GACf,EAAE,QAAQ,CAAC;IACR,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACpC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC,sCAwDD"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { END_NODE_ID } from '@signalsafe/tree-spec-editor-core';
3
3
  import { CONTEXT_MENU_CLASS } from '../canvas/constants.js';
4
- import { joinClasses } from '../utils/joinClasses.js';
4
+ import { editorDropdownItemClass } from '../ui/editorClasses.js';
5
5
  export function GraphCanvasContextMenu({ menu, readOnly, onClose, onDuplicateNode, onDeleteNode, onAutoLayout, }) {
6
6
  if (!menu || readOnly)
7
7
  return null;
@@ -32,7 +32,7 @@ export function GraphCanvasContextMenu({ menu, readOnly, onClose, onDuplicateNod
32
32
  }
33
33
  if (items.length === 0)
34
34
  return null;
35
- return (_jsx("div", { className: CONTEXT_MENU_CLASS, style: { left: menu.x, top: menu.y, zIndex: 1050 }, role: "menu", tabIndex: -1, onContextMenu: (event) => event.preventDefault(), onPointerDown: (event) => event.stopPropagation(), children: items.map((item) => (_jsx("button", { type: "button", className: joinClasses('dropdown-item', item.danger && 'text-danger'), role: "menuitem", onClick: () => {
35
+ return (_jsx("div", { className: CONTEXT_MENU_CLASS, style: { left: menu.x, top: menu.y, zIndex: 1050 }, role: "menu", tabIndex: -1, onContextMenu: (event) => event.preventDefault(), onPointerDown: (event) => event.stopPropagation(), children: items.map((item) => (_jsx("button", { type: "button", className: editorDropdownItemClass(item.danger), role: "menuitem", onClick: () => {
36
36
  item.onClick();
37
37
  onClose();
38
38
  }, children: item.label }, item.key))) }));
@@ -1 +1 @@
1
- {"version":3,"file":"useCanvasContextMenu.d.ts","sourceRoot":"","sources":["../../src/hooks/useCanvasContextMenu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,MAAM,MAAM,2BAA2B,GAAG;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACrC,WAAW,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC3C,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,iBAAiB,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC3D,iBAAiB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CAClD,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,0BAA0B,CAsDrG"}
1
+ {"version":3,"file":"useCanvasContextMenu.d.ts","sourceRoot":"","sources":["../../src/hooks/useCanvasContextMenu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,MAAM,MAAM,2BAA2B,GAAG;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACrC,WAAW,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC3C,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,iBAAiB,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC3D,iBAAiB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CAClD,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,0BAA0B,CAsDrG"}
@@ -1 +1 @@
1
- {"version":3,"file":"useEditorAdapter.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditorAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEjH,OAAO,EAKH,KAAK,aAAa,EAClB,KAAK,YAAY,EACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAQH,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EAC5B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EAER,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EAC3B,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,uBAAuB,GAAG;IAClC,OAAO,EAAE,wBAAwB,CAAC;IAClC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,yBAAyB,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7D,eAAe,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC1C,iBAAiB,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,YAAY,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC3C,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,WAAW,EAAE,sBAAsB,EAAE,CAAC;IACtC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,QAAQ,EAAE,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAC/C,SAAS,EAAE,wBAAwB,CAAC,WAAW,CAAC,CAAC;IACjD,cAAc,EAAE,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;IAC3D,eAAe,EAAE,wBAAwB,CAAC,iBAAiB,CAAC,CAAC;IAC7D,YAAY,EAAE,wBAAwB,CAAC,cAAc,CAAC,CAAC;IACvD,WAAW,EAAE,SAAS,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC7D,YAAY,EAAE,SAAS,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAC,CAAC;CAClE,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,uBAAuB,GAAG,sBAAsB,CAsShG"}
1
+ {"version":3,"file":"useEditorAdapter.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditorAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEjH,OAAO,EAKH,KAAK,aAAa,EAClB,KAAK,YAAY,EACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAQH,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EAC5B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EAER,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EAC3B,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,uBAAuB,GAAG;IAClC,OAAO,EAAE,wBAAwB,CAAC;IAClC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,yBAAyB,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7D,eAAe,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC1C,iBAAiB,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,YAAY,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC3C,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,WAAW,EAAE,sBAAsB,EAAE,CAAC;IACtC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,QAAQ,EAAE,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAC/C,SAAS,EAAE,wBAAwB,CAAC,WAAW,CAAC,CAAC;IACjD,cAAc,EAAE,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;IAC3D,eAAe,EAAE,wBAAwB,CAAC,iBAAiB,CAAC,CAAC;IAC7D,YAAY,EAAE,wBAAwB,CAAC,cAAc,CAAC,CAAC;IACvD,WAAW,EAAE,SAAS,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC7D,YAAY,EAAE,SAAS,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAC,CAAC;CAClE,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,uBAAuB,GAAG,sBAAsB,CAsShG"}
@@ -1 +1 @@
1
- {"version":3,"file":"useEditorAutosave.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditorAutosave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIjF,OAAO,EAAmB,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAE1G,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAExD,MAAM,MAAM,wBAAwB,GAAG;IACnC,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,eAAe,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC1C,YAAY,EAAE,SAAS,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAC,CAAC;CAClE,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CA2CzE"}
1
+ {"version":3,"file":"useEditorAutosave.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditorAutosave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIjF,OAAO,EAAmB,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAE1G,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D,MAAM,MAAM,wBAAwB,GAAG;IACnC,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,eAAe,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC1C,YAAY,EAAE,SAAS,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAC,CAAC;CAClE,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CA2CzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"useTreeSpecEditor.d.ts","sourceRoot":"","sources":["../../src/hooks/useTreeSpecEditor.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAER,wBAAwB,EACxB,uBAAuB,EAE1B,MAAM,SAAS,CAAC;AAcjB;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,uBAAuB,CA6f5F"}
1
+ {"version":3,"file":"useTreeSpecEditor.d.ts","sourceRoot":"","sources":["../../src/hooks/useTreeSpecEditor.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAER,wBAAwB,EACxB,uBAAuB,EAE1B,MAAM,YAAY,CAAC;AAcpB;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,uBAAuB,CA6f5F"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,YAAY,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EACR,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,GACzB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EACR,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,GACzB,MAAM,kBAAkB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChoiceCanvasRow.d.ts","sourceRoot":"","sources":["../../src/nodes/ChoiceCanvasRow.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAkBtE,wBAAgB,eAAe,CAAC,EAC5B,MAAM,EACN,MAAM,EACN,WAAW,EACX,aAAa,EACb,eAAe,EACf,QAAQ,GACX,EAAE,QAAQ,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;CACrB,CAAC,+BAqHD"}
1
+ {"version":3,"file":"ChoiceCanvasRow.d.ts","sourceRoot":"","sources":["../../src/nodes/ChoiceCanvasRow.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAkCtE,wBAAgB,eAAe,CAAC,EAC5B,MAAM,EACN,MAAM,EACN,WAAW,EACX,aAAa,EACb,eAAe,EACf,QAAQ,GACX,EAAE,QAAQ,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;CACrB,CAAC,+BAoID"}
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Handle, Position } from 'reactflow';
3
3
  import { CANVAS_NODE_SELECTED_CLASS, CANVAS_NODE_SELECTED_TEXT_CLASS, CANVAS_CHOICE_SELECTED_CLASS, CHOICE_DRAG_HANDLE_CLASS, CHOICE_DRAG_HANDLE_SELECTOR, CHOICE_DROP_TARGET_CLASS, CHOICE_HANDLE_CLASS, CHOICE_ROW_CLASS, CHOICE_ROW_SELECT_CLASS, CHOICE_ROW_SELECTABLE_CLASS, CHOICE_HANDLE_PREFIX, } from '../canvas/constants.js';
4
4
  import { useGraphEditorCanvas } from '../GraphEditorCanvasContext.js';
5
- import { joinClasses } from '../utils/joinClasses.js';
5
+ import { EDITOR_FLEX_ALIGN_CENTER, EDITOR_FLEX_GROW_1, EDITOR_FLEX_ROW, EDITOR_FLEX_SHRINK_0, EDITOR_ICON, EDITOR_LIST_ITEM, EDITOR_MIN_W_0, EDITOR_SPACING_GAP_1, EDITOR_SPACING_P_0, EDITOR_SPACING_PX_2, EDITOR_SPACING_PY_2, EDITOR_TEXT_START, EDITOR_W_FULL, editorBadgeToneClass, joinClasses, } from '../ui/editorClasses.js';
6
6
  export function ChoiceCanvasRow({ nodeId, choice, choiceIndex, focusChoiceId, choiceTextClass, readOnly, }) {
7
7
  const { choiceDrag, choiceDropTarget, onSelectChoice, onChoiceDragStart, onChoiceDragEnd, onChoiceDragOver, onChoiceDrop, } = useGraphEditorCanvas();
8
8
  const isFocused = focusChoiceId === choice.id;
@@ -38,12 +38,12 @@ export function ChoiceCanvasRow({ nodeId, choice, choiceIndex, focusChoiceId, ch
38
38
  event.stopPropagation();
39
39
  onSelectChoice(nodeId, choice.id);
40
40
  };
41
- return (_jsx("li", { className: joinClasses('list-group-item p-0 border-0', isDropTarget && CHOICE_DROP_TARGET_CLASS), onDragOver: handleDragOver, onDrop: handleDrop, children: _jsxs("div", { className: joinClasses('d-flex align-items-center gap-1 min-w-0 py-2 px-2 w-100', CHOICE_ROW_CLASS, isFocused && CANVAS_CHOICE_SELECTED_CLASS, isFocused && CANVAS_NODE_SELECTED_CLASS, isFocused && CANVAS_NODE_SELECTED_TEXT_CLASS), children: [readOnly ? null : (_jsx("button", { type: "button", className: `${CHOICE_DRAG_HANDLE_CLASS} flex-shrink-0`, draggable: true, onDragStart: (event) => {
41
+ return (_jsx("li", { className: joinClasses(EDITOR_LIST_ITEM, EDITOR_SPACING_P_0, 'graph-editor-list__item--plain', isDropTarget && CHOICE_DROP_TARGET_CLASS), onDragOver: handleDragOver, onDrop: handleDrop, children: _jsxs("div", { className: joinClasses(EDITOR_FLEX_ROW, EDITOR_FLEX_ALIGN_CENTER, EDITOR_SPACING_GAP_1, EDITOR_MIN_W_0, EDITOR_SPACING_PY_2, EDITOR_SPACING_PX_2, EDITOR_W_FULL, CHOICE_ROW_CLASS, isFocused && CANVAS_CHOICE_SELECTED_CLASS, isFocused && CANVAS_NODE_SELECTED_CLASS, isFocused && CANVAS_NODE_SELECTED_TEXT_CLASS), children: [readOnly ? null : (_jsx("button", { type: "button", className: joinClasses(CHOICE_DRAG_HANDLE_CLASS, EDITOR_FLEX_SHRINK_0), draggable: true, onDragStart: (event) => {
42
42
  event.stopPropagation();
43
43
  onChoiceDragStart(nodeId, choice.id);
44
44
  event.dataTransfer.effectAllowed = 'move';
45
45
  event.dataTransfer.setData('text/plain', `${nodeId}::${choice.id}`);
46
- }, onDragEnd: () => onChoiceDragEnd(), onClick: (event) => event.stopPropagation(), title: "Drag to reorder or move to another node", "aria-label": "Drag choice", children: _jsx("i", { className: "bi bi-grip-vertical", "aria-hidden": true }) })), _jsxs("button", { type: "button", className: joinClasses(CHOICE_ROW_SELECT_CLASS, 'text-start flex-grow-1 min-w-0 d-flex align-items-center gap-1', readOnly ? '' : CHOICE_ROW_SELECTABLE_CLASS), disabled: readOnly, onClick: handleChoiceSelect, onKeyDown: (event) => {
46
+ }, onDragEnd: () => onChoiceDragEnd(), onClick: (event) => event.stopPropagation(), title: "Drag to reorder or move to another node", "aria-label": "Drag choice", children: _jsx("span", { className: joinClasses(EDITOR_ICON, 'graph-editor-icon--grip'), "aria-hidden": true, children: "\u22EE\u22EE" }) })), _jsxs("button", { type: "button", className: joinClasses(CHOICE_ROW_SELECT_CLASS, EDITOR_TEXT_START, EDITOR_FLEX_GROW_1, EDITOR_MIN_W_0, EDITOR_FLEX_ROW, EDITOR_FLEX_ALIGN_CENTER, EDITOR_SPACING_GAP_1, readOnly ? '' : CHOICE_ROW_SELECTABLE_CLASS), disabled: readOnly, onClick: handleChoiceSelect, onKeyDown: (event) => {
47
47
  if (readOnly)
48
48
  return;
49
49
  if (event.key === 'Enter' || event.key === ' ') {
@@ -51,5 +51,5 @@ export function ChoiceCanvasRow({ nodeId, choice, choiceIndex, focusChoiceId, ch
51
51
  event.stopPropagation();
52
52
  onSelectChoice(nodeId, choice.id);
53
53
  }
54
- }, children: [_jsx("span", { className: joinClasses(choiceTextClass, 'flex-grow-1 min-w-0'), title: choice.label, children: choice.label }), _jsx("span", { className: "badge bg-light text-dark flex-shrink-0", children: choice.id })] }), _jsx(Handle, { type: "source", position: Position.Right, id: `${CHOICE_HANDLE_PREFIX}${choice.id}`, className: CHOICE_HANDLE_CLASS })] }) }));
54
+ }, children: [_jsx("span", { className: joinClasses(choiceTextClass, EDITOR_FLEX_GROW_1, EDITOR_MIN_W_0), title: choice.label, children: choice.label }), _jsx("span", { className: joinClasses(editorBadgeToneClass('neutral'), EDITOR_FLEX_SHRINK_0), children: choice.id })] }), _jsx(Handle, { type: "source", position: Position.Right, id: `${CHOICE_HANDLE_PREFIX}${choice.id}`, className: CHOICE_HANDLE_CLASS })] }) }));
55
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EndNode.d.ts","sourceRoot":"","sources":["../../src/nodes/EndNode.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAa7D,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,+BAoB9C"}
1
+ {"version":3,"file":"EndNode.d.ts","sourceRoot":"","sources":["../../src/nodes/EndNode.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAsB7D,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,+BAkB9C"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Handle, Position } from 'reactflow';
3
- import { BORDER_DANGER_CLASS, CANVAS_NODE_CLASS, CANVAS_NODE_SELECTED_CLASS, CANVAS_NODE_SELECTED_TEXT_CLASS, END_NODE_WIDTH_CLASS, TARGET_HANDLE_CLASS_DANGER, TARGET_HANDLE_ID, } from '../canvas/constants.js';
4
- import { joinClasses } from '../utils/joinClasses.js';
3
+ import { BORDER_DANGER_CLASS, CANVAS_NODE_CARD_CLASS, CANVAS_NODE_SELECTED_CLASS, CANVAS_NODE_SELECTED_TEXT_CLASS, END_NODE_WIDTH_CLASS, TARGET_HANDLE_CLASS_DANGER, TARGET_HANDLE_ID, } from '../canvas/constants.js';
4
+ import { EDITOR_CARD_BODY, EDITOR_MUTED, EDITOR_SPACING_P_2, EDITOR_TEXT_BOLD, EDITOR_TEXT_CENTER, EDITOR_TEXT_DANGER, EDITOR_TEXT_SM, joinClasses, } from '../ui/editorClasses.js';
5
5
  export function EndNode({ selected }) {
6
- return (_jsxs("div", { className: joinClasses('card', 'rounded', CANVAS_NODE_CLASS, BORDER_DANGER_CLASS, END_NODE_WIDTH_CLASS, selected && CANVAS_NODE_SELECTED_CLASS, selected && CANVAS_NODE_SELECTED_TEXT_CLASS), children: [_jsx(Handle, { type: "target", position: Position.Left, id: TARGET_HANDLE_ID, className: TARGET_HANDLE_CLASS_DANGER }), _jsxs("div", { className: "card-body p-2 text-center", children: [_jsx("div", { className: "fw-bold text-danger", children: "END" }), _jsx("div", { className: "text-muted font-size-12", children: "Outcome required" })] })] }));
6
+ return (_jsxs("div", { className: joinClasses(CANVAS_NODE_CARD_CLASS, BORDER_DANGER_CLASS, END_NODE_WIDTH_CLASS, selected && CANVAS_NODE_SELECTED_CLASS, selected && CANVAS_NODE_SELECTED_TEXT_CLASS), children: [_jsx(Handle, { type: "target", position: Position.Left, id: TARGET_HANDLE_ID, className: TARGET_HANDLE_CLASS_DANGER }), _jsxs("div", { className: joinClasses(EDITOR_CARD_BODY, EDITOR_SPACING_P_2, EDITOR_TEXT_CENTER), children: [_jsx("div", { className: joinClasses(EDITOR_TEXT_BOLD, EDITOR_TEXT_DANGER), children: "END" }), _jsx("div", { className: joinClasses(EDITOR_MUTED, EDITOR_TEXT_SM), children: "Outcome required" })] })] }));
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PromptNode.d.ts","sourceRoot":"","sources":["../../src/nodes/PromptNode.tsx"],"names":[],"mappings":"AACA,OAAO,EAAyD,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AA2BlG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,KAAK,eAAe,GAAG,QAAQ,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC;AAE3D,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,eAAe,+BA+GjE"}
1
+ {"version":3,"file":"PromptNode.d.ts","sourceRoot":"","sources":["../../src/nodes/PromptNode.tsx"],"names":[],"mappings":"AACA,OAAO,EAAyD,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAoClG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,KAAK,eAAe,GAAG,QAAQ,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC;AAE3D,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,eAAe,+BA6GjE"}
@@ -2,10 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useCallback, useEffect } from 'react';
3
3
  import { Handle, NodeResizer, Position, useUpdateNodeInternals } from 'reactflow';
4
4
  import { editorHintsToStyle, getEditorHints, nodeTextWrapClassName, resolveNodeTextWrap, } from '@signalsafe/tree-spec-editor-core';
5
- import { CANVAS_NODE_BODY_CLASS, CANVAS_NODE_CLASS, CANVAS_NODE_SELECTED_CLASS, CANVAS_NODE_SELECTED_TEXT_CLASS, MIN_NODE_HEIGHT, MAX_NODE_HEIGHT, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TARGET_HANDLE_CLASS_DEFAULT, TARGET_HANDLE_ID, } from '../canvas/constants.js';
5
+ import { CANVAS_NODE_BODY_CLASS, CANVAS_NODE_CARD_CLASS, CANVAS_NODE_SELECTED_CLASS, CANVAS_NODE_SELECTED_TEXT_CLASS, MIN_NODE_HEIGHT, MAX_NODE_HEIGHT, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TARGET_HANDLE_CLASS_DEFAULT, TARGET_HANDLE_ID, } from '../canvas/constants.js';
6
6
  import { getPromptNodeBorderClass } from '../canvas/edgeStyle.js';
7
7
  import { useGraphEditorCanvas } from '../GraphEditorCanvasContext.js';
8
- import { joinClasses } from '../utils/joinClasses.js';
8
+ import { EDITOR_CARD_BODY, EDITOR_MIN_W_0, EDITOR_MUTED, EDITOR_SPACING_MB_0, EDITOR_SPACING_PX_2, EDITOR_SPACING_PY_2, EDITOR_TEXT_SM, joinClasses, } from '../ui/editorClasses.js';
9
9
  import { PromptNodeChoicesList } from './PromptNodeChoicesList.js';
10
10
  import { PromptNodeHeader } from './PromptNodeHeader.js';
11
11
  import { PromptNodeToolbar } from './PromptNodeToolbar.js';
@@ -47,5 +47,5 @@ export function PromptNode({ data, selected, id }) {
47
47
  onResizeNodeStart(id, params.width, params.height);
48
48
  }, onResize: handleResize, onResizeEnd: (_event, params) => {
49
49
  onResizeNode(id, params.width, params.height);
50
- } })) : null, _jsxs("div", { className: joinClasses('card', 'rounded', CANVAS_NODE_CLASS, borderClass, showNodeHighlight && CANVAS_NODE_SELECTED_CLASS, showNodeHighlight && CANVAS_NODE_SELECTED_TEXT_CLASS), style: cardStyle, children: [_jsx(Handle, { type: "target", position: Position.Left, id: TARGET_HANDLE_ID, className: TARGET_HANDLE_CLASS_DEFAULT }), _jsx(PromptNodeHeader, { node: n, data: data, editor: editor, locked: locked, readOnly: readOnly }), _jsxs("div", { className: `${CANVAS_NODE_BODY_CLASS} min-w-0`, style: scrollBodyStyle, children: [_jsx("div", { className: "card-body py-2 px-2 min-w-0 nodrag", children: _jsx("div", { className: joinClasses('font-size-12 mb-0', promptTextClass), title: n.prompt || undefined, children: n.prompt || _jsx("em", { className: "text-muted", children: "(empty prompt)" }) }) }), _jsx(PromptNodeChoicesList, { nodeId: id, choices: choices, focusChoiceId: focusChoiceId, choiceTextClass: choiceTextClass, readOnly: readOnly, choiceDrag: choiceDrag, choiceDropTarget: choiceDropTarget, onChoiceDragOver: onChoiceDragOver, onChoiceDrop: onChoiceDrop })] })] })] }));
50
+ } })) : null, _jsxs("div", { className: joinClasses(CANVAS_NODE_CARD_CLASS, borderClass, showNodeHighlight && CANVAS_NODE_SELECTED_CLASS, showNodeHighlight && CANVAS_NODE_SELECTED_TEXT_CLASS), style: cardStyle, children: [_jsx(Handle, { type: "target", position: Position.Left, id: TARGET_HANDLE_ID, className: TARGET_HANDLE_CLASS_DEFAULT }), _jsx(PromptNodeHeader, { node: n, data: data, editor: editor, locked: locked, readOnly: readOnly }), _jsxs("div", { className: joinClasses(CANVAS_NODE_BODY_CLASS, EDITOR_MIN_W_0), style: scrollBodyStyle, children: [_jsx("div", { className: joinClasses(EDITOR_CARD_BODY, EDITOR_SPACING_PY_2, EDITOR_SPACING_PX_2, EDITOR_MIN_W_0, 'nodrag'), children: _jsx("div", { className: joinClasses(EDITOR_TEXT_SM, EDITOR_SPACING_MB_0, promptTextClass), title: n.prompt || undefined, children: n.prompt || _jsx("em", { className: EDITOR_MUTED, children: "(empty prompt)" }) }) }), _jsx(PromptNodeChoicesList, { nodeId: id, choices: choices, focusChoiceId: focusChoiceId, choiceTextClass: choiceTextClass, readOnly: readOnly, choiceDrag: choiceDrag, choiceDropTarget: choiceDropTarget, onChoiceDragOver: onChoiceDragOver, onChoiceDrop: onChoiceDrop })] })] })] }));
51
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PromptNodeChoicesList.d.ts","sourceRoot":"","sources":["../../src/nodes/PromptNodeChoicesList.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAMtE,OAAO,EAAE,KAAK,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAIjF,wBAAgB,qBAAqB,CAAC,EAClC,MAAM,EACN,OAAO,EACP,aAAa,EACb,eAAe,EACf,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GACf,EAAE,QAAQ,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,6BAA6B,CAAC,YAAY,CAAC,CAAC;IACxD,gBAAgB,EAAE,6BAA6B,CAAC,kBAAkB,CAAC,CAAC;IACpE,gBAAgB,EAAE,6BAA6B,CAAC,kBAAkB,CAAC,CAAC;IACpE,YAAY,EAAE,6BAA6B,CAAC,cAAc,CAAC,CAAC;CAC/D,CAAC,+BA2DD"}
1
+ {"version":3,"file":"PromptNodeChoicesList.d.ts","sourceRoot":"","sources":["../../src/nodes/PromptNodeChoicesList.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAMtE,OAAO,EAAE,KAAK,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;AAapF,wBAAgB,qBAAqB,CAAC,EAClC,MAAM,EACN,OAAO,EACP,aAAa,EACb,eAAe,EACf,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GACf,EAAE,QAAQ,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,6BAA6B,CAAC,YAAY,CAAC,CAAC;IACxD,gBAAgB,EAAE,6BAA6B,CAAC,kBAAkB,CAAC,CAAC;IACpE,gBAAgB,EAAE,6BAA6B,CAAC,kBAAkB,CAAC,CAAC;IACpE,YAAY,EAAE,6BAA6B,CAAC,cAAc,CAAC,CAAC;CAC/D,CAAC,+BA8DD"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { CHOICE_DROP_APPEND_CLASS, CHOICE_DROP_TARGET_CLASS, } from '../canvas/constants.js';
3
- import { joinClasses } from '../utils/joinClasses.js';
3
+ import { EDITOR_LIST_FLUSH, EDITOR_LIST_ITEM_EMPTY, EDITOR_MIN_W_0, EDITOR_MUTED, EDITOR_SPACING_PX_2, EDITOR_SPACING_PY_2, EDITOR_TEXT_SM, joinClasses, } from '../ui/editorClasses.js';
4
4
  import { ChoiceCanvasRow } from './ChoiceCanvasRow.js';
5
5
  export function PromptNodeChoicesList({ nodeId, choices, focusChoiceId, choiceTextClass, readOnly, choiceDrag, choiceDropTarget, onChoiceDragOver, onChoiceDrop, }) {
6
6
  const handleListDragOver = (event) => {
@@ -18,7 +18,7 @@ export function PromptNodeChoicesList({ nodeId, choices, focusChoiceId, choiceTe
18
18
  event.stopPropagation();
19
19
  onChoiceDrop(nodeId, choices.length);
20
20
  };
21
- return (_jsxs("ul", { className: "list-group list-group-flush font-size-12 min-w-0 nodrag", "aria-label": "Node choices", onDragOver: handleListDragOver, onDrop: handleListDrop, children: [choices.length === 0 ? (_jsx("li", { className: joinClasses('list-group-item py-2 px-2 text-muted', choiceDrag && CHOICE_DROP_TARGET_CLASS), children: _jsx("em", { children: "No choices" }) })) : (choices.map((c, choiceIndex) => (_jsx(ChoiceCanvasRow, { nodeId: nodeId, choice: c, choiceIndex: choiceIndex, focusChoiceId: focusChoiceId, choiceTextClass: choiceTextClass, readOnly: readOnly }, c.id)))), choiceDrag && readOnly === false && choices.length > 0 ? (_jsx("li", { className: joinClasses(CHOICE_DROP_APPEND_CLASS, 'list-unstyled', choiceDropTarget?.nodeId === nodeId &&
21
+ return (_jsxs("ul", { className: joinClasses(EDITOR_LIST_FLUSH, EDITOR_TEXT_SM, EDITOR_MIN_W_0, 'nodrag'), "aria-label": "Node choices", onDragOver: handleListDragOver, onDrop: handleListDrop, children: [choices.length === 0 ? (_jsx("li", { className: joinClasses(EDITOR_LIST_ITEM_EMPTY, EDITOR_SPACING_PY_2, EDITOR_SPACING_PX_2, EDITOR_MUTED, choiceDrag && CHOICE_DROP_TARGET_CLASS), children: _jsx("em", { children: "No choices" }) })) : (choices.map((c, choiceIndex) => (_jsx(ChoiceCanvasRow, { nodeId: nodeId, choice: c, choiceIndex: choiceIndex, focusChoiceId: focusChoiceId, choiceTextClass: choiceTextClass, readOnly: readOnly }, c.id)))), choiceDrag && readOnly === false && choices.length > 0 ? (_jsx("li", { className: joinClasses(CHOICE_DROP_APPEND_CLASS, 'graph-editor-list__append-target', choiceDropTarget?.nodeId === nodeId &&
22
22
  choiceDropTarget.index === choices.length &&
23
23
  CHOICE_DROP_TARGET_CLASS), "aria-hidden": true })) : null] }));
24
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PromptNodeHeader.d.ts","sourceRoot":"","sources":["../../src/nodes/PromptNodeHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAIpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,gBAAgB,CAAC,EAC7B,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,MAAM,EACN,QAAQ,GACX,EAAE,QAAQ,CAAC;IACR,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACrB,CAAC,+BAkCD"}
1
+ {"version":3,"file":"PromptNodeHeader.d.ts","sourceRoot":"","sources":["../../src/nodes/PromptNodeHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAyBpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,wBAAgB,gBAAgB,CAAC,EAC7B,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,MAAM,EACN,QAAQ,GACX,EAAE,QAAQ,CAAC;IACR,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACrB,CAAC,+BA2DD"}
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { NODE_DRAG_HANDLE_CLASS } from '../canvas/constants.js';
3
+ import { EDITOR_CARD_HEADER_MUTED, EDITOR_FLEX_ALIGN_START, EDITOR_FLEX_BETWEEN, EDITOR_FLEX_GROW_1, EDITOR_FLEX_ROW, EDITOR_FLEX_SHRINK_0, EDITOR_ICON, EDITOR_MIN_W_0, EDITOR_MUTED, EDITOR_OVERFLOW_HIDDEN, EDITOR_SPACING_GAP_1, EDITOR_SPACING_GAP_2, EDITOR_SPACING_MS_1, EDITOR_SPACING_PX_2, EDITOR_SPACING_PY_2, EDITOR_TEXT_BOLD, EDITOR_TEXT_MD, EDITOR_TEXT_XS, joinClasses, } from '../ui/editorClasses.js';
3
4
  import { PromptNodeIssueBadges } from './PromptNodeIssueBadges.js';
4
5
  export function PromptNodeHeader({ node, data, editor, locked, readOnly, }) {
5
- return (_jsx("div", { className: "card-header bg-body-secondary py-2 px-2 min-w-0 flex-shrink-0", children: _jsxs("div", { className: "d-flex justify-content-between align-items-start gap-2 min-w-0", children: [_jsxs("div", { className: "d-flex align-items-start gap-1 min-w-0 flex-grow-1 overflow-hidden", children: [locked || readOnly ? null : (_jsx("span", { className: `${NODE_DRAG_HANDLE_CLASS} flex-shrink-0`, title: "Drag node", "aria-label": "Drag node", children: _jsx("i", { className: "bi bi-grip-vertical", "aria-hidden": true }) })), _jsx("div", { className: "min-w-0 flex-grow-1 overflow-hidden", children: _jsxs("div", { className: "fw-bold font-size-13", children: [data.isStart ? '▶ ' : '', node.type, editor.locked ? (_jsx("i", { className: "bi bi-lock-fill ms-1 text-secondary", title: "Locked", "aria-hidden": true })) : null, _jsx(PromptNodeIssueBadges, { issuesTotal: data.issuesTotal, issuesErrors: data.issuesErrors, issuesWarnings: data.issuesWarnings, issuesInfo: data.issuesInfo })] }) })] }), _jsx("div", { className: "text-muted font-size-11 flex-shrink-0", children: node.id.slice(0, 8) })] }) }));
6
+ return (_jsx("div", { className: joinClasses(EDITOR_CARD_HEADER_MUTED, EDITOR_SPACING_PY_2, EDITOR_SPACING_PX_2, EDITOR_MIN_W_0, EDITOR_FLEX_SHRINK_0), children: _jsxs("div", { className: joinClasses(EDITOR_FLEX_BETWEEN, EDITOR_FLEX_ALIGN_START, EDITOR_SPACING_GAP_2, EDITOR_MIN_W_0), children: [_jsxs("div", { className: joinClasses(EDITOR_FLEX_ROW, EDITOR_FLEX_ALIGN_START, EDITOR_SPACING_GAP_1, EDITOR_MIN_W_0, EDITOR_FLEX_GROW_1, EDITOR_OVERFLOW_HIDDEN), children: [locked || readOnly ? null : (_jsx("span", { className: joinClasses(NODE_DRAG_HANDLE_CLASS, EDITOR_FLEX_SHRINK_0), title: "Drag node", "aria-label": "Drag node", children: _jsx("span", { className: joinClasses(EDITOR_ICON, 'graph-editor-icon--grip'), "aria-hidden": true, children: "\u22EE\u22EE" }) })), _jsx("div", { className: joinClasses(EDITOR_MIN_W_0, EDITOR_FLEX_GROW_1, EDITOR_OVERFLOW_HIDDEN), children: _jsxs("div", { className: joinClasses(EDITOR_TEXT_BOLD, EDITOR_TEXT_MD), children: [data.isStart ? '▶ ' : '', node.type, editor.locked ? (_jsx("span", { className: joinClasses(EDITOR_ICON, 'graph-editor-icon--lock', EDITOR_SPACING_MS_1), title: "Locked", "aria-hidden": true, children: "\uD83D\uDD12" })) : null, _jsx(PromptNodeIssueBadges, { issuesTotal: data.issuesTotal, issuesErrors: data.issuesErrors, issuesWarnings: data.issuesWarnings, issuesInfo: data.issuesInfo })] }) })] }), _jsx("div", { className: joinClasses(EDITOR_MUTED, EDITOR_TEXT_XS, EDITOR_FLEX_SHRINK_0), children: node.id.slice(0, 8) })] }) }));
6
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PromptNodeIssueBadges.d.ts","sourceRoot":"","sources":["../../src/nodes/PromptNodeIssueBadges.tsx"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CAAC,EAClC,WAAW,EACX,YAAY,EACZ,cAAc,EACd,UAAU,GACb,EAAE,QAAQ,CAAC;IACR,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACtB,CAAC,sCAcD"}
1
+ {"version":3,"file":"PromptNodeIssueBadges.d.ts","sourceRoot":"","sources":["../../src/nodes/PromptNodeIssueBadges.tsx"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CAAC,EAClC,WAAW,EACX,YAAY,EACZ,cAAc,EACd,UAAU,GACb,EAAE,QAAQ,CAAC;IACR,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACtB,CAAC,sCAgBD"}
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { EDITOR_SPACING_ME_1, EDITOR_SPACING_MS_2, editorBadgeToneClass } from '../ui/editorClasses.js';
2
3
  export function PromptNodeIssueBadges({ issuesTotal, issuesErrors, issuesWarnings, issuesInfo, }) {
3
4
  if (issuesTotal <= 0)
4
5
  return null;
5
- return (_jsxs("span", { className: "ms-2", title: `${issuesErrors} errors, ${issuesWarnings} warnings, ${issuesInfo} info`, children: [issuesErrors > 0 ? _jsx("span", { className: "badge bg-danger me-1", children: issuesErrors }) : null, issuesWarnings > 0 ? (_jsx("span", { className: "badge bg-warning text-dark me-1", children: issuesWarnings })) : null, issuesInfo > 0 ? _jsx("span", { className: "badge bg-info text-dark", children: issuesInfo }) : null] }));
6
+ return (_jsxs("span", { className: EDITOR_SPACING_MS_2, title: `${issuesErrors} errors, ${issuesWarnings} warnings, ${issuesInfo} info`, children: [issuesErrors > 0 ? (_jsx("span", { className: `${editorBadgeToneClass('danger')} ${EDITOR_SPACING_ME_1}`, children: issuesErrors })) : null, issuesWarnings > 0 ? (_jsx("span", { className: `${editorBadgeToneClass('warning')} ${EDITOR_SPACING_ME_1}`, children: issuesWarnings })) : null, issuesInfo > 0 ? _jsx("span", { className: editorBadgeToneClass('info'), children: issuesInfo }) : null] }));
6
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PromptNodeToolbar.d.ts","sourceRoot":"","sources":["../../src/nodes/PromptNodeToolbar.tsx"],"names":[],"mappings":"AAEA,wBAAgB,iBAAiB,CAAC,EAC9B,MAAM,EACN,eAAe,EACf,YAAY,GACf,EAAE,QAAQ,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC,CAAC,+BA0BD"}
1
+ {"version":3,"file":"PromptNodeToolbar.d.ts","sourceRoot":"","sources":["../../src/nodes/PromptNodeToolbar.tsx"],"names":[],"mappings":"AASA,wBAAgB,iBAAiB,CAAC,EAC9B,MAAM,EACN,eAAe,EACf,YAAY,GACf,EAAE,QAAQ,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC,CAAC,+BA8BD"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Position, NodeToolbar } from 'reactflow';
3
+ import { EDITOR_BTN_GROUP, EDITOR_ICON, EDITOR_SR_ONLY, editorBtnToneClass, } from '../ui/editorClasses.js';
3
4
  export function PromptNodeToolbar({ nodeId, onDuplicateNode, onDeleteNode, }) {
4
- return (_jsx(NodeToolbar, { isVisible: true, position: Position.Bottom, offset: 8, align: "start", children: _jsxs("fieldset", { className: "btn-group btn-group-sm shadow-sm border-0 p-0 m-0", children: [_jsx("legend", { className: "visually-hidden", children: "Node actions" }), _jsx("button", { type: "button", className: "btn btn-light border", title: "Duplicate node", "aria-label": "Duplicate node", onClick: () => onDuplicateNode(nodeId), children: _jsx("i", { className: "bi bi-files", "aria-hidden": true }) }), _jsx("button", { type: "button", className: "btn btn-light border text-danger", title: "Delete node", "aria-label": "Delete node", onClick: () => onDeleteNode(nodeId), children: _jsx("i", { className: "bi bi-trash", "aria-hidden": true }) })] }) }));
5
+ return (_jsx(NodeToolbar, { isVisible: true, position: Position.Bottom, offset: 8, align: "start", children: _jsxs("fieldset", { className: EDITOR_BTN_GROUP, children: [_jsx("legend", { className: EDITOR_SR_ONLY, children: "Node actions" }), _jsx("button", { type: "button", className: editorBtnToneClass('light'), title: "Duplicate node", "aria-label": "Duplicate node", onClick: () => onDuplicateNode(nodeId), children: _jsx("span", { className: EDITOR_ICON, "aria-hidden": true, children: "\u29C9" }) }), _jsx("button", { type: "button", className: editorBtnToneClass('danger'), title: "Delete node", "aria-label": "Delete node", onClick: () => onDeleteNode(nodeId), children: _jsx("span", { className: EDITOR_ICON, "aria-hidden": true, children: "\u2715" }) })] }) }));
5
6
  }
@@ -0,0 +1,53 @@
1
+ /** UI-kit agnostic canvas class hooks (aligned with @signalsafe/tree-spec-editor). */
2
+ import { joinClasses } from '../utils/joinClasses.js';
3
+ export { joinClasses };
4
+ export declare const EDITOR_CARD = "graph-editor-card";
5
+ export declare const EDITOR_CARD_HEADER = "graph-editor-card__header";
6
+ export declare const EDITOR_CARD_BODY = "graph-editor-card__body";
7
+ export declare const EDITOR_CARD_HEADER_MUTED = "graph-editor-card__header graph-editor-surface--muted";
8
+ export declare const EDITOR_LIST = "graph-editor-list";
9
+ export declare const EDITOR_LIST_FLUSH = "graph-editor-list graph-editor-list--flush";
10
+ export declare const EDITOR_LIST_ITEM = "graph-editor-list__item";
11
+ export declare const EDITOR_LIST_ITEM_EMPTY = "graph-editor-list__item graph-editor-list__item--empty";
12
+ export declare const EDITOR_BTN = "graph-editor-btn";
13
+ export declare const EDITOR_BTN_GROUP = "graph-editor-btn-group graph-editor-btn-group--sm";
14
+ export declare const EDITOR_BADGE = "graph-editor-badge";
15
+ export declare const EDITOR_DROPDOWN_MENU = "graph-editor-dropdown__menu";
16
+ export declare const EDITOR_DROPDOWN_ITEM = "graph-editor-dropdown__item";
17
+ export declare const EDITOR_FLEX = "graph-editor-flex";
18
+ export declare const EDITOR_FLEX_BETWEEN = "graph-editor-flex graph-editor-flex--between";
19
+ export declare const EDITOR_FLEX_ROW = "graph-editor-flex graph-editor-flex--row";
20
+ export declare const EDITOR_FLEX_ALIGN_START = "graph-editor-flex graph-editor-flex--align-start";
21
+ export declare const EDITOR_FLEX_ALIGN_CENTER = "graph-editor-flex graph-editor-flex--align-center";
22
+ export declare const EDITOR_MIN_W_0 = "graph-editor-min-w-0";
23
+ export declare const EDITOR_FLEX_SHRINK_0 = "graph-editor-flex-shrink-0";
24
+ export declare const EDITOR_FLEX_GROW_1 = "graph-editor-flex-grow-1";
25
+ export declare const EDITOR_OVERFLOW_HIDDEN = "graph-editor-overflow-hidden";
26
+ export declare const EDITOR_W_FULL = "graph-editor-w-full";
27
+ export declare const EDITOR_MUTED = "graph-editor-muted";
28
+ export declare const EDITOR_TEXT_DANGER = "graph-editor-text--danger";
29
+ export declare const EDITOR_TEXT_CENTER = "graph-editor-text--center";
30
+ export declare const EDITOR_TEXT_START = "graph-editor-text--start";
31
+ export declare const EDITOR_TEXT_BOLD = "graph-editor-text--bold";
32
+ export declare const EDITOR_TEXT_XS = "graph-editor-text--xs";
33
+ export declare const EDITOR_TEXT_SM = "graph-editor-text--sm";
34
+ export declare const EDITOR_TEXT_MD = "graph-editor-text--md";
35
+ export declare const EDITOR_SPACING_PY_2 = "graph-editor-spacing--py-2";
36
+ export declare const EDITOR_SPACING_PX_2 = "graph-editor-spacing--px-2";
37
+ export declare const EDITOR_SPACING_P_2 = "graph-editor-spacing--p-2";
38
+ export declare const EDITOR_SPACING_GAP_1 = "graph-editor-spacing--gap-1";
39
+ export declare const EDITOR_SPACING_GAP_2 = "graph-editor-spacing--gap-2";
40
+ export declare const EDITOR_SPACING_MB_0 = "graph-editor-spacing--mb-0";
41
+ export declare const EDITOR_SPACING_MS_1 = "graph-editor-spacing--ms-1";
42
+ export declare const EDITOR_SPACING_MS_2 = "graph-editor-spacing--ms-2";
43
+ export declare const EDITOR_SPACING_ME_1 = "graph-editor-spacing--me-1";
44
+ export declare const EDITOR_SPACING_P_0 = "graph-editor-spacing--p-0";
45
+ export declare const EDITOR_SPACING_M_0 = "graph-editor-spacing--m-0";
46
+ export declare const EDITOR_ROUNDED = "graph-editor-rounded";
47
+ export declare const EDITOR_SR_ONLY = "graph-editor-sr-only";
48
+ export declare const EDITOR_ICON = "graph-editor-icon";
49
+ export declare const EDITOR_CANVAS_ROOT = "graph-editor-canvas-root";
50
+ export declare function editorBtnToneClass(variant?: string): string;
51
+ export declare function editorBadgeToneClass(variant: 'danger' | 'warning' | 'info' | 'neutral'): string;
52
+ export declare function editorDropdownItemClass(danger?: boolean): string;
53
+ //# sourceMappingURL=editorClasses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editorClasses.d.ts","sourceRoot":"","sources":["../../src/ui/editorClasses.ts"],"names":[],"mappings":"AAAA,sFAAsF;AAEtF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,eAAO,MAAM,WAAW,sBAAsB,CAAC;AAC/C,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAC9D,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAC1D,eAAO,MAAM,wBAAwB,0DAA0D,CAAC;AAEhG,eAAO,MAAM,WAAW,sBAAsB,CAAC;AAC/C,eAAO,MAAM,iBAAiB,+CAA+C,CAAC;AAC9E,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAC1D,eAAO,MAAM,sBAAsB,2DAA2D,CAAC;AAE/F,eAAO,MAAM,UAAU,qBAAqB,CAAC;AAC7C,eAAO,MAAM,gBAAgB,sDAAsD,CAAC;AACpF,eAAO,MAAM,YAAY,uBAAuB,CAAC;AAEjD,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAClE,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAElE,eAAO,MAAM,WAAW,sBAAsB,CAAC;AAC/C,eAAO,MAAM,mBAAmB,iDAAiD,CAAC;AAClF,eAAO,MAAM,eAAe,6CAA6C,CAAC;AAC1E,eAAO,MAAM,uBAAuB,qDAAqD,CAAC;AAC1F,eAAO,MAAM,wBAAwB,sDAAsD,CAAC;AAC5F,eAAO,MAAM,cAAc,yBAAyB,CAAC;AACrD,eAAO,MAAM,oBAAoB,+BAA+B,CAAC;AACjE,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAC7D,eAAO,MAAM,sBAAsB,iCAAiC,CAAC;AACrE,eAAO,MAAM,aAAa,wBAAwB,CAAC;AAEnD,eAAO,MAAM,YAAY,uBAAuB,CAAC;AACjD,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAC5D,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAC1D,eAAO,MAAM,cAAc,0BAA0B,CAAC;AACtD,eAAO,MAAM,cAAc,0BAA0B,CAAC;AACtD,eAAO,MAAM,cAAc,0BAA0B,CAAC;AAEtD,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAChE,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAChE,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAC9D,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAClE,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAClE,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAChE,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAChE,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAChE,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAChE,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAE9D,eAAO,MAAM,cAAc,yBAAyB,CAAC;AACrD,eAAO,MAAM,cAAc,yBAAyB,CAAC;AACrD,eAAO,MAAM,WAAW,sBAAsB,CAAC;AAE/C,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAE7D,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAE/F;AAED,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAEhE"}
@@ -0,0 +1,69 @@
1
+ /** UI-kit agnostic canvas class hooks (aligned with @signalsafe/tree-spec-editor). */
2
+ import { joinClasses } from '../utils/joinClasses.js';
3
+ export { joinClasses };
4
+ export const EDITOR_CARD = 'graph-editor-card';
5
+ export const EDITOR_CARD_HEADER = 'graph-editor-card__header';
6
+ export const EDITOR_CARD_BODY = 'graph-editor-card__body';
7
+ export const EDITOR_CARD_HEADER_MUTED = 'graph-editor-card__header graph-editor-surface--muted';
8
+ export const EDITOR_LIST = 'graph-editor-list';
9
+ export const EDITOR_LIST_FLUSH = 'graph-editor-list graph-editor-list--flush';
10
+ export const EDITOR_LIST_ITEM = 'graph-editor-list__item';
11
+ export const EDITOR_LIST_ITEM_EMPTY = 'graph-editor-list__item graph-editor-list__item--empty';
12
+ export const EDITOR_BTN = 'graph-editor-btn';
13
+ export const EDITOR_BTN_GROUP = 'graph-editor-btn-group graph-editor-btn-group--sm';
14
+ export const EDITOR_BADGE = 'graph-editor-badge';
15
+ export const EDITOR_DROPDOWN_MENU = 'graph-editor-dropdown__menu';
16
+ export const EDITOR_DROPDOWN_ITEM = 'graph-editor-dropdown__item';
17
+ export const EDITOR_FLEX = 'graph-editor-flex';
18
+ export const EDITOR_FLEX_BETWEEN = 'graph-editor-flex graph-editor-flex--between';
19
+ export const EDITOR_FLEX_ROW = 'graph-editor-flex graph-editor-flex--row';
20
+ export const EDITOR_FLEX_ALIGN_START = 'graph-editor-flex graph-editor-flex--align-start';
21
+ export const EDITOR_FLEX_ALIGN_CENTER = 'graph-editor-flex graph-editor-flex--align-center';
22
+ export const EDITOR_MIN_W_0 = 'graph-editor-min-w-0';
23
+ export const EDITOR_FLEX_SHRINK_0 = 'graph-editor-flex-shrink-0';
24
+ export const EDITOR_FLEX_GROW_1 = 'graph-editor-flex-grow-1';
25
+ export const EDITOR_OVERFLOW_HIDDEN = 'graph-editor-overflow-hidden';
26
+ export const EDITOR_W_FULL = 'graph-editor-w-full';
27
+ export const EDITOR_MUTED = 'graph-editor-muted';
28
+ export const EDITOR_TEXT_DANGER = 'graph-editor-text--danger';
29
+ export const EDITOR_TEXT_CENTER = 'graph-editor-text--center';
30
+ export const EDITOR_TEXT_START = 'graph-editor-text--start';
31
+ export const EDITOR_TEXT_BOLD = 'graph-editor-text--bold';
32
+ export const EDITOR_TEXT_XS = 'graph-editor-text--xs';
33
+ export const EDITOR_TEXT_SM = 'graph-editor-text--sm';
34
+ export const EDITOR_TEXT_MD = 'graph-editor-text--md';
35
+ export const EDITOR_SPACING_PY_2 = 'graph-editor-spacing--py-2';
36
+ export const EDITOR_SPACING_PX_2 = 'graph-editor-spacing--px-2';
37
+ export const EDITOR_SPACING_P_2 = 'graph-editor-spacing--p-2';
38
+ export const EDITOR_SPACING_GAP_1 = 'graph-editor-spacing--gap-1';
39
+ export const EDITOR_SPACING_GAP_2 = 'graph-editor-spacing--gap-2';
40
+ export const EDITOR_SPACING_MB_0 = 'graph-editor-spacing--mb-0';
41
+ export const EDITOR_SPACING_MS_1 = 'graph-editor-spacing--ms-1';
42
+ export const EDITOR_SPACING_MS_2 = 'graph-editor-spacing--ms-2';
43
+ export const EDITOR_SPACING_ME_1 = 'graph-editor-spacing--me-1';
44
+ export const EDITOR_SPACING_P_0 = 'graph-editor-spacing--p-0';
45
+ export const EDITOR_SPACING_M_0 = 'graph-editor-spacing--m-0';
46
+ export const EDITOR_ROUNDED = 'graph-editor-rounded';
47
+ export const EDITOR_SR_ONLY = 'graph-editor-sr-only';
48
+ export const EDITOR_ICON = 'graph-editor-icon';
49
+ export const EDITOR_CANVAS_ROOT = 'graph-editor-canvas-root';
50
+ export function editorBtnToneClass(variant) {
51
+ const tone = normalizeBtnTone(variant);
52
+ return `${EDITOR_BTN} graph-editor-btn--${tone}`;
53
+ }
54
+ export function editorBadgeToneClass(variant) {
55
+ return `${EDITOR_BADGE} graph-editor-badge--${variant}`;
56
+ }
57
+ export function editorDropdownItemClass(danger) {
58
+ return joinClasses(EDITOR_DROPDOWN_ITEM, danger && 'graph-editor-dropdown__item--danger');
59
+ }
60
+ function normalizeBtnTone(variant) {
61
+ if (!variant)
62
+ return 'neutral';
63
+ const map = {
64
+ light: 'light',
65
+ danger: 'danger',
66
+ neutral: 'neutral',
67
+ };
68
+ return map[variant] ?? variant.replace(/^outline-/, '');
69
+ }
@@ -0,0 +1,65 @@
1
+ # Canvas UI-kit agnostic styling
2
+
3
+ **Package:** `@signalsafe/tree-spec-editor-react`
4
+ **Status:** Implemented (0.2.0+)
5
+
6
+ ---
7
+
8
+ ## Summary
9
+
10
+ The React Flow canvas emits **semantic HTML** with stable **`graph-editor-*` class hooks**. It does **not** require Bootstrap CSS or Bootstrap Icons.
11
+
12
+ **Host applications own styling.** Map `graph-editor-*` classes in your theme (DeliveryPlus, Tailwind, MUI, etc.) or override via the `className` prop on `TreeSpecGraphEditor`.
13
+
14
+ Peer dependencies: `react`, `react-dom`, `reactflow` only.
15
+
16
+ ---
17
+
18
+ ## Class hooks
19
+
20
+ Canvas nodes, choices, toolbars, and context menus use tokens from `src/ui/editorClasses.ts` and `src/canvas/constants.ts`:
21
+
22
+ | Area | Example classes |
23
+ |------|-----------------|
24
+ | Canvas root | `graph-editor-canvas-root`, `graph-editor-canvas` |
25
+ | Node card | `graph-editor-card`, `graph-editor-canvas-node`, `graph-editor-card__header`, `graph-editor-card__body` |
26
+ | Selection | `graph-editor-canvas__selected`, `graph-editor-canvas-selected`, `graph-editor-canvas-choice-selected` |
27
+ | Issue borders | `graph-editor-canvas-node--border-danger`, `graph-editor-canvas-node--border-warning` |
28
+ | Lists / choices | `graph-editor-list`, `graph-editor-list__item`, `graph-editor-choice-row` |
29
+ | Badges | `graph-editor-badge`, `graph-editor-badge--danger` / `--warning` / `--info` |
30
+ | Toolbar | `graph-editor-btn-group`, `graph-editor-btn`, `graph-editor-btn--light` |
31
+ | Context menu | `graph-editor-context-menu`, `graph-editor-dropdown__menu`, `graph-editor-dropdown__item` |
32
+ | Handles | `graph-editor-target-handle`, `graph-editor-choice-handle` |
33
+
34
+ Text wrap helpers from `@signalsafe/tree-spec-editor-core` already use `graph-editor-node-text-*` classes.
35
+
36
+ ---
37
+
38
+ ## Host override strategy
39
+
40
+ 1. **CSS bridge** — add host styles targeting `graph-editor-*` (recommended for DeliveryPlus migration).
41
+ 2. **`className` prop** — pass layout/sizing classes on `TreeSpecGraphEditor` (default is `graph-editor-canvas-root`).
42
+ 3. **Shell package** — `@signalsafe/tree-spec-editor` can map the same hooks to Bootstrap utilities in host SCSS.
43
+
44
+ This package ships **no CSS file**; `sideEffects: ["**/*.css"]` applies only to the React Flow stylesheet import.
45
+
46
+ ---
47
+
48
+ ## Migration from 0.1.x
49
+
50
+ | Before (0.1.x) | After (0.2.0) |
51
+ |----------------|---------------|
52
+ | `bg-primary-subtle` selection highlight | `graph-editor-canvas__selected` |
53
+ | `border-warning` / `border-danger` | `graph-editor-canvas-node--border-warning` / `--border-danger` |
54
+ | Bootstrap `card`, `list-group`, `btn`, `badge` | `graph-editor-card`, `graph-editor-list`, `graph-editor-btn`, `graph-editor-badge` |
55
+ | Default `className="h-70vh border rounded"` | Default `className="graph-editor-canvas-root"` |
56
+ | Bootstrap Icons (`bi bi-*`) | Unicode / `graph-editor-icon` spans |
57
+
58
+ **Semver:** minor (0.2.0) — DOM class contract change; component props unchanged.
59
+
60
+ ---
61
+
62
+ ## Related packages
63
+
64
+ - `@signalsafe/tree-spec-editor` — full authoring shell (UI-kit agnostic panels; host-owned Bootstrap optional)
65
+ - `@signalsafe/tree-spec-editor-core` — headless model and layout helpers
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@signalsafe/tree-spec-editor-react",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
- "description": "Headless React canvas for the SignalSafe TreeSpec graph editor (React Flow shell, no UI library).",
5
+ "description": "UI-kit agnostic React Flow canvas for the SignalSafe TreeSpec graph editor (no UI library).",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
@@ -36,12 +36,13 @@
36
36
  }
37
37
  },
38
38
  "files": [
39
- "dist",
40
- "README.md",
41
- "LICENSE"
39
+ "dist",
40
+ "README.md",
41
+ "LICENSE",
42
+ "docs"
42
43
  ],
43
44
  "engines": {
44
- "node": ">=18"
45
+ "node": ">=22.12.0"
45
46
  },
46
47
  "packageManager": "yarn@1.22.22",
47
48
  "publishConfig": {
@@ -49,17 +50,19 @@
49
50
  },
50
51
  "scripts": {
51
52
  "build": "tsc -p tsconfig.build.json",
53
+ "lint": "yarn typecheck",
52
54
  "typecheck": "tsc --noEmit",
53
55
  "pack:local": "npm pack --pack-destination ../../dist/reusable-npm",
54
56
  "smoke:package": "node scripts/smoke-package.mjs",
55
57
  "prepublishOnly": "npm run build",
56
58
  "prepare": "npm run build",
57
59
  "test": "vitest run",
60
+ "test:coverage": "yarn test --coverage",
58
61
  "test:monorepo": "cd ../../frontend && yarn vitest run --config vitest.tree-spec-editor-react.config.ts"
59
62
  },
60
63
  "dependencies": {
61
- "@signalsafe/tree-spec": "^0.3.2",
62
- "@signalsafe/tree-spec-editor-core": "^0.1.3"
64
+ "@signalsafe/tree-spec": "^0.3.3",
65
+ "@signalsafe/tree-spec-editor-core": "^0.1.4"
63
66
  },
64
67
  "peerDependencies": {
65
68
  "react": "^18.0.0",
@@ -1,14 +0,0 @@
1
- # Standalone export
2
-
3
- This tree was generated by `scripts/export-standalone-npm-package.sh tree-spec-editor-react` from the DeliveryPlus monorepo.
4
-
5
- ```bash
6
- git init
7
- git branch -M main
8
- git add .
9
- git commit -m "Sync tree-spec-editor-react from DeliveryPlus"
10
- git remote add origin git@github.com:SignalSafeSoftware/tree-spec-editor-react.git
11
- git push -u origin main
12
- ```
13
-
14
- See `RELEASING.md` for npm publish steps.