@signalsafe/tree-spec-editor-react 0.1.2 → 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 +126 -42
- package/dist/TreeSpecGraphEditor.d.ts +2 -2
- package/dist/TreeSpecGraphEditor.d.ts.map +1 -1
- package/dist/TreeSpecGraphEditor.js +18 -17
- 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/canvas/edgeBuilders.js +2 -2
- package/dist/canvas/edgeStyle.js +1 -1
- package/dist/canvas/typeGuards.js +1 -1
- package/dist/contextMenu/GraphCanvasContextMenu.d.ts +1 -1
- package/dist/contextMenu/GraphCanvasContextMenu.d.ts.map +1 -1
- package/dist/contextMenu/GraphCanvasContextMenu.js +3 -3
- package/dist/hooks/useCanvasContextMenu.d.ts +1 -1
- package/dist/hooks/useCanvasContextMenu.d.ts.map +1 -1
- package/dist/hooks/useCanvasGraphState.js +2 -2
- package/dist/hooks/useEditorAdapter.d.ts +1 -1
- package/dist/hooks/useEditorAdapter.d.ts.map +1 -1
- package/dist/hooks/useEditorAutosave.d.ts +1 -1
- package/dist/hooks/useEditorAutosave.d.ts.map +1 -1
- package/dist/hooks/useEditorSelection.d.ts.map +1 -1
- package/dist/hooks/useEditorSelection.js +1 -2
- package/dist/hooks/useGraphConnect.js +1 -1
- package/dist/hooks/useTreeSpecEditor.d.ts +1 -1
- package/dist/hooks/useTreeSpecEditor.d.ts.map +1 -1
- package/dist/hooks/useTreeSpecEditor.js +5 -5
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/nodes/ChoiceCanvasRow.d.ts.map +1 -1
- package/dist/nodes/ChoiceCanvasRow.js +6 -6
- package/dist/nodes/EndNode.d.ts.map +1 -1
- package/dist/nodes/EndNode.js +3 -3
- package/dist/nodes/PromptNode.d.ts +1 -1
- package/dist/nodes/PromptNode.d.ts.map +1 -1
- package/dist/nodes/PromptNode.js +8 -8
- package/dist/nodes/PromptNodeChoicesList.d.ts +1 -1
- package/dist/nodes/PromptNodeChoicesList.d.ts.map +1 -1
- package/dist/nodes/PromptNodeChoicesList.js +4 -4
- package/dist/nodes/PromptNodeHeader.d.ts +1 -1
- package/dist/nodes/PromptNodeHeader.d.ts.map +1 -1
- package/dist/nodes/PromptNodeHeader.js +4 -3
- 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 +17 -9
package/README.md
CHANGED
|
@@ -1,64 +1,148 @@
|
|
|
1
1
|
# @signalsafe/tree-spec-editor-react
|
|
2
2
|
|
|
3
|
-
Headless React layer for the SignalSafe TreeSpec graph editor
|
|
4
|
-
React Flow canvas, owns React state plumbing, and exposes the editor as a
|
|
5
|
-
single React component — without depending on any specific UI library.
|
|
3
|
+
Headless **React + React Flow** layer for the SignalSafe TreeSpec graph editor: canvas component, orchestration hook, and wiring to `@signalsafe/tree-spec-editor-core`.
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
| | |
|
|
6
|
+
|---|---|
|
|
7
|
+
| **npm** | `@signalsafe/tree-spec-editor-react` |
|
|
8
|
+
| **GitHub** | [SignalSafeSoftware/tree-spec-editor-react](https://github.com/SignalSafeSoftware/tree-spec-editor-react) |
|
|
9
|
+
| **Peer deps** | `react`, `react-dom`, `reactflow` (^18 / ^11) — **no UI library required** |
|
|
8
10
|
|
|
9
|
-
##
|
|
11
|
+
## UI-kit agnostic canvas
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
- **`useTreeSpecEditor`** — stateful orchestration hook (load, autosave, validate, publish, selection, undo/redo, choice/edge helpers). Exposes `inspectorNode` (selected node or edge source node), `focusChoiceId`, and `selectedEdge` for sidebar panels.
|
|
13
|
-
- **`TreeSpecGraphEditorProps`** — props type.
|
|
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
14
|
|
|
15
|
-
|
|
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).
|
|
16
|
+
|
|
17
|
+
## What this package does
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
| **Edge** | `inspectorNode` = source node; `focusChoiceId` = source choice | **No pan/zoom** (viewport stays put) |
|
|
21
|
-
| **Choice** (canvas or inspector focus) | `focusChoiceId` set; nodes list highlights via `focusNodeId` | Fits when the parent node is selected |
|
|
19
|
+
- Renders **`TreeSpecGraphEditor`** (React Flow canvas, custom nodes/edges, selection).
|
|
20
|
+
- Exposes **`useTreeSpecEditor`** for load/validate/autosave/publish orchestration (host injects adapter callbacks).
|
|
21
|
+
- Re-exports core editor types used by the hook.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
## What this package does not do
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
- Sidebar panels, modals, toolbars, or UI-kit chrome — use `@signalsafe/tree-spec-editor` or your own UI shell.
|
|
26
|
+
- Routing, HTTP, authentication, or persistence — host app provides adapter implementations.
|
|
27
|
+
- Wire compile/publish to a backend without your adapter code.
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|--------|---------|
|
|
29
|
-
| Editor model, tree operations, layout, autosave/keyboard helpers, choice edge hints | `@signalsafe/tree-spec-editor-core` |
|
|
30
|
-
| Sidebar panels, inspector, modals, toolbar (Bootstrap-styled) | `@signalsafe/tree-spec-editor` |
|
|
31
|
-
| Material-styled React shell (planned) | `@signalsafe/tree-spec-editor-react-mui` |
|
|
32
|
-
| Angular shell + canvas (planned) | `@signalsafe/tree-spec-editor-angular` |
|
|
33
|
-
| Vue shell + canvas (planned) | `@signalsafe/tree-spec-editor-vue` |
|
|
29
|
+
## Install
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
```bash
|
|
32
|
+
npm install @signalsafe/tree-spec-editor-react @signalsafe/tree-spec-editor-core @signalsafe/tree-spec react react-dom reactflow
|
|
33
|
+
```
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
- **Material (React)** hosts should add `-react-mui` (planned), reusing this canvas unchanged.
|
|
39
|
-
- Layer boundaries and refactor plan: [docs/ai/packages-editor-architecture.md](../../docs/ai/packages-editor-architecture.md).
|
|
35
|
+
### React Flow CSS (required)
|
|
40
36
|
|
|
41
|
-
|
|
37
|
+
This package imports `reactflow/dist/style.css` from source. Bundlers treat it as a side effect (`sideEffects: ["**/*.css"]` in `package.json`).
|
|
38
|
+
|
|
39
|
+
Ensure your app loads React Flow styles, for example:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import "reactflow/dist/style.css";
|
|
43
|
+
```
|
|
44
|
+
|
|
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.
|
|
46
|
+
|
|
47
|
+
## Quick start
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { useState } from "react";
|
|
51
|
+
import TreeSpecGraphEditor from "@signalsafe/tree-spec-editor-react";
|
|
52
|
+
import {
|
|
53
|
+
END_NODE_ID,
|
|
54
|
+
type EditorTree,
|
|
55
|
+
} from "@signalsafe/tree-spec-editor-core";
|
|
56
|
+
|
|
57
|
+
const initialTree: EditorTree = {
|
|
58
|
+
start_node: "start",
|
|
59
|
+
nodes: {
|
|
60
|
+
start: {
|
|
61
|
+
id: "start",
|
|
62
|
+
type: "prompt",
|
|
63
|
+
prompt: "Example prompt",
|
|
64
|
+
choices: [{ id: "done", label: "Finish" }],
|
|
65
|
+
position: { x: 40, y: 120 },
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
transitions: [
|
|
69
|
+
{
|
|
70
|
+
id: "t1",
|
|
71
|
+
fromNodeId: "start",
|
|
72
|
+
fromChoiceId: "done",
|
|
73
|
+
toNodeId: END_NODE_ID,
|
|
74
|
+
outcome: "safe",
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export function ExampleCanvas() {
|
|
80
|
+
const [tree, setTree] = useState(initialTree);
|
|
81
|
+
return (
|
|
82
|
+
<TreeSpecGraphEditor
|
|
83
|
+
tree={tree}
|
|
84
|
+
onChange={setTree}
|
|
85
|
+
className="graph-editor-canvas-root my-canvas-host"
|
|
86
|
+
/>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
For full authoring flows (load/save/validate), compose **`useTreeSpecEditor`** with your adapter — see tests and `@signalsafe/tree-spec-editor` for a reference shell.
|
|
92
|
+
|
|
93
|
+
## Public exports
|
|
94
|
+
|
|
95
|
+
| Export | Purpose |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `default` / `TreeSpecGraphEditor` | React Flow canvas |
|
|
98
|
+
| `TreeSpecGraphEditorProps` | Canvas props |
|
|
99
|
+
| `useTreeSpecEditor` | Stateful editor orchestration |
|
|
100
|
+
| `TreeSpecEditorAdapter`, `UseTreeSpecEditorResult`, … | Adapter and hook types |
|
|
101
|
+
|
|
102
|
+
Import from `@signalsafe/tree-spec-editor-react` only (no subpath exports).
|
|
103
|
+
|
|
104
|
+
## Package boundaries
|
|
105
|
+
|
|
106
|
+
| Layer | Package |
|
|
107
|
+
|---|---|
|
|
108
|
+
| Wire | `@signalsafe/tree-spec` |
|
|
109
|
+
| Editor model | `@signalsafe/tree-spec-editor-core` |
|
|
110
|
+
| **React canvas (this package)** | `@signalsafe/tree-spec-editor-react` |
|
|
111
|
+
| Authoring shell | `@signalsafe/tree-spec-editor` |
|
|
112
|
+
|
|
113
|
+
## Canvas selection behavior
|
|
114
|
+
|
|
115
|
+
| Selection | Inspector context | Contextual zoom (default on) |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| Node | selected node | fits node in viewport |
|
|
118
|
+
| Edge | source node + focused choice | viewport unchanged |
|
|
119
|
+
| Choice | `focusChoiceId` set | fits parent node when selected |
|
|
120
|
+
|
|
121
|
+
Pass `contextualZoom={false}` to disable automatic viewport fitting.
|
|
122
|
+
|
|
123
|
+
## Development
|
|
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
|
+
|
|
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.
|
|
42
128
|
|
|
43
129
|
```bash
|
|
44
|
-
|
|
130
|
+
yarn install
|
|
131
|
+
yarn build
|
|
132
|
+
yarn test
|
|
133
|
+
yarn typecheck
|
|
45
134
|
```
|
|
46
135
|
|
|
47
|
-
|
|
48
|
-
e.g. `import 'reactflow/dist/style.css';`) in the consuming app. The
|
|
49
|
-
package itself imports the CSS file from its source, so bundlers that
|
|
50
|
-
resolve module references will pick it up automatically.
|
|
136
|
+
## Security
|
|
51
137
|
|
|
52
|
-
|
|
138
|
+
See [SECURITY.md](./SECURITY.md). Host applications must authenticate users, authorize edits, and validate TreeSpec JSON server-side before publish.
|
|
53
139
|
|
|
54
|
-
|
|
55
|
-
to ship a Material-styled editor only need to publish their own UI shell
|
|
56
|
-
(panels, modals, toolbar) — they reuse the canvas and the editor model
|
|
57
|
-
unchanged. This also keeps `@signalsafe/tree-spec-editor` (the
|
|
58
|
-
Bootstrap variant) from being the sole React entry point.
|
|
140
|
+
## Changelog and releases
|
|
59
141
|
|
|
60
|
-
|
|
142
|
+
- [CHANGELOG.md](./CHANGELOG.md)
|
|
143
|
+
- [RELEASING.md](./RELEASING.md)
|
|
61
144
|
|
|
62
|
-
|
|
145
|
+
## Related packages
|
|
63
146
|
|
|
64
|
-
|
|
147
|
+
- [`@signalsafe/tree-spec-editor-core`](https://github.com/SignalSafeSoftware/tree-spec-editor-core) — framework-agnostic editor helpers.
|
|
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"}
|
|
@@ -3,23 +3,24 @@ import { useCallback, useMemo, useRef, useState } from 'react';
|
|
|
3
3
|
import ReactFlow, { Background, ConnectionMode, Controls, MiniMap, ReactFlowProvider, useReactFlow, } from 'reactflow';
|
|
4
4
|
import 'reactflow/dist/style.css';
|
|
5
5
|
import { GRAPH_SELECTION_KIND, choiceIdFromHandle, resolveGraphViewport, LAYOUT_SNAP_GRID, } from '@signalsafe/tree-spec-editor-core';
|
|
6
|
-
import { GraphEditorCanvasContext, } from './GraphEditorCanvasContext';
|
|
7
|
-
import { buildEdgeMarker, getIssueEdgeStyle, resolveSelectedEdgeStroke } from './canvas/edgeStyle';
|
|
8
|
-
import { CANVAS_CLASS } from './canvas/constants';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
|
|
6
|
+
import { GraphEditorCanvasContext, } from './GraphEditorCanvasContext.js';
|
|
7
|
+
import { buildEdgeMarker, getIssueEdgeStyle, resolveSelectedEdgeStroke } from './canvas/edgeStyle.js';
|
|
8
|
+
import { CANVAS_CLASS } from './canvas/constants.js';
|
|
9
|
+
import { EDITOR_CANVAS_ROOT } from './ui/editorClasses.js';
|
|
10
|
+
import { resolveCanvasFocusChoiceId } from './canvas/focusChoice.js';
|
|
11
|
+
import { isChoiceRowClickTarget } from './canvas/typeGuards.js';
|
|
12
|
+
import { GraphCanvasContextMenu } from './contextMenu/GraphCanvasContextMenu.js';
|
|
13
|
+
import { EndNode } from './nodes/EndNode.js';
|
|
14
|
+
import { PromptNode } from './nodes/PromptNode.js';
|
|
15
|
+
import { joinClasses } from './utils/joinClasses.js';
|
|
16
|
+
import { useCanvasContextMenu } from './hooks/useCanvasContextMenu.js';
|
|
17
|
+
import { useCanvasGraphState } from './hooks/useCanvasGraphState.js';
|
|
18
|
+
import { useCanvasIssueIndex } from './hooks/useCanvasIssueIndex.js';
|
|
19
|
+
import { useCanvasNodeResize } from './hooks/useCanvasNodeResize.js';
|
|
20
|
+
import { useCanvasViewport } from './hooks/useCanvasViewport.js';
|
|
21
|
+
import { useChoiceDragDrop } from './hooks/useChoiceDragDrop.js';
|
|
22
|
+
import { useGraphConnect } from './hooks/useGraphConnect.js';
|
|
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,7 +1,7 @@
|
|
|
1
1
|
import { TERMINAL_OUTCOME } from '@signalsafe/tree-spec';
|
|
2
2
|
import { END_NODE_ID, choiceIdFromHandle, resolveDefaultEdgeType, resolveEffectiveEdgeType, resolveEdgeStrokeColor, shouldShowEdgeLabel, } from '@signalsafe/tree-spec-editor-core';
|
|
3
|
-
import { CHOICE_HANDLE_PREFIX, TARGET_HANDLE_ID, } from './constants';
|
|
4
|
-
import { buildEdgeMarker, buildEdgeStyle, resolveEdgePathStroke } from './edgeStyle';
|
|
3
|
+
import { CHOICE_HANDLE_PREFIX, TARGET_HANDLE_ID, } from './constants.js';
|
|
4
|
+
import { buildEdgeMarker, buildEdgeStyle, resolveEdgePathStroke } from './edgeStyle.js';
|
|
5
5
|
export function edgeLabelForTransition(tree, t) {
|
|
6
6
|
const node = tree.nodes[t.fromNodeId];
|
|
7
7
|
const choice = node?.choices?.find((c) => c.id === t.fromChoiceId);
|
package/dist/canvas/edgeStyle.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_CANVAS_EDGE_STROKE } from '@signalsafe/tree-spec-editor-core';
|
|
2
|
-
import { BORDER_DANGER_CLASS, BORDER_WARNING_CLASS, EDGE_ARROW_MARKER, SELECTED_EDGE_STROKE } from './constants';
|
|
2
|
+
import { BORDER_DANGER_CLASS, BORDER_WARNING_CLASS, EDGE_ARROW_MARKER, SELECTED_EDGE_STROKE } from './constants.js';
|
|
3
3
|
export function getPromptNodeBorderClass(hasErrors, warningCount) {
|
|
4
4
|
if (hasErrors) {
|
|
5
5
|
return BORDER_DANGER_CLASS;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CanvasContextMenuState } from './types';
|
|
1
|
+
import type { CanvasContextMenuState } from './types.js';
|
|
2
2
|
export declare function GraphCanvasContextMenu({ menu, readOnly, onClose, onDuplicateNode, onDeleteNode, onAutoLayout, }: Readonly<{
|
|
3
3
|
menu: CanvasContextMenuState | null;
|
|
4
4
|
readOnly: boolean;
|
|
@@ -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
|
-
import { CONTEXT_MENU_CLASS } from '../canvas/constants';
|
|
4
|
-
import {
|
|
3
|
+
import { CONTEXT_MENU_CLASS } from '../canvas/constants.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:
|
|
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,6 +1,6 @@
|
|
|
1
1
|
import { type MouseEvent } from 'react';
|
|
2
2
|
import type { Node } from 'reactflow';
|
|
3
|
-
import type { CanvasContextMenuState } from '../contextMenu/types';
|
|
3
|
+
import type { CanvasContextMenuState } from '../contextMenu/types.js';
|
|
4
4
|
export type UseCanvasContextMenuOptions = {
|
|
5
5
|
readOnly: boolean;
|
|
6
6
|
onAutoLayout?: () => void;
|
|
@@ -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,8 +1,8 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
import { useEdgesState, useNodesState, } from 'reactflow';
|
|
3
3
|
import { END_NODE_ID, getEditorHints, isNodeLocked, patchGraphEditorMeta, resolveCanvasNodeWidth, resolveEndNodePosition, snapPosition, } from '@signalsafe/tree-spec-editor-core';
|
|
4
|
-
import { buildEdgesFromTransitions, buildTransitionsFromEdges } from '../canvas/edgeBuilders';
|
|
5
|
-
import { NODE_DRAG_HANDLE_SELECTOR } from '../canvas/constants';
|
|
4
|
+
import { buildEdgesFromTransitions, buildTransitionsFromEdges } from '../canvas/edgeBuilders.js';
|
|
5
|
+
import { NODE_DRAG_HANDLE_SELECTOR } from '../canvas/constants.js';
|
|
6
6
|
export function useCanvasGraphState(options) {
|
|
7
7
|
const { tree, onChange, issues, issuesByNode, readOnly, resizeHeightByNodeId, isResizingRef, suppressViewportSaveRef, } = options;
|
|
8
8
|
const isDraggingRef = useRef(false);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type MutableRefObject, type RefObject } from 'react';
|
|
2
2
|
import { type TreeSpecIssue, type TreeSpecWire } from '@signalsafe/tree-spec';
|
|
3
3
|
import { type AutosaveStatus, type EditorTree, type TreeSpecAuditEventItem, type TreeSpecSnapshotItem } from '@signalsafe/tree-spec-editor-core';
|
|
4
|
-
import type { GraphEditorVersionInfo, UseTreeSpecEditorActions, UseTreeSpecEditorOptions } from './types';
|
|
4
|
+
import type { GraphEditorVersionInfo, UseTreeSpecEditorActions, UseTreeSpecEditorOptions } from './types.js';
|
|
5
5
|
export type UseEditorAdapterOptions = {
|
|
6
6
|
options: UseTreeSpecEditorOptions;
|
|
7
7
|
tree: EditorTree | null;
|
|
@@ -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,6 +1,6 @@
|
|
|
1
1
|
import { type MutableRefObject, type RefObject } from 'react';
|
|
2
2
|
import { type AutosaveStatus, type EditorTree } from '@signalsafe/tree-spec-editor-core';
|
|
3
|
-
import type { UseTreeSpecEditorActions } from './types';
|
|
3
|
+
import type { UseTreeSpecEditorActions } from './types.js';
|
|
4
4
|
export type UseEditorAutosaveOptions = {
|
|
5
5
|
enableAutosave: boolean;
|
|
6
6
|
autosaveDebounceMs: number;
|
|
@@ -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":"useEditorSelection.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditorSelection.ts"],"names":[],"mappings":"AAEA,OAAO,EAIH,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,cAAc,EACtB,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,wBAAwB,GAAG;IACnC,SAAS,EAAE,cAAc,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACtC,aAAa,EAAE,UAAU,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,cAAc,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,WAAW,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACvE,YAAY,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,wBAAwB,
|
|
1
|
+
{"version":3,"file":"useEditorSelection.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditorSelection.ts"],"names":[],"mappings":"AAEA,OAAO,EAIH,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,cAAc,EACtB,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,wBAAwB,GAAG;IACnC,SAAS,EAAE,cAAc,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACtC,aAAa,EAAE,UAAU,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,cAAc,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,WAAW,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACvE,YAAY,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,wBAAwB,CA4EpF"}
|
|
@@ -13,8 +13,7 @@ export function useEditorSelection(tree) {
|
|
|
13
13
|
const applySelection = useCallback((next) => {
|
|
14
14
|
setSelection(next);
|
|
15
15
|
if (next.kind === GRAPH_SELECTION_KIND.EDGE && next.id && tree) {
|
|
16
|
-
|
|
17
|
-
if (!edge)
|
|
16
|
+
if (!tree.transitions.some((t) => t.id === next.id))
|
|
18
17
|
return;
|
|
19
18
|
}
|
|
20
19
|
const { focusNodeId: nextFocusNodeId, focusChoiceId: nextFocusChoiceId } = resolveGraphSelectionFocus(next, tree);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback, useRef } from 'react';
|
|
2
2
|
import { useReactFlow } from 'reactflow';
|
|
3
3
|
import { GRAPH_SELECTION_KIND, applyEditorConnect, applyEditorConnectOnDrop, applyEditorReconnect, isValidEditorConnection, } from '@signalsafe/tree-spec-editor-core';
|
|
4
|
-
import { isReactFlowPaneTarget } from '../canvas/typeGuards';
|
|
4
|
+
import { isReactFlowPaneTarget } from '../canvas/typeGuards.js';
|
|
5
5
|
export function useGraphConnect(options) {
|
|
6
6
|
const { treeRef, onChange, onSelect, readOnly } = options;
|
|
7
7
|
const rf = useReactFlow();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UseTreeSpecEditorOptions, UseTreeSpecEditorResult } from './types';
|
|
1
|
+
import type { UseTreeSpecEditorOptions, UseTreeSpecEditorResult } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Headless React hook that owns the full stateful behavior of the SignalSafe
|
|
4
4
|
* TreeSpec graph editor — loading, autosave, validation, publish, snapshots,
|
|
@@ -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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import { compileTreeSpec, decompileTreeSpec, TERMINAL_OUTCOME, TREE_SPEC_ISSUE_SEVERITY, } from '@signalsafe/tree-spec';
|
|
3
3
|
import { applyTreeTemplate, autoLayoutTree, AUTOSAVE_STATUS, deleteNode, deleteTransitionsForChoice, END_NODE_ID, getNextSpawnPosition, getTransition, GRAPH_SELECTION_KIND, moveChoiceInTree, moveNodeChoice, patchChoiceEdgeHints, patchGraphEditorMeta, renameNodeChoiceId, safeUUID, upsertTransition, } from '@signalsafe/tree-spec-editor-core';
|
|
4
|
-
import { useEditorAdapter } from './useEditorAdapter';
|
|
5
|
-
import { useEditorAutosave } from './useEditorAutosave';
|
|
6
|
-
import { useEditorHistory } from './useEditorHistory';
|
|
7
|
-
import { useEditorSelection } from './useEditorSelection';
|
|
8
|
-
import { dispatchEditorKeyboardShortcut, resolveEditorKeyboardShortcutAction } from './keyboardShortcutDispatch';
|
|
4
|
+
import { useEditorAdapter } from './useEditorAdapter.js';
|
|
5
|
+
import { useEditorAutosave } from './useEditorAutosave.js';
|
|
6
|
+
import { useEditorHistory } from './useEditorHistory.js';
|
|
7
|
+
import { useEditorSelection } from './useEditorSelection.js';
|
|
8
|
+
import { dispatchEditorKeyboardShortcut, resolveEditorKeyboardShortcutAction } from './keyboardShortcutDispatch.js';
|
|
9
9
|
const DEFAULT_AUTOSAVE_DEBOUNCE_MS = 2500;
|
|
10
10
|
function isTextFieldTarget(target) {
|
|
11
11
|
const tag = target instanceof HTMLElement ? target.tagName.toLowerCase() : '';
|
package/dist/index.d.ts
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* UI shells layer on top of this package; routing is host-injected via hook
|
|
11
11
|
* callbacks.
|
|
12
12
|
*/
|
|
13
|
-
export { default } from './TreeSpecGraphEditor';
|
|
14
|
-
export type { TreeSpecGraphEditorProps } from './TreeSpecGraphEditor';
|
|
15
|
-
export { useTreeSpecEditor } from './hooks/useTreeSpecEditor';
|
|
16
|
-
export type { AdapterValidationIssue, GraphEditorVersionInfo, TreeSpecEditorAdapter, UseTreeSpecEditorActions, UseTreeSpecEditorOptions, UseTreeSpecEditorResult, UseTreeSpecEditorState, } from './hooks/types';
|
|
13
|
+
export { default } from './TreeSpecGraphEditor.js';
|
|
14
|
+
export type { TreeSpecGraphEditorProps } from './TreeSpecGraphEditor.js';
|
|
15
|
+
export { useTreeSpecEditor } from './hooks/useTreeSpecEditor.js';
|
|
16
|
+
export type { AdapterValidationIssue, GraphEditorVersionInfo, TreeSpecEditorAdapter, UseTreeSpecEditorActions, UseTreeSpecEditorOptions, UseTreeSpecEditorResult, UseTreeSpecEditorState, } from './hooks/types.js';
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
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"}
|
package/dist/index.js
CHANGED
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
* UI shells layer on top of this package; routing is host-injected via hook
|
|
11
11
|
* callbacks.
|
|
12
12
|
*/
|
|
13
|
-
export { default } from './TreeSpecGraphEditor';
|
|
14
|
-
export { useTreeSpecEditor } from './hooks/useTreeSpecEditor';
|
|
13
|
+
export { default } from './TreeSpecGraphEditor.js';
|
|
14
|
+
export { useTreeSpecEditor } from './hooks/useTreeSpecEditor.js';
|
|
@@ -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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Handle, Position } from 'reactflow';
|
|
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';
|
|
4
|
-
import { useGraphEditorCanvas } from '../GraphEditorCanvasContext';
|
|
5
|
-
import { joinClasses } from '../
|
|
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
|
+
import { useGraphEditorCanvas } from '../GraphEditorCanvasContext.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('
|
|
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,5 +1,5 @@
|
|
|
1
1
|
import { type NodeProps } from 'reactflow';
|
|
2
|
-
import type { PromptNodeData } from './types';
|
|
2
|
+
import type { PromptNodeData } from './types.js';
|
|
3
3
|
type PromptNodeProps = Readonly<NodeProps<PromptNodeData>>;
|
|
4
4
|
export declare function PromptNode({ data, selected, id }: PromptNodeProps): import("react").JSX.Element;
|
|
5
5
|
export {};
|
|
@@ -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,13 +2,13 @@ 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,
|
|
6
|
-
import { getPromptNodeBorderClass } from '../canvas/edgeStyle';
|
|
7
|
-
import { useGraphEditorCanvas } from '../GraphEditorCanvasContext';
|
|
8
|
-
import { joinClasses } from '../
|
|
9
|
-
import { PromptNodeChoicesList } from './PromptNodeChoicesList';
|
|
10
|
-
import { PromptNodeHeader } from './PromptNodeHeader';
|
|
11
|
-
import { PromptNodeToolbar } from './PromptNodeToolbar';
|
|
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
|
+
import { getPromptNodeBorderClass } from '../canvas/edgeStyle.js';
|
|
7
|
+
import { useGraphEditorCanvas } from '../GraphEditorCanvasContext.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
|
+
import { PromptNodeChoicesList } from './PromptNodeChoicesList.js';
|
|
10
|
+
import { PromptNodeHeader } from './PromptNodeHeader.js';
|
|
11
|
+
import { PromptNodeToolbar } from './PromptNodeToolbar.js';
|
|
12
12
|
export function PromptNode({ data, selected, id }) {
|
|
13
13
|
const n = data.node;
|
|
14
14
|
const choices = n.choices ?? [];
|
|
@@ -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,5 +1,5 @@
|
|
|
1
1
|
import { type EditorChoice } from '@signalsafe/tree-spec-editor-core';
|
|
2
|
-
import { type GraphEditorCanvasContextValue } from '../GraphEditorCanvasContext';
|
|
2
|
+
import { type GraphEditorCanvasContextValue } from '../GraphEditorCanvasContext.js';
|
|
3
3
|
export declare function PromptNodeChoicesList({ nodeId, choices, focusChoiceId, choiceTextClass, readOnly, choiceDrag, choiceDropTarget, onChoiceDragOver, onChoiceDrop, }: Readonly<{
|
|
4
4
|
nodeId: string;
|
|
5
5
|
choices: EditorChoice[];
|
|
@@ -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,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { CHOICE_DROP_APPEND_CLASS, CHOICE_DROP_TARGET_CLASS, } from '../canvas/constants';
|
|
3
|
-
import { joinClasses } from '../
|
|
4
|
-
import { ChoiceCanvasRow } from './ChoiceCanvasRow';
|
|
2
|
+
import { CHOICE_DROP_APPEND_CLASS, CHOICE_DROP_TARGET_CLASS, } from '../canvas/constants.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
|
+
import { ChoiceCanvasRow } from './ChoiceCanvasRow.js';
|
|
5
5
|
export function PromptNodeChoicesList({ nodeId, choices, focusChoiceId, choiceTextClass, readOnly, choiceDrag, choiceDropTarget, onChoiceDragOver, onChoiceDrop, }) {
|
|
6
6
|
const handleListDragOver = (event) => {
|
|
7
7
|
if (readOnly || !choiceDrag)
|
|
@@ -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,5 +1,5 @@
|
|
|
1
1
|
import { getEditorHints, type EditorNode } from '@signalsafe/tree-spec-editor-core';
|
|
2
|
-
import type { PromptNodeData } from './types';
|
|
2
|
+
import type { PromptNodeData } from './types.js';
|
|
3
3
|
export declare function PromptNodeHeader({ node, data, editor, locked, readOnly, }: Readonly<{
|
|
4
4
|
node: EditorNode;
|
|
5
5
|
data: PromptNodeData;
|
|
@@ -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
|
-
import { NODE_DRAG_HANDLE_CLASS } from '../canvas/constants';
|
|
3
|
-
import {
|
|
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';
|
|
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",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"typescript",
|
|
24
24
|
"signalsafe"
|
|
25
25
|
],
|
|
26
|
-
"sideEffects":
|
|
26
|
+
"sideEffects": [
|
|
27
|
+
"**/*.css"
|
|
28
|
+
],
|
|
27
29
|
"main": "./dist/index.js",
|
|
28
30
|
"types": "./dist/index.d.ts",
|
|
29
31
|
"exports": {
|
|
@@ -34,28 +36,33 @@
|
|
|
34
36
|
}
|
|
35
37
|
},
|
|
36
38
|
"files": [
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE",
|
|
42
|
+
"docs"
|
|
40
43
|
],
|
|
41
44
|
"engines": {
|
|
42
|
-
"node": ">=
|
|
45
|
+
"node": ">=22.12.0"
|
|
43
46
|
},
|
|
47
|
+
"packageManager": "yarn@1.22.22",
|
|
44
48
|
"publishConfig": {
|
|
45
49
|
"access": "public"
|
|
46
50
|
},
|
|
47
51
|
"scripts": {
|
|
48
52
|
"build": "tsc -p tsconfig.build.json",
|
|
53
|
+
"lint": "yarn typecheck",
|
|
49
54
|
"typecheck": "tsc --noEmit",
|
|
50
55
|
"pack:local": "npm pack --pack-destination ../../dist/reusable-npm",
|
|
56
|
+
"smoke:package": "node scripts/smoke-package.mjs",
|
|
51
57
|
"prepublishOnly": "npm run build",
|
|
52
58
|
"prepare": "npm run build",
|
|
53
59
|
"test": "vitest run",
|
|
60
|
+
"test:coverage": "yarn test --coverage",
|
|
54
61
|
"test:monorepo": "cd ../../frontend && yarn vitest run --config vitest.tree-spec-editor-react.config.ts"
|
|
55
62
|
},
|
|
56
63
|
"dependencies": {
|
|
57
|
-
"@signalsafe/tree-spec": "^0.3.
|
|
58
|
-
"@signalsafe/tree-spec-editor-core": "^0.1.
|
|
64
|
+
"@signalsafe/tree-spec": "^0.3.3",
|
|
65
|
+
"@signalsafe/tree-spec-editor-core": "^0.1.4"
|
|
59
66
|
},
|
|
60
67
|
"peerDependencies": {
|
|
61
68
|
"react": "^18.0.0",
|
|
@@ -71,6 +78,7 @@
|
|
|
71
78
|
"react-test-renderer": "^18.3.1",
|
|
72
79
|
"reactflow": "^11.11.4",
|
|
73
80
|
"typescript": "^5.4.2",
|
|
81
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
74
82
|
"vitest": "^3.2.4"
|
|
75
83
|
}
|
|
76
84
|
}
|