@snowcone-app/canvas 0.21.3 → 0.22.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/STYLING_CONTRACT.md +17 -7
- package/dist/{EditorCanvasImpl-M7rw1c1k.js → EditorCanvasImpl-BH_bKy-F.js} +2 -2
- package/dist/{EditorCanvasImpl-M7rw1c1k.js.map → EditorCanvasImpl-BH_bKy-F.js.map} +1 -1
- package/dist/api/embed.d.ts +3 -1
- package/dist/components/editor/EditorCanvas.d.ts +9 -0
- package/dist/components/editor/EditorRoot.d.ts +11 -0
- package/dist/components/embed-realtime/validateEmbed.d.ts +10 -4
- package/dist/design/product-config.d.ts +48 -0
- package/dist/editorErrors-B2mb1sVN.js.map +1 -1
- package/dist/{embed-QBZkgWDr.js → embed-8ecUMMH-.js} +524 -430
- package/dist/embed-8ecUMMH-.js.map +1 -0
- package/dist/embed.mjs +30 -29
- package/dist/errors/editorError.d.ts +3 -0
- package/example/package.json +1 -1
- package/package.json +1 -1
- package/dist/embed-QBZkgWDr.js.map +0 -1
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
import { E as
|
|
1
|
+
import { E as Ee, o as xe, p as ke, C as Ie, q as M, r as Re, t as Se, v as Ce, w as Oe, x as Ne, g as Te, e as _e } from "./UnifiedFontService-CC3CSmH5.js";
|
|
2
2
|
import { y as $ } from "./FontAnalyzer-CwIpgTGd.js";
|
|
3
|
-
import { jsx as
|
|
4
|
-
import { useContext as
|
|
5
|
-
import { assertVariantSelected as
|
|
6
|
-
import { i as
|
|
7
|
-
import { u as
|
|
8
|
-
import { s as
|
|
9
|
-
import { D as
|
|
3
|
+
import { jsx as o, jsxs as C, Fragment as $e } from "react/jsx-runtime";
|
|
4
|
+
import { useContext as De, createContext as Ae, useRef as R, useState as O, useMemo as T, useSyncExternalStore as j, useEffect as B, Component as Be, forwardRef as ce, useId as ne, useLayoutEffect as W, useCallback as q } from "react";
|
|
5
|
+
import { assertVariantSelected as Le, RenderSession as Ve, createCartDetail as Ue } from "@snowcone-app/sdk";
|
|
6
|
+
import { i as le, g as _, B as Fe, E as je, r as qe } from "./editorErrors-B2mb1sVN.js";
|
|
7
|
+
import { u as Me, p as ze } from "./usePieceGuideBundle-CbJJg66S.js";
|
|
8
|
+
import { s as re, i as Pe } from "./design-builder-CT4DHIPe.js";
|
|
9
|
+
import { D as He, C as Ke, g as Ge, e as We } from "./template-fields-C2pSfMBh.js";
|
|
10
10
|
import "./CanvasStateV1-DmZ1Qvvn.js";
|
|
11
|
-
const
|
|
12
|
-
function
|
|
13
|
-
const t =
|
|
11
|
+
const ue = Ae(void 0);
|
|
12
|
+
function Q() {
|
|
13
|
+
const t = De(ue);
|
|
14
14
|
if (!t)
|
|
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 t;
|
|
19
19
|
}
|
|
20
|
-
const
|
|
21
|
-
function
|
|
22
|
-
var r,
|
|
20
|
+
const Qe = "[RealtimeEmbed]";
|
|
21
|
+
function Je(t) {
|
|
22
|
+
var r, s;
|
|
23
23
|
if ((r = t == null ? void 0 : t.requiredPlacements) != null && r.length)
|
|
24
24
|
return t.requiredPlacements.filter((a) => !a.autoFilledByVariant).map((a) => a.label);
|
|
25
25
|
const e = new Set(
|
|
26
|
-
(((
|
|
26
|
+
(((s = t == null ? void 0 : t.options) == null ? void 0 : s.combinations) ?? []).map((a) => a.variantId).filter((a) => typeof a == "string" && a !== "")
|
|
27
27
|
);
|
|
28
28
|
return !!(t != null && t.variantId) || e.size > 1 ? [] : (t == null ? void 0 : t.placements) ?? [];
|
|
29
29
|
}
|
|
30
|
-
function
|
|
31
|
-
var
|
|
32
|
-
const
|
|
33
|
-
if (t ||
|
|
30
|
+
function me({ shop: t, product: e, design: n, hasGrant: r }) {
|
|
31
|
+
var f, u;
|
|
32
|
+
const s = [];
|
|
33
|
+
if (t || s.push({
|
|
34
34
|
severity: "error",
|
|
35
35
|
issue: "missing-shop",
|
|
36
36
|
message: "`shop` is required (your publishable shop id)."
|
|
37
|
-
}), r ||
|
|
37
|
+
}), r || s.push({
|
|
38
38
|
severity: "error",
|
|
39
39
|
issue: "missing-grant",
|
|
40
40
|
message: "no grant source — pass `grantUrl` (a proxy to mintRealtimeGrant) or `grant`. Without it the session can never authorize and no mockup renders."
|
|
41
|
-
}), (
|
|
41
|
+
}), (f = e == null ? void 0 : e.mockupIds) != null && f.length || s.push({
|
|
42
42
|
severity: "error",
|
|
43
43
|
issue: "empty-mockup-ids",
|
|
44
44
|
message: 'product.mockupIds is empty — pass the catalog scene codes (product.mockups[].id) you want rendered, e.g. ["FV1qjO"].'
|
|
45
45
|
}), e != null && e.options)
|
|
46
46
|
try {
|
|
47
|
-
|
|
48
|
-
} catch (
|
|
49
|
-
|
|
47
|
+
Le(e);
|
|
48
|
+
} catch (m) {
|
|
49
|
+
s.push({
|
|
50
50
|
severity: "error",
|
|
51
51
|
issue: "variant-required",
|
|
52
|
-
message:
|
|
52
|
+
message: m instanceof Error ? m.message : String(m)
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
-
const a = n.toJSON(),
|
|
56
|
-
|
|
55
|
+
const a = n.toJSON(), d = a.activeArtboard, c = Je(e);
|
|
56
|
+
c.length > 1 && s.push({
|
|
57
57
|
severity: "error",
|
|
58
58
|
issue: "multi-placement",
|
|
59
|
-
message: `product ${e.productId} requires placements [${
|
|
60
|
-
}), (
|
|
59
|
+
message: `product ${e.productId} requires placements [${c.join(", ")}] but this embed renders a single placement ("${d}"). The render will time out waiting for the others. This product needs the eject path — see https://developers.snowcone.app/embed-mode#eject.`
|
|
60
|
+
}), (u = e == null ? void 0 : e.placements) != null && u.length && !e.placements.includes(d) && s.push({
|
|
61
61
|
severity: "error",
|
|
62
62
|
issue: "placement-mismatch",
|
|
63
|
-
message: `the design's placement "${
|
|
63
|
+
message: `the design's placement "${d}" is not in product.placements [${e.placements.join(", ")}]. The canvas artboard name and renderState placement must equal a real product placement label, or the server renders a blank mockup. Fix the \`name\` passed to design({ name }).`
|
|
64
64
|
});
|
|
65
|
-
const
|
|
66
|
-
return i.length &&
|
|
65
|
+
const l = a.elements.map((m) => m.name).filter((m) => !!m), i = l.filter((m, y) => l.indexOf(m) !== y);
|
|
66
|
+
return i.length && s.push({
|
|
67
67
|
severity: "warn",
|
|
68
68
|
issue: "duplicate-layer-names",
|
|
69
69
|
message: `duplicate layer name(s) [${[...new Set(i)].join(", ")}] — useTextBinding(name) / useImageBinding(name) bind to the FIRST match, so a duplicate name makes a control edit the wrong layer. Keep names unique.`
|
|
70
|
-
}),
|
|
70
|
+
}), s;
|
|
71
71
|
}
|
|
72
|
-
function
|
|
73
|
-
for (const e of
|
|
74
|
-
(e.severity === "error" && e.issue !== "placement-mismatch" ? console.error : console.warn)(`${
|
|
72
|
+
function Ye(t) {
|
|
73
|
+
for (const e of me(t))
|
|
74
|
+
(e.severity === "error" && e.issue !== "placement-mismatch" ? console.error : console.warn)(`${Qe} ${e.message}`);
|
|
75
75
|
}
|
|
76
|
-
const
|
|
77
|
-
function
|
|
78
|
-
return `[RealtimeEmbed] No mockup after ${Math.round(
|
|
76
|
+
const pe = 8e3;
|
|
77
|
+
function Xe(t) {
|
|
78
|
+
return `[RealtimeEmbed] No mockup after ${Math.round(pe / 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 "${t}" — 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 "${t}" not existing on the product. The render may still arrive — this is a heads-up, not a failure.`;
|
|
79
79
|
}
|
|
80
|
-
function
|
|
80
|
+
function Ze(t) {
|
|
81
81
|
if ("grantUrl" in t && t.grantUrl)
|
|
82
82
|
return { grantUrl: t.grantUrl };
|
|
83
83
|
const e = t.grant;
|
|
84
84
|
return typeof e == "function" ? { getToken: e } : { getToken: () => Promise.resolve(e) };
|
|
85
85
|
}
|
|
86
|
-
function
|
|
87
|
-
const n =
|
|
88
|
-
return /* @__PURE__ */
|
|
86
|
+
function fe({ error: t, onRetry: e }) {
|
|
87
|
+
const n = le(t) ? t.code : "EDITOR_ERROR";
|
|
88
|
+
return /* @__PURE__ */ C(
|
|
89
89
|
"div",
|
|
90
90
|
{
|
|
91
91
|
"data-sc-part": "error",
|
|
@@ -101,12 +101,12 @@ function ue({ error: t, onRetry: e }) {
|
|
|
101
101
|
lineHeight: 1.5
|
|
102
102
|
},
|
|
103
103
|
children: [
|
|
104
|
-
/* @__PURE__ */
|
|
104
|
+
/* @__PURE__ */ C("p", { style: { margin: 0, fontWeight: 700 }, children: [
|
|
105
105
|
"Editor failed: ",
|
|
106
106
|
n
|
|
107
107
|
] }),
|
|
108
|
-
/* @__PURE__ */
|
|
109
|
-
e ? /* @__PURE__ */
|
|
108
|
+
/* @__PURE__ */ o("p", { style: { margin: "4px 0 0" }, children: t.message }),
|
|
109
|
+
e ? /* @__PURE__ */ o(
|
|
110
110
|
"button",
|
|
111
111
|
{
|
|
112
112
|
type: "button",
|
|
@@ -130,7 +130,7 @@ function ue({ error: t, onRetry: e }) {
|
|
|
130
130
|
}
|
|
131
131
|
);
|
|
132
132
|
}
|
|
133
|
-
class
|
|
133
|
+
class et extends Be {
|
|
134
134
|
constructor() {
|
|
135
135
|
super(...arguments), this.state = { caught: null };
|
|
136
136
|
}
|
|
@@ -139,33 +139,34 @@ class Je extends $e {
|
|
|
139
139
|
}
|
|
140
140
|
componentDidCatch(e) {
|
|
141
141
|
var n;
|
|
142
|
-
|
|
142
|
+
qe(e), typeof $ < "u" && ((n = $.env) == null ? void 0 : n.NODE_ENV) !== "production" && console.error("[Editor.Root] contained a composition error:", e);
|
|
143
143
|
}
|
|
144
144
|
render() {
|
|
145
|
-
return this.state.caught ? /* @__PURE__ */
|
|
145
|
+
return this.state.caught ? /* @__PURE__ */ o(fe, { error: this.state.caught }) : this.props.children;
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
function
|
|
148
|
+
function tt({ reportedError: t, onRetry: e, children: n }) {
|
|
149
149
|
if (t) {
|
|
150
|
-
const r =
|
|
151
|
-
return /* @__PURE__ */
|
|
150
|
+
const r = le(t) && t.code === "E_CHUNK_LOAD_FAILED";
|
|
151
|
+
return /* @__PURE__ */ o(fe, { error: t, onRetry: r ? e : void 0 });
|
|
152
152
|
}
|
|
153
|
-
return /* @__PURE__ */
|
|
153
|
+
return /* @__PURE__ */ o(et, { reportedError: null, onRetry: e, children: n });
|
|
154
154
|
}
|
|
155
|
-
function
|
|
155
|
+
function nt(t) {
|
|
156
156
|
const {
|
|
157
157
|
shop: e,
|
|
158
158
|
product: n,
|
|
159
159
|
design: r,
|
|
160
|
-
throttleMs:
|
|
160
|
+
throttleMs: s = 200,
|
|
161
161
|
onMockups: a,
|
|
162
|
-
onRenderError:
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
162
|
+
onRenderError: d,
|
|
163
|
+
onIssue: c,
|
|
164
|
+
wsUrl: l,
|
|
165
|
+
services: i,
|
|
166
|
+
children: f,
|
|
167
|
+
internals: u,
|
|
167
168
|
__validation: m = "throw"
|
|
168
|
-
} = t,
|
|
169
|
+
} = t, y = T(() => r.toJSON().activeArtboard, [r]), b = T(() => {
|
|
169
170
|
const p = r.toJSON().artboards[0];
|
|
170
171
|
if (p)
|
|
171
172
|
return {
|
|
@@ -175,160 +176,171 @@ function Xe(t) {
|
|
|
175
176
|
...p.backgroundColor ? { backgroundColor: p.backgroundColor } : {}
|
|
176
177
|
};
|
|
177
178
|
}, [r]);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
179
|
+
j(
|
|
180
|
+
u.commerce.subscribe,
|
|
181
|
+
u.commerce.getVersion,
|
|
182
|
+
u.commerce.getVersion
|
|
182
183
|
);
|
|
183
|
-
const
|
|
184
|
-
if (!
|
|
184
|
+
const v = u.commerce.renderVariantId(), w = Me(v ?? n.variantId ?? n.defaultGvid), h = T(() => {
|
|
185
|
+
if (!w) return null;
|
|
185
186
|
const p = r.toJSON().artboards[0];
|
|
186
|
-
return
|
|
187
|
-
}, [
|
|
188
|
-
|
|
189
|
-
const [
|
|
190
|
-
O(() => {
|
|
187
|
+
return ze(w, p) ?? null;
|
|
188
|
+
}, [w, r]), x = R(a), g = R(d), N = R(c);
|
|
189
|
+
x.current = a, g.current = d, N.current = c;
|
|
190
|
+
const [S, L] = O([]), [D, V] = O(!0), [z, P] = O(null), J = !!("grantUrl" in t && t.grantUrl || "grant" in t && t.grant), Y = Ze(t), be = "grantUrl" in Y ? Y.grantUrl : "getToken", ie = `${n.productId}|${n.mockupIds.join(",")}|${n.variantId ?? ""}`, F = `${e}|${ie}|${y}|${J}`, X = T(() => {
|
|
191
191
|
var I;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
const p = me({ shop: e, product: n, design: r, hasGrant: J });
|
|
193
|
+
if (m !== "throw") return p;
|
|
194
|
+
const E = p.find((A) => A.severity === "error");
|
|
195
|
+
if (E)
|
|
196
|
+
throw new _("E_EMBED_CONFIG", E.message, {
|
|
197
|
+
issue: E.issue,
|
|
197
198
|
docSlug: "embed-mode"
|
|
198
199
|
});
|
|
199
|
-
for (const
|
|
200
|
-
typeof $ < "u" && ((I = $.env) == null ? void 0 : I.NODE_ENV) !== "production" && console.warn(`[Editor.Root] ${
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
200
|
+
for (const A of p)
|
|
201
|
+
typeof $ < "u" && ((I = $.env) == null ? void 0 : I.NODE_ENV) !== "production" && console.warn(`[Editor.Root] ${A.message}`);
|
|
202
|
+
return p;
|
|
203
|
+
}, [F, m]), se = R(null);
|
|
204
|
+
B(() => {
|
|
205
|
+
var p;
|
|
206
|
+
if (X.length !== 0 && se.current !== F) {
|
|
207
|
+
se.current = F;
|
|
208
|
+
for (const E of X) (p = N.current) == null || p.call(N, E);
|
|
209
|
+
}
|
|
210
|
+
}, [X, F]);
|
|
211
|
+
const oe = R(null);
|
|
212
|
+
B(() => {
|
|
204
213
|
var p;
|
|
205
214
|
if (m === "warn" && typeof $ < "u" && ((p = $.env) == null ? void 0 : p.NODE_ENV) !== "production") {
|
|
206
|
-
if (
|
|
207
|
-
|
|
215
|
+
if (oe.current === F) return;
|
|
216
|
+
oe.current = F, Ye({ shop: e, product: n, design: r, hasGrant: J });
|
|
208
217
|
}
|
|
209
|
-
}, [
|
|
210
|
-
const
|
|
218
|
+
}, [F, m]);
|
|
219
|
+
const H = T(
|
|
211
220
|
() => {
|
|
212
221
|
try {
|
|
213
|
-
return { session: new
|
|
222
|
+
return { session: new Ve({ shop: e, product: n, wsUrl: l, ...Y }) };
|
|
214
223
|
} catch (p) {
|
|
215
224
|
return { error: p instanceof Error ? p.message : String(p) };
|
|
216
225
|
}
|
|
217
226
|
},
|
|
218
227
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
219
|
-
[e,
|
|
220
|
-
),
|
|
221
|
-
|
|
222
|
-
var
|
|
223
|
-
const
|
|
224
|
-
|
|
228
|
+
[e, ie, y, l, be]
|
|
229
|
+
), k = "session" in H ? H.session : null, K = "error" in H ? H.error : null, G = T(() => (p, E = s) => {
|
|
230
|
+
k && (P(null), V(!0), k.renderState(y, p, E).catch((I) => {
|
|
231
|
+
var de;
|
|
232
|
+
const A = I instanceof Error ? I.message : String(I);
|
|
233
|
+
P(A), V(!1), (de = g.current) == null || de.call(g, A);
|
|
225
234
|
}));
|
|
226
|
-
}, [
|
|
227
|
-
|
|
235
|
+
}, [k, y, s]);
|
|
236
|
+
B(() => {
|
|
228
237
|
var p;
|
|
229
|
-
if (
|
|
230
|
-
|
|
238
|
+
if (K) {
|
|
239
|
+
P(K), V(!1), (p = g.current) == null || p.call(g, K);
|
|
231
240
|
return;
|
|
232
241
|
}
|
|
233
|
-
if (
|
|
234
|
-
return
|
|
242
|
+
if (k)
|
|
243
|
+
return k.onMockups((E) => {
|
|
235
244
|
var I;
|
|
236
|
-
L(
|
|
237
|
-
}),
|
|
245
|
+
L(E), V(!1), (I = x.current) == null || I.call(x, E);
|
|
246
|
+
}), k.onError((E) => {
|
|
238
247
|
var I;
|
|
239
|
-
|
|
240
|
-
}),
|
|
241
|
-
}, [
|
|
242
|
-
const
|
|
248
|
+
P(E), V(!1), (I = g.current) == null || I.call(g, E);
|
|
249
|
+
}), G(r.toServerRequest()), () => k.close();
|
|
250
|
+
}, [k, K]);
|
|
251
|
+
const Z = R({
|
|
243
252
|
session: null,
|
|
244
253
|
variantId: void 0
|
|
245
254
|
});
|
|
246
|
-
|
|
247
|
-
if (!
|
|
248
|
-
const p =
|
|
249
|
-
if (
|
|
250
|
-
|
|
255
|
+
B(() => {
|
|
256
|
+
if (!k || !v) return;
|
|
257
|
+
const p = Z.current, E = p.session === k ? p.variantId : n.variantId;
|
|
258
|
+
if (v === E) {
|
|
259
|
+
Z.current = { session: k, variantId: E };
|
|
251
260
|
return;
|
|
252
261
|
}
|
|
253
|
-
|
|
254
|
-
}, [
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
262
|
+
Z.current = { session: k, variantId: v }, k.setProduct({ ...n, variantId: v }), G(re(u.store.getState()));
|
|
263
|
+
}, [k, v]), B(() => {
|
|
264
|
+
if (!D) return;
|
|
265
|
+
const p = setTimeout(() => {
|
|
266
|
+
var I, A;
|
|
267
|
+
const E = Xe(y);
|
|
268
|
+
typeof $ < "u" && ((I = $.env) == null ? void 0 : I.NODE_ENV) !== "production" && console.warn(E), (A = N.current) == null || A.call(N, { severity: "warn", issue: "slow-render", message: E });
|
|
269
|
+
}, pe);
|
|
258
270
|
return () => clearTimeout(p);
|
|
259
|
-
}, [
|
|
260
|
-
const
|
|
271
|
+
}, [D, y]);
|
|
272
|
+
const ve = T(
|
|
261
273
|
() => ({
|
|
262
|
-
session:
|
|
274
|
+
session: k,
|
|
263
275
|
design: r,
|
|
264
|
-
placement:
|
|
276
|
+
placement: y,
|
|
265
277
|
product: n,
|
|
266
|
-
mockups:
|
|
267
|
-
isRendering:
|
|
268
|
-
error:
|
|
269
|
-
throttleMs:
|
|
270
|
-
pieceGuides:
|
|
271
|
-
pushRender:
|
|
272
|
-
stateStore:
|
|
278
|
+
mockups: S,
|
|
279
|
+
isRendering: D,
|
|
280
|
+
error: z,
|
|
281
|
+
throttleMs: s,
|
|
282
|
+
pieceGuides: h,
|
|
283
|
+
pushRender: G,
|
|
284
|
+
stateStore: u.store
|
|
273
285
|
}),
|
|
274
|
-
[
|
|
275
|
-
),
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
286
|
+
[k, r, y, n, S, D, z, s, h, G, u.store]
|
|
287
|
+
), we = j(
|
|
288
|
+
u.registry.subscribe,
|
|
289
|
+
u.registry.getVersion,
|
|
290
|
+
u.registry.getVersion
|
|
279
291
|
);
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
|
|
292
|
+
T(() => u.registry.validate(), [u.registry, we]);
|
|
293
|
+
const ae = /* @__PURE__ */ o(ke.Provider, { value: u, children: /* @__PURE__ */ o(ue.Provider, { value: ve, children: /* @__PURE__ */ o(Fe.Provider, { value: u.registry, children: /* @__PURE__ */ o(
|
|
294
|
+
je,
|
|
283
295
|
{
|
|
284
|
-
...
|
|
285
|
-
children:
|
|
296
|
+
...b ? { initialArtboardConfig: b } : {},
|
|
297
|
+
children: f
|
|
286
298
|
}
|
|
287
299
|
) }) }) });
|
|
288
|
-
return
|
|
300
|
+
return i ? /* @__PURE__ */ o(Ie, { services: i, children: ae }) : ae;
|
|
289
301
|
}
|
|
290
|
-
function
|
|
291
|
-
const { design: e, product: n } = t, r = `${n.productId}|${n.variantId ?? ""}`,
|
|
292
|
-
(
|
|
302
|
+
function he(t) {
|
|
303
|
+
const { design: e, product: n } = t, r = `${n.productId}|${n.variantId ?? ""}`, s = R(null), a = R(null), [d, c] = O(null);
|
|
304
|
+
(s.current === null || s.current.design !== e) && (s.current = {
|
|
293
305
|
design: e,
|
|
294
306
|
internals: {
|
|
295
|
-
store: new
|
|
296
|
-
registry: new
|
|
307
|
+
store: new He(e.toJSON()),
|
|
308
|
+
registry: new Ee()
|
|
297
309
|
}
|
|
298
|
-
}), (a.current === null || a.current.productIdentity !== r) && (a.current = { productIdentity: r, commerce: new
|
|
299
|
-
const
|
|
310
|
+
}), (a.current === null || a.current.productIdentity !== r) && (a.current = { productIdentity: r, commerce: new Ke(n) });
|
|
311
|
+
const l = T(
|
|
300
312
|
() => ({
|
|
301
|
-
...
|
|
313
|
+
...s.current.internals,
|
|
302
314
|
commerce: a.current.commerce,
|
|
303
|
-
...
|
|
315
|
+
...xe(c)
|
|
304
316
|
}),
|
|
305
317
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
306
|
-
[
|
|
318
|
+
[s.current.internals, a.current.commerce]
|
|
307
319
|
);
|
|
308
320
|
return (
|
|
309
321
|
// `display: contents` — the .sc-root scope without a layout box, so the
|
|
310
322
|
// host's grid/flex sees the parts directly (and the legacy RealtimeEmbed
|
|
311
323
|
// wrapper, which had no DOM at all, stays layout-identical).
|
|
312
|
-
/* @__PURE__ */
|
|
324
|
+
/* @__PURE__ */ o("div", { className: "sc-root", style: { display: "contents" }, "data-sc-part": "root", children: /* @__PURE__ */ o(tt, { reportedError: d, onRetry: () => c(null), children: /* @__PURE__ */ o(nt, { ...t, internals: l }) }) })
|
|
313
325
|
);
|
|
314
326
|
}
|
|
315
|
-
let
|
|
316
|
-
function
|
|
317
|
-
return
|
|
327
|
+
let rt = () => import("./EditorCanvasImpl-BH_bKy-F.js").then((t) => t.EditorCanvasImpl);
|
|
328
|
+
function ge() {
|
|
329
|
+
return rt();
|
|
318
330
|
}
|
|
319
|
-
const
|
|
320
|
-
const c =
|
|
321
|
-
W(() => c.registry.registerCanvas(
|
|
322
|
-
const [
|
|
323
|
-
return
|
|
324
|
-
let
|
|
325
|
-
return
|
|
331
|
+
const it = ce(function({ children: e, maxHeight: n, floatingToolbar: r = !0, className: s, style: a }, d) {
|
|
332
|
+
const c = M("Editor.Canvas"), l = ne();
|
|
333
|
+
W(() => c.registry.registerCanvas(l), [c.registry, l]);
|
|
334
|
+
const [i, f] = O(null);
|
|
335
|
+
return B(() => {
|
|
336
|
+
let u = !1;
|
|
337
|
+
return ge().then(
|
|
326
338
|
(m) => {
|
|
327
|
-
|
|
339
|
+
u || f(() => m);
|
|
328
340
|
},
|
|
329
341
|
(m) => {
|
|
330
|
-
|
|
331
|
-
new
|
|
342
|
+
u || c.reportRuntimeError(
|
|
343
|
+
new _(
|
|
332
344
|
"E_CHUNK_LOAD_FAILED",
|
|
333
345
|
`the editor's rendering chunk failed to load (${m instanceof Error ? m.message : String(m)}). This is a network/CDN failure, not a composition mistake — retry, or check the deployment serves the @snowcone-app/canvas lazy chunks.`,
|
|
334
346
|
{ cause: m instanceof Error ? m.message : String(m), docSlug: "embed-mode" }
|
|
@@ -336,102 +348,127 @@ const et = ie(function({ children: e, maxHeight: n, className: r, style: o }, a)
|
|
|
336
348
|
);
|
|
337
349
|
}
|
|
338
350
|
), () => {
|
|
339
|
-
|
|
351
|
+
u = !0;
|
|
340
352
|
};
|
|
341
|
-
}, [c]),
|
|
353
|
+
}, [c]), i ? (
|
|
342
354
|
// `builtinControls`: the canvas owns the floating contextual toolbar
|
|
343
|
-
// unless
|
|
344
|
-
//
|
|
345
|
-
|
|
346
|
-
|
|
355
|
+
// unless the host opts out via `floatingToolbar={false}` or a docked
|
|
356
|
+
// <Editor.Controls> is mounted (ADR-0085 §5). Only here — the legacy
|
|
357
|
+
// <RealtimeCanvas> wrapper stays chrome-less.
|
|
358
|
+
/* @__PURE__ */ o(
|
|
359
|
+
i,
|
|
360
|
+
{
|
|
361
|
+
ref: d,
|
|
362
|
+
kit: "embed-only",
|
|
363
|
+
partAttr: "canvas",
|
|
364
|
+
builtinControls: r,
|
|
365
|
+
maxHeight: n,
|
|
366
|
+
className: s,
|
|
367
|
+
style: a,
|
|
368
|
+
children: e
|
|
369
|
+
}
|
|
370
|
+
)
|
|
371
|
+
) : /* @__PURE__ */ o(
|
|
347
372
|
"div",
|
|
348
373
|
{
|
|
349
374
|
"data-sc-part": "canvas",
|
|
350
375
|
"data-sc-state": "loading",
|
|
351
|
-
className:
|
|
352
|
-
style: { minHeight: n ?? 200, ...
|
|
376
|
+
className: s,
|
|
377
|
+
style: { minHeight: n ?? 200, ...a },
|
|
353
378
|
"aria-busy": "true"
|
|
354
379
|
}
|
|
355
380
|
);
|
|
356
|
-
}),
|
|
357
|
-
function
|
|
358
|
-
for (const e of
|
|
381
|
+
}), st = 1.2, ee = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
|
|
382
|
+
function ot(t) {
|
|
383
|
+
for (const e of ee)
|
|
359
384
|
if (e >= t) return e;
|
|
360
|
-
return
|
|
385
|
+
return ee[ee.length - 1];
|
|
361
386
|
}
|
|
362
|
-
function
|
|
363
|
-
if (!(t > 0) || !(e > 0) || e <= t *
|
|
364
|
-
const n =
|
|
387
|
+
function at(t, e) {
|
|
388
|
+
if (!(t > 0) || !(e > 0) || e <= t * st) return null;
|
|
389
|
+
const n = ot(e);
|
|
365
390
|
return `[RealtimeMockup] mockup rendered at ${t}px but displayed at ~${e} device px — the preview will look soft. Pass \`product.width\` (e.g. ${n}) on the embed for a crisp preview.`;
|
|
366
391
|
}
|
|
367
|
-
function
|
|
392
|
+
function ye({
|
|
368
393
|
mockupId: t,
|
|
369
394
|
fallback: e = null,
|
|
370
395
|
alt: n = "Live product mockup",
|
|
371
396
|
className: r,
|
|
372
|
-
style:
|
|
397
|
+
style: s
|
|
373
398
|
}) {
|
|
374
|
-
const { mockups: a, error: c } =
|
|
375
|
-
if (!(
|
|
376
|
-
return
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
399
|
+
const { mockups: a, error: d, isRendering: c } = Q(), l = R(/* @__PURE__ */ new Set()), i = t ? a.find((u) => u.mockupId === t && u.imageUrl) : a.find((u) => u.imageUrl);
|
|
400
|
+
if (!(i != null && i.imageUrl))
|
|
401
|
+
return d ? /* @__PURE__ */ o(
|
|
402
|
+
"div",
|
|
403
|
+
{
|
|
404
|
+
"data-sc-part": "preview-error",
|
|
405
|
+
"data-sc-preview-state": "error",
|
|
406
|
+
role: "alert",
|
|
407
|
+
"data-sc-error": d,
|
|
408
|
+
className: r,
|
|
409
|
+
style: s,
|
|
410
|
+
children: e ?? `Render failed: ${d}`
|
|
411
|
+
}
|
|
412
|
+
) : /* @__PURE__ */ o("div", { "data-sc-part": "preview", "data-sc-preview-state": "rendering", "aria-busy": "true", style: { display: "contents" }, children: e });
|
|
413
|
+
const f = (u) => {
|
|
414
|
+
var w;
|
|
415
|
+
if (typeof $ > "u" || ((w = $.env) == null ? void 0 : w.NODE_ENV) === "production" || typeof window > "u" || l.current.has(i.mockupId)) return;
|
|
416
|
+
const m = u.currentTarget, y = m.getBoundingClientRect().width;
|
|
417
|
+
if (y <= 0) return;
|
|
418
|
+
const b = Math.round(y * (window.devicePixelRatio || 1)), v = at(m.naturalWidth, b);
|
|
419
|
+
v && (l.current.add(i.mockupId), console.warn(v));
|
|
384
420
|
};
|
|
385
421
|
return (
|
|
386
422
|
// eslint-disable-next-line @next/next/no-img-element
|
|
387
|
-
/* @__PURE__ */
|
|
423
|
+
/* @__PURE__ */ o(
|
|
388
424
|
"img",
|
|
389
425
|
{
|
|
390
426
|
"data-sc-part": "preview",
|
|
391
|
-
|
|
427
|
+
"data-sc-preview-state": c ? "rendering" : "ready",
|
|
428
|
+
src: i.imageUrl,
|
|
392
429
|
alt: n,
|
|
393
430
|
className: r,
|
|
394
|
-
style:
|
|
395
|
-
onLoad:
|
|
431
|
+
style: s,
|
|
432
|
+
onLoad: f
|
|
396
433
|
}
|
|
397
434
|
)
|
|
398
435
|
);
|
|
399
436
|
}
|
|
400
|
-
function
|
|
401
|
-
const { layer: e, optional: n = !1, placeholder: r, className:
|
|
437
|
+
function dt(t) {
|
|
438
|
+
const { layer: e, optional: n = !1, placeholder: r, className: s, style: a } = t, d = M("Editor.TextField"), { pushRender: c, throttleMs: l, stateStore: i } = Q(), f = ne(), u = R(null);
|
|
402
439
|
if (!Pe(e))
|
|
403
|
-
throw new
|
|
440
|
+
throw new _(
|
|
404
441
|
"E_LAYER_TOKEN_REQUIRED",
|
|
405
442
|
`the \`layer\` prop must be a token minted by the design — pass layer={design.layer("name")}, not ${typeof e == "string" ? `the bare string "${e}"` : "a plain value"}. Tokens validate the name against the design's layers at mint time.`,
|
|
406
443
|
{ received: typeof e == "string" ? e : typeof e, docSlug: "embed-mode" }
|
|
407
444
|
);
|
|
408
|
-
if (
|
|
409
|
-
const
|
|
410
|
-
if (
|
|
411
|
-
throw new
|
|
445
|
+
if (u.current !== e.name) {
|
|
446
|
+
const b = i.layerKindOf(e.name);
|
|
447
|
+
if (b === void 0)
|
|
448
|
+
throw new _(
|
|
412
449
|
"E_LAYER_NOT_FOUND",
|
|
413
450
|
`no layer "${e.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(i.bindableLayerNames())}.`,
|
|
414
451
|
{ layerName: e.name, validNames: i.bindableLayerNames(), docSlug: "embed-mode" }
|
|
415
452
|
);
|
|
416
|
-
if (
|
|
417
|
-
throw new
|
|
453
|
+
if (b !== "text")
|
|
454
|
+
throw new _(
|
|
418
455
|
"E_LAYER_WRONG_KIND",
|
|
419
|
-
`layer "${e.name}" is ${
|
|
420
|
-
{ layerName: e.name, actualKind:
|
|
456
|
+
`layer "${e.name}" is ${b === null ? "not a bindable kind" : `an ${b} layer`} — <Editor.TextField> binds text layers only.`,
|
|
457
|
+
{ layerName: e.name, actualKind: b, docSlug: "embed-mode" }
|
|
421
458
|
);
|
|
422
|
-
|
|
459
|
+
u.current = e.name;
|
|
423
460
|
}
|
|
424
|
-
W(() =>
|
|
425
|
-
const
|
|
461
|
+
W(() => d.registry.registerTextField(f, { name: e.name, optional: n }), [d.registry, f, e.name, n]);
|
|
462
|
+
const m = j(
|
|
426
463
|
i.subscribe,
|
|
427
464
|
() => i.textOf(e.name) ?? "",
|
|
428
465
|
() => i.textOf(e.name) ?? ""
|
|
429
|
-
),
|
|
430
|
-
(
|
|
431
|
-
const v =
|
|
432
|
-
if (
|
|
433
|
-
|
|
434
|
-
new
|
|
466
|
+
), y = q(
|
|
467
|
+
(b) => {
|
|
468
|
+
const v = b.target.value, w = d.registry.getCanvasBridge();
|
|
469
|
+
if (w) {
|
|
470
|
+
w.setTextByName(e.name, v) || d.reportInvariant(
|
|
471
|
+
new _(
|
|
435
472
|
"E_LAYER_NOT_FOUND",
|
|
436
473
|
`layer "${e.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).`,
|
|
437
474
|
{ layerName: e.name, docSlug: "embed-mode" }
|
|
@@ -439,26 +476,26 @@ function ot(t) {
|
|
|
439
476
|
);
|
|
440
477
|
return;
|
|
441
478
|
}
|
|
442
|
-
i.updateTextLayer(e.name, v),
|
|
479
|
+
i.updateTextLayer(e.name, v), c(re(i.getState()), l);
|
|
443
480
|
},
|
|
444
|
-
[
|
|
481
|
+
[d, e.name, i, c, l]
|
|
445
482
|
);
|
|
446
|
-
return /* @__PURE__ */
|
|
483
|
+
return /* @__PURE__ */ o(
|
|
447
484
|
"input",
|
|
448
485
|
{
|
|
449
486
|
"data-sc-part": "textfield",
|
|
450
487
|
"data-sc-layer": e.name,
|
|
451
488
|
type: "text",
|
|
452
|
-
value:
|
|
453
|
-
onChange:
|
|
489
|
+
value: m,
|
|
490
|
+
onChange: y,
|
|
454
491
|
placeholder: r,
|
|
455
492
|
"aria-label": t["aria-label"] ?? e.name,
|
|
456
|
-
className:
|
|
493
|
+
className: s,
|
|
457
494
|
style: a
|
|
458
495
|
}
|
|
459
496
|
);
|
|
460
497
|
}
|
|
461
|
-
function
|
|
498
|
+
function ct(t) {
|
|
462
499
|
const e = [];
|
|
463
500
|
for (const n of t.missingOptionKeys)
|
|
464
501
|
e.push(`option:${n}`);
|
|
@@ -470,114 +507,114 @@ function st(t) {
|
|
|
470
507
|
e.push(`layer:${n.name}`);
|
|
471
508
|
continue;
|
|
472
509
|
}
|
|
473
|
-
const
|
|
474
|
-
|
|
510
|
+
const s = (t.seedTextOf(n.name) ?? "").trim();
|
|
511
|
+
s.length > 0 && r === s && e.push(`layer-seed:${n.name}`);
|
|
475
512
|
}
|
|
476
513
|
return t.hasRenderableElement || e.push("empty-design"), (!Number.isInteger(t.quantity) || t.quantity < 1) && e.push("quantity"), e;
|
|
477
514
|
}
|
|
478
|
-
function
|
|
515
|
+
function lt(t, e) {
|
|
479
516
|
const n = e.getCombinations(), r = e.getAttributes();
|
|
480
517
|
if (Object.keys(r).length === 0 || n.length === 0) return null;
|
|
481
|
-
const
|
|
482
|
-
Object.entries(r).map(([a,
|
|
518
|
+
const s = Object.fromEntries(
|
|
519
|
+
Object.entries(r).map(([a, d]) => [a, { ...d, choices: Ge(d) }])
|
|
483
520
|
);
|
|
484
|
-
return
|
|
521
|
+
return Ue({
|
|
485
522
|
productId: t.productId,
|
|
486
523
|
quantity: e.getQuantity(),
|
|
487
524
|
selection: e.getSelection(),
|
|
488
525
|
combinations: n,
|
|
489
|
-
attributes:
|
|
526
|
+
attributes: s
|
|
490
527
|
});
|
|
491
528
|
}
|
|
492
|
-
function
|
|
493
|
-
const { onAddToCart: e, defaultQuantity: n, children: r, className:
|
|
494
|
-
if (!(
|
|
495
|
-
throw new
|
|
529
|
+
function ut(t) {
|
|
530
|
+
const { onAddToCart: e, defaultQuantity: n, children: r, className: s, style: a } = t, d = M("Editor.Buy"), { product: c, stateStore: l } = Q(), i = d.commerce;
|
|
531
|
+
if (!(c != null && c.productId))
|
|
532
|
+
throw new _(
|
|
496
533
|
"E_BUY_NO_PRODUCT",
|
|
497
534
|
"<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.",
|
|
498
535
|
{ docSlug: "embed-mode" }
|
|
499
536
|
);
|
|
500
|
-
const
|
|
537
|
+
const f = R(!1);
|
|
501
538
|
W(() => {
|
|
502
|
-
|
|
539
|
+
f.current || (f.current = !0, typeof n == "number" && i.setQuantity(n));
|
|
503
540
|
}, [i]);
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
),
|
|
509
|
-
() =>
|
|
510
|
-
quantity:
|
|
541
|
+
const u = j(l.subscribe, l.getState, l.getState), m = j(i.subscribe, i.getVersion, i.getVersion), y = j(
|
|
542
|
+
d.registry.subscribe,
|
|
543
|
+
d.registry.getVersion,
|
|
544
|
+
d.registry.getVersion
|
|
545
|
+
), b = i.getQuantity(), v = T(
|
|
546
|
+
() => ct({
|
|
547
|
+
quantity: b,
|
|
511
548
|
missingOptionKeys: i.missingOptionKeys(),
|
|
512
549
|
selectionValid: i.selectionValid(),
|
|
513
|
-
textFields:
|
|
514
|
-
textOf: (
|
|
515
|
-
seedTextOf: (
|
|
516
|
-
hasRenderableElement:
|
|
550
|
+
textFields: d.registry.getTextFields(),
|
|
551
|
+
textOf: (S) => l.textOf(S),
|
|
552
|
+
seedTextOf: (S) => l.seedTextOf(S),
|
|
553
|
+
hasRenderableElement: l.hasRenderableElement()
|
|
517
554
|
}),
|
|
518
555
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
519
|
-
[i,
|
|
520
|
-
),
|
|
521
|
-
if (
|
|
522
|
-
|
|
523
|
-
const
|
|
524
|
-
productId:
|
|
525
|
-
...
|
|
556
|
+
[i, b, u, m, y]
|
|
557
|
+
), w = v.length === 0, [h, x] = O(!1), g = R(!1), N = q(() => {
|
|
558
|
+
if (g.current || !w) return;
|
|
559
|
+
g.current = !0, x(!0);
|
|
560
|
+
const S = l.getState(), L = i.resolvedVariantId(), D = {
|
|
561
|
+
productId: c.productId,
|
|
562
|
+
...L ? { variantId: L } : {},
|
|
526
563
|
quantity: i.getQuantity(),
|
|
527
564
|
selection: i.getSelection(),
|
|
528
|
-
cartDetail:
|
|
529
|
-
designState:
|
|
530
|
-
serverRequest:
|
|
565
|
+
cartDetail: lt(c, i),
|
|
566
|
+
designState: S,
|
|
567
|
+
serverRequest: re(S)
|
|
531
568
|
};
|
|
532
|
-
let
|
|
569
|
+
let V;
|
|
533
570
|
try {
|
|
534
|
-
|
|
535
|
-
} catch (
|
|
536
|
-
throw
|
|
571
|
+
V = e(D);
|
|
572
|
+
} catch (z) {
|
|
573
|
+
throw g.current = !1, x(!1), z;
|
|
537
574
|
}
|
|
538
|
-
Promise.resolve(
|
|
539
|
-
|
|
575
|
+
Promise.resolve(V).finally(() => {
|
|
576
|
+
g.current = !1, x(!1);
|
|
540
577
|
});
|
|
541
|
-
}, [
|
|
542
|
-
return /* @__PURE__ */
|
|
578
|
+
}, [w, c, i, l, e]);
|
|
579
|
+
return /* @__PURE__ */ o(
|
|
543
580
|
"button",
|
|
544
581
|
{
|
|
545
582
|
type: "button",
|
|
546
583
|
"data-sc-part": "buy",
|
|
547
|
-
"data-sc-buy-state":
|
|
584
|
+
"data-sc-buy-state": h ? "busy" : w ? "ready" : "incomplete",
|
|
548
585
|
"data-sc-buy-missing": v.join(",") || void 0,
|
|
549
|
-
disabled: !
|
|
550
|
-
"aria-busy":
|
|
551
|
-
onClick:
|
|
552
|
-
className:
|
|
586
|
+
disabled: !w || h,
|
|
587
|
+
"aria-busy": h || void 0,
|
|
588
|
+
onClick: N,
|
|
589
|
+
className: s,
|
|
553
590
|
style: a,
|
|
554
591
|
children: r ?? "Add to cart"
|
|
555
592
|
}
|
|
556
593
|
);
|
|
557
594
|
}
|
|
558
|
-
function
|
|
595
|
+
function mt({
|
|
559
596
|
placement: t = "docked",
|
|
560
597
|
className: e,
|
|
561
598
|
style: n
|
|
562
599
|
}) {
|
|
563
|
-
const r =
|
|
564
|
-
|
|
565
|
-
const
|
|
600
|
+
const r = M("Editor.Controls");
|
|
601
|
+
Re("Editor.Controls");
|
|
602
|
+
const s = ne();
|
|
566
603
|
W(
|
|
567
|
-
() => r.registry.registerControls(
|
|
568
|
-
[r.registry,
|
|
604
|
+
() => r.registry.registerControls(s, t),
|
|
605
|
+
[r.registry, s, t]
|
|
569
606
|
);
|
|
570
|
-
const a = t === "docked", [
|
|
571
|
-
return
|
|
607
|
+
const a = t === "docked", [d, c] = O(null);
|
|
608
|
+
return B(() => {
|
|
572
609
|
if (!a) return;
|
|
573
|
-
let
|
|
610
|
+
let l = !1;
|
|
574
611
|
return import("./ContextualToolbars-BDEt9ND0.js").then((i) => i.s).then(
|
|
575
612
|
(i) => {
|
|
576
|
-
|
|
613
|
+
l || c(() => i.ContextualToolbars);
|
|
577
614
|
},
|
|
578
615
|
(i) => {
|
|
579
|
-
|
|
580
|
-
new
|
|
616
|
+
l || r.reportRuntimeError(
|
|
617
|
+
new _(
|
|
581
618
|
"E_CHUNK_LOAD_FAILED",
|
|
582
619
|
`the editor's controls chunk failed to load (${i instanceof Error ? i.message : String(i)}). This is a network/CDN failure, not a composition mistake — retry, or check the deployment serves the @snowcone-app/canvas lazy chunks.`,
|
|
583
620
|
{ cause: i instanceof Error ? i.message : String(i), docSlug: "embed-mode" }
|
|
@@ -585,23 +622,23 @@ function ct({
|
|
|
585
622
|
);
|
|
586
623
|
}
|
|
587
624
|
), () => {
|
|
588
|
-
|
|
625
|
+
l = !0;
|
|
589
626
|
};
|
|
590
|
-
}, [a, r]), a ? /* @__PURE__ */
|
|
627
|
+
}, [a, r]), a ? /* @__PURE__ */ o(
|
|
591
628
|
"div",
|
|
592
629
|
{
|
|
593
630
|
"data-sc-part": "controls",
|
|
594
631
|
"data-sc-placement": "docked",
|
|
595
632
|
className: e,
|
|
596
633
|
style: n,
|
|
597
|
-
"aria-busy":
|
|
598
|
-
children:
|
|
634
|
+
"aria-busy": d ? void 0 : "true",
|
|
635
|
+
children: d ? /* @__PURE__ */ o(d, { mode: "embedded" }) : null
|
|
599
636
|
}
|
|
600
637
|
) : null;
|
|
601
638
|
}
|
|
602
|
-
function
|
|
603
|
-
const e =
|
|
604
|
-
return
|
|
639
|
+
function pt() {
|
|
640
|
+
const e = M("useProductSelection").commerce, n = j(e.subscribe, e.getVersion, e.getVersion), r = q((a, d) => e.select(a, d), [e]), s = q((a) => e.setQuantity(a), [e]);
|
|
641
|
+
return T(
|
|
605
642
|
() => ({
|
|
606
643
|
attributes: e.getAttributes(),
|
|
607
644
|
selection: e.getSelection(),
|
|
@@ -610,72 +647,128 @@ function lt() {
|
|
|
610
647
|
variantId: e.resolvedVariantId(),
|
|
611
648
|
price: e.resolvedPrice(),
|
|
612
649
|
quantity: e.getQuantity(),
|
|
613
|
-
setQuantity:
|
|
650
|
+
setQuantity: s,
|
|
614
651
|
complete: e.selectionValid(),
|
|
615
652
|
missing: e.missingOptionKeys()
|
|
616
653
|
}),
|
|
617
654
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
618
|
-
[e, r,
|
|
655
|
+
[e, r, s, n]
|
|
619
656
|
);
|
|
620
657
|
}
|
|
621
|
-
const
|
|
658
|
+
const U = {
|
|
622
659
|
/** The one provider boundary — session, design, live state, error boundary. */
|
|
623
|
-
Root:
|
|
660
|
+
Root: he,
|
|
624
661
|
/** The editable artboard (the ONE lazy renderer boundary — D9). */
|
|
625
|
-
Canvas:
|
|
662
|
+
Canvas: it,
|
|
626
663
|
/** Live product mockup. ×N under one Root is valid. */
|
|
627
|
-
Preview:
|
|
664
|
+
Preview: ye,
|
|
628
665
|
/** Form input bound to a design text layer by typed token (T1). */
|
|
629
|
-
TextField:
|
|
666
|
+
TextField: dt,
|
|
630
667
|
/** Smart commerce part: completeness + payload assembly; submit = host callback. */
|
|
631
|
-
Buy:
|
|
668
|
+
Buy: ut,
|
|
632
669
|
/** Layer list. The one editor part that works canvas-free (ADR-0085 §4). */
|
|
633
|
-
Layers:
|
|
670
|
+
Layers: Ne,
|
|
634
671
|
/** Morphing contextual zone — ONE coarse part; placement docked|floating (§5). */
|
|
635
|
-
Controls:
|
|
672
|
+
Controls: mt,
|
|
636
673
|
/** Undo/redo controls. Requires Editor.Canvas. */
|
|
637
|
-
History:
|
|
674
|
+
History: Oe,
|
|
638
675
|
/** The one ⋯ overflow menu. Requires Editor.Canvas. */
|
|
639
|
-
Menu:
|
|
676
|
+
Menu: Ce,
|
|
640
677
|
/** The ⊕ add-element menu. Requires Editor.Canvas. */
|
|
641
|
-
Add:
|
|
678
|
+
Add: Se
|
|
642
679
|
};
|
|
643
|
-
function
|
|
644
|
-
return /* @__PURE__ */
|
|
680
|
+
function $t(t) {
|
|
681
|
+
return /* @__PURE__ */ o(he, { ...t, __validation: "warn" });
|
|
645
682
|
}
|
|
646
|
-
const
|
|
683
|
+
const Dt = ce(
|
|
647
684
|
function(e, n) {
|
|
648
|
-
const { children: r, className:
|
|
649
|
-
return
|
|
650
|
-
let
|
|
651
|
-
return
|
|
652
|
-
(
|
|
653
|
-
|
|
685
|
+
const { children: r, className: s, style: a, maxHeight: d, ...c } = e, [l, i] = O(null);
|
|
686
|
+
return B(() => {
|
|
687
|
+
let f = !1;
|
|
688
|
+
return ge().then(
|
|
689
|
+
(u) => {
|
|
690
|
+
f || i(() => u);
|
|
654
691
|
},
|
|
655
|
-
(
|
|
656
|
-
console.error("[RealtimeCanvas] failed to load the rendering chunk:",
|
|
692
|
+
(u) => {
|
|
693
|
+
console.error("[RealtimeCanvas] failed to load the rendering chunk:", u);
|
|
657
694
|
}
|
|
658
695
|
), () => {
|
|
659
|
-
|
|
696
|
+
f = !0;
|
|
660
697
|
};
|
|
661
|
-
}, []),
|
|
698
|
+
}, []), l ? /* @__PURE__ */ o(l, { ref: n, selfScope: !0, maxHeight: d, className: s, style: a, ...c, children: r }) : /* @__PURE__ */ o(
|
|
662
699
|
"div",
|
|
663
700
|
{
|
|
664
|
-
className: `sc-root${
|
|
665
|
-
style: { minHeight:
|
|
701
|
+
className: `sc-root${s ? ` ${s}` : ""}`,
|
|
702
|
+
style: { minHeight: d ?? 200, ...a },
|
|
666
703
|
"aria-busy": "true"
|
|
667
704
|
}
|
|
668
705
|
);
|
|
669
706
|
}
|
|
670
707
|
);
|
|
671
|
-
function
|
|
672
|
-
return /* @__PURE__ */
|
|
708
|
+
function At(t) {
|
|
709
|
+
return /* @__PURE__ */ o(ye, { ...t });
|
|
673
710
|
}
|
|
674
|
-
function
|
|
675
|
-
const { mockups: t, isRendering: e, error: n } =
|
|
711
|
+
function Bt() {
|
|
712
|
+
const { mockups: t, isRendering: e, error: n } = Q();
|
|
676
713
|
return { mockups: t, isRendering: e, error: n };
|
|
677
714
|
}
|
|
678
|
-
function
|
|
715
|
+
function ft(t) {
|
|
716
|
+
return t.type !== "color" && typeof t.width == "number" && t.width > 0 && typeof t.height == "number" && t.height > 0;
|
|
717
|
+
}
|
|
718
|
+
function Lt(t, e = {}) {
|
|
719
|
+
var m, y, b, v, w;
|
|
720
|
+
const n = (t.placements ?? []).filter(ft), r = n.map((h) => h.label), s = e.placement ? n.find((h) => h.label === e.placement) : n[0];
|
|
721
|
+
if (!s)
|
|
722
|
+
throw e.placement ? new _(
|
|
723
|
+
"E_PRODUCT_NOT_RENDERABLE",
|
|
724
|
+
`product ${t.id} has no renderable placement "${e.placement}". Renderable image placements: [${r.join(", ")}].`,
|
|
725
|
+
{ productId: t.id, requested: e.placement, validNames: r, docSlug: "embed-mode" }
|
|
726
|
+
) : new _(
|
|
727
|
+
"E_PRODUCT_NOT_RENDERABLE",
|
|
728
|
+
`product ${t.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.`,
|
|
729
|
+
{ productId: t.id, docSlug: "embed-mode" }
|
|
730
|
+
);
|
|
731
|
+
const a = ((m = t.options) == null ? void 0 : m.attributes) ?? {}, c = Object.values(a).some(
|
|
732
|
+
(h) => {
|
|
733
|
+
var x;
|
|
734
|
+
return (x = h == null ? void 0 : h.choices) == null ? void 0 : x.some((g) => g == null ? void 0 : g.hex);
|
|
735
|
+
}
|
|
736
|
+
) ? (v = (b = (y = t.options) == null ? void 0 : y.combinations) == null ? void 0 : b.find(
|
|
737
|
+
(h) => typeof h.variantId == "string" && h.variantId !== ""
|
|
738
|
+
)) == null ? void 0 : v.variantId : void 0, l = t.mockups ?? [], i = c ? l.filter((h) => {
|
|
739
|
+
var x;
|
|
740
|
+
return (x = h.gvids) == null ? void 0 : x.includes(c);
|
|
741
|
+
}) : l, f = (i.length > 0 ? i : l).map((h) => h.id);
|
|
742
|
+
if (f.length === 0)
|
|
743
|
+
throw new _(
|
|
744
|
+
"E_PRODUCT_NOT_RENDERABLE",
|
|
745
|
+
`product ${t.id} has no mockup scenes — nothing to render a preview into.`,
|
|
746
|
+
{ productId: t.id, docSlug: "embed-mode" }
|
|
747
|
+
);
|
|
748
|
+
return {
|
|
749
|
+
product: {
|
|
750
|
+
productId: t.id,
|
|
751
|
+
mockupIds: f,
|
|
752
|
+
...typeof c == "string" ? { variantId: c } : {},
|
|
753
|
+
options: t.options,
|
|
754
|
+
placements: (w = t.placements) == null ? void 0 : w.map((h) => h.label),
|
|
755
|
+
mockups: l,
|
|
756
|
+
requiredPlacements: t.requiredPlacements,
|
|
757
|
+
...t.defaultGvid ? { defaultGvid: t.defaultGvid } : {},
|
|
758
|
+
...typeof e.width == "number" ? { width: e.width } : {}
|
|
759
|
+
},
|
|
760
|
+
placement: {
|
|
761
|
+
label: s.label,
|
|
762
|
+
width: s.width,
|
|
763
|
+
height: s.height,
|
|
764
|
+
aspectRatio: s.width / s.height
|
|
765
|
+
},
|
|
766
|
+
placementLabels: r,
|
|
767
|
+
primaryMockupId: f[0],
|
|
768
|
+
variantId: c
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
function ht(t) {
|
|
679
772
|
return new Intl.NumberFormat("en-US", {
|
|
680
773
|
style: "currency",
|
|
681
774
|
currency: "USD",
|
|
@@ -683,7 +776,7 @@ function dt(t) {
|
|
|
683
776
|
maximumFractionDigits: t % 100 === 0 ? 0 : 2
|
|
684
777
|
}).format(t / 100);
|
|
685
778
|
}
|
|
686
|
-
const
|
|
779
|
+
const gt = {
|
|
687
780
|
display: "inline-flex",
|
|
688
781
|
alignItems: "center",
|
|
689
782
|
justifyContent: "center",
|
|
@@ -698,7 +791,7 @@ const ut = {
|
|
|
698
791
|
fontSize: 16,
|
|
699
792
|
lineHeight: 1,
|
|
700
793
|
cursor: "pointer"
|
|
701
|
-
},
|
|
794
|
+
}, yt = {
|
|
702
795
|
display: "flex",
|
|
703
796
|
alignItems: "center",
|
|
704
797
|
gap: 10,
|
|
@@ -714,55 +807,55 @@ const ut = {
|
|
|
714
807
|
textAlign: "left",
|
|
715
808
|
cursor: "pointer"
|
|
716
809
|
};
|
|
717
|
-
function
|
|
810
|
+
function te({
|
|
718
811
|
label: t,
|
|
719
812
|
onSelect: e
|
|
720
813
|
}) {
|
|
721
|
-
return /* @__PURE__ */
|
|
814
|
+
return /* @__PURE__ */ o(
|
|
722
815
|
"button",
|
|
723
816
|
{
|
|
724
817
|
type: "button",
|
|
725
818
|
role: "menuitem",
|
|
726
819
|
"data-sc-part": "snowcone-editor-menu-item",
|
|
727
|
-
style:
|
|
820
|
+
style: yt,
|
|
728
821
|
onClick: e,
|
|
729
822
|
children: t
|
|
730
823
|
}
|
|
731
824
|
);
|
|
732
825
|
}
|
|
733
|
-
function
|
|
826
|
+
function bt({
|
|
734
827
|
fullscreen: t,
|
|
735
828
|
onToggleFullscreen: e,
|
|
736
829
|
viewCount: n,
|
|
737
830
|
viewIndex: r,
|
|
738
|
-
onSelectView:
|
|
831
|
+
onSelectView: s,
|
|
739
832
|
onExport: a
|
|
740
833
|
}) {
|
|
741
|
-
const [
|
|
742
|
-
return /* @__PURE__ */
|
|
743
|
-
/* @__PURE__ */
|
|
834
|
+
const [d, c] = O(!1), l = () => c(!1);
|
|
835
|
+
return /* @__PURE__ */ C("div", { style: { position: "relative" }, children: [
|
|
836
|
+
/* @__PURE__ */ o(
|
|
744
837
|
"button",
|
|
745
838
|
{
|
|
746
839
|
type: "button",
|
|
747
840
|
"aria-label": "Editor menu",
|
|
748
841
|
"aria-haspopup": "menu",
|
|
749
|
-
"aria-expanded":
|
|
842
|
+
"aria-expanded": d,
|
|
750
843
|
"data-sc-part": "snowcone-editor-menu",
|
|
751
|
-
style:
|
|
752
|
-
onClick: () =>
|
|
844
|
+
style: gt,
|
|
845
|
+
onClick: () => c((i) => !i),
|
|
753
846
|
children: "⋮"
|
|
754
847
|
}
|
|
755
848
|
),
|
|
756
|
-
|
|
757
|
-
/* @__PURE__ */
|
|
849
|
+
d ? /* @__PURE__ */ C($e, { children: [
|
|
850
|
+
/* @__PURE__ */ o(
|
|
758
851
|
"div",
|
|
759
852
|
{
|
|
760
853
|
style: { position: "fixed", inset: 0, zIndex: 39 },
|
|
761
|
-
onClick:
|
|
854
|
+
onClick: l,
|
|
762
855
|
"aria-hidden": "true"
|
|
763
856
|
}
|
|
764
857
|
),
|
|
765
|
-
/* @__PURE__ */
|
|
858
|
+
/* @__PURE__ */ C(
|
|
766
859
|
"div",
|
|
767
860
|
{
|
|
768
861
|
role: "menu",
|
|
@@ -781,31 +874,31 @@ function ft({
|
|
|
781
874
|
zIndex: 40
|
|
782
875
|
},
|
|
783
876
|
children: [
|
|
784
|
-
/* @__PURE__ */
|
|
785
|
-
|
|
877
|
+
/* @__PURE__ */ o(
|
|
878
|
+
te,
|
|
786
879
|
{
|
|
787
880
|
label: t ? "Exit fullscreen" : "Fullscreen",
|
|
788
881
|
onSelect: () => {
|
|
789
|
-
|
|
882
|
+
l(), e();
|
|
790
883
|
}
|
|
791
884
|
}
|
|
792
885
|
),
|
|
793
|
-
n > 1 ? Array.from({ length: n }, (i,
|
|
794
|
-
|
|
886
|
+
n > 1 ? Array.from({ length: n }, (i, f) => /* @__PURE__ */ o(
|
|
887
|
+
te,
|
|
795
888
|
{
|
|
796
|
-
label: `View ${
|
|
889
|
+
label: `View ${f + 1}${f === r ? " ✓" : ""}`,
|
|
797
890
|
onSelect: () => {
|
|
798
|
-
|
|
891
|
+
l(), s(f);
|
|
799
892
|
}
|
|
800
893
|
},
|
|
801
|
-
|
|
894
|
+
f
|
|
802
895
|
)) : null,
|
|
803
|
-
/* @__PURE__ */
|
|
804
|
-
|
|
896
|
+
/* @__PURE__ */ o(
|
|
897
|
+
te,
|
|
805
898
|
{
|
|
806
899
|
label: "Export PNG",
|
|
807
900
|
onSelect: () => {
|
|
808
|
-
|
|
901
|
+
l(), a();
|
|
809
902
|
}
|
|
810
903
|
}
|
|
811
904
|
)
|
|
@@ -815,19 +908,19 @@ function ft({
|
|
|
815
908
|
] }) : null
|
|
816
909
|
] });
|
|
817
910
|
}
|
|
818
|
-
function
|
|
819
|
-
const { flatLayers: t, selectLayer: e, generateAllPreviews: n } =
|
|
820
|
-
return
|
|
911
|
+
function vt() {
|
|
912
|
+
const { flatLayers: t, selectLayer: e, generateAllPreviews: n } = Te({ previewSize: 96 });
|
|
913
|
+
return B(() => {
|
|
821
914
|
t.length > 0 && n();
|
|
822
|
-
}, [t.length, n]), /* @__PURE__ */
|
|
915
|
+
}, [t.length, n]), /* @__PURE__ */ C(
|
|
823
916
|
"div",
|
|
824
917
|
{
|
|
825
918
|
"data-sc-part": "snowcone-editor-idle-dock",
|
|
826
919
|
style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 8, minHeight: 44 },
|
|
827
920
|
children: [
|
|
828
|
-
/* @__PURE__ */
|
|
829
|
-
t.length > 0 ? /* @__PURE__ */
|
|
830
|
-
t.map((r) => /* @__PURE__ */
|
|
921
|
+
/* @__PURE__ */ o(U.Add, {}),
|
|
922
|
+
t.length > 0 ? /* @__PURE__ */ o("div", { style: { width: 1, height: 28, background: "rgba(0,0,0,0.1)", flexShrink: 0 }, "aria-hidden": "true" }) : null,
|
|
923
|
+
t.map((r) => /* @__PURE__ */ o(
|
|
831
924
|
"button",
|
|
832
925
|
{
|
|
833
926
|
type: "button",
|
|
@@ -850,8 +943,8 @@ function pt() {
|
|
|
850
943
|
},
|
|
851
944
|
children: r.previewUrl ? (
|
|
852
945
|
// eslint-disable-next-line @next/next/no-img-element
|
|
853
|
-
/* @__PURE__ */
|
|
854
|
-
) : /* @__PURE__ */
|
|
946
|
+
/* @__PURE__ */ o("img", { src: r.previewUrl, alt: "", style: { width: "100%", height: "100%", objectFit: "contain" } })
|
|
947
|
+
) : /* @__PURE__ */ o(
|
|
855
948
|
"span",
|
|
856
949
|
{
|
|
857
950
|
style: {
|
|
@@ -872,13 +965,13 @@ function pt() {
|
|
|
872
965
|
}
|
|
873
966
|
);
|
|
874
967
|
}
|
|
875
|
-
function
|
|
968
|
+
function wt({
|
|
876
969
|
onAddToCart: t,
|
|
877
970
|
defaultQuantity: e
|
|
878
971
|
}) {
|
|
879
|
-
const { price: n, complete: r } =
|
|
880
|
-
return /* @__PURE__ */
|
|
881
|
-
|
|
972
|
+
const { price: n, complete: r } = pt();
|
|
973
|
+
return /* @__PURE__ */ C(
|
|
974
|
+
U.Buy,
|
|
882
975
|
{
|
|
883
976
|
onAddToCart: t,
|
|
884
977
|
...typeof e == "number" ? { defaultQuantity: e } : {},
|
|
@@ -901,36 +994,36 @@ function gt({
|
|
|
901
994
|
},
|
|
902
995
|
children: [
|
|
903
996
|
"Add to cart",
|
|
904
|
-
typeof n == "number" ? ` · ${
|
|
997
|
+
typeof n == "number" ? ` · ${ht(n)}` : ""
|
|
905
998
|
]
|
|
906
999
|
}
|
|
907
1000
|
);
|
|
908
1001
|
}
|
|
909
|
-
function
|
|
1002
|
+
function Et({
|
|
910
1003
|
title: t,
|
|
911
1004
|
height: e,
|
|
912
1005
|
mockupIds: n,
|
|
913
1006
|
onAddToCart: r,
|
|
914
|
-
defaultQuantity:
|
|
1007
|
+
defaultQuantity: s,
|
|
915
1008
|
className: a,
|
|
916
|
-
style:
|
|
1009
|
+
style: d
|
|
917
1010
|
}) {
|
|
918
|
-
const [
|
|
919
|
-
var
|
|
920
|
-
const
|
|
921
|
-
if (!
|
|
922
|
-
const [
|
|
923
|
-
if (typeof
|
|
924
|
-
const
|
|
925
|
-
|
|
926
|
-
}, []),
|
|
1011
|
+
const [c, l] = O(!1), [i, f] = O(0), [u, m] = O(!1), y = R(null), b = We(), v = n[Math.min(i, n.length - 1)], w = q(async () => {
|
|
1012
|
+
var D;
|
|
1013
|
+
const g = await ((D = y.current) == null ? void 0 : D.exportArtboards({ format: "dataUrl" }));
|
|
1014
|
+
if (!g) return;
|
|
1015
|
+
const [N, S] = Object.entries(g)[0] ?? [];
|
|
1016
|
+
if (typeof S != "string") return;
|
|
1017
|
+
const L = document.createElement("a");
|
|
1018
|
+
L.href = S, L.download = `${N ?? "design"}.png`, L.click();
|
|
1019
|
+
}, []), h = {
|
|
927
1020
|
display: "flex",
|
|
928
1021
|
flexDirection: "column",
|
|
929
1022
|
overflow: "hidden",
|
|
930
1023
|
background: "var(--sc-color-surface, #fff)",
|
|
931
1024
|
color: "var(--sc-color-foreground, #111)",
|
|
932
1025
|
fontFamily: "ui-sans-serif, system-ui, sans-serif",
|
|
933
|
-
...
|
|
1026
|
+
...c ? {
|
|
934
1027
|
position: "fixed",
|
|
935
1028
|
inset: 0,
|
|
936
1029
|
zIndex: 9999,
|
|
@@ -943,8 +1036,8 @@ function ht({
|
|
|
943
1036
|
border: "1px solid rgba(0,0,0,0.08)",
|
|
944
1037
|
boxShadow: "0 1px 3px rgba(0,0,0,0.08)"
|
|
945
1038
|
},
|
|
946
|
-
...
|
|
947
|
-
},
|
|
1039
|
+
...d
|
|
1040
|
+
}, x = {
|
|
948
1041
|
position: "absolute",
|
|
949
1042
|
top: 8,
|
|
950
1043
|
right: 12,
|
|
@@ -959,15 +1052,15 @@ function ht({
|
|
|
959
1052
|
cursor: "pointer",
|
|
960
1053
|
zIndex: 2
|
|
961
1054
|
};
|
|
962
|
-
return /* @__PURE__ */
|
|
1055
|
+
return /* @__PURE__ */ C(
|
|
963
1056
|
"div",
|
|
964
1057
|
{
|
|
965
1058
|
"data-sc-part": "snowcone-editor",
|
|
966
|
-
"data-sc-fullscreen":
|
|
1059
|
+
"data-sc-fullscreen": c ? "true" : void 0,
|
|
967
1060
|
className: a,
|
|
968
|
-
style:
|
|
1061
|
+
style: h,
|
|
969
1062
|
children: [
|
|
970
|
-
/* @__PURE__ */
|
|
1063
|
+
/* @__PURE__ */ C(
|
|
971
1064
|
"div",
|
|
972
1065
|
{
|
|
973
1066
|
"data-sc-part": "snowcone-editor-header",
|
|
@@ -979,35 +1072,35 @@ function ht({
|
|
|
979
1072
|
flexShrink: 0
|
|
980
1073
|
},
|
|
981
1074
|
children: [
|
|
982
|
-
/* @__PURE__ */
|
|
983
|
-
/* @__PURE__ */
|
|
984
|
-
/* @__PURE__ */
|
|
985
|
-
|
|
1075
|
+
/* @__PURE__ */ o("span", { style: { fontSize: 14, fontWeight: 700, marginRight: "auto" }, children: t }),
|
|
1076
|
+
/* @__PURE__ */ o(U.History, {}),
|
|
1077
|
+
/* @__PURE__ */ o(
|
|
1078
|
+
bt,
|
|
986
1079
|
{
|
|
987
|
-
fullscreen:
|
|
988
|
-
onToggleFullscreen: () =>
|
|
1080
|
+
fullscreen: c,
|
|
1081
|
+
onToggleFullscreen: () => l((g) => !g),
|
|
989
1082
|
viewCount: n.length,
|
|
990
1083
|
viewIndex: i,
|
|
991
|
-
onSelectView:
|
|
992
|
-
onExport: () => void
|
|
1084
|
+
onSelectView: f,
|
|
1085
|
+
onExport: () => void w()
|
|
993
1086
|
}
|
|
994
1087
|
),
|
|
995
|
-
/* @__PURE__ */
|
|
1088
|
+
/* @__PURE__ */ o(wt, { onAddToCart: r, defaultQuantity: s })
|
|
996
1089
|
]
|
|
997
1090
|
}
|
|
998
1091
|
),
|
|
999
|
-
/* @__PURE__ */
|
|
1092
|
+
/* @__PURE__ */ C(
|
|
1000
1093
|
"div",
|
|
1001
1094
|
{
|
|
1002
1095
|
"data-sc-part": "snowcone-editor-stage",
|
|
1003
1096
|
style: { position: "relative", flex: 1, minHeight: 0, padding: "4px 12px" },
|
|
1004
1097
|
children: [
|
|
1005
|
-
/* @__PURE__ */
|
|
1006
|
-
|
|
1098
|
+
/* @__PURE__ */ o(U.Canvas, { ref: y, style: { height: "100%" } }),
|
|
1099
|
+
u ? (
|
|
1007
1100
|
// Swapped: the mockup IS the stage; the corner chip returns to the
|
|
1008
1101
|
// artwork. The canvas stays mounted underneath (no document
|
|
1009
1102
|
// teardown), just covered.
|
|
1010
|
-
/* @__PURE__ */
|
|
1103
|
+
/* @__PURE__ */ C(
|
|
1011
1104
|
"div",
|
|
1012
1105
|
{
|
|
1013
1106
|
"data-sc-part": "snowcone-editor-swap-stage",
|
|
@@ -1022,24 +1115,24 @@ function ht({
|
|
|
1022
1115
|
padding: 8
|
|
1023
1116
|
},
|
|
1024
1117
|
children: [
|
|
1025
|
-
/* @__PURE__ */
|
|
1026
|
-
|
|
1118
|
+
/* @__PURE__ */ o(
|
|
1119
|
+
U.Preview,
|
|
1027
1120
|
{
|
|
1028
1121
|
mockupId: v,
|
|
1029
1122
|
alt: "Product mockup",
|
|
1030
|
-
fallback: /* @__PURE__ */
|
|
1123
|
+
fallback: /* @__PURE__ */ o("div", { "aria-busy": "true", children: "Rendering…" }),
|
|
1031
1124
|
style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain", borderRadius: 12 }
|
|
1032
1125
|
}
|
|
1033
1126
|
),
|
|
1034
|
-
/* @__PURE__ */
|
|
1127
|
+
/* @__PURE__ */ o(
|
|
1035
1128
|
"button",
|
|
1036
1129
|
{
|
|
1037
1130
|
type: "button",
|
|
1038
1131
|
"aria-label": "Back to artwork",
|
|
1039
1132
|
"data-sc-part": "snowcone-editor-swap-back",
|
|
1040
|
-
onClick: () =>
|
|
1133
|
+
onClick: () => m(!1),
|
|
1041
1134
|
style: {
|
|
1042
|
-
...
|
|
1135
|
+
...x,
|
|
1043
1136
|
display: "flex",
|
|
1044
1137
|
alignItems: "center",
|
|
1045
1138
|
justifyContent: "center",
|
|
@@ -1054,20 +1147,20 @@ function ht({
|
|
|
1054
1147
|
]
|
|
1055
1148
|
}
|
|
1056
1149
|
)
|
|
1057
|
-
) : /* @__PURE__ */
|
|
1150
|
+
) : /* @__PURE__ */ o(
|
|
1058
1151
|
"button",
|
|
1059
1152
|
{
|
|
1060
1153
|
type: "button",
|
|
1061
1154
|
"aria-label": "Show product mockup",
|
|
1062
1155
|
"data-sc-part": "snowcone-editor-pip",
|
|
1063
|
-
onClick: () =>
|
|
1064
|
-
style:
|
|
1065
|
-
children: /* @__PURE__ */
|
|
1066
|
-
|
|
1156
|
+
onClick: () => m(!0),
|
|
1157
|
+
style: x,
|
|
1158
|
+
children: /* @__PURE__ */ o(
|
|
1159
|
+
U.Preview,
|
|
1067
1160
|
{
|
|
1068
1161
|
mockupId: v,
|
|
1069
1162
|
alt: "Product mockup preview",
|
|
1070
|
-
fallback: /* @__PURE__ */
|
|
1163
|
+
fallback: /* @__PURE__ */ o("span", { style: { fontSize: 10, opacity: 0.5 }, "aria-busy": "true", children: "mockup…" }),
|
|
1071
1164
|
style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
|
|
1072
1165
|
}
|
|
1073
1166
|
)
|
|
@@ -1076,15 +1169,15 @@ function ht({
|
|
|
1076
1169
|
]
|
|
1077
1170
|
}
|
|
1078
1171
|
),
|
|
1079
|
-
/* @__PURE__ */
|
|
1172
|
+
/* @__PURE__ */ C(
|
|
1080
1173
|
"div",
|
|
1081
1174
|
{
|
|
1082
1175
|
"data-sc-part": "snowcone-editor-zone",
|
|
1083
|
-
"data-sc-zone-state":
|
|
1176
|
+
"data-sc-zone-state": b ? "selected" : "idle",
|
|
1084
1177
|
style: { flexShrink: 0, padding: "4px 16px 14px" },
|
|
1085
1178
|
children: [
|
|
1086
|
-
/* @__PURE__ */
|
|
1087
|
-
|
|
1179
|
+
/* @__PURE__ */ o("div", { style: { display: b ? void 0 : "none" }, children: /* @__PURE__ */ o(U.Controls, { placement: "docked" }) }),
|
|
1180
|
+
b ? null : /* @__PURE__ */ o(vt, {})
|
|
1088
1181
|
]
|
|
1089
1182
|
}
|
|
1090
1183
|
)
|
|
@@ -1092,41 +1185,42 @@ function ht({
|
|
|
1092
1185
|
}
|
|
1093
1186
|
);
|
|
1094
1187
|
}
|
|
1095
|
-
function
|
|
1188
|
+
function Vt(t) {
|
|
1096
1189
|
const {
|
|
1097
1190
|
onAddToCart: e,
|
|
1098
1191
|
defaultQuantity: n,
|
|
1099
1192
|
title: r = "Editor",
|
|
1100
|
-
height:
|
|
1193
|
+
height: s = 480,
|
|
1101
1194
|
className: a,
|
|
1102
|
-
style:
|
|
1103
|
-
...
|
|
1195
|
+
style: d,
|
|
1196
|
+
...c
|
|
1104
1197
|
} = t;
|
|
1105
|
-
return /* @__PURE__ */
|
|
1106
|
-
|
|
1198
|
+
return /* @__PURE__ */ o(U.Root, { ...c, children: /* @__PURE__ */ o(
|
|
1199
|
+
Et,
|
|
1107
1200
|
{
|
|
1108
1201
|
title: r,
|
|
1109
|
-
height:
|
|
1110
|
-
mockupIds:
|
|
1202
|
+
height: s,
|
|
1203
|
+
mockupIds: c.product.mockupIds,
|
|
1111
1204
|
onAddToCart: e,
|
|
1112
1205
|
...typeof n == "number" ? { defaultQuantity: n } : {},
|
|
1113
1206
|
className: a,
|
|
1114
|
-
style:
|
|
1207
|
+
style: d
|
|
1115
1208
|
}
|
|
1116
1209
|
) });
|
|
1117
1210
|
}
|
|
1118
|
-
|
|
1211
|
+
_e();
|
|
1119
1212
|
export {
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1213
|
+
U as E,
|
|
1214
|
+
Dt as R,
|
|
1215
|
+
Vt as S,
|
|
1216
|
+
$t as a,
|
|
1217
|
+
At as b,
|
|
1218
|
+
me as c,
|
|
1219
|
+
pt as d,
|
|
1220
|
+
Bt as e,
|
|
1221
|
+
ht as f,
|
|
1222
|
+
Lt as p,
|
|
1223
|
+
Q as u,
|
|
1224
|
+
Ye as v
|
|
1131
1225
|
};
|
|
1132
|
-
//# sourceMappingURL=embed-
|
|
1226
|
+
//# sourceMappingURL=embed-8ecUMMH-.js.map
|