@snowcone-app/canvas 0.37.0 → 0.38.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.
- package/ERROR_CONTRACT.md +39 -8
- package/STYLING_CONTRACT.md +24 -2
- package/dist/{CanvasRenderer-CTN4j-uO.js → CanvasRenderer-D-E5WWLm.js} +4 -4
- package/dist/{CanvasRenderer-CTN4j-uO.js.map → CanvasRenderer-D-E5WWLm.js.map} +1 -1
- package/dist/{CanvasStateV1-DLE5d1-d.js → CanvasStateV1-C9LQt2J0.js} +7 -7
- package/dist/{CanvasStateV1-DLE5d1-d.js.map → CanvasStateV1-C9LQt2J0.js.map} +1 -1
- package/dist/{ContextualToolbars-CG5Gmv_i.js → ContextualToolbars-C62As-xY.js} +202 -202
- package/dist/{ContextualToolbars-CG5Gmv_i.js.map → ContextualToolbars-C62As-xY.js.map} +1 -1
- package/dist/EditorCanvasImpl-BnxEbr2p.js +144 -0
- package/dist/EditorCanvasImpl-BnxEbr2p.js.map +1 -0
- package/dist/{ExportManager-CDX5_up8.js → ExportManager-BbBfO22S.js} +45 -45
- package/dist/{ExportManager-CDX5_up8.js.map → ExportManager-BbBfO22S.js.map} +1 -1
- package/dist/{FontAnalyzer-CEYA_6fY.js → FontAnalyzer-DWHS41ba.js} +128 -128
- package/dist/FontAnalyzer-DWHS41ba.js.map +1 -0
- package/dist/{ImagePanel-DLxIDKV-.js → ImagePanel-BaX0UE-L.js} +57 -57
- package/dist/{ImagePanel-DLxIDKV-.js.map → ImagePanel-BaX0UE-L.js.map} +1 -1
- package/dist/SnowconeCanvas-CWSPyqqj.js +1112 -0
- package/dist/SnowconeCanvas-CWSPyqqj.js.map +1 -0
- package/dist/advanced.mjs +138 -138
- package/dist/api/placement.d.ts +3 -0
- package/dist/components/editor/EditorPlacements.d.ts +19 -6
- package/dist/components/editor/RootInternals.d.ts +7 -0
- package/dist/components/editor/designStateStore.d.ts +18 -0
- package/dist/components/editor/index.d.ts +3 -1
- package/dist/components/editor/placementLinks.d.ts +52 -0
- package/dist/components/editor/usePlacements.d.ts +28 -4
- package/dist/components/embed-realtime/context.d.ts +20 -4
- package/dist/components/embed-realtime/usePieceGuideBundle.d.ts +1 -0
- package/dist/components/embed-realtime/validateEmbed.d.ts +6 -3
- package/dist/{custom-icons-D51KIAfz.js → custom-icons-o1U13Vcg.js} +14 -14
- package/dist/{custom-icons-D51KIAfz.js.map → custom-icons-o1U13Vcg.js.map} +1 -1
- package/dist/{design-builder-CqgTpp9B.js → design-builder-CoCtjIwj.js} +86 -86
- package/dist/{design-builder-CqgTpp9B.js.map → design-builder-CoCtjIwj.js.map} +1 -1
- package/dist/{embed-CLz3CTcX.js → embed-SOFUZlGB.js} +843 -729
- package/dist/embed-SOFUZlGB.js.map +1 -0
- package/dist/embed.mjs +28 -28
- package/dist/errors/editorError.d.ts +7 -2
- package/dist/{guards-DldCuuJq.js → guards-DMmhw_Ow.js} +4 -4
- package/dist/{guards-DldCuuJq.js.map → guards-DMmhw_Ow.js.map} +1 -1
- package/dist/index.mjs +21 -21
- package/dist/internals.mjs +108 -108
- package/dist/internals.mjs.map +1 -1
- package/dist/placement-Br5jI_-u.js +90 -0
- package/dist/placement-Br5jI_-u.js.map +1 -0
- package/dist/placement.d.ts +2 -0
- package/dist/placement.mjs +5 -0
- package/dist/placement.mjs.map +1 -0
- package/dist/template-fields-CBLHgW7G.js +556 -0
- package/dist/template-fields-CBLHgW7G.js.map +1 -0
- package/dist/testing.mjs +24 -24
- package/dist/{useCommands-CQi4Pyd2.js → useCommands-x8J7_Mzy.js} +262 -262
- package/dist/{useCommands-CQi4Pyd2.js.map → useCommands-x8J7_Mzy.js.map} +1 -1
- package/dist/usePieceGuideBundle-C7r06a_x.js +65 -0
- package/dist/usePieceGuideBundle-C7r06a_x.js.map +1 -0
- package/dist/{validation-THw5W6N_.js → validation-BG-V98h0.js} +846 -846
- package/dist/validation-BG-V98h0.js.map +1 -0
- package/example/package.json +1 -1
- package/package.json +9 -4
- package/dist/EditorCanvasImpl-BRdFWZA5.js +0 -81
- package/dist/EditorCanvasImpl-BRdFWZA5.js.map +0 -1
- package/dist/FontAnalyzer-CEYA_6fY.js.map +0 -1
- package/dist/SnowconeCanvas-BaFR8QXs.js +0 -1196
- package/dist/SnowconeCanvas-BaFR8QXs.js.map +0 -1
- package/dist/embed-CLz3CTcX.js.map +0 -1
- package/dist/template-fields-D8uOutD4.js +0 -505
- package/dist/template-fields-D8uOutD4.js.map +0 -1
- package/dist/usePieceGuideBundle-BUQKb0Ja.js +0 -61
- package/dist/usePieceGuideBundle-BUQKb0Ja.js.map +0 -1
- package/dist/validation-THw5W6N_.js.map +0 -1
|
@@ -1,176 +1,176 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { jsx as
|
|
4
|
-
import { useContext as
|
|
5
|
-
import { assertVariantSelected as
|
|
6
|
-
import { s as
|
|
7
|
-
import { u as
|
|
8
|
-
import { D as
|
|
9
|
-
import "./ExportManager-
|
|
10
|
-
import "./CanvasStateV1-
|
|
11
|
-
const
|
|
12
|
-
function
|
|
13
|
-
const e =
|
|
1
|
+
import { n as Xe, o as Ze, E as et, C as tt, y as se, z as oe, A as nt, F as rt, G as it, H as st, J as ot, l as at, e as dt } from "./useCommands-x8J7_Mzy.js";
|
|
2
|
+
import { t as S, V as Te, p as z } from "./FontAnalyzer-DWHS41ba.js";
|
|
3
|
+
import { jsx as g, jsxs as U, Fragment as lt } from "react/jsx-runtime";
|
|
4
|
+
import { useContext as ct, createContext as ut, useRef as C, useState as D, useMemo as A, useCallback as G, useLayoutEffect as ae, useEffect as L, useSyncExternalStore as J, Component as mt, forwardRef as Ae, useId as we, memo as pt, isValidElement as De } from "react";
|
|
5
|
+
import { assertVariantSelected as ft, RenderSession as ht, createCartDetail as gt } from "@snowcone-app/sdk";
|
|
6
|
+
import { s as ee, B as yt, E as bt, n as vt, i as wt } from "./design-builder-CoCtjIwj.js";
|
|
7
|
+
import { u as Et, p as kt } from "./usePieceGuideBundle-C7r06a_x.js";
|
|
8
|
+
import { D as xt, C as St, f as Rt, d as It } from "./template-fields-CBLHgW7G.js";
|
|
9
|
+
import "./ExportManager-BbBfO22S.js";
|
|
10
|
+
import "./CanvasStateV1-C9LQt2J0.js";
|
|
11
|
+
const Be = ut(void 0);
|
|
12
|
+
function te() {
|
|
13
|
+
const e = ct(Be);
|
|
14
14
|
if (!e)
|
|
15
15
|
throw new Error(
|
|
16
16
|
"useRealtimeMockups / <RealtimeCanvas> / <RealtimeMockup> must be rendered inside <RealtimeEmbed>. Wrap them: <RealtimeEmbed shop=… product=… design=… grantUrl=…>…</RealtimeEmbed>"
|
|
17
17
|
);
|
|
18
18
|
return e;
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function Ue(e) {
|
|
21
21
|
var t;
|
|
22
22
|
return Array.isArray((t = e.bundle) == null ? void 0 : t.members) && e.bundle.members.length > 0;
|
|
23
23
|
}
|
|
24
|
-
const
|
|
25
|
-
function
|
|
24
|
+
const W = "bundles";
|
|
25
|
+
function Ot(e) {
|
|
26
26
|
return Object.keys(e).sort().map((t) => `${t}:${e[t]}`).join(",");
|
|
27
27
|
}
|
|
28
|
-
function
|
|
28
|
+
function Ee(e) {
|
|
29
29
|
const t = e.indexOf(".");
|
|
30
30
|
return t <= 0 || t === e.length - 1 ? null : { role: e.slice(0, t), key: e.slice(t + 1) };
|
|
31
31
|
}
|
|
32
|
-
function
|
|
32
|
+
function $t(e) {
|
|
33
33
|
return e.type !== "color" && typeof e.width == "number" && e.width > 0 && typeof e.height == "number" && e.height > 0;
|
|
34
34
|
}
|
|
35
|
-
function
|
|
35
|
+
function Ct(e, t) {
|
|
36
36
|
var i, s;
|
|
37
37
|
const n = (s = (i = e.options) == null ? void 0 : i.combinations) == null ? void 0 : s.find((o) => o.variantId === t);
|
|
38
38
|
if (!n) return t;
|
|
39
39
|
const r = Object.entries(n).filter(([o, l]) => o !== "variantId" && o !== "price" && (typeof l == "string" || typeof l == "number")).map(([o, l]) => `${o} ${String(l)}`);
|
|
40
40
|
return r.length > 0 ? r.join(" · ") : t;
|
|
41
41
|
}
|
|
42
|
-
function
|
|
43
|
-
var
|
|
44
|
-
if (!
|
|
45
|
-
throw new
|
|
42
|
+
function On(e, t = {}) {
|
|
43
|
+
var v, B, N, _, F;
|
|
44
|
+
if (!Ue(e))
|
|
45
|
+
throw new S(
|
|
46
46
|
"E_NOT_A_BUNDLE",
|
|
47
47
|
`product ${e.id} has no bundle block — picks / variants are bundle parameters the server refuses on a single product (E_NOT_A_BUNDLE). Use productToRenderConfig() for it.`,
|
|
48
|
-
{ productId: e.id, docSlug:
|
|
48
|
+
{ productId: e.id, docSlug: W }
|
|
49
49
|
);
|
|
50
|
-
const n = e.bundle.members, r = n.map((
|
|
51
|
-
for (const [
|
|
50
|
+
const n = e.bundle.members, r = n.map((h) => h.role);
|
|
51
|
+
for (const [h, $] of [
|
|
52
52
|
["picks", t.picks],
|
|
53
53
|
["variants", t.variants]
|
|
54
54
|
])
|
|
55
|
-
for (const
|
|
56
|
-
if (!r.includes(
|
|
57
|
-
throw new
|
|
55
|
+
for (const V of Object.keys($ ?? {}))
|
|
56
|
+
if (!r.includes(V))
|
|
57
|
+
throw new S(
|
|
58
58
|
"E_BUNDLE_ROLE_NOT_FOUND",
|
|
59
|
-
`bundle ${e.id} has no role "${
|
|
60
|
-
{ productId: e.id, field:
|
|
59
|
+
`bundle ${e.id} has no role "${V}" (in ${h}). Roles: [${r.join(", ")}].`,
|
|
60
|
+
{ productId: e.id, field: h, role: V, validNames: r, docSlug: W }
|
|
61
61
|
);
|
|
62
|
-
const i = {}, s = {}, o = {}, l = e.placements ?? [],
|
|
63
|
-
for (const
|
|
64
|
-
const
|
|
65
|
-
if (!
|
|
66
|
-
throw new
|
|
62
|
+
const i = {}, s = {}, o = {}, l = e.placements ?? [], d = [];
|
|
63
|
+
for (const h of n) {
|
|
64
|
+
const $ = h.products.map((w) => w.productId), V = (v = t.picks) == null ? void 0 : v[h.role], T = V === void 0 ? h.products[0] : h.products.find((w) => w.productId === V);
|
|
65
|
+
if (!T)
|
|
66
|
+
throw new S(
|
|
67
67
|
"E_BUNDLE_PICK_NOT_FOUND",
|
|
68
|
-
`bundle ${e.id} role "${
|
|
69
|
-
{ productId: e.id, role:
|
|
68
|
+
`bundle ${e.id} role "${h.role}" has no alternative "${V}". Alternatives: [${$.join(", ")}] — pass picks: { ${h.role}: "${$[0]}" }.`,
|
|
69
|
+
{ productId: e.id, role: h.role, requested: V, validNames: $, docSlug: W }
|
|
70
70
|
);
|
|
71
|
-
i[
|
|
72
|
-
const
|
|
73
|
-
if (!
|
|
74
|
-
const w = (
|
|
75
|
-
throw new
|
|
71
|
+
i[h.role] = T.productId;
|
|
72
|
+
const j = (T.variants ?? []).map((w) => w.gvid).filter((w) => typeof w == "string" && w !== ""), M = j.length > 0 ? j : T.defaultGvid ? [T.defaultGvid] : [], K = ((B = t.variants) == null ? void 0 : B[h.role]) ?? T.defaultGvid ?? j[0];
|
|
73
|
+
if (!K || !M.includes(K)) {
|
|
74
|
+
const w = (N = t.variants) == null ? void 0 : N[h.role];
|
|
75
|
+
throw new S(
|
|
76
76
|
"E_BUNDLE_VARIANT_NOT_FOUND",
|
|
77
|
-
|
|
77
|
+
M.length === 0 ? `bundle ${e.id} role "${h.role}": alternative ${T.productId} publishes no variant — nothing can render this slot (catalog data is incomplete).` : `bundle ${e.id} role "${h.role}" (${T.productId}) has no variant "${w}". Variants: [${M.join(", ")}] — pass variants: { ${h.role}: "${M[0]}" }.`,
|
|
78
78
|
{
|
|
79
79
|
productId: e.id,
|
|
80
|
-
role:
|
|
81
|
-
memberProductId:
|
|
80
|
+
role: h.role,
|
|
81
|
+
memberProductId: T.productId,
|
|
82
82
|
requested: w,
|
|
83
|
-
validNames:
|
|
84
|
-
docSlug:
|
|
83
|
+
validNames: M,
|
|
84
|
+
docSlug: W
|
|
85
85
|
}
|
|
86
86
|
);
|
|
87
87
|
}
|
|
88
|
-
s[
|
|
89
|
-
const
|
|
90
|
-
(w) => w.role ===
|
|
88
|
+
s[h.role] = K, o[h.role] = ((F = (_ = T.variants) == null ? void 0 : _.find((w) => w.gvid === K)) == null ? void 0 : F.gvidForMockup) || K;
|
|
89
|
+
const X = l.filter(
|
|
90
|
+
(w) => w.role === h.role && w.memberProductId === T.productId && typeof w.key == "string" && w.key !== "" && $t(w)
|
|
91
91
|
).map((w) => ({
|
|
92
92
|
key: w.key,
|
|
93
|
-
role:
|
|
93
|
+
role: h.role,
|
|
94
94
|
label: w.label,
|
|
95
|
-
memberProductId:
|
|
95
|
+
memberProductId: T.productId,
|
|
96
96
|
width: w.width,
|
|
97
97
|
height: w.height,
|
|
98
98
|
aspectRatio: w.width / w.height
|
|
99
99
|
}));
|
|
100
|
-
|
|
101
|
-
role:
|
|
102
|
-
required:
|
|
103
|
-
alternatives:
|
|
104
|
-
pick:
|
|
105
|
-
variantId:
|
|
106
|
-
variantChoices:
|
|
107
|
-
placements:
|
|
100
|
+
d.push({
|
|
101
|
+
role: h.role,
|
|
102
|
+
required: h.required !== !1,
|
|
103
|
+
alternatives: $,
|
|
104
|
+
pick: T.productId,
|
|
105
|
+
variantId: K,
|
|
106
|
+
variantChoices: M.map((w) => ({ gvid: w, label: Ct(T, w) })),
|
|
107
|
+
placements: X
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
|
-
const a = new Set(
|
|
111
|
-
for (const
|
|
112
|
-
if (typeof
|
|
113
|
-
const
|
|
114
|
-
|
|
110
|
+
const a = new Set(d.flatMap((h) => h.placements.map(($) => $.key))), u = new Map(d.flatMap((h) => h.placements.map(($) => [$.key, $]))), c = [];
|
|
111
|
+
for (const h of l) {
|
|
112
|
+
if (typeof h.key != "string" || !a.has(h.key)) continue;
|
|
113
|
+
const $ = u.get(h.key);
|
|
114
|
+
$ && !c.includes($) && c.push($);
|
|
115
115
|
}
|
|
116
|
-
const b =
|
|
117
|
-
let
|
|
116
|
+
const b = c.map((h) => h.key);
|
|
117
|
+
let x;
|
|
118
118
|
if (t.placement !== void 0) {
|
|
119
|
-
if (!
|
|
120
|
-
throw new
|
|
119
|
+
if (!Ee(t.placement))
|
|
120
|
+
throw new S(
|
|
121
121
|
"E_BUNDLE_ROLE_REQUIRED",
|
|
122
122
|
`placement "${t.placement}" names no role — on bundle ${e.id} a placement is addressed by its role-scoped key. Keys: [${b.join(", ")}].`,
|
|
123
|
-
{ productId: e.id, requested: t.placement, validNames: b, docSlug:
|
|
123
|
+
{ productId: e.id, requested: t.placement, validNames: b, docSlug: W }
|
|
124
124
|
);
|
|
125
|
-
if (
|
|
126
|
-
throw new
|
|
125
|
+
if (x = c.find((h) => h.key === t.placement), !x)
|
|
126
|
+
throw new S(
|
|
127
127
|
"E_PRODUCT_NOT_RENDERABLE",
|
|
128
128
|
`bundle ${e.id} has no renderable placement "${t.placement}" for picks ${JSON.stringify(i)}. Keys: [${b.join(", ")}].`,
|
|
129
|
-
{ productId: e.id, requested: t.placement, picks: i, validNames: b, docSlug:
|
|
129
|
+
{ productId: e.id, requested: t.placement, picks: i, validNames: b, docSlug: W }
|
|
130
130
|
);
|
|
131
131
|
} else
|
|
132
|
-
|
|
133
|
-
if (!
|
|
134
|
-
throw new
|
|
132
|
+
x = c[0];
|
|
133
|
+
if (!x)
|
|
134
|
+
throw new S(
|
|
135
135
|
"E_PRODUCT_NOT_RENDERABLE",
|
|
136
136
|
`bundle ${e.id} has no renderable image placement for picks ${JSON.stringify(i)} (a role-scoped, non-color placement with width/height). The catalog payload may be incomplete — fetch it via getProduct(), not a search hit.`,
|
|
137
|
-
{ productId: e.id, picks: i, docSlug:
|
|
137
|
+
{ productId: e.id, picks: i, docSlug: W }
|
|
138
138
|
);
|
|
139
|
-
const
|
|
140
|
-
(
|
|
141
|
-
),
|
|
142
|
-
if (
|
|
143
|
-
throw new
|
|
139
|
+
const m = e.mockups ?? [], E = m.filter(
|
|
140
|
+
(h) => !h.picks || Object.entries(h.picks).every(([$, V]) => i[$] === V)
|
|
141
|
+
), y = (E.length > 0 ? E : m).map((h) => h.id);
|
|
142
|
+
if (y.length === 0)
|
|
143
|
+
throw new S(
|
|
144
144
|
"E_PRODUCT_NOT_RENDERABLE",
|
|
145
145
|
`bundle ${e.id} has no mockup scenes — nothing to render a preview into.`,
|
|
146
|
-
{ productId: e.id, docSlug:
|
|
146
|
+
{ productId: e.id, docSlug: W }
|
|
147
147
|
);
|
|
148
|
-
const
|
|
148
|
+
const p = (e.requiredPlacements ?? []).filter((h) => typeof h.key == "string" && h.key !== "" && a.has(h.key)).map((h) => ({ label: h.key, key: h.key, type: h.type, autoFilledByVariant: h.autoFilledByVariant }));
|
|
149
149
|
return {
|
|
150
150
|
kind: "bundle",
|
|
151
151
|
product: {
|
|
152
152
|
productId: e.id,
|
|
153
|
-
mockupIds:
|
|
153
|
+
mockupIds: y,
|
|
154
154
|
picks: i,
|
|
155
155
|
variants: s,
|
|
156
156
|
placements: b,
|
|
157
|
-
mockups:
|
|
158
|
-
...
|
|
157
|
+
mockups: m,
|
|
158
|
+
...p.length > 0 ? { requiredPlacements: p } : {},
|
|
159
159
|
...typeof t.width == "number" ? { width: t.width } : {}
|
|
160
160
|
},
|
|
161
161
|
picks: i,
|
|
162
162
|
variants: s,
|
|
163
|
-
variantToken:
|
|
164
|
-
roles:
|
|
165
|
-
placement:
|
|
166
|
-
placements:
|
|
163
|
+
variantToken: Ot(o),
|
|
164
|
+
roles: d,
|
|
165
|
+
placement: x,
|
|
166
|
+
placements: c,
|
|
167
167
|
placementKeys: b,
|
|
168
168
|
roleNames: r,
|
|
169
|
-
primaryMockupId:
|
|
169
|
+
primaryMockupId: y[0]
|
|
170
170
|
};
|
|
171
171
|
}
|
|
172
|
-
const
|
|
173
|
-
function
|
|
172
|
+
const Nt = "[RealtimeEmbed]";
|
|
173
|
+
function pe(e) {
|
|
174
174
|
var r, i;
|
|
175
175
|
if ((r = e == null ? void 0 : e.requiredPlacements) != null && r.length)
|
|
176
176
|
return e.requiredPlacements.filter((s) => !s.autoFilledByVariant).map((s) => s.label);
|
|
@@ -179,21 +179,21 @@ function Te(e) {
|
|
|
179
179
|
);
|
|
180
180
|
return !!(e != null && e.variantId) || t.size > 1 ? [] : (e == null ? void 0 : e.placements) ?? [];
|
|
181
181
|
}
|
|
182
|
-
function
|
|
182
|
+
function _t(e) {
|
|
183
183
|
return !!(e != null && e.picks) || !!(e != null && e.variants);
|
|
184
184
|
}
|
|
185
|
-
function
|
|
185
|
+
function Tt(e) {
|
|
186
186
|
const t = /* @__PURE__ */ new Set();
|
|
187
187
|
for (const n of e.placements ?? []) {
|
|
188
|
-
const r =
|
|
188
|
+
const r = Ee(n);
|
|
189
189
|
r && t.add(r.role);
|
|
190
190
|
}
|
|
191
191
|
for (const n of Object.keys(e.picks ?? {})) t.add(n);
|
|
192
192
|
for (const n of Object.keys(e.variants ?? {})) t.add(n);
|
|
193
193
|
return [...t];
|
|
194
194
|
}
|
|
195
|
-
function
|
|
196
|
-
var
|
|
195
|
+
function Le({ shop: e, product: t, design: n, hasGrant: r }) {
|
|
196
|
+
var m, E;
|
|
197
197
|
const i = [];
|
|
198
198
|
if (e || i.push({
|
|
199
199
|
severity: "error",
|
|
@@ -203,67 +203,89 @@ function Ae({ shop: e, product: t, design: n, hasGrant: r }) {
|
|
|
203
203
|
severity: "error",
|
|
204
204
|
issue: "missing-grant",
|
|
205
205
|
message: "no grant source — pass `grantUrl` (a proxy to mintRealtimeGrant) or `grant`. Without it the session can never authorize and no mockup renders."
|
|
206
|
-
}), (
|
|
206
|
+
}), (m = t == null ? void 0 : t.mockupIds) != null && m.length || i.push({
|
|
207
207
|
severity: "error",
|
|
208
208
|
issue: "empty-mockup-ids",
|
|
209
209
|
message: 'product.mockupIds is empty — pass the catalog scene codes (product.mockups[].id) you want rendered, e.g. ["FV1qjO"].'
|
|
210
210
|
}), t != null && t.options)
|
|
211
211
|
try {
|
|
212
|
-
|
|
213
|
-
} catch (
|
|
212
|
+
ft(t);
|
|
213
|
+
} catch (y) {
|
|
214
214
|
i.push({
|
|
215
215
|
severity: "error",
|
|
216
216
|
issue: "variant-required",
|
|
217
|
-
message:
|
|
217
|
+
message: y instanceof Error ? y.message : String(y)
|
|
218
218
|
});
|
|
219
219
|
}
|
|
220
|
-
const s = n.toJSON(), o = s.artboards.map((
|
|
221
|
-
let
|
|
220
|
+
const s = n.toJSON(), o = s.artboards.map((y) => y.name), l = _t(t);
|
|
221
|
+
let d = [];
|
|
222
222
|
if (l) {
|
|
223
|
-
const
|
|
224
|
-
|
|
223
|
+
const y = t.placements ?? [];
|
|
224
|
+
d = o.filter((v) => !Ee(v)), d.length > 0 && i.push({
|
|
225
225
|
severity: "error",
|
|
226
226
|
issue: "bundle-role-required",
|
|
227
|
-
message: `product ${t.productId} is a bundle, but the design's artboard(s) [${
|
|
227
|
+
message: `product ${t.productId} is a bundle, but the design's artboard(s) [${d.join(", ")}] name no role. On a bundle every placement is addressed by its role-scoped key (<role>.<key>)${y.length ? ` — keys: [${y.join(", ")}]` : ""}. Seed the design from bundleToRenderConfig(product).placement.key, not from a bare label.`
|
|
228
228
|
}), t.variantId && i.push({
|
|
229
229
|
severity: "error",
|
|
230
230
|
issue: "bundle-role-required",
|
|
231
231
|
message: `product ${t.productId} is a bundle, but product.variantId ("${t.variantId}") names no slot — the server refuses it (E_BUNDLE_ROLE_REQUIRED). Name the variant per role instead: product.variants = { <role>: <gvid> } (bundleToRenderConfig fills it), and leave variantId unset.`
|
|
232
232
|
});
|
|
233
|
-
const
|
|
234
|
-
var
|
|
235
|
-
return !((
|
|
233
|
+
const O = Tt(t).filter((v) => {
|
|
234
|
+
var B;
|
|
235
|
+
return !((B = t.variants) != null && B[v]);
|
|
236
236
|
});
|
|
237
|
-
|
|
237
|
+
O.length > 0 && i.push({
|
|
238
238
|
severity: "error",
|
|
239
239
|
issue: "bundle-variant-required",
|
|
240
|
-
message: `product ${t.productId} is a bundle, but role(s) [${
|
|
240
|
+
message: `product ${t.productId} is a bundle, but role(s) [${O.join(", ")}] have no entry in product.variants (${JSON.stringify(t.variants ?? {})}). Every role needs a variant — the server keys the render on the per-role set. Build the product with bundleToRenderConfig(product, { picks, variants }), which fills each slot's default.`
|
|
241
241
|
});
|
|
242
242
|
}
|
|
243
|
-
const a =
|
|
244
|
-
a.length > 1 && o.length > 1 &&
|
|
245
|
-
severity: "
|
|
246
|
-
issue: "
|
|
247
|
-
message: `product ${t.productId} requires placements [${a.join(", ")}]
|
|
243
|
+
const a = pe(t), u = a.filter((y) => !o.includes(y));
|
|
244
|
+
a.length > 1 && o.length > 1 && u.length > 0 && i.push({
|
|
245
|
+
severity: "warn",
|
|
246
|
+
issue: "placements-inherit-base",
|
|
247
|
+
message: `product ${t.productId} requires placements [${a.join(", ")}]; the design authors [${o.join(", ")}], so [${u.join(", ")}] inherit the base artboard "${o[0]}" (re-fit per placement, ADR-0101). Intended? Otherwise split them: design(…).artboard('` + u[0] + "', { width, height })… or usePlacements().split('" + u[0] + "') at runtime."
|
|
248
248
|
});
|
|
249
|
-
const
|
|
250
|
-
|
|
249
|
+
const c = (E = t == null ? void 0 : t.placements) != null && E.length ? o.filter((y) => !t.placements.includes(y) && !d.includes(y)) : [];
|
|
250
|
+
c.length > 0 && i.push({
|
|
251
251
|
severity: "error",
|
|
252
252
|
issue: "placement-mismatch",
|
|
253
|
-
message: `the design's artboard(s) [${
|
|
253
|
+
message: `the design's artboard(s) [${c.join(", ")}] are not in product.placements [${t.placements.join(", ")}]. Every artboard name must equal a real product placement label (renderState targets placements by that name), or the server renders a blank mockup. Fix the \`name\` passed to design({ name }) / design().artboard(name, …).`
|
|
254
254
|
});
|
|
255
|
-
const b = s.elements.map((
|
|
256
|
-
return
|
|
255
|
+
const b = s.elements.map((y) => y.name).filter((y) => !!y), x = b.filter((y, p) => b.indexOf(y) !== p);
|
|
256
|
+
return x.length && i.push({
|
|
257
257
|
severity: "warn",
|
|
258
258
|
issue: "duplicate-layer-names",
|
|
259
|
-
message: `duplicate layer name(s) [${[...new Set(
|
|
259
|
+
message: `duplicate layer name(s) [${[...new Set(x)].join(", ")}] — useTextBinding(name) / useImageBinding(name) bind to the FIRST match, so a duplicate name makes a control edit the wrong layer. Keep names unique.`
|
|
260
260
|
}), i;
|
|
261
261
|
}
|
|
262
|
-
function
|
|
263
|
-
for (const t of
|
|
264
|
-
(t.severity === "error" && t.issue !== "placement-mismatch" ? console.error : console.warn)(`${
|
|
262
|
+
function At(e) {
|
|
263
|
+
for (const t of Le(e))
|
|
264
|
+
(t.severity === "error" && t.issue !== "placement-mismatch" ? console.error : console.warn)(`${Nt} ${t.message}`);
|
|
265
|
+
}
|
|
266
|
+
function Fe(e, t) {
|
|
267
|
+
const n = new Set(e);
|
|
268
|
+
if (t.length === 0)
|
|
269
|
+
return e.map((i) => ({ label: i, inherited: !1 }));
|
|
270
|
+
const r = t.map((i) => ({
|
|
271
|
+
label: i,
|
|
272
|
+
inherited: !n.has(i)
|
|
273
|
+
}));
|
|
274
|
+
for (const i of e)
|
|
275
|
+
t.includes(i) || r.push({ label: i, inherited: !1 });
|
|
276
|
+
return r;
|
|
277
|
+
}
|
|
278
|
+
function Ve(e, t) {
|
|
279
|
+
const n = e.artboards ?? [], r = n[0];
|
|
280
|
+
if (!r || t.length === 0) return e;
|
|
281
|
+
const i = n.map((d) => typeof d.name == "string" ? d.name : ""), s = new Map(n.map((d, a) => [i[a], d])), o = Fe(i, t);
|
|
282
|
+
if (o.every((d) => !d.inherited)) return e;
|
|
283
|
+
const l = o.map(
|
|
284
|
+
(d) => d.inherited ? { ...r, name: d.label } : s.get(d.label)
|
|
285
|
+
);
|
|
286
|
+
return { ...e, artboards: l };
|
|
265
287
|
}
|
|
266
|
-
function
|
|
288
|
+
function Pe({ registry: e, store: t, product: n }) {
|
|
267
289
|
const r = [], i = e.getParts(), s = e.getTextFields(), o = e.requiresCanvasPartNames();
|
|
268
290
|
o.length > 0 && !e.hasCanvas() && r.push({
|
|
269
291
|
code: "A_REQUIRES_CANVAS",
|
|
@@ -271,48 +293,48 @@ function De({ registry: e, store: t, product: n }) {
|
|
|
271
293
|
message: `${o.join(", ")} ${o.length === 1 ? "is" : "are"} mounted with no <Editor.Canvas> under this Root — they operate on the editable artboard (selection, editor commands) and throw E_REQUIRES_CANVAS.`,
|
|
272
294
|
fix: `Mount <Editor.Canvas/> under the same <Editor.Root>, or remove ${o.join(", ")}. Canvas-free parts: Editor.Preview, Editor.Buy, Editor.TextField, Editor.Layers.`
|
|
273
295
|
});
|
|
274
|
-
const l = i.filter((
|
|
296
|
+
const l = i.filter((m) => m.name === "Editor.Canvas").some((m) => m.meta.floatingToolbar !== !1);
|
|
275
297
|
e.hasDockedControls() && l && r.push({
|
|
276
298
|
code: "A_CONTROLS_INERT",
|
|
277
299
|
severity: "warn",
|
|
278
300
|
message: "a docked <Editor.Controls> is mounted while <Editor.Canvas> still has floatingToolbar={true} (the default) — both contextual zones are armed, and the floating toolbar is suppressed only as a side effect of the docked Controls being mounted this frame (it silently reappears when the Controls unmounts).",
|
|
279
301
|
fix: 'Declare contextual-zone ownership in the type surface: pass floatingToolbar={false} on <Editor.Canvas> when a <Editor.Controls placement="docked"> owns the zone.'
|
|
280
302
|
});
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
283
|
-
const
|
|
284
|
-
|
|
303
|
+
const d = (n == null ? void 0 : n.mockupIds) ?? [];
|
|
304
|
+
if (d.length > 1) {
|
|
305
|
+
const m = i.filter((E) => E.name === "Editor.Preview" && E.meta.mockupId === void 0);
|
|
306
|
+
m.length > 0 && r.push({
|
|
285
307
|
code: "A_PREVIEW_AMBIGUOUS",
|
|
286
308
|
severity: "warn",
|
|
287
|
-
message: `${
|
|
288
|
-
fix: `Pin each <Editor.Preview> to a scene: mockupId="${
|
|
309
|
+
message: `${m.length} <Editor.Preview> part${m.length === 1 ? " has" : "s have"} no mockupId while the product renders ${d.length} mockup scenes [${d.join(", ")}] — each shows whichever scene renders first, an ambiguous fan-out.`,
|
|
310
|
+
fix: `Pin each <Editor.Preview> to a scene: mockupId="${d[0]}" (one of product.mockupIds).`
|
|
289
311
|
});
|
|
290
312
|
}
|
|
291
|
-
const a = i.some((
|
|
313
|
+
const a = i.some((m) => m.name === "Editor.Buy");
|
|
292
314
|
if (s.length > 0 && !a) {
|
|
293
|
-
const
|
|
315
|
+
const m = s.map((E) => E.name);
|
|
294
316
|
r.push({
|
|
295
317
|
code: "A_NO_BUY",
|
|
296
318
|
severity: "info",
|
|
297
|
-
message: `<Editor.TextField> parts are mounted (layers [${
|
|
319
|
+
message: `<Editor.TextField> parts are mounted (layers [${m.join(", ")}]) but no <Editor.Buy> — personalization has no commerce gate, so nothing enforces completeness (C2/C3) before the design is bought.`,
|
|
298
320
|
fix: "Mount <Editor.Buy onAddToCart={…}/> under the same <Editor.Root> (it assembles the payload and gates on completeness), or ignore if this composition is deliberately non-commerce."
|
|
299
321
|
});
|
|
300
322
|
}
|
|
301
|
-
const
|
|
302
|
-
for (const
|
|
303
|
-
t.layerKindOf(
|
|
323
|
+
const u = [];
|
|
324
|
+
for (const m of s)
|
|
325
|
+
t.layerKindOf(m.name) === void 0 ? r.push({
|
|
304
326
|
code: "A_LAYER_UNMATCHED",
|
|
305
327
|
severity: "error",
|
|
306
|
-
message: `<Editor.TextField layer={design.layer("${
|
|
307
|
-
fix: `Restore a text layer named "${
|
|
308
|
-
}) :
|
|
309
|
-
const
|
|
310
|
-
if (
|
|
311
|
-
const
|
|
328
|
+
message: `<Editor.TextField layer={design.layer("${m.name}")}> matches zero elements in the current design state — the layer was removed or renamed after the field mounted, so the binding is dead and writes will fail. Bindable layers now: ${JSON.stringify(t.bindableLayerNames())}.`,
|
|
329
|
+
fix: `Restore a text layer named "${m.name}" to the design, or bind the field to an existing layer: layer={design.layer(<one of ${JSON.stringify(t.bindableLayerNames())}>)}.`
|
|
330
|
+
}) : u.push(m);
|
|
331
|
+
const c = u.filter((m) => !m.optional);
|
|
332
|
+
if (c.length > 0 && c.every((m) => t.textOf(m.name) === t.seedTextOf(m.name))) {
|
|
333
|
+
const m = c.map((E) => E.name);
|
|
312
334
|
r.push({
|
|
313
335
|
code: "A_TEXT_AT_SEED",
|
|
314
336
|
severity: "info",
|
|
315
|
-
message: `every required <Editor.TextField> still equals its seed value (layers [${
|
|
337
|
+
message: `every required <Editor.TextField> still equals its seed value (layers [${m.join(", ")}]) — <Editor.Buy>'s completeness rule C3 gates checkout until the shopper's text differs from the seed (placeholder text must not be bought).`,
|
|
316
338
|
fix: "Nothing to change for a fresh mount — this clears when the shopper edits the fields. For a field that should NOT gate Buy, pass optional on that <Editor.TextField>."
|
|
317
339
|
});
|
|
318
340
|
}
|
|
@@ -323,40 +345,40 @@ function De({ registry: e, store: t, product: n }) {
|
|
|
323
345
|
fix: "Seed content on the builder passed to <Editor.Root design={…}> — design({…}).text(…)/.background(…)/.shape(…) — or add elements through <Editor.Add>."
|
|
324
346
|
});
|
|
325
347
|
const b = /* @__PURE__ */ new Map();
|
|
326
|
-
for (const
|
|
327
|
-
const
|
|
328
|
-
return { findings: r, parts:
|
|
348
|
+
for (const m of i) b.set(m.name, (b.get(m.name) ?? 0) + 1);
|
|
349
|
+
const x = [...b.entries()].map(([m, E]) => ({ name: m, count: E })).sort((m, E) => m.name.localeCompare(E.name));
|
|
350
|
+
return { findings: r, parts: x };
|
|
329
351
|
}
|
|
330
|
-
const
|
|
331
|
-
function
|
|
332
|
-
return
|
|
333
|
-
const t =
|
|
334
|
-
t !== -1 &&
|
|
352
|
+
const ie = [];
|
|
353
|
+
function Dt(e) {
|
|
354
|
+
return ie.push(e), () => {
|
|
355
|
+
const t = ie.indexOf(e);
|
|
356
|
+
t !== -1 && ie.splice(t, 1);
|
|
335
357
|
};
|
|
336
358
|
}
|
|
337
|
-
function
|
|
338
|
-
const e =
|
|
359
|
+
function $n() {
|
|
360
|
+
const e = ie[ie.length - 1];
|
|
339
361
|
if (!e)
|
|
340
|
-
throw new
|
|
362
|
+
throw new S(
|
|
341
363
|
"E_AUDIT_NO_ROOT",
|
|
342
364
|
"auditEditor() found no mounted <Editor.Root>. Mount a Root first — or, to audit at mount time, pass onAudit on the Root: <Editor.Root onAudit={(report) => …}>.",
|
|
343
365
|
{ docSlug: "embed-mode" }
|
|
344
366
|
);
|
|
345
367
|
return e.compute();
|
|
346
368
|
}
|
|
347
|
-
const
|
|
348
|
-
function
|
|
349
|
-
return `[RealtimeEmbed] No mockup after ${Math.round(
|
|
369
|
+
const je = 8e3;
|
|
370
|
+
function Bt(e) {
|
|
371
|
+
return `[RealtimeEmbed] No mockup after ${Math.round(je / 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.`;
|
|
350
372
|
}
|
|
351
|
-
function
|
|
373
|
+
function Ut(e) {
|
|
352
374
|
if ("grantUrl" in e && e.grantUrl)
|
|
353
375
|
return { grantUrl: e.grantUrl };
|
|
354
376
|
const t = e.grant;
|
|
355
377
|
return typeof t == "function" ? { getToken: t } : { getToken: () => Promise.resolve(t) };
|
|
356
378
|
}
|
|
357
|
-
function
|
|
358
|
-
const n =
|
|
359
|
-
return /* @__PURE__ */
|
|
379
|
+
function Me({ error: e, onRetry: t }) {
|
|
380
|
+
const n = Te(e) ? e.code : "EDITOR_ERROR";
|
|
381
|
+
return /* @__PURE__ */ U(
|
|
360
382
|
"div",
|
|
361
383
|
{
|
|
362
384
|
"data-sc-part": "error",
|
|
@@ -372,12 +394,12 @@ function Le({ error: e, onRetry: t }) {
|
|
|
372
394
|
lineHeight: 1.5
|
|
373
395
|
},
|
|
374
396
|
children: [
|
|
375
|
-
/* @__PURE__ */
|
|
397
|
+
/* @__PURE__ */ U("p", { style: { margin: 0, fontWeight: 700 }, children: [
|
|
376
398
|
"Editor failed: ",
|
|
377
399
|
n
|
|
378
400
|
] }),
|
|
379
|
-
/* @__PURE__ */
|
|
380
|
-
t ? /* @__PURE__ */
|
|
401
|
+
/* @__PURE__ */ g("p", { style: { margin: "4px 0 0" }, children: e.message }),
|
|
402
|
+
t ? /* @__PURE__ */ g(
|
|
381
403
|
"button",
|
|
382
404
|
{
|
|
383
405
|
type: "button",
|
|
@@ -401,7 +423,7 @@ function Le({ error: e, onRetry: t }) {
|
|
|
401
423
|
}
|
|
402
424
|
);
|
|
403
425
|
}
|
|
404
|
-
class
|
|
426
|
+
class Lt extends mt {
|
|
405
427
|
constructor() {
|
|
406
428
|
super(...arguments), this.state = { caught: null };
|
|
407
429
|
}
|
|
@@ -410,20 +432,20 @@ class Nt extends st {
|
|
|
410
432
|
}
|
|
411
433
|
componentDidCatch(t) {
|
|
412
434
|
var n;
|
|
413
|
-
|
|
435
|
+
vt(t), typeof z < "u" && ((n = z.env) == null ? void 0 : n.NODE_ENV) !== "production" && console.error("[Editor.Root] contained a composition error:", t);
|
|
414
436
|
}
|
|
415
437
|
render() {
|
|
416
|
-
return this.state.caught ? /* @__PURE__ */
|
|
438
|
+
return this.state.caught ? /* @__PURE__ */ g(Me, { error: this.state.caught }) : this.props.children;
|
|
417
439
|
}
|
|
418
440
|
}
|
|
419
|
-
function
|
|
441
|
+
function Ft({ reportedError: e, onRetry: t, children: n }) {
|
|
420
442
|
if (e) {
|
|
421
|
-
const r =
|
|
422
|
-
return /* @__PURE__ */
|
|
443
|
+
const r = Te(e) && e.code === "E_CHUNK_LOAD_FAILED";
|
|
444
|
+
return /* @__PURE__ */ g(Me, { error: e, onRetry: r ? t : void 0 });
|
|
423
445
|
}
|
|
424
|
-
return /* @__PURE__ */
|
|
446
|
+
return /* @__PURE__ */ g(Lt, { reportedError: null, onRetry: t, children: n });
|
|
425
447
|
}
|
|
426
|
-
function
|
|
448
|
+
function Vt(e) {
|
|
427
449
|
const {
|
|
428
450
|
shop: t,
|
|
429
451
|
product: n,
|
|
@@ -432,251 +454,284 @@ function Tt(e) {
|
|
|
432
454
|
onMockups: s,
|
|
433
455
|
onRenderError: o,
|
|
434
456
|
onIssue: l,
|
|
435
|
-
wsUrl:
|
|
457
|
+
wsUrl: d,
|
|
436
458
|
services: a,
|
|
437
|
-
children:
|
|
438
|
-
internals:
|
|
459
|
+
children: u,
|
|
460
|
+
internals: c,
|
|
439
461
|
recordAudit: b,
|
|
440
|
-
__validation:
|
|
441
|
-
} = e,
|
|
442
|
-
() => (
|
|
443
|
-
|
|
444
|
-
|
|
462
|
+
__validation: x = "throw"
|
|
463
|
+
} = e, m = A(() => r.toJSON().activeArtboard, [r]), y = J(c.store.subscribe, c.store.getState, c.store.getState).artboards.map((f) => f.name).join("\0"), p = A(
|
|
464
|
+
() => y ? y.split("\0") : [],
|
|
465
|
+
[y]
|
|
466
|
+
), O = JSON.stringify(pe(n)), v = A(() => JSON.parse(O), [O]), [B, N] = D(null), _ = B && B.design === r ? B.label : m, F = A(
|
|
467
|
+
() => (f) => {
|
|
468
|
+
const k = [.../* @__PURE__ */ new Set([...v, ...p])];
|
|
469
|
+
if (!k.includes(f))
|
|
470
|
+
throw new S(
|
|
445
471
|
"E_UNKNOWN_PLACEMENT",
|
|
446
|
-
`no placement "${
|
|
447
|
-
{ placement:
|
|
472
|
+
`no placement "${f}" — the product's placements are ${JSON.stringify(v)} and the design's artboards are ${JSON.stringify(p)} (ADR-0088 / ADR-0101).`,
|
|
473
|
+
{ placement: f, validNames: k, docSlug: "embed-mode" }
|
|
448
474
|
);
|
|
449
|
-
|
|
475
|
+
const R = p[0] ?? f;
|
|
476
|
+
N({ design: r, label: p.includes(f) ? f : R });
|
|
477
|
+
},
|
|
478
|
+
[r, p, v]
|
|
479
|
+
), h = C(null), $ = A(
|
|
480
|
+
() => (f) => {
|
|
481
|
+
var k;
|
|
482
|
+
if (!v.includes(f) && !p.includes(f))
|
|
483
|
+
throw new S(
|
|
484
|
+
"E_UNKNOWN_PLACEMENT",
|
|
485
|
+
`cannot split "${f}" — the product's placements are ${JSON.stringify(v)} (ADR-0101).`,
|
|
486
|
+
{ placement: f, validNames: v, docSlug: "embed-mode" }
|
|
487
|
+
);
|
|
488
|
+
if (!p.includes(f)) {
|
|
489
|
+
const R = c.registry.getCanvasBridge();
|
|
490
|
+
R ? R.splitArtboard(f) : (c.store.splitArtboard(f), (k = h.current) == null || k.call(h, ee(c.store.getState())));
|
|
491
|
+
}
|
|
492
|
+
N({ design: r, label: f });
|
|
450
493
|
},
|
|
451
|
-
[r, v]
|
|
452
|
-
),
|
|
453
|
-
|
|
454
|
-
|
|
494
|
+
[r, p, v, c]
|
|
495
|
+
), V = A(
|
|
496
|
+
() => (f) => {
|
|
497
|
+
var P;
|
|
498
|
+
const k = p[0];
|
|
499
|
+
if (f === k)
|
|
500
|
+
throw new S(
|
|
501
|
+
"E_LINK_BASE",
|
|
502
|
+
`"${f}" is the base artboard — every linked placement inherits it, so it cannot be re-linked. Link a split placement instead, or call linkAll(). Artboards: ${JSON.stringify(p)}.`,
|
|
503
|
+
{ artboardName: f, validNames: p.slice(1), docSlug: "embed-mode" }
|
|
504
|
+
);
|
|
505
|
+
if (!p.includes(f)) return;
|
|
506
|
+
const R = c.registry.getCanvasBridge();
|
|
507
|
+
R ? R.removeArtboard(f) : (c.store.removeArtboard(f), (P = h.current) == null || P.call(h, ee(c.store.getState()))), _ === f && k && N({ design: r, label: k });
|
|
508
|
+
},
|
|
509
|
+
[r, p, c, _]
|
|
510
|
+
), T = A(() => {
|
|
511
|
+
const f = r.toJSON().artboards[0];
|
|
512
|
+
if (f)
|
|
455
513
|
return {
|
|
456
|
-
name:
|
|
457
|
-
width:
|
|
458
|
-
height:
|
|
459
|
-
...
|
|
514
|
+
name: f.name,
|
|
515
|
+
width: f.width,
|
|
516
|
+
height: f.height,
|
|
517
|
+
...f.backgroundColor ? { backgroundColor: f.backgroundColor } : {}
|
|
460
518
|
};
|
|
461
519
|
}, [r]);
|
|
462
520
|
J(
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
521
|
+
c.commerce.subscribe,
|
|
522
|
+
c.commerce.getVersion,
|
|
523
|
+
c.commerce.getVersion
|
|
466
524
|
);
|
|
467
|
-
const
|
|
468
|
-
if (!
|
|
469
|
-
const
|
|
470
|
-
return
|
|
471
|
-
}, [
|
|
472
|
-
|
|
473
|
-
const [
|
|
474
|
-
var
|
|
475
|
-
const
|
|
476
|
-
if (
|
|
477
|
-
const
|
|
478
|
-
if (
|
|
479
|
-
throw new
|
|
480
|
-
issue:
|
|
525
|
+
const j = c.commerce.renderVariantId(), M = Et(j ?? n.variantId ?? n.defaultGvid), K = A(() => {
|
|
526
|
+
if (!M) return null;
|
|
527
|
+
const f = r.toJSON().artboards, k = f.find((R) => R.name === _) ?? f[0];
|
|
528
|
+
return kt(M, k) ?? null;
|
|
529
|
+
}, [M, r, _]), X = C(s), w = C(o), Q = C(l);
|
|
530
|
+
X.current = s, w.current = o, Q.current = l;
|
|
531
|
+
const [ke, He] = D([]), [de, ne] = D(!0), [xe, le] = D(null), fe = !!("grantUrl" in e && e.grantUrl || "grant" in e && e.grant), he = Ut(e), Je = "grantUrl" in he ? he.grantUrl : "getToken", Se = `${n.productId}|${n.mockupIds.join(",")}|${n.variantId ?? ""}`, re = n.picks || n.variants ? JSON.stringify([n.picks ?? null, n.variants ?? null]) : "", Y = `${t}|${Se}|${re}|${m}|${fe}`, ge = A(() => {
|
|
532
|
+
var R;
|
|
533
|
+
const f = Le({ shop: t, product: n, design: r, hasGrant: fe });
|
|
534
|
+
if (x !== "throw") return f;
|
|
535
|
+
const k = f.find((P) => P.severity === "error");
|
|
536
|
+
if (k)
|
|
537
|
+
throw new S("E_EMBED_CONFIG", k.message, {
|
|
538
|
+
issue: k.issue,
|
|
481
539
|
docSlug: "embed-mode"
|
|
482
540
|
});
|
|
483
|
-
for (const
|
|
484
|
-
typeof
|
|
485
|
-
return
|
|
486
|
-
}, [
|
|
487
|
-
|
|
488
|
-
var
|
|
489
|
-
if (
|
|
490
|
-
|
|
491
|
-
for (const
|
|
541
|
+
for (const P of f)
|
|
542
|
+
typeof z < "u" && ((R = z.env) == null ? void 0 : R.NODE_ENV) !== "production" && console.warn(`[Editor.Root] ${P.message}`);
|
|
543
|
+
return f;
|
|
544
|
+
}, [Y, x]), Re = C(null);
|
|
545
|
+
L(() => {
|
|
546
|
+
var f;
|
|
547
|
+
if (ge.length !== 0 && Re.current !== Y) {
|
|
548
|
+
Re.current = Y;
|
|
549
|
+
for (const k of ge) (f = Q.current) == null || f.call(Q, k);
|
|
492
550
|
}
|
|
493
|
-
}, [
|
|
494
|
-
const
|
|
495
|
-
|
|
496
|
-
var
|
|
497
|
-
if (
|
|
498
|
-
if (
|
|
499
|
-
|
|
551
|
+
}, [ge, Y]);
|
|
552
|
+
const Ie = C(null);
|
|
553
|
+
L(() => {
|
|
554
|
+
var f;
|
|
555
|
+
if (x === "warn" && typeof z < "u" && ((f = z.env) == null ? void 0 : f.NODE_ENV) !== "production") {
|
|
556
|
+
if (Ie.current === Y) return;
|
|
557
|
+
Ie.current = Y, At({ shop: t, product: n, design: r, hasGrant: fe });
|
|
500
558
|
}
|
|
501
|
-
}, [
|
|
502
|
-
const
|
|
559
|
+
}, [Y, x]);
|
|
560
|
+
const ce = A(
|
|
503
561
|
() => {
|
|
504
562
|
try {
|
|
505
|
-
return { session: new
|
|
506
|
-
} catch (
|
|
507
|
-
return { error:
|
|
563
|
+
return { session: new ht({ shop: t, product: n, wsUrl: d, ...he }) };
|
|
564
|
+
} catch (f) {
|
|
565
|
+
return { error: f instanceof Error ? f.message : String(f) };
|
|
508
566
|
}
|
|
509
567
|
},
|
|
510
568
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
511
|
-
[t,
|
|
512
|
-
),
|
|
513
|
-
if (!
|
|
514
|
-
|
|
515
|
-
const
|
|
516
|
-
var
|
|
517
|
-
const
|
|
518
|
-
|
|
519
|
-
},
|
|
520
|
-
if (
|
|
521
|
-
for (const
|
|
522
|
-
|
|
569
|
+
[t, Se, m, d, Je]
|
|
570
|
+
), I = "session" in ce ? ce.session : null, ue = "error" in ce ? ce.error : null, Z = A(() => (f, k = i) => {
|
|
571
|
+
if (!I) return;
|
|
572
|
+
le(null), ne(!0);
|
|
573
|
+
const R = (q) => {
|
|
574
|
+
var Ne;
|
|
575
|
+
const me = q instanceof Error ? q.message : String(q);
|
|
576
|
+
le(me), ne(!1), (Ne = w.current) == null || Ne.call(w, me);
|
|
577
|
+
}, P = (q, me) => void I.renderState(q, { schemaVersion: f.schemaVersion, artboards: [me] }, k).catch(R), Ce = Ve(f, pe(n)).artboards ?? [];
|
|
578
|
+
if (Ce.length > 1) {
|
|
579
|
+
for (const q of Ce)
|
|
580
|
+
P(typeof q.name == "string" && q.name ? q.name : m, q);
|
|
523
581
|
return;
|
|
524
582
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
583
|
+
I.renderState(m, f, k).catch(R);
|
|
584
|
+
}, [I, m, n, i]);
|
|
585
|
+
h.current = Z, L(() => {
|
|
586
|
+
var f;
|
|
587
|
+
if (ue) {
|
|
588
|
+
le(ue), ne(!1), (f = w.current) == null || f.call(w, ue);
|
|
529
589
|
return;
|
|
530
590
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
var B;
|
|
542
|
-
Y($), M(!1), (B = m.current) == null || B.call(m, $);
|
|
543
|
-
}), x.onError(($) => {
|
|
544
|
-
var B;
|
|
545
|
-
w($), M(!1), (B = R.current) == null || B.call(R, $);
|
|
546
|
-
}), Z(r.toServerRequest()), () => x.close();
|
|
547
|
-
}, [x, oe]);
|
|
548
|
-
const me = O({
|
|
591
|
+
if (I)
|
|
592
|
+
return I.onMockups((k) => {
|
|
593
|
+
var R;
|
|
594
|
+
He(k), ne(!1), (R = X.current) == null || R.call(X, k);
|
|
595
|
+
}), I.onError((k) => {
|
|
596
|
+
var R;
|
|
597
|
+
le(k), ne(!1), (R = w.current) == null || R.call(w, k);
|
|
598
|
+
}), Z(r.toServerRequest()), () => I.close();
|
|
599
|
+
}, [I, ue]);
|
|
600
|
+
const ye = C({
|
|
549
601
|
session: null,
|
|
550
602
|
variantId: void 0
|
|
551
603
|
});
|
|
552
|
-
|
|
553
|
-
if (!
|
|
554
|
-
const
|
|
555
|
-
if (
|
|
556
|
-
|
|
604
|
+
L(() => {
|
|
605
|
+
if (!I || !j) return;
|
|
606
|
+
const f = ye.current, k = f.session === I ? f.variantId : n.variantId;
|
|
607
|
+
if (j === k) {
|
|
608
|
+
ye.current = { session: I, variantId: k };
|
|
557
609
|
return;
|
|
558
610
|
}
|
|
559
|
-
|
|
560
|
-
}, [
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
if (!
|
|
564
|
-
const
|
|
565
|
-
if (
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
}, [
|
|
569
|
-
if (!
|
|
570
|
-
const
|
|
571
|
-
var
|
|
572
|
-
const
|
|
573
|
-
typeof
|
|
574
|
-
},
|
|
575
|
-
return () => clearTimeout(
|
|
576
|
-
}, [
|
|
577
|
-
const
|
|
611
|
+
ye.current = { session: I, variantId: j }, I.setProduct({ ...n, variantId: j }), Z(ee(c.store.getState()));
|
|
612
|
+
}, [I, j]);
|
|
613
|
+
const Oe = C({ session: null, key: "" });
|
|
614
|
+
L(() => {
|
|
615
|
+
if (!I || !re) return;
|
|
616
|
+
const f = Oe.current;
|
|
617
|
+
if (f.session === I && f.key === re) return;
|
|
618
|
+
const k = f.session !== I;
|
|
619
|
+
Oe.current = { session: I, key: re }, !k && (I.setProduct(n), Z(ee(c.store.getState())));
|
|
620
|
+
}, [I, re]), L(() => {
|
|
621
|
+
if (!de) return;
|
|
622
|
+
const f = setTimeout(() => {
|
|
623
|
+
var R, P;
|
|
624
|
+
const k = Bt(m);
|
|
625
|
+
typeof z < "u" && ((R = z.env) == null ? void 0 : R.NODE_ENV) !== "production" && console.warn(k), (P = Q.current) == null || P.call(Q, { severity: "warn", issue: "slow-render", message: k });
|
|
626
|
+
}, je);
|
|
627
|
+
return () => clearTimeout(f);
|
|
628
|
+
}, [de, m]);
|
|
629
|
+
const Qe = A(
|
|
578
630
|
() => ({
|
|
579
|
-
session:
|
|
631
|
+
session: I,
|
|
580
632
|
design: r,
|
|
581
633
|
// The ACTIVE placement (ADR-0088): Editor.Canvas follows it as its
|
|
582
634
|
// controlled artboard; single-placement designs never see it move.
|
|
583
|
-
placement:
|
|
584
|
-
placements:
|
|
585
|
-
selectPlacement:
|
|
635
|
+
placement: _,
|
|
636
|
+
placements: p,
|
|
637
|
+
selectPlacement: F,
|
|
638
|
+
requiredPlacements: v,
|
|
639
|
+
splitPlacement: $,
|
|
640
|
+
linkPlacement: V,
|
|
586
641
|
product: n,
|
|
587
|
-
mockups:
|
|
588
|
-
isRendering:
|
|
589
|
-
error:
|
|
642
|
+
mockups: ke,
|
|
643
|
+
isRendering: de,
|
|
644
|
+
error: xe,
|
|
590
645
|
throttleMs: i,
|
|
591
|
-
pieceGuides:
|
|
646
|
+
pieceGuides: K,
|
|
592
647
|
pushRender: Z,
|
|
593
|
-
stateStore:
|
|
648
|
+
stateStore: c.store
|
|
594
649
|
}),
|
|
595
|
-
[
|
|
596
|
-
),
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
650
|
+
[I, r, _, p, F, v, $, V, n, ke, de, xe, i, K, Z, c.store]
|
|
651
|
+
), Ye = J(
|
|
652
|
+
c.registry.subscribe,
|
|
653
|
+
c.registry.getVersion,
|
|
654
|
+
c.registry.getVersion
|
|
600
655
|
);
|
|
601
|
-
|
|
656
|
+
A(() => {
|
|
602
657
|
b(
|
|
603
|
-
|
|
604
|
-
),
|
|
605
|
-
}, [
|
|
606
|
-
const
|
|
607
|
-
|
|
658
|
+
Pe({ registry: c.registry, store: c.store, product: n })
|
|
659
|
+
), c.registry.validate();
|
|
660
|
+
}, [c.registry, Ye]);
|
|
661
|
+
const $e = /* @__PURE__ */ g(et.Provider, { value: c, children: /* @__PURE__ */ g(Be.Provider, { value: Qe, children: /* @__PURE__ */ g(yt.Provider, { value: c.registry, children: /* @__PURE__ */ g(
|
|
662
|
+
bt,
|
|
608
663
|
{
|
|
609
|
-
...
|
|
610
|
-
children:
|
|
664
|
+
...T ? { initialArtboardConfig: T } : {},
|
|
665
|
+
children: u
|
|
611
666
|
}
|
|
612
667
|
) }) }) });
|
|
613
|
-
return a ? /* @__PURE__ */
|
|
668
|
+
return a ? /* @__PURE__ */ g(tt, { services: a, children: $e }) : $e;
|
|
614
669
|
}
|
|
615
|
-
function
|
|
616
|
-
const { design: t, product: n, onAudit: r } = e, i = `${n.productId}|${n.variantId ?? ""}`, s =
|
|
670
|
+
function qe(e) {
|
|
671
|
+
const { design: t, product: n, onAudit: r } = e, i = `${n.productId}|${n.variantId ?? ""}`, s = C(null), o = C(null), [l, d] = D(null);
|
|
617
672
|
(s.current === null || s.current.design !== t) && (s.current = {
|
|
618
673
|
design: t,
|
|
619
674
|
internals: {
|
|
620
|
-
store: new
|
|
621
|
-
registry: new
|
|
675
|
+
store: new xt(t.toJSON()),
|
|
676
|
+
registry: new Xe()
|
|
622
677
|
}
|
|
623
|
-
}), (o.current === null || o.current.productIdentity !== i) && (o.current = { productIdentity: i, commerce: new
|
|
624
|
-
const a =
|
|
678
|
+
}), (o.current === null || o.current.productIdentity !== i) && (o.current = { productIdentity: i, commerce: new St(n) });
|
|
679
|
+
const a = A(
|
|
625
680
|
() => ({
|
|
626
681
|
...s.current.internals,
|
|
627
682
|
commerce: o.current.commerce,
|
|
628
|
-
...
|
|
683
|
+
...Ze(d)
|
|
629
684
|
}),
|
|
630
685
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
631
686
|
[s.current.internals, o.current.commerce]
|
|
632
|
-
),
|
|
633
|
-
|
|
634
|
-
const
|
|
635
|
-
|
|
636
|
-
const b =
|
|
637
|
-
b.current =
|
|
638
|
-
}, []),
|
|
639
|
-
() =>
|
|
687
|
+
), u = C(n);
|
|
688
|
+
u.current = n;
|
|
689
|
+
const c = C(r);
|
|
690
|
+
c.current = r;
|
|
691
|
+
const b = C(null), x = G((y) => {
|
|
692
|
+
b.current = y;
|
|
693
|
+
}, []), m = G(
|
|
694
|
+
() => Pe({
|
|
640
695
|
registry: s.current.internals.registry,
|
|
641
696
|
store: s.current.internals.store,
|
|
642
|
-
product:
|
|
697
|
+
product: u.current
|
|
643
698
|
}),
|
|
644
699
|
[]
|
|
645
700
|
);
|
|
646
|
-
|
|
647
|
-
const
|
|
648
|
-
return
|
|
649
|
-
let
|
|
701
|
+
ae(() => Dt({ compute: m }), [m]);
|
|
702
|
+
const E = C(!1);
|
|
703
|
+
return L(() => {
|
|
704
|
+
let y = !1;
|
|
650
705
|
return queueMicrotask(() => {
|
|
651
|
-
var
|
|
652
|
-
|
|
706
|
+
var p;
|
|
707
|
+
y || E.current || (E.current = !0, (p = c.current) == null || p.call(c, b.current ?? m()));
|
|
653
708
|
}), () => {
|
|
654
|
-
|
|
709
|
+
y = !0;
|
|
655
710
|
};
|
|
656
|
-
}, [
|
|
711
|
+
}, [m]), // `display: contents` — the .sc-root scope without a layout box, so the
|
|
657
712
|
// host's grid/flex sees the parts directly (and the legacy RealtimeEmbed
|
|
658
713
|
// wrapper, which had no DOM at all, stays layout-identical).
|
|
659
|
-
/* @__PURE__ */
|
|
714
|
+
/* @__PURE__ */ g("div", { className: "sc-root", style: { display: "contents" }, "data-sc-part": "root", children: /* @__PURE__ */ g(Ft, { reportedError: l, onRetry: () => d(null), children: /* @__PURE__ */ g(Vt, { ...e, internals: a, recordAudit: x }) }) });
|
|
660
715
|
}
|
|
661
|
-
let
|
|
662
|
-
function
|
|
663
|
-
return
|
|
716
|
+
let Pt = () => import("./EditorCanvasImpl-BnxEbr2p.js").then((e) => e.EditorCanvasImpl);
|
|
717
|
+
function ze() {
|
|
718
|
+
return Pt();
|
|
664
719
|
}
|
|
665
|
-
const
|
|
666
|
-
const l =
|
|
667
|
-
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
const [a,
|
|
671
|
-
return
|
|
672
|
-
let
|
|
673
|
-
return
|
|
720
|
+
const jt = Ae(function({ children: t, maxHeight: n, floatingToolbar: r = !0, className: i, style: s }, o) {
|
|
721
|
+
const l = se("Editor.Canvas");
|
|
722
|
+
oe("Editor.Canvas", { floatingToolbar: r });
|
|
723
|
+
const d = we();
|
|
724
|
+
ae(() => l.registry.registerCanvas(d), [l.registry, d]);
|
|
725
|
+
const [a, u] = D(null);
|
|
726
|
+
return L(() => {
|
|
727
|
+
let c = !1;
|
|
728
|
+
return ze().then(
|
|
674
729
|
(b) => {
|
|
675
|
-
|
|
730
|
+
c || u(() => b);
|
|
676
731
|
},
|
|
677
732
|
(b) => {
|
|
678
|
-
|
|
679
|
-
new
|
|
733
|
+
c || l.reportRuntimeError(
|
|
734
|
+
new S(
|
|
680
735
|
"E_CHUNK_LOAD_FAILED",
|
|
681
736
|
`the editor's rendering chunk failed to load (${b instanceof Error ? b.message : String(b)}). This is a network/CDN failure, not a composition mistake — retry, or check the deployment serves the @snowcone-app/canvas lazy chunks.`,
|
|
682
737
|
{ cause: b instanceof Error ? b.message : String(b), docSlug: "embed-mode" }
|
|
@@ -684,14 +739,14 @@ const Dt = $e(function({ children: t, maxHeight: n, floatingToolbar: r = !0, cla
|
|
|
684
739
|
);
|
|
685
740
|
}
|
|
686
741
|
), () => {
|
|
687
|
-
|
|
742
|
+
c = !0;
|
|
688
743
|
};
|
|
689
744
|
}, [l]), a ? (
|
|
690
745
|
// `builtinControls`: the canvas owns the floating contextual toolbar
|
|
691
746
|
// unless the host opts out via `floatingToolbar={false}` or a docked
|
|
692
747
|
// <Editor.Controls> is mounted (ADR-0085 §5). Only here — the legacy
|
|
693
748
|
// <RealtimeCanvas> wrapper stays chrome-less.
|
|
694
|
-
/* @__PURE__ */
|
|
749
|
+
/* @__PURE__ */ g(
|
|
695
750
|
a,
|
|
696
751
|
{
|
|
697
752
|
ref: o,
|
|
@@ -704,7 +759,7 @@ const Dt = $e(function({ children: t, maxHeight: n, floatingToolbar: r = !0, cla
|
|
|
704
759
|
children: t
|
|
705
760
|
}
|
|
706
761
|
)
|
|
707
|
-
) : /* @__PURE__ */
|
|
762
|
+
) : /* @__PURE__ */ g(
|
|
708
763
|
"div",
|
|
709
764
|
{
|
|
710
765
|
"data-sc-part": "canvas",
|
|
@@ -715,55 +770,108 @@ const Dt = $e(function({ children: t, maxHeight: n, floatingToolbar: r = !0, cla
|
|
|
715
770
|
}
|
|
716
771
|
);
|
|
717
772
|
});
|
|
718
|
-
function
|
|
719
|
-
const { placements: e,
|
|
720
|
-
return
|
|
721
|
-
() => ({
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
}),
|
|
726
|
-
|
|
727
|
-
|
|
773
|
+
function Mt() {
|
|
774
|
+
const { placements: e, requiredPlacements: t, placement: n, selectPlacement: r, splitPlacement: i, linkPlacement: s } = te();
|
|
775
|
+
return A(() => {
|
|
776
|
+
const o = Fe(e, t), l = e[0] ?? n, d = o.map((u) => ({
|
|
777
|
+
label: u.label,
|
|
778
|
+
inherited: u.inherited,
|
|
779
|
+
active: u.inherited ? n === l : n === u.label
|
|
780
|
+
})), a = d.length > 1 && d.every((u) => u.inherited || u.label === l);
|
|
781
|
+
return {
|
|
782
|
+
placements: d,
|
|
783
|
+
activePlacement: n,
|
|
784
|
+
basePlacement: l,
|
|
785
|
+
linked: a,
|
|
786
|
+
select: r,
|
|
787
|
+
split: i,
|
|
788
|
+
link: s,
|
|
789
|
+
splitAll: () => {
|
|
790
|
+
for (const u of d) u.inherited && i(u.label);
|
|
791
|
+
},
|
|
792
|
+
linkAll: () => {
|
|
793
|
+
for (const u of d) !u.inherited && u.label !== l && s(u.label);
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
}, [e, t, n, r, i, s]);
|
|
728
797
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
798
|
+
const qt = (e) => e.length === 2 ? "Both sides" : `All ${e.length} areas`, zt = {
|
|
799
|
+
font: "inherit",
|
|
800
|
+
fontSize: "12px",
|
|
801
|
+
color: "var(--sc-color-muted-foreground, inherit)",
|
|
802
|
+
background: "transparent",
|
|
803
|
+
border: "none",
|
|
804
|
+
padding: "2px 8px",
|
|
805
|
+
cursor: "pointer",
|
|
806
|
+
textDecoration: "underline",
|
|
807
|
+
textUnderlineOffset: "4px"
|
|
808
|
+
};
|
|
809
|
+
function Kt({ className: e, style: t, labels: n }) {
|
|
810
|
+
const { placements: r, linked: i, select: s, splitAll: o, linkAll: l } = Mt();
|
|
811
|
+
if (r.length < 2) return null;
|
|
812
|
+
const d = r.map((a) => a.label);
|
|
813
|
+
return /* @__PURE__ */ U(
|
|
732
814
|
"div",
|
|
733
815
|
{
|
|
734
816
|
"data-sc-part": "placements",
|
|
817
|
+
"data-sc-linked": i ? "true" : "false",
|
|
735
818
|
className: e,
|
|
736
819
|
style: { display: "flex", alignItems: "center", gap: "4px", ...t },
|
|
737
|
-
children:
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
820
|
+
children: [
|
|
821
|
+
i ? /* @__PURE__ */ g(
|
|
822
|
+
"span",
|
|
823
|
+
{
|
|
824
|
+
"data-sc-part": "placements-item",
|
|
825
|
+
"data-sc-active": "true",
|
|
826
|
+
"data-sc-linked": "true",
|
|
827
|
+
title: d.join(" · "),
|
|
828
|
+
style: { fontSize: "13px", fontWeight: 700, padding: "2px 8px", color: "var(--sc-color-foreground, inherit)" },
|
|
829
|
+
children: ((n == null ? void 0 : n.linked) ?? qt)(d)
|
|
830
|
+
}
|
|
831
|
+
) : r.map(({ label: a, active: u, inherited: c }) => /* @__PURE__ */ g(
|
|
832
|
+
"button",
|
|
833
|
+
{
|
|
834
|
+
type: "button",
|
|
835
|
+
"data-sc-part": "placements-item",
|
|
836
|
+
"data-sc-active": u ? "true" : "false",
|
|
837
|
+
"data-sc-linked": c ? "true" : "false",
|
|
838
|
+
"aria-pressed": u,
|
|
839
|
+
onClick: () => s(a),
|
|
840
|
+
style: {
|
|
841
|
+
font: "inherit",
|
|
842
|
+
fontSize: "13px",
|
|
843
|
+
fontWeight: u ? 700 : 400,
|
|
844
|
+
color: "var(--sc-color-foreground, inherit)",
|
|
845
|
+
opacity: c ? 0.6 : 1,
|
|
846
|
+
background: "transparent",
|
|
847
|
+
border: "none",
|
|
848
|
+
borderRadius: "9999px",
|
|
849
|
+
padding: "2px 8px",
|
|
850
|
+
cursor: u ? "default" : "pointer",
|
|
851
|
+
textDecoration: u ? "underline" : "none",
|
|
852
|
+
textUnderlineOffset: "4px"
|
|
853
|
+
},
|
|
854
|
+
children: a
|
|
757
855
|
},
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
856
|
+
a
|
|
857
|
+
)),
|
|
858
|
+
/* @__PURE__ */ g(
|
|
859
|
+
"button",
|
|
860
|
+
{
|
|
861
|
+
type: "button",
|
|
862
|
+
"data-sc-part": "placements-link-toggle",
|
|
863
|
+
"data-sc-linked": i ? "true" : "false",
|
|
864
|
+
onClick: i ? o : l,
|
|
865
|
+
style: zt,
|
|
866
|
+
children: i ? (n == null ? void 0 : n.customizeSeparately) ?? "Customize separately" : (n == null ? void 0 : n.useOneDesign) ?? "Use one design for all"
|
|
867
|
+
}
|
|
868
|
+
)
|
|
869
|
+
]
|
|
762
870
|
}
|
|
763
871
|
);
|
|
764
872
|
}
|
|
765
|
-
const
|
|
766
|
-
function
|
|
873
|
+
const Gt = 200, Wt = 400;
|
|
874
|
+
function Ht() {
|
|
767
875
|
return Array.from({ length: 10 }, () => ({
|
|
768
876
|
left: 2 + Math.random() * 96,
|
|
769
877
|
top: 2 + Math.random() * 96,
|
|
@@ -772,10 +880,10 @@ function Vt() {
|
|
|
772
880
|
size: 3 + Math.random() * 5
|
|
773
881
|
}));
|
|
774
882
|
}
|
|
775
|
-
let
|
|
776
|
-
function
|
|
777
|
-
if (!(
|
|
778
|
-
|
|
883
|
+
let _e = !1;
|
|
884
|
+
function Jt() {
|
|
885
|
+
if (!(_e || typeof CSS > "u" || typeof CSS.registerProperty != "function")) {
|
|
886
|
+
_e = !0;
|
|
779
887
|
try {
|
|
780
888
|
CSS.registerProperty({ name: "--sc-prism-mount", syntax: "<number>", initialValue: "0", inherits: !0 });
|
|
781
889
|
} catch {
|
|
@@ -786,89 +894,89 @@ function jt() {
|
|
|
786
894
|
}
|
|
787
895
|
}
|
|
788
896
|
}
|
|
789
|
-
const
|
|
897
|
+
const Ke = pt(function({
|
|
790
898
|
visible: t = !0,
|
|
791
899
|
onExited: n,
|
|
792
900
|
variant: r = "dark"
|
|
793
901
|
}) {
|
|
794
|
-
|
|
795
|
-
const [i, s] =
|
|
796
|
-
|
|
797
|
-
s(
|
|
902
|
+
Jt();
|
|
903
|
+
const [i, s] = D([]);
|
|
904
|
+
L(() => {
|
|
905
|
+
s(Ht());
|
|
798
906
|
}, []);
|
|
799
|
-
const [o, l] =
|
|
800
|
-
|
|
801
|
-
const
|
|
802
|
-
return () => cancelAnimationFrame(
|
|
907
|
+
const [o, l] = D(!1);
|
|
908
|
+
L(() => {
|
|
909
|
+
const u = requestAnimationFrame(() => l(!0));
|
|
910
|
+
return () => cancelAnimationFrame(u);
|
|
803
911
|
}, []);
|
|
804
|
-
const
|
|
805
|
-
(
|
|
806
|
-
|
|
912
|
+
const d = G(
|
|
913
|
+
(u) => {
|
|
914
|
+
u.propertyName === "background-color" && (t || n == null || n());
|
|
807
915
|
},
|
|
808
916
|
[t, n]
|
|
809
917
|
);
|
|
810
918
|
let a = "";
|
|
811
|
-
return t ? o && (a = "sc-prism-fade-in") : a = "sc-prism-fade-out", /* @__PURE__ */
|
|
919
|
+
return t ? o && (a = "sc-prism-fade-in") : a = "sc-prism-fade-out", /* @__PURE__ */ U(
|
|
812
920
|
"div",
|
|
813
921
|
{
|
|
814
922
|
"data-sc-part": "preview-loading",
|
|
815
923
|
className: ["sc-prism-overlay", r === "light" ? "sc-prism-on-light" : "", a].filter(Boolean).join(" "),
|
|
816
|
-
onTransitionEnd:
|
|
924
|
+
onTransitionEnd: d,
|
|
817
925
|
"aria-hidden": "true",
|
|
818
926
|
children: [
|
|
819
|
-
Array.from({ length: 6 }, (
|
|
820
|
-
i.map((
|
|
927
|
+
Array.from({ length: 6 }, (u, c) => /* @__PURE__ */ g("div", { className: "sc-prism-band" }, `b-${c}`)),
|
|
928
|
+
i.map((u, c) => /* @__PURE__ */ g(
|
|
821
929
|
"div",
|
|
822
930
|
{
|
|
823
931
|
className: "sc-prism-particle",
|
|
824
932
|
style: {
|
|
825
|
-
left: `${
|
|
826
|
-
top: `${
|
|
827
|
-
animationDelay: `${
|
|
828
|
-
animationDuration: `${
|
|
829
|
-
width: `${
|
|
830
|
-
height: `${
|
|
933
|
+
left: `${u.left}%`,
|
|
934
|
+
top: `${u.top}%`,
|
|
935
|
+
animationDelay: `${u.delay}s`,
|
|
936
|
+
animationDuration: `${u.duration}s`,
|
|
937
|
+
width: `${u.size}px`,
|
|
938
|
+
height: `${u.size}px`
|
|
831
939
|
}
|
|
832
940
|
},
|
|
833
|
-
`p-${
|
|
941
|
+
`p-${c}`
|
|
834
942
|
))
|
|
835
943
|
]
|
|
836
944
|
}
|
|
837
945
|
);
|
|
838
946
|
});
|
|
839
|
-
function
|
|
840
|
-
const [t, n] =
|
|
841
|
-
l.current = t,
|
|
947
|
+
function Ge(e) {
|
|
948
|
+
const [t, n] = D(!1), [r, i] = D(!1), s = C(null), o = C(null), l = C(!1);
|
|
949
|
+
l.current = t, L(() => (e ? (i(!1), o.current && clearTimeout(o.current), s.current = setTimeout(() => n(!0), Gt)) : (s.current && (clearTimeout(s.current), s.current = null), l.current && (i(!0), o.current = setTimeout(() => i(!1), Wt))), () => {
|
|
842
950
|
s.current && clearTimeout(s.current), o.current && clearTimeout(o.current);
|
|
843
951
|
}), [e]);
|
|
844
|
-
const
|
|
952
|
+
const d = G(() => n(!1), []);
|
|
845
953
|
return {
|
|
846
954
|
showOverlay: t,
|
|
847
955
|
overlayVisible: e || r,
|
|
848
|
-
handleExited:
|
|
956
|
+
handleExited: d
|
|
849
957
|
};
|
|
850
958
|
}
|
|
851
|
-
const
|
|
852
|
-
function
|
|
853
|
-
for (const t of
|
|
959
|
+
const Qt = 1.2, be = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
|
|
960
|
+
function Yt(e) {
|
|
961
|
+
for (const t of be)
|
|
854
962
|
if (t >= e) return t;
|
|
855
|
-
return
|
|
963
|
+
return be[be.length - 1];
|
|
856
964
|
}
|
|
857
|
-
function
|
|
858
|
-
if (!(e > 0) || !(t > 0) || t <= e *
|
|
859
|
-
const n =
|
|
965
|
+
function Xt(e, t) {
|
|
966
|
+
if (!(e > 0) || !(t > 0) || t <= e * Qt) return null;
|
|
967
|
+
const n = Yt(t);
|
|
860
968
|
return `[RealtimeMockup] mockup rendered at ${e}px but displayed at ~${t} device px — the preview will look soft. Pass \`product.width\` (e.g. ${n}) on the embed for a crisp preview.`;
|
|
861
969
|
}
|
|
862
|
-
function
|
|
970
|
+
function Zt(e) {
|
|
863
971
|
if (e === void 0 || e === !0 || e === "dark") return "dark";
|
|
864
|
-
if (e === "light" || e === "host-owned" ||
|
|
865
|
-
throw new
|
|
972
|
+
if (e === "light" || e === "host-owned" || De(e)) return e;
|
|
973
|
+
throw new S(
|
|
866
974
|
"E_PREVIEW_NO_LOADER",
|
|
867
975
|
`Editor.Preview: invalid loadingOverlay value ${JSON.stringify(e)}. A mockup preview always has a render-in-flight treatment (the loader paints over the still-visible previous mockup). Omit the prop for the default rainbow overlay, pass "dark" | "light", pass a custom ReactElement, or declare "host-owned" if the host renders its own indicator off data-sc-preview-state / <Editor.LoadingOverlay>.`,
|
|
868
976
|
{ docSlug: "preview-loading-overlay" }
|
|
869
977
|
);
|
|
870
978
|
}
|
|
871
|
-
function
|
|
979
|
+
function We({
|
|
872
980
|
mockupId: e,
|
|
873
981
|
fallback: t = null,
|
|
874
982
|
alt: n = "Live product mockup",
|
|
@@ -876,73 +984,73 @@ function Me({
|
|
|
876
984
|
className: i,
|
|
877
985
|
style: s
|
|
878
986
|
}) {
|
|
879
|
-
const { mockups: o, error: l, isRendering:
|
|
880
|
-
|
|
881
|
-
const a =
|
|
882
|
-
b &&
|
|
883
|
-
),
|
|
884
|
-
var
|
|
885
|
-
if (!
|
|
886
|
-
const
|
|
887
|
-
if (
|
|
888
|
-
const
|
|
889
|
-
|
|
987
|
+
const { mockups: o, error: l, isRendering: d } = te();
|
|
988
|
+
oe("Editor.Preview", { ...e !== void 0 ? { mockupId: e } : {} });
|
|
989
|
+
const a = Zt(r), u = a === "dark" || a === "light" ? a : null, c = De(a) ? a : null, b = a !== "host-owned", { showOverlay: x, overlayVisible: m, handleExited: E } = Ge(
|
|
990
|
+
b && d
|
|
991
|
+
), y = C(/* @__PURE__ */ new Set()), p = e ? o.find((v) => v.mockupId === e && v.imageUrl) : o.find((v) => v.imageUrl), O = (v) => {
|
|
992
|
+
var h;
|
|
993
|
+
if (!p || typeof z > "u" || ((h = z.env) == null ? void 0 : h.NODE_ENV) === "production" || typeof window > "u" || y.current.has(p.mockupId)) return;
|
|
994
|
+
const B = v.currentTarget, N = B.getBoundingClientRect().width;
|
|
995
|
+
if (N <= 0) return;
|
|
996
|
+
const _ = Math.round(N * (window.devicePixelRatio || 1)), F = Xt(B.naturalWidth, _);
|
|
997
|
+
F && (y.current.add(p.mockupId), console.warn(F));
|
|
890
998
|
};
|
|
891
999
|
if (b) {
|
|
892
|
-
const
|
|
893
|
-
return /* @__PURE__ */
|
|
1000
|
+
const v = p != null && p.imageUrl ? d ? "rendering" : "ready" : l ? "error" : "rendering";
|
|
1001
|
+
return /* @__PURE__ */ U(
|
|
894
1002
|
"div",
|
|
895
1003
|
{
|
|
896
1004
|
"data-sc-part": "preview",
|
|
897
|
-
"data-sc-preview-state":
|
|
898
|
-
"aria-busy":
|
|
1005
|
+
"data-sc-preview-state": v,
|
|
1006
|
+
"aria-busy": v === "rendering" || void 0,
|
|
899
1007
|
className: `sc-preview-frame${i ? ` ${i}` : ""}`,
|
|
900
1008
|
style: s,
|
|
901
1009
|
children: [
|
|
902
|
-
|
|
1010
|
+
p != null && p.imageUrl ? (
|
|
903
1011
|
// eslint-disable-next-line @next/next/no-img-element
|
|
904
|
-
/* @__PURE__ */
|
|
905
|
-
) : l ? /* @__PURE__ */
|
|
906
|
-
|
|
1012
|
+
/* @__PURE__ */ g("img", { "data-sc-part": "preview-image", src: p.imageUrl, alt: n, onLoad: O })
|
|
1013
|
+
) : l ? /* @__PURE__ */ g("div", { "data-sc-part": "preview-error", role: "alert", "data-sc-error": l, children: t ?? `Render failed: ${l}` }) : t,
|
|
1014
|
+
c ? (
|
|
907
1015
|
// Custom indicator: same show-delay + linger window; no exit fade
|
|
908
1016
|
// (the host owns its animation), so it unmounts when the window
|
|
909
1017
|
// closes.
|
|
910
|
-
|
|
1018
|
+
x && m ? /* @__PURE__ */ g(
|
|
911
1019
|
"div",
|
|
912
1020
|
{
|
|
913
1021
|
"data-sc-part": "preview-loading",
|
|
914
1022
|
className: "sc-preview-custom-loading",
|
|
915
1023
|
"aria-hidden": "true",
|
|
916
|
-
children:
|
|
1024
|
+
children: c
|
|
917
1025
|
}
|
|
918
1026
|
) : null
|
|
919
|
-
) :
|
|
920
|
-
|
|
1027
|
+
) : x && u ? /* @__PURE__ */ g(
|
|
1028
|
+
Ke,
|
|
921
1029
|
{
|
|
922
|
-
visible:
|
|
923
|
-
variant:
|
|
924
|
-
onExited:
|
|
1030
|
+
visible: m,
|
|
1031
|
+
variant: u,
|
|
1032
|
+
onExited: E
|
|
925
1033
|
}
|
|
926
1034
|
) : null
|
|
927
1035
|
]
|
|
928
1036
|
}
|
|
929
1037
|
);
|
|
930
1038
|
}
|
|
931
|
-
return
|
|
1039
|
+
return p != null && p.imageUrl ? (
|
|
932
1040
|
// eslint-disable-next-line @next/next/no-img-element
|
|
933
|
-
/* @__PURE__ */
|
|
1041
|
+
/* @__PURE__ */ g(
|
|
934
1042
|
"img",
|
|
935
1043
|
{
|
|
936
1044
|
"data-sc-part": "preview",
|
|
937
|
-
"data-sc-preview-state":
|
|
938
|
-
src:
|
|
1045
|
+
"data-sc-preview-state": d ? "rendering" : "ready",
|
|
1046
|
+
src: p.imageUrl,
|
|
939
1047
|
alt: n,
|
|
940
1048
|
className: i,
|
|
941
1049
|
style: s,
|
|
942
|
-
onLoad:
|
|
1050
|
+
onLoad: O
|
|
943
1051
|
}
|
|
944
1052
|
)
|
|
945
|
-
) : l ? /* @__PURE__ */
|
|
1053
|
+
) : l ? /* @__PURE__ */ g(
|
|
946
1054
|
"div",
|
|
947
1055
|
{
|
|
948
1056
|
"data-sc-part": "preview-error",
|
|
@@ -953,45 +1061,45 @@ function Me({
|
|
|
953
1061
|
style: s,
|
|
954
1062
|
children: t ?? `Render failed: ${l}`
|
|
955
1063
|
}
|
|
956
|
-
) : /* @__PURE__ */
|
|
1064
|
+
) : /* @__PURE__ */ g("div", { "data-sc-part": "preview", "data-sc-preview-state": "rendering", "aria-busy": "true", style: { display: "contents" }, children: t });
|
|
957
1065
|
}
|
|
958
|
-
function
|
|
959
|
-
const { layer: t, optional: n = !1, placeholder: r, className: i, style: s } = e, o =
|
|
960
|
-
|
|
961
|
-
const { pushRender: l, throttleMs:
|
|
962
|
-
if (!
|
|
963
|
-
throw new
|
|
1066
|
+
function en(e) {
|
|
1067
|
+
const { layer: t, optional: n = !1, placeholder: r, className: i, style: s } = e, o = se("Editor.TextField");
|
|
1068
|
+
oe("Editor.TextField");
|
|
1069
|
+
const { pushRender: l, throttleMs: d, stateStore: a } = te(), u = we(), c = C(null);
|
|
1070
|
+
if (!wt(t))
|
|
1071
|
+
throw new S(
|
|
964
1072
|
"E_LAYER_TOKEN_REQUIRED",
|
|
965
1073
|
`the \`layer\` prop must be a token minted by the design — pass layer={design.layer("name")}, not ${typeof t == "string" ? `the bare string "${t}"` : "a plain value"}. Tokens validate the name against the design's layers at mint time.`,
|
|
966
1074
|
{ received: typeof t == "string" ? t : typeof t, docSlug: "embed-mode" }
|
|
967
1075
|
);
|
|
968
|
-
if (
|
|
969
|
-
const
|
|
970
|
-
if (
|
|
971
|
-
throw new
|
|
1076
|
+
if (c.current !== t.name) {
|
|
1077
|
+
const m = a.layerKindOf(t.name);
|
|
1078
|
+
if (m === void 0)
|
|
1079
|
+
throw new S(
|
|
972
1080
|
"E_LAYER_NOT_FOUND",
|
|
973
1081
|
`no layer "${t.name}" in this Root's design — the token was minted from a different design than the one passed to <Editor.Root design={…}>. Bindable layers here: ${JSON.stringify(a.bindableLayerNames())}.`,
|
|
974
1082
|
{ layerName: t.name, validNames: a.bindableLayerNames(), docSlug: "embed-mode" }
|
|
975
1083
|
);
|
|
976
|
-
if (
|
|
977
|
-
throw new
|
|
1084
|
+
if (m !== "text")
|
|
1085
|
+
throw new S(
|
|
978
1086
|
"E_LAYER_WRONG_KIND",
|
|
979
|
-
`layer "${t.name}" is ${
|
|
980
|
-
{ layerName: t.name, actualKind:
|
|
1087
|
+
`layer "${t.name}" is ${m === null ? "not a bindable kind" : `an ${m} layer`} — <Editor.TextField> binds text layers only.`,
|
|
1088
|
+
{ layerName: t.name, actualKind: m, docSlug: "embed-mode" }
|
|
981
1089
|
);
|
|
982
|
-
|
|
1090
|
+
c.current = t.name;
|
|
983
1091
|
}
|
|
984
|
-
|
|
1092
|
+
ae(() => o.registry.registerTextField(u, { name: t.name, optional: n }), [o.registry, u, t.name, n]);
|
|
985
1093
|
const b = J(
|
|
986
1094
|
a.subscribe,
|
|
987
1095
|
() => a.textOf(t.name) ?? "",
|
|
988
1096
|
() => a.textOf(t.name) ?? ""
|
|
989
|
-
),
|
|
990
|
-
(
|
|
991
|
-
const
|
|
992
|
-
if (
|
|
993
|
-
|
|
994
|
-
new
|
|
1097
|
+
), x = G(
|
|
1098
|
+
(m) => {
|
|
1099
|
+
const E = m.target.value, y = o.registry.getCanvasBridge();
|
|
1100
|
+
if (y) {
|
|
1101
|
+
y.setTextByName(t.name, E) || o.reportInvariant(
|
|
1102
|
+
new S(
|
|
995
1103
|
"E_LAYER_NOT_FOUND",
|
|
996
1104
|
`layer "${t.name}" no longer exists in the mounted canvas — it was removed or renamed after this <Editor.TextField> bound to it. Bound layers must not be renamed or deleted while a field is mounted (ADR-0085 §3).`,
|
|
997
1105
|
{ layerName: t.name, docSlug: "embed-mode" }
|
|
@@ -999,18 +1107,18 @@ function Kt(e) {
|
|
|
999
1107
|
);
|
|
1000
1108
|
return;
|
|
1001
1109
|
}
|
|
1002
|
-
a.updateTextLayer(t.name,
|
|
1110
|
+
a.updateTextLayer(t.name, E), l(ee(a.getState()), d);
|
|
1003
1111
|
},
|
|
1004
|
-
[o, t.name, a, l,
|
|
1112
|
+
[o, t.name, a, l, d]
|
|
1005
1113
|
);
|
|
1006
|
-
return /* @__PURE__ */
|
|
1114
|
+
return /* @__PURE__ */ g(
|
|
1007
1115
|
"input",
|
|
1008
1116
|
{
|
|
1009
1117
|
"data-sc-part": "textfield",
|
|
1010
1118
|
"data-sc-layer": t.name,
|
|
1011
1119
|
type: "text",
|
|
1012
1120
|
value: b,
|
|
1013
|
-
onChange:
|
|
1121
|
+
onChange: x,
|
|
1014
1122
|
placeholder: r,
|
|
1015
1123
|
"aria-label": e["aria-label"] ?? t.name,
|
|
1016
1124
|
className: i,
|
|
@@ -1018,7 +1126,7 @@ function Kt(e) {
|
|
|
1018
1126
|
}
|
|
1019
1127
|
);
|
|
1020
1128
|
}
|
|
1021
|
-
function
|
|
1129
|
+
function tn(e) {
|
|
1022
1130
|
const t = [];
|
|
1023
1131
|
for (const n of e.missingOptionKeys)
|
|
1024
1132
|
t.push(`option:${n}`);
|
|
@@ -1035,13 +1143,13 @@ function Gt(e) {
|
|
|
1035
1143
|
}
|
|
1036
1144
|
return e.hasRenderableElement || t.push("empty-design"), (!Number.isInteger(e.quantity) || e.quantity < 1) && t.push("quantity"), t;
|
|
1037
1145
|
}
|
|
1038
|
-
function
|
|
1146
|
+
function nn(e, t) {
|
|
1039
1147
|
const n = t.getCombinations(), r = t.getAttributes();
|
|
1040
1148
|
if (Object.keys(r).length === 0 || n.length === 0) return null;
|
|
1041
1149
|
const i = Object.fromEntries(
|
|
1042
|
-
Object.entries(r).map(([s, o]) => [s, { ...o, choices:
|
|
1150
|
+
Object.entries(r).map(([s, o]) => [s, { ...o, choices: Rt(o) }])
|
|
1043
1151
|
);
|
|
1044
|
-
return
|
|
1152
|
+
return gt({
|
|
1045
1153
|
productId: e.productId,
|
|
1046
1154
|
quantity: t.getQuantity(),
|
|
1047
1155
|
selection: t.getSelection(),
|
|
@@ -1049,97 +1157,103 @@ function Wt(e, t) {
|
|
|
1049
1157
|
attributes: i
|
|
1050
1158
|
});
|
|
1051
1159
|
}
|
|
1052
|
-
function
|
|
1053
|
-
const { onAddToCart: t, defaultQuantity: n, children: r, className: i, style: s } = e, o =
|
|
1054
|
-
|
|
1055
|
-
const { product: l, stateStore:
|
|
1160
|
+
function rn(e) {
|
|
1161
|
+
const { onAddToCart: t, defaultQuantity: n, children: r, className: i, style: s } = e, o = se("Editor.Buy");
|
|
1162
|
+
oe("Editor.Buy");
|
|
1163
|
+
const { product: l, stateStore: d } = te(), a = o.commerce;
|
|
1056
1164
|
if (!(l != null && l.productId))
|
|
1057
|
-
throw new
|
|
1165
|
+
throw new S(
|
|
1058
1166
|
"E_BUY_NO_PRODUCT",
|
|
1059
1167
|
"<Editor.Buy> has no product context — pass `product` (with `productId`) on <Editor.Root product={…}>. Buy assembles its cart payload from the Root product and the live design state.",
|
|
1060
1168
|
{ docSlug: "embed-mode" }
|
|
1061
1169
|
);
|
|
1062
|
-
const
|
|
1063
|
-
|
|
1064
|
-
|
|
1170
|
+
const u = C(!1);
|
|
1171
|
+
ae(() => {
|
|
1172
|
+
u.current || (u.current = !0, typeof n == "number" && a.setQuantity(n));
|
|
1065
1173
|
}, [a]);
|
|
1066
|
-
const
|
|
1174
|
+
const c = J(d.subscribe, d.getState, d.getState), b = J(a.subscribe, a.getVersion, a.getVersion), x = J(
|
|
1067
1175
|
o.registry.subscribe,
|
|
1068
1176
|
o.registry.getVersion,
|
|
1069
1177
|
o.registry.getVersion
|
|
1070
|
-
),
|
|
1071
|
-
() =>
|
|
1072
|
-
quantity:
|
|
1178
|
+
), m = a.getQuantity(), E = A(
|
|
1179
|
+
() => tn({
|
|
1180
|
+
quantity: m,
|
|
1073
1181
|
missingOptionKeys: a.missingOptionKeys(),
|
|
1074
1182
|
selectionValid: a.selectionValid(),
|
|
1075
1183
|
textFields: o.registry.getTextFields(),
|
|
1076
|
-
textOf: (
|
|
1077
|
-
seedTextOf: (
|
|
1078
|
-
hasRenderableElement:
|
|
1184
|
+
textOf: (N) => d.textOf(N),
|
|
1185
|
+
seedTextOf: (N) => d.seedTextOf(N),
|
|
1186
|
+
hasRenderableElement: d.hasRenderableElement()
|
|
1079
1187
|
}),
|
|
1080
1188
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1081
|
-
[a,
|
|
1082
|
-
),
|
|
1083
|
-
if (
|
|
1084
|
-
|
|
1085
|
-
const
|
|
1189
|
+
[a, m, c, b, x]
|
|
1190
|
+
), y = E.length === 0, [p, O] = D(!1), v = C(!1), B = G(() => {
|
|
1191
|
+
if (v.current || !y) return;
|
|
1192
|
+
v.current = !0, O(!0);
|
|
1193
|
+
const N = d.getState(), _ = a.resolvedVariantId(), F = {
|
|
1086
1194
|
productId: l.productId,
|
|
1087
|
-
...
|
|
1195
|
+
..._ ? { variantId: _ } : {},
|
|
1088
1196
|
quantity: a.getQuantity(),
|
|
1089
1197
|
selection: a.getSelection(),
|
|
1090
|
-
cartDetail:
|
|
1091
|
-
designState:
|
|
1092
|
-
|
|
1198
|
+
cartDetail: nn(l, a),
|
|
1199
|
+
designState: N,
|
|
1200
|
+
// ADR-0101: one artboard per REQUIRED placement — linked placements
|
|
1201
|
+
// carry the base relabelled — so buy and preview are the same bytes
|
|
1202
|
+
// and the order pipeline never re-derives the link rule.
|
|
1203
|
+
serverRequest: Ve(
|
|
1204
|
+
ee(N),
|
|
1205
|
+
pe(l)
|
|
1206
|
+
)
|
|
1093
1207
|
};
|
|
1094
|
-
let
|
|
1208
|
+
let h;
|
|
1095
1209
|
try {
|
|
1096
|
-
|
|
1097
|
-
} catch (
|
|
1098
|
-
throw
|
|
1210
|
+
h = t(F);
|
|
1211
|
+
} catch ($) {
|
|
1212
|
+
throw v.current = !1, O(!1), $;
|
|
1099
1213
|
}
|
|
1100
|
-
Promise.resolve(
|
|
1101
|
-
|
|
1214
|
+
Promise.resolve(h).finally(() => {
|
|
1215
|
+
v.current = !1, O(!1);
|
|
1102
1216
|
});
|
|
1103
|
-
}, [
|
|
1104
|
-
return /* @__PURE__ */
|
|
1217
|
+
}, [y, l, a, d, t]);
|
|
1218
|
+
return /* @__PURE__ */ g(
|
|
1105
1219
|
"button",
|
|
1106
1220
|
{
|
|
1107
1221
|
type: "button",
|
|
1108
1222
|
"data-sc-part": "buy",
|
|
1109
|
-
"data-sc-buy-state":
|
|
1110
|
-
"data-sc-buy-missing":
|
|
1111
|
-
disabled: !
|
|
1112
|
-
"aria-busy":
|
|
1113
|
-
onClick:
|
|
1223
|
+
"data-sc-buy-state": p ? "busy" : y ? "ready" : "incomplete",
|
|
1224
|
+
"data-sc-buy-missing": E.join(",") || void 0,
|
|
1225
|
+
disabled: !y || p,
|
|
1226
|
+
"aria-busy": p || void 0,
|
|
1227
|
+
onClick: B,
|
|
1114
1228
|
className: i,
|
|
1115
1229
|
style: s,
|
|
1116
1230
|
children: r ?? "Add to cart"
|
|
1117
1231
|
}
|
|
1118
1232
|
);
|
|
1119
1233
|
}
|
|
1120
|
-
function
|
|
1234
|
+
function sn({
|
|
1121
1235
|
placement: e = "docked",
|
|
1122
1236
|
className: t,
|
|
1123
1237
|
style: n
|
|
1124
1238
|
}) {
|
|
1125
|
-
const r =
|
|
1126
|
-
|
|
1127
|
-
const i =
|
|
1128
|
-
|
|
1239
|
+
const r = se("Editor.Controls");
|
|
1240
|
+
nt("Editor.Controls"), oe("Editor.Controls");
|
|
1241
|
+
const i = we();
|
|
1242
|
+
ae(
|
|
1129
1243
|
() => r.registry.registerControls(i, e),
|
|
1130
1244
|
[r.registry, i, e]
|
|
1131
1245
|
);
|
|
1132
|
-
const s = e === "docked", [o, l] =
|
|
1133
|
-
return
|
|
1246
|
+
const s = e === "docked", [o, l] = D(null);
|
|
1247
|
+
return L(() => {
|
|
1134
1248
|
if (!s) return;
|
|
1135
|
-
let
|
|
1136
|
-
return import("./ContextualToolbars-
|
|
1249
|
+
let d = !1;
|
|
1250
|
+
return import("./ContextualToolbars-C62As-xY.js").then((a) => a.s).then(
|
|
1137
1251
|
(a) => {
|
|
1138
|
-
|
|
1252
|
+
d || l(() => a.ContextualToolbars);
|
|
1139
1253
|
},
|
|
1140
1254
|
(a) => {
|
|
1141
|
-
|
|
1142
|
-
new
|
|
1255
|
+
d || r.reportRuntimeError(
|
|
1256
|
+
new S(
|
|
1143
1257
|
"E_CHUNK_LOAD_FAILED",
|
|
1144
1258
|
`the editor's controls chunk failed to load (${a instanceof Error ? a.message : String(a)}). This is a network/CDN failure, not a composition mistake — retry, or check the deployment serves the @snowcone-app/canvas lazy chunks.`,
|
|
1145
1259
|
{ cause: a instanceof Error ? a.message : String(a), docSlug: "embed-mode" }
|
|
@@ -1147,9 +1261,9 @@ function Jt({
|
|
|
1147
1261
|
);
|
|
1148
1262
|
}
|
|
1149
1263
|
), () => {
|
|
1150
|
-
|
|
1264
|
+
d = !0;
|
|
1151
1265
|
};
|
|
1152
|
-
}, [s, r]), s ? /* @__PURE__ */
|
|
1266
|
+
}, [s, r]), s ? /* @__PURE__ */ g(
|
|
1153
1267
|
"div",
|
|
1154
1268
|
{
|
|
1155
1269
|
"data-sc-part": "controls",
|
|
@@ -1157,30 +1271,30 @@ function Jt({
|
|
|
1157
1271
|
className: t,
|
|
1158
1272
|
style: n,
|
|
1159
1273
|
"aria-busy": o ? void 0 : "true",
|
|
1160
|
-
children: o ? /* @__PURE__ */
|
|
1274
|
+
children: o ? /* @__PURE__ */ g(o, { mode: "embedded" }) : null
|
|
1161
1275
|
}
|
|
1162
1276
|
) : null;
|
|
1163
1277
|
}
|
|
1164
|
-
function
|
|
1278
|
+
function on({
|
|
1165
1279
|
variant: e = "dark",
|
|
1166
1280
|
className: t,
|
|
1167
1281
|
style: n
|
|
1168
1282
|
}) {
|
|
1169
|
-
const { isRendering: r } =
|
|
1170
|
-
return i ? /* @__PURE__ */
|
|
1283
|
+
const { isRendering: r } = te(), { showOverlay: i, overlayVisible: s, handleExited: o } = Ge(r);
|
|
1284
|
+
return i ? /* @__PURE__ */ g(
|
|
1171
1285
|
"div",
|
|
1172
1286
|
{
|
|
1173
1287
|
"data-sc-part": "loading-overlay",
|
|
1174
1288
|
className: `sc-loading-overlay-host${t ? ` ${t}` : ""}`,
|
|
1175
1289
|
style: n,
|
|
1176
1290
|
"aria-hidden": "true",
|
|
1177
|
-
children: /* @__PURE__ */
|
|
1291
|
+
children: /* @__PURE__ */ g(Ke, { visible: s, variant: e, onExited: o })
|
|
1178
1292
|
}
|
|
1179
1293
|
) : null;
|
|
1180
1294
|
}
|
|
1181
|
-
function
|
|
1182
|
-
const t =
|
|
1183
|
-
return
|
|
1295
|
+
function an() {
|
|
1296
|
+
const t = se("useProductSelection").commerce, n = J(t.subscribe, t.getVersion, t.getVersion), r = G((s, o) => t.select(s, o), [t]), i = G((s) => t.setQuantity(s), [t]);
|
|
1297
|
+
return A(
|
|
1184
1298
|
() => ({
|
|
1185
1299
|
attributes: t.getAttributes(),
|
|
1186
1300
|
selection: t.getSelection(),
|
|
@@ -1197,53 +1311,53 @@ function Yt() {
|
|
|
1197
1311
|
[t, r, i, n]
|
|
1198
1312
|
);
|
|
1199
1313
|
}
|
|
1200
|
-
const
|
|
1314
|
+
const H = {
|
|
1201
1315
|
/** The one provider boundary — session, design, live state, error boundary. */
|
|
1202
|
-
Root:
|
|
1316
|
+
Root: qe,
|
|
1203
1317
|
/** The editable artboard (the ONE lazy renderer boundary — D9). */
|
|
1204
|
-
Canvas:
|
|
1318
|
+
Canvas: jt,
|
|
1205
1319
|
/** Live product mockup. ×N under one Root is valid. */
|
|
1206
|
-
Preview:
|
|
1320
|
+
Preview: We,
|
|
1207
1321
|
/** Placement switcher tabs (ADR-0088). Renders nothing for a
|
|
1208
1322
|
* single-placement design; headless floor = usePlacements(). */
|
|
1209
|
-
Placements:
|
|
1323
|
+
Placements: Kt,
|
|
1210
1324
|
/** Form input bound to a design text layer by typed token (T1). */
|
|
1211
|
-
TextField:
|
|
1325
|
+
TextField: en,
|
|
1212
1326
|
/** Smart commerce part: completeness + payload assembly; submit = host callback. */
|
|
1213
|
-
Buy:
|
|
1327
|
+
Buy: rn,
|
|
1214
1328
|
/** Layer list. The one editor part that works canvas-free (ADR-0085 §4). */
|
|
1215
|
-
Layers:
|
|
1329
|
+
Layers: ot,
|
|
1216
1330
|
/** Morphing contextual zone — ONE coarse part; placement docked|floating (§5). */
|
|
1217
|
-
Controls:
|
|
1331
|
+
Controls: sn,
|
|
1218
1332
|
/** Undo/redo controls. Requires Editor.Canvas. */
|
|
1219
|
-
History:
|
|
1333
|
+
History: st,
|
|
1220
1334
|
/** The one ⋯ overflow menu. Requires Editor.Canvas. */
|
|
1221
|
-
Menu:
|
|
1335
|
+
Menu: it,
|
|
1222
1336
|
/** The ⊕ add-element menu. Requires Editor.Canvas. */
|
|
1223
|
-
Add:
|
|
1337
|
+
Add: rt,
|
|
1224
1338
|
/** Standalone render-in-flight rainbow for host-owned preview surfaces.
|
|
1225
1339
|
* Fills its positioned parent; rides the session (canvas-free). */
|
|
1226
|
-
LoadingOverlay:
|
|
1340
|
+
LoadingOverlay: on
|
|
1227
1341
|
};
|
|
1228
|
-
function
|
|
1229
|
-
return /* @__PURE__ */
|
|
1342
|
+
function Cn(e) {
|
|
1343
|
+
return /* @__PURE__ */ g(qe, { ...e, __validation: "warn" });
|
|
1230
1344
|
}
|
|
1231
|
-
const
|
|
1345
|
+
const Nn = Ae(
|
|
1232
1346
|
function(t, n) {
|
|
1233
|
-
const { children: r, className: i, style: s, maxHeight: o, ...l } = t, [
|
|
1234
|
-
return
|
|
1235
|
-
let
|
|
1236
|
-
return
|
|
1237
|
-
(
|
|
1238
|
-
|
|
1347
|
+
const { children: r, className: i, style: s, maxHeight: o, ...l } = t, [d, a] = D(null);
|
|
1348
|
+
return L(() => {
|
|
1349
|
+
let u = !1;
|
|
1350
|
+
return ze().then(
|
|
1351
|
+
(c) => {
|
|
1352
|
+
u || a(() => c);
|
|
1239
1353
|
},
|
|
1240
|
-
(
|
|
1241
|
-
console.error("[RealtimeCanvas] failed to load the rendering chunk:",
|
|
1354
|
+
(c) => {
|
|
1355
|
+
console.error("[RealtimeCanvas] failed to load the rendering chunk:", c);
|
|
1242
1356
|
}
|
|
1243
1357
|
), () => {
|
|
1244
|
-
|
|
1358
|
+
u = !0;
|
|
1245
1359
|
};
|
|
1246
|
-
}, []),
|
|
1360
|
+
}, []), d ? /* @__PURE__ */ g(d, { ref: n, selfScope: !0, maxHeight: o, className: i, style: s, ...l, children: r }) : /* @__PURE__ */ g(
|
|
1247
1361
|
"div",
|
|
1248
1362
|
{
|
|
1249
1363
|
className: `sc-root${i ? ` ${i}` : ""}`,
|
|
@@ -1253,52 +1367,52 @@ const wn = $e(
|
|
|
1253
1367
|
);
|
|
1254
1368
|
}
|
|
1255
1369
|
);
|
|
1256
|
-
function
|
|
1257
|
-
return /* @__PURE__ */
|
|
1370
|
+
function _n(e) {
|
|
1371
|
+
return /* @__PURE__ */ g(We, { ...e });
|
|
1258
1372
|
}
|
|
1259
|
-
function
|
|
1260
|
-
const { mockups: e, isRendering: t, error: n } =
|
|
1373
|
+
function Tn() {
|
|
1374
|
+
const { mockups: e, isRendering: t, error: n } = te();
|
|
1261
1375
|
return { mockups: e, isRendering: t, error: n };
|
|
1262
1376
|
}
|
|
1263
|
-
function
|
|
1377
|
+
function dn(e) {
|
|
1264
1378
|
return e.type !== "color" && typeof e.width == "number" && e.width > 0 && typeof e.height == "number" && e.height > 0;
|
|
1265
1379
|
}
|
|
1266
|
-
function
|
|
1267
|
-
var b,
|
|
1268
|
-
if (
|
|
1269
|
-
throw new
|
|
1380
|
+
function An(e, t = {}) {
|
|
1381
|
+
var b, x, m, E, y;
|
|
1382
|
+
if (Ue(e))
|
|
1383
|
+
throw new S(
|
|
1270
1384
|
"E_BUNDLE_CONFIG_REQUIRED",
|
|
1271
|
-
`product ${e.id} is a bundle (roles: [${e.bundle.members.map((
|
|
1385
|
+
`product ${e.id} is a bundle (roles: [${e.bundle.members.map((p) => p.role).join(", ")}]) — it has per-role variants and role-scoped placement keys, which the single-product config cannot describe. Use bundleToRenderConfig(product, { picks?, variants?, placement?, width? }) instead.`,
|
|
1272
1386
|
{
|
|
1273
1387
|
productId: e.id,
|
|
1274
|
-
validNames: e.bundle.members.map((
|
|
1388
|
+
validNames: e.bundle.members.map((p) => p.role),
|
|
1275
1389
|
docSlug: "bundles"
|
|
1276
1390
|
}
|
|
1277
1391
|
);
|
|
1278
|
-
const n = (e.placements ?? []).filter(
|
|
1392
|
+
const n = (e.placements ?? []).filter(dn), r = n.map((p) => p.label), i = t.placement ? n.find((p) => p.label === t.placement) : n[0];
|
|
1279
1393
|
if (!i)
|
|
1280
|
-
throw t.placement ? new
|
|
1394
|
+
throw t.placement ? new S(
|
|
1281
1395
|
"E_PRODUCT_NOT_RENDERABLE",
|
|
1282
1396
|
`product ${e.id} has no renderable placement "${t.placement}". Renderable image placements: [${r.join(", ")}].`,
|
|
1283
1397
|
{ productId: e.id, requested: t.placement, validNames: r, docSlug: "embed-mode" }
|
|
1284
|
-
) : new
|
|
1398
|
+
) : new S(
|
|
1285
1399
|
"E_PRODUCT_NOT_RENDERABLE",
|
|
1286
1400
|
`product ${e.id} has no renderable image placement (a non-color placement with width/height). The catalog payload may be incomplete — fetch it via getProduct(), not a search hit.`,
|
|
1287
1401
|
{ productId: e.id, docSlug: "embed-mode" }
|
|
1288
1402
|
);
|
|
1289
1403
|
const s = ((b = e.options) == null ? void 0 : b.attributes) ?? {}, l = Object.values(s).some(
|
|
1290
|
-
(
|
|
1291
|
-
var
|
|
1292
|
-
return (
|
|
1404
|
+
(p) => {
|
|
1405
|
+
var O;
|
|
1406
|
+
return (O = p == null ? void 0 : p.choices) == null ? void 0 : O.some((v) => v == null ? void 0 : v.hex);
|
|
1293
1407
|
}
|
|
1294
|
-
) ? (
|
|
1295
|
-
(
|
|
1296
|
-
)) == null ? void 0 :
|
|
1297
|
-
var
|
|
1298
|
-
return (
|
|
1299
|
-
}) :
|
|
1300
|
-
if (
|
|
1301
|
-
throw new
|
|
1408
|
+
) ? (E = (m = (x = e.options) == null ? void 0 : x.combinations) == null ? void 0 : m.find(
|
|
1409
|
+
(p) => typeof p.variantId == "string" && p.variantId !== ""
|
|
1410
|
+
)) == null ? void 0 : E.variantId : void 0, d = e.mockups ?? [], a = l ? d.filter((p) => {
|
|
1411
|
+
var O;
|
|
1412
|
+
return (O = p.gvids) == null ? void 0 : O.includes(l);
|
|
1413
|
+
}) : d, u = (a.length > 0 ? a : d).map((p) => p.id);
|
|
1414
|
+
if (u.length === 0)
|
|
1415
|
+
throw new S(
|
|
1302
1416
|
"E_PRODUCT_NOT_RENDERABLE",
|
|
1303
1417
|
`product ${e.id} has no mockup scenes — nothing to render a preview into.`,
|
|
1304
1418
|
{ productId: e.id, docSlug: "embed-mode" }
|
|
@@ -1306,11 +1420,11 @@ function Rn(e, t = {}) {
|
|
|
1306
1420
|
return {
|
|
1307
1421
|
product: {
|
|
1308
1422
|
productId: e.id,
|
|
1309
|
-
mockupIds:
|
|
1423
|
+
mockupIds: u,
|
|
1310
1424
|
...typeof l == "string" ? { variantId: l } : {},
|
|
1311
1425
|
options: e.options,
|
|
1312
|
-
placements: (
|
|
1313
|
-
mockups:
|
|
1426
|
+
placements: (y = e.placements) == null ? void 0 : y.map((p) => p.label),
|
|
1427
|
+
mockups: d,
|
|
1314
1428
|
requiredPlacements: e.requiredPlacements,
|
|
1315
1429
|
...e.defaultGvid ? { defaultGvid: e.defaultGvid } : {},
|
|
1316
1430
|
...typeof t.width == "number" ? { width: t.width } : {}
|
|
@@ -1322,17 +1436,17 @@ function Rn(e, t = {}) {
|
|
|
1322
1436
|
aspectRatio: i.width / i.height
|
|
1323
1437
|
},
|
|
1324
1438
|
placementLabels: r,
|
|
1325
|
-
placements: n.map((
|
|
1326
|
-
label:
|
|
1327
|
-
width:
|
|
1328
|
-
height:
|
|
1329
|
-
aspectRatio:
|
|
1439
|
+
placements: n.map((p) => ({
|
|
1440
|
+
label: p.label,
|
|
1441
|
+
width: p.width,
|
|
1442
|
+
height: p.height,
|
|
1443
|
+
aspectRatio: p.width / p.height
|
|
1330
1444
|
})),
|
|
1331
|
-
primaryMockupId:
|
|
1445
|
+
primaryMockupId: u[0],
|
|
1332
1446
|
variantId: l
|
|
1333
1447
|
};
|
|
1334
1448
|
}
|
|
1335
|
-
function
|
|
1449
|
+
function ln(e) {
|
|
1336
1450
|
return new Intl.NumberFormat("en-US", {
|
|
1337
1451
|
style: "currency",
|
|
1338
1452
|
currency: "USD",
|
|
@@ -1340,7 +1454,7 @@ function Zt(e) {
|
|
|
1340
1454
|
maximumFractionDigits: e % 100 === 0 ? 0 : 2
|
|
1341
1455
|
}).format(e / 100);
|
|
1342
1456
|
}
|
|
1343
|
-
const
|
|
1457
|
+
const cn = {
|
|
1344
1458
|
display: "inline-flex",
|
|
1345
1459
|
alignItems: "center",
|
|
1346
1460
|
justifyContent: "center",
|
|
@@ -1355,7 +1469,7 @@ const en = {
|
|
|
1355
1469
|
fontSize: 16,
|
|
1356
1470
|
lineHeight: 1,
|
|
1357
1471
|
cursor: "pointer"
|
|
1358
|
-
},
|
|
1472
|
+
}, un = {
|
|
1359
1473
|
display: "flex",
|
|
1360
1474
|
alignItems: "center",
|
|
1361
1475
|
gap: 10,
|
|
@@ -1371,23 +1485,23 @@ const en = {
|
|
|
1371
1485
|
textAlign: "left",
|
|
1372
1486
|
cursor: "pointer"
|
|
1373
1487
|
};
|
|
1374
|
-
function
|
|
1488
|
+
function ve({
|
|
1375
1489
|
label: e,
|
|
1376
1490
|
onSelect: t
|
|
1377
1491
|
}) {
|
|
1378
|
-
return /* @__PURE__ */
|
|
1492
|
+
return /* @__PURE__ */ g(
|
|
1379
1493
|
"button",
|
|
1380
1494
|
{
|
|
1381
1495
|
type: "button",
|
|
1382
1496
|
role: "menuitem",
|
|
1383
1497
|
"data-sc-part": "snowcone-editor-menu-item",
|
|
1384
|
-
style:
|
|
1498
|
+
style: un,
|
|
1385
1499
|
onClick: t,
|
|
1386
1500
|
children: e
|
|
1387
1501
|
}
|
|
1388
1502
|
);
|
|
1389
1503
|
}
|
|
1390
|
-
function
|
|
1504
|
+
function mn({
|
|
1391
1505
|
fullscreen: e,
|
|
1392
1506
|
onToggleFullscreen: t,
|
|
1393
1507
|
viewCount: n,
|
|
@@ -1395,9 +1509,9 @@ function nn({
|
|
|
1395
1509
|
onSelectView: i,
|
|
1396
1510
|
onExport: s
|
|
1397
1511
|
}) {
|
|
1398
|
-
const [o, l] =
|
|
1399
|
-
return /* @__PURE__ */
|
|
1400
|
-
/* @__PURE__ */
|
|
1512
|
+
const [o, l] = D(!1), d = () => l(!1);
|
|
1513
|
+
return /* @__PURE__ */ U("div", { style: { position: "relative" }, children: [
|
|
1514
|
+
/* @__PURE__ */ g(
|
|
1401
1515
|
"button",
|
|
1402
1516
|
{
|
|
1403
1517
|
type: "button",
|
|
@@ -1405,21 +1519,21 @@ function nn({
|
|
|
1405
1519
|
"aria-haspopup": "menu",
|
|
1406
1520
|
"aria-expanded": o,
|
|
1407
1521
|
"data-sc-part": "snowcone-editor-menu",
|
|
1408
|
-
style:
|
|
1522
|
+
style: cn,
|
|
1409
1523
|
onClick: () => l((a) => !a),
|
|
1410
1524
|
children: "⋮"
|
|
1411
1525
|
}
|
|
1412
1526
|
),
|
|
1413
|
-
o ? /* @__PURE__ */
|
|
1414
|
-
/* @__PURE__ */
|
|
1527
|
+
o ? /* @__PURE__ */ U(lt, { children: [
|
|
1528
|
+
/* @__PURE__ */ g(
|
|
1415
1529
|
"div",
|
|
1416
1530
|
{
|
|
1417
1531
|
style: { position: "fixed", inset: 0, zIndex: 39 },
|
|
1418
|
-
onClick:
|
|
1532
|
+
onClick: d,
|
|
1419
1533
|
"aria-hidden": "true"
|
|
1420
1534
|
}
|
|
1421
1535
|
),
|
|
1422
|
-
/* @__PURE__ */
|
|
1536
|
+
/* @__PURE__ */ U(
|
|
1423
1537
|
"div",
|
|
1424
1538
|
{
|
|
1425
1539
|
role: "menu",
|
|
@@ -1438,31 +1552,31 @@ function nn({
|
|
|
1438
1552
|
zIndex: 40
|
|
1439
1553
|
},
|
|
1440
1554
|
children: [
|
|
1441
|
-
/* @__PURE__ */
|
|
1442
|
-
|
|
1555
|
+
/* @__PURE__ */ g(
|
|
1556
|
+
ve,
|
|
1443
1557
|
{
|
|
1444
1558
|
label: e ? "Exit fullscreen" : "Fullscreen",
|
|
1445
1559
|
onSelect: () => {
|
|
1446
|
-
|
|
1560
|
+
d(), t();
|
|
1447
1561
|
}
|
|
1448
1562
|
}
|
|
1449
1563
|
),
|
|
1450
|
-
n > 1 ? Array.from({ length: n }, (a,
|
|
1451
|
-
|
|
1564
|
+
n > 1 ? Array.from({ length: n }, (a, u) => /* @__PURE__ */ g(
|
|
1565
|
+
ve,
|
|
1452
1566
|
{
|
|
1453
|
-
label: `View ${
|
|
1567
|
+
label: `View ${u + 1}${u === r ? " ✓" : ""}`,
|
|
1454
1568
|
onSelect: () => {
|
|
1455
|
-
|
|
1569
|
+
d(), i(u);
|
|
1456
1570
|
}
|
|
1457
1571
|
},
|
|
1458
|
-
|
|
1572
|
+
u
|
|
1459
1573
|
)) : null,
|
|
1460
|
-
/* @__PURE__ */
|
|
1461
|
-
|
|
1574
|
+
/* @__PURE__ */ g(
|
|
1575
|
+
ve,
|
|
1462
1576
|
{
|
|
1463
1577
|
label: "Export PNG",
|
|
1464
1578
|
onSelect: () => {
|
|
1465
|
-
|
|
1579
|
+
d(), s();
|
|
1466
1580
|
}
|
|
1467
1581
|
}
|
|
1468
1582
|
)
|
|
@@ -1472,19 +1586,19 @@ function nn({
|
|
|
1472
1586
|
] }) : null
|
|
1473
1587
|
] });
|
|
1474
1588
|
}
|
|
1475
|
-
function
|
|
1476
|
-
const { flatLayers: e, selectLayer: t, generateAllPreviews: n } =
|
|
1477
|
-
return
|
|
1589
|
+
function pn() {
|
|
1590
|
+
const { flatLayers: e, selectLayer: t, generateAllPreviews: n } = at({ previewSize: 96 });
|
|
1591
|
+
return L(() => {
|
|
1478
1592
|
e.length > 0 && n();
|
|
1479
|
-
}, [e.length, n]), /* @__PURE__ */
|
|
1593
|
+
}, [e.length, n]), /* @__PURE__ */ U(
|
|
1480
1594
|
"div",
|
|
1481
1595
|
{
|
|
1482
1596
|
"data-sc-part": "snowcone-editor-idle-dock",
|
|
1483
1597
|
style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 8, minHeight: 44 },
|
|
1484
1598
|
children: [
|
|
1485
|
-
/* @__PURE__ */
|
|
1486
|
-
e.length > 0 ? /* @__PURE__ */
|
|
1487
|
-
e.map((r) => /* @__PURE__ */
|
|
1599
|
+
/* @__PURE__ */ g(H.Add, {}),
|
|
1600
|
+
e.length > 0 ? /* @__PURE__ */ g("div", { style: { width: 1, height: 28, background: "rgba(0,0,0,0.1)", flexShrink: 0 }, "aria-hidden": "true" }) : null,
|
|
1601
|
+
e.map((r) => /* @__PURE__ */ g(
|
|
1488
1602
|
"button",
|
|
1489
1603
|
{
|
|
1490
1604
|
type: "button",
|
|
@@ -1507,8 +1621,8 @@ function rn() {
|
|
|
1507
1621
|
},
|
|
1508
1622
|
children: r.previewUrl ? (
|
|
1509
1623
|
// eslint-disable-next-line @next/next/no-img-element
|
|
1510
|
-
/* @__PURE__ */
|
|
1511
|
-
) : /* @__PURE__ */
|
|
1624
|
+
/* @__PURE__ */ g("img", { src: r.previewUrl, alt: "", style: { width: "100%", height: "100%", objectFit: "contain" } })
|
|
1625
|
+
) : /* @__PURE__ */ g(
|
|
1512
1626
|
"span",
|
|
1513
1627
|
{
|
|
1514
1628
|
style: {
|
|
@@ -1529,13 +1643,13 @@ function rn() {
|
|
|
1529
1643
|
}
|
|
1530
1644
|
);
|
|
1531
1645
|
}
|
|
1532
|
-
function
|
|
1646
|
+
function fn({
|
|
1533
1647
|
onAddToCart: e,
|
|
1534
1648
|
defaultQuantity: t
|
|
1535
1649
|
}) {
|
|
1536
|
-
const { price: n, complete: r } =
|
|
1537
|
-
return /* @__PURE__ */
|
|
1538
|
-
|
|
1650
|
+
const { price: n, complete: r } = an();
|
|
1651
|
+
return /* @__PURE__ */ U(
|
|
1652
|
+
H.Buy,
|
|
1539
1653
|
{
|
|
1540
1654
|
onAddToCart: e,
|
|
1541
1655
|
...typeof t == "number" ? { defaultQuantity: t } : {},
|
|
@@ -1558,12 +1672,12 @@ function sn({
|
|
|
1558
1672
|
},
|
|
1559
1673
|
children: [
|
|
1560
1674
|
"Add to cart",
|
|
1561
|
-
typeof n == "number" ? ` · ${
|
|
1675
|
+
typeof n == "number" ? ` · ${ln(n)}` : ""
|
|
1562
1676
|
]
|
|
1563
1677
|
}
|
|
1564
1678
|
);
|
|
1565
1679
|
}
|
|
1566
|
-
function
|
|
1680
|
+
function hn({
|
|
1567
1681
|
title: e,
|
|
1568
1682
|
height: t,
|
|
1569
1683
|
mockupIds: n,
|
|
@@ -1572,15 +1686,15 @@ function on({
|
|
|
1572
1686
|
className: s,
|
|
1573
1687
|
style: o
|
|
1574
1688
|
}) {
|
|
1575
|
-
const [l,
|
|
1576
|
-
var
|
|
1577
|
-
const
|
|
1578
|
-
if (!
|
|
1579
|
-
const [
|
|
1580
|
-
if (typeof
|
|
1581
|
-
const
|
|
1582
|
-
|
|
1583
|
-
}, []),
|
|
1689
|
+
const [l, d] = D(!1), [a, u] = D(0), [c, b] = D(!1), x = C(null), m = It(), E = n[Math.min(a, n.length - 1)], y = G(async () => {
|
|
1690
|
+
var F;
|
|
1691
|
+
const v = await ((F = x.current) == null ? void 0 : F.exportArtboards({ format: "dataUrl" }));
|
|
1692
|
+
if (!v) return;
|
|
1693
|
+
const [B, N] = Object.entries(v)[0] ?? [];
|
|
1694
|
+
if (typeof N != "string") return;
|
|
1695
|
+
const _ = document.createElement("a");
|
|
1696
|
+
_.href = N, _.download = `${B ?? "design"}.png`, _.click();
|
|
1697
|
+
}, []), p = {
|
|
1584
1698
|
display: "flex",
|
|
1585
1699
|
flexDirection: "column",
|
|
1586
1700
|
overflow: "hidden",
|
|
@@ -1601,7 +1715,7 @@ function on({
|
|
|
1601
1715
|
boxShadow: "0 1px 3px rgba(0,0,0,0.08)"
|
|
1602
1716
|
},
|
|
1603
1717
|
...o
|
|
1604
|
-
},
|
|
1718
|
+
}, O = {
|
|
1605
1719
|
position: "absolute",
|
|
1606
1720
|
top: 8,
|
|
1607
1721
|
right: 12,
|
|
@@ -1616,15 +1730,15 @@ function on({
|
|
|
1616
1730
|
cursor: "pointer",
|
|
1617
1731
|
zIndex: 2
|
|
1618
1732
|
};
|
|
1619
|
-
return /* @__PURE__ */
|
|
1733
|
+
return /* @__PURE__ */ U(
|
|
1620
1734
|
"div",
|
|
1621
1735
|
{
|
|
1622
1736
|
"data-sc-part": "snowcone-editor",
|
|
1623
1737
|
"data-sc-fullscreen": l ? "true" : void 0,
|
|
1624
1738
|
className: s,
|
|
1625
|
-
style:
|
|
1739
|
+
style: p,
|
|
1626
1740
|
children: [
|
|
1627
|
-
/* @__PURE__ */
|
|
1741
|
+
/* @__PURE__ */ U(
|
|
1628
1742
|
"div",
|
|
1629
1743
|
{
|
|
1630
1744
|
"data-sc-part": "snowcone-editor-header",
|
|
@@ -1636,35 +1750,35 @@ function on({
|
|
|
1636
1750
|
flexShrink: 0
|
|
1637
1751
|
},
|
|
1638
1752
|
children: [
|
|
1639
|
-
/* @__PURE__ */
|
|
1640
|
-
/* @__PURE__ */
|
|
1641
|
-
/* @__PURE__ */
|
|
1642
|
-
|
|
1753
|
+
/* @__PURE__ */ g("span", { style: { fontSize: 14, fontWeight: 700, marginRight: "auto" }, children: e }),
|
|
1754
|
+
/* @__PURE__ */ g(H.History, {}),
|
|
1755
|
+
/* @__PURE__ */ g(
|
|
1756
|
+
mn,
|
|
1643
1757
|
{
|
|
1644
1758
|
fullscreen: l,
|
|
1645
|
-
onToggleFullscreen: () =>
|
|
1759
|
+
onToggleFullscreen: () => d((v) => !v),
|
|
1646
1760
|
viewCount: n.length,
|
|
1647
1761
|
viewIndex: a,
|
|
1648
|
-
onSelectView:
|
|
1649
|
-
onExport: () => void
|
|
1762
|
+
onSelectView: u,
|
|
1763
|
+
onExport: () => void y()
|
|
1650
1764
|
}
|
|
1651
1765
|
),
|
|
1652
|
-
/* @__PURE__ */
|
|
1766
|
+
/* @__PURE__ */ g(fn, { onAddToCart: r, defaultQuantity: i })
|
|
1653
1767
|
]
|
|
1654
1768
|
}
|
|
1655
1769
|
),
|
|
1656
|
-
/* @__PURE__ */
|
|
1770
|
+
/* @__PURE__ */ U(
|
|
1657
1771
|
"div",
|
|
1658
1772
|
{
|
|
1659
1773
|
"data-sc-part": "snowcone-editor-stage",
|
|
1660
1774
|
style: { position: "relative", flex: 1, minHeight: 0, padding: "4px 12px" },
|
|
1661
1775
|
children: [
|
|
1662
|
-
/* @__PURE__ */
|
|
1663
|
-
|
|
1776
|
+
/* @__PURE__ */ g(H.Canvas, { ref: x, style: { height: "100%" } }),
|
|
1777
|
+
c ? (
|
|
1664
1778
|
// Swapped: the mockup IS the stage; the corner chip returns to the
|
|
1665
1779
|
// artwork. The canvas stays mounted underneath (no document
|
|
1666
1780
|
// teardown), just covered.
|
|
1667
|
-
/* @__PURE__ */
|
|
1781
|
+
/* @__PURE__ */ U(
|
|
1668
1782
|
"div",
|
|
1669
1783
|
{
|
|
1670
1784
|
"data-sc-part": "snowcone-editor-swap-stage",
|
|
@@ -1679,17 +1793,17 @@ function on({
|
|
|
1679
1793
|
padding: 8
|
|
1680
1794
|
},
|
|
1681
1795
|
children: [
|
|
1682
|
-
/* @__PURE__ */
|
|
1683
|
-
|
|
1796
|
+
/* @__PURE__ */ g(
|
|
1797
|
+
H.Preview,
|
|
1684
1798
|
{
|
|
1685
|
-
mockupId:
|
|
1799
|
+
mockupId: E,
|
|
1686
1800
|
alt: "Product mockup",
|
|
1687
1801
|
loadingOverlay: !0,
|
|
1688
|
-
fallback: /* @__PURE__ */
|
|
1802
|
+
fallback: /* @__PURE__ */ g("div", { "aria-busy": "true", children: "Rendering…" }),
|
|
1689
1803
|
style: { maxWidth: "100%", maxHeight: "100%", borderRadius: 12 }
|
|
1690
1804
|
}
|
|
1691
1805
|
),
|
|
1692
|
-
/* @__PURE__ */
|
|
1806
|
+
/* @__PURE__ */ g(
|
|
1693
1807
|
"button",
|
|
1694
1808
|
{
|
|
1695
1809
|
type: "button",
|
|
@@ -1697,7 +1811,7 @@ function on({
|
|
|
1697
1811
|
"data-sc-part": "snowcone-editor-swap-back",
|
|
1698
1812
|
onClick: () => b(!1),
|
|
1699
1813
|
style: {
|
|
1700
|
-
...
|
|
1814
|
+
...O,
|
|
1701
1815
|
display: "flex",
|
|
1702
1816
|
alignItems: "center",
|
|
1703
1817
|
justifyContent: "center",
|
|
@@ -1712,21 +1826,21 @@ function on({
|
|
|
1712
1826
|
]
|
|
1713
1827
|
}
|
|
1714
1828
|
)
|
|
1715
|
-
) : /* @__PURE__ */
|
|
1829
|
+
) : /* @__PURE__ */ g(
|
|
1716
1830
|
"button",
|
|
1717
1831
|
{
|
|
1718
1832
|
type: "button",
|
|
1719
1833
|
"aria-label": "Show product mockup",
|
|
1720
1834
|
"data-sc-part": "snowcone-editor-pip",
|
|
1721
1835
|
onClick: () => b(!0),
|
|
1722
|
-
style:
|
|
1723
|
-
children: /* @__PURE__ */
|
|
1724
|
-
|
|
1836
|
+
style: O,
|
|
1837
|
+
children: /* @__PURE__ */ g(
|
|
1838
|
+
H.Preview,
|
|
1725
1839
|
{
|
|
1726
|
-
mockupId:
|
|
1840
|
+
mockupId: E,
|
|
1727
1841
|
alt: "Product mockup preview",
|
|
1728
1842
|
loadingOverlay: !0,
|
|
1729
|
-
fallback: /* @__PURE__ */
|
|
1843
|
+
fallback: /* @__PURE__ */ g("span", { style: { fontSize: 10, opacity: 0.5 }, "aria-busy": "true", children: "mockup…" }),
|
|
1730
1844
|
style: { width: "100%", height: "100%", display: "block" }
|
|
1731
1845
|
}
|
|
1732
1846
|
)
|
|
@@ -1735,15 +1849,15 @@ function on({
|
|
|
1735
1849
|
]
|
|
1736
1850
|
}
|
|
1737
1851
|
),
|
|
1738
|
-
/* @__PURE__ */
|
|
1852
|
+
/* @__PURE__ */ U(
|
|
1739
1853
|
"div",
|
|
1740
1854
|
{
|
|
1741
1855
|
"data-sc-part": "snowcone-editor-zone",
|
|
1742
|
-
"data-sc-zone-state":
|
|
1856
|
+
"data-sc-zone-state": m ? "selected" : "idle",
|
|
1743
1857
|
style: { flexShrink: 0, padding: "4px 16px 14px" },
|
|
1744
1858
|
children: [
|
|
1745
|
-
/* @__PURE__ */
|
|
1746
|
-
|
|
1859
|
+
/* @__PURE__ */ g("div", { style: { display: m ? void 0 : "none" }, children: /* @__PURE__ */ g(H.Controls, { placement: "docked" }) }),
|
|
1860
|
+
m ? null : /* @__PURE__ */ g(pn, {})
|
|
1747
1861
|
]
|
|
1748
1862
|
}
|
|
1749
1863
|
)
|
|
@@ -1751,7 +1865,7 @@ function on({
|
|
|
1751
1865
|
}
|
|
1752
1866
|
);
|
|
1753
1867
|
}
|
|
1754
|
-
function
|
|
1868
|
+
function Dn(e) {
|
|
1755
1869
|
const {
|
|
1756
1870
|
onAddToCart: t,
|
|
1757
1871
|
defaultQuantity: n,
|
|
@@ -1761,8 +1875,8 @@ function xn(e) {
|
|
|
1761
1875
|
style: o,
|
|
1762
1876
|
...l
|
|
1763
1877
|
} = e;
|
|
1764
|
-
return /* @__PURE__ */
|
|
1765
|
-
|
|
1878
|
+
return /* @__PURE__ */ g(H.Root, { ...l, children: /* @__PURE__ */ g(
|
|
1879
|
+
hn,
|
|
1766
1880
|
{
|
|
1767
1881
|
title: r,
|
|
1768
1882
|
height: i,
|
|
@@ -1774,26 +1888,26 @@ function xn(e) {
|
|
|
1774
1888
|
}
|
|
1775
1889
|
) });
|
|
1776
1890
|
}
|
|
1777
|
-
|
|
1891
|
+
dt();
|
|
1778
1892
|
export {
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1893
|
+
H as E,
|
|
1894
|
+
Nn as R,
|
|
1895
|
+
Dn as S,
|
|
1896
|
+
Cn as a,
|
|
1897
|
+
_n as b,
|
|
1898
|
+
$n as c,
|
|
1899
|
+
On as d,
|
|
1900
|
+
Ot as e,
|
|
1901
|
+
Le as f,
|
|
1902
|
+
ln as g,
|
|
1903
|
+
_t as h,
|
|
1904
|
+
Ue as i,
|
|
1905
|
+
Mt as j,
|
|
1906
|
+
an as k,
|
|
1907
|
+
Tn as l,
|
|
1908
|
+
An as p,
|
|
1909
|
+
Ee as s,
|
|
1910
|
+
te as u,
|
|
1911
|
+
At as v
|
|
1798
1912
|
};
|
|
1799
|
-
//# sourceMappingURL=embed-
|
|
1913
|
+
//# sourceMappingURL=embed-SOFUZlGB.js.map
|