@snowcone-app/canvas 0.27.0 → 0.29.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 (73) hide show
  1. package/ERROR_CONTRACT.md +13 -0
  2. package/dist/{CanvasRenderer-yszzrDfo.js → CanvasRenderer-_lFoIoz5.js} +916 -848
  3. package/dist/CanvasRenderer-_lFoIoz5.js.map +1 -0
  4. package/dist/{CanvasStateV1-BTbCD_xC.js → CanvasStateV1-BMxr6xb8.js} +7 -4
  5. package/dist/{CanvasStateV1-BTbCD_xC.js.map → CanvasStateV1-BMxr6xb8.js.map} +1 -1
  6. package/dist/ContextualToolbars-0jWvnQgp.js +5833 -0
  7. package/dist/ContextualToolbars-0jWvnQgp.js.map +1 -0
  8. package/dist/{EditorCanvasImpl-Ui8Ceb-h.js → EditorCanvasImpl-BNz8TPFs.js} +8 -8
  9. package/dist/{EditorCanvasImpl-Ui8Ceb-h.js.map → EditorCanvasImpl-BNz8TPFs.js.map} +1 -1
  10. package/dist/{ExportManager-BTcyj4cf.js → ExportManager-B8Td7uR5.js} +1051 -976
  11. package/dist/ExportManager-B8Td7uR5.js.map +1 -0
  12. package/dist/{FontAnalyzer-EF3gLPr8.js → FontAnalyzer-D4Sg-P6_.js} +1410 -1329
  13. package/dist/FontAnalyzer-D4Sg-P6_.js.map +1 -0
  14. package/dist/{ImagePanel-CIk6z41z.js → ImagePanel-CN2Bu3hf.js} +6 -6
  15. package/dist/{ImagePanel-CIk6z41z.js.map → ImagePanel-CN2Bu3hf.js.map} +1 -1
  16. package/dist/{SnowconeCanvas-DuWALOAt.js → SnowconeCanvas-CR_LdRFP.js} +27 -27
  17. package/dist/{SnowconeCanvas-DuWALOAt.js.map → SnowconeCanvas-CR_LdRFP.js.map} +1 -1
  18. package/dist/{UnifiedFontService-CHVYDBDW.js → UnifiedFontService-CgYnYTj7.js} +755 -713
  19. package/dist/UnifiedFontService-CgYnYTj7.js.map +1 -0
  20. package/dist/advanced.mjs +14 -14
  21. package/dist/components/MultiSelectionToolbar.d.ts +18 -0
  22. package/dist/components/toolbars/SecondaryPanels.d.ts +11 -0
  23. package/dist/components/ui/toolbar-button.d.ts +2 -0
  24. package/dist/core/GestureConstraints.d.ts +92 -0
  25. package/dist/core/InteractionStateMachine.d.ts +16 -2
  26. package/dist/core/ResizeHandler.d.ts +4 -1
  27. package/dist/core/ResizePipeline.d.ts +3 -0
  28. package/dist/core/TextElement.d.ts +13 -0
  29. package/dist/core/TextMetrics.d.ts +17 -3
  30. package/dist/core/rich-text-layout.d.ts +2 -0
  31. package/dist/core/text-spacing.d.ts +74 -0
  32. package/dist/{custom-icons-CcLMyybv.js → custom-icons-B5TRC1Ed.js} +2 -2
  33. package/dist/{custom-icons-CcLMyybv.js.map → custom-icons-B5TRC1Ed.js.map} +1 -1
  34. package/dist/{design-builder-cZY958Rw.js → design-builder-COj0zkxu.js} +2 -2
  35. package/dist/{design-builder-cZY958Rw.js.map → design-builder-COj0zkxu.js.map} +1 -1
  36. package/dist/{editorErrors-BhrZ_nwj.js → editorErrors-CCvoKj_P.js} +2 -2
  37. package/dist/editorErrors-CCvoKj_P.js.map +1 -0
  38. package/dist/{embed-CJswRZte.js → embed-BTRtoktw.js} +10 -10
  39. package/dist/{embed-CJswRZte.js.map → embed-BTRtoktw.js.map} +1 -1
  40. package/dist/embed.mjs +6 -6
  41. package/dist/errors/editorError.d.ts +7 -1
  42. package/dist/{guards-DIX8aXWM.js → guards-uQtEQJbs.js} +2 -2
  43. package/dist/{guards-DIX8aXWM.js.map → guards-uQtEQJbs.js.map} +1 -1
  44. package/dist/hooks/index.d.ts +2 -0
  45. package/dist/hooks/useAlignDistribute.d.ts +19 -0
  46. package/dist/hooks/useTextToolbar.d.ts +8 -0
  47. package/dist/index.mjs +8 -8
  48. package/dist/internals.mjs +5 -5
  49. package/dist/rendering/renderer-types.d.ts +4 -0
  50. package/dist/rendering/rich-text-renderer.d.ts +4 -0
  51. package/dist/rendering/text-renderer.d.ts +4 -1
  52. package/dist/state/CanvasStateV1.d.ts +3 -0
  53. package/dist/{template-fields-BXl29sgh.js → template-fields-BLRp84Ny.js} +6 -6
  54. package/dist/{template-fields-BXl29sgh.js.map → template-fields-BLRp84Ny.js.map} +1 -1
  55. package/dist/testing.mjs +4 -4
  56. package/dist/types/index.d.ts +26 -0
  57. package/dist/{usePieceGuideBundle-DE21DQGZ.js → usePieceGuideBundle-CTQszfKA.js} +2 -2
  58. package/dist/{usePieceGuideBundle-DE21DQGZ.js.map → usePieceGuideBundle-CTQszfKA.js.map} +1 -1
  59. package/dist/utils/alignDistribute.d.ts +41 -0
  60. package/dist/utils/featureApplied.d.ts +6 -0
  61. package/dist/{validation-DGXAQmUC.js → validation-eCebhplp.js} +2991 -2956
  62. package/dist/validation-eCebhplp.js.map +1 -0
  63. package/dist/workers/export-worker.bundle.string.d.ts +1 -1
  64. package/example/package.json +1 -1
  65. package/package.json +1 -1
  66. package/dist/CanvasRenderer-yszzrDfo.js.map +0 -1
  67. package/dist/ContextualToolbars-BHjYsril.js +0 -5556
  68. package/dist/ContextualToolbars-BHjYsril.js.map +0 -1
  69. package/dist/ExportManager-BTcyj4cf.js.map +0 -1
  70. package/dist/FontAnalyzer-EF3gLPr8.js.map +0 -1
  71. package/dist/UnifiedFontService-CHVYDBDW.js.map +0 -1
  72. package/dist/editorErrors-BhrZ_nwj.js.map +0 -1
  73. package/dist/validation-DGXAQmUC.js.map +0 -1
package/dist/embed.mjs CHANGED
@@ -1,9 +1,9 @@
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-CHVYDBDW.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-CJswRZte.js";
3
- import { g as B, i as h, u as y } from "./editorErrors-BhrZ_nwj.js";
4
- import { D as k, d as D, a as I, i as F } from "./design-builder-cZY958Rw.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-BXl29sgh.js";
6
- import { s as X } from "./CanvasStateV1-BTbCD_xC.js";
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";
7
7
  export {
8
8
  a as CanvasServicesProvider,
9
9
  k as DesignBuilder,
@@ -87,7 +87,13 @@ export type EditorErrorCode =
87
87
  | 'E_NO_MUTABLE_BINDING'
88
88
  /** `auditEditor()` called with no `<Editor.Root>` mounted — the imperative
89
89
  * audit reads the most-recent mounted Root's registry (#10). */
90
- | 'E_AUDIT_NO_ROOT';
90
+ | 'E_AUDIT_NO_ROOT'
91
+ /** `computeDistribute()` called with fewer than 3 movable elements —
92
+ * distributing needs something between the two ends. Gate the action on
93
+ * `useAlignDistribute().canDistribute` instead of calling below the
94
+ * threshold (the toolbar hides its distribute buttons for exactly this
95
+ * reason). */
96
+ | 'E_DISTRIBUTE_MIN_THREE';
91
97
  export interface EditorErrorData {
92
98
  code: EditorErrorCode;
93
99
  /** Slug under https://developers.snowcone.app/ for the violated contract. */
@@ -1,4 +1,4 @@
1
- import { G as n, I as t, P as a, S as s, T as i } from "./FontAnalyzer-EF3gLPr8.js";
1
+ import { G as n, I as t, P as a, S as s, T as i } from "./FontAnalyzer-D4Sg-P6_.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-DIX8aXWM.js.map
24
+ //# sourceMappingURL=guards-uQtEQJbs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"guards-DIX8aXWM.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-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;"}
@@ -40,3 +40,5 @@ export { useCanvasEvents } from './useCanvasEvents';
40
40
  export { useCommandHistory } from './useCommandHistory';
41
41
  export { useKeyboardShortcuts } from './useKeyboardShortcuts';
42
42
  export { useElementProperties } from './useElementProperties';
43
+ export { useAlignDistribute } from './useAlignDistribute';
44
+ export type { UseAlignDistributeResult, AlignMode, DistributeMode } from './useAlignDistribute';
@@ -0,0 +1,19 @@
1
+ import { AlignMode, DistributeMode } from '../utils/alignDistribute.js';
2
+ export type { AlignMode, DistributeMode } from '../utils/alignDistribute.js';
3
+ export interface UseAlignDistributeResult {
4
+ /** Number of movable (selected, unlocked) elements. */
5
+ movableCount: number;
6
+ /** True when align commands have something to act on. */
7
+ canAlign: boolean;
8
+ /** True when distribute commands are available (≥3 movable elements).
9
+ * UI must gate rendering of distribute affordances on this. */
10
+ canDistribute: boolean;
11
+ /** Align the movable selection. ≥2 elements: relative to the selection's
12
+ * combined bbox; exactly 1: relative to the active artboard. */
13
+ align: (mode: AlignMode) => void;
14
+ /** Distribute the movable selection with equal gaps between bbox edges.
15
+ * Throws `E_DISTRIBUTE_MIN_THREE` when `canDistribute` is false. */
16
+ distribute: (mode: DistributeMode) => void;
17
+ }
18
+ export declare function useAlignDistribute(): UseAlignDistributeResult;
19
+ export default useAlignDistribute;
@@ -12,8 +12,16 @@ export interface UseTextToolbarReturn {
12
12
  italic: boolean;
13
13
  underline: boolean;
14
14
  letterCase: string;
15
+ /** Letter-spacing in px per character (element-level default; 0 = none). */
16
+ letterSpacing: number;
17
+ /** Line-height multiplier (1.2 = the layout default). */
18
+ lineHeight: number;
15
19
  handleFontSizeChange: (size: number) => void;
16
20
  handleFontSizeIncrement: (delta: number) => void;
21
+ /** Per-character aware (applies to the selection while editing text). */
22
+ handleLetterSpacingChange: (spacing: number) => void;
23
+ /** Element-level only (line layout is an element concern, not a span one). */
24
+ handleLineHeightChange: (lineHeight: number) => void;
17
25
  handleFontFamilyChange: (family: string) => void;
18
26
  handleFontColorChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
19
27
  handleBoldToggle: () => void;
package/dist/index.mjs CHANGED
@@ -1,12 +1,12 @@
1
- import { e as u } from "./UnifiedFontService-CHVYDBDW.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-CHVYDBDW.js";
3
- import { E as _, S as y, S as L, u as O, a as M } from "./SnowconeCanvas-DuWALOAt.js";
4
- import { u as d, a as m } from "./editorErrors-BhrZ_nwj.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-BXl29sgh.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-DGXAQmUC.js";
7
- import { C as W, D as X, d as $, s as ee } from "./design-builder-cZY958Rw.js";
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
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-BTbCD_xC.js";
9
+ import { d as oe, m as ie, s as ne, v as ue } from "./CanvasStateV1-BMxr6xb8.js";
10
10
  function C() {
11
11
  const { isCanvasReady: e } = d();
12
12
  return e;
@@ -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-yszzrDfo.js";
2
- import { r as p } from "./ExportManager-BTcyj4cf.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-BTcyj4cf.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-EF3gLPr8.js";
5
- import { A as Hr, e as Or, C as Fr, S as Lr } from "./CanvasStateV1-BTbCD_xC.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-_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";
6
6
  function y(r, o) {
7
7
  return !r.needsCropPixelConversion || r.cropWidth === void 0 ? r : {
8
8
  ...r,
@@ -19,6 +19,10 @@ export interface SerializedTextElement {
19
19
  italic: boolean;
20
20
  underline: boolean;
21
21
  strikethrough: boolean;
22
+ /** Extra advance per character in px (custom transform only; spans may override). */
23
+ letterSpacing?: number;
24
+ /** Line-height multiplier; undefined = LINE_HEIGHT_MULTIPLIER (1.2). Custom transform only. */
25
+ lineHeight?: number;
22
26
  transformData: AnyTransformData;
23
27
  stroke?: StrokeConfig;
24
28
  openTypeFeatures?: OpenTypeFeatures;
@@ -15,4 +15,8 @@ export declare function renderRichTextFillOnly(ctx: RenderContext, richText: Ric
15
15
  underline?: boolean;
16
16
  strikethrough?: boolean;
17
17
  textAlign?: TextAlign;
18
+ /** Element-level letter-spacing default (px/char); spans may override. */
19
+ letterSpacing?: number;
20
+ /** Line-height multiplier; undefined = LINE_HEIGHT_MULTIPLIER (1.2). */
21
+ lineHeight?: number;
18
22
  }, maxWidth?: number, lockedLineCount?: number): void;
@@ -6,8 +6,9 @@ import { RenderContext, SerializedTextElement } from './renderer-types.js';
6
6
  export declare function buildFontString(fontSize: number, fontFamily: string, bold?: boolean, italic?: boolean): string;
7
7
  /**
8
8
  * Measure text width
9
+ * @param letterSpacing - Extra advance per character in px (default 0 — legacy width)
9
10
  */
10
- export declare function measureTextWidth(text: string, fontSize: number, fontFamily: string, bold?: boolean, italic?: boolean): number;
11
+ export declare function measureTextWidth(text: string, fontSize: number, fontFamily: string, bold?: boolean, italic?: boolean, letterSpacing?: number): number;
11
12
  /**
12
13
  * Get font metrics for accurate text positioning
13
14
  */
@@ -49,6 +50,8 @@ export declare function renderTextFillOnly(ctx: RenderContext, element: {
49
50
  italic?: boolean;
50
51
  textAlign?: TextAlign;
51
52
  color: string;
53
+ /** Extra advance per character in px (custom transform only). */
54
+ letterSpacing?: number;
52
55
  }): void;
53
56
  /**
54
57
  * Word wrap text to fit within a given width
@@ -74,6 +74,7 @@ declare const CharacterStyleSchema: z.ZodObject<{
74
74
  italic: z.ZodOptional<z.ZodBoolean>;
75
75
  underline: z.ZodOptional<z.ZodBoolean>;
76
76
  strikethrough: z.ZodOptional<z.ZodBoolean>;
77
+ letterSpacing: z.ZodOptional<z.ZodNumber>;
77
78
  }, z.core.$strip>;
78
79
  declare const TextSpanSchema: z.ZodObject<{
79
80
  text: z.ZodString;
@@ -85,6 +86,7 @@ declare const TextSpanSchema: z.ZodObject<{
85
86
  italic: z.ZodOptional<z.ZodBoolean>;
86
87
  underline: z.ZodOptional<z.ZodBoolean>;
87
88
  strikethrough: z.ZodOptional<z.ZodBoolean>;
89
+ letterSpacing: z.ZodOptional<z.ZodNumber>;
88
90
  }, z.core.$strip>;
89
91
  }, z.core.$strip>;
90
92
  declare const RichTextSchema: z.ZodObject<{
@@ -98,6 +100,7 @@ declare const RichTextSchema: z.ZodObject<{
98
100
  italic: z.ZodOptional<z.ZodBoolean>;
99
101
  underline: z.ZodOptional<z.ZodBoolean>;
100
102
  strikethrough: z.ZodOptional<z.ZodBoolean>;
103
+ letterSpacing: z.ZodOptional<z.ZodNumber>;
101
104
  }, z.core.$strip>;
102
105
  }, z.core.$strip>>;
103
106
  }, z.core.$strip>;
@@ -1,10 +1,10 @@
1
- import { g as C, u as ut, c as Y, b as W } from "./editorErrors-BhrZ_nwj.js";
2
- import { l as it, i as gt, a as Nt } from "./design-builder-cZY958Rw.js";
1
+ import { g as C, u as ut, c as Y, b as W } from "./editorErrors-CCvoKj_P.js";
2
+ import { l as it, i as gt, a as Nt } from "./design-builder-COj0zkxu.js";
3
3
  import { toOptionAttributes as St, toCombinations as It, getMissingSelections as wt, validateProductSelection as Ot, findBestCombination as J, computeDisabledChoices as At } from "@snowcone-app/sdk";
4
4
  import { useRef as E, useCallback as I, useEffect as Tt, useContext as ht, useId as kt, useLayoutEffect as Dt, useMemo as V, useState as ot } from "react";
5
- import { G as Bt, I as z, P as _t, S as Ft, T as K, z as yt, U as st, c as Ut, y as rt } from "./FontAnalyzer-EF3gLPr8.js";
6
- import { p as pt, U as Rt } from "./UnifiedFontService-CHVYDBDW.js";
7
- import { a as Lt, o as R, b as d, n as Pt, l as b, u as at, c as Yt } from "./CanvasStateV1-BTbCD_xC.js";
5
+ import { G as Bt, I as z, P as _t, S as Ft, T as K, z as yt, U as st, c as Ut, y as rt } from "./FontAnalyzer-D4Sg-P6_.js";
6
+ import { p as pt, U as Rt } from "./UnifiedFontService-CgYnYTj7.js";
7
+ import { a as Lt, o as R, b as d, n as Pt, l as b, u as at, c as Yt } from "./CanvasStateV1-BMxr6xb8.js";
8
8
  function X(e) {
9
9
  return e.text;
10
10
  }
@@ -713,4 +713,4 @@ export {
713
713
  Oe as u,
714
714
  De as w
715
715
  };
716
- //# sourceMappingURL=template-fields-BXl29sgh.js.map
716
+ //# sourceMappingURL=template-fields-BLRp84Ny.js.map