@snowcone-app/canvas 0.15.0 → 0.16.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,1200 @@
1
+ import { jsx as V } from "react/jsx-runtime";
2
+ import { useRef as fe, useState as y, useCallback as l, useEffect as ne, createContext as Q, useContext as q, useMemo as K } from "react";
3
+ import { c as He, ai as qe, b3 as et, b4 as tt, G as Ve, b5 as nt, b6 as ot, b7 as rt, b8 as it, b9 as st, C as ct, ba as dt, bb as at, bc as lt, ad as ut, ag as ze, I as mt, g as ft, S as ht, aa as At, a9 as Oe } from "./HybridHistoryManager-NL3zyEl4.js";
4
+ const ue = He("useCommandHistory");
5
+ function pt(t, e, o, r) {
6
+ const i = fe(new qe(o)), [n, c] = y({
7
+ canUndo: !1,
8
+ canRedo: !1,
9
+ // Per-artboard state for the active artboard
10
+ canUndoActiveArtboard: !1,
11
+ canRedoActiveArtboard: !1
12
+ }), s = l(() => {
13
+ const d = i.current, f = o.getActiveArtboardId();
14
+ c({
15
+ canUndo: d.canUndo(),
16
+ canRedo: d.canRedo(),
17
+ // Per-artboard state - only check active artboard's history
18
+ canUndoActiveArtboard: f ? d.canUndoArtboard(f) : !1,
19
+ canRedoActiveArtboard: f ? d.canRedoArtboard(f) : !1
20
+ });
21
+ }, [o]), C = l(
22
+ (d, f) => {
23
+ const k = new et(
24
+ f.id,
25
+ d || null,
26
+ f,
27
+ (g) => {
28
+ e((W) => W.map((O) => O.id === g.id ? g : O));
29
+ }
30
+ ), I = o.getArtboardIdForElement(f.id);
31
+ if (I)
32
+ i.current.executeOnArtboard(I, k);
33
+ else {
34
+ const g = o.getActiveArtboardId();
35
+ g && i.current.executeOnArtboard(g, k);
36
+ }
37
+ s();
38
+ },
39
+ [e, o, s]
40
+ ), v = l(
41
+ (d, f, k, I) => {
42
+ const g = f || o.getActiveArtboardId();
43
+ if (!g) {
44
+ ue.warn("No active artboard to add element to");
45
+ return;
46
+ }
47
+ const W = new tt(
48
+ d,
49
+ (O) => {
50
+ const N = O;
51
+ e((U) => {
52
+ if (I) {
53
+ const H = U.findIndex((F) => F.id === I);
54
+ if (H !== -1) {
55
+ const F = [...U];
56
+ return F.splice(H, 0, N), F;
57
+ }
58
+ }
59
+ if (k) {
60
+ const H = U.findIndex((F) => F.id === k);
61
+ if (H !== -1) {
62
+ const F = [...U];
63
+ return F.splice(H + 1, 0, N), F;
64
+ }
65
+ for (let F = 0; F < U.length; F++) {
66
+ const G = U[F];
67
+ if (G instanceof Ve && G.children) {
68
+ const ee = G.children.findIndex((X) => X.id === k);
69
+ if (ee !== -1) {
70
+ const X = G.clone();
71
+ X.children.splice(ee + 1, 0, N);
72
+ const Y = [...U];
73
+ return Y[F] = X, Y;
74
+ }
75
+ }
76
+ }
77
+ }
78
+ return [...U, N];
79
+ }), o.addElementToArtboard(O.id, g);
80
+ },
81
+ (O) => {
82
+ e((N) => N.filter((U) => U.id !== O)), o.removeElementFromArtboard(O);
83
+ }
84
+ );
85
+ i.current.executeOnArtboard(g, W), s();
86
+ },
87
+ [e, o, s]
88
+ ), D = l(
89
+ (d) => {
90
+ const f = o.getArtboardIdForElement(d.id);
91
+ if (!f) {
92
+ ue.warn("Element not found in any artboard");
93
+ return;
94
+ }
95
+ const k = new nt(
96
+ d,
97
+ (I) => {
98
+ e((g) => [...g, I]), o.addElementToArtboard(I.id, f);
99
+ },
100
+ (I) => {
101
+ e((g) => g.filter((W) => W.id !== I)), o.removeElementFromArtboard(I);
102
+ }
103
+ );
104
+ i.current.executeOnArtboard(f, k), s();
105
+ },
106
+ [e, o, s]
107
+ ), x = l(
108
+ (d) => {
109
+ const f = new ot(d, o);
110
+ i.current.executeGlobal(f), s(), r == null || r();
111
+ },
112
+ [o, s, r]
113
+ ), p = l(
114
+ (d) => {
115
+ const f = new rt(d, o);
116
+ i.current.executeGlobal(f), s(), r == null || r();
117
+ },
118
+ [o, s, r]
119
+ ), E = l(
120
+ (d, f, k) => {
121
+ const I = new it(d, f, k, o);
122
+ i.current.executeGlobal(I), s(), r == null || r();
123
+ },
124
+ [o, s, r]
125
+ ), w = l(
126
+ (d) => {
127
+ if (d.length === 0)
128
+ return;
129
+ const f = o.getActiveArtboardId();
130
+ if (!f) {
131
+ ue.warn("No active artboard for batch execution");
132
+ return;
133
+ }
134
+ const k = d.map((I) => new class extends Object {
135
+ execute() {
136
+ I.execute();
137
+ }
138
+ undo() {
139
+ I.undo();
140
+ }
141
+ }());
142
+ i.current.executeBatchOnArtboard(f, k), s();
143
+ },
144
+ [o, s]
145
+ ), u = l(() => {
146
+ i.current.undo() && (s(), r == null || r());
147
+ }, [s, r]), m = l(() => {
148
+ i.current.redo() && (s(), r == null || r());
149
+ }, [s, r]), P = l(() => {
150
+ const d = o.getActiveArtboardId();
151
+ d && i.current.undoArtboard(d) && (s(), r == null || r());
152
+ }, [o, s, r]), h = l(() => {
153
+ const d = o.getActiveArtboardId();
154
+ d && i.current.redoArtboard(d) && (s(), r == null || r());
155
+ }, [o, s, r]), b = l(() => {
156
+ i.current.clear(), s();
157
+ }, [s]), _ = l(
158
+ (d) => {
159
+ i.current.clearArtboardHistory(d), s();
160
+ },
161
+ [s]
162
+ ), z = fe(null);
163
+ ne(() => {
164
+ const d = o.getActiveArtboardId();
165
+ d !== z.current && (z.current = d, s());
166
+ });
167
+ const L = l(
168
+ (d, f, k) => {
169
+ const I = t.map((O) => O.id), g = o.getArtboardIdForElement(d);
170
+ if (!g) {
171
+ ue.warn("Element not found in any artboard");
172
+ return;
173
+ }
174
+ const W = new st(d, f, k, I, (O) => {
175
+ e((N) => {
176
+ const U = new Map(N.map((H) => [H.id, H]));
177
+ return O.map((H) => U.get(H)).filter(Boolean);
178
+ });
179
+ });
180
+ i.current.executeOnArtboard(g, W), s();
181
+ },
182
+ [t, e, o, s]
183
+ );
184
+ return {
185
+ // Element operations
186
+ executeElementUpdate: C,
187
+ executeAddElement: v,
188
+ executeRemoveElement: D,
189
+ executeReorderElement: L,
190
+ // Batch operations
191
+ executeCommandBatch: w,
192
+ // Artboard operations
193
+ executeCreateArtboard: x,
194
+ executeDeleteArtboard: p,
195
+ executeUpdateArtboard: E,
196
+ // Undo/redo (smart - considers last operation and active artboard)
197
+ undo: u,
198
+ redo: m,
199
+ // Undo/redo for active artboard only (element operations)
200
+ undoActiveArtboard: P,
201
+ redoActiveArtboard: h,
202
+ clearHistory: b,
203
+ clearArtboardHistory: _,
204
+ // State (smart - considers last operation)
205
+ canUndo: n.canUndo,
206
+ canRedo: n.canRedo,
207
+ // State for active artboard only
208
+ canUndoActiveArtboard: n.canUndoActiveArtboard,
209
+ canRedoActiveArtboard: n.canRedoActiveArtboard,
210
+ historyManager: i.current
211
+ };
212
+ }
213
+ function te(t) {
214
+ return t && "fontSize" in t && "color" in t && "fontFamily" in t;
215
+ }
216
+ function xt(t, e) {
217
+ const [o, r] = y(32), [i, n] = y("#333333"), [c, s] = y("Arial"), [C, v] = y("center");
218
+ ne(() => {
219
+ if (t && te(t)) {
220
+ const u = t.transformType === "circle" && "getEffectiveFontSize" in t ? Math.round(t.getEffectiveFontSize()) : Math.round(t.fontSize), m = t.color, P = t.fontFamily, h = t.textAlign;
221
+ r((b) => b !== u ? u : b), n((b) => b !== m ? m : b), s((b) => b !== P ? P : b), v((b) => b !== h ? h : b);
222
+ }
223
+ }, [t]);
224
+ const D = l(
225
+ (u) => {
226
+ if (!t || !te(t)) return;
227
+ const m = Math.max(dt, Math.min(at, o + u));
228
+ r(m);
229
+ const P = t.clone();
230
+ P.transformType === "circle" && "setEffectiveFontSize" in P ? P.setEffectiveFontSize(m) : P.setFontSize(m), e(P);
231
+ },
232
+ [t, o, e]
233
+ ), x = l(
234
+ (u) => {
235
+ if (!t || !te(t)) return;
236
+ r(u);
237
+ const m = t.clone();
238
+ m.transformType === "circle" && "setEffectiveFontSize" in m ? m.setEffectiveFontSize(u) : m.setFontSize(u), e(m);
239
+ },
240
+ [t, e]
241
+ ), p = l(
242
+ (u) => {
243
+ if (!t || !te(t)) return;
244
+ n(u);
245
+ const m = t.clone();
246
+ if (m.color = u, m.richText)
247
+ for (const P of m.richText.spans)
248
+ P.style.color = void 0;
249
+ e(m);
250
+ },
251
+ [t, e]
252
+ ), E = l(
253
+ (u) => {
254
+ if (!t || !te(t)) return;
255
+ const m = t.fontFamily;
256
+ m !== u && ct.clearCache(m), s(u);
257
+ const P = t.clone();
258
+ P.fontFamily = u, e(P);
259
+ },
260
+ [t, e]
261
+ ), w = l(
262
+ (u) => {
263
+ if (!t || !te(t)) return;
264
+ v(u);
265
+ const m = t.clone();
266
+ m.textAlign = u, e(m);
267
+ },
268
+ [t, e]
269
+ );
270
+ return {
271
+ // State
272
+ fontSize: o,
273
+ fontColor: i,
274
+ fontFamily: c,
275
+ textAlign: C,
276
+ // State setters (for UI only)
277
+ setFontSize: r,
278
+ setFontColor: n,
279
+ setFontFamily: s,
280
+ setTextAlign: v,
281
+ // Update functions (update element + UI)
282
+ updateFontSize: D,
283
+ setFontSizeValue: x,
284
+ updateFontColor: p,
285
+ updateFontFamily: E,
286
+ updateTextAlign: w
287
+ };
288
+ }
289
+ const Ne = "data-preserve-selection";
290
+ function yt(t) {
291
+ if (!(t instanceof Element))
292
+ return !1;
293
+ let e = t;
294
+ const o = [];
295
+ for (; e; ) {
296
+ const r = e.id ? `#${e.id}` : "", i = e.className ? `.${String(e.className).split(" ").slice(0, 2).join(".")}` : "";
297
+ if (o.push(`${e.tagName.toLowerCase()}${r}${i}`), e.hasAttribute(Ne))
298
+ return !0;
299
+ const n = e.getAttribute("role");
300
+ if (n === "dialog" || n === "alertdialog" || n === "menu" || n === "listbox")
301
+ return !0;
302
+ const c = e.getAttribute("data-slot");
303
+ if (c && (c.includes("popover") || c.includes("dialog")) || e.hasAttribute("data-radix-popper-content-wrapper"))
304
+ return !0;
305
+ e = e.parentElement;
306
+ }
307
+ return !1;
308
+ }
309
+ const Lt = {
310
+ [Ne]: ""
311
+ };
312
+ function wt(t) {
313
+ const e = Le(t);
314
+ return e !== null && e < 0.5;
315
+ }
316
+ function Wt(t) {
317
+ const e = Le(t);
318
+ return e !== null && e >= 0.5;
319
+ }
320
+ function Le(t) {
321
+ const e = t.trim();
322
+ if (e.startsWith("#")) {
323
+ const r = e.slice(1);
324
+ let i, n, c;
325
+ if (r.length === 3)
326
+ i = parseInt(r[0] + r[0], 16), n = parseInt(r[1] + r[1], 16), c = parseInt(r[2] + r[2], 16);
327
+ else if (r.length === 6)
328
+ i = parseInt(r.slice(0, 2), 16), n = parseInt(r.slice(2, 4), 16), c = parseInt(r.slice(4, 6), 16);
329
+ else return null;
330
+ return Number.isNaN(i) || Number.isNaN(n) || Number.isNaN(c) ? null : Ue(i, n, c);
331
+ }
332
+ const o = e.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
333
+ return o ? Ue(Number(o[1]), Number(o[2]), Number(o[3])) : null;
334
+ }
335
+ function Ue(t, e, o) {
336
+ const r = (i) => {
337
+ const n = i / 255;
338
+ return n <= 0.03928 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);
339
+ };
340
+ return 0.2126 * r(t) + 0.7152 * r(e) + 0.0722 * r(o);
341
+ }
342
+ const bt = "#333333", Et = "#f4f4f5";
343
+ function St(t) {
344
+ return t && wt(t) ? Et : bt;
345
+ }
346
+ const We = Q(null), It = 0.1, Tt = 4, De = 0.25, gt = ({
347
+ children: t,
348
+ artboardManager: e,
349
+ canvasRef: o,
350
+ viewPadding: r = 0.9
351
+ }) => {
352
+ const [i, n] = y(1), [c, s] = y({ x: 0, y: 0 }), [C, v] = y(!1), [D, x] = y(1), p = l(() => {
353
+ x(1), s({ x: 0, y: 0 });
354
+ }, []), E = l(() => {
355
+ n((h) => Math.min(h + De, Tt));
356
+ }, []), w = l(() => {
357
+ n((h) => Math.max(h - De, It));
358
+ }, []), u = l(() => {
359
+ const h = e.getActiveArtboard();
360
+ if (!h || !o.current) return;
361
+ let b = o.current.parentElement, _ = 0, z = 0;
362
+ for (; b && (_ = b.clientWidth, z = b.clientHeight, !(_ > 0 && z > 0)); )
363
+ b = b.parentElement;
364
+ if (!_ || !z) return;
365
+ const L = Math.min(
366
+ _ * r / h.width,
367
+ z * r / h.height,
368
+ 1
369
+ // Never zoom in beyond 100%
370
+ );
371
+ n(L), s({ x: 0, y: 0 });
372
+ }, [e, o, r]), m = l(() => {
373
+ n(1), s({ x: 0, y: 0 });
374
+ }, []), P = K(
375
+ () => ({
376
+ zoom: i,
377
+ panOffset: c,
378
+ isPanning: C,
379
+ zoomIn: E,
380
+ zoomOut: w,
381
+ zoomToFit: u,
382
+ resetView: m,
383
+ setZoom: n,
384
+ setPanOffset: s,
385
+ setIsPanning: v,
386
+ userZoom: D,
387
+ setUserZoom: x,
388
+ resetUserView: p
389
+ }),
390
+ [i, c, C, E, w, u, m, D, p]
391
+ );
392
+ return /* @__PURE__ */ V(We.Provider, { value: P, children: t });
393
+ };
394
+ function Rt() {
395
+ const t = q(We);
396
+ if (!t)
397
+ throw new Error("useViewportContext must be used within a ViewportProvider (or EditorProvider)");
398
+ return t;
399
+ }
400
+ const _e = Q(null), vt = ({ children: t }) => {
401
+ const [e, o] = y(null), [r, i] = y([]), [n, c] = y(null), [s, C] = y(null), [v, D] = y(!1), x = l((w) => {
402
+ o(w);
403
+ }, []), p = l((w) => {
404
+ c(w);
405
+ }, []), E = K(
406
+ () => ({
407
+ selectedId: e,
408
+ multiSelection: r,
409
+ activeChildElement: n,
410
+ hoveredElementId: s,
411
+ hideHandles: v,
412
+ setSelectedId: o,
413
+ setMultiSelection: i,
414
+ setHoveredElementId: C,
415
+ setHideHandles: D,
416
+ handleSelectionChange: x,
417
+ handleActiveChildChange: p
418
+ }),
419
+ [
420
+ e,
421
+ r,
422
+ n,
423
+ s,
424
+ v,
425
+ x,
426
+ p
427
+ ]
428
+ );
429
+ return /* @__PURE__ */ V(_e.Provider, { value: E, children: t });
430
+ };
431
+ function Pt() {
432
+ const t = q(_e);
433
+ if (!t)
434
+ throw new Error("useSelectionContext must be used within a SelectionProvider (or EditorProvider)");
435
+ return t;
436
+ }
437
+ const Be = Q(null), Ft = ({ children: t, value: e }) => {
438
+ const o = K(
439
+ () => ({
440
+ undo: e.undo,
441
+ redo: e.redo,
442
+ canUndo: e.canUndo,
443
+ canRedo: e.canRedo,
444
+ undoActiveArtboard: e.undoActiveArtboard,
445
+ redoActiveArtboard: e.redoActiveArtboard,
446
+ canUndoActiveArtboard: e.canUndoActiveArtboard,
447
+ canRedoActiveArtboard: e.canRedoActiveArtboard
448
+ }),
449
+ [
450
+ e.undo,
451
+ e.redo,
452
+ e.canUndo,
453
+ e.canRedo,
454
+ e.undoActiveArtboard,
455
+ e.redoActiveArtboard,
456
+ e.canUndoActiveArtboard,
457
+ e.canRedoActiveArtboard
458
+ ]
459
+ );
460
+ return /* @__PURE__ */ V(Be.Provider, { value: o, children: t });
461
+ };
462
+ function _t() {
463
+ const t = q(Be);
464
+ if (!t)
465
+ throw new Error("useHistoryContext must be used within a HistoryProvider (or EditorProvider)");
466
+ return t;
467
+ }
468
+ const Ze = Q(null), Ct = ({ children: t }) => {
469
+ const [e, o] = y(null), [r, i] = y(!1), [n, c] = y(0), [s, C] = y(!1), [v, D] = y(!1), x = K(
470
+ () => ({
471
+ expandedPanelType: e,
472
+ setExpandedPanelType: o,
473
+ isToolbarMenuOpen: r,
474
+ setIsToolbarMenuOpen: i,
475
+ textSelectionVersion: n,
476
+ setTextSelectionVersion: c,
477
+ isCanvasReady: s,
478
+ setCanvasReady: C,
479
+ isRotating: v,
480
+ setIsRotating: D
481
+ }),
482
+ [e, r, n, s, v]
483
+ );
484
+ return /* @__PURE__ */ V(Ze.Provider, { value: x, children: t });
485
+ };
486
+ function kt() {
487
+ const t = q(Ze);
488
+ if (!t)
489
+ throw new Error("useToolStateContext must be used within a ToolStateProvider (or EditorProvider)");
490
+ return t;
491
+ }
492
+ const $e = Q(null), zt = ({ children: t, value: e }) => {
493
+ const o = K(
494
+ () => ({
495
+ elements: e.elements,
496
+ elementStore: e.elementStore,
497
+ artboards: e.artboards,
498
+ artboardManager: e.artboardManager,
499
+ artboardVersion: e.artboardVersion,
500
+ setElements: e.setElements,
501
+ refreshArtboards: e.refreshArtboards,
502
+ getElementById: e.getElementById,
503
+ handleAddElement: e.handleAddElement,
504
+ handleElementUpdate: e.handleElementUpdate,
505
+ handleLoadWorkspace: e.handleLoadWorkspace,
506
+ handleCopyElements: e.handleCopyElements,
507
+ handlePasteElements: e.handlePasteElements,
508
+ fontSize: e.fontSize,
509
+ fontColor: e.fontColor,
510
+ fontFamily: e.fontFamily,
511
+ textAlign: e.textAlign,
512
+ updateFontSize: e.updateFontSize,
513
+ setFontSizeValue: e.setFontSizeValue,
514
+ updateFontColor: e.updateFontColor,
515
+ updateFontFamily: e.updateFontFamily,
516
+ updateTextAlign: e.updateTextAlign,
517
+ canvasRef: e.canvasRef,
518
+ canvasEditorRef: e.canvasEditorRef
519
+ }),
520
+ [
521
+ e.elements,
522
+ e.elementStore,
523
+ e.artboards,
524
+ e.artboardManager,
525
+ e.artboardVersion,
526
+ e.setElements,
527
+ e.refreshArtboards,
528
+ e.getElementById,
529
+ e.handleAddElement,
530
+ e.handleElementUpdate,
531
+ e.handleLoadWorkspace,
532
+ e.handleCopyElements,
533
+ e.handlePasteElements,
534
+ e.fontSize,
535
+ e.fontColor,
536
+ e.fontFamily,
537
+ e.textAlign,
538
+ e.updateFontSize,
539
+ e.setFontSizeValue,
540
+ e.updateFontColor,
541
+ e.updateFontFamily,
542
+ e.updateTextAlign,
543
+ e.canvasRef,
544
+ e.canvasEditorRef
545
+ ]
546
+ );
547
+ return /* @__PURE__ */ V($e.Provider, { value: o, children: t });
548
+ };
549
+ function Bt() {
550
+ const t = q($e);
551
+ if (!t)
552
+ throw new Error("useElementsContext must be used within an ElementsProvider (or EditorProvider)");
553
+ return t;
554
+ }
555
+ const Ge = Q(null), Ot = ({ children: t, value: e }) => {
556
+ const o = K(
557
+ () => ({
558
+ executeElementUpdate: e.executeElementUpdate,
559
+ executeAddElement: e.executeAddElement,
560
+ executeRemoveElement: e.executeRemoveElement,
561
+ executeReorderElement: e.executeReorderElement,
562
+ executeCreateArtboard: e.executeCreateArtboard,
563
+ executeDeleteArtboard: e.executeDeleteArtboard,
564
+ executeUpdateArtboard: e.executeUpdateArtboard,
565
+ executeCommandBatch: e.executeCommandBatch,
566
+ undo: e.undo,
567
+ redo: e.redo,
568
+ canUndo: e.canUndo,
569
+ canRedo: e.canRedo,
570
+ undoActiveArtboard: e.undoActiveArtboard,
571
+ redoActiveArtboard: e.redoActiveArtboard,
572
+ canUndoActiveArtboard: e.canUndoActiveArtboard,
573
+ canRedoActiveArtboard: e.canRedoActiveArtboard,
574
+ historyManager: e.historyManager
575
+ }),
576
+ [
577
+ e.executeElementUpdate,
578
+ e.executeAddElement,
579
+ e.executeRemoveElement,
580
+ e.executeReorderElement,
581
+ e.executeCreateArtboard,
582
+ e.executeDeleteArtboard,
583
+ e.executeUpdateArtboard,
584
+ e.executeCommandBatch,
585
+ e.undo,
586
+ e.redo,
587
+ e.canUndo,
588
+ e.canRedo,
589
+ e.undoActiveArtboard,
590
+ e.redoActiveArtboard,
591
+ e.canUndoActiveArtboard,
592
+ e.canRedoActiveArtboard,
593
+ e.historyManager
594
+ ]
595
+ );
596
+ return /* @__PURE__ */ V(Ge.Provider, { value: o, children: t });
597
+ };
598
+ function Zt() {
599
+ const t = q(Ge);
600
+ if (!t)
601
+ throw new Error("useCommandContext must be used within a CommandProvider (or EditorProvider)");
602
+ return t;
603
+ }
604
+ const Ut = He("EditorContext"), Xe = Q(null), Dt = ({ children: t, artboardManager: e, canvasRef: o, canvasEditorRef: r }) => {
605
+ const i = Rt(), n = Pt(), c = kt(), [s, C] = y(
606
+ () => e.getAllArtboards()
607
+ ), [v, D] = y(0), [x, p] = y(
608
+ () => new ze()
609
+ ), E = K(() => x.toArray(), [x]), w = l((a) => {
610
+ p((A) => {
611
+ const T = A.toArray(), R = typeof a == "function" ? a(T) : a;
612
+ return R === T ? A : ze.fromArray(R);
613
+ });
614
+ }, []), u = l(
615
+ (a) => x.get(a),
616
+ [x]
617
+ ), [m, P] = y([]), h = n.selectedId ? x.get(n.selectedId) : void 0, b = l(() => {
618
+ C([...e.getAllArtboards()]), D((a) => a + 1);
619
+ }, [e]), {
620
+ historyManager: _,
621
+ executeElementUpdate: z,
622
+ executeAddElement: L,
623
+ executeRemoveElement: d,
624
+ executeReorderElement: f,
625
+ executeCommandBatch: k,
626
+ executeCreateArtboard: I,
627
+ executeDeleteArtboard: g,
628
+ executeUpdateArtboard: W,
629
+ undo: O,
630
+ redo: N,
631
+ canUndo: U,
632
+ canRedo: H,
633
+ undoActiveArtboard: F,
634
+ redoActiveArtboard: G,
635
+ canUndoActiveArtboard: ee,
636
+ canRedoActiveArtboard: X
637
+ } = pt(
638
+ E,
639
+ w,
640
+ e,
641
+ b
642
+ ), Y = l(
643
+ (a) => {
644
+ const A = x.get(a.id);
645
+ z(A, a);
646
+ },
647
+ [x, z]
648
+ ), Je = l(
649
+ (a) => {
650
+ if (!h || !(h instanceof Ve))
651
+ return;
652
+ const A = h.clone(), T = A.children.findIndex(
653
+ (R) => R.id === a.id
654
+ );
655
+ T >= 0 && (A.children[T] = a, Y(A));
656
+ },
657
+ [h, Y]
658
+ ), Me = n.activeChildElement || h, je = n.activeChildElement ? Je : Y, {
659
+ fontSize: he,
660
+ fontColor: Ae,
661
+ fontFamily: pe,
662
+ textAlign: xe,
663
+ updateFontSize: ye,
664
+ setFontSizeValue: we,
665
+ updateFontColor: be,
666
+ updateFontFamily: Ee,
667
+ updateTextAlign: Se
668
+ } = xt(Me, je), Ie = l(
669
+ async (a, A) => {
670
+ var Fe;
671
+ const T = e.getActiveArtboardId();
672
+ if (!T) {
673
+ alert("Please create or select an artboard first");
674
+ return;
675
+ }
676
+ const R = `element-${Date.now()}`, S = e.getActiveArtboard(), oe = S ? S.x + S.width / 2 : window.innerWidth / 2, re = S ? S.y + S.height / 2 : window.innerHeight / 2, B = ((Fe = r.current) == null ? void 0 : Fe.getZoom()) || i.zoom || 1;
677
+ if (a === "image") {
678
+ const ae = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", j = 200 / B, J = A == null ? void 0 : A.src, $ = new mt({
679
+ id: R,
680
+ x: oe,
681
+ y: re,
682
+ // Defer loading `src` until after the element is in the store so a
683
+ // synchronously-cached image can't fire onLoadCallback too early.
684
+ imageUrl: J ? "" : ae,
685
+ transformData: {
686
+ type: "image",
687
+ width: j,
688
+ height: j,
689
+ cropX: 0,
690
+ cropY: 0,
691
+ cropWidth: 1,
692
+ cropHeight: 1,
693
+ flipHorizontal: !1,
694
+ flipVertical: !1,
695
+ borderRadius: 0
696
+ }
697
+ });
698
+ J && ($.imageLoaded = !1, $.imageElement = null, $.isCropping = !1, $.imageUrl = J, $.preserveDimensions = !1, $.onLoadCallback = (M) => {
699
+ const Ce = M.transformData.width, ke = M.transformData.height, Pe = Math.min(j / Ce, j / ke, 1);
700
+ Pe < 1 && (M.transformData.width = Ce * Pe, M.transformData.height = ke * Pe), M.transformData.cropX = 0, M.transformData.cropY = 0, M.transformData.cropWidth = 1, M.transformData.cropHeight = 1, z($, M);
701
+ }), L($, T), n.setSelectedId($.id), J && $.loadImage(J);
702
+ return;
703
+ }
704
+ let ie;
705
+ const Z = {
706
+ text: "custom",
707
+ circle: "circle",
708
+ wave: "wave",
709
+ arch: "arch",
710
+ shape: "shape"
711
+ }[a] || "custom", ce = ft(Z);
712
+ if (!ce || !ce.Component)
713
+ return;
714
+ const de = e.getActiveArtboard(), Qe = de ? Math.min(de.width, de.height) * 0.1 : 80, ve = de ? de.width * 0.5 : 300;
715
+ if (a === "shape") {
716
+ const ae = (A == null ? void 0 : A.shapeType) ?? "rectangle";
717
+ let j = 200 / B, J = 200 / B;
718
+ ae === "ellipse" ? (j = 150 / B, J = 250 / B) : ae === "line" && (j = 300 / B, J = 8 / B), ie = new ht({
719
+ id: R,
720
+ x: oe,
721
+ y: re,
722
+ transformData: {
723
+ type: "shape",
724
+ shapeType: ae,
725
+ width: j,
726
+ height: J,
727
+ fillColor: "#3b82f6",
728
+ fillOpacity: 1
729
+ }
730
+ });
731
+ } else
732
+ ie = new ce.Component({
733
+ id: R,
734
+ text: "New Text",
735
+ x: oe,
736
+ y: re,
737
+ fontSize: Qe,
738
+ fontFamily: "Poppins",
739
+ color: St(S == null ? void 0 : S.backgroundColor),
740
+ transformData: Z === "arch" ? {
741
+ type: "arch",
742
+ width: ve,
743
+ archHeight: At.archHeight
744
+ } : Z === "wave" ? {
745
+ type: "wave",
746
+ width: ve,
747
+ amplitude: Oe.amplitude,
748
+ frequency: Oe.frequency
749
+ } : Z === "circle" ? {
750
+ type: "circle",
751
+ radius: ve / 2
752
+ } : void 0
753
+ });
754
+ e.addElementToArtboard(R, T), L(
755
+ ie,
756
+ T,
757
+ n.selectedId || void 0
758
+ ), n.setSelectedId(R);
759
+ },
760
+ [e, L, z, n, i.zoom, r]
761
+ ), Te = l(() => {
762
+ const a = [];
763
+ if (n.multiSelection.length > 0) {
764
+ const A = E.filter(
765
+ (T) => n.multiSelection.includes(T.id)
766
+ );
767
+ a.push(...A);
768
+ } else h && a.push(h);
769
+ if (a.length > 0) {
770
+ const A = a.map((T) => T.clone());
771
+ P(A);
772
+ }
773
+ }, [h, n.multiSelection, E]), ge = l(() => {
774
+ if (m.length === 0) return;
775
+ const a = [], A = 30, T = 30;
776
+ m.forEach((R) => {
777
+ const S = x.get(R.id), oe = S ? S.x : R.x, re = S ? S.y : R.y, B = R.toJSON();
778
+ delete B.id;
779
+ const ie = R.constructor, se = new ie(B);
780
+ se.x = oe + A, se.y = re + T;
781
+ let Z = null;
782
+ if (S && (Z = e.getArtboardIdForElement(
783
+ S.id
784
+ )), Z || (Z = e.getActiveArtboardId()), !Z) {
785
+ Ut.warn("[handlePasteElements] No artboard found for pasting");
786
+ return;
787
+ }
788
+ const ce = S ? S.id : void 0;
789
+ L(se, Z, ce), a.push(se.id);
790
+ }), a.length === 1 ? n.handleSelectionChange(a[0]) : a.length > 1 && n.setMultiSelection(a);
791
+ }, [
792
+ m,
793
+ x,
794
+ e,
795
+ L,
796
+ n
797
+ ]), le = l(() => {
798
+ if (c.expandedPanelType === "crop" && (h == null ? void 0 : h.transformType) === "image") {
799
+ const a = h;
800
+ if (a.isCropping) {
801
+ const A = a.clone();
802
+ A.exitCropMode(), z(a, A);
803
+ }
804
+ }
805
+ c.setExpandedPanelType(null);
806
+ }, [
807
+ c.expandedPanelType,
808
+ c.setExpandedPanelType,
809
+ h,
810
+ z
811
+ ]);
812
+ ne(() => {
813
+ const a = (A) => {
814
+ const T = A.target;
815
+ if (T.tagName === "CANVAS" || yt(T))
816
+ return;
817
+ const S = document.activeElement;
818
+ if (S != null && S.hasAttribute("data-preserve-selection")) {
819
+ S.blur();
820
+ return;
821
+ }
822
+ if (c.expandedPanelType !== null) {
823
+ le();
824
+ return;
825
+ }
826
+ n.setSelectedId(null), n.setMultiSelection([]);
827
+ };
828
+ return document.addEventListener("pointerdown", a), () => document.removeEventListener("pointerdown", a);
829
+ }, [c.expandedPanelType, le, n]);
830
+ const Re = l(
831
+ (a, A, T) => {
832
+ e.clear(), a.forEach((R) => {
833
+ e.createArtboard(R.toJSON());
834
+ }), T && e.setActiveArtboard(T), C([...e.getAllArtboards()]), D((R) => R + 1), w(A), n.setSelectedId(null);
835
+ },
836
+ [e, n, w]
837
+ ), Ke = K(() => ({
838
+ // From ViewportContext
839
+ zoom: i.zoom,
840
+ panOffset: i.panOffset,
841
+ isPanning: i.isPanning,
842
+ zoomIn: i.zoomIn,
843
+ zoomOut: i.zoomOut,
844
+ zoomToFit: i.zoomToFit,
845
+ resetView: i.resetView,
846
+ setZoom: i.setZoom,
847
+ setPanOffset: i.setPanOffset,
848
+ setIsPanning: i.setIsPanning,
849
+ // From SelectionContext
850
+ selectedId: n.selectedId,
851
+ multiSelection: n.multiSelection,
852
+ activeChildElement: n.activeChildElement,
853
+ hoveredElementId: n.hoveredElementId,
854
+ hideHandles: n.hideHandles,
855
+ setSelectedId: n.setSelectedId,
856
+ setMultiSelection: n.setMultiSelection,
857
+ setHoveredElementId: n.setHoveredElementId,
858
+ setHideHandles: n.setHideHandles,
859
+ handleSelectionChange: n.handleSelectionChange,
860
+ handleActiveChildChange: n.handleActiveChildChange,
861
+ // From ToolStateContext
862
+ expandedPanelType: c.expandedPanelType,
863
+ setExpandedPanelType: c.setExpandedPanelType,
864
+ isToolbarMenuOpen: c.isToolbarMenuOpen,
865
+ setIsToolbarMenuOpen: c.setIsToolbarMenuOpen,
866
+ textSelectionVersion: c.textSelectionVersion,
867
+ setTextSelectionVersion: c.setTextSelectionVersion,
868
+ isCanvasReady: c.isCanvasReady,
869
+ setCanvasReady: c.setCanvasReady,
870
+ isRotating: c.isRotating,
871
+ setIsRotating: c.setIsRotating,
872
+ // Cross-context handler
873
+ clearExpandedPanel: le,
874
+ // Core state (element/artboard domain)
875
+ artboardManager: e,
876
+ artboards: s,
877
+ elements: E,
878
+ elementStore: x,
879
+ getElementById: u,
880
+ // Derived state (cross-context)
881
+ selectedElement: h,
882
+ // Refs
883
+ canvasRef: o,
884
+ canvasEditorRef: r,
885
+ // Element setters
886
+ setElements: w,
887
+ // Artboard version counter
888
+ artboardVersion: v,
889
+ // Handlers
890
+ refreshArtboards: b,
891
+ handleElementUpdate: Y,
892
+ handleAddElement: Ie,
893
+ handleLoadWorkspace: Re,
894
+ handleCopyElements: Te,
895
+ handlePasteElements: ge,
896
+ // Command history (undo/redo actions + execute functions)
897
+ historyManager: _,
898
+ executeElementUpdate: z,
899
+ executeAddElement: L,
900
+ executeRemoveElement: d,
901
+ executeReorderElement: f,
902
+ executeCommandBatch: k,
903
+ executeCreateArtboard: I,
904
+ executeDeleteArtboard: g,
905
+ executeUpdateArtboard: W,
906
+ undo: O,
907
+ redo: N,
908
+ canUndo: U,
909
+ canRedo: H,
910
+ undoActiveArtboard: F,
911
+ redoActiveArtboard: G,
912
+ canUndoActiveArtboard: ee,
913
+ canRedoActiveArtboard: X,
914
+ // Element properties
915
+ fontSize: he,
916
+ fontColor: Ae,
917
+ fontFamily: pe,
918
+ textAlign: xe,
919
+ updateFontSize: ye,
920
+ setFontSizeValue: we,
921
+ updateFontColor: be,
922
+ updateFontFamily: Ee,
923
+ updateTextAlign: Se
924
+ }), [
925
+ // Viewport
926
+ i.zoom,
927
+ i.panOffset,
928
+ i.isPanning,
929
+ i.zoomIn,
930
+ i.zoomOut,
931
+ i.zoomToFit,
932
+ i.resetView,
933
+ i.setZoom,
934
+ i.setPanOffset,
935
+ i.setIsPanning,
936
+ // Selection
937
+ n.selectedId,
938
+ n.multiSelection,
939
+ n.activeChildElement,
940
+ n.hoveredElementId,
941
+ n.hideHandles,
942
+ n.setSelectedId,
943
+ n.setMultiSelection,
944
+ n.setHoveredElementId,
945
+ n.setHideHandles,
946
+ n.handleSelectionChange,
947
+ n.handleActiveChildChange,
948
+ // Tool state
949
+ c.expandedPanelType,
950
+ c.setExpandedPanelType,
951
+ c.isToolbarMenuOpen,
952
+ c.setIsToolbarMenuOpen,
953
+ c.textSelectionVersion,
954
+ c.setTextSelectionVersion,
955
+ c.isCanvasReady,
956
+ c.setCanvasReady,
957
+ c.isRotating,
958
+ c.setIsRotating,
959
+ le,
960
+ // Element/artboard domain
961
+ e,
962
+ s,
963
+ E,
964
+ x,
965
+ u,
966
+ h,
967
+ o,
968
+ r,
969
+ w,
970
+ v,
971
+ b,
972
+ Y,
973
+ Ie,
974
+ Re,
975
+ Te,
976
+ ge,
977
+ // Command history
978
+ _,
979
+ z,
980
+ L,
981
+ d,
982
+ f,
983
+ k,
984
+ I,
985
+ g,
986
+ W,
987
+ O,
988
+ N,
989
+ U,
990
+ H,
991
+ F,
992
+ G,
993
+ ee,
994
+ X,
995
+ // Element properties
996
+ he,
997
+ Ae,
998
+ pe,
999
+ xe,
1000
+ ye,
1001
+ we,
1002
+ be,
1003
+ Ee,
1004
+ Se
1005
+ ]);
1006
+ return /* @__PURE__ */ V(
1007
+ Ft,
1008
+ {
1009
+ value: {
1010
+ undo: O,
1011
+ redo: N,
1012
+ canUndo: U,
1013
+ canRedo: H,
1014
+ undoActiveArtboard: F,
1015
+ redoActiveArtboard: G,
1016
+ canUndoActiveArtboard: ee,
1017
+ canRedoActiveArtboard: X
1018
+ },
1019
+ children: /* @__PURE__ */ V(
1020
+ zt,
1021
+ {
1022
+ value: {
1023
+ elements: E,
1024
+ elementStore: x,
1025
+ artboards: s,
1026
+ artboardManager: e,
1027
+ artboardVersion: v,
1028
+ setElements: w,
1029
+ refreshArtboards: b,
1030
+ getElementById: u,
1031
+ handleAddElement: Ie,
1032
+ handleElementUpdate: Y,
1033
+ handleLoadWorkspace: Re,
1034
+ handleCopyElements: Te,
1035
+ handlePasteElements: ge,
1036
+ fontSize: he,
1037
+ fontColor: Ae,
1038
+ fontFamily: pe,
1039
+ textAlign: xe,
1040
+ updateFontSize: ye,
1041
+ setFontSizeValue: we,
1042
+ updateFontColor: be,
1043
+ updateFontFamily: Ee,
1044
+ updateTextAlign: Se,
1045
+ canvasRef: o,
1046
+ canvasEditorRef: r
1047
+ },
1048
+ children: /* @__PURE__ */ V(
1049
+ Ot,
1050
+ {
1051
+ value: {
1052
+ executeElementUpdate: z,
1053
+ executeAddElement: L,
1054
+ executeRemoveElement: d,
1055
+ executeReorderElement: f,
1056
+ executeCommandBatch: k,
1057
+ executeCreateArtboard: I,
1058
+ executeDeleteArtboard: g,
1059
+ executeUpdateArtboard: W,
1060
+ undo: O,
1061
+ redo: N,
1062
+ canUndo: U,
1063
+ canRedo: H,
1064
+ undoActiveArtboard: F,
1065
+ redoActiveArtboard: G,
1066
+ canUndoActiveArtboard: ee,
1067
+ canRedoActiveArtboard: X,
1068
+ historyManager: _
1069
+ },
1070
+ children: /* @__PURE__ */ V(Xe.Provider, { value: Ke, children: t })
1071
+ }
1072
+ )
1073
+ }
1074
+ )
1075
+ }
1076
+ );
1077
+ }, $t = ({
1078
+ children: t,
1079
+ initialArtboardConfig: e = {},
1080
+ viewPadding: o = 0.9
1081
+ }) => {
1082
+ const [r] = y(() => {
1083
+ const c = new ut(), s = {
1084
+ name: e.name || "Artboard 1",
1085
+ x: e.x ?? 0,
1086
+ y: e.y ?? 0,
1087
+ width: e.width ?? 1e3,
1088
+ height: e.height ?? 1e3,
1089
+ backgroundColor: e.backgroundColor || lt
1090
+ };
1091
+ return c.createArtboard(s), c;
1092
+ }), i = fe(null), n = fe(null);
1093
+ return /* @__PURE__ */ V(
1094
+ gt,
1095
+ {
1096
+ artboardManager: r,
1097
+ canvasRef: i,
1098
+ viewPadding: o,
1099
+ children: /* @__PURE__ */ V(vt, { children: /* @__PURE__ */ V(Ct, { children: /* @__PURE__ */ V(
1100
+ Dt,
1101
+ {
1102
+ artboardManager: r,
1103
+ canvasRef: i,
1104
+ canvasEditorRef: n,
1105
+ children: t
1106
+ }
1107
+ ) }) })
1108
+ }
1109
+ );
1110
+ }, Gt = () => {
1111
+ const t = q(Xe);
1112
+ if (!t)
1113
+ throw new Error("useEditor must be used within EditorProvider");
1114
+ return t;
1115
+ }, Ye = Q(void 0);
1116
+ function me() {
1117
+ if (typeof window > "u")
1118
+ return { theme: "light", resolvedTheme: "light", isDark: !1 };
1119
+ const t = document.documentElement.classList.contains("dark"), e = document.documentElement.getAttribute("data-theme");
1120
+ let o = t ? "dark" : "light";
1121
+ e && [
1122
+ "light",
1123
+ "dark",
1124
+ "axis-light",
1125
+ "axis-dark",
1126
+ "ocean-light",
1127
+ "ocean-dark",
1128
+ "sunset-light",
1129
+ "sunset-dark"
1130
+ ].includes(e) && (o = e);
1131
+ let r = t ? "dark" : "light";
1132
+ return o.startsWith("axis") ? r = "axis" : o.startsWith("ocean") ? r = "ocean" : o.startsWith("sunset") && (r = "sunset"), { theme: r, resolvedTheme: o, isDark: t };
1133
+ }
1134
+ const Xt = ({ children: t, defaultTheme: e = "light", passive: o = !1 }) => {
1135
+ const r = () => typeof window > "u" ? e : o ? me().theme : localStorage.getItem("snowcone-theme") || e, i = () => typeof window > "u" ? "light" : o ? me().resolvedTheme : "light", [n, c] = y(r), [s, C] = y(i);
1136
+ ne(() => {
1137
+ if (!o || typeof window > "u") return;
1138
+ const { resolvedTheme: p, theme: E } = me();
1139
+ C(p), c(E);
1140
+ const w = new MutationObserver(() => {
1141
+ const { resolvedTheme: u, theme: m } = me();
1142
+ C(u), c(m);
1143
+ });
1144
+ return w.observe(document.documentElement, {
1145
+ attributes: !0,
1146
+ attributeFilter: ["class", "data-theme"]
1147
+ }), () => w.disconnect();
1148
+ }, [o]), ne(() => {
1149
+ if (o || typeof window > "u") return;
1150
+ const p = window.matchMedia("(prefers-color-scheme: dark)"), E = (w) => {
1151
+ let u;
1152
+ if (n === "auto")
1153
+ u = w.matches ? "dark" : "light";
1154
+ else {
1155
+ if (n === "light" || n === "dark")
1156
+ return;
1157
+ u = w.matches ? `${n}-dark` : `${n}-light`;
1158
+ }
1159
+ C(u), document.documentElement.setAttribute("data-theme", u), u === "dark" || u.endsWith("-dark") ? (document.documentElement.classList.add("dark"), document.body.classList.add("dark")) : (document.documentElement.classList.remove("dark"), document.body.classList.remove("dark"));
1160
+ };
1161
+ return p.addEventListener("change", E), () => p.removeEventListener("change", E);
1162
+ }, [n, o]), ne(() => {
1163
+ if (o || typeof window > "u") return;
1164
+ let p;
1165
+ const E = window.matchMedia("(prefers-color-scheme: dark)").matches;
1166
+ n === "auto" ? p = E ? "dark" : "light" : n === "light" || n === "dark" ? p = n : p = E ? `${n}-dark` : `${n}-light`, C(p), document.documentElement.setAttribute("data-theme", p), p === "dark" || p.endsWith("-dark") ? (document.documentElement.classList.add("dark"), document.body.classList.add("dark")) : (document.documentElement.classList.remove("dark"), document.body.classList.remove("dark")), localStorage.setItem("snowcone-theme", n);
1167
+ }, [n, o]);
1168
+ const v = (p) => {
1169
+ o || c(p);
1170
+ }, D = s === "dark" || s.endsWith("-dark"), x = {
1171
+ theme: n,
1172
+ resolvedTheme: s,
1173
+ setTheme: v,
1174
+ isDark: D
1175
+ };
1176
+ return /* @__PURE__ */ V(Ye.Provider, { value: x, children: t });
1177
+ }, Yt = () => {
1178
+ const t = q(Ye);
1179
+ if (!t)
1180
+ throw new Error("useTheme must be used within ThemeProvider");
1181
+ return t;
1182
+ };
1183
+ export {
1184
+ $t as E,
1185
+ Ne as P,
1186
+ Xt as T,
1187
+ Rt as a,
1188
+ Zt as b,
1189
+ Bt as c,
1190
+ _t as d,
1191
+ Pt as e,
1192
+ Yt as f,
1193
+ kt as g,
1194
+ Wt as h,
1195
+ wt as i,
1196
+ Lt as p,
1197
+ yt as s,
1198
+ Gt as u
1199
+ };
1200
+ //# sourceMappingURL=ThemeContext-D9AaUw9v.js.map