@oh-just-another/react-ui 0.57.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 (186) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +21 -0
  3. package/README.md +54 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/bottom-sheet.d.ts +26 -0
  6. package/dist/bottom-sheet.d.ts.map +1 -0
  7. package/dist/bottom-sheet.js +87 -0
  8. package/dist/bottom-sheet.js.map +1 -0
  9. package/dist/button-group.d.ts +14 -0
  10. package/dist/button-group.d.ts.map +1 -0
  11. package/dist/button-group.js +3 -0
  12. package/dist/button-group.js.map +1 -0
  13. package/dist/color-palette.d.ts +34 -0
  14. package/dist/color-palette.d.ts.map +1 -0
  15. package/dist/color-palette.js +77 -0
  16. package/dist/color-palette.js.map +1 -0
  17. package/dist/color-swatch-picker.d.ts +29 -0
  18. package/dist/color-swatch-picker.d.ts.map +1 -0
  19. package/dist/color-swatch-picker.js +56 -0
  20. package/dist/color-swatch-picker.js.map +1 -0
  21. package/dist/command-palette.d.ts +13 -0
  22. package/dist/command-palette.d.ts.map +1 -0
  23. package/dist/command-palette.js +146 -0
  24. package/dist/command-palette.js.map +1 -0
  25. package/dist/comments-panel.d.ts +27 -0
  26. package/dist/comments-panel.d.ts.map +1 -0
  27. package/dist/comments-panel.js +139 -0
  28. package/dist/comments-panel.js.map +1 -0
  29. package/dist/constants.d.ts +112 -0
  30. package/dist/constants.d.ts.map +1 -0
  31. package/dist/constants.js +119 -0
  32. package/dist/constants.js.map +1 -0
  33. package/dist/context-menu-controller.d.ts +41 -0
  34. package/dist/context-menu-controller.d.ts.map +1 -0
  35. package/dist/context-menu-controller.js +26 -0
  36. package/dist/context-menu-controller.js.map +1 -0
  37. package/dist/context-menu.d.ts +53 -0
  38. package/dist/context-menu.d.ts.map +1 -0
  39. package/dist/context-menu.js +333 -0
  40. package/dist/context-menu.js.map +1 -0
  41. package/dist/context.d.ts +44 -0
  42. package/dist/context.d.ts.map +1 -0
  43. package/dist/context.js +95 -0
  44. package/dist/context.js.map +1 -0
  45. package/dist/diagram-bars.d.ts +21 -0
  46. package/dist/diagram-bars.d.ts.map +1 -0
  47. package/dist/diagram-bars.js +4 -0
  48. package/dist/diagram-bars.js.map +1 -0
  49. package/dist/diagram-canvas.d.ts +39 -0
  50. package/dist/diagram-canvas.d.ts.map +1 -0
  51. package/dist/diagram-canvas.js +9 -0
  52. package/dist/diagram-canvas.js.map +1 -0
  53. package/dist/diagram-root.d.ts +70 -0
  54. package/dist/diagram-root.d.ts.map +1 -0
  55. package/dist/diagram-root.js +180 -0
  56. package/dist/diagram-root.js.map +1 -0
  57. package/dist/diff-panel.d.ts +25 -0
  58. package/dist/diff-panel.d.ts.map +1 -0
  59. package/dist/diff-panel.js +77 -0
  60. package/dist/diff-panel.js.map +1 -0
  61. package/dist/edge-style-panel.d.ts +19 -0
  62. package/dist/edge-style-panel.d.ts.map +1 -0
  63. package/dist/edge-style-panel.js +120 -0
  64. package/dist/edge-style-panel.js.map +1 -0
  65. package/dist/frame-name-editor-overlay.d.ts +13 -0
  66. package/dist/frame-name-editor-overlay.d.ts.map +1 -0
  67. package/dist/frame-name-editor-overlay.js +84 -0
  68. package/dist/frame-name-editor-overlay.js.map +1 -0
  69. package/dist/frame-panel.d.ts +19 -0
  70. package/dist/frame-panel.d.ts.map +1 -0
  71. package/dist/frame-panel.js +66 -0
  72. package/dist/frame-panel.js.map +1 -0
  73. package/dist/help-button.d.ts +16 -0
  74. package/dist/help-button.d.ts.map +1 -0
  75. package/dist/help-button.js +14 -0
  76. package/dist/help-button.js.map +1 -0
  77. package/dist/help-dialog.d.ts +56 -0
  78. package/dist/help-dialog.d.ts.map +1 -0
  79. package/dist/help-dialog.js +142 -0
  80. package/dist/help-dialog.js.map +1 -0
  81. package/dist/hooks.d.ts +54 -0
  82. package/dist/hooks.d.ts.map +1 -0
  83. package/dist/hooks.js +85 -0
  84. package/dist/hooks.js.map +1 -0
  85. package/dist/icon-button.d.ts +28 -0
  86. package/dist/icon-button.d.ts.map +1 -0
  87. package/dist/icon-button.js +14 -0
  88. package/dist/icon-button.js.map +1 -0
  89. package/dist/index.d.ts +45 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +46 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/layer-panel.d.ts +13 -0
  94. package/dist/layer-panel.d.ts.map +1 -0
  95. package/dist/layer-panel.js +109 -0
  96. package/dist/layer-panel.js.map +1 -0
  97. package/dist/library-panel.d.ts +33 -0
  98. package/dist/library-panel.d.ts.map +1 -0
  99. package/dist/library-panel.js +37 -0
  100. package/dist/library-panel.js.map +1 -0
  101. package/dist/link-caption-editor.d.ts +8 -0
  102. package/dist/link-caption-editor.d.ts.map +1 -0
  103. package/dist/link-caption-editor.js +65 -0
  104. package/dist/link-caption-editor.js.map +1 -0
  105. package/dist/link-drop-shape-menu.d.ts +12 -0
  106. package/dist/link-drop-shape-menu.d.ts.map +1 -0
  107. package/dist/link-drop-shape-menu.js +55 -0
  108. package/dist/link-drop-shape-menu.js.map +1 -0
  109. package/dist/link-hover-popup.d.ts +2 -0
  110. package/dist/link-hover-popup.d.ts.map +1 -0
  111. package/dist/link-hover-popup.js +96 -0
  112. package/dist/link-hover-popup.js.map +1 -0
  113. package/dist/main-menu.d.ts +67 -0
  114. package/dist/main-menu.d.ts.map +1 -0
  115. package/dist/main-menu.js +243 -0
  116. package/dist/main-menu.js.map +1 -0
  117. package/dist/markdown.d.ts +10 -0
  118. package/dist/markdown.d.ts.map +1 -0
  119. package/dist/markdown.js +131 -0
  120. package/dist/markdown.js.map +1 -0
  121. package/dist/merge-dialog.d.ts +22 -0
  122. package/dist/merge-dialog.d.ts.map +1 -0
  123. package/dist/merge-dialog.js +46 -0
  124. package/dist/merge-dialog.js.map +1 -0
  125. package/dist/modal.d.ts +19 -0
  126. package/dist/modal.d.ts.map +1 -0
  127. package/dist/modal.js +87 -0
  128. package/dist/modal.js.map +1 -0
  129. package/dist/palette.d.ts +73 -0
  130. package/dist/palette.d.ts.map +1 -0
  131. package/dist/palette.js +330 -0
  132. package/dist/palette.js.map +1 -0
  133. package/dist/popover.d.ts +33 -0
  134. package/dist/popover.d.ts.map +1 -0
  135. package/dist/popover.js +107 -0
  136. package/dist/popover.js.map +1 -0
  137. package/dist/property-panel.d.ts +32 -0
  138. package/dist/property-panel.d.ts.map +1 -0
  139. package/dist/property-panel.js +728 -0
  140. package/dist/property-panel.js.map +1 -0
  141. package/dist/reset-to-content-button.d.ts +10 -0
  142. package/dist/reset-to-content-button.d.ts.map +1 -0
  143. package/dist/reset-to-content-button.js +62 -0
  144. package/dist/reset-to-content-button.js.map +1 -0
  145. package/dist/segmented-control.d.ts +23 -0
  146. package/dist/segmented-control.d.ts.map +1 -0
  147. package/dist/segmented-control.js +5 -0
  148. package/dist/segmented-control.js.map +1 -0
  149. package/dist/selection-floating-panel.d.ts +56 -0
  150. package/dist/selection-floating-panel.d.ts.map +1 -0
  151. package/dist/selection-floating-panel.js +251 -0
  152. package/dist/selection-floating-panel.js.map +1 -0
  153. package/dist/sidebar.d.ts +31 -0
  154. package/dist/sidebar.d.ts.map +1 -0
  155. package/dist/sidebar.js +66 -0
  156. package/dist/sidebar.js.map +1 -0
  157. package/dist/slider.d.ts +20 -0
  158. package/dist/slider.d.ts.map +1 -0
  159. package/dist/slider.js +9 -0
  160. package/dist/slider.js.map +1 -0
  161. package/dist/text-editor-overlay.d.ts +16 -0
  162. package/dist/text-editor-overlay.d.ts.map +1 -0
  163. package/dist/text-editor-overlay.js +112 -0
  164. package/dist/text-editor-overlay.js.map +1 -0
  165. package/dist/toast.d.ts +34 -0
  166. package/dist/toast.d.ts.map +1 -0
  167. package/dist/toast.js +89 -0
  168. package/dist/toast.js.map +1 -0
  169. package/dist/toolbar.d.ts +149 -0
  170. package/dist/toolbar.d.ts.map +1 -0
  171. package/dist/toolbar.js +282 -0
  172. package/dist/toolbar.js.map +1 -0
  173. package/dist/tooltip.d.ts +21 -0
  174. package/dist/tooltip.d.ts.map +1 -0
  175. package/dist/tooltip.js +217 -0
  176. package/dist/tooltip.js.map +1 -0
  177. package/dist/ui-layer.d.ts +22 -0
  178. package/dist/ui-layer.d.ts.map +1 -0
  179. package/dist/ui-layer.js +3 -0
  180. package/dist/ui-layer.js.map +1 -0
  181. package/dist/versioning.d.ts +32 -0
  182. package/dist/versioning.d.ts.map +1 -0
  183. package/dist/versioning.js +206 -0
  184. package/dist/versioning.js.map +1 -0
  185. package/package.json +81 -0
  186. package/src/styles.css +1502 -0
@@ -0,0 +1,70 @@
1
+ import { type CSSProperties, type ReactNode } from "react";
2
+ import { type RendererBackend } from "@oh-just-another/renderer-canvas";
3
+ import { Editor, type Mode } from "@oh-just-another/state";
4
+ import type { Rasterizer, TextShaper } from "@oh-just-another/renderer-core";
5
+ import type { Scene } from "@oh-just-another/scene";
6
+ export interface DiagramRootProps {
7
+ readonly initialScene: Scene;
8
+ readonly initialMode?: Mode;
9
+ readonly children: ReactNode;
10
+ /** Called once the editor is ready (after a `<DiagramSurface>` mounts). */
11
+ readonly onReady?: (editor: Editor) => void;
12
+ /** Skip the implicit `installBuiltinRenderers()` call. */
13
+ readonly skipInstallRenderers?: boolean;
14
+ /**
15
+ * Renderer backend. `"canvas2d"` (default) is the always-safe path;
16
+ * `"webgl2"` and `"offscreen"` are opt-in and require host support
17
+ * (the demo wires a switcher to try each at runtime).
18
+ *
19
+ * Changing this prop after mount **recreates** the editor and
20
+ * surface — the host should keep the value stable except when the
21
+ * user explicitly switches backend.
22
+ */
23
+ readonly renderer?: RendererBackend;
24
+ /**
25
+ * Worker factory for the `offscreen` backend. Hosts must provide
26
+ * a function that returns a fresh `Worker` instance pointing at
27
+ * `@oh-just-another/renderer-canvas`'s `render-worker.ts`. The factory
28
+ * is bundler-specific (Vite vs webpack vs Rollup all spell the
29
+ * URL differently), so the kernel never ships a default.
30
+ */
31
+ readonly workerFactory?: () => Worker;
32
+ /**
33
+ * Pre-loaded WASM text shaper (or any `TextShaper` impl).
34
+ * Forwarded straight into `EditorOptions.textShaper` so the
35
+ * built-in `drawText` renderer uses it for wrap measurements.
36
+ * Pass `WasmTextShaper.loadBundled()` (await first!) from
37
+ * `@oh-just-another/text-wasm`.
38
+ */
39
+ readonly textShaper?: TextShaper;
40
+ /**
41
+ * Pre-loaded WASM rasterizer. Forwarded into the editor for
42
+ * hosts that want path-heavy code to go through WASM bezier
43
+ * flatten / stroke-to-fill.
44
+ */
45
+ readonly rasterizer?: Rasterizer;
46
+ }
47
+ export declare const DiagramRoot: ({ initialScene, initialMode, children, onReady, skipInstallRenderers, renderer, workerFactory, textShaper, rasterizer, }: DiagramRootProps) => import("react/jsx-runtime").JSX.Element;
48
+ export interface DiagramSurfaceProps {
49
+ readonly style?: CSSProperties;
50
+ readonly className?: string;
51
+ /**
52
+ * Accessible name for the canvas region — read out by screen readers
53
+ * and shown as the visible focus-ring tooltip. Defaults to
54
+ * `"Diagram canvas"`. Override per-app to give context (e.g. the
55
+ * document title).
56
+ */
57
+ readonly ariaLabel?: string;
58
+ }
59
+ /**
60
+ * Mounts the canvas host DOM where it is placed in the tree. Must live
61
+ * inside a `<DiagramRoot>`. Renders a plain `<div>` and registers it with
62
+ * the root; the root then creates the editor + `LayeredCanvas` against it.
63
+ *
64
+ * The surface is `tabIndex=0` + `role="application"` so keyboard users
65
+ * can land on it via Tab and screen readers announce it as an interactive
66
+ * canvas (the contents are non-DOM). Hosts that want a different
67
+ * accessible name pass `ariaLabel`.
68
+ */
69
+ export declare const DiagramSurface: ({ style, className, ariaLabel }: DiagramSurfaceProps) => import("react/jsx-runtime").JSX.Element;
70
+ //# sourceMappingURL=diagram-root.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagram-root.d.ts","sourceRoot":"","sources":["../src/diagram-root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAsB,KAAK,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAuBpD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,0DAA0D;IAC1D,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC;;;;;;;;OAQG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;CAClC;AAED,eAAO,MAAM,WAAW,GAAI,0HAUzB,gBAAgB,4CAuIlB,CAAC;AAmCF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,iCAAiC,mBAAmB,4CA2ClF,CAAC"}
@@ -0,0 +1,180 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useRef, useState, } from "react";
3
+ import { createLayeredSurfaceWithFallback, installBuiltinRenderers, } from "@oh-just-another/renderer-canvas";
4
+ import { Editor } from "@oh-just-another/state";
5
+ import { DiagramEditorBridge } from "./context.js";
6
+ import { ContextMenuControllerProvider } from "./context-menu-controller.js";
7
+ const RegisterSurfaceContext = createContext(null);
8
+ export const DiagramRoot = ({ initialScene, initialMode, children, onReady, skipInstallRenderers, renderer = "canvas2d", workerFactory, textShaper, rasterizer, }) => {
9
+ const [editor, setEditor] = useState(null);
10
+ const editorRef = useRef(null);
11
+ const surfaceRef = useRef(null);
12
+ const observerRef = useRef(null);
13
+ const hostRef = useRef(null);
14
+ const unsubscribeRef = useRef(null);
15
+ // The factory ref keeps `registerSurface`'s deps stable while
16
+ // still letting renderer/backend reactivity below see the latest
17
+ // values when it re-mounts the surface.
18
+ const rendererRef = useRef(renderer);
19
+ const workerFactoryRef = useRef(workerFactory);
20
+ const textShaperRef = useRef(textShaper);
21
+ const rasterizerRef = useRef(rasterizer);
22
+ rendererRef.current = renderer;
23
+ workerFactoryRef.current = workerFactory;
24
+ textShaperRef.current = textShaper;
25
+ rasterizerRef.current = rasterizer;
26
+ const mountSurface = useCallback((host) => {
27
+ if (!skipInstallRenderers)
28
+ installBuiltinRenderers();
29
+ const { width, height } = host.getBoundingClientRect();
30
+ const { surface, effectiveBackend } = createLayeredSurfaceWithFallback(host, width, height, {
31
+ backend: rendererRef.current,
32
+ ...(workerFactoryRef.current ? { workerFactory: workerFactoryRef.current } : {}),
33
+ }, (requested, err) => {
34
+ // Backend unavailable (no WebGL2 / OffscreenCanvas / context
35
+ // limit hit). The fallback already returned a canvas2d
36
+ // surface; log so dev tools surface the reason. Hosts that
37
+ // want a toast can read `editor.host.dataset.effectiveBackend`.
38
+ console.warn(`[DiagramRoot] ${requested} renderer unavailable, falling back to canvas2d:`, err);
39
+ });
40
+ host.dataset.effectiveBackend = effectiveBackend;
41
+ const opts = {
42
+ host,
43
+ mainTarget: surface.get("main"),
44
+ overlayTarget: surface.get("overlay"),
45
+ backgroundTarget: surface.get("background"),
46
+ // Flush deferred backends (WebGL2 / OffscreenCanvas) right after each
47
+ // paint, on the same rAF tick. Must NOT be a notify-microtask: notify
48
+ // fires before the rAF render, which would leave the surface one frame
49
+ // behind.
50
+ onAfterRender: () => surfaceRef.current?.present(),
51
+ initialScene,
52
+ ...(initialMode !== undefined ? { initialMode } : {}),
53
+ ...(textShaperRef.current ? { textShaper: textShaperRef.current } : {}),
54
+ ...(rasterizerRef.current ? { rasterizer: rasterizerRef.current } : {}),
55
+ };
56
+ const e = new Editor(opts);
57
+ e.setViewportSize(width, height);
58
+ surfaceRef.current = surface;
59
+ editorRef.current = e;
60
+ setEditor(e);
61
+ onReady?.(e);
62
+ // Deferred backends are flushed via the editor's `onAfterRender` hook
63
+ // (set in EditorOptions above) so present() runs right after the paint
64
+ // on the same rAF tick. Present once now for the initial frame.
65
+ surface.present();
66
+ const ro = new ResizeObserver(() => {
67
+ const next = host.getBoundingClientRect();
68
+ surface.resize(next.width, next.height);
69
+ e.setViewportSize(next.width, next.height);
70
+ e.setMode(e.mode); // forces a re-render at the new size
71
+ });
72
+ ro.observe(host);
73
+ observerRef.current = ro;
74
+ }, []);
75
+ const teardownSurface = useCallback(() => {
76
+ observerRef.current?.disconnect();
77
+ observerRef.current = null;
78
+ unsubscribeRef.current?.();
79
+ unsubscribeRef.current = null;
80
+ editorRef.current?.dispose();
81
+ editorRef.current = null;
82
+ surfaceRef.current?.dispose();
83
+ surfaceRef.current = null;
84
+ }, []);
85
+ const registerSurface = useCallback((host) => {
86
+ teardownSurface();
87
+ hostRef.current = host;
88
+ if (!host) {
89
+ setEditor(null);
90
+ return;
91
+ }
92
+ mountSurface(host);
93
+ }, [mountSurface, teardownSurface]);
94
+ // Re-mount the surface when the host swaps backends at runtime.
95
+ // The first mount is driven by `registerSurface`; subsequent
96
+ // backend changes need an explicit tear-down + remount because
97
+ // `LayeredSurface` ownership is per-backend.
98
+ useEffect(() => {
99
+ const host = hostRef.current;
100
+ if (!host)
101
+ return;
102
+ teardownSurface();
103
+ mountSurface(host);
104
+ }, [renderer, mountSurface, teardownSurface]);
105
+ // Make sure the editor is disposed if `<DiagramRoot>` unmounts even if
106
+ // no surface registered an unmount first (defensive).
107
+ useLayoutEffect(() => {
108
+ return () => {
109
+ teardownSurface();
110
+ hostRef.current = null;
111
+ };
112
+ }, [teardownSurface]);
113
+ return (_jsx(DiagramEditorBridge.Provider, { value: editor, children: _jsx(RegisterSurfaceContext.Provider, { value: registerSurface, children: _jsxs(ContextMenuControllerProvider, { children: [children, _jsx(LiveRegion, { editor: editor })] }) }) }));
114
+ };
115
+ /**
116
+ * Hidden `aria-live="polite"` region that pipes `editor.onAnnounce`
117
+ * messages to assistive tech. Rendered automatically by every
118
+ * `<DiagramRoot>`; visually hidden but readable by screen readers.
119
+ */
120
+ const LiveRegion = ({ editor }) => {
121
+ const [message, setMessage] = useState("");
122
+ useEffect(() => {
123
+ if (!editor)
124
+ return undefined;
125
+ return editor.onAnnounce(setMessage);
126
+ }, [editor]);
127
+ return (_jsx("div", { role: "status", "aria-live": "polite", "aria-atomic": "true", style: {
128
+ position: "absolute",
129
+ width: 1,
130
+ height: 1,
131
+ padding: 0,
132
+ margin: -1,
133
+ overflow: "hidden",
134
+ clip: "rect(0,0,0,0)",
135
+ whiteSpace: "nowrap",
136
+ border: 0,
137
+ }, children: message }));
138
+ };
139
+ /**
140
+ * Mounts the canvas host DOM where it is placed in the tree. Must live
141
+ * inside a `<DiagramRoot>`. Renders a plain `<div>` and registers it with
142
+ * the root; the root then creates the editor + `LayeredCanvas` against it.
143
+ *
144
+ * The surface is `tabIndex=0` + `role="application"` so keyboard users
145
+ * can land on it via Tab and screen readers announce it as an interactive
146
+ * canvas (the contents are non-DOM). Hosts that want a different
147
+ * accessible name pass `ariaLabel`.
148
+ */
149
+ export const DiagramSurface = ({ style, className, ariaLabel }) => {
150
+ const register = useContext(RegisterSurfaceContext);
151
+ const ref = useRef(null);
152
+ useLayoutEffect(() => {
153
+ if (!register)
154
+ return undefined;
155
+ register(ref.current);
156
+ return () => { register(null); };
157
+ }, [register]);
158
+ if (!register) {
159
+ throw new Error("@oh-just-another/react-ui: <DiagramSurface> rendered outside <DiagramRoot>.");
160
+ }
161
+ return (_jsx("div", { ref: ref, className: className, role: "application", tabIndex: 0, "aria-label": ariaLabel ?? "Diagram canvas", style: {
162
+ position: "relative",
163
+ width: "100%",
164
+ height: "100%",
165
+ overflow: "hidden",
166
+ touchAction: "none",
167
+ userSelect: "none",
168
+ // Visible focus ring — UA-default for `outline` is sometimes
169
+ // suppressed by parent `*:focus { outline: none }` rules; we
170
+ // declare an explicit one so keyboard users always see focus.
171
+ outline: "none",
172
+ ...style,
173
+ }, onFocus: (ev) => {
174
+ ev.currentTarget.style.outline = "2px solid var(--accent, #1a73e8)";
175
+ ev.currentTarget.style.outlineOffset = "-2px";
176
+ }, onBlur: (ev) => {
177
+ ev.currentTarget.style.outline = "none";
178
+ } }));
179
+ };
180
+ //# sourceMappingURL=diagram-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagram-root.js","sourceRoot":"","sources":["../src/diagram-root.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,aAAa,EACb,WAAW,EACX,UAAU,EACV,SAAS,EACT,eAAe,EACf,MAAM,EACN,QAAQ,GAGT,MAAM,OAAO,CAAC;AACf,OAAO,EACL,gCAAgC,EAChC,uBAAuB,GAGxB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAiC,MAAM,wBAAwB,CAAC;AAG/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAmB7E,MAAM,sBAAsB,GAAG,aAAa,CAAyB,IAAI,CAAC,CAAC;AA4C3E,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAC1B,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,OAAO,EACP,oBAAoB,EACpB,QAAQ,GAAG,UAAU,EACrB,aAAa,EACb,UAAU,EACV,UAAU,GACO,EAAE,EAAE;IACrB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,MAAM,CAAqB,IAAI,CAAC,CAAC;IACjD,MAAM,cAAc,GAAG,MAAM,CAAsB,IAAI,CAAC,CAAC;IACzD,8DAA8D;IAC9D,iEAAiE;IACjE,wCAAwC;IACxC,MAAM,WAAW,GAAG,MAAM,CAAkB,QAAQ,CAAC,CAAC;IACtD,MAAM,gBAAgB,GAAG,MAAM,CAA6B,aAAa,CAAC,CAAC;IAC3E,MAAM,aAAa,GAAG,MAAM,CAAyB,UAAU,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,MAAM,CAAyB,UAAU,CAAC,CAAC;IACjE,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC/B,gBAAgB,CAAC,OAAO,GAAG,aAAa,CAAC;IACzC,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC;IACnC,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC;IAEnC,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,IAAiB,EAAE,EAAE;QACrD,IAAI,CAAC,oBAAoB;YAAE,uBAAuB,EAAE,CAAC;QAErD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACvD,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,gCAAgC,CACpE,IAAI,EACJ,KAAK,EACL,MAAM,EACN;YACE,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjF,EACD,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE;YACjB,6DAA6D;YAC7D,uDAAuD;YACvD,2DAA2D;YAC3D,gEAAgE;YAChE,OAAO,CAAC,IAAI,CACV,iBAAiB,SAAS,kDAAkD,EAC5E,GAAG,CACJ,CAAC;QACJ,CAAC,CACF,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACjD,MAAM,IAAI,GAAkB;YAC1B,IAAI;YACJ,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;YAC/B,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;YACrC,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;YAC3C,sEAAsE;YACtE,sEAAsE;YACtE,uEAAuE;YACvE,UAAU;YACV,aAAa,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE;YAClD,YAAY;YACZ,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxE,CAAC;QACF,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAEjC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;QAC7B,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC;QACtB,SAAS,CAAC,CAAC,CAAC,CAAC;QACb,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAEb,sEAAsE;QACtE,uEAAuE;QACvE,gEAAgE;QAChE,OAAO,CAAC,OAAO,EAAE,CAAC;QAElB,MAAM,EAAE,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC1C,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACxC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3C,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,qCAAqC;QAC1D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACjB,WAAW,CAAC,OAAO,GAAG,EAAE,CAAC;IAC3B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;QACvC,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;QAClC,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;QAC3B,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3B,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;QAC9B,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAC7B,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;QACzB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAC9B,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,eAAe,GAAG,WAAW,CACjC,CAAC,IAAI,EAAE,EAAE;QACP,eAAe,EAAE,CAAC;QAClB,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QACD,YAAY,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC,EACD,CAAC,YAAY,EAAE,eAAe,CAAC,CAChC,CAAC;IAEF,gEAAgE;IAChE,6DAA6D;IAC7D,+DAA+D;IAC/D,6CAA6C;IAC7C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,eAAe,EAAE,CAAC;QAClB,YAAY,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAE9C,uEAAuE;IACvE,sDAAsD;IACtD,eAAe,CAAC,GAAG,EAAE;QACnB,OAAO,GAAG,EAAE;YACV,eAAe,EAAE,CAAC;YAClB,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;QACzB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAEtB,OAAO,CACL,KAAC,mBAAmB,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,YACzC,KAAC,sBAAsB,CAAC,QAAQ,IAAC,KAAK,EAAE,eAAe,YACrD,MAAC,6BAA6B,eAC3B,QAAQ,EACT,KAAC,UAAU,IAAC,MAAM,EAAE,MAAM,GAAI,IACA,GACA,GACL,CAChC,CAAC;AACJ,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,GAAG,CAAC,EAAE,MAAM,EAAsC,EAAE,EAAE;IACpE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,OAAO,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACb,OAAO,CACL,cACE,IAAI,EAAC,QAAQ,eACH,QAAQ,iBACN,MAAM,EAClB,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,CAAC,CAAC;YACV,QAAQ,EAAE,QAAQ;YAClB,IAAI,EAAE,eAAe;YACrB,UAAU,EAAE,QAAQ;YACpB,MAAM,EAAE,CAAC;SACV,YAEA,OAAO,GACJ,CACP,CAAC;AACJ,CAAC,CAAC;AAcF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAuB,EAAE,EAAE;IACrF,MAAM,QAAQ,GAAG,UAAU,CAAC,sBAAsB,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAEzC,eAAe,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QAChC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,GAAG,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;IACjG,CAAC;IAED,OAAO,CACL,cACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,SAAS,EACpB,IAAI,EAAC,aAAa,EAClB,QAAQ,EAAE,CAAC,gBACC,SAAS,IAAI,gBAAgB,EACzC,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,MAAM;YACnB,UAAU,EAAE,MAAM;YAClB,6DAA6D;YAC7D,6DAA6D;YAC7D,8DAA8D;YAC9D,OAAO,EAAE,MAAM;YACf,GAAG,KAAK;SACT,EACD,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;YACd,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,GAAG,kCAAkC,CAAC;YACpE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;QAChD,CAAC,EACD,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE;YACb,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAC1C,CAAC,GACD,CACH,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { type CSSProperties } from "react";
2
+ import { type Scene } from "@oh-just-another/scene";
3
+ /**
4
+ * Side-by-side scene comparison. Renders two snapshots to SVG via the
5
+ * headless renderer and overlays diff markers:
6
+ *
7
+ * green box — added in `right`
8
+ * red box — removed (only in `left`)
9
+ * yellow box — modified (in both, different ref)
10
+ *
11
+ * Pure presentation — receives two `Scene` values from the host
12
+ * (typically a `VersionStore` snapshot pair) and never touches the
13
+ * live editor. Hosts pick which snapshots to compare via the
14
+ * VersionPanel UI; this component is the visual.
15
+ */
16
+ export interface DiffPanelProps {
17
+ readonly left: Scene;
18
+ readonly right: Scene;
19
+ readonly leftLabel?: string;
20
+ readonly rightLabel?: string;
21
+ readonly className?: string;
22
+ readonly style?: CSSProperties;
23
+ }
24
+ export declare const DiffPanel: ({ left, right, leftLabel, rightLabel, className, style, }: DiffPanelProps) => import("react/jsx-runtime").JSX.Element;
25
+ //# sourceMappingURL=diff-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-panel.d.ts","sourceRoot":"","sources":["../src/diff-panel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAGL,KAAK,KAAK,EAEX,MAAM,wBAAwB,CAAC;AAIhC;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAKD,eAAO,MAAM,SAAS,GAAI,2DAOvB,cAAc,4CA0BhB,CAAC"}
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { diffSceneElements, getElementWorldBounds, } from "@oh-just-another/scene";
4
+ import { renderSceneToSvg } from "@oh-just-another/renderer-svg";
5
+ import { DIFF_COLORS } from "@oh-just-another/tokens";
6
+ const PANEL_WIDTH = 480;
7
+ const PANEL_HEIGHT = 360;
8
+ export const DiffPanel = ({ left, right, leftLabel = "Before", rightLabel = "After", className, style, }) => {
9
+ const diff = useMemo(() => diffSceneElements(left, right), [left, right]);
10
+ const leftSvg = useMemo(() => renderSceneToSvg(left, { width: PANEL_WIDTH, height: PANEL_HEIGHT }), [left]);
11
+ const rightSvg = useMemo(() => renderSceneToSvg(right, { width: PANEL_WIDTH, height: PANEL_HEIGHT }), [right]);
12
+ const container = {
13
+ display: "flex",
14
+ gap: 12,
15
+ padding: 12,
16
+ background: "var(--panel, #161616)",
17
+ color: "var(--text, #ddd)",
18
+ ...style,
19
+ };
20
+ return (_jsxs("div", { className: className, style: container, children: [_jsx(SideView, { label: leftLabel, svg: leftSvg, scene: left, diff: diff, side: "left" }), _jsx(SideView, { label: rightLabel, svg: rightSvg, scene: right, diff: diff, side: "right" })] }));
21
+ };
22
+ const SideView = ({ label, svg, scene, diff, side, }) => {
23
+ // Which markers to draw on this side:
24
+ // - left side highlights `removed` (red) — shapes that existed
25
+ // in `prev` but not in `next`.
26
+ // - right side highlights `added` (green).
27
+ // - both sides highlight `modified` (yellow) using each side's
28
+ // own bounds — so the user sees the before AND after position
29
+ // of a moved shape.
30
+ const overlays = useMemo(() => {
31
+ const out = [];
32
+ const palette = DIFF_COLORS;
33
+ if (side === "left") {
34
+ for (const id of diff.removed) {
35
+ const s = scene.elements.get(id);
36
+ if (s)
37
+ out.push({ id, color: palette.removed, bounds: getElementWorldBounds(s) });
38
+ }
39
+ }
40
+ else {
41
+ for (const id of diff.added) {
42
+ const s = scene.elements.get(id);
43
+ if (s)
44
+ out.push({ id, color: palette.added, bounds: getElementWorldBounds(s) });
45
+ }
46
+ }
47
+ for (const id of diff.modified) {
48
+ const s = scene.elements.get(id);
49
+ if (s)
50
+ out.push({ id, color: palette.modified, bounds: getElementWorldBounds(s) });
51
+ }
52
+ return out;
53
+ }, [scene, diff, side]);
54
+ const frameStyle = {
55
+ flex: 1,
56
+ display: "flex",
57
+ flexDirection: "column",
58
+ gap: 4,
59
+ minWidth: 0,
60
+ };
61
+ const figureStyle = {
62
+ position: "relative",
63
+ width: PANEL_WIDTH,
64
+ height: PANEL_HEIGHT,
65
+ background: "var(--surface, #fff)",
66
+ border: "1px solid var(--border, #2a2a2a)",
67
+ borderRadius: 4,
68
+ overflow: "hidden",
69
+ };
70
+ return (_jsxs("section", { style: frameStyle, children: [_jsx("header", { style: {
71
+ fontSize: 11,
72
+ textTransform: "uppercase",
73
+ letterSpacing: 0.5,
74
+ color: "var(--muted, #888)",
75
+ }, children: label }), _jsxs("div", { style: figureStyle, children: [_jsx("div", { dangerouslySetInnerHTML: { __html: svg }, style: { position: "absolute", inset: 0 } }), _jsx("svg", { style: { position: "absolute", inset: 0, pointerEvents: "none" }, viewBox: `0 0 ${PANEL_WIDTH} ${PANEL_HEIGHT}`, children: overlays.map((m) => (_jsx("rect", { x: m.bounds.x, y: m.bounds.y, width: m.bounds.width, height: m.bounds.height, fill: "none", stroke: m.color, strokeWidth: 2, strokeDasharray: "4,3" }, `${side}-${m.id}`))) })] })] }));
76
+ };
77
+ //# sourceMappingURL=diff-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-panel.js","sourceRoot":"","sources":["../src/diff-panel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { CSSProperties } from "react";
2
+ /**
3
+ * Mini-panel that surfaces the most-edited properties of the
4
+ * currently-selected edge: routing strategy, arrowheads, stroke
5
+ * style (color / width / dash), and label text. Renders nothing
6
+ * when no edge is selected — host can put it inside a sidebar slot
7
+ * unconditionally.
8
+ *
9
+ * Field semantics map 1:1 to the scene `Link` shape (routing,
10
+ * arrowheads.{from,to}, style.{stroke,strokeWidth,dashArray},
11
+ * label.text). Edits go through `Editor.updateSelectedLink`, which
12
+ * commits one history step per change.
13
+ */
14
+ export interface LinkStylePanelProps {
15
+ readonly className?: string;
16
+ readonly style?: CSSProperties;
17
+ }
18
+ export declare const LinkStylePanel: ({ className, style }: LinkStylePanelProps) => import("react/jsx-runtime").JSX.Element | null;
19
+ //# sourceMappingURL=edge-style-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-style-panel.d.ts","sourceRoot":"","sources":["../src/edge-style-panel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAI3C;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AA6BD,eAAO,MAAM,cAAc,GAAI,sBAAsB,mBAAmB,mDAyLvE,CAAC"}
@@ -0,0 +1,120 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useDiagramOptional, useScene, useSelectedLink } from "./hooks.js";
3
+ const ARROW_OPTIONS = [
4
+ { value: "none", label: "None" },
5
+ { value: "arrow", label: "Arrow" },
6
+ { value: "triangle", label: "Triangle" },
7
+ { value: "diamond", label: "Diamond" },
8
+ { value: "circle", label: "Circle" },
9
+ ];
10
+ const ROUTING_OPTIONS = [
11
+ { value: "straight", label: "Straight" },
12
+ { value: "orthogonal", label: "Elbow" },
13
+ { value: "bezier", label: "Curved" },
14
+ ];
15
+ const DASH_OPTIONS = [
16
+ { value: "solid", label: "Solid", array: null },
17
+ { value: "dashed", label: "Dashed", array: [6, 4] },
18
+ { value: "dotted", label: "Dotted", array: [2, 4] },
19
+ ];
20
+ const dashKey = (arr) => {
21
+ if (!arr || arr.length === 0)
22
+ return "solid";
23
+ if (arr.length === 2 && arr[0] === 6 && arr[1] === 4)
24
+ return "dashed";
25
+ if (arr.length === 2 && arr[0] === 2 && arr[1] === 4)
26
+ return "dotted";
27
+ return "custom";
28
+ };
29
+ export const LinkStylePanel = ({ className, style }) => {
30
+ const editor = useDiagramOptional();
31
+ const scene = useScene();
32
+ const selectedLinkId = useSelectedLink();
33
+ const edge = selectedLinkId !== null ? scene.links.get(selectedLinkId) : undefined;
34
+ if (!editor || !edge)
35
+ return null;
36
+ const containerStyle = {
37
+ padding: 12,
38
+ display: "flex",
39
+ flexDirection: "column",
40
+ gap: 10,
41
+ background: "var(--panel, #161616)",
42
+ color: "var(--text, #ddd)",
43
+ fontSize: 12,
44
+ minWidth: 220,
45
+ ...style,
46
+ };
47
+ const setArrowhead = (side, value) => {
48
+ editor.updateSelectedLink((e) => ({
49
+ ...e,
50
+ arrowheads: { ...(e.arrowheads ?? {}), [side]: value === "none" ? undefined : value },
51
+ }));
52
+ };
53
+ const setRouting = (routing) => {
54
+ editor.updateSelectedLink((e) => ({ ...e, routing }));
55
+ };
56
+ const setStroke = (stroke) => {
57
+ editor.updateSelectedLink((e) => ({ ...e, style: { ...e.style, stroke } }));
58
+ };
59
+ const setStrokeWidth = (w) => {
60
+ editor.updateSelectedLink((e) => ({ ...e, style: { ...e.style, strokeWidth: w } }));
61
+ };
62
+ const setDash = (kind) => {
63
+ const opt = DASH_OPTIONS.find((o) => o.value === kind);
64
+ editor.updateSelectedLink((e) => {
65
+ if (!opt?.array) {
66
+ // "Solid" — strip the field entirely so the renderer treats
67
+ // the stroke as continuous instead of falling through with
68
+ // an empty-array dash pattern.
69
+ const { dashArray: _d, ...restStyle } = e.style;
70
+ void _d;
71
+ return { ...e, style: restStyle };
72
+ }
73
+ return { ...e, style: { ...e.style, dashArray: opt.array } };
74
+ });
75
+ };
76
+ const setLabel = (text) => {
77
+ editor.updateSelectedLink((e) => {
78
+ if (text === "") {
79
+ // Empty string removes the label entirely.
80
+ const { label: _l, ...rest } = e;
81
+ void _l;
82
+ return rest;
83
+ }
84
+ return { ...e, label: { ...(e.label ?? {}), text } };
85
+ });
86
+ };
87
+ return (_jsxs("aside", { className: className, style: containerStyle, children: [_jsx("h2", { style: {
88
+ margin: 0,
89
+ fontSize: 11,
90
+ textTransform: "uppercase",
91
+ letterSpacing: 0.5,
92
+ color: "var(--muted, #888)",
93
+ }, children: "Link" }), _jsx(Row, { label: "Kind", children: _jsxs("select", { value: edge.lineKind ?? "line", onChange: (ev) => {
94
+ editor.updateSelectedLink((e) => ({
95
+ ...e,
96
+ lineKind: ev.target.value === "block-arrow" ? "block-arrow" : "line",
97
+ }));
98
+ }, style: selectStyle, children: [_jsx("option", { value: "line", children: "Line" }), _jsx("option", { value: "block-arrow", children: "Block arrow" })] }) }), _jsx(Row, { label: "Routing", children: _jsx("select", { value: edge.routing ?? "straight", onChange: (ev) => { setRouting(ev.target.value); }, style: selectStyle, children: ROUTING_OPTIONS.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) }) }), _jsx(Row, { label: "Start", children: _jsx("select", { value: edge.arrowheads?.from ?? "none", onChange: (ev) => { setArrowhead("from", ev.target.value); }, style: selectStyle, children: ARROW_OPTIONS.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) }) }), _jsx(Row, { label: "End", children: _jsx("select", { value: edge.arrowheads?.to ?? "none", onChange: (ev) => { setArrowhead("to", ev.target.value); }, style: selectStyle, children: ARROW_OPTIONS.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) }) }), _jsx(Row, { label: "Color", children: _jsx("input", { type: "color", value: normaliseColor(edge.style.stroke), onChange: (ev) => { setStroke(ev.target.value); }, style: { width: 36, height: 24, border: "none", background: "none", padding: 0 } }) }), _jsx(Row, { label: "Width", children: _jsx("input", { type: "number", min: 0.5, max: 20, step: 0.5, value: edge.style.strokeWidth ?? 1.5, onChange: (ev) => { setStrokeWidth(Number(ev.target.value) || 1); }, style: { ...selectStyle, width: 72 } }) }), _jsx(Row, { label: "Dash", children: _jsx("select", { value: dashKey(edge.style.dashArray), onChange: (ev) => { setDash(ev.target.value); }, style: selectStyle, children: DASH_OPTIONS.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) }) }), _jsx(Row, { label: "Label", children: _jsx("input", { type: "text", placeholder: "(no label)", value: edge.label?.text ?? "", onChange: (ev) => { setLabel(ev.target.value); }, style: { ...selectStyle, flex: 1 } }) })] }));
99
+ };
100
+ const selectStyle = {
101
+ background: "var(--button-bg, #1f1f1f)",
102
+ color: "var(--text, #ddd)",
103
+ border: "1px solid var(--border, #2a2a2a)",
104
+ borderRadius: 4,
105
+ padding: "4px 8px",
106
+ font: "inherit",
107
+ fontSize: 12,
108
+ };
109
+ const Row = ({ label, children }) => (_jsxs("label", { style: { display: "flex", alignItems: "center", gap: 8, justifyContent: "space-between" }, children: [_jsx("span", { style: { color: "var(--muted, #888)" }, children: label }), children] }));
110
+ // Accept either #rrggbb (browser color picker) or any other CSS value.
111
+ // The color picker can't display non-hex values, so we coerce to a
112
+ // neutral grey if the current stroke is `null` or non-hex.
113
+ const normaliseColor = (s) => {
114
+ if (typeof s !== "string")
115
+ return "#444444";
116
+ if (/^#[0-9a-f]{6}$/i.test(s))
117
+ return s;
118
+ return "#444444";
119
+ };
120
+ //# sourceMappingURL=edge-style-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-style-panel.js","sourceRoot":"","sources":["../src/edge-style-panel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Inline editor for a frame's header name. Unlike the in-canvas text
3
+ * editor (invisible sink + canvas-drawn caret), the frame label has no
4
+ * canvas caret, so this is a VISIBLE `<input>` positioned over the header
5
+ * strip and styled to match it (dark bar, light text). Opens via
6
+ * `editor.beginFrameNameEdit(id)` (double-click the header / frame body);
7
+ * commits on Enter or blur, cancels on Escape.
8
+ *
9
+ * Wiring: drop as a sibling of `<DiagramSurface>` inside `<DiagramRoot>`,
10
+ * next to `<TextEditorOverlay>`.
11
+ */
12
+ export declare const FrameNameEditorOverlay: () => import("react/jsx-runtime").JSX.Element | null;
13
+ //# sourceMappingURL=frame-name-editor-overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-name-editor-overlay.d.ts","sourceRoot":"","sources":["../src/frame-name-editor-overlay.tsx"],"names":[],"mappings":"AAUA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,sDAmFlC,CAAC"}