@snowcone-app/canvas 0.21.2 → 0.21.3
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 +14 -0
- 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-M7rw1c1k.js} +5 -5
- package/dist/{EditorCanvasImpl-BmLHjXe7.js.map → EditorCanvasImpl-M7rw1c1k.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/components/editor/LazyImageBrowser.d.ts +7 -0
- package/dist/components/editor/commerceStore.d.ts +13 -0
- package/dist/custom-icons-BW6hqmkL.js +236 -0
- package/dist/custom-icons-BW6hqmkL.js.map +1 -0
- package/dist/{embed-pM7ZkFuz.js → embed-QBZkgWDr.js} +287 -272
- package/dist/{embed-pM7ZkFuz.js.map → embed-QBZkgWDr.js.map} +1 -1
- package/dist/embed.mjs +3 -3
- 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/template-fields-BsnHMf1i.js.map +0 -1
- package/dist/validation-DdVeWnlo.js +0 -9308
- package/dist/validation-DdVeWnlo.js.map +0 -1
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { E as
|
|
2
|
-
import { y as
|
|
3
|
-
import { jsx as s, jsxs 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 be, o as ve, p as xe, C as we, q, r as Ee, t as ke, v as Se, w as Ie, x as Re, g as Ce, e as Oe } from "./UnifiedFontService-CC3CSmH5.js";
|
|
2
|
+
import { y as $ } from "./FontAnalyzer-CwIpgTGd.js";
|
|
3
|
+
import { jsx as s, jsxs as R, Fragment as se } from "react/jsx-runtime";
|
|
4
|
+
import { useContext as Ne, createContext as Te, useRef as N, useState as C, useMemo as O, useSyncExternalStore as B, useEffect as D, Component as $e, forwardRef as ie, useId as Z, useLayoutEffect as W, useCallback as j } from "react";
|
|
5
|
+
import { assertVariantSelected as _e, RenderSession as De, createCartDetail as Ve } from "@snowcone-app/sdk";
|
|
6
|
+
import { i as ae, g as V, B as Ae, E as Fe, r as Be } from "./editorErrors-B2mb1sVN.js";
|
|
7
|
+
import { u as Ue, p as Le } from "./usePieceGuideBundle-CbJJg66S.js";
|
|
8
|
+
import { s as ee, i as Pe } from "./design-builder-CT4DHIPe.js";
|
|
9
|
+
import { D as je, C as qe, g as Me, e as ze } from "./template-fields-C2pSfMBh.js";
|
|
10
10
|
import "./CanvasStateV1-DmZ1Qvvn.js";
|
|
11
|
-
const
|
|
11
|
+
const ce = Te(void 0);
|
|
12
12
|
function G() {
|
|
13
|
-
const t =
|
|
13
|
+
const t = Ne(ce);
|
|
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
|
|
20
|
+
const He = "[RealtimeEmbed]";
|
|
21
|
+
function Ke(t) {
|
|
22
22
|
var r, o;
|
|
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);
|
|
@@ -27,7 +27,7 @@ function He(t) {
|
|
|
27
27
|
);
|
|
28
28
|
return !!(t != null && t.variantId) || e.size > 1 ? [] : (t == null ? void 0 : t.placements) ?? [];
|
|
29
29
|
}
|
|
30
|
-
function
|
|
30
|
+
function le({ shop: t, product: e, design: n, hasGrant: r }) {
|
|
31
31
|
var l, m;
|
|
32
32
|
const o = [];
|
|
33
33
|
if (t || o.push({
|
|
@@ -44,7 +44,7 @@ function ce({ shop: t, product: e, design: n, hasGrant: r }) {
|
|
|
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
|
-
|
|
47
|
+
_e(e);
|
|
48
48
|
} catch (f) {
|
|
49
49
|
o.push({
|
|
50
50
|
severity: "error",
|
|
@@ -52,7 +52,7 @@ function ce({ shop: t, product: e, design: n, hasGrant: r }) {
|
|
|
52
52
|
message: f instanceof Error ? f.message : String(f)
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
-
const a = n.toJSON(), c = a.activeArtboard, u =
|
|
55
|
+
const a = n.toJSON(), c = a.activeArtboard, u = Ke(e);
|
|
56
56
|
u.length > 1 && o.push({
|
|
57
57
|
severity: "error",
|
|
58
58
|
issue: "multi-placement",
|
|
@@ -62,30 +62,30 @@ function ce({ shop: t, product: e, design: n, hasGrant: r }) {
|
|
|
62
62
|
issue: "placement-mismatch",
|
|
63
63
|
message: `the design's placement "${c}" 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 d = a.elements.map((f) => f.name).filter((f) => !!f), i = d.filter((f,
|
|
65
|
+
const d = a.elements.map((f) => f.name).filter((f) => !!f), i = d.filter((f, w) => d.indexOf(f) !== w);
|
|
66
66
|
return i.length && o.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
|
}), o;
|
|
71
71
|
}
|
|
72
|
-
function Ke(t) {
|
|
73
|
-
for (const e of ce(t))
|
|
74
|
-
(e.severity === "error" && e.issue !== "placement-mismatch" ? console.error : console.warn)(`${ze} ${e.message}`);
|
|
75
|
-
}
|
|
76
|
-
const le = 8e3;
|
|
77
72
|
function We(t) {
|
|
78
|
-
|
|
73
|
+
for (const e of le(t))
|
|
74
|
+
(e.severity === "error" && e.issue !== "placement-mismatch" ? console.error : console.warn)(`${He} ${e.message}`);
|
|
79
75
|
}
|
|
76
|
+
const de = 8e3;
|
|
80
77
|
function Ge(t) {
|
|
78
|
+
return `[RealtimeEmbed] No mockup after ${Math.round(de / 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
|
+
}
|
|
80
|
+
function Qe(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 ue({ error: t, onRetry: e }) {
|
|
87
|
+
const n = ae(t) ? t.code : "EDITOR_ERROR";
|
|
88
|
+
return /* @__PURE__ */ R(
|
|
89
89
|
"div",
|
|
90
90
|
{
|
|
91
91
|
"data-sc-part": "error",
|
|
@@ -101,7 +101,7 @@ function de({ error: t, onRetry: e }) {
|
|
|
101
101
|
lineHeight: 1.5
|
|
102
102
|
},
|
|
103
103
|
children: [
|
|
104
|
-
/* @__PURE__ */
|
|
104
|
+
/* @__PURE__ */ R("p", { style: { margin: 0, fontWeight: 700 }, children: [
|
|
105
105
|
"Editor failed: ",
|
|
106
106
|
n
|
|
107
107
|
] }),
|
|
@@ -130,7 +130,7 @@ function de({ error: t, onRetry: e }) {
|
|
|
130
130
|
}
|
|
131
131
|
);
|
|
132
132
|
}
|
|
133
|
-
class
|
|
133
|
+
class Je extends $e {
|
|
134
134
|
constructor() {
|
|
135
135
|
super(...arguments), this.state = { caught: null };
|
|
136
136
|
}
|
|
@@ -139,20 +139,20 @@ class Qe extends Te {
|
|
|
139
139
|
}
|
|
140
140
|
componentDidCatch(e) {
|
|
141
141
|
var n;
|
|
142
|
-
|
|
142
|
+
Be(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__ */ s(
|
|
145
|
+
return this.state.caught ? /* @__PURE__ */ s(ue, { error: this.state.caught }) : this.props.children;
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
function
|
|
148
|
+
function Ye({ reportedError: t, onRetry: e, children: n }) {
|
|
149
149
|
if (t) {
|
|
150
|
-
const r =
|
|
151
|
-
return /* @__PURE__ */ s(
|
|
150
|
+
const r = ae(t) && t.code === "E_CHUNK_LOAD_FAILED";
|
|
151
|
+
return /* @__PURE__ */ s(ue, { error: t, onRetry: r ? e : void 0 });
|
|
152
152
|
}
|
|
153
|
-
return /* @__PURE__ */ s(
|
|
153
|
+
return /* @__PURE__ */ s(Je, { reportedError: null, onRetry: e, children: n });
|
|
154
154
|
}
|
|
155
|
-
function
|
|
155
|
+
function Xe(t) {
|
|
156
156
|
const {
|
|
157
157
|
shop: e,
|
|
158
158
|
product: n,
|
|
@@ -165,127 +165,142 @@ function Ye(t) {
|
|
|
165
165
|
children: i,
|
|
166
166
|
internals: l,
|
|
167
167
|
__validation: m = "throw"
|
|
168
|
-
} = t, f = O(() => r.toJSON().activeArtboard, [r])
|
|
168
|
+
} = t, f = O(() => r.toJSON().activeArtboard, [r]), w = O(() => {
|
|
169
|
+
const p = r.toJSON().artboards[0];
|
|
170
|
+
if (p)
|
|
171
|
+
return {
|
|
172
|
+
name: p.name,
|
|
173
|
+
width: p.width,
|
|
174
|
+
height: p.height,
|
|
175
|
+
...p.backgroundColor ? { backgroundColor: p.backgroundColor } : {}
|
|
176
|
+
};
|
|
177
|
+
}, [r]);
|
|
169
178
|
B(
|
|
170
179
|
l.commerce.subscribe,
|
|
171
180
|
l.commerce.getVersion,
|
|
172
181
|
l.commerce.getVersion
|
|
173
182
|
);
|
|
174
|
-
const
|
|
175
|
-
if (!
|
|
176
|
-
const
|
|
177
|
-
return
|
|
178
|
-
}, [
|
|
179
|
-
|
|
180
|
-
const [
|
|
183
|
+
const g = l.commerce.renderVariantId(), v = Ue(g ?? n.variantId ?? n.defaultGvid), E = O(() => {
|
|
184
|
+
if (!v) return null;
|
|
185
|
+
const p = r.toJSON().artboards[0];
|
|
186
|
+
return Le(v, p) ?? null;
|
|
187
|
+
}, [v, r]), T = N(a), h = N(c);
|
|
188
|
+
T.current = a, h.current = c;
|
|
189
|
+
const [k, L] = C([]), [x, S] = C(!0), [A, F] = C(null), P = !!("grantUrl" in t && t.grantUrl || "grant" in t && t.grant), Q = Qe(t), ge = "grantUrl" in Q ? Q.grantUrl : "getToken", te = `${n.productId}|${n.mockupIds.join(",")}|${n.variantId ?? ""}`, M = `${e}|${te}|${f}|${P}`;
|
|
181
190
|
O(() => {
|
|
182
|
-
var
|
|
191
|
+
var I;
|
|
183
192
|
if (m !== "throw") return;
|
|
184
|
-
const
|
|
193
|
+
const p = le({ shop: e, product: n, design: r, hasGrant: P }), y = p.find((U) => U.severity === "error");
|
|
185
194
|
if (y)
|
|
186
|
-
throw new
|
|
195
|
+
throw new V("E_EMBED_CONFIG", y.message, {
|
|
187
196
|
issue: y.issue,
|
|
188
197
|
docSlug: "embed-mode"
|
|
189
198
|
});
|
|
190
|
-
for (const
|
|
191
|
-
typeof
|
|
199
|
+
for (const U of p)
|
|
200
|
+
typeof $ < "u" && ((I = $.env) == null ? void 0 : I.NODE_ENV) !== "production" && console.warn(`[Editor.Root] ${U.message}`);
|
|
192
201
|
}, [M, m]);
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
var
|
|
196
|
-
if (m === "warn" && typeof
|
|
197
|
-
if (
|
|
198
|
-
|
|
202
|
+
const ne = N(null);
|
|
203
|
+
D(() => {
|
|
204
|
+
var p;
|
|
205
|
+
if (m === "warn" && typeof $ < "u" && ((p = $.env) == null ? void 0 : p.NODE_ENV) !== "production") {
|
|
206
|
+
if (ne.current === M) return;
|
|
207
|
+
ne.current = M, We({ shop: e, product: n, design: r, hasGrant: P });
|
|
199
208
|
}
|
|
200
209
|
}, [M, m]);
|
|
201
210
|
const z = O(
|
|
202
211
|
() => {
|
|
203
212
|
try {
|
|
204
|
-
return { session: new
|
|
205
|
-
} catch (
|
|
206
|
-
return { error:
|
|
213
|
+
return { session: new De({ shop: e, product: n, wsUrl: u, ...Q }) };
|
|
214
|
+
} catch (p) {
|
|
215
|
+
return { error: p instanceof Error ? p.message : String(p) };
|
|
207
216
|
}
|
|
208
217
|
},
|
|
209
218
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
210
|
-
[e,
|
|
211
|
-
),
|
|
212
|
-
|
|
213
|
-
var
|
|
214
|
-
const
|
|
215
|
-
|
|
219
|
+
[e, te, f, u, ge]
|
|
220
|
+
), b = "session" in z ? z.session : null, H = "error" in z ? z.error : null, K = O(() => (p, y = o) => {
|
|
221
|
+
b && (F(null), S(!0), b.renderState(f, p, y).catch((I) => {
|
|
222
|
+
var oe;
|
|
223
|
+
const U = I instanceof Error ? I.message : String(I);
|
|
224
|
+
F(U), S(!1), (oe = h.current) == null || oe.call(h, U);
|
|
216
225
|
}));
|
|
217
|
-
}, [
|
|
218
|
-
|
|
219
|
-
var
|
|
226
|
+
}, [b, f, o]);
|
|
227
|
+
D(() => {
|
|
228
|
+
var p;
|
|
220
229
|
if (H) {
|
|
221
|
-
|
|
230
|
+
F(H), S(!1), (p = h.current) == null || p.call(h, H);
|
|
222
231
|
return;
|
|
223
232
|
}
|
|
224
|
-
if (
|
|
225
|
-
return
|
|
226
|
-
var
|
|
227
|
-
|
|
228
|
-
}),
|
|
229
|
-
var
|
|
230
|
-
|
|
231
|
-
}), K(r.toServerRequest()), () =>
|
|
232
|
-
}, [
|
|
233
|
-
const
|
|
233
|
+
if (b)
|
|
234
|
+
return b.onMockups((y) => {
|
|
235
|
+
var I;
|
|
236
|
+
L(y), S(!1), (I = T.current) == null || I.call(T, y);
|
|
237
|
+
}), b.onError((y) => {
|
|
238
|
+
var I;
|
|
239
|
+
F(y), S(!1), (I = h.current) == null || I.call(h, y);
|
|
240
|
+
}), K(r.toServerRequest()), () => b.close();
|
|
241
|
+
}, [b, H]);
|
|
242
|
+
const J = N({
|
|
234
243
|
session: null,
|
|
235
244
|
variantId: void 0
|
|
236
245
|
});
|
|
237
|
-
|
|
238
|
-
if (!
|
|
239
|
-
const
|
|
240
|
-
if (
|
|
241
|
-
|
|
246
|
+
D(() => {
|
|
247
|
+
if (!b || !g) return;
|
|
248
|
+
const p = J.current, y = p.session === b ? p.variantId : n.variantId;
|
|
249
|
+
if (g === y) {
|
|
250
|
+
J.current = { session: b, variantId: y };
|
|
242
251
|
return;
|
|
243
252
|
}
|
|
244
|
-
|
|
245
|
-
}, [
|
|
253
|
+
J.current = { session: b, variantId: g }, b.setProduct({ ...n, variantId: g }), K(ee(l.store.getState()));
|
|
254
|
+
}, [b, g]), D(() => {
|
|
246
255
|
var y;
|
|
247
|
-
if (!
|
|
248
|
-
const
|
|
249
|
-
return () => clearTimeout(
|
|
250
|
-
}, [
|
|
251
|
-
const
|
|
256
|
+
if (!x || typeof $ > "u" || ((y = $.env) == null ? void 0 : y.NODE_ENV) === "production") return;
|
|
257
|
+
const p = setTimeout(() => console.warn(Ge(f)), de);
|
|
258
|
+
return () => clearTimeout(p);
|
|
259
|
+
}, [x, f]);
|
|
260
|
+
const he = O(
|
|
252
261
|
() => ({
|
|
253
|
-
session:
|
|
262
|
+
session: b,
|
|
254
263
|
design: r,
|
|
255
264
|
placement: f,
|
|
256
265
|
product: n,
|
|
257
|
-
mockups:
|
|
258
|
-
isRendering:
|
|
259
|
-
error:
|
|
266
|
+
mockups: k,
|
|
267
|
+
isRendering: x,
|
|
268
|
+
error: A,
|
|
260
269
|
throttleMs: o,
|
|
261
|
-
pieceGuides:
|
|
270
|
+
pieceGuides: E,
|
|
262
271
|
pushRender: K,
|
|
263
272
|
stateStore: l.store
|
|
264
273
|
}),
|
|
265
|
-
[
|
|
266
|
-
),
|
|
274
|
+
[b, r, f, n, k, x, A, o, E, K, l.store]
|
|
275
|
+
), ye = B(
|
|
267
276
|
l.registry.subscribe,
|
|
268
277
|
l.registry.getVersion,
|
|
269
278
|
l.registry.getVersion
|
|
270
279
|
);
|
|
271
|
-
O(() => l.registry.validate(), [l.registry,
|
|
272
|
-
const
|
|
273
|
-
|
|
280
|
+
O(() => l.registry.validate(), [l.registry, ye]);
|
|
281
|
+
const re = /* @__PURE__ */ s(xe.Provider, { value: l, children: /* @__PURE__ */ s(ce.Provider, { value: he, children: /* @__PURE__ */ s(Ae.Provider, { value: l.registry, children: /* @__PURE__ */ s(
|
|
282
|
+
Fe,
|
|
283
|
+
{
|
|
284
|
+
...w ? { initialArtboardConfig: w } : {},
|
|
285
|
+
children: i
|
|
286
|
+
}
|
|
287
|
+
) }) }) });
|
|
288
|
+
return d ? /* @__PURE__ */ s(we, { services: d, children: re }) : re;
|
|
274
289
|
}
|
|
275
|
-
function
|
|
276
|
-
const { design: e, product: n } = t, r = `${n.productId}|${n.variantId ?? ""}`, o =
|
|
290
|
+
function me(t) {
|
|
291
|
+
const { design: e, product: n } = t, r = `${n.productId}|${n.variantId ?? ""}`, o = N(null), a = N(null), [c, u] = C(null);
|
|
277
292
|
(o.current === null || o.current.design !== e) && (o.current = {
|
|
278
293
|
design: e,
|
|
279
294
|
internals: {
|
|
280
|
-
store: new
|
|
281
|
-
registry: new
|
|
295
|
+
store: new je(e.toJSON()),
|
|
296
|
+
registry: new be()
|
|
282
297
|
}
|
|
283
|
-
}), (a.current === null || a.current.productIdentity !== r) && (a.current = { productIdentity: r, commerce: new
|
|
298
|
+
}), (a.current === null || a.current.productIdentity !== r) && (a.current = { productIdentity: r, commerce: new qe(n) });
|
|
284
299
|
const d = O(
|
|
285
300
|
() => ({
|
|
286
301
|
...o.current.internals,
|
|
287
302
|
commerce: a.current.commerce,
|
|
288
|
-
...
|
|
303
|
+
...ve(u)
|
|
289
304
|
}),
|
|
290
305
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
291
306
|
[o.current.internals, a.current.commerce]
|
|
@@ -294,26 +309,26 @@ function ue(t) {
|
|
|
294
309
|
// `display: contents` — the .sc-root scope without a layout box, so the
|
|
295
310
|
// host's grid/flex sees the parts directly (and the legacy RealtimeEmbed
|
|
296
311
|
// wrapper, which had no DOM at all, stays layout-identical).
|
|
297
|
-
/* @__PURE__ */ s("div", { className: "sc-root", style: { display: "contents" }, "data-sc-part": "root", children: /* @__PURE__ */ s(
|
|
312
|
+
/* @__PURE__ */ s("div", { className: "sc-root", style: { display: "contents" }, "data-sc-part": "root", children: /* @__PURE__ */ s(Ye, { reportedError: c, onRetry: () => u(null), children: /* @__PURE__ */ s(Xe, { ...t, internals: d }) }) })
|
|
298
313
|
);
|
|
299
314
|
}
|
|
300
|
-
let
|
|
301
|
-
function
|
|
302
|
-
return
|
|
315
|
+
let Ze = () => import("./EditorCanvasImpl-M7rw1c1k.js").then((t) => t.EditorCanvasImpl);
|
|
316
|
+
function fe() {
|
|
317
|
+
return Ze();
|
|
303
318
|
}
|
|
304
|
-
const
|
|
305
|
-
const c = q("Editor.Canvas"), u =
|
|
319
|
+
const et = ie(function({ children: e, maxHeight: n, className: r, style: o }, a) {
|
|
320
|
+
const c = q("Editor.Canvas"), u = Z();
|
|
306
321
|
W(() => c.registry.registerCanvas(u), [c.registry, u]);
|
|
307
|
-
const [d, i] =
|
|
308
|
-
return
|
|
322
|
+
const [d, i] = C(null);
|
|
323
|
+
return D(() => {
|
|
309
324
|
let l = !1;
|
|
310
|
-
return
|
|
325
|
+
return fe().then(
|
|
311
326
|
(m) => {
|
|
312
327
|
l || i(() => m);
|
|
313
328
|
},
|
|
314
329
|
(m) => {
|
|
315
330
|
l || c.reportRuntimeError(
|
|
316
|
-
new
|
|
331
|
+
new V(
|
|
317
332
|
"E_CHUNK_LOAD_FAILED",
|
|
318
333
|
`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
334
|
{ cause: m instanceof Error ? m.message : String(m), docSlug: "embed-mode" }
|
|
@@ -338,34 +353,34 @@ const Ze = se(function({ children: e, maxHeight: n, className: r, style: o }, a)
|
|
|
338
353
|
"aria-busy": "true"
|
|
339
354
|
}
|
|
340
355
|
);
|
|
341
|
-
}),
|
|
342
|
-
function
|
|
343
|
-
for (const e of
|
|
356
|
+
}), tt = 1.2, Y = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
|
|
357
|
+
function nt(t) {
|
|
358
|
+
for (const e of Y)
|
|
344
359
|
if (e >= t) return e;
|
|
345
|
-
return
|
|
360
|
+
return Y[Y.length - 1];
|
|
346
361
|
}
|
|
347
|
-
function
|
|
348
|
-
if (!(t > 0) || !(e > 0) || e <= t *
|
|
349
|
-
const n =
|
|
362
|
+
function rt(t, e) {
|
|
363
|
+
if (!(t > 0) || !(e > 0) || e <= t * tt) return null;
|
|
364
|
+
const n = nt(e);
|
|
350
365
|
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
366
|
}
|
|
352
|
-
function
|
|
367
|
+
function pe({
|
|
353
368
|
mockupId: t,
|
|
354
369
|
fallback: e = null,
|
|
355
370
|
alt: n = "Live product mockup",
|
|
356
371
|
className: r,
|
|
357
372
|
style: o
|
|
358
373
|
}) {
|
|
359
|
-
const { mockups: a, error: c } = G(), u =
|
|
374
|
+
const { mockups: a, error: c } = G(), u = N(/* @__PURE__ */ new Set()), d = t ? a.find((l) => l.mockupId === t && l.imageUrl) : a.find((l) => l.imageUrl);
|
|
360
375
|
if (!(d != null && d.imageUrl))
|
|
361
|
-
return c ? /* @__PURE__ */ s("div", { "data-sc-part": "preview-error", role: "alert", "data-sc-error": c, className: r, style: o, children: e ?? `Render failed: ${c}` }) : /* @__PURE__ */ s(
|
|
376
|
+
return c ? /* @__PURE__ */ s("div", { "data-sc-part": "preview-error", role: "alert", "data-sc-error": c, className: r, style: o, children: e ?? `Render failed: ${c}` }) : /* @__PURE__ */ s(se, { children: e });
|
|
362
377
|
const i = (l) => {
|
|
363
|
-
var
|
|
364
|
-
if (typeof
|
|
378
|
+
var v;
|
|
379
|
+
if (typeof $ > "u" || ((v = $.env) == null ? void 0 : v.NODE_ENV) === "production" || typeof window > "u" || u.current.has(d.mockupId)) return;
|
|
365
380
|
const m = l.currentTarget, f = m.getBoundingClientRect().width;
|
|
366
381
|
if (f <= 0) return;
|
|
367
|
-
const
|
|
368
|
-
|
|
382
|
+
const w = Math.round(f * (window.devicePixelRatio || 1)), g = rt(m.naturalWidth, w);
|
|
383
|
+
g && (u.current.add(d.mockupId), console.warn(g));
|
|
369
384
|
};
|
|
370
385
|
return (
|
|
371
386
|
// eslint-disable-next-line @next/next/no-img-element
|
|
@@ -382,27 +397,27 @@ function fe({
|
|
|
382
397
|
)
|
|
383
398
|
);
|
|
384
399
|
}
|
|
385
|
-
function
|
|
386
|
-
const { layer: e, optional: n = !1, placeholder: r, className: o, style: a } = t, c = q("Editor.TextField"), { pushRender: u, throttleMs: d, stateStore: i } = G(), l =
|
|
387
|
-
if (!
|
|
388
|
-
throw new
|
|
400
|
+
function ot(t) {
|
|
401
|
+
const { layer: e, optional: n = !1, placeholder: r, className: o, style: a } = t, c = q("Editor.TextField"), { pushRender: u, throttleMs: d, stateStore: i } = G(), l = Z(), m = N(null);
|
|
402
|
+
if (!Pe(e))
|
|
403
|
+
throw new V(
|
|
389
404
|
"E_LAYER_TOKEN_REQUIRED",
|
|
390
405
|
`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
406
|
{ received: typeof e == "string" ? e : typeof e, docSlug: "embed-mode" }
|
|
392
407
|
);
|
|
393
408
|
if (m.current !== e.name) {
|
|
394
|
-
const
|
|
395
|
-
if (
|
|
396
|
-
throw new
|
|
409
|
+
const g = i.layerKindOf(e.name);
|
|
410
|
+
if (g === void 0)
|
|
411
|
+
throw new V(
|
|
397
412
|
"E_LAYER_NOT_FOUND",
|
|
398
413
|
`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
414
|
{ layerName: e.name, validNames: i.bindableLayerNames(), docSlug: "embed-mode" }
|
|
400
415
|
);
|
|
401
|
-
if (
|
|
402
|
-
throw new
|
|
416
|
+
if (g !== "text")
|
|
417
|
+
throw new V(
|
|
403
418
|
"E_LAYER_WRONG_KIND",
|
|
404
|
-
`layer "${e.name}" is ${
|
|
405
|
-
{ layerName: e.name, actualKind:
|
|
419
|
+
`layer "${e.name}" is ${g === null ? "not a bindable kind" : `an ${g} layer`} — <Editor.TextField> binds text layers only.`,
|
|
420
|
+
{ layerName: e.name, actualKind: g, docSlug: "embed-mode" }
|
|
406
421
|
);
|
|
407
422
|
m.current = e.name;
|
|
408
423
|
}
|
|
@@ -411,12 +426,12 @@ function rt(t) {
|
|
|
411
426
|
i.subscribe,
|
|
412
427
|
() => i.textOf(e.name) ?? "",
|
|
413
428
|
() => i.textOf(e.name) ?? ""
|
|
414
|
-
),
|
|
415
|
-
(
|
|
416
|
-
const
|
|
429
|
+
), w = j(
|
|
430
|
+
(g) => {
|
|
431
|
+
const v = g.target.value, E = c.registry.getCanvasBridge();
|
|
417
432
|
if (E) {
|
|
418
|
-
E.setTextByName(e.name,
|
|
419
|
-
new
|
|
433
|
+
E.setTextByName(e.name, v) || c.reportInvariant(
|
|
434
|
+
new V(
|
|
420
435
|
"E_LAYER_NOT_FOUND",
|
|
421
436
|
`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
437
|
{ layerName: e.name, docSlug: "embed-mode" }
|
|
@@ -424,7 +439,7 @@ function rt(t) {
|
|
|
424
439
|
);
|
|
425
440
|
return;
|
|
426
441
|
}
|
|
427
|
-
i.updateTextLayer(e.name,
|
|
442
|
+
i.updateTextLayer(e.name, v), u(ee(i.getState()), d);
|
|
428
443
|
},
|
|
429
444
|
[c, e.name, i, u, d]
|
|
430
445
|
);
|
|
@@ -435,7 +450,7 @@ function rt(t) {
|
|
|
435
450
|
"data-sc-layer": e.name,
|
|
436
451
|
type: "text",
|
|
437
452
|
value: f,
|
|
438
|
-
onChange:
|
|
453
|
+
onChange: w,
|
|
439
454
|
placeholder: r,
|
|
440
455
|
"aria-label": t["aria-label"] ?? e.name,
|
|
441
456
|
className: o,
|
|
@@ -443,7 +458,7 @@ function rt(t) {
|
|
|
443
458
|
}
|
|
444
459
|
);
|
|
445
460
|
}
|
|
446
|
-
function
|
|
461
|
+
function st(t) {
|
|
447
462
|
const e = [];
|
|
448
463
|
for (const n of t.missingOptionKeys)
|
|
449
464
|
e.push(`option:${n}`);
|
|
@@ -460,13 +475,13 @@ function ot(t) {
|
|
|
460
475
|
}
|
|
461
476
|
return t.hasRenderableElement || e.push("empty-design"), (!Number.isInteger(t.quantity) || t.quantity < 1) && e.push("quantity"), e;
|
|
462
477
|
}
|
|
463
|
-
function
|
|
478
|
+
function it(t, e) {
|
|
464
479
|
const n = e.getCombinations(), r = e.getAttributes();
|
|
465
480
|
if (Object.keys(r).length === 0 || n.length === 0) return null;
|
|
466
481
|
const o = Object.fromEntries(
|
|
467
|
-
Object.entries(r).map(([a, c]) => [a, { ...c, choices:
|
|
482
|
+
Object.entries(r).map(([a, c]) => [a, { ...c, choices: Me(c) }])
|
|
468
483
|
);
|
|
469
|
-
return
|
|
484
|
+
return Ve({
|
|
470
485
|
productId: t.productId,
|
|
471
486
|
quantity: e.getQuantity(),
|
|
472
487
|
selection: e.getSelection(),
|
|
@@ -474,25 +489,25 @@ function st(t, e) {
|
|
|
474
489
|
attributes: o
|
|
475
490
|
});
|
|
476
491
|
}
|
|
477
|
-
function
|
|
492
|
+
function at(t) {
|
|
478
493
|
const { onAddToCart: e, defaultQuantity: n, children: r, className: o, style: a } = t, c = q("Editor.Buy"), { product: u, stateStore: d } = G(), i = c.commerce;
|
|
479
494
|
if (!(u != null && u.productId))
|
|
480
|
-
throw new
|
|
495
|
+
throw new V(
|
|
481
496
|
"E_BUY_NO_PRODUCT",
|
|
482
497
|
"<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
498
|
{ docSlug: "embed-mode" }
|
|
484
499
|
);
|
|
485
|
-
const l =
|
|
500
|
+
const l = N(!1);
|
|
486
501
|
W(() => {
|
|
487
502
|
l.current || (l.current = !0, typeof n == "number" && i.setQuantity(n));
|
|
488
503
|
}, [i]);
|
|
489
|
-
const m = B(d.subscribe, d.getState, d.getState), f = B(i.subscribe, i.getVersion, i.getVersion),
|
|
504
|
+
const m = B(d.subscribe, d.getState, d.getState), f = B(i.subscribe, i.getVersion, i.getVersion), w = B(
|
|
490
505
|
c.registry.subscribe,
|
|
491
506
|
c.registry.getVersion,
|
|
492
507
|
c.registry.getVersion
|
|
493
|
-
),
|
|
494
|
-
() =>
|
|
495
|
-
quantity:
|
|
508
|
+
), g = i.getQuantity(), v = O(
|
|
509
|
+
() => st({
|
|
510
|
+
quantity: g,
|
|
496
511
|
missingOptionKeys: i.missingOptionKeys(),
|
|
497
512
|
selectionValid: i.selectionValid(),
|
|
498
513
|
textFields: c.registry.getTextFields(),
|
|
@@ -501,27 +516,27 @@ function it(t) {
|
|
|
501
516
|
hasRenderableElement: d.hasRenderableElement()
|
|
502
517
|
}),
|
|
503
518
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
504
|
-
[i,
|
|
505
|
-
), E =
|
|
506
|
-
if (
|
|
507
|
-
|
|
508
|
-
const x = d.getState(),
|
|
519
|
+
[i, g, m, f, w]
|
|
520
|
+
), E = v.length === 0, [T, h] = C(!1), k = N(!1), L = j(() => {
|
|
521
|
+
if (k.current || !E) return;
|
|
522
|
+
k.current = !0, h(!0);
|
|
523
|
+
const x = d.getState(), S = i.resolvedVariantId(), A = {
|
|
509
524
|
productId: u.productId,
|
|
510
|
-
|
|
525
|
+
...S ? { variantId: S } : {},
|
|
511
526
|
quantity: i.getQuantity(),
|
|
512
527
|
selection: i.getSelection(),
|
|
513
|
-
cartDetail:
|
|
528
|
+
cartDetail: it(u, i),
|
|
514
529
|
designState: x,
|
|
515
|
-
serverRequest:
|
|
530
|
+
serverRequest: ee(x)
|
|
516
531
|
};
|
|
517
|
-
let
|
|
532
|
+
let F;
|
|
518
533
|
try {
|
|
519
|
-
|
|
534
|
+
F = e(A);
|
|
520
535
|
} catch (P) {
|
|
521
|
-
throw
|
|
536
|
+
throw k.current = !1, h(!1), P;
|
|
522
537
|
}
|
|
523
|
-
Promise.resolve(
|
|
524
|
-
|
|
538
|
+
Promise.resolve(F).finally(() => {
|
|
539
|
+
k.current = !1, h(!1);
|
|
525
540
|
});
|
|
526
541
|
}, [E, u, i, d, e]);
|
|
527
542
|
return /* @__PURE__ */ s(
|
|
@@ -529,40 +544,40 @@ function it(t) {
|
|
|
529
544
|
{
|
|
530
545
|
type: "button",
|
|
531
546
|
"data-sc-part": "buy",
|
|
532
|
-
"data-sc-buy-state":
|
|
533
|
-
"data-sc-buy-missing":
|
|
534
|
-
disabled: !E ||
|
|
535
|
-
"aria-busy":
|
|
536
|
-
onClick:
|
|
547
|
+
"data-sc-buy-state": T ? "busy" : E ? "ready" : "incomplete",
|
|
548
|
+
"data-sc-buy-missing": v.join(",") || void 0,
|
|
549
|
+
disabled: !E || T,
|
|
550
|
+
"aria-busy": T || void 0,
|
|
551
|
+
onClick: L,
|
|
537
552
|
className: o,
|
|
538
553
|
style: a,
|
|
539
554
|
children: r ?? "Add to cart"
|
|
540
555
|
}
|
|
541
556
|
);
|
|
542
557
|
}
|
|
543
|
-
function
|
|
558
|
+
function ct({
|
|
544
559
|
placement: t = "docked",
|
|
545
560
|
className: e,
|
|
546
561
|
style: n
|
|
547
562
|
}) {
|
|
548
563
|
const r = q("Editor.Controls");
|
|
549
|
-
|
|
550
|
-
const o =
|
|
564
|
+
Ee("Editor.Controls");
|
|
565
|
+
const o = Z();
|
|
551
566
|
W(
|
|
552
567
|
() => r.registry.registerControls(o, t),
|
|
553
568
|
[r.registry, o, t]
|
|
554
569
|
);
|
|
555
|
-
const a = t === "docked", [c, u] =
|
|
556
|
-
return
|
|
570
|
+
const a = t === "docked", [c, u] = C(null);
|
|
571
|
+
return D(() => {
|
|
557
572
|
if (!a) return;
|
|
558
573
|
let d = !1;
|
|
559
|
-
return import("./ContextualToolbars-
|
|
574
|
+
return import("./ContextualToolbars-BDEt9ND0.js").then((i) => i.s).then(
|
|
560
575
|
(i) => {
|
|
561
576
|
d || u(() => i.ContextualToolbars);
|
|
562
577
|
},
|
|
563
578
|
(i) => {
|
|
564
579
|
d || r.reportRuntimeError(
|
|
565
|
-
new
|
|
580
|
+
new V(
|
|
566
581
|
"E_CHUNK_LOAD_FAILED",
|
|
567
582
|
`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
583
|
{ cause: i instanceof Error ? i.message : String(i), docSlug: "embed-mode" }
|
|
@@ -584,7 +599,7 @@ function at({
|
|
|
584
599
|
}
|
|
585
600
|
) : null;
|
|
586
601
|
}
|
|
587
|
-
function
|
|
602
|
+
function lt() {
|
|
588
603
|
const e = q("useProductSelection").commerce, n = B(e.subscribe, e.getVersion, e.getVersion), r = j((a, c) => e.select(a, c), [e]), o = j((a) => e.setQuantity(a), [e]);
|
|
589
604
|
return O(
|
|
590
605
|
() => ({
|
|
@@ -603,37 +618,37 @@ function ct() {
|
|
|
603
618
|
[e, r, o, n]
|
|
604
619
|
);
|
|
605
620
|
}
|
|
606
|
-
const
|
|
621
|
+
const _ = {
|
|
607
622
|
/** The one provider boundary — session, design, live state, error boundary. */
|
|
608
|
-
Root:
|
|
623
|
+
Root: me,
|
|
609
624
|
/** The editable artboard (the ONE lazy renderer boundary — D9). */
|
|
610
|
-
Canvas:
|
|
625
|
+
Canvas: et,
|
|
611
626
|
/** Live product mockup. ×N under one Root is valid. */
|
|
612
|
-
Preview:
|
|
627
|
+
Preview: pe,
|
|
613
628
|
/** Form input bound to a design text layer by typed token (T1). */
|
|
614
|
-
TextField:
|
|
629
|
+
TextField: ot,
|
|
615
630
|
/** Smart commerce part: completeness + payload assembly; submit = host callback. */
|
|
616
|
-
Buy:
|
|
631
|
+
Buy: at,
|
|
617
632
|
/** Layer list. The one editor part that works canvas-free (ADR-0085 §4). */
|
|
618
|
-
Layers:
|
|
633
|
+
Layers: Re,
|
|
619
634
|
/** Morphing contextual zone — ONE coarse part; placement docked|floating (§5). */
|
|
620
|
-
Controls:
|
|
635
|
+
Controls: ct,
|
|
621
636
|
/** Undo/redo controls. Requires Editor.Canvas. */
|
|
622
|
-
History:
|
|
637
|
+
History: Ie,
|
|
623
638
|
/** The one ⋯ overflow menu. Requires Editor.Canvas. */
|
|
624
639
|
Menu: Se,
|
|
625
640
|
/** The ⊕ add-element menu. Requires Editor.Canvas. */
|
|
626
|
-
Add:
|
|
641
|
+
Add: ke
|
|
627
642
|
};
|
|
628
|
-
function
|
|
629
|
-
return /* @__PURE__ */ s(
|
|
643
|
+
function Ct(t) {
|
|
644
|
+
return /* @__PURE__ */ s(me, { ...t, __validation: "warn" });
|
|
630
645
|
}
|
|
631
|
-
const
|
|
646
|
+
const Ot = ie(
|
|
632
647
|
function(e, n) {
|
|
633
|
-
const { children: r, className: o, style: a, maxHeight: c, ...u } = e, [d, i] =
|
|
634
|
-
return
|
|
648
|
+
const { children: r, className: o, style: a, maxHeight: c, ...u } = e, [d, i] = C(null);
|
|
649
|
+
return D(() => {
|
|
635
650
|
let l = !1;
|
|
636
|
-
return
|
|
651
|
+
return fe().then(
|
|
637
652
|
(m) => {
|
|
638
653
|
l || i(() => m);
|
|
639
654
|
},
|
|
@@ -653,14 +668,14 @@ const Ct = se(
|
|
|
653
668
|
);
|
|
654
669
|
}
|
|
655
670
|
);
|
|
656
|
-
function
|
|
657
|
-
return /* @__PURE__ */ s(
|
|
671
|
+
function Nt(t) {
|
|
672
|
+
return /* @__PURE__ */ s(pe, { ...t });
|
|
658
673
|
}
|
|
659
|
-
function
|
|
674
|
+
function Tt() {
|
|
660
675
|
const { mockups: t, isRendering: e, error: n } = G();
|
|
661
676
|
return { mockups: t, isRendering: e, error: n };
|
|
662
677
|
}
|
|
663
|
-
function
|
|
678
|
+
function dt(t) {
|
|
664
679
|
return new Intl.NumberFormat("en-US", {
|
|
665
680
|
style: "currency",
|
|
666
681
|
currency: "USD",
|
|
@@ -668,7 +683,7 @@ function lt(t) {
|
|
|
668
683
|
maximumFractionDigits: t % 100 === 0 ? 0 : 2
|
|
669
684
|
}).format(t / 100);
|
|
670
685
|
}
|
|
671
|
-
const
|
|
686
|
+
const ut = {
|
|
672
687
|
display: "inline-flex",
|
|
673
688
|
alignItems: "center",
|
|
674
689
|
justifyContent: "center",
|
|
@@ -683,7 +698,7 @@ const dt = {
|
|
|
683
698
|
fontSize: 16,
|
|
684
699
|
lineHeight: 1,
|
|
685
700
|
cursor: "pointer"
|
|
686
|
-
},
|
|
701
|
+
}, mt = {
|
|
687
702
|
display: "flex",
|
|
688
703
|
alignItems: "center",
|
|
689
704
|
gap: 10,
|
|
@@ -699,7 +714,7 @@ const dt = {
|
|
|
699
714
|
textAlign: "left",
|
|
700
715
|
cursor: "pointer"
|
|
701
716
|
};
|
|
702
|
-
function
|
|
717
|
+
function X({
|
|
703
718
|
label: t,
|
|
704
719
|
onSelect: e
|
|
705
720
|
}) {
|
|
@@ -709,13 +724,13 @@ function Y({
|
|
|
709
724
|
type: "button",
|
|
710
725
|
role: "menuitem",
|
|
711
726
|
"data-sc-part": "snowcone-editor-menu-item",
|
|
712
|
-
style:
|
|
727
|
+
style: mt,
|
|
713
728
|
onClick: e,
|
|
714
729
|
children: t
|
|
715
730
|
}
|
|
716
731
|
);
|
|
717
732
|
}
|
|
718
|
-
function
|
|
733
|
+
function ft({
|
|
719
734
|
fullscreen: t,
|
|
720
735
|
onToggleFullscreen: e,
|
|
721
736
|
viewCount: n,
|
|
@@ -723,8 +738,8 @@ function mt({
|
|
|
723
738
|
onSelectView: o,
|
|
724
739
|
onExport: a
|
|
725
740
|
}) {
|
|
726
|
-
const [c, u] =
|
|
727
|
-
return /* @__PURE__ */
|
|
741
|
+
const [c, u] = C(!1), d = () => u(!1);
|
|
742
|
+
return /* @__PURE__ */ R("div", { style: { position: "relative" }, children: [
|
|
728
743
|
/* @__PURE__ */ s(
|
|
729
744
|
"button",
|
|
730
745
|
{
|
|
@@ -733,12 +748,12 @@ function mt({
|
|
|
733
748
|
"aria-haspopup": "menu",
|
|
734
749
|
"aria-expanded": c,
|
|
735
750
|
"data-sc-part": "snowcone-editor-menu",
|
|
736
|
-
style:
|
|
751
|
+
style: ut,
|
|
737
752
|
onClick: () => u((i) => !i),
|
|
738
753
|
children: "⋮"
|
|
739
754
|
}
|
|
740
755
|
),
|
|
741
|
-
c ? /* @__PURE__ */
|
|
756
|
+
c ? /* @__PURE__ */ R(se, { children: [
|
|
742
757
|
/* @__PURE__ */ s(
|
|
743
758
|
"div",
|
|
744
759
|
{
|
|
@@ -747,7 +762,7 @@ function mt({
|
|
|
747
762
|
"aria-hidden": "true"
|
|
748
763
|
}
|
|
749
764
|
),
|
|
750
|
-
/* @__PURE__ */
|
|
765
|
+
/* @__PURE__ */ R(
|
|
751
766
|
"div",
|
|
752
767
|
{
|
|
753
768
|
role: "menu",
|
|
@@ -767,7 +782,7 @@ function mt({
|
|
|
767
782
|
},
|
|
768
783
|
children: [
|
|
769
784
|
/* @__PURE__ */ s(
|
|
770
|
-
|
|
785
|
+
X,
|
|
771
786
|
{
|
|
772
787
|
label: t ? "Exit fullscreen" : "Fullscreen",
|
|
773
788
|
onSelect: () => {
|
|
@@ -776,7 +791,7 @@ function mt({
|
|
|
776
791
|
}
|
|
777
792
|
),
|
|
778
793
|
n > 1 ? Array.from({ length: n }, (i, l) => /* @__PURE__ */ s(
|
|
779
|
-
|
|
794
|
+
X,
|
|
780
795
|
{
|
|
781
796
|
label: `View ${l + 1}${l === r ? " ✓" : ""}`,
|
|
782
797
|
onSelect: () => {
|
|
@@ -786,7 +801,7 @@ function mt({
|
|
|
786
801
|
l
|
|
787
802
|
)) : null,
|
|
788
803
|
/* @__PURE__ */ s(
|
|
789
|
-
|
|
804
|
+
X,
|
|
790
805
|
{
|
|
791
806
|
label: "Export PNG",
|
|
792
807
|
onSelect: () => {
|
|
@@ -800,17 +815,17 @@ function mt({
|
|
|
800
815
|
] }) : null
|
|
801
816
|
] });
|
|
802
817
|
}
|
|
803
|
-
function
|
|
804
|
-
const { flatLayers: t, selectLayer: e, generateAllPreviews: n } =
|
|
805
|
-
return
|
|
818
|
+
function pt() {
|
|
819
|
+
const { flatLayers: t, selectLayer: e, generateAllPreviews: n } = Ce({ previewSize: 96 });
|
|
820
|
+
return D(() => {
|
|
806
821
|
t.length > 0 && n();
|
|
807
|
-
}, [t.length, n]), /* @__PURE__ */
|
|
822
|
+
}, [t.length, n]), /* @__PURE__ */ R(
|
|
808
823
|
"div",
|
|
809
824
|
{
|
|
810
825
|
"data-sc-part": "snowcone-editor-idle-dock",
|
|
811
826
|
style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 8, minHeight: 44 },
|
|
812
827
|
children: [
|
|
813
|
-
/* @__PURE__ */ s(
|
|
828
|
+
/* @__PURE__ */ s(_.Add, {}),
|
|
814
829
|
t.length > 0 ? /* @__PURE__ */ s("div", { style: { width: 1, height: 28, background: "rgba(0,0,0,0.1)", flexShrink: 0 }, "aria-hidden": "true" }) : null,
|
|
815
830
|
t.map((r) => /* @__PURE__ */ s(
|
|
816
831
|
"button",
|
|
@@ -857,13 +872,13 @@ function ft() {
|
|
|
857
872
|
}
|
|
858
873
|
);
|
|
859
874
|
}
|
|
860
|
-
function
|
|
875
|
+
function gt({
|
|
861
876
|
onAddToCart: t,
|
|
862
877
|
defaultQuantity: e
|
|
863
878
|
}) {
|
|
864
|
-
const { price: n, complete: r } =
|
|
865
|
-
return /* @__PURE__ */
|
|
866
|
-
|
|
879
|
+
const { price: n, complete: r } = lt();
|
|
880
|
+
return /* @__PURE__ */ R(
|
|
881
|
+
_.Buy,
|
|
867
882
|
{
|
|
868
883
|
onAddToCart: t,
|
|
869
884
|
...typeof e == "number" ? { defaultQuantity: e } : {},
|
|
@@ -886,12 +901,12 @@ function pt({
|
|
|
886
901
|
},
|
|
887
902
|
children: [
|
|
888
903
|
"Add to cart",
|
|
889
|
-
typeof n == "number" ? ` · ${
|
|
904
|
+
typeof n == "number" ? ` · ${dt(n)}` : ""
|
|
890
905
|
]
|
|
891
906
|
}
|
|
892
907
|
);
|
|
893
908
|
}
|
|
894
|
-
function
|
|
909
|
+
function ht({
|
|
895
910
|
title: t,
|
|
896
911
|
height: e,
|
|
897
912
|
mockupIds: n,
|
|
@@ -900,15 +915,15 @@ function gt({
|
|
|
900
915
|
className: a,
|
|
901
916
|
style: c
|
|
902
917
|
}) {
|
|
903
|
-
const [u, d] =
|
|
904
|
-
var
|
|
905
|
-
const
|
|
906
|
-
if (!
|
|
907
|
-
const [
|
|
918
|
+
const [u, d] = C(!1), [i, l] = C(0), [m, f] = C(!1), w = N(null), g = ze(), v = n[Math.min(i, n.length - 1)], E = j(async () => {
|
|
919
|
+
var A;
|
|
920
|
+
const k = await ((A = w.current) == null ? void 0 : A.exportArtboards({ format: "dataUrl" }));
|
|
921
|
+
if (!k) return;
|
|
922
|
+
const [L, x] = Object.entries(k)[0] ?? [];
|
|
908
923
|
if (typeof x != "string") return;
|
|
909
|
-
const
|
|
910
|
-
|
|
911
|
-
}, []),
|
|
924
|
+
const S = document.createElement("a");
|
|
925
|
+
S.href = x, S.download = `${L ?? "design"}.png`, S.click();
|
|
926
|
+
}, []), T = {
|
|
912
927
|
display: "flex",
|
|
913
928
|
flexDirection: "column",
|
|
914
929
|
overflow: "hidden",
|
|
@@ -929,7 +944,7 @@ function gt({
|
|
|
929
944
|
boxShadow: "0 1px 3px rgba(0,0,0,0.08)"
|
|
930
945
|
},
|
|
931
946
|
...c
|
|
932
|
-
},
|
|
947
|
+
}, h = {
|
|
933
948
|
position: "absolute",
|
|
934
949
|
top: 8,
|
|
935
950
|
right: 12,
|
|
@@ -944,15 +959,15 @@ function gt({
|
|
|
944
959
|
cursor: "pointer",
|
|
945
960
|
zIndex: 2
|
|
946
961
|
};
|
|
947
|
-
return /* @__PURE__ */
|
|
962
|
+
return /* @__PURE__ */ R(
|
|
948
963
|
"div",
|
|
949
964
|
{
|
|
950
965
|
"data-sc-part": "snowcone-editor",
|
|
951
966
|
"data-sc-fullscreen": u ? "true" : void 0,
|
|
952
967
|
className: a,
|
|
953
|
-
style:
|
|
968
|
+
style: T,
|
|
954
969
|
children: [
|
|
955
|
-
/* @__PURE__ */
|
|
970
|
+
/* @__PURE__ */ R(
|
|
956
971
|
"div",
|
|
957
972
|
{
|
|
958
973
|
"data-sc-part": "snowcone-editor-header",
|
|
@@ -965,34 +980,34 @@ function gt({
|
|
|
965
980
|
},
|
|
966
981
|
children: [
|
|
967
982
|
/* @__PURE__ */ s("span", { style: { fontSize: 14, fontWeight: 700, marginRight: "auto" }, children: t }),
|
|
968
|
-
/* @__PURE__ */ s(
|
|
983
|
+
/* @__PURE__ */ s(_.History, {}),
|
|
969
984
|
/* @__PURE__ */ s(
|
|
970
|
-
|
|
985
|
+
ft,
|
|
971
986
|
{
|
|
972
987
|
fullscreen: u,
|
|
973
|
-
onToggleFullscreen: () => d((
|
|
988
|
+
onToggleFullscreen: () => d((k) => !k),
|
|
974
989
|
viewCount: n.length,
|
|
975
990
|
viewIndex: i,
|
|
976
991
|
onSelectView: l,
|
|
977
992
|
onExport: () => void E()
|
|
978
993
|
}
|
|
979
994
|
),
|
|
980
|
-
/* @__PURE__ */ s(
|
|
995
|
+
/* @__PURE__ */ s(gt, { onAddToCart: r, defaultQuantity: o })
|
|
981
996
|
]
|
|
982
997
|
}
|
|
983
998
|
),
|
|
984
|
-
/* @__PURE__ */
|
|
999
|
+
/* @__PURE__ */ R(
|
|
985
1000
|
"div",
|
|
986
1001
|
{
|
|
987
1002
|
"data-sc-part": "snowcone-editor-stage",
|
|
988
1003
|
style: { position: "relative", flex: 1, minHeight: 0, padding: "4px 12px" },
|
|
989
1004
|
children: [
|
|
990
|
-
/* @__PURE__ */ s(
|
|
1005
|
+
/* @__PURE__ */ s(_.Canvas, { ref: w, style: { height: "100%" } }),
|
|
991
1006
|
m ? (
|
|
992
1007
|
// Swapped: the mockup IS the stage; the corner chip returns to the
|
|
993
1008
|
// artwork. The canvas stays mounted underneath (no document
|
|
994
1009
|
// teardown), just covered.
|
|
995
|
-
/* @__PURE__ */
|
|
1010
|
+
/* @__PURE__ */ R(
|
|
996
1011
|
"div",
|
|
997
1012
|
{
|
|
998
1013
|
"data-sc-part": "snowcone-editor-swap-stage",
|
|
@@ -1008,9 +1023,9 @@ function gt({
|
|
|
1008
1023
|
},
|
|
1009
1024
|
children: [
|
|
1010
1025
|
/* @__PURE__ */ s(
|
|
1011
|
-
|
|
1026
|
+
_.Preview,
|
|
1012
1027
|
{
|
|
1013
|
-
mockupId:
|
|
1028
|
+
mockupId: v,
|
|
1014
1029
|
alt: "Product mockup",
|
|
1015
1030
|
fallback: /* @__PURE__ */ s("div", { "aria-busy": "true", children: "Rendering…" }),
|
|
1016
1031
|
style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain", borderRadius: 12 }
|
|
@@ -1024,7 +1039,7 @@ function gt({
|
|
|
1024
1039
|
"data-sc-part": "snowcone-editor-swap-back",
|
|
1025
1040
|
onClick: () => f(!1),
|
|
1026
1041
|
style: {
|
|
1027
|
-
...
|
|
1042
|
+
...h,
|
|
1028
1043
|
display: "flex",
|
|
1029
1044
|
alignItems: "center",
|
|
1030
1045
|
justifyContent: "center",
|
|
@@ -1046,11 +1061,11 @@ function gt({
|
|
|
1046
1061
|
"aria-label": "Show product mockup",
|
|
1047
1062
|
"data-sc-part": "snowcone-editor-pip",
|
|
1048
1063
|
onClick: () => f(!0),
|
|
1049
|
-
style:
|
|
1064
|
+
style: h,
|
|
1050
1065
|
children: /* @__PURE__ */ s(
|
|
1051
|
-
|
|
1066
|
+
_.Preview,
|
|
1052
1067
|
{
|
|
1053
|
-
mockupId:
|
|
1068
|
+
mockupId: v,
|
|
1054
1069
|
alt: "Product mockup preview",
|
|
1055
1070
|
fallback: /* @__PURE__ */ s("span", { style: { fontSize: 10, opacity: 0.5 }, "aria-busy": "true", children: "mockup…" }),
|
|
1056
1071
|
style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
|
|
@@ -1061,15 +1076,15 @@ function gt({
|
|
|
1061
1076
|
]
|
|
1062
1077
|
}
|
|
1063
1078
|
),
|
|
1064
|
-
/* @__PURE__ */
|
|
1079
|
+
/* @__PURE__ */ R(
|
|
1065
1080
|
"div",
|
|
1066
1081
|
{
|
|
1067
1082
|
"data-sc-part": "snowcone-editor-zone",
|
|
1068
|
-
"data-sc-zone-state":
|
|
1083
|
+
"data-sc-zone-state": g ? "selected" : "idle",
|
|
1069
1084
|
style: { flexShrink: 0, padding: "4px 16px 14px" },
|
|
1070
1085
|
children: [
|
|
1071
|
-
/* @__PURE__ */ s("div", { style: { display:
|
|
1072
|
-
|
|
1086
|
+
/* @__PURE__ */ s("div", { style: { display: g ? void 0 : "none" }, children: /* @__PURE__ */ s(_.Controls, { placement: "docked" }) }),
|
|
1087
|
+
g ? null : /* @__PURE__ */ s(pt, {})
|
|
1073
1088
|
]
|
|
1074
1089
|
}
|
|
1075
1090
|
)
|
|
@@ -1077,7 +1092,7 @@ function gt({
|
|
|
1077
1092
|
}
|
|
1078
1093
|
);
|
|
1079
1094
|
}
|
|
1080
|
-
function
|
|
1095
|
+
function $t(t) {
|
|
1081
1096
|
const {
|
|
1082
1097
|
onAddToCart: e,
|
|
1083
1098
|
defaultQuantity: n,
|
|
@@ -1087,8 +1102,8 @@ function Tt(t) {
|
|
|
1087
1102
|
style: c,
|
|
1088
1103
|
...u
|
|
1089
1104
|
} = t;
|
|
1090
|
-
return /* @__PURE__ */ s(
|
|
1091
|
-
|
|
1105
|
+
return /* @__PURE__ */ s(_.Root, { ...u, children: /* @__PURE__ */ s(
|
|
1106
|
+
ht,
|
|
1092
1107
|
{
|
|
1093
1108
|
title: r,
|
|
1094
1109
|
height: o,
|
|
@@ -1100,18 +1115,18 @@ function Tt(t) {
|
|
|
1100
1115
|
}
|
|
1101
1116
|
) });
|
|
1102
1117
|
}
|
|
1103
|
-
|
|
1118
|
+
Oe();
|
|
1104
1119
|
export {
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1120
|
+
_ as E,
|
|
1121
|
+
Ot as R,
|
|
1122
|
+
$t as S,
|
|
1123
|
+
Ct as a,
|
|
1124
|
+
Nt as b,
|
|
1125
|
+
le as c,
|
|
1126
|
+
lt as d,
|
|
1127
|
+
Tt as e,
|
|
1128
|
+
dt as f,
|
|
1114
1129
|
G as u,
|
|
1115
|
-
|
|
1130
|
+
We as v
|
|
1116
1131
|
};
|
|
1117
|
-
//# sourceMappingURL=embed-
|
|
1132
|
+
//# sourceMappingURL=embed-QBZkgWDr.js.map
|