@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.
- package/README.md +14 -6
- package/dist/TreeSpecGraphEditor.d.ts +2 -2
- package/dist/TreeSpecGraphEditor.d.ts.map +1 -1
- package/dist/TreeSpecGraphEditor.js +2 -1
- package/dist/canvas/constants.d.ts +8 -7
- package/dist/canvas/constants.d.ts.map +1 -1
- package/dist/canvas/constants.js +10 -7
- package/dist/contextMenu/GraphCanvasContextMenu.d.ts.map +1 -1
- package/dist/contextMenu/GraphCanvasContextMenu.js +2 -2
- package/dist/hooks/useCanvasContextMenu.d.ts.map +1 -1
- package/dist/hooks/useEditorAdapter.d.ts.map +1 -1
- package/dist/hooks/useEditorAutosave.d.ts.map +1 -1
- package/dist/hooks/useTreeSpecEditor.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/nodes/ChoiceCanvasRow.d.ts.map +1 -1
- package/dist/nodes/ChoiceCanvasRow.js +4 -4
- package/dist/nodes/EndNode.d.ts.map +1 -1
- package/dist/nodes/EndNode.js +3 -3
- package/dist/nodes/PromptNode.d.ts.map +1 -1
- package/dist/nodes/PromptNode.js +3 -3
- package/dist/nodes/PromptNodeChoicesList.d.ts.map +1 -1
- package/dist/nodes/PromptNodeChoicesList.js +2 -2
- package/dist/nodes/PromptNodeHeader.d.ts.map +1 -1
- package/dist/nodes/PromptNodeHeader.js +2 -1
- package/dist/nodes/PromptNodeIssueBadges.d.ts.map +1 -1
- package/dist/nodes/PromptNodeIssueBadges.js +2 -1
- package/dist/nodes/PromptNodeToolbar.d.ts.map +1 -1
- package/dist/nodes/PromptNodeToolbar.js +2 -1
- package/dist/ui/editorClasses.d.ts +53 -0
- package/dist/ui/editorClasses.d.ts.map +1 -0
- package/dist/ui/editorClasses.js +69 -0
- package/docs/UI_KIT_AGNOSTIC_CANVAS.md +65 -0
- package/package.json +11 -8
- 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
|
|
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`
|
|
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="
|
|
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
|
-
|
|
|
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) —
|
|
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
|
|
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
|
|
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;
|
|
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 =
|
|
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 = "
|
|
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 = "
|
|
22
|
-
export declare const TARGET_HANDLE_CLASS_DANGER = "
|
|
23
|
-
export declare const CONTEXT_MENU_CLASS
|
|
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 = "
|
|
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;
|
|
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"}
|
package/dist/canvas/constants.js
CHANGED
|
@@ -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 = '
|
|
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 = '
|
|
22
|
-
export const TARGET_HANDLE_CLASS_DANGER = '
|
|
23
|
-
export const CONTEXT_MENU_CLASS = 'graph-editor-context-menu
|
|
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 = '
|
|
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,
|
|
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 {
|
|
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:
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
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;
|
|
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 '../
|
|
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('
|
|
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("
|
|
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,
|
|
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;
|
|
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"}
|
package/dist/nodes/EndNode.js
CHANGED
|
@@ -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,
|
|
4
|
-
import { joinClasses } from '../
|
|
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(
|
|
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;
|
|
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"}
|
package/dist/nodes/PromptNode.js
CHANGED
|
@@ -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,
|
|
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 '../
|
|
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(
|
|
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,
|
|
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 '../
|
|
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:
|
|
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;
|
|
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:
|
|
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":"
|
|
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:
|
|
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":"
|
|
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:
|
|
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.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE",
|
|
42
|
+
"docs"
|
|
42
43
|
],
|
|
43
44
|
"engines": {
|
|
44
|
-
"node": ">=
|
|
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.
|
|
62
|
-
"@signalsafe/tree-spec-editor-core": "^0.1.
|
|
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",
|
package/README.standalone.md
DELETED
|
@@ -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.
|