@snowcone-app/canvas 0.21.2 → 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 +31 -7
- package/dist/{CanvasRenderer-B0szG0Us.js → CanvasRenderer-6_HhR4-q.js} +170 -189
- package/dist/CanvasRenderer-6_HhR4-q.js.map +1 -0
- package/dist/{ContextualToolbars-BYnovWnN.js → ContextualToolbars-BDEt9ND0.js} +1619 -1846
- package/dist/ContextualToolbars-BDEt9ND0.js.map +1 -0
- package/dist/{EditorCanvasImpl-BmLHjXe7.js → EditorCanvasImpl-BH_bKy-F.js} +5 -5
- package/dist/{EditorCanvasImpl-BmLHjXe7.js.map → EditorCanvasImpl-BH_bKy-F.js.map} +1 -1
- package/dist/ImagePanel-BwqFDKvW.js +951 -0
- package/dist/ImagePanel-BwqFDKvW.js.map +1 -0
- package/dist/{SnowconeCanvas-Bj2773ym.js → SnowconeCanvas-Cx7nXlBI.js} +19 -18
- package/dist/{SnowconeCanvas-Bj2773ym.js.map → SnowconeCanvas-Cx7nXlBI.js.map} +1 -1
- package/dist/{UnifiedFontService-C8gaspRD.js → UnifiedFontService-CC3CSmH5.js} +1042 -984
- package/dist/UnifiedFontService-CC3CSmH5.js.map +1 -0
- package/dist/advanced.mjs +97 -96
- package/dist/advanced.mjs.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/editor/LazyImageBrowser.d.ts +7 -0
- package/dist/components/editor/commerceStore.d.ts +13 -0
- package/dist/components/embed-realtime/validateEmbed.d.ts +10 -4
- package/dist/custom-icons-BW6hqmkL.js +236 -0
- package/dist/custom-icons-BW6hqmkL.js.map +1 -0
- package/dist/design/product-config.d.ts +48 -0
- package/dist/editorErrors-B2mb1sVN.js.map +1 -1
- package/dist/{embed-pM7ZkFuz.js → embed-8ecUMMH-.js} +550 -441
- package/dist/embed-8ecUMMH-.js.map +1 -0
- package/dist/embed.mjs +30 -29
- package/dist/errors/editorError.d.ts +3 -0
- package/dist/guards-8rkFAMBs.js +24 -0
- package/dist/guards-8rkFAMBs.js.map +1 -0
- package/dist/index.mjs +5 -5
- package/dist/internals.mjs +1 -1
- package/dist/style.css +1 -1
- package/dist/{template-fields-BsnHMf1i.js → template-fields-C2pSfMBh.js} +57 -39
- package/dist/template-fields-C2pSfMBh.js.map +1 -0
- package/dist/validation-C9Fe9ahK.js +8367 -0
- package/dist/validation-C9Fe9ahK.js.map +1 -0
- package/example/package.json +1 -1
- package/package.json +1 -1
- package/dist/CanvasRenderer-B0szG0Us.js.map +0 -1
- package/dist/ContextualToolbars-BYnovWnN.js.map +0 -1
- package/dist/UnifiedFontService-C8gaspRD.js.map +0 -1
- package/dist/embed-pM7ZkFuz.js.map +0 -1
- package/dist/template-fields-BsnHMf1i.js.map +0 -1
- package/dist/validation-DdVeWnlo.js +0 -9308
- package/dist/validation-DdVeWnlo.js.map +0 -1
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
import { E as
|
|
2
|
-
import { y as
|
|
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
|
|
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
|
+
import { y as $ } from "./FontAnalyzer-CwIpgTGd.js";
|
|
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 de({ 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 de({ 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,181 +139,208 @@ class Qe extends Te {
|
|
|
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
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
} = t, y = T(() => r.toJSON().activeArtboard, [r]), b = T(() => {
|
|
170
|
+
const p = r.toJSON().artboards[0];
|
|
171
|
+
if (p)
|
|
172
|
+
return {
|
|
173
|
+
name: p.name,
|
|
174
|
+
width: p.width,
|
|
175
|
+
height: p.height,
|
|
176
|
+
...p.backgroundColor ? { backgroundColor: p.backgroundColor } : {}
|
|
177
|
+
};
|
|
178
|
+
}, [r]);
|
|
179
|
+
j(
|
|
180
|
+
u.commerce.subscribe,
|
|
181
|
+
u.commerce.getVersion,
|
|
182
|
+
u.commerce.getVersion
|
|
173
183
|
);
|
|
174
|
-
const
|
|
175
|
-
if (!
|
|
176
|
-
const
|
|
177
|
-
return
|
|
178
|
-
}, [
|
|
179
|
-
|
|
180
|
-
const [
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (m !== "throw") return;
|
|
184
|
-
const
|
|
185
|
-
if (
|
|
186
|
-
throw new
|
|
187
|
-
issue:
|
|
184
|
+
const v = u.commerce.renderVariantId(), w = Me(v ?? n.variantId ?? n.defaultGvid), h = T(() => {
|
|
185
|
+
if (!w) return null;
|
|
186
|
+
const p = r.toJSON().artboards[0];
|
|
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
|
+
var I;
|
|
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,
|
|
188
198
|
docSlug: "embed-mode"
|
|
189
199
|
});
|
|
190
|
-
for (const
|
|
191
|
-
typeof
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
var
|
|
196
|
-
if (
|
|
197
|
-
|
|
198
|
-
|
|
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(() => {
|
|
213
|
+
var p;
|
|
214
|
+
if (m === "warn" && typeof $ < "u" && ((p = $.env) == null ? void 0 : p.NODE_ENV) !== "production") {
|
|
215
|
+
if (oe.current === F) return;
|
|
216
|
+
oe.current = F, Ye({ shop: e, product: n, design: r, hasGrant: J });
|
|
199
217
|
}
|
|
200
|
-
}, [
|
|
201
|
-
const
|
|
218
|
+
}, [F, m]);
|
|
219
|
+
const H = T(
|
|
202
220
|
() => {
|
|
203
221
|
try {
|
|
204
|
-
return { session: new
|
|
205
|
-
} catch (
|
|
206
|
-
return { error:
|
|
222
|
+
return { session: new Ve({ shop: e, product: n, wsUrl: l, ...Y }) };
|
|
223
|
+
} catch (p) {
|
|
224
|
+
return { error: p instanceof Error ? p.message : String(p) };
|
|
207
225
|
}
|
|
208
226
|
},
|
|
209
227
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
210
|
-
[e,
|
|
211
|
-
),
|
|
212
|
-
|
|
213
|
-
var
|
|
214
|
-
const
|
|
215
|
-
|
|
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);
|
|
216
234
|
}));
|
|
217
|
-
}, [
|
|
218
|
-
|
|
219
|
-
var
|
|
220
|
-
if (
|
|
221
|
-
|
|
235
|
+
}, [k, y, s]);
|
|
236
|
+
B(() => {
|
|
237
|
+
var p;
|
|
238
|
+
if (K) {
|
|
239
|
+
P(K), V(!1), (p = g.current) == null || p.call(g, K);
|
|
222
240
|
return;
|
|
223
241
|
}
|
|
224
|
-
if (
|
|
225
|
-
return
|
|
226
|
-
var
|
|
227
|
-
|
|
228
|
-
}),
|
|
229
|
-
var
|
|
230
|
-
|
|
231
|
-
}),
|
|
232
|
-
}, [
|
|
233
|
-
const
|
|
242
|
+
if (k)
|
|
243
|
+
return k.onMockups((E) => {
|
|
244
|
+
var I;
|
|
245
|
+
L(E), V(!1), (I = x.current) == null || I.call(x, E);
|
|
246
|
+
}), k.onError((E) => {
|
|
247
|
+
var I;
|
|
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({
|
|
234
252
|
session: null,
|
|
235
253
|
variantId: void 0
|
|
236
254
|
});
|
|
237
|
-
|
|
238
|
-
if (!
|
|
239
|
-
const
|
|
240
|
-
if (
|
|
241
|
-
|
|
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 };
|
|
242
260
|
return;
|
|
243
261
|
}
|
|
244
|
-
|
|
245
|
-
}, [
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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);
|
|
270
|
+
return () => clearTimeout(p);
|
|
271
|
+
}, [D, y]);
|
|
272
|
+
const ve = T(
|
|
252
273
|
() => ({
|
|
253
|
-
session:
|
|
274
|
+
session: k,
|
|
254
275
|
design: r,
|
|
255
|
-
placement:
|
|
276
|
+
placement: y,
|
|
256
277
|
product: n,
|
|
257
|
-
mockups:
|
|
278
|
+
mockups: S,
|
|
258
279
|
isRendering: D,
|
|
259
|
-
error:
|
|
260
|
-
throttleMs:
|
|
261
|
-
pieceGuides:
|
|
262
|
-
pushRender:
|
|
263
|
-
stateStore:
|
|
280
|
+
error: z,
|
|
281
|
+
throttleMs: s,
|
|
282
|
+
pieceGuides: h,
|
|
283
|
+
pushRender: G,
|
|
284
|
+
stateStore: u.store
|
|
264
285
|
}),
|
|
265
|
-
[
|
|
266
|
-
),
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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
|
|
270
291
|
);
|
|
271
|
-
|
|
272
|
-
const
|
|
273
|
-
|
|
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,
|
|
295
|
+
{
|
|
296
|
+
...b ? { initialArtboardConfig: b } : {},
|
|
297
|
+
children: f
|
|
298
|
+
}
|
|
299
|
+
) }) }) });
|
|
300
|
+
return i ? /* @__PURE__ */ o(Ie, { services: i, children: ae }) : ae;
|
|
274
301
|
}
|
|
275
|
-
function
|
|
276
|
-
const { design: e, product: n } = t, r = `${n.productId}|${n.variantId ?? ""}`,
|
|
277
|
-
(
|
|
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 = {
|
|
278
305
|
design: e,
|
|
279
306
|
internals: {
|
|
280
|
-
store: new
|
|
281
|
-
registry: new
|
|
307
|
+
store: new He(e.toJSON()),
|
|
308
|
+
registry: new Ee()
|
|
282
309
|
}
|
|
283
|
-
}), (a.current === null || a.current.productIdentity !== r) && (a.current = { productIdentity: r, commerce: new
|
|
284
|
-
const
|
|
310
|
+
}), (a.current === null || a.current.productIdentity !== r) && (a.current = { productIdentity: r, commerce: new Ke(n) });
|
|
311
|
+
const l = T(
|
|
285
312
|
() => ({
|
|
286
|
-
...
|
|
313
|
+
...s.current.internals,
|
|
287
314
|
commerce: a.current.commerce,
|
|
288
|
-
...
|
|
315
|
+
...xe(c)
|
|
289
316
|
}),
|
|
290
317
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
291
|
-
[
|
|
318
|
+
[s.current.internals, a.current.commerce]
|
|
292
319
|
);
|
|
293
320
|
return (
|
|
294
321
|
// `display: contents` — the .sc-root scope without a layout box, so the
|
|
295
322
|
// host's grid/flex sees the parts directly (and the legacy RealtimeEmbed
|
|
296
323
|
// wrapper, which had no DOM at all, stays layout-identical).
|
|
297
|
-
/* @__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 }) }) })
|
|
298
325
|
);
|
|
299
326
|
}
|
|
300
|
-
let
|
|
301
|
-
function
|
|
302
|
-
return
|
|
327
|
+
let rt = () => import("./EditorCanvasImpl-BH_bKy-F.js").then((t) => t.EditorCanvasImpl);
|
|
328
|
+
function ge() {
|
|
329
|
+
return rt();
|
|
303
330
|
}
|
|
304
|
-
const
|
|
305
|
-
const c =
|
|
306
|
-
W(() => c.registry.registerCanvas(
|
|
307
|
-
const [
|
|
308
|
-
return
|
|
309
|
-
let
|
|
310
|
-
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(
|
|
311
338
|
(m) => {
|
|
312
|
-
|
|
339
|
+
u || f(() => m);
|
|
313
340
|
},
|
|
314
341
|
(m) => {
|
|
315
|
-
|
|
316
|
-
new
|
|
342
|
+
u || c.reportRuntimeError(
|
|
343
|
+
new _(
|
|
317
344
|
"E_CHUNK_LOAD_FAILED",
|
|
318
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.`,
|
|
319
346
|
{ cause: m instanceof Error ? m.message : String(m), docSlug: "embed-mode" }
|
|
@@ -321,102 +348,127 @@ const Ze = se(function({ children: e, maxHeight: n, className: r, style: o }, a)
|
|
|
321
348
|
);
|
|
322
349
|
}
|
|
323
350
|
), () => {
|
|
324
|
-
|
|
351
|
+
u = !0;
|
|
325
352
|
};
|
|
326
|
-
}, [c]),
|
|
353
|
+
}, [c]), i ? (
|
|
327
354
|
// `builtinControls`: the canvas owns the floating contextual toolbar
|
|
328
|
-
// unless
|
|
329
|
-
//
|
|
330
|
-
|
|
331
|
-
|
|
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(
|
|
332
372
|
"div",
|
|
333
373
|
{
|
|
334
374
|
"data-sc-part": "canvas",
|
|
335
375
|
"data-sc-state": "loading",
|
|
336
|
-
className:
|
|
337
|
-
style: { minHeight: n ?? 200, ...
|
|
376
|
+
className: s,
|
|
377
|
+
style: { minHeight: n ?? 200, ...a },
|
|
338
378
|
"aria-busy": "true"
|
|
339
379
|
}
|
|
340
380
|
);
|
|
341
|
-
}),
|
|
342
|
-
function
|
|
343
|
-
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)
|
|
344
384
|
if (e >= t) return e;
|
|
345
|
-
return
|
|
385
|
+
return ee[ee.length - 1];
|
|
346
386
|
}
|
|
347
|
-
function
|
|
348
|
-
if (!(t > 0) || !(e > 0) || e <= t *
|
|
349
|
-
const n =
|
|
387
|
+
function at(t, e) {
|
|
388
|
+
if (!(t > 0) || !(e > 0) || e <= t * st) return null;
|
|
389
|
+
const n = ot(e);
|
|
350
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.`;
|
|
351
391
|
}
|
|
352
|
-
function
|
|
392
|
+
function ye({
|
|
353
393
|
mockupId: t,
|
|
354
394
|
fallback: e = null,
|
|
355
395
|
alt: n = "Live product mockup",
|
|
356
396
|
className: r,
|
|
357
|
-
style:
|
|
397
|
+
style: s
|
|
358
398
|
}) {
|
|
359
|
-
const { mockups: a, error: c } =
|
|
360
|
-
if (!(
|
|
361
|
-
return
|
|
362
|
-
|
|
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) => {
|
|
363
414
|
var w;
|
|
364
|
-
if (typeof
|
|
365
|
-
const m =
|
|
366
|
-
if (
|
|
367
|
-
const
|
|
368
|
-
|
|
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));
|
|
369
420
|
};
|
|
370
421
|
return (
|
|
371
422
|
// eslint-disable-next-line @next/next/no-img-element
|
|
372
|
-
/* @__PURE__ */
|
|
423
|
+
/* @__PURE__ */ o(
|
|
373
424
|
"img",
|
|
374
425
|
{
|
|
375
426
|
"data-sc-part": "preview",
|
|
376
|
-
|
|
427
|
+
"data-sc-preview-state": c ? "rendering" : "ready",
|
|
428
|
+
src: i.imageUrl,
|
|
377
429
|
alt: n,
|
|
378
430
|
className: r,
|
|
379
|
-
style:
|
|
380
|
-
onLoad:
|
|
431
|
+
style: s,
|
|
432
|
+
onLoad: f
|
|
381
433
|
}
|
|
382
434
|
)
|
|
383
435
|
);
|
|
384
436
|
}
|
|
385
|
-
function
|
|
386
|
-
const { layer: e, optional: n = !1, placeholder: r, className:
|
|
387
|
-
if (!
|
|
388
|
-
throw new
|
|
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);
|
|
439
|
+
if (!Pe(e))
|
|
440
|
+
throw new _(
|
|
389
441
|
"E_LAYER_TOKEN_REQUIRED",
|
|
390
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.`,
|
|
391
443
|
{ received: typeof e == "string" ? e : typeof e, docSlug: "embed-mode" }
|
|
392
444
|
);
|
|
393
|
-
if (
|
|
394
|
-
const
|
|
395
|
-
if (
|
|
396
|
-
throw new
|
|
445
|
+
if (u.current !== e.name) {
|
|
446
|
+
const b = i.layerKindOf(e.name);
|
|
447
|
+
if (b === void 0)
|
|
448
|
+
throw new _(
|
|
397
449
|
"E_LAYER_NOT_FOUND",
|
|
398
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())}.`,
|
|
399
451
|
{ layerName: e.name, validNames: i.bindableLayerNames(), docSlug: "embed-mode" }
|
|
400
452
|
);
|
|
401
|
-
if (
|
|
402
|
-
throw new
|
|
453
|
+
if (b !== "text")
|
|
454
|
+
throw new _(
|
|
403
455
|
"E_LAYER_WRONG_KIND",
|
|
404
|
-
`layer "${e.name}" is ${
|
|
405
|
-
{ 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" }
|
|
406
458
|
);
|
|
407
|
-
|
|
459
|
+
u.current = e.name;
|
|
408
460
|
}
|
|
409
|
-
W(() =>
|
|
410
|
-
const
|
|
461
|
+
W(() => d.registry.registerTextField(f, { name: e.name, optional: n }), [d.registry, f, e.name, n]);
|
|
462
|
+
const m = j(
|
|
411
463
|
i.subscribe,
|
|
412
464
|
() => i.textOf(e.name) ?? "",
|
|
413
465
|
() => i.textOf(e.name) ?? ""
|
|
414
|
-
),
|
|
415
|
-
(
|
|
416
|
-
const
|
|
417
|
-
if (
|
|
418
|
-
|
|
419
|
-
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 _(
|
|
420
472
|
"E_LAYER_NOT_FOUND",
|
|
421
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).`,
|
|
422
474
|
{ layerName: e.name, docSlug: "embed-mode" }
|
|
@@ -424,26 +476,26 @@ function rt(t) {
|
|
|
424
476
|
);
|
|
425
477
|
return;
|
|
426
478
|
}
|
|
427
|
-
i.updateTextLayer(e.name,
|
|
479
|
+
i.updateTextLayer(e.name, v), c(re(i.getState()), l);
|
|
428
480
|
},
|
|
429
|
-
[
|
|
481
|
+
[d, e.name, i, c, l]
|
|
430
482
|
);
|
|
431
|
-
return /* @__PURE__ */
|
|
483
|
+
return /* @__PURE__ */ o(
|
|
432
484
|
"input",
|
|
433
485
|
{
|
|
434
486
|
"data-sc-part": "textfield",
|
|
435
487
|
"data-sc-layer": e.name,
|
|
436
488
|
type: "text",
|
|
437
|
-
value:
|
|
438
|
-
onChange:
|
|
489
|
+
value: m,
|
|
490
|
+
onChange: y,
|
|
439
491
|
placeholder: r,
|
|
440
492
|
"aria-label": t["aria-label"] ?? e.name,
|
|
441
|
-
className:
|
|
493
|
+
className: s,
|
|
442
494
|
style: a
|
|
443
495
|
}
|
|
444
496
|
);
|
|
445
497
|
}
|
|
446
|
-
function
|
|
498
|
+
function ct(t) {
|
|
447
499
|
const e = [];
|
|
448
500
|
for (const n of t.missingOptionKeys)
|
|
449
501
|
e.push(`option:${n}`);
|
|
@@ -455,114 +507,114 @@ function ot(t) {
|
|
|
455
507
|
e.push(`layer:${n.name}`);
|
|
456
508
|
continue;
|
|
457
509
|
}
|
|
458
|
-
const
|
|
459
|
-
|
|
510
|
+
const s = (t.seedTextOf(n.name) ?? "").trim();
|
|
511
|
+
s.length > 0 && r === s && e.push(`layer-seed:${n.name}`);
|
|
460
512
|
}
|
|
461
513
|
return t.hasRenderableElement || e.push("empty-design"), (!Number.isInteger(t.quantity) || t.quantity < 1) && e.push("quantity"), e;
|
|
462
514
|
}
|
|
463
|
-
function
|
|
515
|
+
function lt(t, e) {
|
|
464
516
|
const n = e.getCombinations(), r = e.getAttributes();
|
|
465
517
|
if (Object.keys(r).length === 0 || n.length === 0) return null;
|
|
466
|
-
const
|
|
467
|
-
Object.entries(r).map(([a,
|
|
518
|
+
const s = Object.fromEntries(
|
|
519
|
+
Object.entries(r).map(([a, d]) => [a, { ...d, choices: Ge(d) }])
|
|
468
520
|
);
|
|
469
|
-
return
|
|
521
|
+
return Ue({
|
|
470
522
|
productId: t.productId,
|
|
471
523
|
quantity: e.getQuantity(),
|
|
472
524
|
selection: e.getSelection(),
|
|
473
525
|
combinations: n,
|
|
474
|
-
attributes:
|
|
526
|
+
attributes: s
|
|
475
527
|
});
|
|
476
528
|
}
|
|
477
|
-
function
|
|
478
|
-
const { onAddToCart: e, defaultQuantity: n, children: r, className:
|
|
479
|
-
if (!(
|
|
480
|
-
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 _(
|
|
481
533
|
"E_BUY_NO_PRODUCT",
|
|
482
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.",
|
|
483
535
|
{ docSlug: "embed-mode" }
|
|
484
536
|
);
|
|
485
|
-
const
|
|
537
|
+
const f = R(!1);
|
|
486
538
|
W(() => {
|
|
487
|
-
|
|
539
|
+
f.current || (f.current = !0, typeof n == "number" && i.setQuantity(n));
|
|
488
540
|
}, [i]);
|
|
489
|
-
const
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
),
|
|
494
|
-
() =>
|
|
495
|
-
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,
|
|
496
548
|
missingOptionKeys: i.missingOptionKeys(),
|
|
497
549
|
selectionValid: i.selectionValid(),
|
|
498
|
-
textFields:
|
|
499
|
-
textOf: (
|
|
500
|
-
seedTextOf: (
|
|
501
|
-
hasRenderableElement:
|
|
550
|
+
textFields: d.registry.getTextFields(),
|
|
551
|
+
textOf: (S) => l.textOf(S),
|
|
552
|
+
seedTextOf: (S) => l.seedTextOf(S),
|
|
553
|
+
hasRenderableElement: l.hasRenderableElement()
|
|
502
554
|
}),
|
|
503
555
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
504
|
-
[i,
|
|
505
|
-
),
|
|
506
|
-
if (
|
|
507
|
-
|
|
508
|
-
const
|
|
509
|
-
productId:
|
|
510
|
-
|
|
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 } : {},
|
|
511
563
|
quantity: i.getQuantity(),
|
|
512
564
|
selection: i.getSelection(),
|
|
513
|
-
cartDetail:
|
|
514
|
-
designState:
|
|
515
|
-
serverRequest:
|
|
565
|
+
cartDetail: lt(c, i),
|
|
566
|
+
designState: S,
|
|
567
|
+
serverRequest: re(S)
|
|
516
568
|
};
|
|
517
|
-
let
|
|
569
|
+
let V;
|
|
518
570
|
try {
|
|
519
|
-
|
|
520
|
-
} catch (
|
|
521
|
-
throw
|
|
571
|
+
V = e(D);
|
|
572
|
+
} catch (z) {
|
|
573
|
+
throw g.current = !1, x(!1), z;
|
|
522
574
|
}
|
|
523
|
-
Promise.resolve(
|
|
524
|
-
|
|
575
|
+
Promise.resolve(V).finally(() => {
|
|
576
|
+
g.current = !1, x(!1);
|
|
525
577
|
});
|
|
526
|
-
}, [
|
|
527
|
-
return /* @__PURE__ */
|
|
578
|
+
}, [w, c, i, l, e]);
|
|
579
|
+
return /* @__PURE__ */ o(
|
|
528
580
|
"button",
|
|
529
581
|
{
|
|
530
582
|
type: "button",
|
|
531
583
|
"data-sc-part": "buy",
|
|
532
|
-
"data-sc-buy-state":
|
|
533
|
-
"data-sc-buy-missing":
|
|
534
|
-
disabled: !
|
|
535
|
-
"aria-busy":
|
|
536
|
-
onClick:
|
|
537
|
-
className:
|
|
584
|
+
"data-sc-buy-state": h ? "busy" : w ? "ready" : "incomplete",
|
|
585
|
+
"data-sc-buy-missing": v.join(",") || void 0,
|
|
586
|
+
disabled: !w || h,
|
|
587
|
+
"aria-busy": h || void 0,
|
|
588
|
+
onClick: N,
|
|
589
|
+
className: s,
|
|
538
590
|
style: a,
|
|
539
591
|
children: r ?? "Add to cart"
|
|
540
592
|
}
|
|
541
593
|
);
|
|
542
594
|
}
|
|
543
|
-
function
|
|
595
|
+
function mt({
|
|
544
596
|
placement: t = "docked",
|
|
545
597
|
className: e,
|
|
546
598
|
style: n
|
|
547
599
|
}) {
|
|
548
|
-
const r =
|
|
549
|
-
|
|
550
|
-
const
|
|
600
|
+
const r = M("Editor.Controls");
|
|
601
|
+
Re("Editor.Controls");
|
|
602
|
+
const s = ne();
|
|
551
603
|
W(
|
|
552
|
-
() => r.registry.registerControls(
|
|
553
|
-
[r.registry,
|
|
604
|
+
() => r.registry.registerControls(s, t),
|
|
605
|
+
[r.registry, s, t]
|
|
554
606
|
);
|
|
555
|
-
const a = t === "docked", [
|
|
556
|
-
return
|
|
607
|
+
const a = t === "docked", [d, c] = O(null);
|
|
608
|
+
return B(() => {
|
|
557
609
|
if (!a) return;
|
|
558
|
-
let
|
|
559
|
-
return import("./ContextualToolbars-
|
|
610
|
+
let l = !1;
|
|
611
|
+
return import("./ContextualToolbars-BDEt9ND0.js").then((i) => i.s).then(
|
|
560
612
|
(i) => {
|
|
561
|
-
|
|
613
|
+
l || c(() => i.ContextualToolbars);
|
|
562
614
|
},
|
|
563
615
|
(i) => {
|
|
564
|
-
|
|
565
|
-
new
|
|
616
|
+
l || r.reportRuntimeError(
|
|
617
|
+
new _(
|
|
566
618
|
"E_CHUNK_LOAD_FAILED",
|
|
567
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.`,
|
|
568
620
|
{ cause: i instanceof Error ? i.message : String(i), docSlug: "embed-mode" }
|
|
@@ -570,23 +622,23 @@ function at({
|
|
|
570
622
|
);
|
|
571
623
|
}
|
|
572
624
|
), () => {
|
|
573
|
-
|
|
625
|
+
l = !0;
|
|
574
626
|
};
|
|
575
|
-
}, [a, r]), a ? /* @__PURE__ */
|
|
627
|
+
}, [a, r]), a ? /* @__PURE__ */ o(
|
|
576
628
|
"div",
|
|
577
629
|
{
|
|
578
630
|
"data-sc-part": "controls",
|
|
579
631
|
"data-sc-placement": "docked",
|
|
580
632
|
className: e,
|
|
581
633
|
style: n,
|
|
582
|
-
"aria-busy":
|
|
583
|
-
children:
|
|
634
|
+
"aria-busy": d ? void 0 : "true",
|
|
635
|
+
children: d ? /* @__PURE__ */ o(d, { mode: "embedded" }) : null
|
|
584
636
|
}
|
|
585
637
|
) : null;
|
|
586
638
|
}
|
|
587
|
-
function
|
|
588
|
-
const e =
|
|
589
|
-
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(
|
|
590
642
|
() => ({
|
|
591
643
|
attributes: e.getAttributes(),
|
|
592
644
|
selection: e.getSelection(),
|
|
@@ -595,72 +647,128 @@ function ct() {
|
|
|
595
647
|
variantId: e.resolvedVariantId(),
|
|
596
648
|
price: e.resolvedPrice(),
|
|
597
649
|
quantity: e.getQuantity(),
|
|
598
|
-
setQuantity:
|
|
650
|
+
setQuantity: s,
|
|
599
651
|
complete: e.selectionValid(),
|
|
600
652
|
missing: e.missingOptionKeys()
|
|
601
653
|
}),
|
|
602
654
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
603
|
-
[e, r,
|
|
655
|
+
[e, r, s, n]
|
|
604
656
|
);
|
|
605
657
|
}
|
|
606
|
-
const
|
|
658
|
+
const U = {
|
|
607
659
|
/** The one provider boundary — session, design, live state, error boundary. */
|
|
608
|
-
Root:
|
|
660
|
+
Root: he,
|
|
609
661
|
/** The editable artboard (the ONE lazy renderer boundary — D9). */
|
|
610
|
-
Canvas:
|
|
662
|
+
Canvas: it,
|
|
611
663
|
/** Live product mockup. ×N under one Root is valid. */
|
|
612
|
-
Preview:
|
|
664
|
+
Preview: ye,
|
|
613
665
|
/** Form input bound to a design text layer by typed token (T1). */
|
|
614
|
-
TextField:
|
|
666
|
+
TextField: dt,
|
|
615
667
|
/** Smart commerce part: completeness + payload assembly; submit = host callback. */
|
|
616
|
-
Buy:
|
|
668
|
+
Buy: ut,
|
|
617
669
|
/** Layer list. The one editor part that works canvas-free (ADR-0085 §4). */
|
|
618
|
-
Layers:
|
|
670
|
+
Layers: Ne,
|
|
619
671
|
/** Morphing contextual zone — ONE coarse part; placement docked|floating (§5). */
|
|
620
|
-
Controls:
|
|
672
|
+
Controls: mt,
|
|
621
673
|
/** Undo/redo controls. Requires Editor.Canvas. */
|
|
622
|
-
History:
|
|
674
|
+
History: Oe,
|
|
623
675
|
/** The one ⋯ overflow menu. Requires Editor.Canvas. */
|
|
624
|
-
Menu:
|
|
676
|
+
Menu: Ce,
|
|
625
677
|
/** The ⊕ add-element menu. Requires Editor.Canvas. */
|
|
626
|
-
Add:
|
|
678
|
+
Add: Se
|
|
627
679
|
};
|
|
628
|
-
function
|
|
629
|
-
return /* @__PURE__ */
|
|
680
|
+
function $t(t) {
|
|
681
|
+
return /* @__PURE__ */ o(he, { ...t, __validation: "warn" });
|
|
630
682
|
}
|
|
631
|
-
const
|
|
683
|
+
const Dt = ce(
|
|
632
684
|
function(e, n) {
|
|
633
|
-
const { children: r, className:
|
|
634
|
-
return
|
|
635
|
-
let
|
|
636
|
-
return
|
|
637
|
-
(
|
|
638
|
-
|
|
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);
|
|
639
691
|
},
|
|
640
|
-
(
|
|
641
|
-
console.error("[RealtimeCanvas] failed to load the rendering chunk:",
|
|
692
|
+
(u) => {
|
|
693
|
+
console.error("[RealtimeCanvas] failed to load the rendering chunk:", u);
|
|
642
694
|
}
|
|
643
695
|
), () => {
|
|
644
|
-
|
|
696
|
+
f = !0;
|
|
645
697
|
};
|
|
646
|
-
}, []),
|
|
698
|
+
}, []), l ? /* @__PURE__ */ o(l, { ref: n, selfScope: !0, maxHeight: d, className: s, style: a, ...c, children: r }) : /* @__PURE__ */ o(
|
|
647
699
|
"div",
|
|
648
700
|
{
|
|
649
|
-
className: `sc-root${
|
|
650
|
-
style: { minHeight:
|
|
701
|
+
className: `sc-root${s ? ` ${s}` : ""}`,
|
|
702
|
+
style: { minHeight: d ?? 200, ...a },
|
|
651
703
|
"aria-busy": "true"
|
|
652
704
|
}
|
|
653
705
|
);
|
|
654
706
|
}
|
|
655
707
|
);
|
|
656
|
-
function
|
|
657
|
-
return /* @__PURE__ */
|
|
708
|
+
function At(t) {
|
|
709
|
+
return /* @__PURE__ */ o(ye, { ...t });
|
|
658
710
|
}
|
|
659
|
-
function
|
|
660
|
-
const { mockups: t, isRendering: e, error: n } =
|
|
711
|
+
function Bt() {
|
|
712
|
+
const { mockups: t, isRendering: e, error: n } = Q();
|
|
661
713
|
return { mockups: t, isRendering: e, error: n };
|
|
662
714
|
}
|
|
663
|
-
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) {
|
|
664
772
|
return new Intl.NumberFormat("en-US", {
|
|
665
773
|
style: "currency",
|
|
666
774
|
currency: "USD",
|
|
@@ -668,7 +776,7 @@ function lt(t) {
|
|
|
668
776
|
maximumFractionDigits: t % 100 === 0 ? 0 : 2
|
|
669
777
|
}).format(t / 100);
|
|
670
778
|
}
|
|
671
|
-
const
|
|
779
|
+
const gt = {
|
|
672
780
|
display: "inline-flex",
|
|
673
781
|
alignItems: "center",
|
|
674
782
|
justifyContent: "center",
|
|
@@ -683,7 +791,7 @@ const dt = {
|
|
|
683
791
|
fontSize: 16,
|
|
684
792
|
lineHeight: 1,
|
|
685
793
|
cursor: "pointer"
|
|
686
|
-
},
|
|
794
|
+
}, yt = {
|
|
687
795
|
display: "flex",
|
|
688
796
|
alignItems: "center",
|
|
689
797
|
gap: 10,
|
|
@@ -699,55 +807,55 @@ const dt = {
|
|
|
699
807
|
textAlign: "left",
|
|
700
808
|
cursor: "pointer"
|
|
701
809
|
};
|
|
702
|
-
function
|
|
810
|
+
function te({
|
|
703
811
|
label: t,
|
|
704
812
|
onSelect: e
|
|
705
813
|
}) {
|
|
706
|
-
return /* @__PURE__ */
|
|
814
|
+
return /* @__PURE__ */ o(
|
|
707
815
|
"button",
|
|
708
816
|
{
|
|
709
817
|
type: "button",
|
|
710
818
|
role: "menuitem",
|
|
711
819
|
"data-sc-part": "snowcone-editor-menu-item",
|
|
712
|
-
style:
|
|
820
|
+
style: yt,
|
|
713
821
|
onClick: e,
|
|
714
822
|
children: t
|
|
715
823
|
}
|
|
716
824
|
);
|
|
717
825
|
}
|
|
718
|
-
function
|
|
826
|
+
function bt({
|
|
719
827
|
fullscreen: t,
|
|
720
828
|
onToggleFullscreen: e,
|
|
721
829
|
viewCount: n,
|
|
722
830
|
viewIndex: r,
|
|
723
|
-
onSelectView:
|
|
831
|
+
onSelectView: s,
|
|
724
832
|
onExport: a
|
|
725
833
|
}) {
|
|
726
|
-
const [
|
|
727
|
-
return /* @__PURE__ */
|
|
728
|
-
/* @__PURE__ */
|
|
834
|
+
const [d, c] = O(!1), l = () => c(!1);
|
|
835
|
+
return /* @__PURE__ */ C("div", { style: { position: "relative" }, children: [
|
|
836
|
+
/* @__PURE__ */ o(
|
|
729
837
|
"button",
|
|
730
838
|
{
|
|
731
839
|
type: "button",
|
|
732
840
|
"aria-label": "Editor menu",
|
|
733
841
|
"aria-haspopup": "menu",
|
|
734
|
-
"aria-expanded":
|
|
842
|
+
"aria-expanded": d,
|
|
735
843
|
"data-sc-part": "snowcone-editor-menu",
|
|
736
|
-
style:
|
|
737
|
-
onClick: () =>
|
|
844
|
+
style: gt,
|
|
845
|
+
onClick: () => c((i) => !i),
|
|
738
846
|
children: "⋮"
|
|
739
847
|
}
|
|
740
848
|
),
|
|
741
|
-
|
|
742
|
-
/* @__PURE__ */
|
|
849
|
+
d ? /* @__PURE__ */ C($e, { children: [
|
|
850
|
+
/* @__PURE__ */ o(
|
|
743
851
|
"div",
|
|
744
852
|
{
|
|
745
853
|
style: { position: "fixed", inset: 0, zIndex: 39 },
|
|
746
|
-
onClick:
|
|
854
|
+
onClick: l,
|
|
747
855
|
"aria-hidden": "true"
|
|
748
856
|
}
|
|
749
857
|
),
|
|
750
|
-
/* @__PURE__ */
|
|
858
|
+
/* @__PURE__ */ C(
|
|
751
859
|
"div",
|
|
752
860
|
{
|
|
753
861
|
role: "menu",
|
|
@@ -766,31 +874,31 @@ function mt({
|
|
|
766
874
|
zIndex: 40
|
|
767
875
|
},
|
|
768
876
|
children: [
|
|
769
|
-
/* @__PURE__ */
|
|
770
|
-
|
|
877
|
+
/* @__PURE__ */ o(
|
|
878
|
+
te,
|
|
771
879
|
{
|
|
772
880
|
label: t ? "Exit fullscreen" : "Fullscreen",
|
|
773
881
|
onSelect: () => {
|
|
774
|
-
|
|
882
|
+
l(), e();
|
|
775
883
|
}
|
|
776
884
|
}
|
|
777
885
|
),
|
|
778
|
-
n > 1 ? Array.from({ length: n }, (i,
|
|
779
|
-
|
|
886
|
+
n > 1 ? Array.from({ length: n }, (i, f) => /* @__PURE__ */ o(
|
|
887
|
+
te,
|
|
780
888
|
{
|
|
781
|
-
label: `View ${
|
|
889
|
+
label: `View ${f + 1}${f === r ? " ✓" : ""}`,
|
|
782
890
|
onSelect: () => {
|
|
783
|
-
|
|
891
|
+
l(), s(f);
|
|
784
892
|
}
|
|
785
893
|
},
|
|
786
|
-
|
|
894
|
+
f
|
|
787
895
|
)) : null,
|
|
788
|
-
/* @__PURE__ */
|
|
789
|
-
|
|
896
|
+
/* @__PURE__ */ o(
|
|
897
|
+
te,
|
|
790
898
|
{
|
|
791
899
|
label: "Export PNG",
|
|
792
900
|
onSelect: () => {
|
|
793
|
-
|
|
901
|
+
l(), a();
|
|
794
902
|
}
|
|
795
903
|
}
|
|
796
904
|
)
|
|
@@ -800,19 +908,19 @@ function mt({
|
|
|
800
908
|
] }) : null
|
|
801
909
|
] });
|
|
802
910
|
}
|
|
803
|
-
function
|
|
804
|
-
const { flatLayers: t, selectLayer: e, generateAllPreviews: n } =
|
|
805
|
-
return
|
|
911
|
+
function vt() {
|
|
912
|
+
const { flatLayers: t, selectLayer: e, generateAllPreviews: n } = Te({ previewSize: 96 });
|
|
913
|
+
return B(() => {
|
|
806
914
|
t.length > 0 && n();
|
|
807
|
-
}, [t.length, n]), /* @__PURE__ */
|
|
915
|
+
}, [t.length, n]), /* @__PURE__ */ C(
|
|
808
916
|
"div",
|
|
809
917
|
{
|
|
810
918
|
"data-sc-part": "snowcone-editor-idle-dock",
|
|
811
919
|
style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 8, minHeight: 44 },
|
|
812
920
|
children: [
|
|
813
|
-
/* @__PURE__ */
|
|
814
|
-
t.length > 0 ? /* @__PURE__ */
|
|
815
|
-
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(
|
|
816
924
|
"button",
|
|
817
925
|
{
|
|
818
926
|
type: "button",
|
|
@@ -835,8 +943,8 @@ function ft() {
|
|
|
835
943
|
},
|
|
836
944
|
children: r.previewUrl ? (
|
|
837
945
|
// eslint-disable-next-line @next/next/no-img-element
|
|
838
|
-
/* @__PURE__ */
|
|
839
|
-
) : /* @__PURE__ */
|
|
946
|
+
/* @__PURE__ */ o("img", { src: r.previewUrl, alt: "", style: { width: "100%", height: "100%", objectFit: "contain" } })
|
|
947
|
+
) : /* @__PURE__ */ o(
|
|
840
948
|
"span",
|
|
841
949
|
{
|
|
842
950
|
style: {
|
|
@@ -857,13 +965,13 @@ function ft() {
|
|
|
857
965
|
}
|
|
858
966
|
);
|
|
859
967
|
}
|
|
860
|
-
function
|
|
968
|
+
function wt({
|
|
861
969
|
onAddToCart: t,
|
|
862
970
|
defaultQuantity: e
|
|
863
971
|
}) {
|
|
864
|
-
const { price: n, complete: r } =
|
|
865
|
-
return /* @__PURE__ */
|
|
866
|
-
|
|
972
|
+
const { price: n, complete: r } = pt();
|
|
973
|
+
return /* @__PURE__ */ C(
|
|
974
|
+
U.Buy,
|
|
867
975
|
{
|
|
868
976
|
onAddToCart: t,
|
|
869
977
|
...typeof e == "number" ? { defaultQuantity: e } : {},
|
|
@@ -886,36 +994,36 @@ function pt({
|
|
|
886
994
|
},
|
|
887
995
|
children: [
|
|
888
996
|
"Add to cart",
|
|
889
|
-
typeof n == "number" ? ` · ${
|
|
997
|
+
typeof n == "number" ? ` · ${ht(n)}` : ""
|
|
890
998
|
]
|
|
891
999
|
}
|
|
892
1000
|
);
|
|
893
1001
|
}
|
|
894
|
-
function
|
|
1002
|
+
function Et({
|
|
895
1003
|
title: t,
|
|
896
1004
|
height: e,
|
|
897
1005
|
mockupIds: n,
|
|
898
1006
|
onAddToCart: r,
|
|
899
|
-
defaultQuantity:
|
|
1007
|
+
defaultQuantity: s,
|
|
900
1008
|
className: a,
|
|
901
|
-
style:
|
|
1009
|
+
style: d
|
|
902
1010
|
}) {
|
|
903
|
-
const [
|
|
904
|
-
var
|
|
905
|
-
const
|
|
906
|
-
if (!
|
|
907
|
-
const [
|
|
908
|
-
if (typeof
|
|
909
|
-
const
|
|
910
|
-
|
|
911
|
-
}, []),
|
|
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 = {
|
|
912
1020
|
display: "flex",
|
|
913
1021
|
flexDirection: "column",
|
|
914
1022
|
overflow: "hidden",
|
|
915
1023
|
background: "var(--sc-color-surface, #fff)",
|
|
916
1024
|
color: "var(--sc-color-foreground, #111)",
|
|
917
1025
|
fontFamily: "ui-sans-serif, system-ui, sans-serif",
|
|
918
|
-
...
|
|
1026
|
+
...c ? {
|
|
919
1027
|
position: "fixed",
|
|
920
1028
|
inset: 0,
|
|
921
1029
|
zIndex: 9999,
|
|
@@ -928,8 +1036,8 @@ function gt({
|
|
|
928
1036
|
border: "1px solid rgba(0,0,0,0.08)",
|
|
929
1037
|
boxShadow: "0 1px 3px rgba(0,0,0,0.08)"
|
|
930
1038
|
},
|
|
931
|
-
...
|
|
932
|
-
},
|
|
1039
|
+
...d
|
|
1040
|
+
}, x = {
|
|
933
1041
|
position: "absolute",
|
|
934
1042
|
top: 8,
|
|
935
1043
|
right: 12,
|
|
@@ -944,15 +1052,15 @@ function gt({
|
|
|
944
1052
|
cursor: "pointer",
|
|
945
1053
|
zIndex: 2
|
|
946
1054
|
};
|
|
947
|
-
return /* @__PURE__ */
|
|
1055
|
+
return /* @__PURE__ */ C(
|
|
948
1056
|
"div",
|
|
949
1057
|
{
|
|
950
1058
|
"data-sc-part": "snowcone-editor",
|
|
951
|
-
"data-sc-fullscreen":
|
|
1059
|
+
"data-sc-fullscreen": c ? "true" : void 0,
|
|
952
1060
|
className: a,
|
|
953
|
-
style:
|
|
1061
|
+
style: h,
|
|
954
1062
|
children: [
|
|
955
|
-
/* @__PURE__ */
|
|
1063
|
+
/* @__PURE__ */ C(
|
|
956
1064
|
"div",
|
|
957
1065
|
{
|
|
958
1066
|
"data-sc-part": "snowcone-editor-header",
|
|
@@ -964,35 +1072,35 @@ function gt({
|
|
|
964
1072
|
flexShrink: 0
|
|
965
1073
|
},
|
|
966
1074
|
children: [
|
|
967
|
-
/* @__PURE__ */
|
|
968
|
-
/* @__PURE__ */
|
|
969
|
-
/* @__PURE__ */
|
|
970
|
-
|
|
1075
|
+
/* @__PURE__ */ o("span", { style: { fontSize: 14, fontWeight: 700, marginRight: "auto" }, children: t }),
|
|
1076
|
+
/* @__PURE__ */ o(U.History, {}),
|
|
1077
|
+
/* @__PURE__ */ o(
|
|
1078
|
+
bt,
|
|
971
1079
|
{
|
|
972
|
-
fullscreen:
|
|
973
|
-
onToggleFullscreen: () =>
|
|
1080
|
+
fullscreen: c,
|
|
1081
|
+
onToggleFullscreen: () => l((g) => !g),
|
|
974
1082
|
viewCount: n.length,
|
|
975
1083
|
viewIndex: i,
|
|
976
|
-
onSelectView:
|
|
977
|
-
onExport: () => void
|
|
1084
|
+
onSelectView: f,
|
|
1085
|
+
onExport: () => void w()
|
|
978
1086
|
}
|
|
979
1087
|
),
|
|
980
|
-
/* @__PURE__ */
|
|
1088
|
+
/* @__PURE__ */ o(wt, { onAddToCart: r, defaultQuantity: s })
|
|
981
1089
|
]
|
|
982
1090
|
}
|
|
983
1091
|
),
|
|
984
|
-
/* @__PURE__ */
|
|
1092
|
+
/* @__PURE__ */ C(
|
|
985
1093
|
"div",
|
|
986
1094
|
{
|
|
987
1095
|
"data-sc-part": "snowcone-editor-stage",
|
|
988
1096
|
style: { position: "relative", flex: 1, minHeight: 0, padding: "4px 12px" },
|
|
989
1097
|
children: [
|
|
990
|
-
/* @__PURE__ */
|
|
991
|
-
|
|
1098
|
+
/* @__PURE__ */ o(U.Canvas, { ref: y, style: { height: "100%" } }),
|
|
1099
|
+
u ? (
|
|
992
1100
|
// Swapped: the mockup IS the stage; the corner chip returns to the
|
|
993
1101
|
// artwork. The canvas stays mounted underneath (no document
|
|
994
1102
|
// teardown), just covered.
|
|
995
|
-
/* @__PURE__ */
|
|
1103
|
+
/* @__PURE__ */ C(
|
|
996
1104
|
"div",
|
|
997
1105
|
{
|
|
998
1106
|
"data-sc-part": "snowcone-editor-swap-stage",
|
|
@@ -1007,24 +1115,24 @@ function gt({
|
|
|
1007
1115
|
padding: 8
|
|
1008
1116
|
},
|
|
1009
1117
|
children: [
|
|
1010
|
-
/* @__PURE__ */
|
|
1011
|
-
|
|
1118
|
+
/* @__PURE__ */ o(
|
|
1119
|
+
U.Preview,
|
|
1012
1120
|
{
|
|
1013
|
-
mockupId:
|
|
1121
|
+
mockupId: v,
|
|
1014
1122
|
alt: "Product mockup",
|
|
1015
|
-
fallback: /* @__PURE__ */
|
|
1123
|
+
fallback: /* @__PURE__ */ o("div", { "aria-busy": "true", children: "Rendering…" }),
|
|
1016
1124
|
style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain", borderRadius: 12 }
|
|
1017
1125
|
}
|
|
1018
1126
|
),
|
|
1019
|
-
/* @__PURE__ */
|
|
1127
|
+
/* @__PURE__ */ o(
|
|
1020
1128
|
"button",
|
|
1021
1129
|
{
|
|
1022
1130
|
type: "button",
|
|
1023
1131
|
"aria-label": "Back to artwork",
|
|
1024
1132
|
"data-sc-part": "snowcone-editor-swap-back",
|
|
1025
|
-
onClick: () =>
|
|
1133
|
+
onClick: () => m(!1),
|
|
1026
1134
|
style: {
|
|
1027
|
-
...
|
|
1135
|
+
...x,
|
|
1028
1136
|
display: "flex",
|
|
1029
1137
|
alignItems: "center",
|
|
1030
1138
|
justifyContent: "center",
|
|
@@ -1039,20 +1147,20 @@ function gt({
|
|
|
1039
1147
|
]
|
|
1040
1148
|
}
|
|
1041
1149
|
)
|
|
1042
|
-
) : /* @__PURE__ */
|
|
1150
|
+
) : /* @__PURE__ */ o(
|
|
1043
1151
|
"button",
|
|
1044
1152
|
{
|
|
1045
1153
|
type: "button",
|
|
1046
1154
|
"aria-label": "Show product mockup",
|
|
1047
1155
|
"data-sc-part": "snowcone-editor-pip",
|
|
1048
|
-
onClick: () =>
|
|
1049
|
-
style:
|
|
1050
|
-
children: /* @__PURE__ */
|
|
1051
|
-
|
|
1156
|
+
onClick: () => m(!0),
|
|
1157
|
+
style: x,
|
|
1158
|
+
children: /* @__PURE__ */ o(
|
|
1159
|
+
U.Preview,
|
|
1052
1160
|
{
|
|
1053
|
-
mockupId:
|
|
1161
|
+
mockupId: v,
|
|
1054
1162
|
alt: "Product mockup preview",
|
|
1055
|
-
fallback: /* @__PURE__ */
|
|
1163
|
+
fallback: /* @__PURE__ */ o("span", { style: { fontSize: 10, opacity: 0.5 }, "aria-busy": "true", children: "mockup…" }),
|
|
1056
1164
|
style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
|
|
1057
1165
|
}
|
|
1058
1166
|
)
|
|
@@ -1061,15 +1169,15 @@ function gt({
|
|
|
1061
1169
|
]
|
|
1062
1170
|
}
|
|
1063
1171
|
),
|
|
1064
|
-
/* @__PURE__ */
|
|
1172
|
+
/* @__PURE__ */ C(
|
|
1065
1173
|
"div",
|
|
1066
1174
|
{
|
|
1067
1175
|
"data-sc-part": "snowcone-editor-zone",
|
|
1068
|
-
"data-sc-zone-state":
|
|
1176
|
+
"data-sc-zone-state": b ? "selected" : "idle",
|
|
1069
1177
|
style: { flexShrink: 0, padding: "4px 16px 14px" },
|
|
1070
1178
|
children: [
|
|
1071
|
-
/* @__PURE__ */
|
|
1072
|
-
|
|
1179
|
+
/* @__PURE__ */ o("div", { style: { display: b ? void 0 : "none" }, children: /* @__PURE__ */ o(U.Controls, { placement: "docked" }) }),
|
|
1180
|
+
b ? null : /* @__PURE__ */ o(vt, {})
|
|
1073
1181
|
]
|
|
1074
1182
|
}
|
|
1075
1183
|
)
|
|
@@ -1077,41 +1185,42 @@ function gt({
|
|
|
1077
1185
|
}
|
|
1078
1186
|
);
|
|
1079
1187
|
}
|
|
1080
|
-
function
|
|
1188
|
+
function Vt(t) {
|
|
1081
1189
|
const {
|
|
1082
1190
|
onAddToCart: e,
|
|
1083
1191
|
defaultQuantity: n,
|
|
1084
1192
|
title: r = "Editor",
|
|
1085
|
-
height:
|
|
1193
|
+
height: s = 480,
|
|
1086
1194
|
className: a,
|
|
1087
|
-
style:
|
|
1088
|
-
...
|
|
1195
|
+
style: d,
|
|
1196
|
+
...c
|
|
1089
1197
|
} = t;
|
|
1090
|
-
return /* @__PURE__ */
|
|
1091
|
-
|
|
1198
|
+
return /* @__PURE__ */ o(U.Root, { ...c, children: /* @__PURE__ */ o(
|
|
1199
|
+
Et,
|
|
1092
1200
|
{
|
|
1093
1201
|
title: r,
|
|
1094
|
-
height:
|
|
1095
|
-
mockupIds:
|
|
1202
|
+
height: s,
|
|
1203
|
+
mockupIds: c.product.mockupIds,
|
|
1096
1204
|
onAddToCart: e,
|
|
1097
1205
|
...typeof n == "number" ? { defaultQuantity: n } : {},
|
|
1098
1206
|
className: a,
|
|
1099
|
-
style:
|
|
1207
|
+
style: d
|
|
1100
1208
|
}
|
|
1101
1209
|
) });
|
|
1102
1210
|
}
|
|
1103
|
-
|
|
1211
|
+
_e();
|
|
1104
1212
|
export {
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
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
|
|
1116
1225
|
};
|
|
1117
|
-
//# sourceMappingURL=embed-
|
|
1226
|
+
//# sourceMappingURL=embed-8ecUMMH-.js.map
|