@snowcone-app/canvas 0.19.1 → 0.21.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 (86) hide show
  1. package/README.md +124 -13
  2. package/STYLING_CONTRACT.md +427 -0
  3. package/dist/{CanvasRenderer-DUc-MOeR.js → CanvasRenderer-CwiYq8qg.js} +3 -3
  4. package/dist/{CanvasRenderer-DUc-MOeR.js.map → CanvasRenderer-CwiYq8qg.js.map} +1 -1
  5. package/dist/{CanvasStateV1-Bq48qhv5.js → CanvasStateV1-BFabcAKC.js} +35 -30
  6. package/dist/{CanvasStateV1-Bq48qhv5.js.map → CanvasStateV1-BFabcAKC.js.map} +1 -1
  7. package/dist/{ContextualToolbars-CkLjHNPn.js → ContextualToolbars--vTtorNg.js} +5 -5
  8. package/dist/{ContextualToolbars-CkLjHNPn.js.map → ContextualToolbars--vTtorNg.js.map} +1 -1
  9. package/dist/{EditorCanvasImpl-_3xCnLkx.js → EditorCanvasImpl-2ZgIUVpK.js} +18 -17
  10. package/dist/{EditorCanvasImpl-_3xCnLkx.js.map → EditorCanvasImpl-2ZgIUVpK.js.map} +1 -1
  11. package/dist/{ImportManager-D--7JnvW.js → ExportManager-DK7CdI-G.js} +24758 -24758
  12. package/dist/ExportManager-DK7CdI-G.js.map +1 -0
  13. package/dist/{FontAnalyzer-DIlqmyuf.js → FontAnalyzer-BpsTYowD.js} +5 -2
  14. package/dist/FontAnalyzer-BpsTYowD.js.map +1 -0
  15. package/dist/SnowconeCanvas-DqZicdxK.js +1172 -0
  16. package/dist/SnowconeCanvas-DqZicdxK.js.map +1 -0
  17. package/dist/{MenuButton-CeoEAtzP.js → UnifiedFontService-B1PGVu8O.js} +3704 -3429
  18. package/dist/UnifiedFontService-B1PGVu8O.js.map +1 -0
  19. package/dist/advanced.mjs +13 -13
  20. package/dist/api/embed.d.ts +3 -1
  21. package/dist/api/stable.d.ts +2 -2
  22. package/dist/components/editor/EditorAdd.d.ts +2 -1
  23. package/dist/components/editor/EditorBuy.d.ts +2 -1
  24. package/dist/components/editor/EditorCanvas.d.ts +2 -1
  25. package/dist/components/editor/EditorControls.d.ts +2 -1
  26. package/dist/components/editor/EditorHistory.d.ts +2 -1
  27. package/dist/components/editor/EditorLayers.d.ts +2 -1
  28. package/dist/components/editor/EditorMenu.d.ts +2 -1
  29. package/dist/components/editor/EditorPreview.d.ts +2 -1
  30. package/dist/components/editor/EditorRoot.d.ts +2 -1
  31. package/dist/components/editor/EditorTextField.d.ts +2 -1
  32. package/dist/components/editor/useProductSelection.d.ts +2 -1
  33. package/dist/components/embed/SnowconeCanvas.d.ts +10 -2
  34. package/dist/components/embed-realtime/context.d.ts +1 -1
  35. package/dist/contexts/EditorContext.d.ts +1 -1
  36. package/dist/core/ArtboardElement.d.ts +2 -1
  37. package/dist/default-editor/SnowconeEditor.d.ts +40 -0
  38. package/dist/design/design-builder.d.ts +46 -21
  39. package/dist/design/template-fields.d.ts +32 -0
  40. package/dist/design-builder-CPF60RU2.js +367 -0
  41. package/dist/design-builder-CPF60RU2.js.map +1 -0
  42. package/dist/{EditorContext-5QpqAhjh.js → editorErrors-CK1RISFa.js} +382 -358
  43. package/dist/editorErrors-CK1RISFa.js.map +1 -0
  44. package/dist/embed-2tp6Ue90.js +1117 -0
  45. package/dist/embed-2tp6Ue90.js.map +1 -0
  46. package/dist/embed.mjs +33 -31
  47. package/dist/hooks/useArtboards.d.ts +2 -1
  48. package/dist/index.mjs +8 -8
  49. package/dist/internals.mjs +5 -5
  50. package/dist/kits/sections.d.ts +11 -7
  51. package/dist/rendering/serialize-for-server.d.ts +3 -0
  52. package/dist/state/CanvasStateV1.d.ts +12 -0
  53. package/dist/template-fields-FgImixyv.js +476 -0
  54. package/dist/template-fields-FgImixyv.js.map +1 -0
  55. package/dist/testing/assertRenders.d.ts +2 -1
  56. package/dist/testing.mjs +8 -8
  57. package/dist/testing.mjs.map +1 -1
  58. package/dist/types/index.d.ts +10 -0
  59. package/dist/{usePieceGuideBundle-DVOISsB1.js → usePieceGuideBundle-Ctnu5k2D.js} +2 -2
  60. package/dist/{usePieceGuideBundle-DVOISsB1.js.map → usePieceGuideBundle-Ctnu5k2D.js.map} +1 -1
  61. package/dist/{validation-0IscSfRb.js → validation-3YEMnKLB.js} +467 -463
  62. package/dist/validation-3YEMnKLB.js.map +1 -0
  63. package/example/README.md +179 -0
  64. package/example/index.html +12 -0
  65. package/example/package.json +24 -0
  66. package/example/src/Widget.tsx +62 -0
  67. package/example/src/main.tsx +9 -0
  68. package/example/tsconfig.json +14 -0
  69. package/example/vite.config.ts +11 -0
  70. package/llms.txt +45 -0
  71. package/package.json +11 -6
  72. package/dist/EditorContext-5QpqAhjh.js.map +0 -1
  73. package/dist/FontAnalyzer-DIlqmyuf.js.map +0 -1
  74. package/dist/ImportManager-D--7JnvW.js.map +0 -1
  75. package/dist/MenuButton-CeoEAtzP.js.map +0 -1
  76. package/dist/SnowconeCanvas-3PA17na3.js +0 -1166
  77. package/dist/SnowconeCanvas-3PA17na3.js.map +0 -1
  78. package/dist/design-builder-v4935TeS.js +0 -343
  79. package/dist/design-builder-v4935TeS.js.map +0 -1
  80. package/dist/editorErrors-DXNfVXtD.js +0 -29
  81. package/dist/editorErrors-DXNfVXtD.js.map +0 -1
  82. package/dist/embed-D2QOpJXG.js +0 -1090
  83. package/dist/embed-D2QOpJXG.js.map +0 -1
  84. package/dist/template-fields-Dr3fMItw.js +0 -329
  85. package/dist/template-fields-Dr3fMItw.js.map +0 -1
  86. package/dist/validation-0IscSfRb.js.map +0 -1
package/dist/advanced.mjs CHANGED
@@ -1,20 +1,20 @@
1
- import { D as te, T as M, h as D, B as re, I as q, i as I, j as ne, e as se } from "./MenuButton-CeoEAtzP.js";
2
- import { k as at, L as it, M as ct, l as lt, S as dt, m as ut, s as mt, n as ft } from "./MenuButton-CeoEAtzP.js";
3
- import { r as oe, v as ae } from "./validation-0IscSfRb.js";
4
- import { a as pt, b as xt, c as gt, d as bt, D as yt, e as vt, f as wt, G as St, I as Ct, K as Tt, g as Et, L as $t, S as kt, T as At, Z as Ft, h as Pt, i as Nt, j as Rt, k as Bt, l as Mt, m as Dt, n as It, u as zt, o as Ot, p as Lt } from "./validation-0IscSfRb.js";
5
- import { P as ie, a as ce, b as le } from "./ContextualToolbars-CkLjHNPn.js";
6
- import { A as Kt, B as Gt, c as _t, C as Ut, d as jt, e as Jt, F as qt, f as Zt, I as Vt, g as Xt, M as Yt, h as Ht, S as Qt, T as er, i as tr, j as rr, k as nr, U as sr, l as or, u as ar, m as ir } from "./ContextualToolbars-CkLjHNPn.js";
7
- import { u as Z } from "./EditorContext-5QpqAhjh.js";
8
- import { E as lr, P as dr, p as ur, s as mr, b as fr, c as hr, d as pr, e as xr, f as gr, a as br } from "./EditorContext-5QpqAhjh.js";
1
+ import { D as te, T as M, h as D, B as re, I as q, i as I, j as ne, e as se } from "./UnifiedFontService-B1PGVu8O.js";
2
+ import { k as at, L as it, M as ct, l as lt, S as dt, m as ut, s as mt, n as ft } from "./UnifiedFontService-B1PGVu8O.js";
3
+ import { r as oe, v as ae } from "./validation-3YEMnKLB.js";
4
+ import { a as pt, b as xt, c as gt, d as bt, D as yt, e as vt, f as wt, G as St, I as Ct, K as Tt, g as Et, L as $t, S as kt, T as At, Z as Ft, h as Pt, i as Nt, j as Rt, k as Bt, l as Mt, m as Dt, n as It, u as zt, o as Ot, p as Lt } from "./validation-3YEMnKLB.js";
5
+ import { P as ie, a as ce, b as le } from "./ContextualToolbars--vTtorNg.js";
6
+ import { A as Kt, B as Gt, c as _t, C as Ut, d as jt, e as Jt, F as qt, f as Zt, I as Vt, g as Xt, M as Yt, h as Ht, S as Qt, T as er, i as tr, j as rr, k as nr, U as sr, l as or, u as ar, m as ir } from "./ContextualToolbars--vTtorNg.js";
7
+ import { u as Z } from "./editorErrors-CK1RISFa.js";
8
+ import { E as lr, P as dr, p as ur, s as mr, b as fr, c as hr, d as pr, e as xr, f as gr, a as br } from "./editorErrors-CK1RISFa.js";
9
9
  import { T as vr, u as wr } from "./ThemeContext-Rjz25x9X.js";
10
- import { c as de, G as ue, F as me, g as fe, r as he, u as pe } from "./FontAnalyzer-DIlqmyuf.js";
11
- import { A as Cr, B as Tr, I as Er, P as $r, R as kr, S as Ar, T as Fr, h as Pr, a as Nr, b as Rr, i as Br, d as Mr, e as Dr, f as Ir, j as zr, k as Or, l as Lr, m as Wr, n as Kr, o as Gr, p as _r, q as Ur, s as jr, t as Jr, v as qr, w as Zr, x as Vr } from "./FontAnalyzer-DIlqmyuf.js";
12
- import { i as Yr, a as Hr, b as Qr, c as en, d as tn } from "./CanvasRenderer-DUc-MOeR.js";
10
+ import { c as de, G as ue, F as me, g as fe, r as he, u as pe } from "./FontAnalyzer-BpsTYowD.js";
11
+ import { A as Cr, B as Tr, I as Er, P as $r, R as kr, S as Ar, T as Fr, h as Pr, a as Nr, b as Rr, i as Br, d as Mr, e as Dr, f as Ir, j as zr, k as Or, l as Lr, m as Wr, n as Kr, o as Gr, p as _r, q as Ur, s as jr, t as Jr, v as qr, w as Zr, x as Vr } from "./FontAnalyzer-BpsTYowD.js";
12
+ import { i as Yr, a as Hr, b as Qr, c as en, d as tn } from "./CanvasRenderer-CwiYq8qg.js";
13
13
  import { useState as A, useCallback as y, useEffect as V, useMemo as X, useRef as B, memo as xe } from "react";
14
- import { I as ge } from "./ImportManager-D--7JnvW.js";
14
+ import { I as ge } from "./ExportManager-DK7CdI-G.js";
15
15
  import { e as be, c as ye } from "./compose-DtQL_oit.js";
16
16
  import { jsxs as b, jsx as a, Fragment as ve } from "react/jsx-runtime";
17
- import { P as nn, p as sn, u as on } from "./usePieceGuideBundle-DVOISsB1.js";
17
+ import { P as nn, p as sn, u as on } from "./usePieceGuideBundle-Ctnu5k2D.js";
18
18
  const ze = ({
19
19
  title: e,
20
20
  icon: t,
@@ -50,7 +50,7 @@ export type { UseRealtimeMockupsResult } from '../components/embed-realtime/useR
50
50
  export { validateEmbed, collectEmbedIssues } from '../components/embed-realtime/validateEmbed.js';
51
51
  export type { ValidateEmbedInput, EmbedIssue } from '../components/embed-realtime/validateEmbed.js';
52
52
  export { design, DesignBuilder, isLayerToken } from '../design/design-builder.js';
53
- export type { Anchor, ShapeKind, DesignArtboard, AnyDesign, LayerKind, LayerToken, } from '../design/design-builder.js';
53
+ export type { Anchor, ShapeKind, DesignArtboard, StateArtboard, FromStateOptions, AnyDesign, LayerKind, LayerToken, } from '../design/design-builder.js';
54
54
  export { useEditor } from '../contexts/EditorContext.js';
55
55
  export type { EditorContextValue, EditorProviderProps } from '../contexts/EditorContext.js';
56
56
  export { useLayers } from '../hooks/useLayers.js';
@@ -78,3 +78,5 @@ export type { CanvasServices, ResolvedCanvasServices } from '../contexts/CanvasS
78
78
  export { createProxyImageSearch, createProxyGenerate } from '../services/imageSearch.js';
79
79
  export type { ImageSearchProvider, ImageSearchResult, ImageSearchResponse, ImageSearchParams, GenerateProvider, GenerateParams, GenerateResponse, } from '../services/imageSearch.js';
80
80
  export type { RenderProduct, RenderProductOptions, RenderProductCombination, RenderProductRequiredPlacement, MockupResult, RealtimeGrant, } from '@snowcone-app/sdk';
81
+ export { SnowconeEditor, formatBuyPrice } from '../default-editor/SnowconeEditor.js';
82
+ export type { SnowconeEditorProps } from '../default-editor/SnowconeEditor.js';
@@ -44,14 +44,14 @@ export { COMPACT_CUSTOMIZER, PRO_STUDIO, EMBED_ONLY } from '../kits/presets.js';
44
44
  export type { KitDefinition, KitPresetId, RuntimeTheme, KitValidationResult } from '../kits/index.js';
45
45
  export { ALL_CAPABILITIES, MINIMAL_CAPABILITIES } from '../types/capabilities.js';
46
46
  export type { EditorCapabilities, ElementType, EffectType, PanelType, ToolType } from '../types/capabilities.js';
47
- export type { ArtboardConfig as ArtboardElementConfig, TransformType, AnyElementConfig, TextAlign, BlendMode, BoundingBox, Point, CanvasError, CanvasErrorCategory, } from '../types/index.js';
47
+ export type { ArtboardConfig as ArtboardElementConfig, ArtboardRole, TransformType, AnyElementConfig, TextAlign, BlendMode, BoundingBox, Point, CanvasError, CanvasErrorCategory, } from '../types/index.js';
48
48
  export { ErrorBoundary } from '../components/embed/ErrorBoundary.js';
49
49
  export type { ErrorBoundaryProps } from '../components/embed/ErrorBoundary.js';
50
50
  export { serializeState, deserializeState, validateState, migrateState, } from '../state/index.js';
51
51
  export { serializeStateForServer, CANVAS_STATE_SCHEMA_VERSION, } from '../rendering/serialize-for-server.js';
52
52
  export type { ServerRenderRequest } from '../rendering/serialize-for-server.js';
53
53
  export { design, DesignBuilder } from '../design/design-builder.js';
54
- export type { Anchor, ShapeKind, DesignArtboard, BackgroundOptions, ImageOptions, TextOptions, ShapeOptions, } from '../design/design-builder.js';
54
+ export type { Anchor, ShapeKind, DesignArtboard, StateArtboard, FromStateOptions, BackgroundOptions, ImageOptions, TextOptions, ShapeOptions, } from '../design/design-builder.js';
55
55
  export { readTemplateFields, withTemplateFields, TEMPLATE_FIELDS_KEY, } from '../design/template-fields.js';
56
56
  export type { TemplateField, TemplateTextField, TemplateImageField, TemplateColorField, TemplateSelectField, } from '../design/template-fields.js';
57
57
  export type { CanvasStateV1, SerializedArtboard, SerializedElement, DeserializeResult, ValidationResult, } from '../state/index.js';
@@ -6,6 +6,7 @@ export interface EditorAddProps {
6
6
  /**
7
7
  * The ⊕ add-element menu.
8
8
  *
9
- * @experimental ADR-0085; subject to change until the P4 gate.
9
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
10
+ * surface, CI-gated); additive-only from here.
10
11
  */
11
12
  export declare function EditorAdd({ className, style }: EditorAddProps): React.ReactElement;
@@ -55,6 +55,7 @@ export declare function evaluateBuyCompleteness(input: {
55
55
  /**
56
56
  * The add-to-cart button, completeness-gated and payload-assembling.
57
57
  *
58
- * @experimental ADR-0085; subject to change until the P4 gate.
58
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
59
+ * surface, CI-gated); additive-only from here.
59
60
  */
60
61
  export declare function EditorBuy(props: EditorBuyProps): React.ReactElement;
@@ -24,7 +24,8 @@ export interface EditorCanvasProps {
24
24
  * (`E_DUPLICATE_CANVAS`); mount none for the no-canvas personalization
25
25
  * composition.
26
26
  *
27
- * @experimental ADR-0085; subject to change until the P4 gate.
27
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
28
+ * surface, CI-gated); additive-only from here.
28
29
  */
29
30
  export declare const EditorCanvas: React.ForwardRefExoticComponent<EditorCanvasProps & React.RefAttributes<SnowconeCanvasHandle>>;
30
31
  export type { EditorCanvasImplProps };
@@ -9,6 +9,7 @@ export interface EditorControlsProps {
9
9
  /**
10
10
  * The contextual controls zone.
11
11
  *
12
- * @experimental ADR-0085; subject to change until the P4 gate.
12
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
13
+ * surface, CI-gated); additive-only from here.
13
14
  */
14
15
  export declare function EditorControls({ placement, className, style, }: EditorControlsProps): React.ReactElement | null;
@@ -6,6 +6,7 @@ export interface EditorHistoryProps {
6
6
  /**
7
7
  * Undo/redo for the editor document.
8
8
  *
9
- * @experimental ADR-0085; subject to change until the P4 gate.
9
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
10
+ * surface, CI-gated); additive-only from here.
10
11
  */
11
12
  export declare function EditorHistory({ className, style }: EditorHistoryProps): React.ReactElement;
@@ -11,6 +11,7 @@ export interface EditorLayersProps {
11
11
  * layers read-only); with a mounted `Editor.Canvas` it is the live document
12
12
  * panel.
13
13
  *
14
- * @experimental ADR-0085; subject to change until the P4 gate.
14
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
15
+ * surface, CI-gated); additive-only from here.
15
16
  */
16
17
  export declare function EditorLayers({ direction, className, style, }: EditorLayersProps): React.ReactElement;
@@ -6,6 +6,7 @@ export interface EditorMenuProps {
6
6
  /**
7
7
  * The editor's overflow menu.
8
8
  *
9
- * @experimental ADR-0085; subject to change until the P4 gate.
9
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
10
+ * surface, CI-gated); additive-only from here.
10
11
  */
11
12
  export declare function EditorMenu({ className, style }: EditorMenuProps): React.ReactElement;
@@ -34,6 +34,7 @@ export declare function resolutionMismatchHint(naturalWidth: number, devicePx: n
34
34
  /**
35
35
  * The live product mockup. Mount as many as you need under one Root.
36
36
  *
37
- * @experimental ADR-0085; subject to change until the P4 gate.
37
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
38
+ * surface, CI-gated); additive-only from here.
38
39
  */
39
40
  export declare function EditorPreview({ mockupId, fallback, alt, className, style, }: EditorPreviewProps): React.ReactElement;
@@ -81,6 +81,7 @@ export declare function slowRenderHint(placement: string): string;
81
81
  * model; see `RealtimeEmbed` for the legacy turnkey wrapper this was
82
82
  * extracted from.
83
83
  *
84
- * @experimental ADR-0085; subject to change until the P4 gate.
84
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
85
+ * surface, CI-gated); additive-only from here.
85
86
  */
86
87
  export declare function EditorRoot(props: EditorRootProps): React.ReactElement;
@@ -17,6 +17,7 @@ export interface EditorTextFieldProps {
17
17
  * A text input bound to a design layer. Works with or without a mounted
18
18
  * `Editor.Canvas`.
19
19
  *
20
- * @experimental ADR-0085; subject to change until the P4 gate.
20
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
21
+ * surface, CI-gated); additive-only from here.
21
22
  */
22
23
  export declare function EditorTextField(props: EditorTextFieldProps): React.ReactElement;
@@ -34,6 +34,7 @@ export interface ProductSelectionApi {
34
34
  /**
35
35
  * Read/write the Buy-owned product selection under this `Editor.Root`.
36
36
  *
37
- * @experimental ADR-0085; subject to change until the P4 gate.
37
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
38
+ * surface, CI-gated); additive-only from here.
38
39
  */
39
40
  export declare function useProductSelection(): ProductSelectionApi;
@@ -1,9 +1,9 @@
1
1
  import { default as React } from 'react';
2
2
  import { CanvasServices } from '../../contexts/CanvasServicesContext.js';
3
- import { CanvasError, ClipShape, AnyElementConfig } from '../../types/index.js';
3
+ import { CanvasError, ArtboardRole, ClipShape, AnyElementConfig } from '../../types/index.js';
4
4
  import { KitPresetId, KitDefinition } from '../../kits/types.js';
5
5
  import { PieceGuide, PieceGuideRendererPiece, PieceGuideRendererStyle, PieceGuideVisibility } from '../../rendering/PieceGuideRenderer.js';
6
- export type { ClipShape } from '../../types/index.js';
6
+ export type { ClipShape, ArtboardRole } from '../../types/index.js';
7
7
  /** 9-point alignment grid values */
8
8
  export type AlignmentPoint = 'tl' | 't' | 'tr' | 'l' | 'c' | 'r' | 'bl' | 'b' | 'br' | 'center' | 'top' | 'bottom' | 'left' | 'right';
9
9
  /** Events emitted during the export lifecycle */
@@ -41,6 +41,14 @@ export interface ArtboardConfig {
41
41
  * match the editor.
42
42
  */
43
43
  exportBackground?: boolean;
44
+ /**
45
+ * Pacing role in a multi-page template (ADR-0086 albums):
46
+ * `'cover' | 'front-matter' | 'repeating' | 'back-matter'`. Template
47
+ * metadata only — auto-fill clones `repeating` spreads as the page count
48
+ * grows. Round-trips through saved states and `onChange`; never sent on
49
+ * the server render wire (`serializeStateForServer` strips it).
50
+ */
51
+ role?: ArtboardRole;
44
52
  /** Scale mode for initial image: "cover" fills area (may crop), "contain" fits inside (may have space). Default: "cover" */
45
53
  scaleMode?: 'cover' | 'contain';
46
54
  /** Top margin in pixels for contain mode (reduces available area) */
@@ -39,7 +39,7 @@ export interface EmbedContextValue {
39
39
  * write, last-write-wins. Commerce parts read THIS, never the seed. Stable
40
40
  * identity; subscribe for updates (`useSyncExternalStore`-shaped).
41
41
  *
42
- * @experimental ADR-0085; subject to change until the P4 gate.
42
+ * Stable since ADR-0085 P4; additive-only from here.
43
43
  */
44
44
  stateStore: DesignStateStore;
45
45
  }
@@ -191,7 +191,7 @@ export declare const EditorProvider: React.FC<EditorProviderProps>;
191
191
  * - **Undo/redo**: `undo`, `redo`, `canUndo`, `canRedo`
192
192
  *
193
193
  * Everything else on the returned value is `@experimental` and may change in
194
- * minors until the P4 gate (the default editor rebuilt from public parts).
194
+ * minors — the stable subset above is the documented headless contract.
195
195
  *
196
196
  * Must be called inside an `EditorProvider`. For focused access, prefer the
197
197
  * sub-context hooks which expose smaller slices of state and cause fewer re-renders:
@@ -1,7 +1,7 @@
1
1
  import { TextElement } from './TextElement.js';
2
2
  import { ImageElement } from './ImageElement.js';
3
3
  import { GroupElement } from './GroupElement.js';
4
- import { BoundingBox, Point, ArtboardConfig, ArtboardBackgroundType, ArtboardDistressTexture, ArtboardImageMask, ClipShape } from '../types/index.js';
4
+ import { BoundingBox, Point, ArtboardConfig, ArtboardBackgroundType, ArtboardDistressTexture, ArtboardImageMask, ArtboardRole, ClipShape } from '../types/index.js';
5
5
  export declare class ArtboardElement {
6
6
  id: string;
7
7
  name: string;
@@ -16,6 +16,7 @@ export declare class ArtboardElement {
16
16
  transformType: 'artboard';
17
17
  clipShape?: ClipShape;
18
18
  previewBackgroundColor?: string;
19
+ role?: ArtboardRole;
19
20
  distressTexture?: ArtboardDistressTexture;
20
21
  imageMask?: ArtboardImageMask;
21
22
  private elementIds;
@@ -0,0 +1,40 @@
1
+ import { default as React, CSSProperties } from 'react';
2
+ import { EditorRootBaseProps, EditorBuyPayload, GrantSource } from '../api/embed.js';
3
+ export type SnowconeEditorProps = GrantSource & Omit<EditorRootBaseProps, 'children' | '__validation'> & {
4
+ /** The final submit — your one line. Variant/quantity/completeness and
5
+ * payload assembly are `Editor.Buy`'s job. */
6
+ onAddToCart: (payload: EditorBuyPayload) => void | Promise<void>;
7
+ /** Seeds the Buy-owned quantity once on mount (default 1). */
8
+ defaultQuantity?: number;
9
+ /** Header title. Default "Editor". */
10
+ title?: string;
11
+ /** Embedded-card height (px or CSS length). Fullscreen ignores it. */
12
+ height?: number | string;
13
+ className?: string;
14
+ style?: CSSProperties;
15
+ };
16
+ /** Price label for the Buy pill — catalog prices are cents. Whole dollars
17
+ * render without cents ("$24"), like the PDP. */
18
+ export declare function formatBuyPrice(cents: number): string;
19
+ /**
20
+ * The turnkey Snowcone editor — the same public parts, our arrangement.
21
+ *
22
+ * ```tsx
23
+ * import { SnowconeEditor, design } from '@snowcone-app/canvas/embed';
24
+ *
25
+ * <SnowconeEditor
26
+ * shop={SHOP_KEY}
27
+ * product={{ productId: 'BEEB77', mockupIds: ['FV1qjO'], variantId: 'Pv1sLC', placements: ['Front'] }}
28
+ * design={design({ name: 'Front', width: 1480, height: 2328 }).text('hello', { name: 'headline' })}
29
+ * grantUrl="/api/realtime/grant"
30
+ * onAddToCart={(payload) => persist(payload.designState)}
31
+ * />
32
+ * ```
33
+ *
34
+ * Customizing beyond the props means composing `Editor.*` yourself — this
35
+ * component is ~300 lines of public-surface composition you can copy and own.
36
+ *
37
+ * Stable since ADR-0085 P4 (this component IS the gate artifact — composed
38
+ * only from the public embed entry); additive-only from here.
39
+ */
40
+ export declare function SnowconeEditor(props: SnowconeEditorProps): React.ReactElement;
@@ -1,4 +1,4 @@
1
- import { AnyElementConfig } from '../types/index.js';
1
+ import { AnyElementConfig, ArtboardRole } from '../types/index.js';
2
2
  import { ServerRenderRequest } from '../rendering/serialize-for-server.js';
3
3
  /** A nine-point anchor: where the element sits relative to the artboard. */
4
4
  export type Anchor = 'top-left' | 'top' | 'top-right' | 'left' | 'center' | 'right' | 'bottom-left' | 'bottom' | 'bottom-right';
@@ -14,6 +14,32 @@ export interface DesignArtboard {
14
14
  /** Optional solid background fill behind all elements. Rendered everywhere
15
15
  * the design is — editor, exports, and server renders (realtime mockups). */
16
16
  backgroundColor?: string;
17
+ /** Pacing role in a multi-page template (ADR-0086 albums). Template
18
+ * metadata only — never sent on the server render wire. */
19
+ role?: ArtboardRole;
20
+ }
21
+ /** One artboard of a saved multi-artboard state, as {@link DesignBuilder.fromState}
22
+ * accepts and `toJSON()` emits. */
23
+ export interface StateArtboard {
24
+ name: string;
25
+ width: number;
26
+ height: number;
27
+ backgroundColor?: string;
28
+ exportBackground?: boolean;
29
+ /** Pacing role in a multi-page template (ADR-0086 albums). */
30
+ role?: ArtboardRole;
31
+ }
32
+ export interface FromStateOptions {
33
+ /**
34
+ * Which artboards to load:
35
+ * - `'active'` (default) — today's behavior: the active artboard becomes the
36
+ * builder's artboard; elements tagged for other artboards are skipped.
37
+ * - `'all'` — multi-page templates (ADR-0086): every artboard and its
38
+ * elements are kept, with `artboard` membership tags preserved, so
39
+ * `toJSON()` / `toServerRequest()` stay multi-artboard. Template fields
40
+ * scope per page via `TemplateField.artboard`.
41
+ */
42
+ artboards?: 'active' | 'all';
17
43
  }
18
44
  /** A stable layer name. Set it so you can bind the layer in an interactive
19
45
  * `<SnowconeCanvas/>` editor — `useImageBinding(name)` / `useTextBinding(name)`
@@ -85,7 +111,8 @@ declare const LAYER_TOKEN_BRAND: unique symbol;
85
111
  * accepts — bare strings are rejected (`E_LAYER_TOKEN_REQUIRED`). Mint with
86
112
  * {@link DesignBuilder.layer}; not constructible by hand (branded).
87
113
  *
88
- * @experimental ADR-0085; subject to change until the P4 gate.
114
+ * Stable since ADR-0085 P4 (the default editor is rebuilt from this public
115
+ * surface, CI-gated); additive-only from here.
89
116
  */
90
117
  export interface LayerToken<K extends LayerKind = LayerKind, N extends string = string> {
91
118
  readonly kind: K;
@@ -118,6 +145,9 @@ export declare class DesignBuilder<out TText extends string = string, out TImage
118
145
  private readonly artboard;
119
146
  private readonly els;
120
147
  private idCounter;
148
+ /** Every artboard of a multi-page state (fromState `{ artboards: 'all' }`);
149
+ * unset for single-artboard builders. */
150
+ private allArtboards?;
121
151
  constructor(artboard: DesignArtboard);
122
152
  /**
123
153
  * Seed a builder from a previously saved canvas state — the editor shape
@@ -125,20 +155,20 @@ export declare class DesignBuilder<out TText extends string = string, out TImage
125
155
  *
126
156
  * This is how a saved editable template re-enters the turnkey embed path:
127
157
  * load the template's state JSON, lift it back into a `DesignBuilder`, and
128
- * hand it to `<RealtimeEmbed design={…}>`. The active artboard becomes the
129
- * builder's artboard; elements tagged for other artboards are skipped
130
- * (untagged elements are assumed to belong to the active one).
158
+ * hand it to `<RealtimeEmbed design={…}>`. By default the active artboard
159
+ * becomes the builder's artboard; elements tagged for other artboards are
160
+ * skipped (untagged elements are assumed to belong to the active one).
161
+ *
162
+ * Pass `{ artboards: 'all' }` to load a multi-page template (ADR-0086)
163
+ * whole: every artboard (with its pacing `role`) and every element are
164
+ * kept, membership tags preserved, so `toJSON()` / `toServerRequest()`
165
+ * emit all pages and `TemplateField.artboard` can scope fields per page.
131
166
  */
132
167
  static fromState(state: {
133
168
  elements: AnyElementConfig[];
134
- artboards: Array<{
135
- name: string;
136
- width: number;
137
- height: number;
138
- backgroundColor?: string;
139
- }>;
169
+ artboards: StateArtboard[];
140
170
  activeArtboard: string;
141
- }): DesignBuilder;
171
+ }, options?: FromStateOptions): DesignBuilder;
142
172
  private nextId;
143
173
  /** Full-bleed background image (fills the whole artboard). Cover-fit (no
144
174
  * distortion) when `aspectRatio` is supplied. Inserted at the bottom of the
@@ -172,7 +202,6 @@ export declare class DesignBuilder<out TText extends string = string, out TImage
172
202
  * the valid names per kind.
173
203
  * @throws EditorError `E_LAYER_WRONG_KIND` — the name matches a layer that
174
204
  * is not bindable (shape/group/path).
175
- * @experimental ADR-0085; subject to change until the P4 gate.
176
205
  */
177
206
  layer<N extends TText | TImage>(name: N): LayerToken<InferKind<N, TText, TImage>, N>;
178
207
  /** Names of bindable layers of one kind, in stack order. @internal */
@@ -182,16 +211,12 @@ export declare class DesignBuilder<out TText extends string = string, out TImage
182
211
  /** The composed elements, in render order (background first). Editor shape. */
183
212
  get elements(): AnyElementConfig[];
184
213
  /** Editor-shape canvas state for `<SnowconeCanvas initialElements=… />` and
185
- * `serializeStateForServer`. `activeArtboard` is the artboard name. */
214
+ * `serializeStateForServer`. `activeArtboard` is the artboard name. A
215
+ * builder loaded with `fromState(…, { artboards: 'all' })` emits every
216
+ * page (artboard `role`s and element membership tags included). */
186
217
  toJSON(): {
187
218
  elements: AnyElementConfig[];
188
- artboards: Array<{
189
- name: string;
190
- width: number;
191
- height: number;
192
- backgroundColor?: string;
193
- exportBackground?: boolean;
194
- }>;
219
+ artboards: StateArtboard[];
195
220
  activeArtboard: string;
196
221
  };
197
222
  /** Server-render payload for `RenderSession.renderState(placement, …)`.
@@ -14,6 +14,14 @@ export interface TemplateTextField {
14
14
  * `maxLength`); the canvas itself doesn't truncate.
15
15
  */
16
16
  maxLength?: number;
17
+ /**
18
+ * Artboard (page) this field is scoped to, by artboard NAME — the same
19
+ * convention as the element `artboard` membership tag. In a multi-page
20
+ * template (ADR-0086) the same element name can repeat on every page;
21
+ * scoping disambiguates which page's element the field binds. Absent =
22
+ * whole-design (legacy behavior: binds across all artboards).
23
+ */
24
+ artboard?: string;
17
25
  /** Optional grouping label — consecutive fields sharing a group render together. */
18
26
  group?: string;
19
27
  }
@@ -28,6 +36,14 @@ export interface TemplateImageField {
28
36
  placeholder?: string;
29
37
  /** How the buyer's image fits the original element bounds. Default: "cover". */
30
38
  fit?: ImageFitMode;
39
+ /**
40
+ * Artboard (page) this field is scoped to, by artboard NAME — the same
41
+ * convention as the element `artboard` membership tag. In a multi-page
42
+ * template (ADR-0086) the same element name can repeat on every page;
43
+ * scoping disambiguates which page's element the field binds. Absent =
44
+ * whole-design (legacy behavior: binds across all artboards).
45
+ */
46
+ artboard?: string;
31
47
  /** Optional grouping label — consecutive fields sharing a group render together. */
32
48
  group?: string;
33
49
  }
@@ -38,6 +54,14 @@ export interface TemplateColorField {
38
54
  color: string;
39
55
  /** Label shown to the buyer (e.g. "Accent color"). */
40
56
  label: string;
57
+ /**
58
+ * Artboard (page) this field is scoped to, by artboard NAME — the same
59
+ * convention as the element `artboard` membership tag. In a multi-page
60
+ * template (ADR-0086) the same element name can repeat on every page;
61
+ * scoping disambiguates which page's element the field binds. Absent =
62
+ * whole-design (legacy behavior: binds across all artboards).
63
+ */
64
+ artboard?: string;
41
65
  /** Optional grouping label — consecutive fields sharing a group render together. */
42
66
  group?: string;
43
67
  }
@@ -64,6 +88,14 @@ export interface TemplateSelectField {
64
88
  label: string;
65
89
  value: string;
66
90
  }>;
91
+ /**
92
+ * Artboard (page) this field is scoped to, by artboard NAME — the same
93
+ * convention as the element `artboard` membership tag. In a multi-page
94
+ * template (ADR-0086) the same element name can repeat on every page;
95
+ * scoping disambiguates which page's element the field binds. Absent =
96
+ * whole-design (legacy behavior: binds across all artboards).
97
+ */
98
+ artboard?: string;
67
99
  /** Optional grouping label — consecutive fields sharing a group render together. */
68
100
  group?: string;
69
101
  }