@snowcone-app/canvas 0.13.1 → 0.15.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 (53) hide show
  1. package/dist/CanvasStateV1-BQD8fCBU.js +3699 -0
  2. package/dist/CanvasStateV1-BQD8fCBU.js.map +1 -0
  3. package/dist/advanced.mjs +323 -327
  4. package/dist/advanced.mjs.map +1 -1
  5. package/dist/api/embed.d.ts +14 -0
  6. package/dist/components/VisualGuideOverlay.d.ts +1 -1
  7. package/dist/components/embed-realtime/RealtimeCanvas.d.ts +24 -1
  8. package/dist/components/ui/index.d.ts +34 -34
  9. package/dist/embed.mjs +171 -156
  10. package/dist/embed.mjs.map +1 -1
  11. package/dist/index.mjs +47 -51
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/internals.mjs +1 -1
  14. package/dist/style.css +1 -1
  15. package/dist/{template-fields-IgDV7PRY.js → template-fields-coO73lV3.js} +245 -240
  16. package/dist/template-fields-coO73lV3.js.map +1 -0
  17. package/dist/validation-BahKiJWj.js +22973 -0
  18. package/dist/validation-BahKiJWj.js.map +1 -0
  19. package/dist/vendor/ui/index.d.ts +35 -0
  20. package/dist/vendor/ui/lib/utils.d.ts +2 -0
  21. package/dist/vendor/ui/primitives/Button.d.ts +14 -0
  22. package/dist/vendor/ui/primitives/accordion.d.ts +37 -0
  23. package/dist/vendor/ui/primitives/badge.d.ts +20 -0
  24. package/dist/vendor/ui/primitives/card.d.ts +12 -0
  25. package/dist/vendor/ui/primitives/checkbox.d.ts +8 -0
  26. package/dist/vendor/ui/primitives/collapsible.d.ts +10 -0
  27. package/dist/vendor/ui/primitives/drawer.d.ts +66 -0
  28. package/dist/vendor/ui/primitives/dropdown-menu.d.ts +27 -0
  29. package/dist/vendor/ui/primitives/fieldset.d.ts +35 -0
  30. package/dist/vendor/ui/primitives/input.d.ts +18 -0
  31. package/dist/vendor/ui/primitives/kbd.d.ts +37 -0
  32. package/dist/vendor/ui/primitives/label.d.ts +5 -0
  33. package/dist/vendor/ui/primitives/link.d.ts +52 -0
  34. package/dist/vendor/ui/primitives/popover.d.ts +26 -0
  35. package/dist/vendor/ui/primitives/radio-group.d.ts +15 -0
  36. package/dist/vendor/ui/primitives/select.d.ts +17 -0
  37. package/dist/vendor/ui/primitives/separator.d.ts +4 -0
  38. package/dist/vendor/ui/primitives/slider.d.ts +26 -0
  39. package/dist/vendor/ui/primitives/spinner.d.ts +12 -0
  40. package/dist/vendor/ui/primitives/surface.d.ts +52 -0
  41. package/dist/vendor/ui/primitives/switch.d.ts +4 -0
  42. package/dist/vendor/ui/primitives/tabs.d.ts +28 -0
  43. package/dist/vendor/ui/primitives/text-field.d.ts +36 -0
  44. package/dist/vendor/ui/primitives/textarea.d.ts +10 -0
  45. package/dist/vendor/ui/primitives/tooltip.d.ts +19 -0
  46. package/package.json +7 -5
  47. package/dist/CanvasStateV1-CKsfggNP.js +0 -456
  48. package/dist/CanvasStateV1-CKsfggNP.js.map +0 -1
  49. package/dist/schemas-B4UXytQB.js +0 -3250
  50. package/dist/schemas-B4UXytQB.js.map +0 -1
  51. package/dist/template-fields-IgDV7PRY.js.map +0 -1
  52. package/dist/validation-BpmNOvuY.js +0 -21177
  53. package/dist/validation-BpmNOvuY.js.map +0 -1
@@ -38,6 +38,7 @@ export { RealtimeEmbed } from '../components/embed-realtime/RealtimeEmbed.js';
38
38
  export type { RealtimeEmbedProps, GrantSource } from '../components/embed-realtime/RealtimeEmbed.js';
39
39
  export { RealtimeCanvas } from '../components/embed-realtime/RealtimeCanvas.js';
40
40
  export type { RealtimeCanvasProps } from '../components/embed-realtime/RealtimeCanvas.js';
41
+ export type { SnowconeCanvasHandle, CanvasState } from '../components/embed/SnowconeCanvas.js';
41
42
  export { RealtimeMockup } from '../components/embed-realtime/RealtimeMockup.js';
42
43
  export type { RealtimeMockupProps } from '../components/embed-realtime/RealtimeMockup.js';
43
44
  export { useRealtimeMockups } from '../components/embed-realtime/useRealtimeMockups.js';
@@ -46,6 +47,19 @@ export { validateEmbed } from '../components/embed-realtime/validateEmbed.js';
46
47
  export type { ValidateEmbedInput } from '../components/embed-realtime/validateEmbed.js';
47
48
  export { design, DesignBuilder } from '../design/design-builder.js';
48
49
  export type { Anchor, ShapeKind, DesignArtboard } from '../design/design-builder.js';
50
+ export { useEditor } from '../contexts/EditorContext.js';
51
+ export type { EditorContextValue, EditorProviderProps } from '../contexts/EditorContext.js';
52
+ export { useLayers } from '../hooks/useLayers.js';
53
+ export type { LayerInfo, UseLayersOptions, UseLayersReturn } from '../hooks/useLayers.js';
54
+ export { useCommands } from '../hooks/useCommands.js';
55
+ export type { UseCommandsReturn } from '../hooks/useCommands.js';
56
+ export { useArtboards } from '../hooks/useArtboards.js';
57
+ export type { ArtboardInfo, UseArtboardsReturn } from '../hooks/useArtboards.js';
58
+ export { useExport } from '../hooks/useExport.js';
59
+ export type { ExportProgress, ContinuousExportOptions, UseExportReturn } from '../hooks/useExport.js';
60
+ export { useSelectedElement } from '../hooks/useSelectedElement.js';
61
+ export { serializeState } from '../state/index.js';
62
+ export type { CanvasStateV1, SerializedArtboard, SerializedElement, } from '../state/index.js';
49
63
  export { useTextBinding } from '../hooks/useTextBinding.js';
50
64
  export { useImageBinding } from '../hooks/useImageBinding.js';
51
65
  export { useColorBinding } from '../hooks/useColorBinding.js';
@@ -153,4 +153,4 @@ export interface VisualGuideOverlayProps {
153
153
  /** `className` applied to the wrapping SVG element. */
154
154
  className?: string;
155
155
  }
156
- export declare function VisualGuideOverlay({ artboardWidth, artboardHeight, canvasPadding, pieces, pieceGuides, show, style, className, }: VisualGuideOverlayProps): JSX.Element;
156
+ export declare function VisualGuideOverlay({ artboardWidth, artboardHeight, canvasPadding, pieces, pieceGuides, show, style, className, }: VisualGuideOverlayProps): React.JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import { default as React, CSSProperties, ReactNode } from 'react';
2
+ import { CanvasState, SnowconeCanvasHandle } from '../embed/SnowconeCanvas.js';
2
3
  import { KitPresetId, KitDefinition } from '../../kits/types.js';
3
4
  import { CanvasServices } from '../../contexts/CanvasServicesContext.js';
4
5
  export interface RealtimeCanvasProps {
@@ -35,7 +36,29 @@ export interface RealtimeCanvasProps {
35
36
  * server — your vendor keys live there.
36
37
  */
37
38
  services?: CanvasServices;
39
+ /**
40
+ * Observe the live design state. Fires with the full {@link CanvasState}
41
+ * (elements stamped with their artboard name) whenever the canvas content
42
+ * changes — including once after the initial seed loads — in addition to the
43
+ * embed's internal edit→server-render flow, which is unaffected. This is the
44
+ * state you persist at add-to-cart / checkout so the purchased design can be
45
+ * re-rendered server-side later.
46
+ *
47
+ * Safe to pass inline: the underlying canvas reads the callback from a ref,
48
+ * so a new identity each render never re-fires or loops.
49
+ */
50
+ onChange?: (state: CanvasState) => void;
38
51
  className?: string;
39
52
  style?: CSSProperties;
40
53
  }
41
- export declare function RealtimeCanvas({ children, kit, inheritTheme, maxHeight, services, className, style, }: RealtimeCanvasProps): React.ReactElement;
54
+ /**
55
+ * Note the export naming wart, kept for backwards compatibility:
56
+ * - The ref handle's {@link SnowconeCanvasHandle.exportArtboards} resolves a
57
+ * record keyed by artboard **name** (e.g. `'Front'`) — names match the
58
+ * `placements` you configured on the embed.
59
+ * - The lower-level `useExport().exportArtboard(id)` hook takes an artboard
60
+ * **ID** (get one from `useArtboards()`).
61
+ * For print-res exports at checkout, the ref handle is the intended path:
62
+ * `ref.current.exportArtboards({ all: true, scale: 4, format: 'blob' })`.
63
+ */
64
+ export declare const RealtimeCanvas: React.ForwardRefExoticComponent<RealtimeCanvasProps & React.RefAttributes<SnowconeCanvasHandle>>;
@@ -1,37 +1,37 @@
1
- export { Label } from '@snowcone-app/ui';
2
- export { Switch } from '@snowcone-app/ui';
3
- export { Separator } from '@snowcone-app/ui';
4
- export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } from '@snowcone-app/ui';
5
- export { Spinner, spinnerVariants } from '@snowcone-app/ui';
6
- export type { SpinnerProps } from '@snowcone-app/ui';
7
- export { Surface, surfaceVariants, useSurface, SurfaceContext } from '@snowcone-app/ui';
8
- export type { SurfaceProps } from '@snowcone-app/ui';
9
- export { TextField } from '@snowcone-app/ui';
10
- export type { TextFieldProps } from '@snowcone-app/ui';
11
- export { Kbd, kbdVariants } from '@snowcone-app/ui';
12
- export type { KbdProps } from '@snowcone-app/ui';
13
- export { Fieldset, Legend } from '@snowcone-app/ui';
14
- export type { FieldsetProps, LegendProps } from '@snowcone-app/ui';
15
- export { Link, LinkIcon, linkVariants } from '@snowcone-app/ui';
16
- export type { LinkProps } from '@snowcone-app/ui';
17
- export { Tabs, TabsList, TabsTrigger, TabsContent, TabsRoot } from '@snowcone-app/ui';
18
- export { RadioGroup, RadioGroupItem, Radio } from '@snowcone-app/ui';
19
- export { Collapsible, CollapsibleTrigger, CollapsibleContent, CollapsibleRoot, Disclosure, DisclosureTrigger, DisclosureContent, } from '@snowcone-app/ui';
20
- export { Textarea, TextArea } from '@snowcone-app/ui';
21
- export type { TextareaProps } from '@snowcone-app/ui';
22
- export { Input } from '@snowcone-app/ui';
23
- export type { InputProps } from '@snowcone-app/ui';
24
- export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipRoot } from '@snowcone-app/ui';
25
- export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@snowcone-app/ui';
26
- export { Checkbox } from '@snowcone-app/ui';
27
- export { Badge, Chip, badgeVariants } from '@snowcone-app/ui';
28
- export type { BadgeProps } from '@snowcone-app/ui';
29
- export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup, } from '@snowcone-app/ui';
30
- export { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton, } from '@snowcone-app/ui';
31
- export { Button, buttonVariants } from '@snowcone-app/ui';
32
- export type { ButtonProps } from '@snowcone-app/ui';
33
- export { Slider, SliderTrack, SliderThumb, SliderFill, SliderOutput } from '@snowcone-app/ui';
34
- export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverRoot } from '@snowcone-app/ui';
1
+ export { Label } from '../../vendor/ui';
2
+ export { Switch } from '../../vendor/ui';
3
+ export { Separator } from '../../vendor/ui';
4
+ export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } from '../../vendor/ui';
5
+ export { Spinner, spinnerVariants } from '../../vendor/ui';
6
+ export type { SpinnerProps } from '../../vendor/ui';
7
+ export { Surface, surfaceVariants, useSurface, SurfaceContext } from '../../vendor/ui';
8
+ export type { SurfaceProps } from '../../vendor/ui';
9
+ export { TextField } from '../../vendor/ui';
10
+ export type { TextFieldProps } from '../../vendor/ui';
11
+ export { Kbd, kbdVariants } from '../../vendor/ui';
12
+ export type { KbdProps } from '../../vendor/ui';
13
+ export { Fieldset, Legend } from '../../vendor/ui';
14
+ export type { FieldsetProps, LegendProps } from '../../vendor/ui';
15
+ export { Link, LinkIcon, linkVariants } from '../../vendor/ui';
16
+ export type { LinkProps } from '../../vendor/ui';
17
+ export { Tabs, TabsList, TabsTrigger, TabsContent, TabsRoot } from '../../vendor/ui';
18
+ export { RadioGroup, RadioGroupItem, Radio } from '../../vendor/ui';
19
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent, CollapsibleRoot, Disclosure, DisclosureTrigger, DisclosureContent, } from '../../vendor/ui';
20
+ export { Textarea, TextArea } from '../../vendor/ui';
21
+ export type { TextareaProps } from '../../vendor/ui';
22
+ export { Input } from '../../vendor/ui';
23
+ export type { InputProps } from '../../vendor/ui';
24
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipRoot } from '../../vendor/ui';
25
+ export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '../../vendor/ui';
26
+ export { Checkbox } from '../../vendor/ui';
27
+ export { Badge, Chip, badgeVariants } from '../../vendor/ui';
28
+ export type { BadgeProps } from '../../vendor/ui';
29
+ export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup, } from '../../vendor/ui';
30
+ export { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton, } from '../../vendor/ui';
31
+ export { Button, buttonVariants } from '../../vendor/ui';
32
+ export type { ButtonProps } from '../../vendor/ui';
33
+ export { Slider, SliderTrack, SliderThumb, SliderFill, SliderOutput } from '../../vendor/ui';
34
+ export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverRoot } from '../../vendor/ui';
35
35
  export { ToolbarButton } from './toolbar-button';
36
36
  export type { ToolbarButtonProps } from './toolbar-button';
37
37
  export { NormalizedIcon, getIconSet, getScaleFactor, getNormalizedSize, SET_SCALE_FACTORS, SIZE_PRESETS, } from './normalized-icon';
package/dist/embed.mjs CHANGED
@@ -1,218 +1,233 @@
1
- import { a as J, e as z } from "./validation-BpmNOvuY.js";
2
- import { b as Re, d as Ie, f as Te } from "./validation-BpmNOvuY.js";
3
- import { y as w } from "./HybridHistoryManager-NL3zyEl4.js";
4
- import { jsx as y, Fragment as Y } from "react/jsx-runtime";
5
- import { createContext as Q, useContext as X, useMemo as S, useRef as x, useState as N, useEffect as G } from "react";
6
- import { assertVariantSelected as Z, RenderSession as ee } from "@snowcone-app/sdk";
7
- import { u as ne, p as te } from "./usePieceGuideBundle-Cyl695jv.js";
8
- import { S as re, s as se } from "./template-fields-IgDV7PRY.js";
9
- import { D as Me, T as Ue, d as Be, r as Ce, a as Ne, e as Ge, f as Oe, g as qe, h as Fe, w as Pe } from "./template-fields-IgDV7PRY.js";
10
- const L = Q(void 0);
11
- function q() {
12
- const e = X(L);
1
+ import { a as H, e as J } from "./validation-BahKiJWj.js";
2
+ import { b as Ie, d as Te, u as xe, f as Me, g as Ue, h as Be } from "./validation-BahKiJWj.js";
3
+ import { y as R } from "./HybridHistoryManager-NL3zyEl4.js";
4
+ import { jsx as $, Fragment as Y } from "react/jsx-runtime";
5
+ import { createContext as Q, useContext as X, useMemo as k, useRef as T, useState as O, useEffect as q, forwardRef as Z } from "react";
6
+ import { assertVariantSelected as ee, RenderSession as ne } from "@snowcone-app/sdk";
7
+ import { u as te, p as re } from "./usePieceGuideBundle-Cyl695jv.js";
8
+ import { S as se, s as ae } from "./template-fields-coO73lV3.js";
9
+ import { D as Ne, T as Ge, d as Oe, r as qe, a as Ae, b as Fe, e as Pe, f as _e, g as je, h as Le, i as De, w as Ve } from "./template-fields-coO73lV3.js";
10
+ import { u as We } from "./ThemeContext-Cl1JPVLZ.js";
11
+ import { s as He } from "./CanvasStateV1-BQD8fCBU.js";
12
+ const V = Q(void 0);
13
+ function F() {
14
+ const e = X(V);
13
15
  if (!e)
14
16
  throw new Error(
15
17
  "useRealtimeMockups / <RealtimeCanvas> / <RealtimeMockup> must be rendered inside <RealtimeEmbed>. Wrap them: <RealtimeEmbed shop=… product=… design=… grantUrl=…>…</RealtimeEmbed>"
16
18
  );
17
19
  return e;
18
20
  }
19
- const E = "[RealtimeEmbed]";
20
- function ae(e) {
21
- var s, l;
22
- if ((s = e == null ? void 0 : e.requiredPlacements) != null && s.length)
23
- return e.requiredPlacements.filter((t) => !t.autoFilledByVariant).map((t) => t.label);
21
+ const w = "[RealtimeEmbed]";
22
+ function oe(e) {
23
+ var o, i;
24
+ if ((o = e == null ? void 0 : e.requiredPlacements) != null && o.length)
25
+ return e.requiredPlacements.filter((r) => !r.autoFilledByVariant).map((r) => r.label);
24
26
  const n = new Set(
25
- (((l = e == null ? void 0 : e.options) == null ? void 0 : l.combinations) ?? []).map((t) => t.variantId).filter((t) => typeof t == "string" && t !== "")
27
+ (((i = e == null ? void 0 : e.options) == null ? void 0 : i.combinations) ?? []).map((r) => r.variantId).filter((r) => typeof r == "string" && r !== "")
26
28
  );
27
29
  return !!(e != null && e.variantId) || n.size > 1 ? [] : (e == null ? void 0 : e.placements) ?? [];
28
30
  }
29
- function oe({ shop: e, product: n, design: r, hasGrant: s }) {
30
- var u, o;
31
- if (e || console.error(`${E} \`shop\` is required (your publishable shop id).`), s || console.error(
32
- `${E} no grant source — pass \`grantUrl\` (a proxy to mintRealtimeGrant) or \`grant\`. Without it the session can never authorize and no mockup renders.`
33
- ), (u = n == null ? void 0 : n.mockupIds) != null && u.length || console.error(
34
- `${E} product.mockupIds is empty — pass the catalog scene codes (product.mockups[].id) you want rendered, e.g. ["FV1qjO"].`
31
+ function ie({ shop: e, product: n, design: t, hasGrant: o }) {
32
+ var d, s;
33
+ if (e || console.error(`${w} \`shop\` is required (your publishable shop id).`), o || console.error(
34
+ `${w} no grant source — pass \`grantUrl\` (a proxy to mintRealtimeGrant) or \`grant\`. Without it the session can never authorize and no mockup renders.`
35
+ ), (d = n == null ? void 0 : n.mockupIds) != null && d.length || console.error(
36
+ `${w} product.mockupIds is empty — pass the catalog scene codes (product.mockups[].id) you want rendered, e.g. ["FV1qjO"].`
35
37
  ), n != null && n.options)
36
38
  try {
37
- Z(n);
39
+ ee(n);
38
40
  } catch (a) {
39
- console.error(`${E} ${a instanceof Error ? a.message : String(a)}`);
41
+ console.error(`${w} ${a instanceof Error ? a.message : String(a)}`);
40
42
  }
41
- const l = r.toJSON(), t = l.activeArtboard, f = ae(n);
43
+ const i = t.toJSON(), r = i.activeArtboard, f = oe(n);
42
44
  f.length > 1 && console.error(
43
- `${E} product ${n.productId} requires placements [${f.join(", ")}] but <RealtimeEmbed> renders a single placement ("${t}"). The render will time out waiting for the others. This product needs the eject path — see https://developers.snowcone.app/embed-mode#eject.`
44
- ), (o = n == null ? void 0 : n.placements) != null && o.length && !n.placements.includes(t) && console.warn(
45
- `${E} the design's placement "${t}" is not in product.placements [${n.placements.join(", ")}]. The canvas artboard name and renderState placement must equal a real product placement label, or the server renders a blank mockup. Fix the \`name\` passed to design({ name }).`
45
+ `${w} product ${n.productId} requires placements [${f.join(", ")}] but <RealtimeEmbed> renders a single placement ("${r}"). The render will time out waiting for the others. This product needs the eject path — see https://developers.snowcone.app/embed-mode#eject.`
46
+ ), (s = n == null ? void 0 : n.placements) != null && s.length && !n.placements.includes(r) && console.warn(
47
+ `${w} the design's placement "${r}" is not in product.placements [${n.placements.join(", ")}]. The canvas artboard name and renderState placement must equal a real product placement label, or the server renders a blank mockup. Fix the \`name\` passed to design({ name }).`
46
48
  );
47
- const i = l.elements.map((a) => a.name).filter((a) => !!a), h = i.filter((a, p) => i.indexOf(a) !== p);
49
+ const c = i.elements.map((a) => a.name).filter((a) => !!a), h = c.filter((a, b) => c.indexOf(a) !== b);
48
50
  h.length && console.warn(
49
- `${E} duplicate layer name(s) [${[...new Set(h)].join(", ")}] — useTextBinding(name) / useImageBinding(name) bind to the FIRST match, so a duplicate name makes a control edit the wrong layer. Keep names unique.`
51
+ `${w} duplicate layer name(s) [${[...new Set(h)].join(", ")}] — useTextBinding(name) / useImageBinding(name) bind to the FIRST match, so a duplicate name makes a control edit the wrong layer. Keep names unique.`
50
52
  );
51
53
  }
52
- function ie(e) {
54
+ function ce(e) {
53
55
  if ("grantUrl" in e && e.grantUrl)
54
56
  return { grantUrl: e.grantUrl };
55
57
  const n = e.grant;
56
58
  return typeof n == "function" ? { getToken: n } : { getToken: () => Promise.resolve(n) };
57
59
  }
58
- const V = 8e3;
59
- function ce(e) {
60
- return `[RealtimeEmbed] No mockup after ${Math.round(V / 1e3)}s. Common causes: a variant product missing \`variantId\` (pass \`product.options\` so the embed can flag it up front), a multi-placement product (the server waits for every required placement but <RealtimeEmbed> sends only "${e}" — pass \`product.requiredPlacements\` so this is flagged at mount; such products need the eject path), an unreachable or non-public asset URL in the design, or the placement "${e}" not existing on the product. The render may still arrive — this is a heads-up, not a failure.`;
60
+ const K = 8e3;
61
+ function le(e) {
62
+ return `[RealtimeEmbed] No mockup after ${Math.round(K / 1e3)}s. Common causes: a variant product missing \`variantId\` (pass \`product.options\` so the embed can flag it up front), a multi-placement product (the server waits for every required placement but <RealtimeEmbed> sends only "${e}" — pass \`product.requiredPlacements\` so this is flagged at mount; such products need the eject path), an unreachable or non-public asset URL in the design, or the placement "${e}" not existing on the product. The render may still arrive — this is a heads-up, not a failure.`;
61
63
  }
62
- function Ee(e) {
63
- const { shop: n, product: r, design: s, throttleMs: l = 200, onMockups: t, onRenderError: f, wsUrl: i, services: h, children: u } = e, o = S(() => s.toJSON().activeArtboard, [s]), a = ne(r.variantId ?? r.defaultGvid), p = S(() => {
64
+ function Se(e) {
65
+ const { shop: n, product: t, design: o, throttleMs: i = 200, onMockups: r, onRenderError: f, wsUrl: c, services: h, children: d } = e, s = k(() => o.toJSON().activeArtboard, [o]), a = te(t.variantId ?? t.defaultGvid), b = k(() => {
64
66
  if (!a) return null;
65
- const c = s.toJSON().artboards[0];
66
- return te(a, c) ?? null;
67
- }, [a, s]), v = x(t), d = x(f);
68
- v.current = t, d.current = f;
69
- const [F, K] = N([]), [$, k] = N(!0), [P, R] = N(null), M = !!("grantUrl" in e && e.grantUrl || "grant" in e && e.grant), U = ie(e), W = "grantUrl" in U ? U.grantUrl : "getToken", B = `${r.productId}|${r.mockupIds.join(",")}|${r.variantId ?? ""}`, I = S(
67
+ const u = o.toJSON().artboards[0];
68
+ return re(a, u) ?? null;
69
+ }, [a, o]), p = T(r), l = T(f);
70
+ p.current = r, l.current = f;
71
+ const [I, y] = O([]), [S, E] = O(!0), [P, x] = O(null), B = !!("grantUrl" in e && e.grantUrl || "grant" in e && e.grant), C = ce(e), W = "grantUrl" in C ? C.grantUrl : "getToken", N = `${t.productId}|${t.mockupIds.join(",")}|${t.variantId ?? ""}`, M = k(
70
72
  () => {
71
73
  try {
72
- return { session: new ee({ shop: n, product: r, wsUrl: i, ...U }) };
73
- } catch (c) {
74
- return { error: c instanceof Error ? c.message : String(c) };
74
+ return { session: new ne({ shop: n, product: t, wsUrl: c, ...C }) };
75
+ } catch (u) {
76
+ return { error: u instanceof Error ? u.message : String(u) };
75
77
  }
76
78
  },
77
79
  // eslint-disable-next-line react-hooks/exhaustive-deps
78
- [n, B, o, i, W]
79
- ), g = "session" in I ? I.session : null, T = "error" in I ? I.error : null, _ = x(null);
80
- G(() => {
81
- var c;
82
- if (typeof w < "u" && ((c = w.env) == null ? void 0 : c.NODE_ENV) !== "production") {
83
- const m = `${n}|${B}|${o}|${M}`;
80
+ [n, N, s, c, W]
81
+ ), g = "session" in M ? M.session : null, U = "error" in M ? M.error : null, _ = T(null);
82
+ q(() => {
83
+ var u;
84
+ if (typeof R < "u" && ((u = R.env) == null ? void 0 : u.NODE_ENV) !== "production") {
85
+ const m = `${n}|${N}|${s}|${B}`;
84
86
  if (_.current === m) return;
85
- _.current = m, oe({ shop: n, product: r, design: s, hasGrant: M });
87
+ _.current = m, ie({ shop: n, product: t, design: o, hasGrant: B });
86
88
  }
87
- }, [n, B, o, M]);
88
- const C = S(() => (c, m = l) => {
89
- g && (R(null), k(!0), g.renderState(o, c, m).catch((b) => {
89
+ }, [n, N, s, B]);
90
+ const G = k(() => (u, m = i) => {
91
+ g && (x(null), E(!0), g.renderState(s, u, m).catch((v) => {
90
92
  var D;
91
- const A = b instanceof Error ? b.message : String(b);
92
- R(A), k(!1), (D = d.current) == null || D.call(d, A);
93
+ const L = v instanceof Error ? v.message : String(v);
94
+ x(L), E(!1), (D = l.current) == null || D.call(l, L);
93
95
  }));
94
- }, [g, o, l]);
95
- G(() => {
96
- var c;
97
- if (T) {
98
- R(T), k(!1), (c = d.current) == null || c.call(d, T);
96
+ }, [g, s, i]);
97
+ q(() => {
98
+ var u;
99
+ if (U) {
100
+ x(U), E(!1), (u = l.current) == null || u.call(l, U);
99
101
  return;
100
102
  }
101
103
  if (g)
102
104
  return g.onMockups((m) => {
103
- var b;
104
- K(m), k(!1), (b = v.current) == null || b.call(v, m);
105
+ var v;
106
+ y(m), E(!1), (v = p.current) == null || v.call(p, m);
105
107
  }), g.onError((m) => {
106
- var b;
107
- R(m), k(!1), (b = d.current) == null || b.call(d, m);
108
- }), C(s.toServerRequest()), () => g.close();
109
- }, [g, T]), G(() => {
108
+ var v;
109
+ x(m), E(!1), (v = l.current) == null || v.call(l, m);
110
+ }), G(o.toServerRequest()), () => g.close();
111
+ }, [g, U]), q(() => {
110
112
  var m;
111
- if (!$ || typeof w > "u" || ((m = w.env) == null ? void 0 : m.NODE_ENV) === "production") return;
112
- const c = setTimeout(() => console.warn(ce(o)), V);
113
- return () => clearTimeout(c);
114
- }, [$, o]);
115
- const H = S(
113
+ if (!S || typeof R > "u" || ((m = R.env) == null ? void 0 : m.NODE_ENV) === "production") return;
114
+ const u = setTimeout(() => console.warn(le(s)), K);
115
+ return () => clearTimeout(u);
116
+ }, [S, s]);
117
+ const z = k(
116
118
  () => ({
117
119
  session: g,
118
- design: s,
119
- placement: o,
120
- product: r,
121
- mockups: F,
122
- isRendering: $,
120
+ design: o,
121
+ placement: s,
122
+ product: t,
123
+ mockups: I,
124
+ isRendering: S,
123
125
  error: P,
124
- throttleMs: l,
125
- pieceGuides: p,
126
- pushRender: C
126
+ throttleMs: i,
127
+ pieceGuides: b,
128
+ pushRender: G
127
129
  }),
128
- [g, s, o, r, F, $, P, l, p, C]
129
- ), j = /* @__PURE__ */ y(L.Provider, { value: H, children: u });
130
- return h ? /* @__PURE__ */ y(J, { services: h, children: j }) : j;
131
- }
132
- function Se({
133
- children: e,
134
- kit: n = "embed-only",
135
- inheritTheme: r = !0,
136
- maxHeight: s,
137
- services: l,
138
- className: t,
139
- style: f
140
- }) {
141
- const { design: i, placement: h, throttleMs: u, pieceGuides: o, pushRender: a } = q(), p = S(() => i.toJSON(), [i]);
142
- return /* @__PURE__ */ y("div", { className: `app-modern${t ? ` ${t}` : ""}`, style: f, children: /* @__PURE__ */ y(
143
- re,
144
- {
145
- kit: n,
146
- inheritTheme: r,
147
- services: l,
148
- artboards: p.artboards,
149
- activeArtboard: h,
150
- initialElements: p.elements,
151
- layoutConfig: s ? { maxHeight: s } : void 0,
152
- overlay: e,
153
- pieceGuides: o ?? void 0,
154
- onChange: (v) => a(se(v), u)
155
- }
156
- ) });
130
+ [g, o, s, t, I, S, P, i, b, G]
131
+ ), j = /* @__PURE__ */ $(V.Provider, { value: z, children: d });
132
+ return h ? /* @__PURE__ */ $(H, { services: h, children: j }) : j;
157
133
  }
158
- const le = 1.2, O = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
159
- function ue(e) {
160
- for (const n of O)
134
+ const we = Z(
135
+ function({
136
+ children: n,
137
+ kit: t = "embed-only",
138
+ inheritTheme: o = !0,
139
+ maxHeight: i,
140
+ services: r,
141
+ onChange: f,
142
+ className: c,
143
+ style: h
144
+ }, d) {
145
+ const { design: s, placement: a, throttleMs: b, pieceGuides: p, pushRender: l } = F(), I = k(() => s.toJSON(), [s]), y = T(f);
146
+ return y.current = f, /* @__PURE__ */ $("div", { className: `sc-root${c ? ` ${c}` : ""}`, style: h, children: /* @__PURE__ */ $(
147
+ se,
148
+ {
149
+ ref: d,
150
+ kit: t,
151
+ inheritTheme: o,
152
+ services: r,
153
+ artboards: I.artboards,
154
+ activeArtboard: a,
155
+ initialElements: I.elements,
156
+ layoutConfig: i ? { maxHeight: i } : void 0,
157
+ overlay: n,
158
+ pieceGuides: p ?? void 0,
159
+ onChange: (S) => {
160
+ var E;
161
+ l(ae(S), b), (E = y.current) == null || E.call(y, S);
162
+ }
163
+ }
164
+ ) });
165
+ }
166
+ ), ue = 1.2, A = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
167
+ function de(e) {
168
+ for (const n of A)
161
169
  if (n >= e) return n;
162
- return O[O.length - 1];
170
+ return A[A.length - 1];
163
171
  }
164
- function de(e, n) {
165
- if (!(e > 0) || !(n > 0) || n <= e * le) return null;
166
- const r = ue(n);
167
- return `[RealtimeMockup] mockup rendered at ${e}px but displayed at ~${n} device px — the preview will look soft. Pass \`product.width\` (e.g. ${r}) on <RealtimeEmbed> for a crisp preview.`;
172
+ function me(e, n) {
173
+ if (!(e > 0) || !(n > 0) || n <= e * ue) return null;
174
+ const t = de(n);
175
+ return `[RealtimeMockup] mockup rendered at ${e}px but displayed at ~${n} device px — the preview will look soft. Pass \`product.width\` (e.g. ${t}) on <RealtimeEmbed> for a crisp preview.`;
168
176
  }
169
- function we({
177
+ function ye({
170
178
  mockupId: e,
171
179
  fallback: n = null,
172
- alt: r = "Live product mockup",
173
- className: s,
174
- style: l
180
+ alt: t = "Live product mockup",
181
+ className: o,
182
+ style: i
175
183
  }) {
176
- const { mockups: t } = q(), f = x(/* @__PURE__ */ new Set()), i = e ? t.find((u) => u.mockupId === e && u.imageUrl) : t.find((u) => u.imageUrl);
177
- if (!(i != null && i.imageUrl))
178
- return /* @__PURE__ */ y(Y, { children: n });
179
- const h = (u) => {
180
- var d;
181
- if (typeof w > "u" || ((d = w.env) == null ? void 0 : d.NODE_ENV) === "production" || typeof window > "u" || f.current.has(i.mockupId)) return;
182
- const o = u.currentTarget, a = o.getBoundingClientRect().width;
184
+ const { mockups: r } = F(), f = T(/* @__PURE__ */ new Set()), c = e ? r.find((d) => d.mockupId === e && d.imageUrl) : r.find((d) => d.imageUrl);
185
+ if (!(c != null && c.imageUrl))
186
+ return /* @__PURE__ */ $(Y, { children: n });
187
+ const h = (d) => {
188
+ var l;
189
+ if (typeof R > "u" || ((l = R.env) == null ? void 0 : l.NODE_ENV) === "production" || typeof window > "u" || f.current.has(c.mockupId)) return;
190
+ const s = d.currentTarget, a = s.getBoundingClientRect().width;
183
191
  if (a <= 0) return;
184
- const p = Math.round(a * (window.devicePixelRatio || 1)), v = de(o.naturalWidth, p);
185
- v && (f.current.add(i.mockupId), console.warn(v));
192
+ const b = Math.round(a * (window.devicePixelRatio || 1)), p = me(s.naturalWidth, b);
193
+ p && (f.current.add(c.mockupId), console.warn(p));
186
194
  };
187
195
  return (
188
196
  // eslint-disable-next-line @next/next/no-img-element
189
- /* @__PURE__ */ y("img", { src: i.imageUrl, alt: r, className: s, style: l, onLoad: h })
197
+ /* @__PURE__ */ $("img", { src: c.imageUrl, alt: t, className: o, style: i, onLoad: h })
190
198
  );
191
199
  }
192
- function ye() {
193
- const { mockups: e, isRendering: n, error: r } = q();
194
- return { mockups: e, isRendering: n, error: r };
200
+ function ke() {
201
+ const { mockups: e, isRendering: n, error: t } = F();
202
+ return { mockups: e, isRendering: n, error: t };
195
203
  }
196
- z();
204
+ J();
197
205
  export {
198
- J as CanvasServicesProvider,
199
- Me as DesignBuilder,
200
- Se as RealtimeCanvas,
201
- Ee as RealtimeEmbed,
202
- we as RealtimeMockup,
203
- Ue as TEMPLATE_FIELDS_KEY,
204
- Re as createProxyGenerate,
205
- Ie as createProxyImageSearch,
206
- Be as design,
207
- Ce as readTemplateFields,
208
- Te as useCanvasServices,
209
- Ne as useColorBinding,
210
- Ge as useElementByName,
211
- Oe as useFontBinding,
212
- qe as useImageBinding,
213
- ye as useRealtimeMockups,
214
- Fe as useTextBinding,
215
- oe as validateEmbed,
216
- Pe as withTemplateFields
206
+ H as CanvasServicesProvider,
207
+ Ne as DesignBuilder,
208
+ we as RealtimeCanvas,
209
+ Se as RealtimeEmbed,
210
+ ye as RealtimeMockup,
211
+ Ge as TEMPLATE_FIELDS_KEY,
212
+ Ie as createProxyGenerate,
213
+ Te as createProxyImageSearch,
214
+ Oe as design,
215
+ qe as readTemplateFields,
216
+ He as serializeState,
217
+ xe as useArtboards,
218
+ Me as useCanvasServices,
219
+ Ae as useColorBinding,
220
+ Fe as useCommands,
221
+ We as useEditor,
222
+ Pe as useElementByName,
223
+ Ue as useExport,
224
+ _e as useFontBinding,
225
+ je as useImageBinding,
226
+ Be as useLayers,
227
+ ke as useRealtimeMockups,
228
+ Le as useSelectedElement,
229
+ De as useTextBinding,
230
+ ie as validateEmbed,
231
+ Ve as withTemplateFields
217
232
  };
218
233
  //# sourceMappingURL=embed.mjs.map