@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.
- package/CHANGELOG.md +22 -0
- package/LICENSE +21 -0
- package/README.md +54 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/bottom-sheet.d.ts +26 -0
- package/dist/bottom-sheet.d.ts.map +1 -0
- package/dist/bottom-sheet.js +87 -0
- package/dist/bottom-sheet.js.map +1 -0
- package/dist/button-group.d.ts +14 -0
- package/dist/button-group.d.ts.map +1 -0
- package/dist/button-group.js +3 -0
- package/dist/button-group.js.map +1 -0
- package/dist/color-palette.d.ts +34 -0
- package/dist/color-palette.d.ts.map +1 -0
- package/dist/color-palette.js +77 -0
- package/dist/color-palette.js.map +1 -0
- package/dist/color-swatch-picker.d.ts +29 -0
- package/dist/color-swatch-picker.d.ts.map +1 -0
- package/dist/color-swatch-picker.js +56 -0
- package/dist/color-swatch-picker.js.map +1 -0
- package/dist/command-palette.d.ts +13 -0
- package/dist/command-palette.d.ts.map +1 -0
- package/dist/command-palette.js +146 -0
- package/dist/command-palette.js.map +1 -0
- package/dist/comments-panel.d.ts +27 -0
- package/dist/comments-panel.d.ts.map +1 -0
- package/dist/comments-panel.js +139 -0
- package/dist/comments-panel.js.map +1 -0
- package/dist/constants.d.ts +112 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +119 -0
- package/dist/constants.js.map +1 -0
- package/dist/context-menu-controller.d.ts +41 -0
- package/dist/context-menu-controller.d.ts.map +1 -0
- package/dist/context-menu-controller.js +26 -0
- package/dist/context-menu-controller.js.map +1 -0
- package/dist/context-menu.d.ts +53 -0
- package/dist/context-menu.d.ts.map +1 -0
- package/dist/context-menu.js +333 -0
- package/dist/context-menu.js.map +1 -0
- package/dist/context.d.ts +44 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +95 -0
- package/dist/context.js.map +1 -0
- package/dist/diagram-bars.d.ts +21 -0
- package/dist/diagram-bars.d.ts.map +1 -0
- package/dist/diagram-bars.js +4 -0
- package/dist/diagram-bars.js.map +1 -0
- package/dist/diagram-canvas.d.ts +39 -0
- package/dist/diagram-canvas.d.ts.map +1 -0
- package/dist/diagram-canvas.js +9 -0
- package/dist/diagram-canvas.js.map +1 -0
- package/dist/diagram-root.d.ts +70 -0
- package/dist/diagram-root.d.ts.map +1 -0
- package/dist/diagram-root.js +180 -0
- package/dist/diagram-root.js.map +1 -0
- package/dist/diff-panel.d.ts +25 -0
- package/dist/diff-panel.d.ts.map +1 -0
- package/dist/diff-panel.js +77 -0
- package/dist/diff-panel.js.map +1 -0
- package/dist/edge-style-panel.d.ts +19 -0
- package/dist/edge-style-panel.d.ts.map +1 -0
- package/dist/edge-style-panel.js +120 -0
- package/dist/edge-style-panel.js.map +1 -0
- package/dist/frame-name-editor-overlay.d.ts +13 -0
- package/dist/frame-name-editor-overlay.d.ts.map +1 -0
- package/dist/frame-name-editor-overlay.js +84 -0
- package/dist/frame-name-editor-overlay.js.map +1 -0
- package/dist/frame-panel.d.ts +19 -0
- package/dist/frame-panel.d.ts.map +1 -0
- package/dist/frame-panel.js +66 -0
- package/dist/frame-panel.js.map +1 -0
- package/dist/help-button.d.ts +16 -0
- package/dist/help-button.d.ts.map +1 -0
- package/dist/help-button.js +14 -0
- package/dist/help-button.js.map +1 -0
- package/dist/help-dialog.d.ts +56 -0
- package/dist/help-dialog.d.ts.map +1 -0
- package/dist/help-dialog.js +142 -0
- package/dist/help-dialog.js.map +1 -0
- package/dist/hooks.d.ts +54 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +85 -0
- package/dist/hooks.js.map +1 -0
- package/dist/icon-button.d.ts +28 -0
- package/dist/icon-button.d.ts.map +1 -0
- package/dist/icon-button.js +14 -0
- package/dist/icon-button.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/layer-panel.d.ts +13 -0
- package/dist/layer-panel.d.ts.map +1 -0
- package/dist/layer-panel.js +109 -0
- package/dist/layer-panel.js.map +1 -0
- package/dist/library-panel.d.ts +33 -0
- package/dist/library-panel.d.ts.map +1 -0
- package/dist/library-panel.js +37 -0
- package/dist/library-panel.js.map +1 -0
- package/dist/link-caption-editor.d.ts +8 -0
- package/dist/link-caption-editor.d.ts.map +1 -0
- package/dist/link-caption-editor.js +65 -0
- package/dist/link-caption-editor.js.map +1 -0
- package/dist/link-drop-shape-menu.d.ts +12 -0
- package/dist/link-drop-shape-menu.d.ts.map +1 -0
- package/dist/link-drop-shape-menu.js +55 -0
- package/dist/link-drop-shape-menu.js.map +1 -0
- package/dist/link-hover-popup.d.ts +2 -0
- package/dist/link-hover-popup.d.ts.map +1 -0
- package/dist/link-hover-popup.js +96 -0
- package/dist/link-hover-popup.js.map +1 -0
- package/dist/main-menu.d.ts +67 -0
- package/dist/main-menu.d.ts.map +1 -0
- package/dist/main-menu.js +243 -0
- package/dist/main-menu.js.map +1 -0
- package/dist/markdown.d.ts +10 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +131 -0
- package/dist/markdown.js.map +1 -0
- package/dist/merge-dialog.d.ts +22 -0
- package/dist/merge-dialog.d.ts.map +1 -0
- package/dist/merge-dialog.js +46 -0
- package/dist/merge-dialog.js.map +1 -0
- package/dist/modal.d.ts +19 -0
- package/dist/modal.d.ts.map +1 -0
- package/dist/modal.js +87 -0
- package/dist/modal.js.map +1 -0
- package/dist/palette.d.ts +73 -0
- package/dist/palette.d.ts.map +1 -0
- package/dist/palette.js +330 -0
- package/dist/palette.js.map +1 -0
- package/dist/popover.d.ts +33 -0
- package/dist/popover.d.ts.map +1 -0
- package/dist/popover.js +107 -0
- package/dist/popover.js.map +1 -0
- package/dist/property-panel.d.ts +32 -0
- package/dist/property-panel.d.ts.map +1 -0
- package/dist/property-panel.js +728 -0
- package/dist/property-panel.js.map +1 -0
- package/dist/reset-to-content-button.d.ts +10 -0
- package/dist/reset-to-content-button.d.ts.map +1 -0
- package/dist/reset-to-content-button.js +62 -0
- package/dist/reset-to-content-button.js.map +1 -0
- package/dist/segmented-control.d.ts +23 -0
- package/dist/segmented-control.d.ts.map +1 -0
- package/dist/segmented-control.js +5 -0
- package/dist/segmented-control.js.map +1 -0
- package/dist/selection-floating-panel.d.ts +56 -0
- package/dist/selection-floating-panel.d.ts.map +1 -0
- package/dist/selection-floating-panel.js +251 -0
- package/dist/selection-floating-panel.js.map +1 -0
- package/dist/sidebar.d.ts +31 -0
- package/dist/sidebar.d.ts.map +1 -0
- package/dist/sidebar.js +66 -0
- package/dist/sidebar.js.map +1 -0
- package/dist/slider.d.ts +20 -0
- package/dist/slider.d.ts.map +1 -0
- package/dist/slider.js +9 -0
- package/dist/slider.js.map +1 -0
- package/dist/text-editor-overlay.d.ts +16 -0
- package/dist/text-editor-overlay.d.ts.map +1 -0
- package/dist/text-editor-overlay.js +112 -0
- package/dist/text-editor-overlay.js.map +1 -0
- package/dist/toast.d.ts +34 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/toast.js +89 -0
- package/dist/toast.js.map +1 -0
- package/dist/toolbar.d.ts +149 -0
- package/dist/toolbar.d.ts.map +1 -0
- package/dist/toolbar.js +282 -0
- package/dist/toolbar.js.map +1 -0
- package/dist/tooltip.d.ts +21 -0
- package/dist/tooltip.d.ts.map +1 -0
- package/dist/tooltip.js +217 -0
- package/dist/tooltip.js.map +1 -0
- package/dist/ui-layer.d.ts +22 -0
- package/dist/ui-layer.d.ts.map +1 -0
- package/dist/ui-layer.js +3 -0
- package/dist/ui-layer.js.map +1 -0
- package/dist/versioning.d.ts +32 -0
- package/dist/versioning.d.ts.map +1 -0
- package/dist/versioning.js +206 -0
- package/dist/versioning.js.map +1 -0
- package/package.json +81 -0
- package/src/styles.css +1502 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState, } from "react";
|
|
3
|
+
import { defaultActionRegistry, formatHotkey } from "@oh-just-another/state";
|
|
4
|
+
import { useDiagramOptional } from "./hooks.js";
|
|
5
|
+
import { useContextMenuController } from "./context-menu-controller.js";
|
|
6
|
+
export const ContextMenu = ({ items, target, style, className }) => {
|
|
7
|
+
const editor = useDiagramOptional();
|
|
8
|
+
const controller = useContextMenuController();
|
|
9
|
+
const [open, setOpen] = useState(null);
|
|
10
|
+
const menuRef = useRef(null);
|
|
11
|
+
// Register an imperative opener so UI outside the canvas (e.g. the
|
|
12
|
+
// "⋯" button in the selection floating panel) can open this same
|
|
13
|
+
// menu at a chosen point.
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (!controller)
|
|
16
|
+
return undefined;
|
|
17
|
+
return controller.register(({ screenPoint, worldPoint }) => { setOpen({ screenPoint, worldPoint }); });
|
|
18
|
+
}, [controller]);
|
|
19
|
+
// Wire the contextmenu listener (mouse right-click) AND long-press
|
|
20
|
+
// (touch). Both end up calling `setOpen` with viewport-relative
|
|
21
|
+
// screen coords.
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!editor)
|
|
24
|
+
return undefined;
|
|
25
|
+
const root = target ?? window;
|
|
26
|
+
const onContext = (ev) => {
|
|
27
|
+
const me = ev;
|
|
28
|
+
me.preventDefault();
|
|
29
|
+
const screenPoint = { x: me.clientX, y: me.clientY };
|
|
30
|
+
const rect = editor.hostElement.getBoundingClientRect();
|
|
31
|
+
const worldPoint = editor.screenToWorld({
|
|
32
|
+
x: screenPoint.x - rect.left,
|
|
33
|
+
y: screenPoint.y - rect.top,
|
|
34
|
+
});
|
|
35
|
+
setOpen({ screenPoint, worldPoint });
|
|
36
|
+
};
|
|
37
|
+
root.addEventListener("contextmenu", onContext);
|
|
38
|
+
// Touch fallback: editor fires onLongPress with host-relative
|
|
39
|
+
// coords; the menu needs viewport-relative for positioning.
|
|
40
|
+
const unsubscribeLongPress = editor.onLongPress(({ screenPoint, worldPoint }) => {
|
|
41
|
+
const rect = editor.hostElement.getBoundingClientRect();
|
|
42
|
+
setOpen({
|
|
43
|
+
screenPoint: { x: screenPoint.x + rect.left, y: screenPoint.y + rect.top },
|
|
44
|
+
worldPoint,
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
return () => {
|
|
48
|
+
root.removeEventListener("contextmenu", onContext);
|
|
49
|
+
unsubscribeLongPress();
|
|
50
|
+
};
|
|
51
|
+
}, [editor, target]);
|
|
52
|
+
// Dismiss on click outside / Escape.
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (!open)
|
|
55
|
+
return undefined;
|
|
56
|
+
const onPointer = (ev) => {
|
|
57
|
+
if (menuRef.current?.contains(ev.target))
|
|
58
|
+
return;
|
|
59
|
+
setOpen(null);
|
|
60
|
+
};
|
|
61
|
+
const onKey = (ev) => {
|
|
62
|
+
if (ev.key === "Escape")
|
|
63
|
+
setOpen(null);
|
|
64
|
+
};
|
|
65
|
+
window.addEventListener("pointerdown", onPointer, true);
|
|
66
|
+
window.addEventListener("keydown", onKey);
|
|
67
|
+
return () => {
|
|
68
|
+
window.removeEventListener("pointerdown", onPointer, true);
|
|
69
|
+
window.removeEventListener("keydown", onKey);
|
|
70
|
+
};
|
|
71
|
+
}, [open]);
|
|
72
|
+
const close = useCallback(() => { setOpen(null); }, []);
|
|
73
|
+
if (!editor || !open)
|
|
74
|
+
return null;
|
|
75
|
+
const ctx = {
|
|
76
|
+
worldPoint: open.worldPoint,
|
|
77
|
+
screenPoint: open.screenPoint,
|
|
78
|
+
};
|
|
79
|
+
// Filter visibility once per open — items that compute `visible` against
|
|
80
|
+
// the editor still see a consistent snapshot.
|
|
81
|
+
const visibleItems = items.filter((item) => item.kind === "divider" || item.visible?.(editor, ctx) !== false);
|
|
82
|
+
// Collapse adjacent dividers + leading/trailing dividers.
|
|
83
|
+
const cleanedItems = collapseDividers(visibleItems);
|
|
84
|
+
if (cleanedItems.length === 0)
|
|
85
|
+
return null;
|
|
86
|
+
return (_jsx("div", { ref: menuRef, role: "menu", style: {
|
|
87
|
+
position: "fixed",
|
|
88
|
+
zIndex: 1000,
|
|
89
|
+
top: open.screenPoint.y,
|
|
90
|
+
left: open.screenPoint.x,
|
|
91
|
+
background: "var(--menu-bg, #1a1a1a)",
|
|
92
|
+
color: "var(--menu-text, #ddd)",
|
|
93
|
+
border: "1px solid var(--menu-border, #333)",
|
|
94
|
+
borderRadius: 6,
|
|
95
|
+
padding: "4px 0",
|
|
96
|
+
minWidth: 180,
|
|
97
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.3)",
|
|
98
|
+
font: "13px system-ui, -apple-system, Segoe UI, Roboto, sans-serif",
|
|
99
|
+
...style,
|
|
100
|
+
}, className: className, children: cleanedItems.map((item, i) => item.kind === "divider" ? (_jsx("hr", { style: {
|
|
101
|
+
border: 0,
|
|
102
|
+
borderTop: "1px solid var(--menu-divider, #2a2a2a)",
|
|
103
|
+
margin: "4px 0",
|
|
104
|
+
} }, `d-${i}`)) : (_jsx(ContextMenuRow, { item: item, editor: editor, ctx: ctx, onActivate: () => {
|
|
105
|
+
close();
|
|
106
|
+
item.onClick(editor, ctx);
|
|
107
|
+
} }, item.id))) }));
|
|
108
|
+
};
|
|
109
|
+
const ContextMenuRow = ({ item, editor, ctx, onActivate, }) => {
|
|
110
|
+
const disabled = item.disabled?.(editor, ctx) ?? false;
|
|
111
|
+
const handle = (ev) => {
|
|
112
|
+
if (disabled) {
|
|
113
|
+
ev.preventDefault();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
ev.stopPropagation();
|
|
117
|
+
onActivate();
|
|
118
|
+
};
|
|
119
|
+
return (_jsxs("button", { type: "button", role: "menuitem", onClick: handle, disabled: disabled, style: {
|
|
120
|
+
all: "unset",
|
|
121
|
+
display: "flex",
|
|
122
|
+
justifyContent: "space-between",
|
|
123
|
+
padding: "6px 12px",
|
|
124
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
125
|
+
opacity: disabled ? 0.4 : 1,
|
|
126
|
+
width: "100%",
|
|
127
|
+
boxSizing: "border-box",
|
|
128
|
+
}, onMouseEnter: (ev) => {
|
|
129
|
+
if (!disabled)
|
|
130
|
+
ev.currentTarget.style.background = "#2a2a2a";
|
|
131
|
+
}, onMouseLeave: (ev) => {
|
|
132
|
+
ev.currentTarget.style.background = "transparent";
|
|
133
|
+
}, children: [_jsx("span", { children: item.label }), item.shortcut ? (_jsx("span", { style: { marginLeft: 16, opacity: 0.6, fontSize: 11 }, children: item.shortcut })) : null] }));
|
|
134
|
+
};
|
|
135
|
+
const collapseDividers = (items) => {
|
|
136
|
+
const out = [];
|
|
137
|
+
for (const item of items) {
|
|
138
|
+
if (item.kind === "divider") {
|
|
139
|
+
if (out.length === 0)
|
|
140
|
+
continue;
|
|
141
|
+
const last = out[out.length - 1];
|
|
142
|
+
if (last?.kind === "divider")
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
out.push(item);
|
|
146
|
+
}
|
|
147
|
+
while (out.length > 0) {
|
|
148
|
+
const last = out[out.length - 1];
|
|
149
|
+
if (last?.kind !== "divider")
|
|
150
|
+
break;
|
|
151
|
+
out.pop();
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Build a context-menu row from a registered action: label, shortcut (from
|
|
157
|
+
* the action's hotkey, platform-correct), visibility (the action's
|
|
158
|
+
* `predicate`) and click (dispatch) all come from the registry. Position-/
|
|
159
|
+
* DOM-dependent menu items (annotations, add-comment, move-to-layer) can't be
|
|
160
|
+
* registry actions (the action context carries no world point) and stay
|
|
161
|
+
* inline below.
|
|
162
|
+
*
|
|
163
|
+
* `opts.label` / `opts.visible` override when the menu needs different
|
|
164
|
+
* text or visibility than the action's defaults (e.g. z-order entries
|
|
165
|
+
* shown only for a single selection).
|
|
166
|
+
*/
|
|
167
|
+
const actionMenuItem = (actionId, opts) => {
|
|
168
|
+
const action = defaultActionRegistry.get(actionId);
|
|
169
|
+
const pred = action?.predicate;
|
|
170
|
+
const matchers = !action?.hotkey
|
|
171
|
+
? []
|
|
172
|
+
: Array.isArray(action.hotkey)
|
|
173
|
+
? action.hotkey
|
|
174
|
+
: [action.hotkey];
|
|
175
|
+
const first = matchers[0];
|
|
176
|
+
const visible = opts?.visible ?? (pred ? (editor) => pred({ editor }) : undefined);
|
|
177
|
+
return {
|
|
178
|
+
kind: "action",
|
|
179
|
+
id: actionId,
|
|
180
|
+
label: opts?.label ?? action?.label ?? actionId,
|
|
181
|
+
...(first ? { shortcut: formatHotkey(first) } : {}),
|
|
182
|
+
...(visible ? { visible } : {}),
|
|
183
|
+
onClick: (editor) => { defaultActionRegistry.dispatch(actionId, { editor }); },
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
export const DEFAULT_CONTEXT_MENU = [
|
|
187
|
+
// --- Annotation pin actions (only when right-click landed on a pin) ---
|
|
188
|
+
{
|
|
189
|
+
kind: "action",
|
|
190
|
+
id: "annotation-open",
|
|
191
|
+
label: "Open thread",
|
|
192
|
+
visible: (e, ctx) => e.hitAnnotation(ctx.worldPoint) !== null,
|
|
193
|
+
onClick: (e, ctx) => {
|
|
194
|
+
const id = e.hitAnnotation(ctx.worldPoint);
|
|
195
|
+
if (id)
|
|
196
|
+
e.setSelectedAnnotation(id);
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
kind: "action",
|
|
201
|
+
id: "annotation-toggle-resolved",
|
|
202
|
+
label: "Toggle resolved",
|
|
203
|
+
visible: (e, ctx) => e.hitAnnotation(ctx.worldPoint) !== null,
|
|
204
|
+
onClick: (e, ctx) => {
|
|
205
|
+
const id = e.hitAnnotation(ctx.worldPoint);
|
|
206
|
+
if (id)
|
|
207
|
+
e.toggleAnnotationResolved(id);
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
kind: "action",
|
|
212
|
+
id: "annotation-delete",
|
|
213
|
+
label: "Delete annotation",
|
|
214
|
+
visible: (e, ctx) => e.hitAnnotation(ctx.worldPoint) !== null,
|
|
215
|
+
onClick: (e, ctx) => {
|
|
216
|
+
const id = e.hitAnnotation(ctx.worldPoint);
|
|
217
|
+
if (id)
|
|
218
|
+
e.removeAnnotation(id);
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
kind: "divider",
|
|
223
|
+
},
|
|
224
|
+
// --- Selection ops (registry-backed) ---
|
|
225
|
+
actionMenuItem("delete-selection", { label: "Delete" }),
|
|
226
|
+
actionMenuItem("duplicate-selection", { label: "Duplicate" }),
|
|
227
|
+
actionMenuItem("copy"),
|
|
228
|
+
actionMenuItem("cut"),
|
|
229
|
+
actionMenuItem("paste"),
|
|
230
|
+
actionMenuItem("select-all"),
|
|
231
|
+
{ kind: "divider" },
|
|
232
|
+
// --- Grouping + arrange (registry-backed) ---
|
|
233
|
+
actionMenuItem("group-selection", { label: "Group" }),
|
|
234
|
+
actionMenuItem("ungroup-selection", { label: "Ungroup" }),
|
|
235
|
+
actionMenuItem("arrange-grid"),
|
|
236
|
+
actionMenuItem("arrange-stack-h"),
|
|
237
|
+
actionMenuItem("arrange-stack-v"),
|
|
238
|
+
actionMenuItem("auto-arrange"),
|
|
239
|
+
actionMenuItem("compact-z-order"),
|
|
240
|
+
{ kind: "divider" },
|
|
241
|
+
// --- Z-order (single-selection scope; registry-backed, visibility
|
|
242
|
+
// narrowed to a single selection) ---
|
|
243
|
+
actionMenuItem("bring-to-front", { visible: (e) => e.selection.size === 1 }),
|
|
244
|
+
actionMenuItem("send-to-back", { visible: (e) => e.selection.size === 1 }),
|
|
245
|
+
{
|
|
246
|
+
kind: "action",
|
|
247
|
+
id: "move-to-layer",
|
|
248
|
+
label: "Move to layer…",
|
|
249
|
+
visible: (e) => e.selection.size > 0 && e.scene.layers.size > 1,
|
|
250
|
+
onClick: (e) => {
|
|
251
|
+
if (typeof window === "undefined")
|
|
252
|
+
return;
|
|
253
|
+
const layers = [...e.scene.layers.values()];
|
|
254
|
+
const names = layers.map((l, i) => `${i + 1}. ${l.name}`).join("\n");
|
|
255
|
+
const choice = window.prompt(`Move selection to layer (1-${layers.length}):\n${names}`);
|
|
256
|
+
if (!choice)
|
|
257
|
+
return;
|
|
258
|
+
const idx = parseInt(choice, 10) - 1;
|
|
259
|
+
const target = layers[idx];
|
|
260
|
+
if (target)
|
|
261
|
+
e.moveSelectionToLayer(target.id);
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
{ kind: "divider" },
|
|
265
|
+
// --- Annotation actions (when right-click hits a pin) ---
|
|
266
|
+
{
|
|
267
|
+
kind: "action",
|
|
268
|
+
id: "open-thread",
|
|
269
|
+
label: "Open thread",
|
|
270
|
+
visible: (e, ctx) => e.hitAnnotation(ctx.worldPoint) !== null,
|
|
271
|
+
onClick: (e, ctx) => {
|
|
272
|
+
const ann = e.hitAnnotation(ctx.worldPoint);
|
|
273
|
+
if (ann)
|
|
274
|
+
e.setSelectedAnnotation(ann);
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
kind: "action",
|
|
279
|
+
id: "resolve-annotation",
|
|
280
|
+
label: "Toggle resolved",
|
|
281
|
+
visible: (e, ctx) => e.hitAnnotation(ctx.worldPoint) !== null,
|
|
282
|
+
onClick: (e, ctx) => {
|
|
283
|
+
const ann = e.hitAnnotation(ctx.worldPoint);
|
|
284
|
+
if (ann)
|
|
285
|
+
e.toggleAnnotationResolved(ann);
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
kind: "action",
|
|
290
|
+
id: "remove-annotation",
|
|
291
|
+
label: "Delete annotation",
|
|
292
|
+
visible: (e, ctx) => e.hitAnnotation(ctx.worldPoint) !== null,
|
|
293
|
+
onClick: (e, ctx) => {
|
|
294
|
+
const ann = e.hitAnnotation(ctx.worldPoint);
|
|
295
|
+
if (ann)
|
|
296
|
+
e.removeAnnotation(ann);
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
kind: "action",
|
|
301
|
+
id: "add-comment",
|
|
302
|
+
label: "Add comment",
|
|
303
|
+
visible: (e, ctx) => e.hitAnnotation(ctx.worldPoint) === null,
|
|
304
|
+
onClick: (e, ctx) => {
|
|
305
|
+
const elementUnder = [...e.scene.elements.values()].reverse().find((s) => {
|
|
306
|
+
const pos = s.position;
|
|
307
|
+
const w = "width" in s && typeof s.width === "number" ? s.width : 0;
|
|
308
|
+
const h = "height" in s && typeof s.height === "number" ? s.height : 0;
|
|
309
|
+
return (ctx.worldPoint.x >= pos.x &&
|
|
310
|
+
ctx.worldPoint.y >= pos.y &&
|
|
311
|
+
ctx.worldPoint.x <= pos.x + w &&
|
|
312
|
+
ctx.worldPoint.y <= pos.y + h);
|
|
313
|
+
});
|
|
314
|
+
const position = elementUnder
|
|
315
|
+
? {
|
|
316
|
+
x: ctx.worldPoint.x - elementUnder.position.x,
|
|
317
|
+
y: ctx.worldPoint.y - elementUnder.position.y,
|
|
318
|
+
}
|
|
319
|
+
: ctx.worldPoint;
|
|
320
|
+
e.addAnnotation({ position, elementId: elementUnder?.id ?? null });
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
{ kind: "divider" },
|
|
324
|
+
// --- Viewport (registry-backed) ---
|
|
325
|
+
actionMenuItem("zoom-in"),
|
|
326
|
+
actionMenuItem("zoom-out"),
|
|
327
|
+
actionMenuItem("zoom-reset", { label: "Reset zoom (100%)" }),
|
|
328
|
+
actionMenuItem("zoom-to-fit", {
|
|
329
|
+
label: "Fit to screen",
|
|
330
|
+
visible: (e) => e.scene.elements.size > 0,
|
|
331
|
+
}),
|
|
332
|
+
];
|
|
333
|
+
//# sourceMappingURL=context-menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-menu.js","sourceRoot":"","sources":["../src/context-menu.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { Editor, EditorEvents } from "@oh-just-another/state";
|
|
3
|
+
export interface DiagramProviderProps {
|
|
4
|
+
readonly editor: Editor;
|
|
5
|
+
readonly children: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
/** Static provider — wraps a ready-made editor. */
|
|
8
|
+
export declare const DiagramProvider: ({ editor, children }: DiagramProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Internal bridge used by `<DiagramRoot>` to flow a lazy editor down to its
|
|
11
|
+
* descendants. Exported so the root can set it.
|
|
12
|
+
*/
|
|
13
|
+
export declare const DiagramEditorBridge: import("react").Context<Editor | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Strict accessor — throws when called outside any provider. Use for
|
|
16
|
+
* imperative paths that *require* the editor right now (`editor.addElement`,
|
|
17
|
+
* `editor.screenToWorld`, etc).
|
|
18
|
+
*/
|
|
19
|
+
export declare const useDiagramContext: () => Editor;
|
|
20
|
+
/**
|
|
21
|
+
* Forgiving variant — returns `null` when the editor hasn't been created
|
|
22
|
+
* yet. Pair with safe defaults; used by the reactive hooks to render
|
|
23
|
+
* cleanly during the first frame.
|
|
24
|
+
*/
|
|
25
|
+
export declare const useDiagramContextOptional: () => Editor | null;
|
|
26
|
+
/**
|
|
27
|
+
* "Subscribe to editor + select a value" helper. Re-runs `select` whenever
|
|
28
|
+
* the editor notifies a change; re-renders the caller when the projected
|
|
29
|
+
* value actually changes.
|
|
30
|
+
*
|
|
31
|
+
* The editor may be missing during the very first frame (before
|
|
32
|
+
* `<DiagramSurface>` registers with `<DiagramRoot>`). `defaultValue` is
|
|
33
|
+
* returned during that window.
|
|
34
|
+
*/
|
|
35
|
+
export declare const useEditorSelector: <T>(select: (editor: Editor) => T, defaultValue: T,
|
|
36
|
+
/**
|
|
37
|
+
* Optional typed event to subscribe to instead of the umbrella
|
|
38
|
+
* `change`. When omitted, falls back to `editor.subscribe(fn)`, which
|
|
39
|
+
* fires on every notify. Passing e.g. `"mode"` makes the hook re-run
|
|
40
|
+
* the selector only when the mode flipped, skipping selection /
|
|
41
|
+
* viewport / scene notifies entirely.
|
|
42
|
+
*/
|
|
43
|
+
event?: keyof EditorEvents) => T;
|
|
44
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA0D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/F,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAoBnE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B;AAED,mDAAmD;AACnD,eAAO,MAAM,eAAe,GAAI,sBAAsB,oBAAoB,4CAEzE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,wCAAiB,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,QAAO,MASpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,QAAO,MAAM,GAAG,IAAkC,CAAC;AAEzF;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,EACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,EAC7B,cAAc,CAAC;AACf;;;;;;GAMG;AACH,QAAQ,MAAM,YAAY,KACzB,CA+BF,CAAC"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useRef, useState } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Holds the live `Editor` instance. Components and hooks read from this
|
|
5
|
+
* context to subscribe to scene / selection / history changes.
|
|
6
|
+
*
|
|
7
|
+
* Two ways to populate it:
|
|
8
|
+
* - Build an editor yourself and pass it via `<DiagramProvider>`. Useful
|
|
9
|
+
* when you want full lifecycle control (multi-canvas, server-built
|
|
10
|
+
* editor, etc).
|
|
11
|
+
* - Use `<DiagramRoot>` (in `diagram-root.tsx`): it lazy-creates the editor
|
|
12
|
+
* when a child `<DiagramSurface>` mounts and provides it here.
|
|
13
|
+
*
|
|
14
|
+
* Most hooks tolerate the `null` value during the brief window between
|
|
15
|
+
* `<DiagramRoot>` rendering and `<DiagramSurface>` mounting — they return
|
|
16
|
+
* sensible defaults. `useDiagramContext` (the strict variant) still throws
|
|
17
|
+
* so direct imperative misuse outside a provider is caught early.
|
|
18
|
+
*/
|
|
19
|
+
const DiagramContext = createContext(null);
|
|
20
|
+
/** Static provider — wraps a ready-made editor. */
|
|
21
|
+
export const DiagramProvider = ({ editor, children }) => {
|
|
22
|
+
return _jsx(DiagramContext.Provider, { value: editor, children: children });
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Internal bridge used by `<DiagramRoot>` to flow a lazy editor down to its
|
|
26
|
+
* descendants. Exported so the root can set it.
|
|
27
|
+
*/
|
|
28
|
+
export const DiagramEditorBridge = DiagramContext;
|
|
29
|
+
/**
|
|
30
|
+
* Strict accessor — throws when called outside any provider. Use for
|
|
31
|
+
* imperative paths that *require* the editor right now (`editor.addElement`,
|
|
32
|
+
* `editor.screenToWorld`, etc).
|
|
33
|
+
*/
|
|
34
|
+
export const useDiagramContext = () => {
|
|
35
|
+
const editor = useContext(DiagramContext);
|
|
36
|
+
if (!editor) {
|
|
37
|
+
throw new Error("@oh-just-another/react-ui: hook called outside <DiagramProvider> / <DiagramRoot>, " +
|
|
38
|
+
"or before <DiagramSurface> mounted.");
|
|
39
|
+
}
|
|
40
|
+
return editor;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Forgiving variant — returns `null` when the editor hasn't been created
|
|
44
|
+
* yet. Pair with safe defaults; used by the reactive hooks to render
|
|
45
|
+
* cleanly during the first frame.
|
|
46
|
+
*/
|
|
47
|
+
export const useDiagramContextOptional = () => useContext(DiagramContext);
|
|
48
|
+
/**
|
|
49
|
+
* "Subscribe to editor + select a value" helper. Re-runs `select` whenever
|
|
50
|
+
* the editor notifies a change; re-renders the caller when the projected
|
|
51
|
+
* value actually changes.
|
|
52
|
+
*
|
|
53
|
+
* The editor may be missing during the very first frame (before
|
|
54
|
+
* `<DiagramSurface>` registers with `<DiagramRoot>`). `defaultValue` is
|
|
55
|
+
* returned during that window.
|
|
56
|
+
*/
|
|
57
|
+
export const useEditorSelector = (select, defaultValue,
|
|
58
|
+
/**
|
|
59
|
+
* Optional typed event to subscribe to instead of the umbrella
|
|
60
|
+
* `change`. When omitted, falls back to `editor.subscribe(fn)`, which
|
|
61
|
+
* fires on every notify. Passing e.g. `"mode"` makes the hook re-run
|
|
62
|
+
* the selector only when the mode flipped, skipping selection /
|
|
63
|
+
* viewport / scene notifies entirely.
|
|
64
|
+
*/
|
|
65
|
+
event) => {
|
|
66
|
+
const editor = useDiagramContextOptional();
|
|
67
|
+
const [value, setValue] = useState(() => (editor ? select(editor) : defaultValue));
|
|
68
|
+
// Keep select / defaultValue in refs so the subscription effect runs only
|
|
69
|
+
// when the editor identity changes. Callers may pass fresh literals every
|
|
70
|
+
// render — that's fine.
|
|
71
|
+
const selectRef = useRef(select);
|
|
72
|
+
selectRef.current = select;
|
|
73
|
+
const defaultRef = useRef(defaultValue);
|
|
74
|
+
defaultRef.current = defaultValue;
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (!editor) {
|
|
77
|
+
setValue(defaultRef.current);
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
const update = () => {
|
|
81
|
+
const next = selectRef.current(editor);
|
|
82
|
+
setValue((prev) => (Object.is(prev, next) ? prev : next));
|
|
83
|
+
};
|
|
84
|
+
update();
|
|
85
|
+
// Typed event when given; umbrella subscribe otherwise. Both paths
|
|
86
|
+
// fire in lock-step (typed events fan out of the same notify() that
|
|
87
|
+
// runs the umbrella subscribers), so the typed path is just narrower.
|
|
88
|
+
if (event !== undefined) {
|
|
89
|
+
return editor.on(event, update);
|
|
90
|
+
}
|
|
91
|
+
return editor.subscribe(update);
|
|
92
|
+
}, [editor, event]);
|
|
93
|
+
return value;
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAG/F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,cAAc,GAAG,aAAa,CAAgB,IAAI,CAAC,CAAC;AAO1D,mDAAmD;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAwB,EAAE,EAAE;IAC5E,OAAO,KAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,YAAG,QAAQ,GAA2B,CAAC;AACtF,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAW,EAAE;IAC5C,MAAM,MAAM,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,oFAAoF;YAClF,qCAAqC,CACxC,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAkB,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AAEzF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,MAA6B,EAC7B,YAAe;AACf;;;;;;GAMG;AACH,KAA0B,EACvB,EAAE;IACL,MAAM,MAAM,GAAG,yBAAyB,EAAE,CAAC;IAC3C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAI,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IACtF,0EAA0E;IAC1E,0EAA0E;IAC1E,wBAAwB;IACxB,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;IAC3B,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IACxC,UAAU,CAAC,OAAO,GAAG,YAAY,CAAC;IAElC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACvC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC,CAAC;QACF,MAAM,EAAE,CAAC;QACT,mEAAmE;QACnE,oEAAoE;QACpE,sEAAsE;QACtE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAEpB,OAAO,KAAK,CAAC;AACf,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* modern-style 3-zone bar (left / center / right). Sits at the
|
|
4
|
+
* top or bottom of the canvas with a small inset margin. Each zone
|
|
5
|
+
* is an inline-flex row of buttons / button-groups; the wrapper
|
|
6
|
+
* keeps them at the edges + centred middle without flex shrinking
|
|
7
|
+
* (passing `null` for a zone collapses that slot cleanly).
|
|
8
|
+
*
|
|
9
|
+
* `pointer-events: none` on the bar itself means clicks pass
|
|
10
|
+
* through to the canvas; only the buttons inside the zones receive
|
|
11
|
+
* events. The CSS handles that via `du-bar > * { pointer-events:
|
|
12
|
+
* auto }` so authors don't have to think about it.
|
|
13
|
+
*/
|
|
14
|
+
export interface DiagramBarProps {
|
|
15
|
+
readonly left?: ReactNode;
|
|
16
|
+
readonly center?: ReactNode;
|
|
17
|
+
readonly right?: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
export declare const TopBar: ({ left, center, right }: DiagramBarProps) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export declare const BottomBar: ({ left, center, right }: DiagramBarProps) => import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=diagram-bars.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram-bars.d.ts","sourceRoot":"","sources":["../src/diagram-bars.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,eAAO,MAAM,MAAM,GAAI,yBAAyB,eAAe,4CAU9D,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,yBAAyB,eAAe,4CAUjE,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export const TopBar = ({ left, center, right }) => (_jsxs("div", { className: "du-bar du-bar-top", children: [_jsx("div", { className: "du-bar-zone", children: left }), center !== undefined && center !== null ? (_jsx("div", { className: "du-bar-zone du-bar-zone-center", children: center })) : (_jsx("div", {})), _jsx("div", { className: "du-bar-zone", children: right })] }));
|
|
3
|
+
export const BottomBar = ({ left, center, right }) => (_jsxs("div", { className: "du-bar du-bar-bottom", children: [_jsx("div", { className: "du-bar-zone", children: left }), center !== undefined && center !== null ? (_jsx("div", { className: "du-bar-zone du-bar-zone-center", children: center })) : (_jsx("div", {})), _jsx("div", { className: "du-bar-zone", children: right })] }));
|
|
4
|
+
//# sourceMappingURL=diagram-bars.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram-bars.js","sourceRoot":"","sources":["../src/diagram-bars.tsx"],"names":[],"mappings":";AAoBA,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAmB,EAAE,EAAE,CAAC,CAClE,eAAK,SAAS,EAAC,mBAAmB,aAChC,cAAK,SAAS,EAAC,aAAa,YAAE,IAAI,GAAO,EACxC,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CACzC,cAAK,SAAS,EAAC,gCAAgC,YAAE,MAAM,GAAO,CAC/D,CAAC,CAAC,CAAC,CACF,eAAO,CACR,EACD,cAAK,SAAS,EAAC,aAAa,YAAE,KAAK,GAAO,IACtC,CACP,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAmB,EAAE,EAAE,CAAC,CACrE,eAAK,SAAS,EAAC,sBAAsB,aACnC,cAAK,SAAS,EAAC,aAAa,YAAE,IAAI,GAAO,EACxC,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CACzC,cAAK,SAAS,EAAC,gCAAgC,YAAE,MAAM,GAAO,CAC/D,CAAC,CAAC,CAAC,CACF,eAAO,CACR,EACD,cAAK,SAAS,EAAC,aAAa,YAAE,KAAK,GAAO,IACtC,CACP,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
import type { Editor, Mode } from "@oh-just-another/state";
|
|
3
|
+
import type { Scene } from "@oh-just-another/scene";
|
|
4
|
+
/**
|
|
5
|
+
* Convenience one-component setup for the simple case where the canvas is
|
|
6
|
+
* the **only** content (no side panels or floating toolbar). Equivalent to:
|
|
7
|
+
*
|
|
8
|
+
* ```tsx
|
|
9
|
+
* <DiagramRoot initialScene={s}>
|
|
10
|
+
* <DiagramSurface style={style} />
|
|
11
|
+
* </DiagramRoot>
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* For layouts with a palette / property panel / toolbar living next to the
|
|
15
|
+
* canvas, prefer `<DiagramRoot>` + `<DiagramSurface>` directly — that lets
|
|
16
|
+
* the side panels be flex siblings of the canvas surface instead of being
|
|
17
|
+
* covered by the underlying canvas elements.
|
|
18
|
+
*/
|
|
19
|
+
export interface DiagramCanvasProps {
|
|
20
|
+
readonly initialScene: Scene;
|
|
21
|
+
readonly initialMode?: Mode;
|
|
22
|
+
readonly onReady?: (editor: Editor) => void;
|
|
23
|
+
readonly style?: CSSProperties;
|
|
24
|
+
readonly className?: string;
|
|
25
|
+
readonly skipInstallRenderers?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Optional React subtree rendered **as a sibling** of the canvas surface
|
|
28
|
+
* inside a shared `<DiagramRoot>`. Useful when the host wants e.g. a
|
|
29
|
+
* floating toolbar with `position: absolute` over the surface.
|
|
30
|
+
*
|
|
31
|
+
* Note: anything that needs to share horizontal space with the canvas
|
|
32
|
+
* (palettes, inspectors) should be placed alongside a `<DiagramSurface>`
|
|
33
|
+
* inside a `<DiagramRoot>` instead — using this `children` prop overlays
|
|
34
|
+
* them, which is rarely what you want.
|
|
35
|
+
*/
|
|
36
|
+
readonly children?: ReactNode;
|
|
37
|
+
}
|
|
38
|
+
export declare const DiagramCanvas: ({ initialScene, initialMode, onReady, style, className, skipInstallRenderers, children, }: DiagramCanvasProps) => import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
//# sourceMappingURL=diagram-canvas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram-canvas.d.ts","sourceRoot":"","sources":["../src/diagram-canvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAGpD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC;;;;;;;;;OASG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;CAC/B;AAED,eAAO,MAAM,aAAa,GAAI,2FAQ3B,kBAAkB,4CAoBpB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { DiagramRoot, DiagramSurface } from "./diagram-root.js";
|
|
3
|
+
export const DiagramCanvas = ({ initialScene, initialMode, onReady, style, className, skipInstallRenderers, children, }) => (_jsx(DiagramRoot, { initialScene: initialScene, ...(initialMode !== undefined ? { initialMode } : {}), ...(onReady !== undefined ? { onReady } : {}), ...(skipInstallRenderers !== undefined ? { skipInstallRenderers } : {}), children: _jsxs("div", { className: className, style: {
|
|
4
|
+
position: "relative",
|
|
5
|
+
width: "100%",
|
|
6
|
+
height: "100%",
|
|
7
|
+
...style,
|
|
8
|
+
}, children: [_jsx(DiagramSurface, {}), children] }) }));
|
|
9
|
+
//# sourceMappingURL=diagram-canvas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram-canvas.js","sourceRoot":"","sources":["../src/diagram-canvas.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAqChE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAC5B,YAAY,EACZ,WAAW,EACX,OAAO,EACP,KAAK,EACL,SAAS,EACT,oBAAoB,EACpB,QAAQ,GACW,EAAE,EAAE,CAAC,CACxB,KAAC,WAAW,IACV,YAAY,EAAE,YAAY,KACtB,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAClD,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAC1C,CAAC,oBAAoB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,YAExE,eACE,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,MAAM;YACd,GAAG,KAAK;SACT,aAED,KAAC,cAAc,KAAG,EACjB,QAAQ,IACL,GACM,CACf,CAAC"}
|