@mocanvas/mocanvas 1.0.0 → 4.0.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.
@@ -0,0 +1,1340 @@
1
+ import { pathWordsToSvgD, getGeoGeometry } from './chunk-OMUOD53T.js';
2
+ import { GEO_SHAPE_KINDS, EditorPortal, useEditor, useValue, getLocaleChain, resolveUiMessage, useActions, useTools, useIsToolSelected } from '@mocanvas/editor';
3
+ import { createContext, useState, useCallback, useMemo, useContext, useRef, useEffect, useLayoutEffect, useId } from 'react';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+
6
+ var DialogsContext = createContext(null);
7
+ var NOOP = { addDialog: () => "", removeDialog: () => {
8
+ }, clearDialogs: () => {
9
+ }, dialogs: [] };
10
+ var nextDialogId = 0;
11
+ function TldrawUiDialogsProvider({ children }) {
12
+ const [dialogs, setDialogs] = useState([]);
13
+ const removeDialog = useCallback((id) => {
14
+ setDialogs((current) => {
15
+ current.find((dialog) => dialog.id === id)?.onClose?.();
16
+ return current.filter((dialog) => dialog.id !== id);
17
+ });
18
+ }, []);
19
+ const addDialog = useCallback((dialog) => {
20
+ const id = dialog.id ?? `dialog:${nextDialogId++}`;
21
+ setDialogs((current) => [...current.filter((d) => d.id !== id), { ...dialog, id }]);
22
+ return id;
23
+ }, []);
24
+ const clearDialogs = useCallback(() => {
25
+ setDialogs((current) => {
26
+ for (const dialog of current) dialog.onClose?.();
27
+ return [];
28
+ });
29
+ }, []);
30
+ const value = useMemo(
31
+ () => ({ addDialog, removeDialog, clearDialogs, dialogs }),
32
+ [addDialog, removeDialog, clearDialogs, dialogs]
33
+ );
34
+ return /* @__PURE__ */ jsx(DialogsContext.Provider, { value, children });
35
+ }
36
+ function useDialogs() {
37
+ return useContext(DialogsContext) ?? NOOP;
38
+ }
39
+ var FOCUSABLE = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
40
+ function DialogFrame({ dialog, onClose }) {
41
+ const ref = useRef(null);
42
+ const returnFocusTo = useRef(null);
43
+ useEffect(() => {
44
+ returnFocusTo.current = ref.current?.ownerDocument.activeElement ?? null;
45
+ const first = ref.current?.querySelector(FOCUSABLE);
46
+ (first ?? ref.current)?.focus();
47
+ return () => {
48
+ const previous = returnFocusTo.current;
49
+ if (previous instanceof HTMLElement) previous.focus();
50
+ };
51
+ }, []);
52
+ const onKeyDown = (event) => {
53
+ if (event.key === "Escape") {
54
+ event.stopPropagation();
55
+ onClose();
56
+ return;
57
+ }
58
+ if (event.key !== "Tab") return;
59
+ const items = Array.from(ref.current?.querySelectorAll(FOCUSABLE) ?? []);
60
+ if (items.length === 0) return;
61
+ const first = items[0];
62
+ const last = items[items.length - 1];
63
+ const active = ref.current?.ownerDocument.activeElement;
64
+ if (event.shiftKey && active === first) {
65
+ event.preventDefault();
66
+ last.focus();
67
+ } else if (!event.shiftKey && active === last) {
68
+ event.preventDefault();
69
+ first.focus();
70
+ }
71
+ };
72
+ const Component = dialog.component;
73
+ return /* @__PURE__ */ jsx(
74
+ "div",
75
+ {
76
+ className: "mocanvas-dialog-backdrop",
77
+ onPointerDown: (event) => {
78
+ if (event.target === event.currentTarget && !dialog.preventBackdropClose) onClose();
79
+ },
80
+ children: /* @__PURE__ */ jsx("div", { ref, className: "mocanvas-dialog mocanvas-panel", role: "dialog", "aria-modal": "true", tabIndex: -1, onKeyDown, children: /* @__PURE__ */ jsx(Component, { onClose }) })
81
+ }
82
+ );
83
+ }
84
+ function DefaultDialogs() {
85
+ const { dialogs, removeDialog } = useDialogs();
86
+ if (dialogs.length === 0) return null;
87
+ return /* @__PURE__ */ jsx(EditorPortal, { children: dialogs.map((dialog) => /* @__PURE__ */ jsx(DialogFrame, { dialog, onClose: () => removeDialog(dialog.id) }, dialog.id)) });
88
+ }
89
+ function TldrawUiDialogHeader({ className, children }) {
90
+ return /* @__PURE__ */ jsx("div", { className: className ? `mocanvas-dialog-header ${className}` : "mocanvas-dialog-header", children });
91
+ }
92
+ function TldrawUiDialogTitle({ className, children }) {
93
+ return /* @__PURE__ */ jsx("h2", { className: className ? `mocanvas-dialog-title ${className}` : "mocanvas-dialog-title", children });
94
+ }
95
+ function TldrawUiDialogCloseButton() {
96
+ const { dialogs, removeDialog } = useDialogs();
97
+ const top = dialogs[dialogs.length - 1];
98
+ return /* @__PURE__ */ jsx(
99
+ "button",
100
+ {
101
+ type: "button",
102
+ className: "mocanvas-btn mocanvas-dialog-close",
103
+ "aria-label": "Close",
104
+ onClick: () => {
105
+ if (top) removeDialog(top.id);
106
+ },
107
+ children: "\xD7"
108
+ }
109
+ );
110
+ }
111
+ function TldrawUiDialogBody({ className, style, children }) {
112
+ return /* @__PURE__ */ jsx("div", { className: className ? `mocanvas-dialog-body ${className}` : "mocanvas-dialog-body", style, children });
113
+ }
114
+ function TldrawUiDialogFooter({ className, children }) {
115
+ return /* @__PURE__ */ jsx("div", { className: className ? `mocanvas-dialog-footer ${className}` : "mocanvas-dialog-footer", children });
116
+ }
117
+ function ExampleDialog({
118
+ title = "Title",
119
+ body = "Description",
120
+ confirmLabel = "Continue",
121
+ cancelLabel = "Cancel",
122
+ displayDontShowAgain = false,
123
+ onCancel,
124
+ onContinue,
125
+ onClose
126
+ }) {
127
+ const [dontShowAgain, setDontShowAgain] = useState(false);
128
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
129
+ /* @__PURE__ */ jsxs(TldrawUiDialogHeader, { children: [
130
+ /* @__PURE__ */ jsx(TldrawUiDialogTitle, { children: title }),
131
+ /* @__PURE__ */ jsx(TldrawUiDialogCloseButton, {})
132
+ ] }),
133
+ /* @__PURE__ */ jsx(TldrawUiDialogBody, { children: body }),
134
+ /* @__PURE__ */ jsxs(TldrawUiDialogFooter, { children: [
135
+ displayDontShowAgain ? /* @__PURE__ */ jsxs("label", { className: "mocanvas-dialog-checkbox", children: [
136
+ /* @__PURE__ */ jsx("input", { type: "checkbox", checked: dontShowAgain, onChange: (event) => setDontShowAgain(event.target.checked) }),
137
+ "Don\u2019t show again"
138
+ ] }) : null,
139
+ /* @__PURE__ */ jsx(
140
+ "button",
141
+ {
142
+ type: "button",
143
+ className: "mocanvas-btn mocanvas-btn--wide",
144
+ onClick: () => {
145
+ onCancel?.();
146
+ onClose();
147
+ },
148
+ children: cancelLabel
149
+ }
150
+ ),
151
+ /* @__PURE__ */ jsx(
152
+ "button",
153
+ {
154
+ type: "button",
155
+ className: "mocanvas-btn mocanvas-btn--wide",
156
+ onClick: () => {
157
+ onContinue?.();
158
+ onClose();
159
+ },
160
+ children: confirmLabel
161
+ }
162
+ )
163
+ ] })
164
+ ] });
165
+ }
166
+ var ICON_GRID = 24;
167
+ var GEO_BOX = 16;
168
+ var solid = { fill: "currentColor", stroke: "none" };
169
+ var TOOL_ICONS = {
170
+ select: /* @__PURE__ */ jsx("path", { d: "M6.65 4.05v13.95l3.54-3.35 2.41 5.3 2.33-1.02-2.42-5.21 4.84-.19z" }),
171
+ hand: /* @__PURE__ */ jsx("path", { d: "M8.35 14.6V9.5a1.3 1.3 0 0 1 2.6 0V5.3a1.3 1.3 0 0 1 2.6 0v.5a1.3 1.3 0 0 1 2.6 0v1.9a1.3 1.3 0 0 1 2.6 0v6.75c0 3.15-2.55 5.7-5.7 5.7h-.6c-1.9 0-3.68-.96-4.72-2.55l-1.75-2.65a1.3 1.3 0 0 1 2.17-1.42z" }),
172
+ draw: /* @__PURE__ */ jsxs(Fragment, { children: [
173
+ /* @__PURE__ */ jsx("path", { d: "M4.4 19.6l1.05-3.8L15.5 5.75a2 2 0 0 1 2.83 2.83L8.2 18.55z" }),
174
+ /* @__PURE__ */ jsx("path", { d: "M13.55 7.7l2.83 2.83" })
175
+ ] }),
176
+ eraser: /* @__PURE__ */ jsxs(Fragment, { children: [
177
+ /* @__PURE__ */ jsxs("g", { transform: "translate(12 10.5) rotate(-45)", children: [
178
+ /* @__PURE__ */ jsx("rect", { x: "-5.75", y: "-3.5", width: "11.5", height: "7", rx: "1.6" }),
179
+ /* @__PURE__ */ jsx("path", { d: "M0 -3.5V3.5" })
180
+ ] }),
181
+ /* @__PURE__ */ jsx("path", { d: "M7 19.4h10.5" })
182
+ ] }),
183
+ text: /* @__PURE__ */ jsxs(Fragment, { children: [
184
+ /* @__PURE__ */ jsx("path", { d: "M5 6.25V4.5h14v1.75" }),
185
+ /* @__PURE__ */ jsx("path", { d: "M12 4.5v15" }),
186
+ /* @__PURE__ */ jsx("path", { d: "M8.75 19.5h6.5" })
187
+ ] }),
188
+ note: /* @__PURE__ */ jsxs(Fragment, { children: [
189
+ /* @__PURE__ */ jsx("path", { d: "M4.5 5.75A1.75 1.75 0 0 1 6.25 4h11.5a1.75 1.75 0 0 1 1.75 1.75v8L13.5 20H6.25A1.75 1.75 0 0 1 4.5 18.25z" }),
190
+ /* @__PURE__ */ jsx("path", { d: "M19.5 13.75h-4.25a1.75 1.75 0 0 0-1.75 1.75V20" })
191
+ ] }),
192
+ frame: /* @__PURE__ */ jsxs(Fragment, { children: [
193
+ /* @__PURE__ */ jsx("path", { d: "M8 4.5v15M16 4.5v15" }),
194
+ /* @__PURE__ */ jsx("path", { d: "M4.5 8h15M4.5 16h15" })
195
+ ] }),
196
+ arrow: /* @__PURE__ */ jsxs(Fragment, { children: [
197
+ /* @__PURE__ */ jsx("path", { d: "M5.15 18.85L18.85 5.15" }),
198
+ /* @__PURE__ */ jsx("path", { d: "M12 5.15h6.85V12" })
199
+ ] }),
200
+ line: /* @__PURE__ */ jsxs(Fragment, { children: [
201
+ /* @__PURE__ */ jsx("path", { d: "M7.6 16.4L16.4 7.6" }),
202
+ /* @__PURE__ */ jsx("circle", { cx: "5.85", cy: "18.15", r: "1.85" }),
203
+ /* @__PURE__ */ jsx("circle", { cx: "18.15", cy: "5.85", r: "1.85" })
204
+ ] }),
205
+ image: /* @__PURE__ */ jsxs(Fragment, { children: [
206
+ /* @__PURE__ */ jsx("rect", { x: "3.9", y: "5.25", width: "16.2", height: "13.5", rx: "2.25" }),
207
+ /* @__PURE__ */ jsx("circle", { cx: "8.9", cy: "10", r: "1.55" }),
208
+ /* @__PURE__ */ jsx("path", { d: "M4 16.2l4.75-4.2 3.75 3.25 3-2.5 4.6 4.05" })
209
+ ] })
210
+ };
211
+ var ACTION_ICONS = {
212
+ "zoom-in": /* @__PURE__ */ jsxs(Fragment, { children: [
213
+ /* @__PURE__ */ jsx("circle", { cx: "10.75", cy: "10.75", r: "6.25" }),
214
+ /* @__PURE__ */ jsx("path", { d: "M15.4 15.4l5.1 5.1" }),
215
+ /* @__PURE__ */ jsx("path", { d: "M8 10.75h5.5M10.75 8v5.5" })
216
+ ] }),
217
+ "zoom-out": /* @__PURE__ */ jsxs(Fragment, { children: [
218
+ /* @__PURE__ */ jsx("circle", { cx: "10.75", cy: "10.75", r: "6.25" }),
219
+ /* @__PURE__ */ jsx("path", { d: "M15.4 15.4l5.1 5.1" }),
220
+ /* @__PURE__ */ jsx("path", { d: "M8 10.75h5.5" })
221
+ ] }),
222
+ "zoom-fit": /* @__PURE__ */ jsx("path", { d: "M4 9V5.5A1.5 1.5 0 0 1 5.5 4H9M15 4h3.5A1.5 1.5 0 0 1 20 5.5V9M20 15v3.5a1.5 1.5 0 0 1-1.5 1.5H15M9 20H5.5A1.5 1.5 0 0 1 4 18.5V15" }),
223
+ undo: /* @__PURE__ */ jsxs(Fragment, { children: [
224
+ /* @__PURE__ */ jsx("path", { d: "M4.25 8.75h10.25a5.25 5.25 0 0 1 0 10.5H10" }),
225
+ /* @__PURE__ */ jsx("path", { d: "M8.25 4.75L4.25 8.75l4 4" })
226
+ ] }),
227
+ redo: /* @__PURE__ */ jsxs(Fragment, { children: [
228
+ /* @__PURE__ */ jsx("path", { d: "M19.75 8.75H9.5a5.25 5.25 0 0 0 0 10.5H14" }),
229
+ /* @__PURE__ */ jsx("path", { d: "M15.75 4.75l4 4-4 4" })
230
+ ] }),
231
+ lock: /* @__PURE__ */ jsxs(Fragment, { children: [
232
+ /* @__PURE__ */ jsx("rect", { x: "4.75", y: "10.5", width: "14.5", height: "9.5", rx: "2.25" }),
233
+ /* @__PURE__ */ jsx("path", { d: "M8.25 10.5V7.75a3.75 3.75 0 0 1 7.5 0v2.75" })
234
+ ] }),
235
+ unlock: /* @__PURE__ */ jsxs(Fragment, { children: [
236
+ /* @__PURE__ */ jsx("rect", { x: "4.75", y: "10.5", width: "14.5", height: "9.5", rx: "2.25" }),
237
+ /* @__PURE__ */ jsx("path", { d: "M8.25 10.5V7.75a3.75 3.75 0 0 1 7.15-1.5" })
238
+ ] }),
239
+ duplicate: /* @__PURE__ */ jsxs(Fragment, { children: [
240
+ /* @__PURE__ */ jsx("rect", { x: "8.5", y: "8.5", width: "11.5", height: "11.5", rx: "2.25" }),
241
+ /* @__PURE__ */ jsx("path", { d: "M15.5 4H6.25A2.25 2.25 0 0 0 4 6.25V15.5" })
242
+ ] }),
243
+ trash: /* @__PURE__ */ jsxs(Fragment, { children: [
244
+ /* @__PURE__ */ jsx("path", { d: "M4.5 7h15" }),
245
+ /* @__PURE__ */ jsx("path", { d: "M9.5 7V5.75A1.5 1.5 0 0 1 11 4.25h2a1.5 1.5 0 0 1 1.5 1.5V7" }),
246
+ /* @__PURE__ */ jsx("path", { d: "M6.75 7l.75 11.5A1.5 1.5 0 0 0 9 20h6a1.5 1.5 0 0 0 1.5-1.5L17.25 7" }),
247
+ /* @__PURE__ */ jsx("path", { d: "M10.25 10.5v6M13.75 10.5v6" })
248
+ ] }),
249
+ group: /* @__PURE__ */ jsxs(Fragment, { children: [
250
+ /* @__PURE__ */ jsx("rect", { x: "4", y: "4", width: "16", height: "16", rx: "2", strokeDasharray: "3 3" }),
251
+ /* @__PURE__ */ jsx("rect", { x: "7", y: "7", width: "4.5", height: "4.5", rx: "1" }),
252
+ /* @__PURE__ */ jsx("rect", { x: "12.5", y: "12.5", width: "4.5", height: "4.5", rx: "1" })
253
+ ] }),
254
+ ungroup: /* @__PURE__ */ jsxs(Fragment, { children: [
255
+ /* @__PURE__ */ jsx("path", { d: "M4 8V5.25A1.25 1.25 0 0 1 5.25 4H8M16 4h2.75A1.25 1.25 0 0 1 20 5.25V8M20 16v2.75A1.25 1.25 0 0 1 18.75 20H16M8 20H5.25A1.25 1.25 0 0 1 4 18.75V16" }),
256
+ /* @__PURE__ */ jsx("rect", { x: "7", y: "7", width: "4.5", height: "4.5", rx: "1" }),
257
+ /* @__PURE__ */ jsx("rect", { x: "12.5", y: "12.5", width: "4.5", height: "4.5", rx: "1" })
258
+ ] }),
259
+ "bring-forward": /* @__PURE__ */ jsxs(Fragment, { children: [
260
+ /* @__PURE__ */ jsx("rect", { x: "4.75", y: "11.25", width: "14.5", height: "8.75", rx: "2.25" }),
261
+ /* @__PURE__ */ jsx("path", { d: "M12 9V4M8.75 7.25L12 4l3.25 3.25" })
262
+ ] }),
263
+ "send-backward": /* @__PURE__ */ jsxs(Fragment, { children: [
264
+ /* @__PURE__ */ jsx("rect", { x: "4.75", y: "4", width: "14.5", height: "8.75", rx: "2.25" }),
265
+ /* @__PURE__ */ jsx("path", { d: "M12 15v5M8.75 16.75L12 20l3.25-3.25" })
266
+ ] }),
267
+ "chevron-down": /* @__PURE__ */ jsx("path", { d: "M6.75 9.75L12 15l5.25-5.25" }),
268
+ "chevron-up": /* @__PURE__ */ jsx("path", { d: "M6.75 14.25L12 9l5.25 5.25" }),
269
+ check: /* @__PURE__ */ jsx("path", { d: "M5 12.5l4.9 4.9L19 6.75" }),
270
+ close: /* @__PURE__ */ jsx("path", { d: "M6.5 6.5l11 11M17.5 6.5l-11 11" }),
271
+ mixed: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "7.25", strokeDasharray: "2.6 2.8" })
272
+ };
273
+ var FILL_BOX = { x: 4.25, y: 4.25, width: 15.5, height: 15.5, rx: 3 };
274
+ var STYLE_ICONS = {
275
+ "fill-none": /* @__PURE__ */ jsx("rect", { ...FILL_BOX }),
276
+ "fill-semi": /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("rect", { ...FILL_BOX, fill: "currentColor", fillOpacity: 0.22 }) }),
277
+ "fill-solid": /* @__PURE__ */ jsx("rect", { ...FILL_BOX, fill: "currentColor" }),
278
+ // Hatching is texture, not outline: a lighter stroke keeps the block's weight
279
+ // level with the other three fill icons.
280
+ "fill-pattern": /* @__PURE__ */ jsxs(Fragment, { children: [
281
+ /* @__PURE__ */ jsx("rect", { ...FILL_BOX }),
282
+ /* @__PURE__ */ jsx("path", { d: "M6.2 12.6l6.4-6.4M6.2 17.1l10.9-10.9M9.4 18.3l8.9-8.9M14.6 18.4l3.7-3.7", strokeWidth: 1.25 })
283
+ ] }),
284
+ "dash-draw": /* @__PURE__ */ jsx("path", { d: "M4 14.9c1.6-3.4 3.2-4.9 4.9-4.4 1.7.4 2.4 4 4.2 4.4 1.9.4 3.9-1.9 6.9-5.9" }),
285
+ "dash-solid": /* @__PURE__ */ jsx("path", { d: "M4.25 12h15.5" }),
286
+ "dash-dashed": /* @__PURE__ */ jsx("path", { d: "M4.5 12h15", strokeDasharray: "3.1 2.8" }),
287
+ // Round caps on a zero-length dash draw the dots; the wider stroke is the dot.
288
+ "dash-dotted": /* @__PURE__ */ jsx("path", { d: "M5 12h14", strokeDasharray: "0.01 4.35", strokeWidth: 2.6 }),
289
+ "size-s": /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "2", ...solid }),
290
+ "size-m": /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3.4", ...solid }),
291
+ "size-l": /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "4.9", ...solid }),
292
+ "size-xl": /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "6.6", ...solid }),
293
+ "align-left": /* @__PURE__ */ jsx("path", { d: "M4.5 6.5h15M4.5 12h7.5M4.5 17.5h11.5" }),
294
+ "align-center": /* @__PURE__ */ jsx("path", { d: "M4.5 6.5h15M8.25 12h7.5M6.25 17.5h11.5" }),
295
+ "align-right": /* @__PURE__ */ jsx("path", { d: "M4.5 6.5h15M12 12h7.5M8 17.5h11.5" }),
296
+ "valign-top": /* @__PURE__ */ jsxs(Fragment, { children: [
297
+ /* @__PURE__ */ jsx("path", { d: "M4.5 4.5h15" }),
298
+ /* @__PURE__ */ jsx("rect", { x: "7.5", y: "7.75", width: "9", height: "6.25", rx: "1.5" })
299
+ ] }),
300
+ "valign-middle": /* @__PURE__ */ jsxs(Fragment, { children: [
301
+ /* @__PURE__ */ jsx("path", { d: "M4.5 12h15" }),
302
+ /* @__PURE__ */ jsx("rect", { x: "7.5", y: "8.9", width: "9", height: "6.25", rx: "1.5" })
303
+ ] }),
304
+ "valign-bottom": /* @__PURE__ */ jsxs(Fragment, { children: [
305
+ /* @__PURE__ */ jsx("path", { d: "M4.5 19.5h15" }),
306
+ /* @__PURE__ */ jsx("rect", { x: "7.5", y: "10", width: "9", height: "6.25", rx: "1.5" })
307
+ ] }),
308
+ // A single-storey script "a": the other three fonts share the capital-A
309
+ // silhouette, so the handwriting option needs a different letter to stay
310
+ // legible at 20px.
311
+ "font-draw": /* @__PURE__ */ jsxs(Fragment, { children: [
312
+ /* @__PURE__ */ jsx("circle", { cx: "10.6", cy: "12.6", r: "4.4" }),
313
+ /* @__PURE__ */ jsx("path", { d: "M15 6.3v8.9c0 1.5 1 2.5 2.5 2.5" })
314
+ ] }),
315
+ "font-sans": /* @__PURE__ */ jsxs(Fragment, { children: [
316
+ /* @__PURE__ */ jsx("path", { d: "M5.5 19L12 5l6.5 14" }),
317
+ /* @__PURE__ */ jsx("path", { d: "M8 14.5h8" })
318
+ ] }),
319
+ "font-serif": /* @__PURE__ */ jsxs(Fragment, { children: [
320
+ /* @__PURE__ */ jsx("path", { d: "M6.75 19L12 5l5.25 14" }),
321
+ /* @__PURE__ */ jsx("path", { d: "M8.7 14.5h6.6" }),
322
+ /* @__PURE__ */ jsx("path", { d: "M4.9 19h3.6M15.5 19h3.6" })
323
+ ] }),
324
+ "font-mono": /* @__PURE__ */ jsxs(Fragment, { children: [
325
+ /* @__PURE__ */ jsx("path", { d: "M8 19l4-13 4 13" }),
326
+ /* @__PURE__ */ jsx("path", { d: "M9.6 14.9h4.8" }),
327
+ /* @__PURE__ */ jsx("path", { d: "M4.75 5.75v12.5M19.25 5.75v12.5", strokeWidth: 1.4 })
328
+ ] })
329
+ };
330
+ var GEO_ICON_BOX = {
331
+ rectangle: [GEO_BOX, 12],
332
+ oval: [GEO_BOX, 10.5],
333
+ "arrow-left": [GEO_BOX, 13],
334
+ "arrow-right": [GEO_BOX, 13],
335
+ "arrow-up": [13, GEO_BOX],
336
+ "arrow-down": [13, GEO_BOX]
337
+ };
338
+ function getGeoIconBox(kind) {
339
+ return GEO_ICON_BOX[kind] ?? [GEO_BOX, GEO_BOX];
340
+ }
341
+ var GEO_ICON_PATHS = Object.fromEntries(
342
+ GEO_SHAPE_KINDS.map((kind) => {
343
+ const [w, h] = getGeoIconBox(kind);
344
+ return [kind, pathWordsToSvgD(getGeoGeometry(kind, w, h, false).toPathWords())];
345
+ })
346
+ );
347
+ var GEO_ICONS = Object.fromEntries(
348
+ GEO_SHAPE_KINDS.map((kind) => {
349
+ const [w, h] = getGeoIconBox(kind);
350
+ return [
351
+ `geo-${kind}`,
352
+ /* @__PURE__ */ jsx("g", { transform: `translate(${(ICON_GRID - w) / 2} ${(ICON_GRID - h) / 2})`, children: /* @__PURE__ */ jsx("path", { d: GEO_ICON_PATHS[kind] }) })
353
+ ];
354
+ })
355
+ );
356
+ var ICONS = { ...TOOL_ICONS, ...ACTION_ICONS, ...STYLE_ICONS, ...GEO_ICONS };
357
+ var ICON_NAMES = Object.keys(ICONS).sort();
358
+ function Icon({ name, size = 20, className }) {
359
+ return /* @__PURE__ */ jsx(
360
+ "svg",
361
+ {
362
+ className: className ? `mocanvas-icon ${className}` : "mocanvas-icon",
363
+ width: size,
364
+ height: size,
365
+ viewBox: "0 0 24 24",
366
+ fill: "none",
367
+ stroke: "currentColor",
368
+ strokeWidth: 1.75,
369
+ strokeLinecap: "round",
370
+ strokeLinejoin: "round",
371
+ "aria-hidden": "true",
372
+ focusable: "false",
373
+ children: ICONS[name]
374
+ }
375
+ );
376
+ }
377
+ function isUrl(icon) {
378
+ return icon.includes("/") || icon.includes(".");
379
+ }
380
+ function TldrawUiIcon({ icon, label, small, invertIcon, className, style, color }) {
381
+ const classes = ["mocanvas-icon", small ? "mocanvas-icon--small" : null, className].filter(Boolean).join(" ");
382
+ const transform = invertIcon ? "scaleX(-1)" : void 0;
383
+ const size = small ? 16 : 20;
384
+ if (Object.prototype.hasOwnProperty.call(ICONS, icon)) {
385
+ return /* @__PURE__ */ jsx("span", { className: classes, style: { ...style, color, transform, display: "inline-flex" }, ...label ? { role: "img", "aria-label": label } : { "aria-hidden": true }, children: /* @__PURE__ */ jsx(Icon, { name: icon, size }) });
386
+ }
387
+ if (isUrl(icon)) {
388
+ return /* @__PURE__ */ jsx(
389
+ "img",
390
+ {
391
+ className: classes,
392
+ src: icon,
393
+ alt: label ?? "",
394
+ width: size,
395
+ height: size,
396
+ style: { ...style, transform },
397
+ ...label ? {} : { "aria-hidden": true }
398
+ }
399
+ );
400
+ }
401
+ return /* @__PURE__ */ jsx(
402
+ "span",
403
+ {
404
+ className: `${classes} mocanvas-icon--fallback`,
405
+ style: { ...style, color, transform, width: size, height: size, display: "inline-flex", alignItems: "center", justifyContent: "center", fontWeight: 600 },
406
+ ...label ? { role: "img", "aria-label": label } : { "aria-hidden": true },
407
+ children: (label ?? icon).slice(0, 1).toUpperCase()
408
+ }
409
+ );
410
+ }
411
+ function TldrawUiButton({
412
+ type = "normal",
413
+ isChecked,
414
+ isActive,
415
+ disabled,
416
+ title,
417
+ className,
418
+ style,
419
+ id,
420
+ tabIndex,
421
+ role,
422
+ ref,
423
+ onClick,
424
+ onPointerDown,
425
+ onPointerUp,
426
+ onKeyDown,
427
+ onFocus,
428
+ onBlur,
429
+ children,
430
+ ...rest
431
+ }) {
432
+ const label = rest["aria-label"] ?? title;
433
+ return /* @__PURE__ */ jsx(
434
+ "button",
435
+ {
436
+ ref,
437
+ type: "button",
438
+ id,
439
+ role,
440
+ tabIndex,
441
+ className: ["mocanvas-btn", `mocanvas-btn--${type}`, className].filter(Boolean).join(" "),
442
+ style,
443
+ disabled,
444
+ ...label ? { "aria-label": label, "data-tooltip": title ?? label } : {},
445
+ ...isChecked === void 0 ? {} : { "aria-pressed": isChecked },
446
+ ...isActive ? { "aria-current": true } : {},
447
+ onClick,
448
+ onPointerDown,
449
+ onPointerUp,
450
+ onKeyDown,
451
+ onFocus,
452
+ onBlur,
453
+ children
454
+ }
455
+ );
456
+ }
457
+ function TldrawUiButtonIcon({ icon, small, invertIcon, className }) {
458
+ return /* @__PURE__ */ jsx(TldrawUiIcon, { icon, ...small ? { small } : {}, ...invertIcon ? { invertIcon } : {}, className: ["mocanvas-btn-icon", className].filter(Boolean).join(" ") });
459
+ }
460
+ function TldrawUiButtonLabel({ className, children }) {
461
+ return /* @__PURE__ */ jsx("span", { className: ["mocanvas-btn-label", className].filter(Boolean).join(" "), children });
462
+ }
463
+ function TldrawUiButtonCheck({ checked, className }) {
464
+ return /* @__PURE__ */ jsx(
465
+ "span",
466
+ {
467
+ className: ["mocanvas-btn-check", className].filter(Boolean).join(" "),
468
+ "data-checked": checked,
469
+ "aria-hidden": "true",
470
+ style: { visibility: checked ? "visible" : "hidden", display: "inline-flex" },
471
+ children: /* @__PURE__ */ jsx(TldrawUiIcon, { icon: "check", small: true })
472
+ }
473
+ );
474
+ }
475
+ var GAP = 8;
476
+ var EDGE = 8;
477
+ function placeNear(anchor, box, prefer, vw, vh) {
478
+ const above = anchor.top - box.height - GAP;
479
+ const below = anchor.bottom + GAP;
480
+ let top = prefer === "above" ? above : below;
481
+ if (prefer === "above" && above < EDGE && below + box.height <= vh - EDGE) top = below;
482
+ if (prefer === "below" && below + box.height > vh - EDGE && above >= EDGE) top = above;
483
+ top = Math.min(Math.max(top, EDGE), Math.max(EDGE, vh - box.height - EDGE));
484
+ let left = anchor.left + anchor.width / 2 - box.width / 2;
485
+ left = Math.min(Math.max(left, EDGE), Math.max(EDGE, vw - box.width - EDGE));
486
+ return { left, top };
487
+ }
488
+ function useClamped(getAnchor, prefer, deps) {
489
+ const ref = useRef(null);
490
+ const [pos, setPos] = useState(null);
491
+ useLayoutEffect(() => {
492
+ const el = ref.current;
493
+ const anchor = getAnchor();
494
+ if (!el || !anchor) {
495
+ setPos(null);
496
+ return;
497
+ }
498
+ const box = el.getBoundingClientRect();
499
+ setPos(placeNear(anchor, box, prefer, window.innerWidth, window.innerHeight));
500
+ }, deps);
501
+ return [ref, pos];
502
+ }
503
+ var HOVER_DELAY = 500;
504
+ function UiTooltip() {
505
+ const [tip, setTip] = useState(null);
506
+ const timer = useRef(void 0);
507
+ const clear = useCallback(() => {
508
+ clearTimeout(timer.current);
509
+ setTip(null);
510
+ }, []);
511
+ useEffect(() => {
512
+ const read = (el) => {
513
+ const label = el.dataset["tooltip"];
514
+ if (!label) return null;
515
+ return { label, shortcut: el.dataset["shortcut"] ?? null, anchor: el.getBoundingClientRect() };
516
+ };
517
+ const target = (e) => {
518
+ const el = e.target?.closest?.("[data-tooltip]");
519
+ if (!el || el.matches(":disabled") || el.getAttribute("aria-disabled") === "true") return null;
520
+ return el;
521
+ };
522
+ const onOver = (e) => {
523
+ const el = target(e);
524
+ clearTimeout(timer.current);
525
+ if (!el) {
526
+ setTip(null);
527
+ return;
528
+ }
529
+ timer.current = setTimeout(() => setTip(read(el)), HOVER_DELAY);
530
+ };
531
+ const onFocus = (e) => {
532
+ const el = target(e);
533
+ clearTimeout(timer.current);
534
+ setTip(el && el.matches(":focus-visible") ? read(el) : null);
535
+ };
536
+ document.addEventListener("pointerover", onOver, true);
537
+ document.addEventListener("pointerdown", clear, true);
538
+ document.addEventListener("focusin", onFocus, true);
539
+ document.addEventListener("focusout", clear, true);
540
+ window.addEventListener("scroll", clear, true);
541
+ return () => {
542
+ clearTimeout(timer.current);
543
+ document.removeEventListener("pointerover", onOver, true);
544
+ document.removeEventListener("pointerdown", clear, true);
545
+ document.removeEventListener("focusin", onFocus, true);
546
+ document.removeEventListener("focusout", clear, true);
547
+ window.removeEventListener("scroll", clear, true);
548
+ };
549
+ }, [clear]);
550
+ const [ref, pos] = useClamped(() => tip?.anchor ?? null, "above", [tip]);
551
+ if (!tip) return null;
552
+ return /* @__PURE__ */ jsxs(
553
+ "div",
554
+ {
555
+ ref,
556
+ className: "mocanvas-tooltip mocanvas-layer",
557
+ role: "tooltip",
558
+ style: pos ? { left: pos.left, top: pos.top } : { left: 0, top: 0, visibility: "hidden" },
559
+ children: [
560
+ tip.label,
561
+ tip.shortcut ? /* @__PURE__ */ jsx("kbd", { children: tip.shortcut }) : null
562
+ ]
563
+ }
564
+ );
565
+ }
566
+ function Popover({ anchorRef, open, onClose, label, cols = 5, prefer = "above", children }) {
567
+ const [ref, pos] = useClamped(() => anchorRef.current?.getBoundingClientRect() ?? null, prefer, [open, anchorRef]);
568
+ useEffect(() => {
569
+ if (!open) return;
570
+ const onDown = (e) => {
571
+ const t = e.target;
572
+ if (ref.current?.contains(t) || anchorRef.current?.contains(t)) return;
573
+ onClose();
574
+ };
575
+ const onKey = (e) => {
576
+ if (e.key === "Escape") {
577
+ e.stopPropagation();
578
+ onClose();
579
+ anchorRef.current?.focus();
580
+ }
581
+ };
582
+ document.addEventListener("pointerdown", onDown, true);
583
+ document.addEventListener("keydown", onKey, true);
584
+ return () => {
585
+ document.removeEventListener("pointerdown", onDown, true);
586
+ document.removeEventListener("keydown", onKey, true);
587
+ };
588
+ }, [open, onClose, anchorRef, ref]);
589
+ if (!open) return null;
590
+ return /* @__PURE__ */ jsx(
591
+ "div",
592
+ {
593
+ ref,
594
+ className: "mocanvas-popover mocanvas-layer",
595
+ role: "menu",
596
+ "aria-label": label,
597
+ style: {
598
+ ["--mocanvas-popover-cols"]: cols,
599
+ ...pos ? { left: pos.left, top: pos.top } : { left: 0, top: 0, visibility: "hidden" }
600
+ },
601
+ onPointerDown: (e) => e.stopPropagation(),
602
+ children
603
+ }
604
+ );
605
+ }
606
+ function useAnchoredPosition(anchorRef, open, prefer) {
607
+ const ref = useRef(null);
608
+ const [pos, setPos] = useState(null);
609
+ useLayoutEffect(() => {
610
+ const el = ref.current;
611
+ const anchor = anchorRef.current?.getBoundingClientRect() ?? null;
612
+ if (!open || !el || !anchor) {
613
+ setPos(null);
614
+ return;
615
+ }
616
+ const box = el.getBoundingClientRect();
617
+ setPos(placeNear(anchor, box, prefer, window.innerWidth, window.innerHeight));
618
+ }, [open, prefer, anchorRef]);
619
+ return [ref, pos];
620
+ }
621
+ function useDismissable(open, layerRef, anchorRef, onClose) {
622
+ useEffect(() => {
623
+ if (!open) return;
624
+ const onDown = (event) => {
625
+ const target = event.target;
626
+ if (layerRef.current?.contains(target) || anchorRef.current?.contains(target)) return;
627
+ onClose();
628
+ };
629
+ const onKey = (event) => {
630
+ if (event.key !== "Escape") return;
631
+ event.stopPropagation();
632
+ onClose();
633
+ anchorRef.current?.focus();
634
+ };
635
+ document.addEventListener("pointerdown", onDown, true);
636
+ document.addEventListener("keydown", onKey, true);
637
+ return () => {
638
+ document.removeEventListener("pointerdown", onDown, true);
639
+ document.removeEventListener("keydown", onKey, true);
640
+ };
641
+ }, [open, layerRef, anchorRef, onClose]);
642
+ }
643
+ var FOCUSABLE2 = '[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"],[role="option"],button:not([disabled]),a[href],input:not([disabled])';
644
+ function useMenuKeyboard(open, layerRef) {
645
+ useEffect(() => {
646
+ if (!open) return;
647
+ const layer = layerRef.current;
648
+ if (!layer) return;
649
+ const items = () => Array.from(layer.querySelectorAll(FOCUSABLE2));
650
+ const first = items()[0];
651
+ first?.focus();
652
+ const onKey = (event) => {
653
+ const list = items();
654
+ if (list.length === 0) return;
655
+ const index = list.indexOf(layer.ownerDocument.activeElement);
656
+ if (event.key === "ArrowDown" || event.key === "ArrowRight") {
657
+ event.preventDefault();
658
+ list[(index + 1) % list.length]?.focus();
659
+ } else if (event.key === "ArrowUp" || event.key === "ArrowLeft") {
660
+ event.preventDefault();
661
+ list[(index - 1 + list.length) % list.length]?.focus();
662
+ } else if (event.key === "Home") {
663
+ event.preventDefault();
664
+ list[0]?.focus();
665
+ } else if (event.key === "End") {
666
+ event.preventDefault();
667
+ list[list.length - 1]?.focus();
668
+ }
669
+ };
670
+ layer.addEventListener("keydown", onKey);
671
+ return () => layer.removeEventListener("keydown", onKey);
672
+ }, [open, layerRef]);
673
+ }
674
+ function FloatingLayer({
675
+ anchorRef,
676
+ open,
677
+ onClose,
678
+ prefer = "below",
679
+ role = "menu",
680
+ label,
681
+ className,
682
+ keyboardNav = true,
683
+ children
684
+ }) {
685
+ const [ref, pos] = useAnchoredPosition(anchorRef, open, prefer);
686
+ useDismissable(open, ref, anchorRef, onClose);
687
+ useMenuKeyboard(keyboardNav && open, ref);
688
+ if (!open) return null;
689
+ return /* @__PURE__ */ jsx(EditorPortal, { children: /* @__PURE__ */ jsx(
690
+ "div",
691
+ {
692
+ ref,
693
+ className: ["mocanvas-layer", className].filter(Boolean).join(" "),
694
+ role,
695
+ ...label ? { "aria-label": label } : {},
696
+ style: pos ? { position: "fixed", left: pos.left, top: pos.top } : { position: "fixed", left: 0, top: 0, visibility: "hidden" },
697
+ onPointerDown: (event) => event.stopPropagation(),
698
+ children
699
+ }
700
+ ) });
701
+ }
702
+ var DropdownContext = createContext(null);
703
+ function useDropdown(component) {
704
+ const value = useContext(DropdownContext);
705
+ if (!value) throw new Error(`${component}: render inside <TldrawUiDropdownMenuRoot>.`);
706
+ return value;
707
+ }
708
+ function TldrawUiDropdownMenuRoot({ id, open: controlled, onOpenChange, children }) {
709
+ const generated = useId();
710
+ const [uncontrolled, setUncontrolled] = useState(false);
711
+ const anchorRef = useRef(null);
712
+ const open = controlled ?? uncontrolled;
713
+ const setOpen = useCallback(
714
+ (next) => {
715
+ if (controlled === void 0) setUncontrolled(next);
716
+ onOpenChange?.(next);
717
+ },
718
+ [controlled, onOpenChange]
719
+ );
720
+ const value = useMemo(() => ({ id: id ?? generated, open, setOpen, anchorRef }), [id, generated, open, setOpen]);
721
+ return /* @__PURE__ */ jsx(DropdownContext.Provider, { value, children });
722
+ }
723
+ function TldrawUiDropdownMenuTrigger({ className, label, children }) {
724
+ const { id, open, setOpen, anchorRef } = useDropdown("TldrawUiDropdownMenuTrigger");
725
+ return /* @__PURE__ */ jsx(
726
+ "button",
727
+ {
728
+ ref: (node) => {
729
+ anchorRef.current = node;
730
+ },
731
+ type: "button",
732
+ className: ["mocanvas-btn", className].filter(Boolean).join(" "),
733
+ "aria-haspopup": "menu",
734
+ "aria-expanded": open,
735
+ "aria-controls": `${id}-content`,
736
+ ...label ? { "aria-label": label, "data-tooltip": label } : {},
737
+ onClick: () => setOpen(!open),
738
+ onKeyDown: (event) => {
739
+ if (event.key === "ArrowDown" && !open) {
740
+ event.preventDefault();
741
+ setOpen(true);
742
+ }
743
+ },
744
+ children
745
+ }
746
+ );
747
+ }
748
+ function TldrawUiDropdownMenuContent({ label, className, side = "below", children }) {
749
+ const ctx = useDropdown("TldrawUiDropdownMenuContent");
750
+ const close = useCallback(() => ctx.setOpen(false), [ctx]);
751
+ return /* @__PURE__ */ jsx(
752
+ FloatingLayer,
753
+ {
754
+ anchorRef: ctx.anchorRef,
755
+ open: ctx.open,
756
+ onClose: close,
757
+ prefer: side,
758
+ role: "menu",
759
+ className: ["mocanvas-menu", className].filter(Boolean).join(" "),
760
+ ...label ? { label } : {},
761
+ children: /* @__PURE__ */ jsx("div", { id: `${ctx.id}-content`, className: "mocanvas-menu-list", children })
762
+ }
763
+ );
764
+ }
765
+ function TldrawUiDropdownMenuGroup({ label, className, children }) {
766
+ return /* @__PURE__ */ jsx("div", { className: ["mocanvas-menu-group", className].filter(Boolean).join(" "), role: "group", ...label ? { "aria-label": label } : {}, children });
767
+ }
768
+ function TldrawUiDropdownMenuItem({ closeOnSelect = true, disabled, className, onSelect, children }) {
769
+ const ctx = useContext(DropdownContext);
770
+ return /* @__PURE__ */ jsx(
771
+ "button",
772
+ {
773
+ type: "button",
774
+ role: "menuitem",
775
+ className: ["mocanvas-menu-item", className].filter(Boolean).join(" "),
776
+ disabled,
777
+ onClick: () => {
778
+ onSelect?.();
779
+ if (closeOnSelect) ctx?.setOpen(false);
780
+ },
781
+ children
782
+ }
783
+ );
784
+ }
785
+ function TldrawUiDropdownMenuCheckboxItem({ checked, disabled, title, className, onSelect, children }) {
786
+ return /* @__PURE__ */ jsxs(
787
+ "button",
788
+ {
789
+ type: "button",
790
+ role: "menuitemcheckbox",
791
+ "aria-checked": checked,
792
+ className: ["mocanvas-menu-item", className].filter(Boolean).join(" "),
793
+ disabled,
794
+ ...title ? { "data-tooltip": title } : {},
795
+ onClick: () => onSelect?.(),
796
+ children: [
797
+ children,
798
+ /* @__PURE__ */ jsx(TldrawUiButtonCheck, { checked })
799
+ ]
800
+ }
801
+ );
802
+ }
803
+ function TldrawUiDropdownMenuIndicator() {
804
+ return /* @__PURE__ */ jsx("span", { className: "mocanvas-menu-indicator", "aria-hidden": "true" });
805
+ }
806
+ var SubContext = createContext(null);
807
+ function TldrawUiDropdownMenuSub({ id, open: controlled, onOpenChange, children }) {
808
+ const generated = useId();
809
+ const [uncontrolled, setUncontrolled] = useState(false);
810
+ const anchorRef = useRef(null);
811
+ const open = controlled ?? uncontrolled;
812
+ const setOpen = useCallback(
813
+ (next) => {
814
+ if (controlled === void 0) setUncontrolled(next);
815
+ onOpenChange?.(next);
816
+ },
817
+ [controlled, onOpenChange]
818
+ );
819
+ const value = useMemo(() => ({ id: id ?? generated, open, setOpen, anchorRef }), [id, generated, open, setOpen]);
820
+ return /* @__PURE__ */ jsx(SubContext.Provider, { value, children });
821
+ }
822
+ function TldrawUiDropdownMenuSubTrigger({ label, disabled, className, children }) {
823
+ const ctx = useContext(SubContext);
824
+ return /* @__PURE__ */ jsxs(
825
+ "button",
826
+ {
827
+ ref: (node) => {
828
+ if (ctx) ctx.anchorRef.current = node;
829
+ },
830
+ type: "button",
831
+ role: "menuitem",
832
+ "aria-haspopup": "menu",
833
+ "aria-expanded": ctx?.open ?? false,
834
+ className: ["mocanvas-menu-item", "mocanvas-menu-item--sub", className].filter(Boolean).join(" "),
835
+ disabled,
836
+ onClick: () => ctx?.setOpen(!ctx.open),
837
+ onKeyDown: (event) => {
838
+ if (event.key === "ArrowRight") {
839
+ event.preventDefault();
840
+ event.stopPropagation();
841
+ ctx?.setOpen(true);
842
+ } else if (event.key === "ArrowLeft" && ctx?.open) {
843
+ event.preventDefault();
844
+ event.stopPropagation();
845
+ ctx.setOpen(false);
846
+ }
847
+ },
848
+ children: [
849
+ children ?? label,
850
+ /* @__PURE__ */ jsx(TldrawUiIcon, { icon: "chevron-down", small: true })
851
+ ]
852
+ }
853
+ );
854
+ }
855
+ function TldrawUiDropdownMenuSubContent({ label, className, children }) {
856
+ const ctx = useContext(SubContext);
857
+ const close = useCallback(() => ctx?.setOpen(false), [ctx]);
858
+ if (!ctx) return null;
859
+ return /* @__PURE__ */ jsx(
860
+ FloatingLayer,
861
+ {
862
+ anchorRef: ctx.anchorRef,
863
+ open: ctx.open,
864
+ onClose: close,
865
+ prefer: "below",
866
+ role: "menu",
867
+ className: ["mocanvas-menu", "mocanvas-menu--sub", className].filter(Boolean).join(" "),
868
+ ...label ? { label } : {},
869
+ children: /* @__PURE__ */ jsx("div", { id: `${ctx.id}-content`, className: "mocanvas-menu-list", children })
870
+ }
871
+ );
872
+ }
873
+ var APPLE = {
874
+ mod: "\u2318",
875
+ cmd: "\u2318",
876
+ alt: "\u2325",
877
+ opt: "\u2325",
878
+ shift: "\u21E7",
879
+ ctrl: "\u2303",
880
+ enter: "\u21B5",
881
+ backspace: "\u232B",
882
+ del: "\u2326",
883
+ esc: "\u238B",
884
+ tab: "\u21E5",
885
+ up: "\u2191",
886
+ down: "\u2193",
887
+ left: "\u2190",
888
+ right: "\u2192"
889
+ };
890
+ var OTHER = {
891
+ mod: "Ctrl",
892
+ cmd: "Ctrl",
893
+ alt: "Alt",
894
+ opt: "Alt",
895
+ shift: "Shift",
896
+ ctrl: "Ctrl",
897
+ enter: "Enter",
898
+ backspace: "Backspace",
899
+ del: "Delete",
900
+ esc: "Esc",
901
+ tab: "Tab",
902
+ up: "\u2191",
903
+ down: "\u2193",
904
+ left: "\u2190",
905
+ right: "\u2192"
906
+ };
907
+ function isApplePlatform() {
908
+ if (typeof navigator === "undefined") return false;
909
+ return /Mac|iPhone|iPad|iPod/.test(navigator.platform || navigator.userAgent || "");
910
+ }
911
+ function kbdToKeys(kbd, isApple = isApplePlatform()) {
912
+ const table = isApple ? APPLE : OTHER;
913
+ const first = (kbd.split(",")[0] ?? "").trim();
914
+ if (first === "") return [];
915
+ return first.split("+").map((part) => part.trim()).filter(Boolean).map((part) => table[part.toLowerCase()] ?? (part.length === 1 ? part.toUpperCase() : part));
916
+ }
917
+ function TldrawUiKbd({ children, isApple, className }) {
918
+ const raw = typeof children === "string" ? children : String(children ?? "");
919
+ const keys = kbdToKeys(raw, isApple ?? isApplePlatform());
920
+ if (keys.length === 0) return null;
921
+ return /* @__PURE__ */ jsx("span", { className: ["mocanvas-kbd", className].filter(Boolean).join(" "), "aria-hidden": "true", children: keys.map((key, i) => /* @__PURE__ */ jsx("kbd", { children: key }, `${key}-${i}`)) });
922
+ }
923
+ function useCanUndo() {
924
+ const editor = useEditor();
925
+ return useValue("canUndo", () => editor.getCanUndo(), [editor]);
926
+ }
927
+ function useCanRedo() {
928
+ const editor = useEditor();
929
+ return useValue("canRedo", () => editor.getCanRedo(), [editor]);
930
+ }
931
+ function useReadonly() {
932
+ const editor = useEditor();
933
+ return useValue("isReadonly", () => editor.getIsReadonly(), [editor]);
934
+ }
935
+ function useUnlockedSelectedShapesCount(min = 1) {
936
+ const editor = useEditor();
937
+ return useValue("unlockedSelectedShapes", () => editor.getSelectedShapes().filter((shape) => !shape.isLocked).length >= min, [editor, min]);
938
+ }
939
+ function useCanApplySelectionAction() {
940
+ const readonly = useReadonly();
941
+ const hasUnlocked = useUnlockedSelectedShapesCount(1);
942
+ return !readonly && hasUnlocked;
943
+ }
944
+ function useHasLockedShapes() {
945
+ const editor = useEditor();
946
+ return useValue("hasLockedShapes", () => editor.getCurrentPageShapes().some((shape) => shape.isLocked), [editor]);
947
+ }
948
+ function useIsGridMode() {
949
+ const editor = useEditor();
950
+ return useValue("isGridMode", () => editor.getInstanceState().isGridMode, [editor]);
951
+ }
952
+ function useIsDarkMode() {
953
+ const editor = useEditor();
954
+ return useValue("isDarkMode", () => editor.getColorMode() === "dark", [editor]);
955
+ }
956
+ function useRelevantStyles() {
957
+ const editor = useEditor();
958
+ return useValue(
959
+ "relevantStyles",
960
+ () => {
961
+ const styles = editor.getSharedStyles();
962
+ if (styles.size === 0 && editor.getSelectedShapeIds().length > 0) return null;
963
+ return styles.size === 0 ? null : styles;
964
+ },
965
+ [editor]
966
+ );
967
+ }
968
+ function useActionState(actionId) {
969
+ const editor = useEditor();
970
+ return useValue(
971
+ "actionState",
972
+ () => {
973
+ const readonly = editor.getIsReadonly();
974
+ const shapes = editor.getSelectedShapes();
975
+ const unlocked = shapes.filter((shape) => !shape.isLocked).length;
976
+ const instance = editor.getInstanceState();
977
+ const user = editor.user;
978
+ const edits = (min) => ({ disabled: readonly || unlocked < min, checked: false });
979
+ switch (actionId) {
980
+ case "undo":
981
+ return { disabled: !editor.getCanUndo(), checked: false };
982
+ case "redo":
983
+ return { disabled: !editor.getCanRedo(), checked: false };
984
+ case "zoom-to-selection":
985
+ case "select-none":
986
+ return { disabled: shapes.length === 0, checked: false };
987
+ case "delete":
988
+ case "duplicate":
989
+ case "toggle-lock":
990
+ case "rotate-cw":
991
+ case "rotate-ccw":
992
+ case "bring-to-front":
993
+ case "bring-forward":
994
+ case "send-backward":
995
+ case "send-to-back":
996
+ case "flip-horizontal":
997
+ case "flip-vertical":
998
+ return edits(1);
999
+ case "group":
1000
+ case "align-left":
1001
+ case "align-center-horizontal":
1002
+ case "align-right":
1003
+ case "align-top":
1004
+ case "align-center-vertical":
1005
+ case "align-bottom":
1006
+ case "stretch-horizontal":
1007
+ case "stretch-vertical":
1008
+ return edits(2);
1009
+ case "distribute-horizontal":
1010
+ case "distribute-vertical":
1011
+ case "stack-horizontal":
1012
+ case "stack-vertical":
1013
+ case "pack":
1014
+ return edits(3);
1015
+ case "ungroup":
1016
+ return { disabled: readonly || !shapes.some((shape) => shape.type === "group"), checked: false };
1017
+ case "unlock-all":
1018
+ return { disabled: readonly || !editor.getCurrentPageShapes().some((shape) => shape.isLocked), checked: false };
1019
+ case "delete-page":
1020
+ return { disabled: readonly || editor.getPages().length < 2, checked: false };
1021
+ case "new-page":
1022
+ case "duplicate-page":
1023
+ return { disabled: readonly, checked: false };
1024
+ case "toggle-grid":
1025
+ return { disabled: false, checked: instance.isGridMode };
1026
+ case "toggle-focus-mode":
1027
+ return { disabled: false, checked: instance.isFocusMode };
1028
+ case "toggle-debug-mode":
1029
+ return { disabled: false, checked: instance.isDebugMode };
1030
+ case "toggle-tool-lock":
1031
+ return { disabled: readonly, checked: instance.isToolLocked };
1032
+ // The preference is "transparent background", the record is
1033
+ // "paint a background", so the tick is the negation.
1034
+ case "toggle-transparent":
1035
+ return { disabled: false, checked: !instance.exportBackground };
1036
+ case "toggle-snap-mode":
1037
+ return { disabled: false, checked: user.getIsSnapMode() };
1038
+ case "toggle-wrap-mode":
1039
+ return { disabled: false, checked: user.getIsWrapMode() };
1040
+ case "toggle-dynamic-size-mode":
1041
+ return { disabled: false, checked: user.getIsDynamicSizeMode() };
1042
+ case "toggle-paste-at-cursor":
1043
+ return { disabled: false, checked: user.getIsPasteAtCursorMode() };
1044
+ case "toggle-edge-scrolling":
1045
+ return { disabled: false, checked: user.getEdgeScrollSpeed() !== 0 };
1046
+ case "toggle-reduce-motion":
1047
+ return { disabled: false, checked: user.getAnimationSpeed() === 0 };
1048
+ case "toggle-dark-mode":
1049
+ return { disabled: false, checked: editor.getColorMode() === "dark" };
1050
+ case "toggle-keyboard-shortcuts":
1051
+ return { disabled: false, checked: user.getAreKeyboardShortcutsEnabled() };
1052
+ default:
1053
+ return { disabled: false, checked: false };
1054
+ }
1055
+ },
1056
+ [editor, actionId]
1057
+ );
1058
+ }
1059
+ var EventsContext = createContext(null);
1060
+ function TldrawUiEventsProvider({ onEvent, children }) {
1061
+ return /* @__PURE__ */ jsx(EventsContext.Provider, { value: onEvent ?? null, children });
1062
+ }
1063
+ function useUiEvents() {
1064
+ const handler = useContext(EventsContext);
1065
+ return useCallback(
1066
+ (name, data) => {
1067
+ handler?.(name, data);
1068
+ },
1069
+ [handler]
1070
+ );
1071
+ }
1072
+ var LANGUAGES = [
1073
+ { locale: "ar", label: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629" },
1074
+ { locale: "cs", label: "\u010Ce\u0161tina" },
1075
+ { locale: "da", label: "Dansk" },
1076
+ { locale: "de", label: "Deutsch" },
1077
+ { locale: "en", label: "English" },
1078
+ { locale: "es", label: "Espa\xF1ol" },
1079
+ { locale: "fa", label: "\u0641\u0627\u0631\u0633\u06CC" },
1080
+ { locale: "fi", label: "Suomi" },
1081
+ { locale: "fr", label: "Fran\xE7ais" },
1082
+ { locale: "he", label: "\u05E2\u05D1\u05E8\u05D9\u05EA" },
1083
+ { locale: "hi", label: "\u0939\u093F\u0928\u094D\u0926\u0940" },
1084
+ { locale: "hu", label: "Magyar" },
1085
+ { locale: "it", label: "Italiano" },
1086
+ { locale: "ja", label: "\u65E5\u672C\u8A9E" },
1087
+ { locale: "ko", label: "\uD55C\uAD6D\uC5B4" },
1088
+ { locale: "nl", label: "Nederlands" },
1089
+ { locale: "no", label: "Norsk" },
1090
+ { locale: "pl", label: "Polski" },
1091
+ { locale: "pt", label: "Portugu\xEAs" },
1092
+ { locale: "ru", label: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439" },
1093
+ { locale: "sv", label: "Svenska" },
1094
+ { locale: "tr", label: "T\xFCrk\xE7e" },
1095
+ { locale: "uk", label: "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430" },
1096
+ { locale: "vi", label: "Ti\u1EBFng Vi\u1EC7t" },
1097
+ { locale: "zh", label: "\u4E2D\u6587" }
1098
+ ];
1099
+ var RTL_LANGUAGES = ["ar", "fa", "he", "ur"];
1100
+ function getDefaultTranslationLocale(locales = typeof navigator === "undefined" ? [] : navigator.languages ?? []) {
1101
+ for (const locale of locales) {
1102
+ for (const candidate of getLocaleChain(locale)) {
1103
+ if (LANGUAGES.some((l) => l.locale === candidate)) return candidate;
1104
+ }
1105
+ }
1106
+ return "en";
1107
+ }
1108
+ function isRtlLanguage(locale) {
1109
+ return RTL_LANGUAGES.includes(locale.split(/[-_]/)[0] ?? locale);
1110
+ }
1111
+ var TranslationContext = createContext(null);
1112
+ function TldrawUiTranslationProvider({ overrides, children }) {
1113
+ const editor = useEditor();
1114
+ const locale = useValue("ui locale", () => editor.user.getLocale(), [editor]);
1115
+ const value = useMemo(() => {
1116
+ const messages = overrides ? Object.assign({}, ...getLocaleChain(locale).reverse().map((l) => overrides[l] ?? {})) : {};
1117
+ return {
1118
+ locale,
1119
+ label: LANGUAGES.find((l) => l.locale === locale)?.label ?? locale,
1120
+ dir: isRtlLanguage(locale) ? "rtl" : "ltr",
1121
+ messages
1122
+ };
1123
+ }, [locale, overrides]);
1124
+ return /* @__PURE__ */ jsx(TranslationContext.Provider, { value, children });
1125
+ }
1126
+ function useCurrentTranslation() {
1127
+ const value = useContext(TranslationContext);
1128
+ if (!value) throw new Error("useCurrentTranslation: render inside <TldrawUiTranslationProvider>.");
1129
+ return value;
1130
+ }
1131
+ function useMaybeCurrentTranslation() {
1132
+ return useContext(TranslationContext);
1133
+ }
1134
+ function useTranslation() {
1135
+ const translation = useMaybeCurrentTranslation();
1136
+ return useMemo(() => {
1137
+ if (!translation) return (id) => id;
1138
+ const dict = { [translation.locale]: translation.messages };
1139
+ return (id) => resolveUiMessage(dict, translation.locale, id);
1140
+ }, [translation]);
1141
+ }
1142
+ var useMsg = useTranslation;
1143
+ function useDirection() {
1144
+ return useMaybeCurrentTranslation()?.dir ?? "ltr";
1145
+ }
1146
+ var MenuContext = createContext({ type: "menu", sourceId: "menu" });
1147
+ function TldrawUiMenuContextProvider({ type, sourceId, children }) {
1148
+ const resolved = sourceId ?? (type === "context-menu" ? "context-menu" : type === "toolbar" ? "toolbar" : "menu");
1149
+ return /* @__PURE__ */ jsx(MenuContext.Provider, { value: { type, sourceId: resolved }, children });
1150
+ }
1151
+ function useTldrawUiMenuContext() {
1152
+ return useContext(MenuContext);
1153
+ }
1154
+ function TldrawUiMenuItem({ id, label, icon, kbd, title, disabled, isSelected, noClose, children, onSelect }) {
1155
+ const { type, sourceId } = useTldrawUiMenuContext();
1156
+ const msg = useTranslation();
1157
+ const trackEvent = useUiEvents();
1158
+ const text = label === void 0 ? void 0 : msg(label);
1159
+ const select = () => {
1160
+ onSelect?.(sourceId);
1161
+ trackEvent(id, { source: sourceId });
1162
+ };
1163
+ switch (type) {
1164
+ case "keyboard-shortcuts":
1165
+ return /* @__PURE__ */ jsxs("div", { className: "mocanvas-shortcut-row", "data-item": id, children: [
1166
+ /* @__PURE__ */ jsx("span", { className: "mocanvas-shortcut-label", children: text ?? id }),
1167
+ kbd ? /* @__PURE__ */ jsx(TldrawUiKbd, { children: kbd }) : null
1168
+ ] });
1169
+ case "small-icons":
1170
+ case "icons":
1171
+ case "helper-buttons":
1172
+ case "toolbar":
1173
+ return /* @__PURE__ */ jsx(
1174
+ "button",
1175
+ {
1176
+ type: "button",
1177
+ className: "mocanvas-btn",
1178
+ "data-item": id,
1179
+ disabled,
1180
+ "aria-label": text ?? id,
1181
+ "data-tooltip": title ?? text ?? id,
1182
+ ...kbd ? { "aria-keyshortcuts": kbd, "data-shortcut": kbd } : {},
1183
+ ...isSelected === void 0 ? {} : { "aria-pressed": isSelected },
1184
+ onClick: select,
1185
+ children: icon ? /* @__PURE__ */ jsx(TldrawUiIcon, { icon, label: text ?? id }) : children ?? /* @__PURE__ */ jsx("span", { children: text ?? id })
1186
+ }
1187
+ );
1188
+ default:
1189
+ return /* @__PURE__ */ jsxs(TldrawUiDropdownMenuItem, { closeOnSelect: !noClose, ...disabled ? { disabled } : {}, onSelect: select, children: [
1190
+ icon ? /* @__PURE__ */ jsx(TldrawUiIcon, { icon }) : null,
1191
+ /* @__PURE__ */ jsx("span", { className: "mocanvas-menu-item-label", children: children ?? text ?? id }),
1192
+ kbd ? /* @__PURE__ */ jsx(TldrawUiKbd, { children: kbd }) : null
1193
+ ] });
1194
+ }
1195
+ }
1196
+ function TldrawUiMenuGroup({ id, label, className, children }) {
1197
+ const { type } = useTldrawUiMenuContext();
1198
+ const msg = useTranslation();
1199
+ if (type === "small-icons" || type === "icons" || type === "toolbar" || type === "helper-buttons") {
1200
+ return /* @__PURE__ */ jsx("div", { className: "mocanvas-menu-icon-group", "data-group": id, role: "group", ...label ? { "aria-label": msg(label) } : {}, children });
1201
+ }
1202
+ return /* @__PURE__ */ jsx(TldrawUiDropdownMenuGroup, { className: ["mocanvas-menu-group", className].filter(Boolean).join(" "), ...label ? { label: msg(label) } : {}, children });
1203
+ }
1204
+ function TldrawUiMenuSubmenu({ id, label, disabled, children }) {
1205
+ const { type } = useTldrawUiMenuContext();
1206
+ const msg = useTranslation();
1207
+ const text = label ? msg(label) : id;
1208
+ if (type === "small-icons" || type === "icons" || type === "toolbar" || type === "helper-buttons" || type === "keyboard-shortcuts") {
1209
+ return /* @__PURE__ */ jsx("div", { className: "mocanvas-menu-icon-group", "data-group": id, role: "group", "aria-label": text, children });
1210
+ }
1211
+ return /* @__PURE__ */ jsxs(TldrawUiDropdownMenuSub, { id, children: [
1212
+ /* @__PURE__ */ jsx(TldrawUiDropdownMenuSubTrigger, { label: text, ...disabled ? { disabled } : {} }),
1213
+ /* @__PURE__ */ jsx(TldrawUiDropdownMenuSubContent, { label: text, children })
1214
+ ] });
1215
+ }
1216
+ function TldrawUiMenuCheckboxItem({ id, label, icon, kbd, title, checked = false, disabled, onSelect }) {
1217
+ const { type, sourceId } = useTldrawUiMenuContext();
1218
+ const msg = useTranslation();
1219
+ const trackEvent = useUiEvents();
1220
+ const text = label ? msg(label) : id;
1221
+ const select = () => {
1222
+ onSelect?.(sourceId);
1223
+ trackEvent(id, { source: sourceId });
1224
+ };
1225
+ if (type === "keyboard-shortcuts") {
1226
+ return /* @__PURE__ */ jsxs("div", { className: "mocanvas-shortcut-row", "data-item": id, children: [
1227
+ /* @__PURE__ */ jsx("span", { className: "mocanvas-shortcut-label", children: text }),
1228
+ kbd ? /* @__PURE__ */ jsx(TldrawUiKbd, { children: kbd }) : null
1229
+ ] });
1230
+ }
1231
+ if (type === "small-icons" || type === "icons" || type === "toolbar" || type === "helper-buttons") {
1232
+ return /* @__PURE__ */ jsx(
1233
+ "button",
1234
+ {
1235
+ type: "button",
1236
+ className: "mocanvas-btn",
1237
+ "data-item": id,
1238
+ role: "checkbox",
1239
+ "aria-checked": checked,
1240
+ "aria-label": text,
1241
+ "data-tooltip": title ?? text,
1242
+ disabled,
1243
+ onClick: select,
1244
+ children: icon ? /* @__PURE__ */ jsx(TldrawUiIcon, { icon, label: text }) : /* @__PURE__ */ jsx("span", { children: text })
1245
+ }
1246
+ );
1247
+ }
1248
+ return /* @__PURE__ */ jsxs(TldrawUiDropdownMenuCheckboxItem, { checked, ...disabled ? { disabled } : {}, ...title ? { title } : {}, onSelect: select, children: [
1249
+ icon ? /* @__PURE__ */ jsx(TldrawUiIcon, { icon }) : null,
1250
+ /* @__PURE__ */ jsx("span", { className: "mocanvas-menu-item-label", children: text }),
1251
+ kbd ? /* @__PURE__ */ jsx(TldrawUiKbd, { children: kbd }) : null
1252
+ ] });
1253
+ }
1254
+ function TldrawUiMenuActionItem({ actionId, label, icon, disabled, noClose }) {
1255
+ const actions = useActions();
1256
+ const state = useActionState(actionId);
1257
+ const action = actions[actionId];
1258
+ if (!action) return null;
1259
+ return /* @__PURE__ */ jsx(
1260
+ TldrawUiMenuItem,
1261
+ {
1262
+ id: action.id,
1263
+ label: label ?? action.label,
1264
+ ...icon ?? action.icon ? { icon: icon ?? action.icon } : {},
1265
+ ...action.kbd ? { kbd: action.kbd } : {},
1266
+ ...disabled ?? action.disabled ?? state.disabled ? { disabled: true } : {},
1267
+ ...noClose ? { noClose } : {},
1268
+ onSelect: (source) => action.onSelect(source)
1269
+ }
1270
+ );
1271
+ }
1272
+ function TldrawUiMenuActionCheckboxItem({ actionId, label, icon, checked, disabled }) {
1273
+ const actions = useActions();
1274
+ const state = useActionState(actionId);
1275
+ const action = actions[actionId];
1276
+ if (!action) return null;
1277
+ const isChecked = checked ?? (typeof action.meta?.["checked"] === "boolean" ? action.meta["checked"] : state.checked);
1278
+ return /* @__PURE__ */ jsx(
1279
+ TldrawUiMenuCheckboxItem,
1280
+ {
1281
+ id: action.id,
1282
+ label: label ?? action.label,
1283
+ ...icon ?? action.icon ? { icon: icon ?? action.icon } : {},
1284
+ ...action.kbd ? { kbd: action.kbd } : {},
1285
+ checked: isChecked,
1286
+ ...disabled ?? action.disabled ?? state.disabled ? { disabled: true } : {},
1287
+ onSelect: (source) => action.onSelect(source)
1288
+ }
1289
+ );
1290
+ }
1291
+ function TldrawUiMenuToolItem({ toolId, label, icon, disabled }) {
1292
+ const tools = useTools();
1293
+ const tool = tools[toolId];
1294
+ const isSelected = useIsToolSelected(tool);
1295
+ if (!tool) return null;
1296
+ return /* @__PURE__ */ jsx(
1297
+ TldrawUiMenuItem,
1298
+ {
1299
+ id: tool.id,
1300
+ label: label ?? tool.label,
1301
+ icon: icon ?? tool.icon,
1302
+ ...tool.kbd ? { kbd: tool.kbd } : {},
1303
+ ...disabled ?? tool.disabled ? { disabled: true } : {},
1304
+ isSelected,
1305
+ onSelect: (source) => tool.onSelect(source)
1306
+ }
1307
+ );
1308
+ }
1309
+ function DefaultKeyboardShortcutsDialogContent() {
1310
+ const tools = useTools();
1311
+ const actions = useActions();
1312
+ const toolItems = Object.values(tools).filter((tool) => tool.kbd);
1313
+ const actionItems = Object.values(actions).filter((action) => action.kbd);
1314
+ return /* @__PURE__ */ jsxs(TldrawUiMenuContextProvider, { type: "keyboard-shortcuts", children: [
1315
+ /* @__PURE__ */ jsxs("section", { className: "mocanvas-shortcut-section", children: [
1316
+ /* @__PURE__ */ jsx("h3", { children: "Tools" }),
1317
+ toolItems.map((tool) => /* @__PURE__ */ jsx(TldrawUiMenuItem, { id: tool.id, label: tool.label, kbd: tool.kbd }, tool.id))
1318
+ ] }),
1319
+ /* @__PURE__ */ jsxs("section", { className: "mocanvas-shortcut-section", children: [
1320
+ /* @__PURE__ */ jsx("h3", { children: "Actions" }),
1321
+ actionItems.map((action) => /* @__PURE__ */ jsx(TldrawUiMenuItem, { id: action.id, label: action.label, kbd: action.kbd }, action.id))
1322
+ ] })
1323
+ ] });
1324
+ }
1325
+ function DefaultKeyboardShortcutsDialog({ children }) {
1326
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1327
+ /* @__PURE__ */ jsxs(TldrawUiDialogHeader, { children: [
1328
+ /* @__PURE__ */ jsx(TldrawUiDialogTitle, { children: "Keyboard shortcuts" }),
1329
+ /* @__PURE__ */ jsx(TldrawUiDialogCloseButton, {})
1330
+ ] }),
1331
+ /* @__PURE__ */ jsx(TldrawUiDialogBody, { className: "mocanvas-shortcuts", children: children ?? /* @__PURE__ */ jsx(DefaultKeyboardShortcutsDialogContent, {}) })
1332
+ ] });
1333
+ }
1334
+ function KeyboardShortcutsDialogContents(_props) {
1335
+ return /* @__PURE__ */ jsx(DefaultKeyboardShortcutsDialog, {});
1336
+ }
1337
+
1338
+ export { DefaultDialogs, DefaultKeyboardShortcutsDialog, DefaultKeyboardShortcutsDialogContent, ExampleDialog, FloatingLayer, GEO_BOX, GEO_ICON_PATHS, ICONS, ICON_GRID, ICON_NAMES, Icon, KeyboardShortcutsDialogContents, LANGUAGES, Popover, RTL_LANGUAGES, TldrawUiButton, TldrawUiButtonCheck, TldrawUiButtonIcon, TldrawUiButtonLabel, TldrawUiDialogBody, TldrawUiDialogCloseButton, TldrawUiDialogFooter, TldrawUiDialogHeader, TldrawUiDialogTitle, TldrawUiDialogsProvider, TldrawUiDropdownMenuCheckboxItem, TldrawUiDropdownMenuContent, TldrawUiDropdownMenuGroup, TldrawUiDropdownMenuIndicator, TldrawUiDropdownMenuItem, TldrawUiDropdownMenuRoot, TldrawUiDropdownMenuSub, TldrawUiDropdownMenuSubContent, TldrawUiDropdownMenuSubTrigger, TldrawUiDropdownMenuTrigger, TldrawUiEventsProvider, TldrawUiIcon, TldrawUiKbd, TldrawUiMenuActionCheckboxItem, TldrawUiMenuActionItem, TldrawUiMenuCheckboxItem, TldrawUiMenuContextProvider, TldrawUiMenuGroup, TldrawUiMenuItem, TldrawUiMenuSubmenu, TldrawUiMenuToolItem, TldrawUiTranslationProvider, UiTooltip, getDefaultTranslationLocale, getGeoIconBox, isRtlLanguage, kbdToKeys, placeNear, useActionState, useAnchoredPosition, useCanApplySelectionAction, useCanRedo, useCanUndo, useCurrentTranslation, useDialogs, useDirection, useDismissable, useHasLockedShapes, useIsDarkMode, useIsGridMode, useMaybeCurrentTranslation, useMenuKeyboard, useMsg, useReadonly, useRelevantStyles, useTldrawUiMenuContext, useTranslation, useUiEvents, useUnlockedSelectedShapesCount };
1339
+ //# sourceMappingURL=chunk-QDUQZXE4.js.map
1340
+ //# sourceMappingURL=chunk-QDUQZXE4.js.map