@snowcone-app/canvas 0.29.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/ERROR_CONTRACT.md +13 -0
  2. package/dist/{CanvasRenderer-_lFoIoz5.js → CanvasRenderer-BEf0hXeF.js} +4 -4
  3. package/dist/{CanvasRenderer-_lFoIoz5.js.map → CanvasRenderer-BEf0hXeF.js.map} +1 -1
  4. package/dist/{CanvasStateV1-BMxr6xb8.js → CanvasStateV1-BDSyYo4A.js} +868 -843
  5. package/dist/{CanvasStateV1-BMxr6xb8.js.map → CanvasStateV1-BDSyYo4A.js.map} +1 -1
  6. package/dist/ContextualToolbars-C3D_6sep.js +5960 -0
  7. package/dist/ContextualToolbars-C3D_6sep.js.map +1 -0
  8. package/dist/{EditorCanvasImpl-BNz8TPFs.js → EditorCanvasImpl-DXeBz2CX.js} +8 -8
  9. package/dist/{EditorCanvasImpl-BNz8TPFs.js.map → EditorCanvasImpl-DXeBz2CX.js.map} +1 -1
  10. package/dist/{ExportManager-B8Td7uR5.js → ExportManager-DUdis6se.js} +794 -536
  11. package/dist/ExportManager-DUdis6se.js.map +1 -0
  12. package/dist/{FontAnalyzer-D4Sg-P6_.js → FontAnalyzer-DKG5JK0x.js} +823 -808
  13. package/dist/FontAnalyzer-DKG5JK0x.js.map +1 -0
  14. package/dist/{ImagePanel-CN2Bu3hf.js → ImagePanel-CBgGqmVV.js} +53 -53
  15. package/dist/{ImagePanel-CN2Bu3hf.js.map → ImagePanel-CBgGqmVV.js.map} +1 -1
  16. package/dist/SnowconeCanvas-BWPBngvI.js +1192 -0
  17. package/dist/SnowconeCanvas-BWPBngvI.js.map +1 -0
  18. package/dist/{UnifiedFontService-CgYnYTj7.js → UnifiedFontService-Co9tQ59z.js} +869 -826
  19. package/dist/UnifiedFontService-Co9tQ59z.js.map +1 -0
  20. package/dist/advanced.mjs +14 -14
  21. package/dist/api/embed.d.ts +2 -0
  22. package/dist/api/stable.d.ts +2 -0
  23. package/dist/components/CanvasContextMenu.d.ts +15 -0
  24. package/dist/components/CanvasEditor/hooks/useCanvasInteraction.d.ts +27 -0
  25. package/dist/components/CanvasEditor.d.ts +8 -0
  26. package/dist/components/embed/SnowconeCanvas.d.ts +13 -0
  27. package/dist/components/embed/kernel.d.ts +8 -0
  28. package/dist/components/ui/icons.d.ts +2 -0
  29. package/dist/contexts/CanvasServicesContext.d.ts +17 -0
  30. package/dist/contexts/EditorContext.d.ts +7 -0
  31. package/dist/{custom-icons-B5TRC1Ed.js → custom-icons-BIaRovwG.js} +2 -2
  32. package/dist/{custom-icons-B5TRC1Ed.js.map → custom-icons-BIaRovwG.js.map} +1 -1
  33. package/dist/{design-builder-COj0zkxu.js → design-builder-JYLO_Hyi.js} +2 -2
  34. package/dist/{design-builder-COj0zkxu.js.map → design-builder-JYLO_Hyi.js.map} +1 -1
  35. package/dist/{editorErrors-CCvoKj_P.js → editorErrors-WzaNxU1Y.js} +181 -194
  36. package/dist/editorErrors-WzaNxU1Y.js.map +1 -0
  37. package/dist/{embed-BTRtoktw.js → embed-Csez1hui.js} +113 -112
  38. package/dist/{embed-BTRtoktw.js.map → embed-Csez1hui.js.map} +1 -1
  39. package/dist/embed.mjs +51 -45
  40. package/dist/embed.mjs.map +1 -1
  41. package/dist/errors/editorError.d.ts +8 -0
  42. package/dist/{guards-uQtEQJbs.js → guards-BSoX73yg.js} +2 -2
  43. package/dist/{guards-uQtEQJbs.js.map → guards-BSoX73yg.js.map} +1 -1
  44. package/dist/hooks/useKeyboardShortcuts.d.ts +15 -2
  45. package/dist/hooks/useLayers.d.ts +2 -0
  46. package/dist/index.mjs +42 -37
  47. package/dist/index.mjs.map +1 -1
  48. package/dist/internals.mjs +47 -47
  49. package/dist/state/CanvasStateV1.d.ts +31 -3
  50. package/dist/state/index.d.ts +2 -2
  51. package/dist/{template-fields-BLRp84Ny.js → template-fields-DYPW7bVU.js} +40 -40
  52. package/dist/{template-fields-BLRp84Ny.js.map → template-fields-DYPW7bVU.js.map} +1 -1
  53. package/dist/testing.mjs +13 -13
  54. package/dist/{usePieceGuideBundle-CTQszfKA.js → usePieceGuideBundle-CRLY2iQa.js} +2 -2
  55. package/dist/{usePieceGuideBundle-CTQszfKA.js.map → usePieceGuideBundle-CRLY2iQa.js.map} +1 -1
  56. package/dist/utils/custom-fonts.d.ts +99 -0
  57. package/dist/validation-BGEl9rrE.js +8686 -0
  58. package/dist/validation-BGEl9rrE.js.map +1 -0
  59. package/dist/workers/export-protocol.d.ts +13 -0
  60. package/dist/workers/export-worker.bundle.string.d.ts +1 -1
  61. package/example/package.json +1 -1
  62. package/package.json +1 -1
  63. package/dist/ContextualToolbars-0jWvnQgp.js +0 -5833
  64. package/dist/ContextualToolbars-0jWvnQgp.js.map +0 -1
  65. package/dist/ExportManager-B8Td7uR5.js.map +0 -1
  66. package/dist/FontAnalyzer-D4Sg-P6_.js.map +0 -1
  67. package/dist/SnowconeCanvas-CR_LdRFP.js +0 -1173
  68. package/dist/SnowconeCanvas-CR_LdRFP.js.map +0 -1
  69. package/dist/UnifiedFontService-CgYnYTj7.js.map +0 -1
  70. package/dist/editorErrors-CCvoKj_P.js.map +0 -1
  71. package/dist/validation-eCebhplp.js +0 -8402
  72. package/dist/validation-eCebhplp.js.map +0 -1
package/dist/embed.mjs CHANGED
@@ -1,54 +1,60 @@
1
- import { C as a, a as r, b as t, u as i, d as o, f as n, g as d } from "./UnifiedFontService-CgYnYTj7.js";
2
- import { E as l, R as u, a as E, b as c, S as p, c as g, d as S, f, p as x, e as T, g as v, h as C, v as P } from "./embed-BTRtoktw.js";
3
- import { g as B, i as h, u as y } from "./editorErrors-CCvoKj_P.js";
4
- import { D as k, d as D, a as I, i as F } from "./design-builder-COj0zkxu.js";
5
- import { D as w, T as M, h as A, i as G, j as K, k as _, l as j, m as z, r as N, u as Y, a as q, b as H, c as J, d as O, e as Q, f as U, w as V } from "./template-fields-BLRp84Ny.js";
6
- import { s as X } from "./CanvasStateV1-BMxr6xb8.js";
1
+ import { C as a, a as t, b as r, u as o, d as i, f as n, g as m } from "./UnifiedFontService-Co9tQ59z.js";
2
+ import { E as u, R as l, a as E, b as c, S as p, c as g, d as f, f as x, p as S, e as C, g as T, h as v, v as y } from "./embed-Csez1hui.js";
3
+ import { E as P, y as b } from "./FontAnalyzer-DKG5JK0x.js";
4
+ import { D as R, d as h, a as k, i as D } from "./design-builder-JYLO_Hyi.js";
5
+ import { u as L } from "./editorErrors-WzaNxU1Y.js";
6
+ import { D as M, T as A, h as G, i as K, j as _, k as j, l as z, m as N, r as Y, u as q, a as H, b as J, c as O, d as Q, e as U, f as V, w as W } from "./template-fields-DYPW7bVU.js";
7
+ import { c as Z, e as $, l as ee, r as se } from "./ExportManager-DUdis6se.js";
8
+ import { s as te } from "./CanvasStateV1-BDSyYo4A.js";
7
9
  export {
8
10
  a as CanvasServicesProvider,
9
- k as DesignBuilder,
10
- w as DesignStateStore,
11
- l as Editor,
12
- B as EditorError,
13
- u as RealtimeCanvas,
11
+ R as DesignBuilder,
12
+ M as DesignStateStore,
13
+ u as Editor,
14
+ P as EditorError,
15
+ l as RealtimeCanvas,
14
16
  E as RealtimeEmbed,
15
17
  c as RealtimeMockup,
16
18
  p as SnowconeEditor,
17
- M as TEMPLATE_FIELDS_KEY,
19
+ A as TEMPLATE_FIELDS_KEY,
18
20
  g as auditEditor,
19
- S as collectEmbedIssues,
20
- r as createProxyGenerate,
21
- t as createProxyImageSearch,
22
- D as design,
23
- A as editorElementKind,
24
- f as formatBuyPrice,
25
- I as isColorToken,
26
- h as isEditorError,
27
- G as isGroupElement,
28
- K as isImageElement,
29
- F as isLayerToken,
30
- _ as isPathElement,
31
- j as isShapeElement,
32
- z as isTextElement,
33
- x as productToRenderConfig,
34
- N as readTemplateFields,
35
- X as serializeState,
36
- i as useArtboards,
37
- o as useCanvasServices,
38
- Y as useColorBinding,
39
- q as useCommands,
40
- y as useEditor,
41
- H as useElementByName,
21
+ f as collectEmbedIssues,
22
+ t as createProxyGenerate,
23
+ r as createProxyImageSearch,
24
+ Z as customFontRegistry,
25
+ h as design,
26
+ G as editorElementKind,
27
+ $ as ensureCustomFontsLoaded,
28
+ x as formatBuyPrice,
29
+ k as isColorToken,
30
+ b as isEditorError,
31
+ K as isGroupElement,
32
+ _ as isImageElement,
33
+ D as isLayerToken,
34
+ j as isPathElement,
35
+ z as isShapeElement,
36
+ N as isTextElement,
37
+ ee as loadCustomFont,
38
+ S as productToRenderConfig,
39
+ Y as readTemplateFields,
40
+ se as registerCustomFonts,
41
+ te as serializeState,
42
+ o as useArtboards,
43
+ i as useCanvasServices,
44
+ q as useColorBinding,
45
+ H as useCommands,
46
+ L as useEditor,
47
+ J as useElementByName,
42
48
  n as useExport,
43
- J as useFontBinding,
44
- O as useImageBinding,
45
- d as useLayers,
46
- T as usePlacements,
47
- v as useProductSelection,
48
- C as useRealtimeMockups,
49
- Q as useSelectedElement,
50
- U as useTextBinding,
51
- P as validateEmbed,
52
- V as withTemplateFields
49
+ O as useFontBinding,
50
+ Q as useImageBinding,
51
+ m as useLayers,
52
+ C as usePlacements,
53
+ T as useProductSelection,
54
+ v as useRealtimeMockups,
55
+ U as useSelectedElement,
56
+ V as useTextBinding,
57
+ y as validateEmbed,
58
+ W as withTemplateFields
53
59
  };
54
60
  //# sourceMappingURL=embed.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"embed.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
1
+ {"version":3,"file":"embed.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -88,6 +88,14 @@ export type EditorErrorCode =
88
88
  /** `auditEditor()` called with no `<Editor.Root>` mounted — the imperative
89
89
  * audit reads the most-recent mounted Root's registry (#10). */
90
90
  | 'E_AUDIT_NO_ROOT'
91
+ /** A custom (brand) font failed to load from its hosted URL — the binary
92
+ * fetch failed (CORS, 404, network) or FontFace rejected the bytes.
93
+ * Custom fonts NEVER fall back silently to a system face: the design
94
+ * would render with a different typeface/metrics everywhere it's
95
+ * consumed. `data` carries `family`, `url`, `weight`, `style`. Fix the
96
+ * URL (must serve the font file over a plain cross-origin GET) and
97
+ * re-register. Dev AND prod. */
98
+ | 'E_FONT_LOAD_FAILED'
91
99
  /** `computeDistribute()` called with fewer than 3 movable elements —
92
100
  * distributing needs something between the two ends. Gate the action on
93
101
  * `useAlignDistribute().canDistribute` instead of calling below the
@@ -1,4 +1,4 @@
1
- import { G as n, I as t, P as a, S as s, T as i } from "./FontAnalyzer-D4Sg-P6_.js";
1
+ import { G as n, I as t, P as a, S as s, T as i } from "./FontAnalyzer-DKG5JK0x.js";
2
2
  function r(e) {
3
3
  return e instanceof i;
4
4
  }
@@ -21,4 +21,4 @@ export {
21
21
  r as d,
22
22
  u as i
23
23
  };
24
- //# sourceMappingURL=guards-uQtEQJbs.js.map
24
+ //# sourceMappingURL=guards-BSoX73yg.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"guards-uQtEQJbs.js","sources":["../src/types/guards.ts"],"sourcesContent":["/**\n * Type guards for EditorElement discrimination\n *\n * These guards use instanceof checks against the concrete element classes,\n * matching the pattern established in EditorContext.tsx. They accept\n * BaseElement | EditorElement | undefined | null for maximum flexibility\n * at call sites.\n */\n\nimport { BaseElement } from '../core/BaseElement.js';\nimport { TextElement } from '../core/TextElement.js';\nimport { ImageElement } from '../core/ImageElement.js';\nimport { GroupElement } from '../core/GroupElement.js';\nimport { ShapeElement } from '../core/ShapeElement.js';\nimport { PathElement } from '../core/PathElement.js';\n\ntype Narrowable = BaseElement | TextElement | ImageElement | GroupElement | ShapeElement | PathElement | undefined | null;\n\n/**\n * Type guard: checks if an element is a TextElement (or any text-based transform subclass).\n *\n * TextElement is the base class for all text transforms (custom, circle, arch, wave, etc.),\n * so this returns true for any text-based element regardless of its specific transformType.\n */\nexport function isTextElement(element: Narrowable): element is TextElement {\n return element instanceof TextElement;\n}\n\n/**\n * Type guard: checks if an element is an ImageElement.\n */\nexport function isImageElement(element: Narrowable): element is ImageElement {\n return element instanceof ImageElement;\n}\n\n/**\n * Type guard: checks if an element is a GroupElement.\n */\nexport function isGroupElement(element: Narrowable): element is GroupElement {\n return element instanceof GroupElement;\n}\n\n/**\n * Type guard: checks if an element is a ShapeElement.\n */\nexport function isShapeElement(element: Narrowable): element is ShapeElement {\n return element instanceof ShapeElement;\n}\n\n/**\n * Type guard: checks if an element is a PathElement.\n */\nexport function isPathElement(element: Narrowable): element is PathElement {\n return element instanceof PathElement;\n}\n"],"names":["isTextElement","element","TextElement","isImageElement","ImageElement","isGroupElement","GroupElement","isShapeElement","ShapeElement","isPathElement","PathElement"],"mappings":";AAwBO,SAASA,EAAcC,GAA6C;AACzE,SAAOA,aAAmBC;AAC5B;AAKO,SAASC,EAAeF,GAA8C;AAC3E,SAAOA,aAAmBG;AAC5B;AAKO,SAASC,EAAeJ,GAA8C;AAC3E,SAAOA,aAAmBK;AAC5B;AAKO,SAASC,EAAeN,GAA8C;AAC3E,SAAOA,aAAmBO;AAC5B;AAKO,SAASC,EAAcR,GAA6C;AACzE,SAAOA,aAAmBS;AAC5B;"}
1
+ {"version":3,"file":"guards-BSoX73yg.js","sources":["../src/types/guards.ts"],"sourcesContent":["/**\n * Type guards for EditorElement discrimination\n *\n * These guards use instanceof checks against the concrete element classes,\n * matching the pattern established in EditorContext.tsx. They accept\n * BaseElement | EditorElement | undefined | null for maximum flexibility\n * at call sites.\n */\n\nimport { BaseElement } from '../core/BaseElement.js';\nimport { TextElement } from '../core/TextElement.js';\nimport { ImageElement } from '../core/ImageElement.js';\nimport { GroupElement } from '../core/GroupElement.js';\nimport { ShapeElement } from '../core/ShapeElement.js';\nimport { PathElement } from '../core/PathElement.js';\n\ntype Narrowable = BaseElement | TextElement | ImageElement | GroupElement | ShapeElement | PathElement | undefined | null;\n\n/**\n * Type guard: checks if an element is a TextElement (or any text-based transform subclass).\n *\n * TextElement is the base class for all text transforms (custom, circle, arch, wave, etc.),\n * so this returns true for any text-based element regardless of its specific transformType.\n */\nexport function isTextElement(element: Narrowable): element is TextElement {\n return element instanceof TextElement;\n}\n\n/**\n * Type guard: checks if an element is an ImageElement.\n */\nexport function isImageElement(element: Narrowable): element is ImageElement {\n return element instanceof ImageElement;\n}\n\n/**\n * Type guard: checks if an element is a GroupElement.\n */\nexport function isGroupElement(element: Narrowable): element is GroupElement {\n return element instanceof GroupElement;\n}\n\n/**\n * Type guard: checks if an element is a ShapeElement.\n */\nexport function isShapeElement(element: Narrowable): element is ShapeElement {\n return element instanceof ShapeElement;\n}\n\n/**\n * Type guard: checks if an element is a PathElement.\n */\nexport function isPathElement(element: Narrowable): element is PathElement {\n return element instanceof PathElement;\n}\n"],"names":["isTextElement","element","TextElement","isImageElement","ImageElement","isGroupElement","GroupElement","isShapeElement","ShapeElement","isPathElement","PathElement"],"mappings":";AAwBO,SAASA,EAAcC,GAA6C;AACzE,SAAOA,aAAmBC;AAC5B;AAKO,SAASC,EAAeF,GAA8C;AAC3E,SAAOA,aAAmBG;AAC5B;AAKO,SAASC,EAAeJ,GAA8C;AAC3E,SAAOA,aAAmBK;AAC5B;AAKO,SAASC,EAAeN,GAA8C;AAC3E,SAAOA,aAAmBO;AAC5B;AAKO,SAASC,EAAcR,GAA6C;AACzE,SAAOA,aAAmBS;AAC5B;"}
@@ -1,7 +1,20 @@
1
+ import { useEditor } from '../contexts/EditorContext.js';
1
2
  /**
2
- * useKeyboardShortcuts - Hook for handling keyboard shortcuts in the editor
3
- * Provides copy/paste and other keyboard shortcuts
3
+ * Select every element on the ACTIVE artboard (multi-selection).
4
+ *
5
+ * Shared implementation behind Cmd/Ctrl+A AND the canvas context menu's
6
+ * "Select All" entry — one definition so the two surfaces can't drift.
7
+ * Locked elements are included — locking gates manipulation, not selection
8
+ * (gotcha #20); hidden elements are skipped to mirror marquee selection.
9
+ * Same state path as marquee selection: the multi-selection array is the
10
+ * source of truth; single selection is cleared alongside it.
4
11
  */
12
+ export declare function selectAllOnActiveArtboard(opts: {
13
+ elements: ReturnType<typeof useEditor>['elements'];
14
+ artboardManager: ReturnType<typeof useEditor>['artboardManager'];
15
+ handleSelectionChange: (id: string | null) => void;
16
+ setMultiSelection: (ids: string[]) => void;
17
+ }): void;
5
18
  /**
6
19
  * Hook that sets up keyboard shortcuts for the editor
7
20
  * Handles copy/paste, delete, undo/redo, and other shortcuts
@@ -40,6 +40,8 @@ export interface UseLayersReturn {
40
40
  reorderWithinGroup: (draggedId: string, targetId: string, position: 'before' | 'after', groupId: string) => void;
41
41
  moveLayerForward: (id: string) => void;
42
42
  moveLayerBackward: (id: string) => void;
43
+ bringToFront: (id: string) => void;
44
+ sendToBack: (id: string) => void;
43
45
  groupLayers: (ids: string[]) => void;
44
46
  ungroupLayer: (id: string) => void;
45
47
  addToGroup: (elementId: string, groupId: string) => void;
package/dist/index.mjs CHANGED
@@ -1,64 +1,69 @@
1
- import { e as u } from "./UnifiedFontService-CgYnYTj7.js";
2
- import { C as l, c as x, a as I, b as v, u as A, d as T, f as g, g as B } from "./UnifiedFontService-CgYnYTj7.js";
3
- import { E as _, S as y, S as L, u as O, a as M } from "./SnowconeCanvas-CR_LdRFP.js";
4
- import { u as d, a as m } from "./editorErrors-CCvoKj_P.js";
5
- import { T as z, r as w, u as F, a as D, b as K, c as N, d as V, e as b, f as h, w as U } from "./template-fields-BLRp84Ny.js";
6
- import { A as Z, C as G, E as H, M as j, P as k, r as q, v as J } from "./validation-eCebhplp.js";
7
- import { C as W, D as X, d as $, s as ee } from "./design-builder-COj0zkxu.js";
8
- import { c as se, e as te } from "./compose-DtQL_oit.js";
9
- import { d as oe, m as ie, s as ne, v as ue } from "./CanvasStateV1-BMxr6xb8.js";
10
- function C() {
11
- const { isCanvasReady: e } = d();
1
+ import { e as u } from "./UnifiedFontService-Co9tQ59z.js";
2
+ import { C as p, c as x, a as I, b as v, u as A, d as g, f as T, g as B } from "./UnifiedFontService-Co9tQ59z.js";
3
+ import { E as y, S as F, S as L, u as _, a as O } from "./SnowconeCanvas-BWPBngvI.js";
4
+ import { u as m, a as d } from "./editorErrors-WzaNxU1Y.js";
5
+ import { T as M, r as z, u as w, a as D, b as K, c as N, d as V, e as b, f as h, w as U } from "./template-fields-DYPW7bVU.js";
6
+ import { A as Z, C as G, E as H, M as j, P as k, r as q, v as J } from "./validation-BGEl9rrE.js";
7
+ import { c as W, e as X, l as $, r as ee } from "./ExportManager-DUdis6se.js";
8
+ import { C as ae, D as te, d as oe, s as re } from "./design-builder-JYLO_Hyi.js";
9
+ import { c as ie, e as ue } from "./compose-DtQL_oit.js";
10
+ import { d as de, m as Ce, s as Se, v as Ee } from "./CanvasStateV1-BDSyYo4A.js";
11
+ function E() {
12
+ const { isCanvasReady: e } = m();
12
13
  return e;
13
14
  }
14
- function f() {
15
- const { zoom: e, panOffset: a, zoomIn: s, zoomOut: t, zoomToFit: r, resetView: o, setZoom: i, setPanOffset: n } = m();
16
- return { zoom: e, panOffset: a, zoomIn: s, zoomOut: t, zoomToFit: r, resetView: o, setZoom: i, setPanOffset: n };
15
+ function c() {
16
+ const { zoom: e, panOffset: s, zoomIn: a, zoomOut: t, zoomToFit: o, resetView: r, setZoom: n, setPanOffset: i } = d();
17
+ return { zoom: e, panOffset: s, zoomIn: a, zoomOut: t, zoomToFit: o, resetView: r, setZoom: n, setPanOffset: i };
17
18
  }
18
19
  u();
19
20
  export {
20
21
  Z as ALL_CAPABILITIES,
21
- W as CANVAS_STATE_SCHEMA_VERSION,
22
+ ae as CANVAS_STATE_SCHEMA_VERSION,
22
23
  G as COMPACT_CUSTOMIZER,
23
- l as CanvasServicesProvider,
24
- X as DesignBuilder,
24
+ p as CanvasServicesProvider,
25
+ te as DesignBuilder,
25
26
  H as EMBED_ONLY,
26
- _ as ErrorBoundary,
27
+ y as ErrorBoundary,
27
28
  j as MINIMAL_CAPABILITIES,
28
29
  k as PRO_STUDIO,
29
- y as SnowconeCanvas,
30
- z as TEMPLATE_FIELDS_KEY,
31
- se as createKit,
30
+ F as SnowconeCanvas,
31
+ M as TEMPLATE_FIELDS_KEY,
32
+ ie as createKit,
32
33
  x as createProxyBgRemove,
33
34
  I as createProxyGenerate,
34
35
  v as createProxyImageSearch,
36
+ W as customFontRegistry,
35
37
  L as default,
36
- oe as deserializeState,
37
- $ as design,
38
- te as extendKit,
39
- ie as migrateState,
40
- w as readTemplateFields,
38
+ de as deserializeState,
39
+ oe as design,
40
+ X as ensureCustomFontsLoaded,
41
+ ue as extendKit,
42
+ $ as loadCustomFont,
43
+ Ce as migrateState,
44
+ z as readTemplateFields,
45
+ ee as registerCustomFonts,
41
46
  q as resolveKit,
42
- ne as serializeState,
43
- ee as serializeStateForServer,
47
+ Se as serializeState,
48
+ re as serializeStateForServer,
44
49
  A as useArtboards,
45
- O as useAutoExport,
46
- C as useCanvasReady,
47
- T as useCanvasServices,
48
- F as useColorBinding,
50
+ _ as useAutoExport,
51
+ E as useCanvasReady,
52
+ g as useCanvasServices,
53
+ w as useColorBinding,
49
54
  D as useCommands,
50
- M as useContentReady,
51
- d as useEditor,
55
+ O as useContentReady,
56
+ m as useEditor,
52
57
  K as useElementByName,
53
- g as useExport,
58
+ T as useExport,
54
59
  N as useFontBinding,
55
60
  V as useImageBinding,
56
61
  B as useLayers,
57
62
  b as useSelectedElement,
58
63
  h as useTextBinding,
59
- f as useViewport,
64
+ c as useViewport,
60
65
  J as validateKit,
61
- ue as validateState,
66
+ Ee as validateState,
62
67
  U as withTemplateFields
63
68
  };
64
69
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/hooks/useCanvasReady.ts","../src/hooks/useViewport.ts"],"sourcesContent":["import { useEditor } from '../contexts/EditorContext.js';\n\n/**\n * Returns whether the canvas is fully initialized and ready for operations.\n *\n * The canvas is not ready until the underlying `<canvas>` element is mounted\n * and the editor has completed its initial setup. Use this to gate operations\n * like export or programmatic element manipulation that require a live canvas.\n *\n * @returns `true` when the canvas is mounted and ready, `false` otherwise.\n *\n * @example\n * ```tsx\n * function ExportButton() {\n * const ready = useCanvasReady();\n * return (\n * <button disabled={!ready} onClick={handleExport}>\n * Export PNG\n * </button>\n * );\n * }\n * ```\n */\nexport function useCanvasReady(): boolean {\n const { isCanvasReady } = useEditor();\n return isCanvasReady;\n}\n","import React from 'react';\nimport { useViewportContext } from '../contexts/ViewportContext.js';\nimport type { PanOffset } from '../contexts/ViewportContext.js';\n\n/**\n * Return type for {@link useViewport}.\n */\nexport interface UseViewportReturn {\n /** Current zoom level (1.0 = 100%) */\n zoom: number;\n /** Current pan offset in world coordinates */\n panOffset: PanOffset;\n /** Increment zoom by one step */\n zoomIn: () => void;\n /** Decrement zoom by one step */\n zoomOut: () => void;\n /** Zoom to fit the active artboard in the viewport */\n zoomToFit: () => void;\n /** Reset zoom to 100% and pan offset to origin */\n resetView: () => void;\n /** Set zoom to an exact value */\n setZoom: React.Dispatch<React.SetStateAction<number>>;\n /** Set pan offset to an exact value */\n setPanOffset: React.Dispatch<React.SetStateAction<PanOffset>>;\n}\n\n/**\n * Returns viewport state (zoom, pan) and control functions.\n *\n * This hook now reads directly from ViewportContext (instead of the full\n * EditorContext), so components using it will only re-render when viewport\n * state changes -- not when elements, selection, or other state changes.\n *\n * @example\n * ```tsx\n * function ZoomBar() {\n * const { zoom, zoomIn, zoomOut, zoomToFit } = useViewport();\n * return (\n * <div>\n * <button onClick={zoomOut}>-</button>\n * <span>{Math.round(zoom * 100)}%</span>\n * <button onClick={zoomIn}>+</button>\n * <button onClick={zoomToFit}>Fit</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useViewport(): UseViewportReturn {\n const { zoom, panOffset, zoomIn, zoomOut, zoomToFit, resetView, setZoom, setPanOffset } = useViewportContext();\n return { zoom, panOffset, zoomIn, zoomOut, zoomToFit, resetView, setZoom, setPanOffset };\n}\n"],"names":["useCanvasReady","isCanvasReady","useEditor","useViewport","zoom","panOffset","zoomIn","zoomOut","zoomToFit","resetView","setZoom","setPanOffset","useViewportContext"],"mappings":";;;;;;;;;AAuBO,SAASA,IAA0B;AACxC,QAAM,EAAE,eAAAC,EAAA,IAAkBC,EAAA;AAC1B,SAAOD;AACT;ACsBO,SAASE,IAAiC;AAC/C,QAAM,EAAE,MAAAC,GAAM,WAAAC,GAAW,QAAAC,GAAQ,SAAAC,GAAS,WAAAC,GAAW,WAAAC,GAAW,SAAAC,GAAS,cAAAC,EAAA,IAAiBC,EAAA;AAC1F,SAAO,EAAE,MAAAR,GAAM,WAAAC,GAAW,QAAAC,GAAQ,SAAAC,GAAS,WAAAC,GAAW,WAAAC,GAAW,SAAAC,GAAS,cAAAC,EAAA;AAC5E;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/hooks/useCanvasReady.ts","../src/hooks/useViewport.ts"],"sourcesContent":["import { useEditor } from '../contexts/EditorContext.js';\n\n/**\n * Returns whether the canvas is fully initialized and ready for operations.\n *\n * The canvas is not ready until the underlying `<canvas>` element is mounted\n * and the editor has completed its initial setup. Use this to gate operations\n * like export or programmatic element manipulation that require a live canvas.\n *\n * @returns `true` when the canvas is mounted and ready, `false` otherwise.\n *\n * @example\n * ```tsx\n * function ExportButton() {\n * const ready = useCanvasReady();\n * return (\n * <button disabled={!ready} onClick={handleExport}>\n * Export PNG\n * </button>\n * );\n * }\n * ```\n */\nexport function useCanvasReady(): boolean {\n const { isCanvasReady } = useEditor();\n return isCanvasReady;\n}\n","import React from 'react';\nimport { useViewportContext } from '../contexts/ViewportContext.js';\nimport type { PanOffset } from '../contexts/ViewportContext.js';\n\n/**\n * Return type for {@link useViewport}.\n */\nexport interface UseViewportReturn {\n /** Current zoom level (1.0 = 100%) */\n zoom: number;\n /** Current pan offset in world coordinates */\n panOffset: PanOffset;\n /** Increment zoom by one step */\n zoomIn: () => void;\n /** Decrement zoom by one step */\n zoomOut: () => void;\n /** Zoom to fit the active artboard in the viewport */\n zoomToFit: () => void;\n /** Reset zoom to 100% and pan offset to origin */\n resetView: () => void;\n /** Set zoom to an exact value */\n setZoom: React.Dispatch<React.SetStateAction<number>>;\n /** Set pan offset to an exact value */\n setPanOffset: React.Dispatch<React.SetStateAction<PanOffset>>;\n}\n\n/**\n * Returns viewport state (zoom, pan) and control functions.\n *\n * This hook now reads directly from ViewportContext (instead of the full\n * EditorContext), so components using it will only re-render when viewport\n * state changes -- not when elements, selection, or other state changes.\n *\n * @example\n * ```tsx\n * function ZoomBar() {\n * const { zoom, zoomIn, zoomOut, zoomToFit } = useViewport();\n * return (\n * <div>\n * <button onClick={zoomOut}>-</button>\n * <span>{Math.round(zoom * 100)}%</span>\n * <button onClick={zoomIn}>+</button>\n * <button onClick={zoomToFit}>Fit</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useViewport(): UseViewportReturn {\n const { zoom, panOffset, zoomIn, zoomOut, zoomToFit, resetView, setZoom, setPanOffset } = useViewportContext();\n return { zoom, panOffset, zoomIn, zoomOut, zoomToFit, resetView, setZoom, setPanOffset };\n}\n"],"names":["useCanvasReady","isCanvasReady","useEditor","useViewport","zoom","panOffset","zoomIn","zoomOut","zoomToFit","resetView","setZoom","setPanOffset","useViewportContext"],"mappings":";;;;;;;;;;AAuBO,SAASA,IAA0B;AACxC,QAAM,EAAE,eAAAC,EAAA,IAAkBC,EAAA;AAC1B,SAAOD;AACT;ACsBO,SAASE,IAAiC;AAC/C,QAAM,EAAE,MAAAC,GAAM,WAAAC,GAAW,QAAAC,GAAQ,SAAAC,GAAS,WAAAC,GAAW,WAAAC,GAAW,SAAAC,GAAS,cAAAC,EAAA,IAAiBC,EAAA;AAC1F,SAAO,EAAE,MAAAR,GAAM,WAAAC,GAAW,QAAAC,GAAQ,SAAAC,GAAS,WAAAC,GAAW,WAAAC,GAAW,SAAAC,GAAS,cAAAC,EAAA;AAC5E;;"}
@@ -1,8 +1,8 @@
1
- import { A as w, a as b, C as I, I as R, R as W, S as A, T as E } from "./CanvasRenderer-_lFoIoz5.js";
2
- import { r as p } from "./ExportManager-B8Td7uR5.js";
3
- import { D as O, E as F, I as L, W as X, a as z, b as K, c as Y, d as B, e as _, f as J, h as N, i as V, j, k as q, l as Q, m as U, n as Z, o as $, p as m, q as G, s as x, t as D, u as rr, v as or, w as sr, x as ir, y as er, z as ar, A as nr, B as tr, C as hr } from "./ExportManager-B8Td7uR5.js";
4
- import { D as cr, E as fr, H as pr, J as gr, K as lr, L as ur, M as Tr, N as kr, O as Mr, Q as yr, W as Cr, V as vr, X as Sr, Y as Pr, c as wr, Z as br, _ as Ir, $ as Rr, a0 as Wr, a1 as Ar } from "./FontAnalyzer-D4Sg-P6_.js";
5
- import { A as Hr, e as Or, C as Fr, S as Lr } from "./CanvasStateV1-BMxr6xb8.js";
1
+ import { A as w, a as b, C as I, I as R, R as W, S as A, T as E } from "./CanvasRenderer-BEf0hXeF.js";
2
+ import { a as p } from "./ExportManager-DUdis6se.js";
3
+ import { D as O, E as F, I as L, W as X, b as z, d as K, f as Y, h as B, i as J, j as _, k as N, m as V, n as j, o as q, p as G, q as Q, s as U, t as Z, u as $, v as m, w as x, x as D, y as rr, z as or, A as sr, B as ir, C as ar, F as er, G as nr, H as tr, J as hr } from "./ExportManager-DUdis6se.js";
4
+ import { J as cr, K as fr, L as pr, M as gr, N as lr, O as ur, Q as Tr, V as kr, W as Mr, X as yr, Y as Cr, Z as vr, _ as Sr, $ as Pr, c as wr, a0 as br, a1 as Ir, a2 as Rr, a3 as Wr, a4 as Ar } from "./FontAnalyzer-DKG5JK0x.js";
5
+ import { A as Hr, e as Or, C as Fr, S as Lr } from "./CanvasStateV1-BDSyYo4A.js";
6
6
  function y(r, o) {
7
7
  return !r.needsCropPixelConversion || r.cropWidth === void 0 ? r : {
8
8
  ...r,
@@ -14,10 +14,10 @@ function y(r, o) {
14
14
  };
15
15
  }
16
16
  function C(r, o, c) {
17
- var a, n;
17
+ var e, n;
18
18
  r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180);
19
- let e = 1, h = 1;
20
- if (o.flipHorizontal && (e = -1), o.flipVertical && (h = -1), (e !== 1 || h !== 1) && r.scale(e, h), o.opacity !== void 0 && o.opacity !== 1 && (r.globalAlpha = o.opacity), o.borderRadius && o.borderRadius > 0) {
19
+ let a = 1, h = 1;
20
+ if (o.flipHorizontal && (a = -1), o.flipVertical && (h = -1), (a !== 1 || h !== 1) && r.scale(a, h), o.opacity !== void 0 && o.opacity !== 1 && (r.globalAlpha = o.opacity), o.borderRadius && o.borderRadius > 0) {
21
21
  const i = Math.min(
22
22
  o.borderRadius / 100 * Math.min(o.width, o.height),
23
23
  o.width / 2,
@@ -37,7 +37,7 @@ function C(r, o, c) {
37
37
  -o.height / 2,
38
38
  o.width,
39
39
  o.height
40
- ) : r.drawImage(c, -o.width / 2, -o.height / 2, o.width, o.height), r.restore(), (a = o.stroke) != null && a.enabled) {
40
+ ) : r.drawImage(c, -o.width / 2, -o.height / 2, o.width, o.height), r.restore(), (e = o.stroke) != null && e.enabled) {
41
41
  const i = ((n = o.knockoutParts) == null ? void 0 : n.stroke) === !0, s = {
42
42
  x: o.x,
43
43
  y: o.y,
@@ -79,13 +79,13 @@ function T(r, o) {
79
79
  return c.width = r, c.height = o, c;
80
80
  }
81
81
  function v(r, o) {
82
- var a;
83
- const c = o.opacity ?? 1, e = !!((a = o.stroke) != null && a.enabled);
84
- c < 1 && e ? k(r, o, c) : g(r, o, c);
82
+ var e;
83
+ const c = o.opacity ?? 1, a = !!((e = o.stroke) != null && e.enabled);
84
+ c < 1 && a ? k(r, o, c) : g(r, o, c);
85
85
  }
86
86
  function k(r, o, c) {
87
87
  var f;
88
- const e = o.transformData, a = (((f = o.stroke) == null ? void 0 : f.width) || 2) + 2, n = Math.ceil(e.width + a * 2), i = Math.ceil(e.height + a * 2), s = T(n, i), t = s.getContext("2d");
88
+ const a = o.transformData, e = (((f = o.stroke) == null ? void 0 : f.width) || 2) + 2, n = Math.ceil(a.width + e * 2), i = Math.ceil(a.height + e * 2), s = T(n, i), t = s.getContext("2d");
89
89
  if (!t) {
90
90
  g(r, o, c);
91
91
  return;
@@ -98,65 +98,65 @@ function k(r, o, c) {
98
98
  g(t, d, 1), r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180), r.globalAlpha = c, r.drawImage(s, -n / 2, -i / 2), r.restore();
99
99
  }
100
100
  function g(r, o, c) {
101
- var a;
102
- const e = o.transformData, h = e.fillOpacity ?? 1;
103
- if (r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180), r.globalAlpha = c * h, r.fillStyle = e.fillColor || "#3b82f6", r.beginPath(), u(r, e), r.fill(), r.restore(), (a = o.stroke) != null && a.enabled) {
101
+ var e;
102
+ const a = o.transformData, h = a.fillOpacity ?? 1;
103
+ if (r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180), r.globalAlpha = c * h, r.fillStyle = a.fillColor || "#3b82f6", r.beginPath(), u(r, a), r.fill(), r.restore(), (e = o.stroke) != null && e.enabled) {
104
104
  r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180);
105
105
  const n = o.stroke;
106
- r.globalAlpha = c * (n.opacity ?? 1), r.strokeStyle = n.color || "#000000", r.lineWidth = n.width || 2, r.lineCap = n.lineCap || "round", r.lineJoin = n.lineJoin || "round", r.beginPath(), u(r, e), r.stroke(), r.restore();
106
+ r.globalAlpha = c * (n.opacity ?? 1), r.strokeStyle = n.color || "#000000", r.lineWidth = n.width || 2, r.lineCap = n.lineCap || "round", r.lineJoin = n.lineJoin || "round", r.beginPath(), u(r, a), r.stroke(), r.restore();
107
107
  }
108
108
  }
109
109
  function u(r, o) {
110
- const { shapeType: c, width: e, height: h } = o;
110
+ const { shapeType: c, width: a, height: h } = o;
111
111
  switch (c) {
112
112
  case "rectangle": {
113
- const a = o.borderRadius || 0, n = -e / 2, i = -h / 2;
114
- if (a > 0) {
115
- const s = Math.min(a / 100 * Math.min(e, h), e / 2, h / 2);
116
- r.roundRect(n, i, e, h, s);
113
+ const e = o.borderRadius || 0, n = -a / 2, i = -h / 2;
114
+ if (e > 0) {
115
+ const s = Math.min(e / 100 * Math.min(a, h), a / 2, h / 2);
116
+ r.roundRect(n, i, a, h, s);
117
117
  } else
118
- r.rect(n, i, e, h);
118
+ r.rect(n, i, a, h);
119
119
  break;
120
120
  }
121
121
  case "circle": {
122
- const a = Math.min(e, h) / 2;
123
- r.arc(0, 0, a, 0, Math.PI * 2);
122
+ const e = Math.min(a, h) / 2;
123
+ r.arc(0, 0, e, 0, Math.PI * 2);
124
124
  break;
125
125
  }
126
126
  case "ellipse": {
127
- r.ellipse(0, 0, e / 2, h / 2, 0, 0, Math.PI * 2);
127
+ r.ellipse(0, 0, a / 2, h / 2, 0, 0, Math.PI * 2);
128
128
  break;
129
129
  }
130
130
  case "triangle": {
131
- const a = e / 2, n = h / 2;
132
- r.moveTo(0, -n), r.lineTo(a, n), r.lineTo(-a, n), r.closePath();
131
+ const e = a / 2, n = h / 2;
132
+ r.moveTo(0, -n), r.lineTo(e, n), r.lineTo(-e, n), r.closePath();
133
133
  break;
134
134
  }
135
135
  case "polygon": {
136
- const a = o.sides || 5, n = Math.min(e, h) / 2;
137
- for (let i = 0; i < a; i++) {
138
- const s = i * 2 * Math.PI / a - Math.PI / 2, t = n * Math.cos(s), d = n * Math.sin(s);
136
+ const e = o.sides || 5, n = Math.min(a, h) / 2;
137
+ for (let i = 0; i < e; i++) {
138
+ const s = i * 2 * Math.PI / e - Math.PI / 2, t = n * Math.cos(s), d = n * Math.sin(s);
139
139
  i === 0 ? r.moveTo(t, d) : r.lineTo(t, d);
140
140
  }
141
141
  r.closePath();
142
142
  break;
143
143
  }
144
144
  case "star": {
145
- const a = o.points || 5, n = Math.min(e, h) / 2, i = n * (o.innerRadius || 0.4);
146
- for (let s = 0; s < a * 2; s++) {
147
- const t = s * Math.PI / a - Math.PI / 2, d = s % 2 === 0 ? n : i, f = d * Math.cos(t), l = d * Math.sin(t);
145
+ const e = o.points || 5, n = Math.min(a, h) / 2, i = n * (o.innerRadius || 0.4);
146
+ for (let s = 0; s < e * 2; s++) {
147
+ const t = s * Math.PI / e - Math.PI / 2, d = s % 2 === 0 ? n : i, f = d * Math.cos(t), l = d * Math.sin(t);
148
148
  s === 0 ? r.moveTo(f, l) : r.lineTo(f, l);
149
149
  }
150
150
  r.closePath();
151
151
  break;
152
152
  }
153
153
  case "line": {
154
- const a = e / 2, n = h / 2;
155
- r.rect(-a, -n, e, h);
154
+ const e = a / 2, n = h / 2;
155
+ r.rect(-e, -n, a, h);
156
156
  break;
157
157
  }
158
158
  default:
159
- r.rect(-e / 2, -h / 2, e, h);
159
+ r.rect(-a / 2, -h / 2, a, h);
160
160
  }
161
161
  }
162
162
  export {
@@ -193,22 +193,22 @@ export {
193
193
  Sr as calculateResizeHandles,
194
194
  Pr as calculateRotationHandlePosition,
195
195
  B as clearImageBitmapCache,
196
- _ as clearMaskCache,
197
- J as clearRegisteredBitmapKeys,
196
+ J as clearMaskCache,
197
+ _ as clearRegisteredBitmapKeys,
198
198
  N as createCirclePath,
199
199
  V as createImagePath,
200
200
  wr as createLogger,
201
201
  j as createRectPath,
202
202
  q as createTextPath,
203
- Q as getFontMetrics,
204
- U as getSharedWorkerExportManager,
203
+ G as getFontMetrics,
204
+ Q as getSharedWorkerExportManager,
205
205
  br as hitTestCircle,
206
206
  Ir as hitTestRect,
207
- Z as invalidateMaskCache,
207
+ U as invalidateMaskCache,
208
208
  Rr as logger,
209
- $ as measureTextWidth,
210
- m as removeFromImageBitmapCache,
211
- G as renderCustomTransform,
209
+ Z as measureTextWidth,
210
+ $ as removeFromImageBitmapCache,
211
+ m as renderCustomTransform,
212
212
  C as renderImageElement,
213
213
  p as renderImageStroke,
214
214
  x as renderMultilineText,
@@ -218,8 +218,8 @@ export {
218
218
  or as renderTextElement,
219
219
  sr as renderTextFillOnly,
220
220
  ir as renderTextStroke,
221
- er as renderWithKnockout,
222
- ar as renderWithMasks,
221
+ ar as renderWithKnockout,
222
+ er as renderWithMasks,
223
223
  y as resolveServerCrop,
224
224
  Wr as splitRichTextIntoLines,
225
225
  nr as terminateSharedWorkerExportManager,
@@ -2,6 +2,7 @@ import { z } from 'zod';
2
2
  import { ArtboardManager } from '../core/ArtboardManager.js';
3
3
  import { ArtboardElement } from '../core/ArtboardElement.js';
4
4
  import { BaseElement } from '../core/BaseElement.js';
5
+ import { CustomFont } from '../utils/custom-fonts.js';
5
6
  declare const StrokeConfigSchema: z.ZodObject<{
6
7
  enabled: z.ZodBoolean;
7
8
  color: z.ZodString;
@@ -266,6 +267,15 @@ declare const SerializedArtboardSchema: z.ZodObject<{
266
267
  }>>;
267
268
  elementIds: z.ZodArray<z.ZodString>;
268
269
  }, z.core.$strip>;
270
+ /**
271
+ * A custom (brand) font dependency of the design — `{ family, url }` of a
272
+ * host-stored font binary plus optional weight/style descriptors. Saved
273
+ * designs carry these so every consumer (live editor, export worker, server
274
+ * render) can load the exact file. Families are stored as-is; a family that
275
+ * collides with a Google Fonts family deterministically SHADOWS it (see
276
+ * `utils/custom-fonts.ts` for the resolution contract).
277
+ */
278
+ declare const CustomFontSchema: z.ZodType<CustomFont>;
269
279
  /**
270
280
  * Top-level CanvasStateV1 schema.
271
281
  *
@@ -273,6 +283,7 @@ declare const SerializedArtboardSchema: z.ZodObject<{
273
283
  * - `artboards` contains serialized artboard configs with `elementIds`.
274
284
  * - `elements` is a flat array of all elements across all artboards.
275
285
  * - `activeArtboardId` identifies which artboard is currently active.
286
+ * - `customFonts` (optional) lists the design's custom-font dependencies.
276
287
  */
277
288
  declare const CanvasStateV1Schema: z.ZodObject<{
278
289
  version: z.ZodLiteral<1>;
@@ -324,6 +335,7 @@ declare const CanvasStateV1Schema: z.ZodObject<{
324
335
  }, z.core.$strip>>;
325
336
  elements: z.ZodArray<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
326
337
  activeArtboardId: z.ZodString;
338
+ customFonts: z.ZodOptional<z.ZodArray<z.ZodType<CustomFont, unknown, z.core.$ZodTypeInternals<CustomFont, unknown>>>>;
327
339
  }, z.core.$strip>;
328
340
  /** A serialized artboard (artboard config + elementIds, no nested elements). */
329
341
  type SerializedArtboard = z.infer<typeof SerializedArtboardSchema>;
@@ -331,19 +343,35 @@ type SerializedArtboard = z.infer<typeof SerializedArtboardSchema>;
331
343
  type SerializedElement = z.infer<typeof AnyElementConfigSchema>;
332
344
  /** The full versioned state document. */
333
345
  type CanvasStateV1 = z.infer<typeof CanvasStateV1Schema>;
346
+ /** Options for {@link serializeState}. */
347
+ interface SerializeStateOptions {
348
+ /**
349
+ * Custom-font dependencies to embed in the document. When omitted, the
350
+ * default is CORRECT, not empty: the registered custom fonts whose family
351
+ * is actually used by the serialized elements are included automatically,
352
+ * so a host that uploaded a brand font cannot forget to persist it.
353
+ * Pass `[]` explicitly to serialize without custom fonts.
354
+ */
355
+ customFonts?: readonly CustomFont[];
356
+ }
334
357
  /**
335
358
  * Serialize the current editor state into a `CanvasStateV1` document.
336
359
  *
337
360
  * @param artboardManager - The ArtboardManager instance (provides artboard list + active ID).
338
361
  * @param elements - All elements currently in the editor (across all artboards).
362
+ * @param options - See {@link SerializeStateOptions} (`customFonts` defaults to
363
+ * the registered custom fonts the elements actually use).
339
364
  * @returns A validated CanvasStateV1 object ready for JSON.stringify().
340
365
  */
341
- declare function serializeState(artboardManager: ArtboardManager, elements: BaseElement[]): CanvasStateV1;
366
+ declare function serializeState(artboardManager: ArtboardManager, elements: BaseElement[], options?: SerializeStateOptions): CanvasStateV1;
342
367
  /** Result of deserializing a CanvasStateV1 document. */
343
368
  interface DeserializeResult {
344
369
  artboards: ArtboardElement[];
345
370
  elements: BaseElement[];
346
371
  activeArtboardId: string;
372
+ /** The design's custom-font dependencies (already registered with
373
+ * `customFontRegistry` as a side effect of deserializing). */
374
+ customFonts: CustomFont[];
347
375
  }
348
376
  /**
349
377
  * Deserialize a validated `CanvasStateV1` document back into runtime objects.
@@ -384,5 +412,5 @@ declare function validateState(data: unknown): ValidationResult;
384
412
  * @throws Error if the data cannot be migrated.
385
413
  */
386
414
  declare function migrateState(data: unknown): CanvasStateV1;
387
- export { CanvasStateV1Schema, SerializedArtboardSchema, AnyElementConfigSchema, AnyTransformDataSchema, StrokeConfigSchema, KnockoutConfigSchema, DistressEffectSchema, MaskDefinitionSchema, CharacterStyleSchema, TextSpanSchema, RichTextSchema, ClipShapeSchema, serializeState, deserializeState, validateState, migrateState, };
388
- export type { CanvasStateV1, SerializedArtboard, SerializedElement, DeserializeResult, ValidationResult, };
415
+ export { CanvasStateV1Schema, SerializedArtboardSchema, AnyElementConfigSchema, AnyTransformDataSchema, StrokeConfigSchema, KnockoutConfigSchema, DistressEffectSchema, MaskDefinitionSchema, CharacterStyleSchema, TextSpanSchema, RichTextSchema, ClipShapeSchema, CustomFontSchema, serializeState, deserializeState, validateState, migrateState, };
416
+ export type { CanvasStateV1, SerializedArtboard, SerializedElement, DeserializeResult, ValidationResult, SerializeStateOptions, CustomFont, };
@@ -6,5 +6,5 @@
6
6
  *
7
7
  * @module
8
8
  */
9
- export { CanvasStateV1Schema, SerializedArtboardSchema, AnyElementConfigSchema, AnyTransformDataSchema, StrokeConfigSchema, KnockoutConfigSchema, DistressEffectSchema, MaskDefinitionSchema, CharacterStyleSchema, TextSpanSchema, RichTextSchema, ClipShapeSchema, serializeState, deserializeState, validateState, migrateState, } from './CanvasStateV1.js';
10
- export type { CanvasStateV1, SerializedArtboard, SerializedElement, DeserializeResult, ValidationResult, } from './CanvasStateV1.js';
9
+ export { CanvasStateV1Schema, SerializedArtboardSchema, AnyElementConfigSchema, AnyTransformDataSchema, StrokeConfigSchema, KnockoutConfigSchema, DistressEffectSchema, MaskDefinitionSchema, CharacterStyleSchema, TextSpanSchema, RichTextSchema, ClipShapeSchema, CustomFontSchema, serializeState, deserializeState, validateState, migrateState, } from './CanvasStateV1.js';
10
+ export type { CanvasStateV1, SerializedArtboard, SerializedElement, DeserializeResult, ValidationResult, SerializeStateOptions, CustomFont, } from './CanvasStateV1.js';