@signalsafe/tree-spec-editor 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.
Files changed (56) hide show
  1. package/README.md +657 -2
  2. package/dist/index.d.ts +48 -7
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +39 -5
  5. package/dist/lib/PanelHeaderCollapseCarets.d.ts +10 -0
  6. package/dist/lib/PanelHeaderCollapseCarets.d.ts.map +1 -0
  7. package/dist/lib/PanelHeaderCollapseCarets.js +13 -0
  8. package/dist/lib/buildDefaultToolbarSpec.d.ts +157 -0
  9. package/dist/lib/buildDefaultToolbarSpec.d.ts.map +1 -0
  10. package/dist/lib/buildDefaultToolbarSpec.js +202 -0
  11. package/dist/lib/panelHelpers.d.ts +9 -0
  12. package/dist/lib/panelHelpers.d.ts.map +1 -0
  13. package/dist/lib/panelHelpers.js +22 -0
  14. package/dist/modals/AuditLogModal.d.ts +21 -0
  15. package/dist/modals/AuditLogModal.d.ts.map +1 -0
  16. package/dist/modals/AuditLogModal.js +23 -0
  17. package/dist/modals/DraftHistoryModal.d.ts +34 -0
  18. package/dist/modals/DraftHistoryModal.d.ts.map +1 -0
  19. package/dist/modals/DraftHistoryModal.js +27 -0
  20. package/dist/modals/PublishReviewModal.d.ts +37 -0
  21. package/dist/modals/PublishReviewModal.d.ts.map +1 -0
  22. package/dist/modals/PublishReviewModal.js +25 -0
  23. package/dist/panels/AdvancedJsonPanel.d.ts +27 -0
  24. package/dist/panels/AdvancedJsonPanel.d.ts.map +1 -0
  25. package/dist/panels/AdvancedJsonPanel.js +11 -0
  26. package/dist/panels/GraphEditorInfoPanel.d.ts +20 -0
  27. package/dist/panels/GraphEditorInfoPanel.d.ts.map +1 -0
  28. package/dist/panels/GraphEditorInfoPanel.js +25 -0
  29. package/dist/panels/InspectorPanel.d.ts +79 -0
  30. package/dist/panels/InspectorPanel.d.ts.map +1 -0
  31. package/dist/panels/InspectorPanel.js +63 -0
  32. package/dist/panels/IssuesPanel.d.ts +33 -0
  33. package/dist/panels/IssuesPanel.d.ts.map +1 -0
  34. package/dist/panels/IssuesPanel.js +46 -0
  35. package/dist/panels/NodesPanel.d.ts +28 -0
  36. package/dist/panels/NodesPanel.d.ts.map +1 -0
  37. package/dist/panels/NodesPanel.js +56 -0
  38. package/dist/panels/SelectedEdgePanel.d.ts +18 -0
  39. package/dist/panels/SelectedEdgePanel.d.ts.map +1 -0
  40. package/dist/panels/SelectedEdgePanel.js +9 -0
  41. package/dist/panels/ToolbarPanel.d.ts +90 -0
  42. package/dist/panels/ToolbarPanel.d.ts.map +1 -0
  43. package/dist/panels/ToolbarPanel.js +59 -0
  44. package/package.json +7 -3
  45. package/dist/TreeSpecGraphEditor.d.ts +0 -16
  46. package/dist/TreeSpecGraphEditor.d.ts.map +0 -1
  47. package/dist/TreeSpecGraphEditor.js +0 -272
  48. package/dist/editorHelpers.d.ts +0 -16
  49. package/dist/editorHelpers.d.ts.map +0 -1
  50. package/dist/editorHelpers.js +0 -67
  51. package/dist/model.d.ts +0 -23
  52. package/dist/model.d.ts.map +0 -1
  53. package/dist/model.js +0 -1
  54. package/dist/treeLayout.d.ts +0 -11
  55. package/dist/treeLayout.d.ts.map +0 -1
  56. package/dist/treeLayout.js +0 -63
package/dist/index.d.ts CHANGED
@@ -1,12 +1,53 @@
1
1
  /**
2
2
  * @packageDocumentation
3
- * TreeSpec graph editor (React Flow) and authoring helpers. No API, routing, or simulator runtime.
3
+ * React + Bootstrap implementation of the TreeSpec graph editor.
4
+ *
5
+ * Layered architecture:
6
+ * - `@signalsafe/tree-spec` — wire contract (pure TS, no UI).
7
+ * - `@signalsafe/tree-spec-editor-core` — framework-agnostic model, helpers,
8
+ * and constants (no React, no DOM).
9
+ * - `@signalsafe/tree-spec-editor-react` — headless React: React Flow canvas
10
+ * (no UI library).
11
+ * - **`@signalsafe/tree-spec-editor`** (this package) — React + Bootstrap shell:
12
+ * sidebar panels, modals, toolbar, and the Bootstrap severity badge helper.
13
+ *
14
+ * The framework-agnostic surface from `-core` and the canvas from `-react`
15
+ * are re-exported from this barrel for consumer convenience. Hosts targeting
16
+ * alternative UI libraries (e.g. Material) should consume `-react` plus their
17
+ * own UI shell instead.
18
+ *
19
+ * Source layout:
20
+ * - `panels/` — sidebar / toolbar / inspector presentational components
21
+ * - `modals/` — authoring-flow dialogs
22
+ * - `lib/` — UI-flavored helpers (Bootstrap severity badge classes)
4
23
  */
5
- export { default } from './TreeSpecGraphEditor';
6
- export type { TreeSpecGraphEditorProps } from './TreeSpecGraphEditor';
7
- export { END_NODE_ID } from './model';
8
- export type { EditorChoice, EditorNode, EditorTransition, EditorTree, GraphEditorIssue, GraphSelection, ReactFlowEdgeChange, ReactFlowNodeChange, } from './model';
9
- export { safeUUID, getTransition, upsertTransition, deleteTransitionsForChoice, lintEditorTree, parsePydanticOutcomeErrors, TREE_SPEC_NODE_TYPE_PRESETS, } from './editorHelpers';
10
- export { autoLayoutTree, getNextSpawnPosition } from './treeLayout';
24
+ export { default } from '@signalsafe/tree-spec-editor-react';
25
+ export type { TreeSpecGraphEditorProps, GraphEditorVersionInfo } from '@signalsafe/tree-spec-editor-react';
26
+ export { default as IssuesPanel } from './panels/IssuesPanel';
27
+ export type { IssuesPanelProps } from './panels/IssuesPanel';
28
+ export { default as GraphEditorInfoPanel } from './panels/GraphEditorInfoPanel';
29
+ export type { GraphEditorInfoPanelProps } from './panels/GraphEditorInfoPanel';
30
+ export { default as NodesPanel } from './panels/NodesPanel';
31
+ export type { NodesPanelProps } from './panels/NodesPanel';
32
+ export { default as AdvancedJsonPanel } from './panels/AdvancedJsonPanel';
33
+ export type { AdvancedJsonPanelProps } from './panels/AdvancedJsonPanel';
34
+ export { default as InspectorPanel, DEFAULT_OUTCOME_OPTIONS } from './panels/InspectorPanel';
35
+ export type { InspectorPanelProps, InspectorNodeRenderContext, InspectorChoiceRenderContext, } from './panels/InspectorPanel';
36
+ export { default as SelectedEdgePanel } from './panels/SelectedEdgePanel';
37
+ export type { SelectedEdgePanelProps } from './panels/SelectedEdgePanel';
38
+ export { default as PublishReviewModal } from './modals/PublishReviewModal';
39
+ export type { PublishReviewModalProps } from './modals/PublishReviewModal';
40
+ export { default as DraftHistoryModal } from './modals/DraftHistoryModal';
41
+ export type { DraftHistoryModalProps } from './modals/DraftHistoryModal';
42
+ export { default as AuditLogModal } from './modals/AuditLogModal';
43
+ export type { AuditLogModalProps } from './modals/AuditLogModal';
44
+ export { default as ToolbarPanel, TOOLBAR_ITEM_KIND } from './panels/ToolbarPanel';
45
+ export type { ToolbarPanelProps, ToolbarItem, ToolbarItemKind, ToolbarButtonItem, ToolbarDropdownItem, ToolbarDropdownEntry, ToolbarBadgeItem, ToolbarTextItem, ToolbarCustomItem, ToolbarVariant, } from './panels/ToolbarPanel';
46
+ export { getIssueSeverityBadgeClass } from './lib/panelHelpers';
47
+ export { default as PanelHeaderCollapseCarets } from './lib/PanelHeaderCollapseCarets';
48
+ export { buildDefaultToolbarSpec } from './lib/buildDefaultToolbarSpec';
49
+ export type { BuildDefaultToolbarSpecOptions, DefaultToolbarActions, DefaultToolbarCapabilities, DefaultToolbarLabels, DefaultToolbarNodeType, DefaultToolbarState, DefaultToolbarTemplate, } from './lib/buildDefaultToolbarSpec';
50
+ export { END_NODE_ID, GRAPH_SELECTION_KIND, safeUUID, getTransition, upsertTransition, deleteTransitionsForChoice, lintEditorTree, parsePydanticOutcomeErrors, shouldQueueInitialValidation, TREE_SPEC_NODE_TYPE_PRESETS, autoLayoutTree, getNextSpawnPosition, getAutosaveStatusLabel, AUTOSAVE_STATUS, getKeyboardShortcutAction, KEYBOARD_SHORTCUT_ACTION, applyTreeTemplate, computeTreeDiffSummary, deleteNode, duplicateNode, buildStableEntries, } from '@signalsafe/tree-spec-editor-core';
51
+ export type { EditorChoice, EditorNode, EditorTransition, EditorTree, GraphEditorIssue, GraphSelection, GraphSelectionKind, ReactFlowEdgeChange, ReactFlowNodeChange, TreeSpecAuditEventItem, TreeSpecSnapshotItem, TreeSpecNodeTypePreset, AutosaveStatus, KeyboardShortcutAction, KeyboardShortcutParams, ApplyTreeTemplateOptions, TreeDiffSummary, TreeTemplateNodeSpec, TreeTemplateSpec, TreeTemplateTransitionSpec, } from '@signalsafe/tree-spec-editor-core';
11
52
  export type { TreeSpecIssue, TreeSpecWire } from '@signalsafe/tree-spec';
12
53
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,YAAY,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,YAAY,EACR,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,mBAAmB,GACtB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACH,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,0BAA0B,EAC1B,cAAc,EACd,0BAA0B,EAC1B,2BAA2B,GAC9B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,8 +1,42 @@
1
1
  /**
2
2
  * @packageDocumentation
3
- * TreeSpec graph editor (React Flow) and authoring helpers. No API, routing, or simulator runtime.
3
+ * React + Bootstrap implementation of the TreeSpec graph editor.
4
+ *
5
+ * Layered architecture:
6
+ * - `@signalsafe/tree-spec` — wire contract (pure TS, no UI).
7
+ * - `@signalsafe/tree-spec-editor-core` — framework-agnostic model, helpers,
8
+ * and constants (no React, no DOM).
9
+ * - `@signalsafe/tree-spec-editor-react` — headless React: React Flow canvas
10
+ * (no UI library).
11
+ * - **`@signalsafe/tree-spec-editor`** (this package) — React + Bootstrap shell:
12
+ * sidebar panels, modals, toolbar, and the Bootstrap severity badge helper.
13
+ *
14
+ * The framework-agnostic surface from `-core` and the canvas from `-react`
15
+ * are re-exported from this barrel for consumer convenience. Hosts targeting
16
+ * alternative UI libraries (e.g. Material) should consume `-react` plus their
17
+ * own UI shell instead.
18
+ *
19
+ * Source layout:
20
+ * - `panels/` — sidebar / toolbar / inspector presentational components
21
+ * - `modals/` — authoring-flow dialogs
22
+ * - `lib/` — UI-flavored helpers (Bootstrap severity badge classes)
4
23
  */
5
- export { default } from './TreeSpecGraphEditor';
6
- export { END_NODE_ID } from './model';
7
- export { safeUUID, getTransition, upsertTransition, deleteTransitionsForChoice, lintEditorTree, parsePydanticOutcomeErrors, TREE_SPEC_NODE_TYPE_PRESETS, } from './editorHelpers';
8
- export { autoLayoutTree, getNextSpawnPosition } from './treeLayout';
24
+ export { default } from '@signalsafe/tree-spec-editor-react';
25
+ export { default as IssuesPanel } from './panels/IssuesPanel';
26
+ export { default as GraphEditorInfoPanel } from './panels/GraphEditorInfoPanel';
27
+ export { default as NodesPanel } from './panels/NodesPanel';
28
+ export { default as AdvancedJsonPanel } from './panels/AdvancedJsonPanel';
29
+ export { default as InspectorPanel, DEFAULT_OUTCOME_OPTIONS } from './panels/InspectorPanel';
30
+ export { default as SelectedEdgePanel } from './panels/SelectedEdgePanel';
31
+ export { default as PublishReviewModal } from './modals/PublishReviewModal';
32
+ export { default as DraftHistoryModal } from './modals/DraftHistoryModal';
33
+ export { default as AuditLogModal } from './modals/AuditLogModal';
34
+ export { default as ToolbarPanel, TOOLBAR_ITEM_KIND } from './panels/ToolbarPanel';
35
+ export { getIssueSeverityBadgeClass } from './lib/panelHelpers';
36
+ export { default as PanelHeaderCollapseCarets } from './lib/PanelHeaderCollapseCarets';
37
+ export { buildDefaultToolbarSpec } from './lib/buildDefaultToolbarSpec';
38
+ /* ------------------------------------------------------------------------- */
39
+ /* Framework-agnostic re-exports from @signalsafe/tree-spec-editor-core. */
40
+ /* Hosts may consume these directly from `-core` to skip the React surface. */
41
+ /* ------------------------------------------------------------------------- */
42
+ export { END_NODE_ID, GRAPH_SELECTION_KIND, safeUUID, getTransition, upsertTransition, deleteTransitionsForChoice, lintEditorTree, parsePydanticOutcomeErrors, shouldQueueInitialValidation, TREE_SPEC_NODE_TYPE_PRESETS, autoLayoutTree, getNextSpawnPosition, getAutosaveStatusLabel, AUTOSAVE_STATUS, getKeyboardShortcutAction, KEYBOARD_SHORTCUT_ACTION, applyTreeTemplate, computeTreeDiffSummary, deleteNode, duplicateNode, buildStableEntries, } from '@signalsafe/tree-spec-editor-core';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Single toggle next to the panel title: **caret-up** while expanded (click to hide body),
3
+ * **caret-down** while collapsed (click to show). Avoids relying on Bootstrap’s `.collapse`
4
+ * transition/CSS, which can fail to hide content in some host bundles.
5
+ */
6
+ export default function PanelHeaderCollapseCarets({ expanded, onToggle, }: Readonly<{
7
+ expanded: boolean;
8
+ onToggle: () => void;
9
+ }>): import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=PanelHeaderCollapseCarets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelHeaderCollapseCarets.d.ts","sourceRoot":"","sources":["../../src/lib/PanelHeaderCollapseCarets.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAAC,EAC9C,QAAQ,EACR,QAAQ,GACX,EAAE,QAAQ,CAAC;IACR,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC,2CAiBD"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Single toggle next to the panel title: **caret-up** while expanded (click to hide body),
4
+ * **caret-down** while collapsed (click to show). Avoids relying on Bootstrap’s `.collapse`
5
+ * transition/CSS, which can fail to hide content in some host bundles.
6
+ */
7
+ export default function PanelHeaderCollapseCarets({ expanded, onToggle, }) {
8
+ return (_jsx("button", { type: "button", className: "btn btn-link btn-sm py-1 px-2 lh-1 text-body-secondary text-decoration-none ms-1 align-middle", "aria-expanded": expanded, "aria-label": expanded ? 'Collapse panel' : 'Expand panel', title: expanded ? 'Collapse' : 'Expand', onClick: (e) => {
9
+ e.preventDefault();
10
+ e.stopPropagation();
11
+ onToggle();
12
+ }, children: _jsx("i", { className: `bi ${expanded ? 'bi-caret-up' : 'bi-caret-down'}`, "aria-hidden": true }) }));
13
+ }
@@ -0,0 +1,157 @@
1
+ import type { ReactNode } from 'react';
2
+ import { AUTOSAVE_STATUS, type AutosaveStatus, type EditorNode, type TreeTemplateSpec } from '@signalsafe/tree-spec-editor-core';
3
+ import { type ToolbarItem } from '../panels/ToolbarPanel';
4
+ /**
5
+ * Description of a node type the host wants in the "+ Add" dropdown, or a
6
+ * visual divider between groups.
7
+ *
8
+ * Each entry encodes the host's vocabulary: the package never assumes a fixed
9
+ * set of node types. When a label is omitted, the type id is title-cased. Pass
10
+ * `{ divider: true }` to insert a `<Dropdown.Divider />`.
11
+ */
12
+ export interface DefaultToolbarNodeType {
13
+ /** Node type id (matches `EditorNode.type`). Required unless `divider: true`. */
14
+ type?: string;
15
+ /** Optional display label; defaults to the title-cased type id. */
16
+ label?: ReactNode;
17
+ /** Optional patch applied to the spawned node (e.g. starter prompt). */
18
+ patch?: Partial<EditorNode>;
19
+ /** Optional stable id; defaults to `add-<type>`. */
20
+ id?: string;
21
+ /** Render this entry as a visual divider. Ignores `type` / `label` / `patch`. */
22
+ divider?: boolean;
23
+ }
24
+ /** Description of a starter template the host wants in the "Templates" dropdown. */
25
+ export interface DefaultToolbarTemplate {
26
+ /** Template id used as the React key. */
27
+ id: string;
28
+ /** Display label in the dropdown. */
29
+ label: ReactNode;
30
+ /** Template spec consumed by `actions.insertTemplate`. */
31
+ spec: TreeTemplateSpec;
32
+ }
33
+ /**
34
+ * Minimal subset of {@link UseTreeSpecEditorState} consumed by
35
+ * {@link buildDefaultToolbarSpec}. Hosts pass the state object returned by
36
+ * `useTreeSpecEditor` (which satisfies this contract structurally) — see the
37
+ * `-react` package for the full state type.
38
+ */
39
+ export interface DefaultToolbarState {
40
+ isPublished: boolean;
41
+ saving: boolean;
42
+ publishing: boolean;
43
+ creatingSnapshot: boolean;
44
+ cloning: boolean;
45
+ canPublish: boolean;
46
+ hasTree: boolean;
47
+ autosaveStatus: AutosaveStatus;
48
+ }
49
+ /**
50
+ * Minimal subset of {@link UseTreeSpecEditorActions} consumed by
51
+ * {@link buildDefaultToolbarSpec}.
52
+ */
53
+ export interface DefaultToolbarActions {
54
+ addNodeOfType: (type: string, patch?: Partial<EditorNode>) => unknown;
55
+ insertTemplate: (spec: TreeTemplateSpec) => void;
56
+ triggerResetView: () => void;
57
+ autoLayout: () => void;
58
+ validate: (...args: unknown[]) => unknown;
59
+ saveDraft: (...args: unknown[]) => unknown;
60
+ setShowDraftHistory: (next: boolean) => void;
61
+ setShowAudit: (next: boolean) => void;
62
+ createSnapshot: (...args: unknown[]) => unknown;
63
+ cloneToDraft: (...args: unknown[]) => unknown;
64
+ setShowPublishModal: (next: boolean) => void;
65
+ }
66
+ /**
67
+ * Adapter-capability flags consumed by {@link buildDefaultToolbarSpec}.
68
+ * Hosts pass `Boolean(adapter.validate)` (etc.) so the builder can gate the
69
+ * Validate / Draft history / Audit / Snapshot / Clone / Publish buttons.
70
+ */
71
+ export interface DefaultToolbarCapabilities {
72
+ /** Show the Validate button. */
73
+ canValidate?: boolean;
74
+ /** Show the Draft history button. */
75
+ canListSnapshots?: boolean;
76
+ /** Show the Audit button. */
77
+ canListAudit?: boolean;
78
+ /** Show the Snapshot button. */
79
+ canCreateSnapshot?: boolean;
80
+ /** Show the Clone to Draft button. */
81
+ canCloneToDraft?: boolean;
82
+ /** Show the Publish button. */
83
+ canPublish?: boolean;
84
+ }
85
+ /** Optional labels for the default toolbar; defaults are in en-US. */
86
+ export interface DefaultToolbarLabels {
87
+ add?: ReactNode;
88
+ templates?: ReactNode;
89
+ resetView?: ReactNode;
90
+ autoLayout?: ReactNode;
91
+ validate?: ReactNode;
92
+ draftHistory?: ReactNode;
93
+ audit?: ReactNode;
94
+ snapshot?: ReactNode;
95
+ snapshotInFlight?: ReactNode;
96
+ cloneToDraft?: ReactNode;
97
+ cloneInFlight?: ReactNode;
98
+ saveDraft?: ReactNode;
99
+ saveDraftInFlight?: ReactNode;
100
+ publish?: ReactNode;
101
+ publishInFlight?: ReactNode;
102
+ statusPublished?: ReactNode;
103
+ statusDraft?: ReactNode;
104
+ }
105
+ /** Options for {@link buildDefaultToolbarSpec}. */
106
+ export interface BuildDefaultToolbarSpecOptions {
107
+ /** Editor state from `useTreeSpecEditor` (or a structurally compatible source). */
108
+ state: DefaultToolbarState;
109
+ /** Editor actions from `useTreeSpecEditor`. */
110
+ actions: DefaultToolbarActions;
111
+ /** Adapter-capability flags. Buttons are hidden when their flag is false. */
112
+ capabilities?: DefaultToolbarCapabilities;
113
+ /** Node types the host wants in the "+ Add" dropdown. */
114
+ nodeTypes?: DefaultToolbarNodeType[];
115
+ /** Starter templates the host wants in the "Templates" dropdown. */
116
+ templates?: DefaultToolbarTemplate[];
117
+ /**
118
+ * Optional slot rendered before everything else. Hosts use this for a
119
+ * router-aware back link (e.g. `() => <Link to=...>Back</Link>`).
120
+ */
121
+ backSlot?: {
122
+ id?: string;
123
+ render: () => ReactNode;
124
+ };
125
+ /**
126
+ * Optional Preview action. When supplied, a `Preview` button is appended
127
+ * after the status badge.
128
+ */
129
+ preview?: {
130
+ onClick: () => void;
131
+ disabled?: boolean;
132
+ label?: ReactNode;
133
+ };
134
+ /**
135
+ * When `false`, the published/draft badge and autosave status text are not
136
+ * appended to the toolbar (hosts can show them elsewhere, e.g. an info panel).
137
+ * Default: `true`.
138
+ */
139
+ includePublishedAutosaveStatus?: boolean;
140
+ /** Items appended after the autosave-status text (e.g. project-specific badges). */
141
+ extraItems?: ToolbarItem[];
142
+ /** Override the default English labels. */
143
+ labels?: DefaultToolbarLabels;
144
+ }
145
+ /**
146
+ * Build the standard TreeSpec editor toolbar — Reset view / Auto layout /
147
+ * Validate / Draft history / Audit / Snapshot / Clone to Draft / Save Draft /
148
+ * Publish / (optional) status badge + autosave label — and inject host-supplied
149
+ * vocabulary (node types, templates, back-link slot, preview action).
150
+ *
151
+ * This is the opinionated SignalSafe + Bootstrap toolbar layout. Hosts using a
152
+ * different UI library should write their own builder; the
153
+ * {@link useTreeSpecEditor} hook does not depend on this helper.
154
+ */
155
+ export declare function buildDefaultToolbarSpec(options: BuildDefaultToolbarSpecOptions): ToolbarItem[];
156
+ export { AUTOSAVE_STATUS };
157
+ //# sourceMappingURL=buildDefaultToolbarSpec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildDefaultToolbarSpec.d.ts","sourceRoot":"","sources":["../../src/lib/buildDefaultToolbarSpec.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EACH,eAAe,EAEf,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACxB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAGH,KAAK,WAAW,EACnB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAsB;IACnC,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5B,oDAAoD;IACpD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACnC,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,qCAAqC;IACrC,KAAK,EAAE,SAAS,CAAC;IACjB,0DAA0D;IAC1D,IAAI,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IAClC,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC;IACtE,cAAc,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACjD,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAC1C,SAAS,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAC3C,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,cAAc,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAChD,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAC9C,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAChD;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACvC,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qCAAqC;IACrC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6BAA6B;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gCAAgC;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,sCAAsC;IACtC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+BAA+B;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,sEAAsE;AACtE,MAAM,WAAW,oBAAoB;IACjC,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,SAAS,CAAC;CAC3B;AAsBD,mDAAmD;AACnD,MAAM,WAAW,8BAA8B;IAC3C,mFAAmF;IACnF,KAAK,EAAE,mBAAmB,CAAC;IAC3B,+CAA+C;IAC/C,OAAO,EAAE,qBAAqB,CAAC;IAC/B,6EAA6E;IAC7E,YAAY,CAAC,EAAE,0BAA0B,CAAC;IAC1C,yDAAyD;IACzD,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACrC,oEAAoE;IACpE,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,SAAS,CAAA;KAAE,CAAC;IACpD;;;OAGG;IACH,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC;IACzE;;;;OAIG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC,oFAAoF;IACpF,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC;IAC3B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,oBAAoB,CAAC;CACjC;AAUD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,8BAA8B,GAAG,WAAW,EAAE,CA4L9F;AAGD,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,202 @@
1
+ import { AUTOSAVE_STATUS, getAutosaveStatusLabel, } from '@signalsafe/tree-spec-editor-core';
2
+ import { TOOLBAR_ITEM_KIND, } from '../panels/ToolbarPanel';
3
+ const DEFAULT_LABELS = {
4
+ add: '+ Add',
5
+ templates: 'Templates',
6
+ resetView: 'Reset view',
7
+ autoLayout: 'Auto layout',
8
+ validate: 'Validate',
9
+ draftHistory: 'Draft history',
10
+ audit: 'Audit',
11
+ snapshot: 'Snapshot',
12
+ snapshotInFlight: 'Creating…',
13
+ cloneToDraft: 'Clone to Draft',
14
+ cloneInFlight: 'Cloning…',
15
+ saveDraft: 'Save Draft',
16
+ saveDraftInFlight: 'Saving…',
17
+ publish: 'Publish',
18
+ publishInFlight: 'Publishing…',
19
+ statusPublished: 'Published (read-only)',
20
+ statusDraft: 'Draft',
21
+ };
22
+ function titleCase(type) {
23
+ return type
24
+ .split(/[_-]/)
25
+ .filter(Boolean)
26
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
27
+ .join(' ');
28
+ }
29
+ /**
30
+ * Build the standard TreeSpec editor toolbar — Reset view / Auto layout /
31
+ * Validate / Draft history / Audit / Snapshot / Clone to Draft / Save Draft /
32
+ * Publish / (optional) status badge + autosave label — and inject host-supplied
33
+ * vocabulary (node types, templates, back-link slot, preview action).
34
+ *
35
+ * This is the opinionated SignalSafe + Bootstrap toolbar layout. Hosts using a
36
+ * different UI library should write their own builder; the
37
+ * {@link useTreeSpecEditor} hook does not depend on this helper.
38
+ */
39
+ export function buildDefaultToolbarSpec(options) {
40
+ const { state, actions, capabilities = {}, nodeTypes = [], templates = [], backSlot, preview, extraItems = [], labels: labelOverrides, includePublishedAutosaveStatus = true, } = options;
41
+ const labels = { ...DEFAULT_LABELS, ...(labelOverrides ?? {}) };
42
+ const items = [];
43
+ if (backSlot) {
44
+ items.push({
45
+ kind: TOOLBAR_ITEM_KIND.CUSTOM,
46
+ id: backSlot.id ?? 'back',
47
+ render: backSlot.render,
48
+ });
49
+ }
50
+ if (nodeTypes.length > 0) {
51
+ const entries = nodeTypes
52
+ .map((nt, idx) => {
53
+ if (nt.divider) {
54
+ return { id: nt.id ?? `divider-${idx}`, label: '', divider: true };
55
+ }
56
+ if (!nt.type)
57
+ return null;
58
+ return {
59
+ id: nt.id ?? `add-${nt.type}`,
60
+ label: nt.label ?? titleCase(nt.type),
61
+ onClick: () => actions.addNodeOfType(nt.type, nt.patch),
62
+ disabled: state.isPublished,
63
+ };
64
+ })
65
+ .filter((e) => e !== null);
66
+ items.push({
67
+ kind: TOOLBAR_ITEM_KIND.DROPDOWN,
68
+ id: 'add',
69
+ label: labels.add,
70
+ disabled: state.isPublished,
71
+ entries,
72
+ });
73
+ }
74
+ if (templates.length > 0) {
75
+ const entries = templates.map((t) => ({
76
+ id: t.id,
77
+ label: t.label,
78
+ onClick: () => actions.insertTemplate(t.spec),
79
+ disabled: state.isPublished,
80
+ }));
81
+ items.push({
82
+ kind: TOOLBAR_ITEM_KIND.DROPDOWN,
83
+ id: 'templates',
84
+ label: labels.templates,
85
+ disabled: state.isPublished,
86
+ entries,
87
+ });
88
+ }
89
+ items.push({
90
+ kind: TOOLBAR_ITEM_KIND.BUTTON,
91
+ id: 'reset-view',
92
+ label: labels.resetView,
93
+ onClick: () => actions.triggerResetView(),
94
+ title: 'Reset view to fit graph',
95
+ });
96
+ items.push({
97
+ kind: TOOLBAR_ITEM_KIND.BUTTON,
98
+ id: 'auto-layout',
99
+ label: labels.autoLayout,
100
+ onClick: () => actions.autoLayout(),
101
+ disabled: state.isPublished,
102
+ });
103
+ if (capabilities.canValidate) {
104
+ items.push({
105
+ kind: TOOLBAR_ITEM_KIND.BUTTON,
106
+ id: 'validate',
107
+ label: labels.validate,
108
+ variant: 'outline-primary',
109
+ onClick: () => {
110
+ void actions.validate();
111
+ },
112
+ disabled: state.saving || state.publishing,
113
+ });
114
+ }
115
+ if (capabilities.canListSnapshots) {
116
+ items.push({
117
+ kind: TOOLBAR_ITEM_KIND.BUTTON,
118
+ id: 'draft-history',
119
+ label: labels.draftHistory,
120
+ onClick: () => actions.setShowDraftHistory(true),
121
+ disabled: state.isPublished,
122
+ });
123
+ }
124
+ if (capabilities.canListAudit) {
125
+ items.push({
126
+ kind: TOOLBAR_ITEM_KIND.BUTTON,
127
+ id: 'audit',
128
+ label: labels.audit,
129
+ onClick: () => actions.setShowAudit(true),
130
+ });
131
+ }
132
+ if (capabilities.canCreateSnapshot) {
133
+ items.push({
134
+ kind: TOOLBAR_ITEM_KIND.BUTTON,
135
+ id: 'snapshot',
136
+ label: state.creatingSnapshot ? labels.snapshotInFlight : labels.snapshot,
137
+ onClick: () => {
138
+ void actions.createSnapshot();
139
+ },
140
+ disabled: state.isPublished || !state.hasTree || state.creatingSnapshot,
141
+ });
142
+ }
143
+ if (capabilities.canCloneToDraft) {
144
+ items.push({
145
+ kind: TOOLBAR_ITEM_KIND.BUTTON,
146
+ id: 'clone-to-draft',
147
+ label: state.cloning ? labels.cloneInFlight : labels.cloneToDraft,
148
+ onClick: () => {
149
+ void actions.cloneToDraft();
150
+ },
151
+ disabled: state.cloning,
152
+ });
153
+ }
154
+ items.push({
155
+ kind: TOOLBAR_ITEM_KIND.BUTTON,
156
+ id: 'save-draft',
157
+ label: state.saving ? labels.saveDraftInFlight : labels.saveDraft,
158
+ variant: 'primary',
159
+ onClick: () => {
160
+ void actions.saveDraft();
161
+ },
162
+ disabled: state.isPublished || state.saving || state.publishing,
163
+ });
164
+ if (capabilities.canPublish) {
165
+ items.push({
166
+ kind: TOOLBAR_ITEM_KIND.BUTTON,
167
+ id: 'publish',
168
+ label: state.publishing ? labels.publishInFlight : labels.publish,
169
+ variant: 'success',
170
+ onClick: () => actions.setShowPublishModal(true),
171
+ disabled: state.isPublished || !state.canPublish || state.saving || state.publishing,
172
+ });
173
+ }
174
+ if (preview) {
175
+ items.push({
176
+ kind: TOOLBAR_ITEM_KIND.BUTTON,
177
+ id: 'preview',
178
+ label: preview.label ?? 'Preview',
179
+ variant: 'outline-dark',
180
+ onClick: preview.onClick,
181
+ disabled: preview.disabled ?? false,
182
+ });
183
+ }
184
+ if (includePublishedAutosaveStatus) {
185
+ items.push({
186
+ kind: TOOLBAR_ITEM_KIND.BADGE,
187
+ id: 'status',
188
+ label: state.isPublished ? labels.statusPublished : labels.statusDraft,
189
+ variant: state.isPublished ? 'success' : 'secondary',
190
+ });
191
+ items.push({
192
+ kind: TOOLBAR_ITEM_KIND.TEXT,
193
+ id: 'autosave',
194
+ content: getAutosaveStatusLabel(state.autosaveStatus),
195
+ });
196
+ }
197
+ if (extraItems.length > 0)
198
+ items.push(...extraItems);
199
+ return items;
200
+ }
201
+ // Re-exported for tests / hosts wiring the autosave label themselves.
202
+ export { AUTOSAVE_STATUS };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Map a TreeSpec issue severity to the matching Bootstrap badge classes.
3
+ *
4
+ * This lives in the Bootstrap-flavored package because the returned class
5
+ * names are Bootstrap-specific. Material / Angular shells expose their own
6
+ * equivalent helper.
7
+ */
8
+ export declare function getIssueSeverityBadgeClass(severity: string): string;
9
+ //# sourceMappingURL=panelHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panelHelpers.d.ts","sourceRoot":"","sources":["../../src/lib/panelHelpers.ts"],"names":[],"mappings":"AASA;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAInE"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Bootstrap-flavored helpers for the editor sidebar panels.
3
+ *
4
+ * Pure / framework-agnostic helpers (e.g. {@link buildStableEntries}) live in
5
+ * `@signalsafe/tree-spec-editor-core` and are re-exported from this package's
6
+ * barrel for consumer convenience.
7
+ */
8
+ import { TREE_SPEC_ISSUE_SEVERITY } from '@signalsafe/tree-spec';
9
+ /**
10
+ * Map a TreeSpec issue severity to the matching Bootstrap badge classes.
11
+ *
12
+ * This lives in the Bootstrap-flavored package because the returned class
13
+ * names are Bootstrap-specific. Material / Angular shells expose their own
14
+ * equivalent helper.
15
+ */
16
+ export function getIssueSeverityBadgeClass(severity) {
17
+ if (severity === TREE_SPEC_ISSUE_SEVERITY.ERROR)
18
+ return 'bg-danger';
19
+ if (severity === TREE_SPEC_ISSUE_SEVERITY.WARNING)
20
+ return 'bg-warning text-dark';
21
+ return 'bg-info';
22
+ }
@@ -0,0 +1,21 @@
1
+ import type { TreeSpecAuditEventItem } from '@signalsafe/tree-spec-editor-core';
2
+ export interface AuditLogModalProps {
3
+ show: boolean;
4
+ loadingAudit: boolean;
5
+ auditEvents: TreeSpecAuditEventItem[];
6
+ onClose: () => void;
7
+ /** Override the modal title (default "Audit log"). */
8
+ title?: string;
9
+ /** Override the muted subtitle below the title. */
10
+ subtitle?: string;
11
+ /** Override the loading state text. */
12
+ loadingText?: string;
13
+ /** Override the empty-state text (when there are zero events). */
14
+ emptyStateText?: string;
15
+ /** Override the "Actor ID:" label prefix shown for events that have an actor. */
16
+ actorLabel?: string;
17
+ /** Override the Close button label in the footer. */
18
+ closeLabel?: string;
19
+ }
20
+ export default function AuditLogModal({ show, loadingAudit, auditEvents, onClose, title, subtitle, loadingText, emptyStateText, actorLabel, closeLabel, }: Readonly<AuditLogModalProps>): import("react/jsx-runtime").JSX.Element | null;
21
+ //# sourceMappingURL=AuditLogModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuditLogModal.d.ts","sourceRoot":"","sources":["../../src/modals/AuditLogModal.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,sBAAsB,EAAE,CAAC;IACtC,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AASD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,OAAO,EACP,KAAqB,EACrB,QAA2B,EAC3B,WAAkC,EAClC,cAAyC,EACzC,UAAgC,EAChC,UAAgC,GACnC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,kDAwD9B"}
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, CloseButton } from 'react-bootstrap';
3
+ const DEFAULT_TITLE = 'Audit log';
4
+ const DEFAULT_SUBTITLE = 'Authoring actions for this tree_spec version.';
5
+ const DEFAULT_LOADING_TEXT = 'Loading…';
6
+ const DEFAULT_EMPTY_STATE_TEXT = 'No audit events yet.';
7
+ const DEFAULT_ACTOR_LABEL = 'Actor ID:';
8
+ const DEFAULT_CLOSE_LABEL = 'Close';
9
+ export default function AuditLogModal({ show, loadingAudit, auditEvents, onClose, title = DEFAULT_TITLE, subtitle = DEFAULT_SUBTITLE, loadingText = DEFAULT_LOADING_TEXT, emptyStateText = DEFAULT_EMPTY_STATE_TEXT, actorLabel = DEFAULT_ACTOR_LABEL, closeLabel = DEFAULT_CLOSE_LABEL, }) {
10
+ if (!show)
11
+ return null;
12
+ let auditContent;
13
+ if (loadingAudit) {
14
+ auditContent = _jsx("div", { className: "text-muted", children: loadingText });
15
+ }
16
+ else if (auditEvents.length === 0) {
17
+ auditContent = (_jsx("div", { className: "text-muted", children: _jsx("em", { children: emptyStateText }) }));
18
+ }
19
+ else {
20
+ auditContent = (_jsx("ul", { className: "list-unstyled mb-0 overflow-auto-max-h-400", children: auditEvents.map((e) => (_jsxs("li", { className: "border-bottom py-2", children: [_jsxs("div", { className: "d-flex justify-content-between align-items-start", children: [_jsx("span", { className: "badge bg-secondary me-2", children: e.action }), _jsx("span", { className: "text-muted font-size-12", children: new Date(e.created_at).toLocaleString() })] }), e.actor == null ? null : (_jsxs("span", { className: "text-muted font-size-12", children: [actorLabel, " ", e.actor] })), e.detail && Object.keys(e.detail).length > 0 ? (_jsx("pre", { className: "mb-0 mt-1 small text-muted font-size-11", children: JSON.stringify(e.detail) })) : null] }, e.id))) }));
21
+ }
22
+ return (_jsx("dialog", { className: "modal d-block modal-backdrop-dark", open: true, children: _jsx("div", { className: "modal-dialog modal-lg", children: _jsxs("div", { className: "modal-content", children: [_jsxs("div", { className: "modal-header", children: [_jsx("h5", { className: "modal-title", children: title }), _jsx(CloseButton, { "aria-label": "Close", onClick: onClose })] }), _jsxs("div", { className: "modal-body", children: [_jsx("p", { className: "text-muted font-size-13", children: subtitle }), auditContent] }), _jsx("div", { className: "modal-footer", children: _jsx(Button, { variant: "secondary", onClick: onClose, children: closeLabel }) })] }) }) }));
23
+ }
@@ -0,0 +1,34 @@
1
+ import type { EditorTree, TreeSpecSnapshotItem } from '@signalsafe/tree-spec-editor-core';
2
+ export interface DraftHistoryModalProps {
3
+ show: boolean;
4
+ loadingSnapshots: boolean;
5
+ snapshots: TreeSpecSnapshotItem[];
6
+ restoringSnapshotId: string | null;
7
+ creatingSnapshot: boolean;
8
+ tree: EditorTree | null;
9
+ onClose: () => void;
10
+ onCreateSnapshot: () => void;
11
+ onRestoreSnapshot: (snapshotId: string) => void;
12
+ /** Override the modal title (default "Draft history"). */
13
+ title?: string;
14
+ /** Override the muted subtitle below the title. */
15
+ subtitle?: string;
16
+ /** Override the "Snapshots (newest first)" caption above the list. */
17
+ listCaption?: string;
18
+ /** Override the "Create snapshot" button label. */
19
+ createSnapshotLabel?: string;
20
+ /** Override the "Creating\u2026" label while a create is in flight. */
21
+ creatingSnapshotLabel?: string;
22
+ /** Override the "Restore" button label. */
23
+ restoreLabel?: string;
24
+ /** Override the "Restoring\u2026" button label while a restore is in flight. */
25
+ restoringLabel?: string;
26
+ /** Override the loading state text. */
27
+ loadingText?: string;
28
+ /** Override the empty-state text (when there are zero snapshots). */
29
+ emptyStateText?: string;
30
+ /** Override the Close button label in the footer. */
31
+ closeLabel?: string;
32
+ }
33
+ export default function DraftHistoryModal({ show, loadingSnapshots, snapshots, restoringSnapshotId, creatingSnapshot, tree, onClose, onCreateSnapshot, onRestoreSnapshot, title, subtitle, listCaption, createSnapshotLabel, creatingSnapshotLabel, restoreLabel, restoringLabel, loadingText, emptyStateText, closeLabel, }: Readonly<DraftHistoryModalProps>): import("react/jsx-runtime").JSX.Element | null;
34
+ //# sourceMappingURL=DraftHistoryModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DraftHistoryModal.d.ts","sourceRoot":"","sources":["../../src/modals/DraftHistoryModal.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAE1F,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAEhD,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAcD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACtC,IAAI,EACJ,gBAAgB,EAChB,SAAS,EACT,mBAAmB,EACnB,gBAAgB,EAChB,IAAI,EACJ,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,KAAqB,EACrB,QAA2B,EAC3B,WAAkC,EAClC,mBAA0C,EAC1C,qBAA8C,EAC9C,YAAoC,EACpC,cAAwC,EACxC,WAAkC,EAClC,cAAyC,EACzC,UAAgC,GACnC,EAAE,QAAQ,CAAC,sBAAsB,CAAC,kDAuElC"}