@snowcone-app/ui 0.2.6 → 0.3.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/CHANGELOG.md +16 -0
- package/dist/index.cjs +905 -580
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +882 -552
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/LoadingOverlayPrismCandy.tsx +476 -0
- package/src/index.ts +5 -0
package/dist/index.cjs
CHANGED
|
@@ -235,6 +235,8 @@ __export(src_exports, {
|
|
|
235
235
|
Link: () => Link,
|
|
236
236
|
LinkIcon: () => LinkIcon,
|
|
237
237
|
LoadingOverlayPrism: () => LoadingOverlayPrism,
|
|
238
|
+
LoadingOverlayPrismCandy: () => LoadingOverlayPrismCandy,
|
|
239
|
+
LoadingOverlayPrismCandyInline: () => LoadingOverlayPrismCandyInline,
|
|
238
240
|
MasonryGrid: () => MasonryGrid,
|
|
239
241
|
MobileProductCarousel: () => MobileProductCarousel,
|
|
240
242
|
MockupPriorityProvider: () => MockupPriorityProvider,
|
|
@@ -376,7 +378,7 @@ __export(src_exports, {
|
|
|
376
378
|
useProductSelection: () => useProductSelection,
|
|
377
379
|
useProviderStatus: () => useProviderStatus,
|
|
378
380
|
useRealtime: () => useRealtime,
|
|
379
|
-
useRealtimeMockup: () =>
|
|
381
|
+
useRealtimeMockup: () => import_react69.useRealtimeMockup,
|
|
380
382
|
useRealtimeOptional: () => useRealtimeOptional,
|
|
381
383
|
useRenderCount: () => useRenderCount,
|
|
382
384
|
useRenderGuard: () => useRenderGuard,
|
|
@@ -9014,12 +9016,333 @@ function useLoadingOverlay(isLoading) {
|
|
|
9014
9016
|
};
|
|
9015
9017
|
}
|
|
9016
9018
|
|
|
9019
|
+
// src/components/LoadingOverlayPrismCandy.tsx
|
|
9020
|
+
var import_react40 = require("react");
|
|
9021
|
+
var import_react_dom2 = require("react-dom");
|
|
9022
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
9023
|
+
var BANDS = [
|
|
9024
|
+
{ rgb: "230, 45, 55", delay: "-0.0s" },
|
|
9025
|
+
// red
|
|
9026
|
+
{ rgb: "250, 125, 30", delay: "-0.3s" },
|
|
9027
|
+
// orange
|
|
9028
|
+
{ rgb: "244, 215, 60", delay: "-0.6s" },
|
|
9029
|
+
// yellow
|
|
9030
|
+
{ rgb: "110, 200, 70", delay: "-0.9s" },
|
|
9031
|
+
// green
|
|
9032
|
+
{ rgb: "65, 145, 205", delay: "-1.2s" },
|
|
9033
|
+
// blue
|
|
9034
|
+
{ rgb: "140, 90, 175", delay: "-1.5s" }
|
|
9035
|
+
// purple
|
|
9036
|
+
];
|
|
9037
|
+
function generateParticles2() {
|
|
9038
|
+
return Array.from({ length: 10 }, () => ({
|
|
9039
|
+
left: 2 + Math.random() * 96,
|
|
9040
|
+
top: 2 + Math.random() * 96,
|
|
9041
|
+
delay: (Math.random() * 3.5).toFixed(1),
|
|
9042
|
+
duration: (3 + Math.random() * 2).toFixed(1),
|
|
9043
|
+
size: 3 + Math.random() * 5
|
|
9044
|
+
}));
|
|
9045
|
+
}
|
|
9046
|
+
var PLATE_ALPHA = 0.1;
|
|
9047
|
+
var BAND_ALPHA = 0.55;
|
|
9048
|
+
var FADE_IN_MS2 = 600;
|
|
9049
|
+
var FADE_OUT_MS2 = 400;
|
|
9050
|
+
var STYLES2 = `
|
|
9051
|
+
/* Registered custom properties \u2014 required for the browser to interpolate
|
|
9052
|
+
them across a CSS transition / animation. Without @property, value
|
|
9053
|
+
changes snap rather than animate. */
|
|
9054
|
+
@property --candy-mount {
|
|
9055
|
+
syntax: "<number>";
|
|
9056
|
+
initial-value: 0;
|
|
9057
|
+
inherits: true;
|
|
9058
|
+
}
|
|
9059
|
+
/* Per-band sweep-fade. Animated by the keyframes below to scale the band
|
|
9060
|
+
rgba alpha 0 \u2192 1 \u2192 1 \u2192 0 across a sweep cycle. Lives on .candy-band
|
|
9061
|
+
only (not inherited), so each band has its own animated value. */
|
|
9062
|
+
@property --band-alpha {
|
|
9063
|
+
syntax: "<number>";
|
|
9064
|
+
initial-value: 0;
|
|
9065
|
+
inherits: false;
|
|
9066
|
+
}
|
|
9067
|
+
|
|
9068
|
+
.candy-loading-overlay {
|
|
9069
|
+
--candy-mount: 0;
|
|
9070
|
+
overflow: hidden;
|
|
9071
|
+
background-color: rgba(255, 255, 255, calc(${PLATE_ALPHA} * var(--candy-mount)));
|
|
9072
|
+
transition: --candy-mount ${FADE_IN_MS2}ms ease-in,
|
|
9073
|
+
background-color ${FADE_IN_MS2}ms ease-in;
|
|
9074
|
+
}
|
|
9075
|
+
.candy-loading-overlay.candy-fade-in { --candy-mount: 1; }
|
|
9076
|
+
.candy-loading-overlay.candy-fade-out {
|
|
9077
|
+
--candy-mount: 0;
|
|
9078
|
+
transition: --candy-mount ${FADE_OUT_MS2}ms ease-out,
|
|
9079
|
+
background-color ${FADE_OUT_MS2}ms ease-out;
|
|
9080
|
+
}
|
|
9081
|
+
|
|
9082
|
+
.candy-band {
|
|
9083
|
+
--band-alpha: 0;
|
|
9084
|
+
position: absolute;
|
|
9085
|
+
width: 220%; height: 30%;
|
|
9086
|
+
left: -60%;
|
|
9087
|
+
mix-blend-mode: screen;
|
|
9088
|
+
-webkit-mask-image: linear-gradient(180deg, transparent 0%, black 35%, black 65%, transparent 100%);
|
|
9089
|
+
mask-image: linear-gradient(180deg, transparent 0%, black 35%, black 65%, transparent 100%);
|
|
9090
|
+
animation-timing-function: ease-in-out;
|
|
9091
|
+
animation-iteration-count: infinite;
|
|
9092
|
+
animation-duration: 6s;
|
|
9093
|
+
}
|
|
9094
|
+
${BANDS.map((b, i) => {
|
|
9095
|
+
const top = -5 + i * 16;
|
|
9096
|
+
const direction = i % 2 === 0 ? "ltr" : "rtl";
|
|
9097
|
+
return `.candy-band:nth-child(${i + 1}) { top: ${top}%; background: linear-gradient(90deg, transparent 0%, rgba(${b.rgb}, calc(${BAND_ALPHA} * var(--candy-mount) * var(--band-alpha) * var(--band-strength, 1))) 30%, rgba(${b.rgb}, calc(${BAND_ALPHA} * var(--candy-mount) * var(--band-alpha) * var(--band-strength, 1))) 70%, transparent 100%); animation-name: candy-sweep-${direction}; animation-delay: ${b.delay}; }`;
|
|
9098
|
+
}).join("\n")}
|
|
9099
|
+
@keyframes candy-sweep-ltr {
|
|
9100
|
+
0% { transform: translateX(-45%) rotate(-6deg); --band-alpha: 0; }
|
|
9101
|
+
25% { --band-alpha: 1; }
|
|
9102
|
+
50% { transform: translateX(0%) rotate(-6deg); }
|
|
9103
|
+
75% { --band-alpha: 1; }
|
|
9104
|
+
100% { transform: translateX(45%) rotate(-6deg); --band-alpha: 0; }
|
|
9105
|
+
}
|
|
9106
|
+
@keyframes candy-sweep-rtl {
|
|
9107
|
+
0% { transform: translateX(45%) rotate(-6deg); --band-alpha: 0; }
|
|
9108
|
+
25% { --band-alpha: 1; }
|
|
9109
|
+
50% { transform: translateX(0%) rotate(-6deg); }
|
|
9110
|
+
75% { --band-alpha: 1; }
|
|
9111
|
+
100% { transform: translateX(-45%) rotate(-6deg); --band-alpha: 0; }
|
|
9112
|
+
}
|
|
9113
|
+
|
|
9114
|
+
.candy-particle {
|
|
9115
|
+
position: absolute; border-radius: 50%;
|
|
9116
|
+
/* Particle background and glow alphas also scale with --candy-mount so
|
|
9117
|
+
the sparkles fade with the rest of the overlay. */
|
|
9118
|
+
background: rgba(255, 255, 255, calc(1 * var(--candy-mount)));
|
|
9119
|
+
box-shadow: 0 0 8px rgba(255, 255, 255, calc(0.85 * var(--candy-mount)));
|
|
9120
|
+
opacity: 0;
|
|
9121
|
+
animation: candy-sparkle infinite ease-in-out;
|
|
9122
|
+
}
|
|
9123
|
+
@keyframes candy-sparkle {
|
|
9124
|
+
0% { opacity: 0; transform: scale(0); }
|
|
9125
|
+
15% { opacity: 0.7; transform: scale(1.4); }
|
|
9126
|
+
30% { opacity: 0.4; transform: scale(0.6); }
|
|
9127
|
+
55% { opacity: 1; transform: scale(2); }
|
|
9128
|
+
75% { opacity: 0.5; transform: scale(0.9); }
|
|
9129
|
+
100% { opacity: 0; transform: scale(0); }
|
|
9130
|
+
}
|
|
9131
|
+
|
|
9132
|
+
/* Light-backdrop variant. The default bands screen-blend \u2014 vivid on a dark
|
|
9133
|
+
stage, but they wash out to nothing over white (screen over white = white).
|
|
9134
|
+
On a light card we multiply-blend instead, so each band tints the backdrop
|
|
9135
|
+
toward its hue (jewel/pastel rainbow rather than neon). The sparkle particles
|
|
9136
|
+
stay white in both variants \u2014 they read as snow, and the white glow keeps
|
|
9137
|
+
them legible over the multiply rainbow bands. */
|
|
9138
|
+
.candy-on-light .candy-band { mix-blend-mode: multiply; }
|
|
9139
|
+
/* Opaque light stage baked into the overlay so it fades in/out as one unit
|
|
9140
|
+
with the bands \u2014 matching the PDP hero's smooth crossfade \u2014 instead of a
|
|
9141
|
+
hard backdrop on the parent that snaps on/off. The alpha scales with
|
|
9142
|
+
--candy-mount (overriding the default 0.1 white plate), so it rides the
|
|
9143
|
+
same candy-fade-in / candy-fade-out transition the bands do. The bands
|
|
9144
|
+
multiply-blend against this opaque stage to read as the candy rainbow.
|
|
9145
|
+
#f5f5f5 = the site page background (defaults.css --color-background), kept
|
|
9146
|
+
as a fixed hex (not the token, which would flip dark in dark mode and break
|
|
9147
|
+
the multiply blend) so the loader sits flush with the surrounding page. */
|
|
9148
|
+
.candy-on-light {
|
|
9149
|
+
background-color: rgba(245, 245, 245, calc(1 * var(--candy-mount)));
|
|
9150
|
+
/* Half the band opacity on the light stage \u2014 multiply-blended bands read
|
|
9151
|
+
stronger on light gray than the screen-blended ones do on the dark PDP
|
|
9152
|
+
stage, so dial them back to ~50%. Inherits down to .candy-band; the dark
|
|
9153
|
+
default leaves --band-strength at its 1 fallback, untouched. */
|
|
9154
|
+
--band-strength: 0.5;
|
|
9155
|
+
}
|
|
9156
|
+
|
|
9157
|
+
`;
|
|
9158
|
+
var stylesInjected2 = false;
|
|
9159
|
+
function ensureStyles2() {
|
|
9160
|
+
if (stylesInjected2 || typeof document === "undefined") return;
|
|
9161
|
+
if (typeof CSS !== "undefined" && typeof CSS.registerProperty === "function") {
|
|
9162
|
+
try {
|
|
9163
|
+
CSS.registerProperty({
|
|
9164
|
+
name: "--candy-mount",
|
|
9165
|
+
syntax: "<number>",
|
|
9166
|
+
initialValue: "0",
|
|
9167
|
+
inherits: true
|
|
9168
|
+
});
|
|
9169
|
+
} catch {
|
|
9170
|
+
}
|
|
9171
|
+
try {
|
|
9172
|
+
CSS.registerProperty({
|
|
9173
|
+
name: "--band-alpha",
|
|
9174
|
+
syntax: "<number>",
|
|
9175
|
+
initialValue: "0",
|
|
9176
|
+
inherits: false
|
|
9177
|
+
});
|
|
9178
|
+
} catch {
|
|
9179
|
+
}
|
|
9180
|
+
}
|
|
9181
|
+
const s = document.createElement("style");
|
|
9182
|
+
s.textContent = STYLES2;
|
|
9183
|
+
document.head.appendChild(s);
|
|
9184
|
+
stylesInjected2 = true;
|
|
9185
|
+
}
|
|
9186
|
+
function CandyVisual({
|
|
9187
|
+
fadeClass,
|
|
9188
|
+
style,
|
|
9189
|
+
onTransitionEnd,
|
|
9190
|
+
variantClass = ""
|
|
9191
|
+
}) {
|
|
9192
|
+
const [particles, setParticles] = (0, import_react40.useState)([]);
|
|
9193
|
+
(0, import_react40.useEffect)(() => {
|
|
9194
|
+
setParticles(generateParticles2());
|
|
9195
|
+
}, []);
|
|
9196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
9197
|
+
"div",
|
|
9198
|
+
{
|
|
9199
|
+
className: `candy-loading-overlay ${variantClass} ${fadeClass}`.trim(),
|
|
9200
|
+
style,
|
|
9201
|
+
onTransitionEnd,
|
|
9202
|
+
children: [
|
|
9203
|
+
BANDS.map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "candy-band" }, `b-${i}`)),
|
|
9204
|
+
particles.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
9205
|
+
"div",
|
|
9206
|
+
{
|
|
9207
|
+
className: "candy-particle",
|
|
9208
|
+
style: {
|
|
9209
|
+
left: `${p.left}%`,
|
|
9210
|
+
top: `${p.top}%`,
|
|
9211
|
+
animationDelay: `${p.delay}s`,
|
|
9212
|
+
animationDuration: `${p.duration}s`,
|
|
9213
|
+
width: `${p.size}px`,
|
|
9214
|
+
height: `${p.size}px`
|
|
9215
|
+
}
|
|
9216
|
+
},
|
|
9217
|
+
`p-${i}`
|
|
9218
|
+
))
|
|
9219
|
+
]
|
|
9220
|
+
}
|
|
9221
|
+
);
|
|
9222
|
+
}
|
|
9223
|
+
var LoadingOverlayPrismCandy = (0, import_react40.memo)(function LoadingOverlayPrismCandy2({
|
|
9224
|
+
visible = true,
|
|
9225
|
+
onExited
|
|
9226
|
+
}) {
|
|
9227
|
+
ensureStyles2();
|
|
9228
|
+
const anchorRef = (0, import_react40.useRef)(null);
|
|
9229
|
+
const [bounds, setBounds] = (0, import_react40.useState)(null);
|
|
9230
|
+
const [mounted, setMounted] = (0, import_react40.useState)(false);
|
|
9231
|
+
const measure = (0, import_react40.useCallback)(() => {
|
|
9232
|
+
const el = anchorRef.current;
|
|
9233
|
+
if (!el) return;
|
|
9234
|
+
const r = el.getBoundingClientRect();
|
|
9235
|
+
setBounds({
|
|
9236
|
+
top: r.top + window.scrollY,
|
|
9237
|
+
left: r.left + window.scrollX,
|
|
9238
|
+
width: r.width,
|
|
9239
|
+
height: r.height
|
|
9240
|
+
});
|
|
9241
|
+
}, []);
|
|
9242
|
+
(0, import_react40.useLayoutEffect)(() => {
|
|
9243
|
+
measure();
|
|
9244
|
+
window.addEventListener("resize", measure);
|
|
9245
|
+
let ro = null;
|
|
9246
|
+
if (typeof ResizeObserver !== "undefined" && anchorRef.current) {
|
|
9247
|
+
ro = new ResizeObserver(measure);
|
|
9248
|
+
ro.observe(anchorRef.current);
|
|
9249
|
+
}
|
|
9250
|
+
return () => {
|
|
9251
|
+
window.removeEventListener("resize", measure);
|
|
9252
|
+
ro?.disconnect();
|
|
9253
|
+
};
|
|
9254
|
+
}, [measure]);
|
|
9255
|
+
(0, import_react40.useEffect)(() => {
|
|
9256
|
+
const raf = requestAnimationFrame(() => setMounted(true));
|
|
9257
|
+
return () => cancelAnimationFrame(raf);
|
|
9258
|
+
}, []);
|
|
9259
|
+
const handleTransitionEnd = (0, import_react40.useCallback)(
|
|
9260
|
+
(e) => {
|
|
9261
|
+
if (e.propertyName !== "background-color") return;
|
|
9262
|
+
if (!visible) onExited?.();
|
|
9263
|
+
},
|
|
9264
|
+
[visible, onExited]
|
|
9265
|
+
);
|
|
9266
|
+
let fadeClass = "";
|
|
9267
|
+
if (!visible) fadeClass = "candy-fade-out";
|
|
9268
|
+
else if (mounted) fadeClass = "candy-fade-in";
|
|
9269
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
|
|
9270
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
9271
|
+
"div",
|
|
9272
|
+
{
|
|
9273
|
+
ref: anchorRef,
|
|
9274
|
+
style: {
|
|
9275
|
+
position: "absolute",
|
|
9276
|
+
inset: 0,
|
|
9277
|
+
pointerEvents: "none"
|
|
9278
|
+
},
|
|
9279
|
+
"aria-hidden": "true"
|
|
9280
|
+
}
|
|
9281
|
+
),
|
|
9282
|
+
bounds && typeof document !== "undefined" && (0, import_react_dom2.createPortal)(
|
|
9283
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
9284
|
+
CandyVisual,
|
|
9285
|
+
{
|
|
9286
|
+
fadeClass,
|
|
9287
|
+
style: {
|
|
9288
|
+
position: "absolute",
|
|
9289
|
+
top: bounds.top,
|
|
9290
|
+
left: bounds.left,
|
|
9291
|
+
width: bounds.width,
|
|
9292
|
+
height: bounds.height,
|
|
9293
|
+
pointerEvents: "none"
|
|
9294
|
+
},
|
|
9295
|
+
onTransitionEnd: handleTransitionEnd
|
|
9296
|
+
}
|
|
9297
|
+
),
|
|
9298
|
+
document.body
|
|
9299
|
+
)
|
|
9300
|
+
] });
|
|
9301
|
+
});
|
|
9302
|
+
var LoadingOverlayPrismCandyInline = (0, import_react40.memo)(
|
|
9303
|
+
function LoadingOverlayPrismCandyInline2({
|
|
9304
|
+
visible = true,
|
|
9305
|
+
onExited,
|
|
9306
|
+
variant = "dark"
|
|
9307
|
+
}) {
|
|
9308
|
+
ensureStyles2();
|
|
9309
|
+
const [mounted, setMounted] = (0, import_react40.useState)(false);
|
|
9310
|
+
(0, import_react40.useEffect)(() => {
|
|
9311
|
+
const raf = requestAnimationFrame(() => setMounted(true));
|
|
9312
|
+
return () => cancelAnimationFrame(raf);
|
|
9313
|
+
}, []);
|
|
9314
|
+
const handleTransitionEnd = (0, import_react40.useCallback)(
|
|
9315
|
+
(e) => {
|
|
9316
|
+
if (e.propertyName !== "background-color") return;
|
|
9317
|
+
if (!visible) onExited?.();
|
|
9318
|
+
},
|
|
9319
|
+
[visible, onExited]
|
|
9320
|
+
);
|
|
9321
|
+
let fadeClass = "";
|
|
9322
|
+
if (!visible) fadeClass = "candy-fade-out";
|
|
9323
|
+
else if (mounted) fadeClass = "candy-fade-in";
|
|
9324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
9325
|
+
CandyVisual,
|
|
9326
|
+
{
|
|
9327
|
+
fadeClass,
|
|
9328
|
+
variantClass: variant === "light" ? "candy-on-light" : "",
|
|
9329
|
+
style: {
|
|
9330
|
+
position: "absolute",
|
|
9331
|
+
inset: 0,
|
|
9332
|
+
pointerEvents: "none"
|
|
9333
|
+
},
|
|
9334
|
+
onTransitionEnd: handleTransitionEnd
|
|
9335
|
+
}
|
|
9336
|
+
);
|
|
9337
|
+
}
|
|
9338
|
+
);
|
|
9339
|
+
|
|
9017
9340
|
// src/index.ts
|
|
9018
|
-
var
|
|
9341
|
+
var import_react69 = require("@snowcone-app/sdk/react");
|
|
9019
9342
|
var import_sdk11 = require("@snowcone-app/sdk");
|
|
9020
9343
|
|
|
9021
9344
|
// src/patterns/ProductPageProvider.tsx
|
|
9022
|
-
var
|
|
9345
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
9023
9346
|
function ProductPageProvider({
|
|
9024
9347
|
children,
|
|
9025
9348
|
productId,
|
|
@@ -9033,12 +9356,12 @@ function ProductPageProvider({
|
|
|
9033
9356
|
realtimeGrantUrl,
|
|
9034
9357
|
enablePriority = true
|
|
9035
9358
|
}) {
|
|
9036
|
-
let content = /* @__PURE__ */ (0,
|
|
9359
|
+
let content = /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Product, { productId, productData, children });
|
|
9037
9360
|
if (enablePriority) {
|
|
9038
|
-
content = /* @__PURE__ */ (0,
|
|
9361
|
+
content = /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(MockupPriorityProvider, { children: content });
|
|
9039
9362
|
}
|
|
9040
9363
|
if (enableRealtime) {
|
|
9041
|
-
content = /* @__PURE__ */ (0,
|
|
9364
|
+
content = /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9042
9365
|
RealtimeProvider,
|
|
9043
9366
|
{
|
|
9044
9367
|
wsUrl: realtimeWsUrl,
|
|
@@ -9048,7 +9371,7 @@ function ProductPageProvider({
|
|
|
9048
9371
|
}
|
|
9049
9372
|
);
|
|
9050
9373
|
}
|
|
9051
|
-
return /* @__PURE__ */ (0,
|
|
9374
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9052
9375
|
Shop,
|
|
9053
9376
|
{
|
|
9054
9377
|
endpoint,
|
|
@@ -9068,23 +9391,23 @@ function ProductPageProviderMinimal({
|
|
|
9068
9391
|
shop,
|
|
9069
9392
|
initialArtwork
|
|
9070
9393
|
}) {
|
|
9071
|
-
return /* @__PURE__ */ (0,
|
|
9394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9072
9395
|
Shop,
|
|
9073
9396
|
{
|
|
9074
9397
|
endpoint,
|
|
9075
9398
|
mockupUrl,
|
|
9076
9399
|
shop,
|
|
9077
9400
|
initialArtwork,
|
|
9078
|
-
children: /* @__PURE__ */ (0,
|
|
9401
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Product, { productId, productData, children })
|
|
9079
9402
|
}
|
|
9080
9403
|
);
|
|
9081
9404
|
}
|
|
9082
9405
|
|
|
9083
9406
|
// src/composed/ArtAlignment.tsx
|
|
9084
|
-
var
|
|
9085
|
-
var
|
|
9407
|
+
var import_react41 = require("react");
|
|
9408
|
+
var import_react42 = require("@use-gesture/react");
|
|
9086
9409
|
var import_sdk9 = require("@snowcone-app/sdk");
|
|
9087
|
-
var
|
|
9410
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
9088
9411
|
function ArtAlignment({
|
|
9089
9412
|
src: propSrc,
|
|
9090
9413
|
artworkAspectRatio: propAspectRatio,
|
|
@@ -9118,16 +9441,16 @@ function ArtAlignment({
|
|
|
9118
9441
|
selection: {}
|
|
9119
9442
|
};
|
|
9120
9443
|
}
|
|
9121
|
-
const containerRef = (0,
|
|
9122
|
-
const imageRef = (0,
|
|
9123
|
-
const lastUserDragTimeRef = (0,
|
|
9124
|
-
const [containerSize, setContainerSize] = (0,
|
|
9125
|
-
const [position, setPosition] = (0,
|
|
9126
|
-
const [isReady, setIsReady] = (0,
|
|
9127
|
-
const [detectedAspectRatio, setDetectedAspectRatio] = (0,
|
|
9444
|
+
const containerRef = (0, import_react41.useRef)(null);
|
|
9445
|
+
const imageRef = (0, import_react41.useRef)(null);
|
|
9446
|
+
const lastUserDragTimeRef = (0, import_react41.useRef)(0);
|
|
9447
|
+
const [containerSize, setContainerSize] = (0, import_react41.useState)({ width: 0, height: 0 });
|
|
9448
|
+
const [position, setPosition] = (0, import_react41.useState)({ x: 0, y: 0 });
|
|
9449
|
+
const [isReady, setIsReady] = (0, import_react41.useState)(false);
|
|
9450
|
+
const [detectedAspectRatio, setDetectedAspectRatio] = (0, import_react41.useState)();
|
|
9128
9451
|
const effectiveAspectRatio = artworkAspectRatio || detectedAspectRatio;
|
|
9129
9452
|
const alignment = placementDesign?.alignment || propAlignment || "center";
|
|
9130
|
-
const descriptor = (0,
|
|
9453
|
+
const descriptor = (0, import_react41.useMemo)(
|
|
9131
9454
|
() => (0, import_sdk9.describeProductArtAlignment)(
|
|
9132
9455
|
{
|
|
9133
9456
|
src,
|
|
@@ -9149,7 +9472,7 @@ function ArtAlignment({
|
|
|
9149
9472
|
productContext
|
|
9150
9473
|
]
|
|
9151
9474
|
);
|
|
9152
|
-
const containerStyle = (0,
|
|
9475
|
+
const containerStyle = (0, import_react41.useMemo)(() => {
|
|
9153
9476
|
const style = {};
|
|
9154
9477
|
if (height !== void 0) {
|
|
9155
9478
|
const heightValue = typeof height === "number" ? height : parseFloat(height);
|
|
@@ -9180,7 +9503,7 @@ function ArtAlignment({
|
|
|
9180
9503
|
}
|
|
9181
9504
|
return style;
|
|
9182
9505
|
}, [effectiveAspectRatio, height, maxHeight, minHeight]);
|
|
9183
|
-
(0,
|
|
9506
|
+
(0, import_react41.useEffect)(() => {
|
|
9184
9507
|
if (!containerRef.current) return;
|
|
9185
9508
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
9186
9509
|
const entry = entries[0];
|
|
@@ -9206,7 +9529,7 @@ function ArtAlignment({
|
|
|
9206
9529
|
}
|
|
9207
9530
|
}
|
|
9208
9531
|
};
|
|
9209
|
-
(0,
|
|
9532
|
+
(0, import_react41.useEffect)(() => {
|
|
9210
9533
|
if (!imageRef.current || !descriptor) return;
|
|
9211
9534
|
if (imageRef.current.complete) {
|
|
9212
9535
|
setIsReady(true);
|
|
@@ -9231,7 +9554,7 @@ function ArtAlignment({
|
|
|
9231
9554
|
img.removeEventListener("load", handleLoad);
|
|
9232
9555
|
};
|
|
9233
9556
|
}, [descriptor?.src, artworkAspectRatio]);
|
|
9234
|
-
const maskDimensions = (0,
|
|
9557
|
+
const maskDimensions = (0, import_react41.useMemo)(() => {
|
|
9235
9558
|
if (!isReady || containerSize.width === 0 || !descriptor) {
|
|
9236
9559
|
return { width: 0, height: 0 };
|
|
9237
9560
|
}
|
|
@@ -9246,14 +9569,14 @@ function ArtAlignment({
|
|
|
9246
9569
|
descriptor?.effectiveAlignment,
|
|
9247
9570
|
isReady
|
|
9248
9571
|
]);
|
|
9249
|
-
const clipPathCoords = (0,
|
|
9572
|
+
const clipPathCoords = (0, import_react41.useMemo)(() => {
|
|
9250
9573
|
const halfMaskW = maskDimensions.width / 2;
|
|
9251
9574
|
const halfMaskH = maskDimensions.height / 2;
|
|
9252
9575
|
const halfContainerW = containerSize.width / 2;
|
|
9253
9576
|
const halfContainerH = containerSize.height / 2;
|
|
9254
9577
|
return { halfMaskW, halfMaskH, halfContainerW, halfContainerH };
|
|
9255
9578
|
}, [maskDimensions.width, maskDimensions.height, containerSize.width, containerSize.height]);
|
|
9256
|
-
(0,
|
|
9579
|
+
(0, import_react41.useEffect)(() => {
|
|
9257
9580
|
if (Date.now() - lastUserDragTimeRef.current < 500) return;
|
|
9258
9581
|
if (!isReady || maskDimensions.width === 0 || !descriptor) return;
|
|
9259
9582
|
const points = (0, import_sdk9.getSnapPoints)(
|
|
@@ -9275,7 +9598,7 @@ function ArtAlignment({
|
|
|
9275
9598
|
maskDimensions.height,
|
|
9276
9599
|
isReady
|
|
9277
9600
|
]);
|
|
9278
|
-
const overlayStyle = (0,
|
|
9601
|
+
const overlayStyle = (0, import_react41.useMemo)(() => {
|
|
9279
9602
|
const { halfMaskW, halfMaskH, halfContainerW, halfContainerH } = clipPathCoords;
|
|
9280
9603
|
const cx = position.x + halfContainerW;
|
|
9281
9604
|
const cy = position.y + halfContainerH;
|
|
@@ -9296,7 +9619,7 @@ function ArtAlignment({
|
|
|
9296
9619
|
clipPath: isReady ? `polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%, 0% 0%, ${right}px ${bottom}px, ${right}px ${top}px, ${left}px ${top}px, ${left}px ${bottom}px, ${right}px ${bottom}px)` : "none"
|
|
9297
9620
|
};
|
|
9298
9621
|
}, [isReady, position.x, position.y, clipPathCoords]);
|
|
9299
|
-
const maskStyle = (0,
|
|
9622
|
+
const maskStyle = (0, import_react41.useMemo)(() => ({
|
|
9300
9623
|
width: `${maskDimensions.width}px`,
|
|
9301
9624
|
height: `${maskDimensions.height}px`,
|
|
9302
9625
|
boxShadow: `0 0 0 2px var(--color-background), 0 0 0 4px var(--color-primary)`,
|
|
@@ -9311,7 +9634,7 @@ function ArtAlignment({
|
|
|
9311
9634
|
// GPU acceleration for smoother drag
|
|
9312
9635
|
borderRadius: "var(--radius-image, 4px)"
|
|
9313
9636
|
}), [maskDimensions.width, maskDimensions.height]);
|
|
9314
|
-
const clearImageClipPath = (0,
|
|
9637
|
+
const clearImageClipPath = (0, import_react41.useMemo)(() => {
|
|
9315
9638
|
if (!isReady) return "none";
|
|
9316
9639
|
const { halfMaskW, halfMaskH, halfContainerW, halfContainerH } = clipPathCoords;
|
|
9317
9640
|
const cx = position.x + halfContainerW;
|
|
@@ -9322,14 +9645,14 @@ function ArtAlignment({
|
|
|
9322
9645
|
const top = cy - halfMaskH;
|
|
9323
9646
|
return `polygon(${left}px ${top}px, ${right}px ${top}px, ${right}px ${bottom}px, ${left}px ${bottom}px)`;
|
|
9324
9647
|
}, [isReady, position.x, position.y, clipPathCoords]);
|
|
9325
|
-
const maskTransform = (0,
|
|
9648
|
+
const maskTransform = (0, import_react41.useMemo)(() => {
|
|
9326
9649
|
return descriptor?.effectiveAlignment === "horizontal" ? `translate(calc(-50% + ${position.x}px), -50%)` : `translate(-50%, calc(-50% + ${position.y}px))`;
|
|
9327
9650
|
}, [descriptor?.effectiveAlignment, position.x, position.y]);
|
|
9328
|
-
const lastContextUpdateTimeRef = (0,
|
|
9329
|
-
const pendingAlignmentRef = (0,
|
|
9330
|
-
const throttleTimeoutRef = (0,
|
|
9651
|
+
const lastContextUpdateTimeRef = (0, import_react41.useRef)(0);
|
|
9652
|
+
const pendingAlignmentRef = (0, import_react41.useRef)(null);
|
|
9653
|
+
const throttleTimeoutRef = (0, import_react41.useRef)(null);
|
|
9331
9654
|
const THROTTLE_MS = 150;
|
|
9332
|
-
const bind = (0,
|
|
9655
|
+
const bind = (0, import_react42.useDrag)(
|
|
9333
9656
|
({ offset: [ox, oy], last }) => {
|
|
9334
9657
|
if (maskDimensions.width === 0 || maskDimensions.height === 0 || !descriptor) {
|
|
9335
9658
|
return;
|
|
@@ -9422,7 +9745,7 @@ function ArtAlignment({
|
|
|
9422
9745
|
if (!descriptor) {
|
|
9423
9746
|
return null;
|
|
9424
9747
|
}
|
|
9425
|
-
return /* @__PURE__ */ (0,
|
|
9748
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
9426
9749
|
"div",
|
|
9427
9750
|
{
|
|
9428
9751
|
className: `relative ${className || ""}`,
|
|
@@ -9431,8 +9754,8 @@ function ArtAlignment({
|
|
|
9431
9754
|
width: "fit-content",
|
|
9432
9755
|
maxWidth: "100%"
|
|
9433
9756
|
},
|
|
9434
|
-
children: /* @__PURE__ */ (0,
|
|
9435
|
-
/* @__PURE__ */ (0,
|
|
9757
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "overflow-hidden p-1", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { ref: containerRef, className: "relative", style: containerStyle, children: [
|
|
9758
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
9436
9759
|
"img",
|
|
9437
9760
|
{
|
|
9438
9761
|
ref: imageRef,
|
|
@@ -9457,9 +9780,9 @@ function ArtAlignment({
|
|
|
9457
9780
|
loading: "eager"
|
|
9458
9781
|
}
|
|
9459
9782
|
),
|
|
9460
|
-
isReady && maskDimensions.width > 0 && /* @__PURE__ */ (0,
|
|
9461
|
-
/* @__PURE__ */ (0,
|
|
9462
|
-
/* @__PURE__ */ (0,
|
|
9783
|
+
isReady && maskDimensions.width > 0 && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
|
|
9784
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { style: overlayStyle }),
|
|
9785
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
9463
9786
|
"img",
|
|
9464
9787
|
{
|
|
9465
9788
|
src: descriptor.src,
|
|
@@ -9487,7 +9810,7 @@ function ArtAlignment({
|
|
|
9487
9810
|
loading: "eager"
|
|
9488
9811
|
}
|
|
9489
9812
|
),
|
|
9490
|
-
/* @__PURE__ */ (0,
|
|
9813
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
9491
9814
|
"div",
|
|
9492
9815
|
{
|
|
9493
9816
|
...bind(),
|
|
@@ -9504,8 +9827,8 @@ function ArtAlignment({
|
|
|
9504
9827
|
}
|
|
9505
9828
|
|
|
9506
9829
|
// src/composed/ArtworkCustomizer.tsx
|
|
9507
|
-
var
|
|
9508
|
-
var
|
|
9830
|
+
var import_react43 = require("react");
|
|
9831
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
9509
9832
|
function ArtworkCustomizer(props) {
|
|
9510
9833
|
const designContext = useDesign();
|
|
9511
9834
|
const artwork = props.artwork || designContext.selectedArtwork;
|
|
@@ -9517,7 +9840,7 @@ function ArtworkCustomizer(props) {
|
|
|
9517
9840
|
const placements = productCtx?.product?.placements || [];
|
|
9518
9841
|
const selectedPlacement = productCtx?.selectedPlacement;
|
|
9519
9842
|
const setSelectedPlacement = productCtx?.setSelectedPlacement;
|
|
9520
|
-
(0,
|
|
9843
|
+
(0, import_react43.useEffect)(() => {
|
|
9521
9844
|
if (placements.length > 0 && !selectedPlacement && setSelectedPlacement) {
|
|
9522
9845
|
setSelectedPlacement(placements[0].label);
|
|
9523
9846
|
}
|
|
@@ -9527,13 +9850,13 @@ function ArtworkCustomizer(props) {
|
|
|
9527
9850
|
);
|
|
9528
9851
|
const isColorPlacement = currentPlacement?.type === "color";
|
|
9529
9852
|
const isFitMode = currentPlacement?.defaultScaleMode === "fit";
|
|
9530
|
-
(0,
|
|
9853
|
+
(0, import_react43.useEffect)(() => {
|
|
9531
9854
|
}, [selectedPlacement]);
|
|
9532
9855
|
if (!artwork) {
|
|
9533
|
-
return /* @__PURE__ */ (0,
|
|
9856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: `text-sm text-muted-foreground ${props.className || ""}`, children: "Select artwork to customize" });
|
|
9534
9857
|
}
|
|
9535
9858
|
if (artwork.type === "pattern") {
|
|
9536
|
-
return /* @__PURE__ */ (0,
|
|
9859
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
9537
9860
|
TileCount,
|
|
9538
9861
|
{
|
|
9539
9862
|
artwork,
|
|
@@ -9544,8 +9867,8 @@ function ArtworkCustomizer(props) {
|
|
|
9544
9867
|
);
|
|
9545
9868
|
}
|
|
9546
9869
|
const isCanvasEditorMode = props.mode === "canvas" || !!props.children && props.mode !== "alignment";
|
|
9547
|
-
return /* @__PURE__ */ (0,
|
|
9548
|
-
placements.length > 1 && /* @__PURE__ */ (0,
|
|
9870
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "flex flex-col gap-4", children: [
|
|
9871
|
+
placements.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "text-sm leading-relaxed", children: placements.map((p) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
9549
9872
|
"button",
|
|
9550
9873
|
{
|
|
9551
9874
|
onClick: () => setSelectedPlacement?.(p.label),
|
|
@@ -9554,7 +9877,7 @@ function ArtworkCustomizer(props) {
|
|
|
9554
9877
|
},
|
|
9555
9878
|
p.label
|
|
9556
9879
|
)) }),
|
|
9557
|
-
isColorPlacement ? /* @__PURE__ */ (0,
|
|
9880
|
+
isColorPlacement ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ColorPicker2, { placement: selectedPlacement }) : isFitMode ? null : /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "relative", children: props.children || /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
9558
9881
|
ArtAlignment,
|
|
9559
9882
|
{
|
|
9560
9883
|
artwork: { src: artwork.src },
|
|
@@ -9570,7 +9893,7 @@ function ArtworkCustomizer(props) {
|
|
|
9570
9893
|
|
|
9571
9894
|
// src/composed/CanvasEditor.tsx
|
|
9572
9895
|
var import_lucide_react2 = require("lucide-react");
|
|
9573
|
-
var
|
|
9896
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
9574
9897
|
var ImageIcon = import_lucide_react2.Image;
|
|
9575
9898
|
var TypeIcon = import_lucide_react2.Type;
|
|
9576
9899
|
var ShapesIcon = import_lucide_react2.Shapes;
|
|
@@ -9581,43 +9904,43 @@ function CanvasEditor({
|
|
|
9581
9904
|
onOpenTypography,
|
|
9582
9905
|
children
|
|
9583
9906
|
}) {
|
|
9584
|
-
return /* @__PURE__ */ (0,
|
|
9585
|
-
/* @__PURE__ */ (0,
|
|
9586
|
-
/* @__PURE__ */ (0,
|
|
9587
|
-
/* @__PURE__ */ (0,
|
|
9907
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex flex-col gap-6", children: [
|
|
9908
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "bg-background border-2 border-border rounded-lg aspect-square overflow-hidden relative", children: children || /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "flex items-center justify-center w-full h-full", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "text-muted-foreground text-sm", children: "No editor provided" }) }) }),
|
|
9909
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex items-center justify-center gap-8 py-2", children: [
|
|
9910
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9588
9911
|
"button",
|
|
9589
9912
|
{
|
|
9590
9913
|
onClick: onOpenImageGallery,
|
|
9591
9914
|
className: "flex flex-col items-center gap-2 text-muted-foreground hover:text-foreground transition-colors",
|
|
9592
9915
|
"aria-label": "Open image gallery",
|
|
9593
|
-
children: /* @__PURE__ */ (0,
|
|
9916
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "w-10 h-10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(ImageIcon, { className: "w-6 h-6" }) })
|
|
9594
9917
|
}
|
|
9595
9918
|
),
|
|
9596
|
-
/* @__PURE__ */ (0,
|
|
9919
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9597
9920
|
"button",
|
|
9598
9921
|
{
|
|
9599
9922
|
onClick: onOpenTypography,
|
|
9600
9923
|
className: "flex flex-col items-center gap-2 text-muted-foreground hover:text-foreground transition-colors",
|
|
9601
9924
|
"aria-label": "Add text",
|
|
9602
|
-
children: /* @__PURE__ */ (0,
|
|
9925
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "w-10 h-10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TypeIcon, { className: "w-6 h-6" }) })
|
|
9603
9926
|
}
|
|
9604
9927
|
),
|
|
9605
|
-
/* @__PURE__ */ (0,
|
|
9606
|
-
/* @__PURE__ */ (0,
|
|
9928
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { className: "flex flex-col items-center gap-2 text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "w-10 h-10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(ShapesIcon, { className: "w-6 h-6" }) }) }),
|
|
9929
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { className: "flex flex-col items-center gap-2 text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "w-10 h-10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(UploadIcon, { className: "w-6 h-6" }) }) })
|
|
9607
9930
|
] })
|
|
9608
9931
|
] });
|
|
9609
9932
|
}
|
|
9610
9933
|
|
|
9611
9934
|
// src/composed/HeroProductImage.tsx
|
|
9612
|
-
var
|
|
9935
|
+
var import_react45 = require("react");
|
|
9613
9936
|
var import_sdk10 = require("@snowcone-app/sdk");
|
|
9614
9937
|
|
|
9615
9938
|
// src/hooks/viewport/useContainerWidth.ts
|
|
9616
|
-
var
|
|
9939
|
+
var import_react44 = require("react");
|
|
9617
9940
|
function useContainerWidth(containerRef, maxWidth = 3e3) {
|
|
9618
|
-
const [width, setWidth] = (0,
|
|
9619
|
-
const resizeTimeoutRef = (0,
|
|
9620
|
-
(0,
|
|
9941
|
+
const [width, setWidth] = (0, import_react44.useState)(0);
|
|
9942
|
+
const resizeTimeoutRef = (0, import_react44.useRef)(null);
|
|
9943
|
+
(0, import_react44.useLayoutEffect)(() => {
|
|
9621
9944
|
const el = containerRef.current;
|
|
9622
9945
|
if (!el) return;
|
|
9623
9946
|
const cssWidth = el.offsetWidth;
|
|
@@ -9625,7 +9948,7 @@ function useContainerWidth(containerRef, maxWidth = 3e3) {
|
|
|
9625
9948
|
const dpr = window.devicePixelRatio ?? 1;
|
|
9626
9949
|
setWidth(Math.min(Math.round(cssWidth * dpr), maxWidth));
|
|
9627
9950
|
}, [containerRef, maxWidth]);
|
|
9628
|
-
(0,
|
|
9951
|
+
(0, import_react44.useEffect)(() => {
|
|
9629
9952
|
const measure = () => {
|
|
9630
9953
|
const el = containerRef.current;
|
|
9631
9954
|
if (!el) return;
|
|
@@ -9648,7 +9971,7 @@ function useContainerWidth(containerRef, maxWidth = 3e3) {
|
|
|
9648
9971
|
}
|
|
9649
9972
|
|
|
9650
9973
|
// src/composed/HeroProductImage.tsx
|
|
9651
|
-
var
|
|
9974
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
9652
9975
|
function slugifyPlacementKey(label) {
|
|
9653
9976
|
return label.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
9654
9977
|
}
|
|
@@ -9686,7 +10009,7 @@ function buildHeroMockupUrl(args) {
|
|
|
9686
10009
|
});
|
|
9687
10010
|
}
|
|
9688
10011
|
var EMPTY_IMAGES = [];
|
|
9689
|
-
var HeroProductImage = (0,
|
|
10012
|
+
var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
9690
10013
|
productId,
|
|
9691
10014
|
mockupId,
|
|
9692
10015
|
variantId,
|
|
@@ -9719,24 +10042,24 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
9719
10042
|
const shopContext = useShopOptional();
|
|
9720
10043
|
const realtimeContext = useRealtimeOptional();
|
|
9721
10044
|
const priorityContext = useMockupPriorityOptional();
|
|
9722
|
-
const priorityContextRef = (0,
|
|
10045
|
+
const priorityContextRef = (0, import_react45.useRef)(priorityContext);
|
|
9723
10046
|
priorityContextRef.current = priorityContext;
|
|
9724
|
-
const contextRef = (0,
|
|
10047
|
+
const contextRef = (0, import_react45.useRef)(context);
|
|
9725
10048
|
contextRef.current = context;
|
|
9726
10049
|
const actualProductId = product?.id || productId || context?.product?.id;
|
|
9727
|
-
const actualGvid = (0,
|
|
10050
|
+
const actualGvid = (0, import_react45.useMemo)(() => {
|
|
9728
10051
|
return (0, import_sdk10.resolveVariantId)(context, gvid, variantId);
|
|
9729
10052
|
}, [gvid, variantId, context?.selection, context?.combinations]);
|
|
9730
|
-
const actualMockupId = (0,
|
|
10053
|
+
const actualMockupId = (0, import_react45.useMemo)(() => {
|
|
9731
10054
|
return (0, import_sdk10.resolveMockupId)(context, actualGvid, mockupId);
|
|
9732
10055
|
}, [mockupId, actualGvid, context]);
|
|
9733
10056
|
const artworkSrc = artwork?.src;
|
|
9734
10057
|
const selectedArtworkSrc = designContext?.selectedArtwork?.src;
|
|
9735
10058
|
const effectiveArtworkSrc = artworkSrc || selectedArtworkSrc;
|
|
9736
|
-
const containerRef = (0,
|
|
10059
|
+
const containerRef = (0, import_react45.useRef)(null);
|
|
9737
10060
|
const measuredWidth = useContainerWidth(containerRef);
|
|
9738
10061
|
const width = widthProp ?? measuredWidth;
|
|
9739
|
-
const initialStaticUrl = (0,
|
|
10062
|
+
const initialStaticUrl = (0, import_react45.useMemo)(() => {
|
|
9740
10063
|
if (realtimeUrl) return null;
|
|
9741
10064
|
if (mode === "realtime") return null;
|
|
9742
10065
|
if (typeof window !== "undefined" && window.snowcone?.signMockupUrl) {
|
|
@@ -9802,28 +10125,28 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
9802
10125
|
shimmerDelay,
|
|
9803
10126
|
initialUrl: realtimeUrl || initialStaticUrl
|
|
9804
10127
|
});
|
|
9805
|
-
const [error, setError] = (0,
|
|
9806
|
-
const [isInPreloadZone, setIsInPreloadZone] = (0,
|
|
9807
|
-
const componentIdRef = (0,
|
|
10128
|
+
const [error, setError] = (0, import_react45.useState)(null);
|
|
10129
|
+
const [isInPreloadZone, setIsInPreloadZone] = (0, import_react45.useState)(true);
|
|
10130
|
+
const componentIdRef = (0, import_react45.useRef)(
|
|
9808
10131
|
`hero-product-image-${Math.random().toString(36).substr(2, 9)}`
|
|
9809
10132
|
);
|
|
9810
|
-
const [containerMounted, setContainerMounted] = (0,
|
|
9811
|
-
const setContainerRef = (0,
|
|
10133
|
+
const [containerMounted, setContainerMounted] = (0, import_react45.useState)(false);
|
|
10134
|
+
const setContainerRef = (0, import_react45.useCallback)((node) => {
|
|
9812
10135
|
containerRef.current = node;
|
|
9813
10136
|
setContainerMounted(!!node);
|
|
9814
10137
|
}, []);
|
|
9815
|
-
const lastUrlRef = (0,
|
|
9816
|
-
const priorityRegisteredRef = (0,
|
|
9817
|
-
const onLoadCalledRef = (0,
|
|
9818
|
-
const prevArtworkSrcRef = (0,
|
|
9819
|
-
const realtimeArtworkSrcRef = (0,
|
|
9820
|
-
const hasReceivedRealtimeRef = (0,
|
|
9821
|
-
const isPendingExportRef = (0,
|
|
9822
|
-
const onUrlGeneratedRef = (0,
|
|
10138
|
+
const lastUrlRef = (0, import_react45.useRef)(realtimeUrl ?? initialStaticUrl ?? null);
|
|
10139
|
+
const priorityRegisteredRef = (0, import_react45.useRef)(false);
|
|
10140
|
+
const onLoadCalledRef = (0, import_react45.useRef)(false);
|
|
10141
|
+
const prevArtworkSrcRef = (0, import_react45.useRef)(void 0);
|
|
10142
|
+
const realtimeArtworkSrcRef = (0, import_react45.useRef)(void 0);
|
|
10143
|
+
const hasReceivedRealtimeRef = (0, import_react45.useRef)(false);
|
|
10144
|
+
const isPendingExportRef = (0, import_react45.useRef)(false);
|
|
10145
|
+
const onUrlGeneratedRef = (0, import_react45.useRef)(onUrlGenerated);
|
|
9823
10146
|
onUrlGeneratedRef.current = onUrlGenerated;
|
|
9824
|
-
const layersLengthRef = (0,
|
|
10147
|
+
const layersLengthRef = (0, import_react45.useRef)(layers.length);
|
|
9825
10148
|
layersLengthRef.current = layers.length;
|
|
9826
|
-
(0,
|
|
10149
|
+
(0, import_react45.useEffect)(() => {
|
|
9827
10150
|
if (initialPriority === 1) return;
|
|
9828
10151
|
if (!containerMounted || !containerRef.current) return;
|
|
9829
10152
|
if (isInPreloadZone) return;
|
|
@@ -9842,7 +10165,7 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
9842
10165
|
);
|
|
9843
10166
|
return unobserve;
|
|
9844
10167
|
}, [containerMounted, initialPriority, isInPreloadZone]);
|
|
9845
|
-
(0,
|
|
10168
|
+
(0, import_react45.useEffect)(() => {
|
|
9846
10169
|
if (!realtimeUrl) return;
|
|
9847
10170
|
if (realtimeUrl === lastUrlRef.current) return;
|
|
9848
10171
|
lastUrlRef.current = realtimeUrl;
|
|
@@ -9850,7 +10173,7 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
9850
10173
|
const isInitialLoad = layersLengthRef.current === 0;
|
|
9851
10174
|
addLayerDirectly(realtimeUrl, { skipTransition: isInitialLoad });
|
|
9852
10175
|
}, [realtimeUrl, addLayerDirectly, actualMockupId, placement]);
|
|
9853
|
-
(0,
|
|
10176
|
+
(0, import_react45.useEffect)(() => {
|
|
9854
10177
|
if (mode === "static") {
|
|
9855
10178
|
return;
|
|
9856
10179
|
}
|
|
@@ -9894,7 +10217,7 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
9894
10217
|
addLayerDirectly
|
|
9895
10218
|
// NOTE: layers.length removed - use layersLengthRef instead to prevent duplicate requests
|
|
9896
10219
|
]);
|
|
9897
|
-
(0,
|
|
10220
|
+
(0, import_react45.useEffect)(() => {
|
|
9898
10221
|
if (mode === "static") return;
|
|
9899
10222
|
if (!realtimeContext?.subscribePendingBlob || !placement) return;
|
|
9900
10223
|
const handlePendingExport = (pendingPlacement) => {
|
|
@@ -9907,7 +10230,7 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
9907
10230
|
unsubscribe?.();
|
|
9908
10231
|
};
|
|
9909
10232
|
}, [mode, realtimeContext?.subscribePendingBlob, placement]);
|
|
9910
|
-
(0,
|
|
10233
|
+
(0, import_react45.useEffect)(() => {
|
|
9911
10234
|
if (!priorityContext || !actualMockupId || !placement) return;
|
|
9912
10235
|
priorityContext.registerMockup(actualMockupId, placement, initialPriority);
|
|
9913
10236
|
priorityRegisteredRef.current = true;
|
|
@@ -9918,7 +10241,7 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
9918
10241
|
}
|
|
9919
10242
|
};
|
|
9920
10243
|
}, [priorityContext, actualMockupId, placement, initialPriority]);
|
|
9921
|
-
(0,
|
|
10244
|
+
(0, import_react45.useEffect)(() => {
|
|
9922
10245
|
if (!priorityContext?.updateElementRef || !actualMockupId) return;
|
|
9923
10246
|
if (containerMounted && containerRef.current) {
|
|
9924
10247
|
priorityContext.updateElementRef(actualMockupId, containerRef.current);
|
|
@@ -9932,7 +10255,7 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
9932
10255
|
const artworkTileCount = artwork?.type === "pattern" ? artwork?.tileCount : void 0;
|
|
9933
10256
|
const selectedArtworkType = designContext?.selectedArtwork?.type;
|
|
9934
10257
|
const selectedArtworkTileCount = designContext?.selectedArtwork?.type === "pattern" ? designContext?.selectedArtwork?.tileCount : void 0;
|
|
9935
|
-
(0,
|
|
10258
|
+
(0, import_react45.useEffect)(() => {
|
|
9936
10259
|
const currentSrc = artworkSrc || selectedArtworkSrc;
|
|
9937
10260
|
if (currentSrc !== prevArtworkSrcRef.current) {
|
|
9938
10261
|
lastUrlRef.current = null;
|
|
@@ -9942,11 +10265,11 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
9942
10265
|
realtimeArtworkSrcRef.current = void 0;
|
|
9943
10266
|
}
|
|
9944
10267
|
}, [artworkSrc, selectedArtworkSrc]);
|
|
9945
|
-
const contextSelectionRef = (0,
|
|
9946
|
-
const contextOptionAttributesRef = (0,
|
|
10268
|
+
const contextSelectionRef = (0, import_react45.useRef)(context?.selection);
|
|
10269
|
+
const contextOptionAttributesRef = (0, import_react45.useRef)(context?.optionAttributes);
|
|
9947
10270
|
contextSelectionRef.current = context?.selection;
|
|
9948
10271
|
contextOptionAttributesRef.current = context?.optionAttributes;
|
|
9949
|
-
const createDesignForPlacementsWrapper = (0,
|
|
10272
|
+
const createDesignForPlacementsWrapper = (0, import_react45.useCallback)(
|
|
9950
10273
|
(placements, providedImages) => {
|
|
9951
10274
|
const effectiveArtworkSrc2 = artworkSrc || selectedArtworkSrc;
|
|
9952
10275
|
if (!effectiveArtworkSrc2 || effectiveArtworkSrc2.trim() === "" || effectiveArtworkSrc2 === "undefined" || effectiveArtworkSrc2 === "null") {
|
|
@@ -9985,7 +10308,7 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
9985
10308
|
selectedArtworkTileCount
|
|
9986
10309
|
]
|
|
9987
10310
|
);
|
|
9988
|
-
(0,
|
|
10311
|
+
(0, import_react45.useEffect)(() => {
|
|
9989
10312
|
if (mode === "realtime") return;
|
|
9990
10313
|
if (initialStaticUrl && lastUrlRef.current === initialStaticUrl) {
|
|
9991
10314
|
return;
|
|
@@ -10085,13 +10408,13 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
10085
10408
|
const topLayer = layers[layers.length - 1];
|
|
10086
10409
|
const displayUrl = topLayer?.url || realtimeUrl || initialStaticUrl;
|
|
10087
10410
|
const CROSSFADE_MS = 400;
|
|
10088
|
-
const [prevUrl, setPrevUrl] = (0,
|
|
10089
|
-
const [showNew, setShowNew] = (0,
|
|
10090
|
-
const [renderedUrl, setRenderedUrl] = (0,
|
|
10091
|
-
const [firstImageLoaded, setFirstImageLoaded] = (0,
|
|
10092
|
-
const prevDisplayUrlRef = (0,
|
|
10093
|
-
const signHintShownRef = (0,
|
|
10094
|
-
(0,
|
|
10411
|
+
const [prevUrl, setPrevUrl] = (0, import_react45.useState)(null);
|
|
10412
|
+
const [showNew, setShowNew] = (0, import_react45.useState)(false);
|
|
10413
|
+
const [renderedUrl, setRenderedUrl] = (0, import_react45.useState)(displayUrl);
|
|
10414
|
+
const [firstImageLoaded, setFirstImageLoaded] = (0, import_react45.useState)(false);
|
|
10415
|
+
const prevDisplayUrlRef = (0, import_react45.useRef)(displayUrl);
|
|
10416
|
+
const signHintShownRef = (0, import_react45.useRef)(false);
|
|
10417
|
+
(0, import_react45.useEffect)(() => {
|
|
10095
10418
|
if (!displayUrl || displayUrl === prevDisplayUrlRef.current) return;
|
|
10096
10419
|
const oldUrl = prevDisplayUrlRef.current;
|
|
10097
10420
|
prevDisplayUrlRef.current = displayUrl;
|
|
@@ -10116,25 +10439,25 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
10116
10439
|
preload.onload = null;
|
|
10117
10440
|
};
|
|
10118
10441
|
}, [displayUrl]);
|
|
10119
|
-
const handleCrossfadeEnd = (0,
|
|
10442
|
+
const handleCrossfadeEnd = (0, import_react45.useCallback)(() => {
|
|
10120
10443
|
setPrevUrl(null);
|
|
10121
10444
|
setShowNew(false);
|
|
10122
10445
|
}, []);
|
|
10123
10446
|
if (!hasArtwork) {
|
|
10124
|
-
return /* @__PURE__ */ (0,
|
|
10447
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10125
10448
|
"div",
|
|
10126
10449
|
{
|
|
10127
10450
|
className: `bg-gray-100 flex items-center justify-center ${className || ""}`,
|
|
10128
10451
|
style,
|
|
10129
|
-
children: /* @__PURE__ */ (0,
|
|
10130
|
-
/* @__PURE__ */ (0,
|
|
10452
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "text-gray-400 text-center p-4", children: [
|
|
10453
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10131
10454
|
"svg",
|
|
10132
10455
|
{
|
|
10133
10456
|
className: "w-8 h-8 mx-auto mb-2",
|
|
10134
10457
|
fill: "none",
|
|
10135
10458
|
stroke: "currentColor",
|
|
10136
10459
|
viewBox: "0 0 24 24",
|
|
10137
|
-
children: /* @__PURE__ */ (0,
|
|
10460
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10138
10461
|
"path",
|
|
10139
10462
|
{
|
|
10140
10463
|
strokeLinecap: "round",
|
|
@@ -10145,22 +10468,22 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
10145
10468
|
)
|
|
10146
10469
|
}
|
|
10147
10470
|
),
|
|
10148
|
-
/* @__PURE__ */ (0,
|
|
10471
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "text-xs", children: "No artwork" })
|
|
10149
10472
|
] })
|
|
10150
10473
|
}
|
|
10151
10474
|
);
|
|
10152
10475
|
}
|
|
10153
10476
|
if (error) {
|
|
10154
|
-
return /* @__PURE__ */ (0,
|
|
10477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10155
10478
|
"div",
|
|
10156
10479
|
{
|
|
10157
10480
|
className: `bg-red-50 flex items-center justify-center ${className || ""}`,
|
|
10158
10481
|
style,
|
|
10159
|
-
children: /* @__PURE__ */ (0,
|
|
10482
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "text-red-600 text-center p-4", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "text-xs", children: "Error loading" }) })
|
|
10160
10483
|
}
|
|
10161
10484
|
);
|
|
10162
10485
|
}
|
|
10163
|
-
return /* @__PURE__ */ (0,
|
|
10486
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
10164
10487
|
"div",
|
|
10165
10488
|
{
|
|
10166
10489
|
ref: setContainerRef,
|
|
@@ -10168,8 +10491,8 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
10168
10491
|
style,
|
|
10169
10492
|
"data-hero-image": "true",
|
|
10170
10493
|
children: [
|
|
10171
|
-
!firstImageLoaded && /* @__PURE__ */ (0,
|
|
10172
|
-
renderedUrl && /* @__PURE__ */ (0,
|
|
10494
|
+
!firstImageLoaded && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "absolute inset-0 bg-muted-foreground/20 animate-pulse" }),
|
|
10495
|
+
renderedUrl && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10173
10496
|
"img",
|
|
10174
10497
|
{
|
|
10175
10498
|
alt: `Product mockup${placement ? ` - ${placement}` : ""}`,
|
|
@@ -10201,7 +10524,7 @@ var HeroProductImage = (0, import_react44.memo)(function HeroProductImage2({
|
|
|
10201
10524
|
}
|
|
10202
10525
|
}
|
|
10203
10526
|
),
|
|
10204
|
-
prevUrl && /* @__PURE__ */ (0,
|
|
10527
|
+
prevUrl && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10205
10528
|
"img",
|
|
10206
10529
|
{
|
|
10207
10530
|
alt: "",
|
|
@@ -10241,11 +10564,11 @@ var { searchClient } = (0, import_instant_meilisearch.instantMeiliSearch)(
|
|
|
10241
10564
|
);
|
|
10242
10565
|
|
|
10243
10566
|
// src/composed/search/SearchProvider.tsx
|
|
10244
|
-
var
|
|
10245
|
-
var
|
|
10567
|
+
var import_react46 = require("react");
|
|
10568
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
10246
10569
|
function InitialSearchTrigger() {
|
|
10247
10570
|
const { refine } = (0, import_react_instantsearch.useSearchBox)();
|
|
10248
|
-
(0,
|
|
10571
|
+
(0, import_react46.useEffect)(() => {
|
|
10249
10572
|
refine("");
|
|
10250
10573
|
}, [refine]);
|
|
10251
10574
|
return null;
|
|
@@ -10269,7 +10592,7 @@ function SearchProvider({
|
|
|
10269
10592
|
],
|
|
10270
10593
|
children
|
|
10271
10594
|
}) {
|
|
10272
|
-
return /* @__PURE__ */ (0,
|
|
10595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
10273
10596
|
import_react_instantsearch.InstantSearch,
|
|
10274
10597
|
{
|
|
10275
10598
|
searchClient,
|
|
@@ -10297,7 +10620,7 @@ function SearchProvider({
|
|
|
10297
10620
|
}
|
|
10298
10621
|
},
|
|
10299
10622
|
children: [
|
|
10300
|
-
/* @__PURE__ */ (0,
|
|
10623
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
10301
10624
|
import_react_instantsearch.Configure,
|
|
10302
10625
|
{
|
|
10303
10626
|
hitsPerPage,
|
|
@@ -10306,7 +10629,7 @@ function SearchProvider({
|
|
|
10306
10629
|
attributesToRetrieve
|
|
10307
10630
|
}
|
|
10308
10631
|
),
|
|
10309
|
-
/* @__PURE__ */ (0,
|
|
10632
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(InitialSearchTrigger, {}),
|
|
10310
10633
|
children
|
|
10311
10634
|
]
|
|
10312
10635
|
}
|
|
@@ -10316,17 +10639,17 @@ function SearchProvider({
|
|
|
10316
10639
|
// src/composed/search/SearchBox.tsx
|
|
10317
10640
|
var import_react_instantsearch2 = require("react-instantsearch");
|
|
10318
10641
|
var import_lucide_react3 = require("lucide-react");
|
|
10319
|
-
var
|
|
10320
|
-
var
|
|
10642
|
+
var import_react47 = require("react");
|
|
10643
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
10321
10644
|
function SearchBox() {
|
|
10322
10645
|
const { query, refine, clear } = (0, import_react_instantsearch2.useSearchBox)();
|
|
10323
10646
|
const searchParams = useUiSearchParams();
|
|
10324
10647
|
const router = useUiRouter();
|
|
10325
|
-
const inputRef = (0,
|
|
10326
|
-
const [showShimmer, setShowShimmer] = (0,
|
|
10648
|
+
const inputRef = (0, import_react47.useRef)(null);
|
|
10649
|
+
const [showShimmer, setShowShimmer] = (0, import_react47.useState)(false);
|
|
10327
10650
|
const inputId = "search-products-input";
|
|
10328
10651
|
const descriptionId = "search-description";
|
|
10329
|
-
(0,
|
|
10652
|
+
(0, import_react47.useEffect)(() => {
|
|
10330
10653
|
const handleSpotlight = () => {
|
|
10331
10654
|
inputRef.current?.focus();
|
|
10332
10655
|
inputRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
@@ -10336,7 +10659,7 @@ function SearchBox() {
|
|
|
10336
10659
|
window.addEventListener("search-spotlight", handleSpotlight);
|
|
10337
10660
|
return () => window.removeEventListener("search-spotlight", handleSpotlight);
|
|
10338
10661
|
}, []);
|
|
10339
|
-
(0,
|
|
10662
|
+
(0, import_react47.useEffect)(() => {
|
|
10340
10663
|
const shouldFocus = searchParams.get("focus") === "search";
|
|
10341
10664
|
if (shouldFocus && inputRef.current) {
|
|
10342
10665
|
const timer = setTimeout(() => {
|
|
@@ -10351,8 +10674,8 @@ function SearchBox() {
|
|
|
10351
10674
|
return () => clearTimeout(timer);
|
|
10352
10675
|
}
|
|
10353
10676
|
}, [searchParams, router]);
|
|
10354
|
-
return /* @__PURE__ */ (0,
|
|
10355
|
-
/* @__PURE__ */ (0,
|
|
10677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("form", { role: "search", onSubmit: (e) => e.preventDefault(), children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "relative", children: [
|
|
10678
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
10356
10679
|
Input,
|
|
10357
10680
|
{
|
|
10358
10681
|
ref: inputRef,
|
|
@@ -10361,15 +10684,15 @@ function SearchBox() {
|
|
|
10361
10684
|
value: query,
|
|
10362
10685
|
onChange: (e) => refine(e.target.value),
|
|
10363
10686
|
placeholder: "Search products...",
|
|
10364
|
-
startContent: /* @__PURE__ */ (0,
|
|
10365
|
-
endContent: query ? /* @__PURE__ */ (0,
|
|
10687
|
+
startContent: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react3.Search, { className: "w-5 h-5", strokeWidth: 1.5, "aria-hidden": "true" }),
|
|
10688
|
+
endContent: query ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
10366
10689
|
"button",
|
|
10367
10690
|
{
|
|
10368
10691
|
type: "button",
|
|
10369
10692
|
onClick: clear,
|
|
10370
10693
|
className: "hover:text-foreground transition-colors",
|
|
10371
10694
|
"aria-label": "Clear search",
|
|
10372
|
-
children: /* @__PURE__ */ (0,
|
|
10695
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react3.X, { className: "w-4 h-4", strokeWidth: 2, "aria-hidden": "true" })
|
|
10373
10696
|
}
|
|
10374
10697
|
) : void 0,
|
|
10375
10698
|
"aria-label": "Search products",
|
|
@@ -10379,11 +10702,11 @@ function SearchBox() {
|
|
|
10379
10702
|
className: "[&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden"
|
|
10380
10703
|
}
|
|
10381
10704
|
),
|
|
10382
|
-
showShimmer && /* @__PURE__ */ (0,
|
|
10705
|
+
showShimmer && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
10383
10706
|
"div",
|
|
10384
10707
|
{
|
|
10385
10708
|
className: "absolute inset-0 pointer-events-none rounded-input z-20 overflow-hidden",
|
|
10386
|
-
children: /* @__PURE__ */ (0,
|
|
10709
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
10387
10710
|
"div",
|
|
10388
10711
|
{
|
|
10389
10712
|
className: "absolute inset-0",
|
|
@@ -10396,13 +10719,13 @@ function SearchBox() {
|
|
|
10396
10719
|
)
|
|
10397
10720
|
}
|
|
10398
10721
|
),
|
|
10399
|
-
/* @__PURE__ */ (0,
|
|
10722
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("style", { dangerouslySetInnerHTML: { __html: `
|
|
10400
10723
|
@keyframes searchShimmer {
|
|
10401
10724
|
0% { transform: translateX(-100%); }
|
|
10402
10725
|
100% { transform: translateX(100%); }
|
|
10403
10726
|
}
|
|
10404
10727
|
` } }),
|
|
10405
|
-
/* @__PURE__ */ (0,
|
|
10728
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { id: descriptionId, className: "sr-only", children: "Search results will update as you type" })
|
|
10406
10729
|
] }) });
|
|
10407
10730
|
}
|
|
10408
10731
|
|
|
@@ -10410,7 +10733,7 @@ function SearchBox() {
|
|
|
10410
10733
|
var import_react_instantsearch3 = require("react-instantsearch");
|
|
10411
10734
|
|
|
10412
10735
|
// src/composed/search/ProductHit.tsx
|
|
10413
|
-
var
|
|
10736
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
10414
10737
|
function ProductHitComponent({
|
|
10415
10738
|
hit: product,
|
|
10416
10739
|
variant = "overlay"
|
|
@@ -10427,12 +10750,12 @@ function ProductHitComponent({
|
|
|
10427
10750
|
}
|
|
10428
10751
|
return "";
|
|
10429
10752
|
};
|
|
10430
|
-
return /* @__PURE__ */ (0,
|
|
10753
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10431
10754
|
Product,
|
|
10432
10755
|
{
|
|
10433
10756
|
productId,
|
|
10434
10757
|
productData: product,
|
|
10435
|
-
children: /* @__PURE__ */ (0,
|
|
10758
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10436
10759
|
ProductCard,
|
|
10437
10760
|
{
|
|
10438
10761
|
variant,
|
|
@@ -10453,10 +10776,10 @@ function ProductHitComponent({
|
|
|
10453
10776
|
}
|
|
10454
10777
|
|
|
10455
10778
|
// src/composed/search/ProductGrid.tsx
|
|
10456
|
-
var
|
|
10457
|
-
var
|
|
10779
|
+
var import_react48 = require("react");
|
|
10780
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
10458
10781
|
function ProductGridSkeletonItem() {
|
|
10459
|
-
return /* @__PURE__ */ (0,
|
|
10782
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: "aspect-square bg-muted animate-pulse" });
|
|
10460
10783
|
}
|
|
10461
10784
|
function ProductGrid({
|
|
10462
10785
|
className = "",
|
|
@@ -10466,26 +10789,26 @@ function ProductGrid({
|
|
|
10466
10789
|
}) {
|
|
10467
10790
|
const { nbHits } = (0, import_react_instantsearch3.useStats)();
|
|
10468
10791
|
const { status, results } = (0, import_react_instantsearch3.useInstantSearch)();
|
|
10469
|
-
const [announcement, setAnnouncement] = (0,
|
|
10792
|
+
const [announcement, setAnnouncement] = (0, import_react48.useState)("");
|
|
10470
10793
|
const hitsCount = results?.hits?.length ?? 0;
|
|
10471
10794
|
const showSkeleton = hitsCount === 0 && status !== "error";
|
|
10472
|
-
(0,
|
|
10795
|
+
(0, import_react48.useEffect)(() => {
|
|
10473
10796
|
const timer = setTimeout(() => {
|
|
10474
10797
|
setAnnouncement(`${nbHits} ${nbHits === 1 ? "product" : "products"} found`);
|
|
10475
10798
|
}, 1e3);
|
|
10476
10799
|
return () => clearTimeout(timer);
|
|
10477
10800
|
}, [nbHits]);
|
|
10478
|
-
const HitComponent = (0,
|
|
10801
|
+
const HitComponent = (0, import_react48.useCallback)(({ hit }) => /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
10479
10802
|
ProductHitComponent,
|
|
10480
10803
|
{
|
|
10481
10804
|
hit,
|
|
10482
10805
|
variant
|
|
10483
10806
|
}
|
|
10484
10807
|
), [variant]);
|
|
10485
|
-
return /* @__PURE__ */ (0,
|
|
10486
|
-
/* @__PURE__ */ (0,
|
|
10487
|
-
showSkeleton && /* @__PURE__ */ (0,
|
|
10488
|
-
/* @__PURE__ */ (0,
|
|
10808
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className, children: [
|
|
10809
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: "sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement }),
|
|
10810
|
+
showSkeleton && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: `grid ${gridClassName}`, children: Array.from({ length: skeletonCount }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ProductGridSkeletonItem, {}, i)) }),
|
|
10811
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: showSkeleton ? "hidden" : "", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
10489
10812
|
import_react_instantsearch3.Hits,
|
|
10490
10813
|
{
|
|
10491
10814
|
hitComponent: HitComponent,
|
|
@@ -10500,18 +10823,18 @@ function ProductGrid({
|
|
|
10500
10823
|
}
|
|
10501
10824
|
|
|
10502
10825
|
// src/composed/search/Filters.tsx
|
|
10503
|
-
var
|
|
10826
|
+
var import_react50 = require("react");
|
|
10504
10827
|
|
|
10505
10828
|
// src/composed/search/FiltersButton.tsx
|
|
10506
10829
|
var import_lucide_react4 = require("lucide-react");
|
|
10507
|
-
var
|
|
10830
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
10508
10831
|
var SlidersHorizontalIcon = import_lucide_react4.SlidersHorizontal;
|
|
10509
10832
|
function FiltersButton({
|
|
10510
10833
|
onClick,
|
|
10511
10834
|
className = "",
|
|
10512
10835
|
children = "Filters"
|
|
10513
10836
|
}) {
|
|
10514
|
-
return /* @__PURE__ */ (0,
|
|
10837
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(
|
|
10515
10838
|
Button,
|
|
10516
10839
|
{
|
|
10517
10840
|
variant: "field",
|
|
@@ -10519,8 +10842,8 @@ function FiltersButton({
|
|
|
10519
10842
|
className,
|
|
10520
10843
|
"aria-label": "Open filters",
|
|
10521
10844
|
children: [
|
|
10522
|
-
/* @__PURE__ */ (0,
|
|
10523
|
-
/* @__PURE__ */ (0,
|
|
10845
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(SlidersHorizontalIcon, { className: "w-4 h-4" }),
|
|
10846
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { children })
|
|
10524
10847
|
]
|
|
10525
10848
|
}
|
|
10526
10849
|
);
|
|
@@ -10529,15 +10852,15 @@ function FiltersButton({
|
|
|
10529
10852
|
// src/composed/search/FiltersDrawer.tsx
|
|
10530
10853
|
var import_react_instantsearch4 = require("react-instantsearch");
|
|
10531
10854
|
var import_lucide_react5 = require("lucide-react");
|
|
10532
|
-
var
|
|
10855
|
+
var import_react49 = require("react");
|
|
10533
10856
|
var Slider2 = __toESM(require("@radix-ui/react-slider"), 1);
|
|
10534
|
-
var
|
|
10857
|
+
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
10535
10858
|
var XIcon2 = import_lucide_react5.X;
|
|
10536
10859
|
function FiltersDrawer({ isOpen, onClose }) {
|
|
10537
|
-
const [showCounts, setShowCounts] = (0,
|
|
10860
|
+
const [showCounts, setShowCounts] = (0, import_react49.useState)(false);
|
|
10538
10861
|
const { nbHits } = (0, import_react_instantsearch4.useStats)();
|
|
10539
10862
|
const containerRef = useFocusTrap(isOpen, onClose);
|
|
10540
|
-
(0,
|
|
10863
|
+
(0, import_react49.useEffect)(() => {
|
|
10541
10864
|
if (isOpen) {
|
|
10542
10865
|
document.body.style.overflow = "hidden";
|
|
10543
10866
|
} else {
|
|
@@ -10547,7 +10870,7 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10547
10870
|
document.body.style.overflow = "";
|
|
10548
10871
|
};
|
|
10549
10872
|
}, [isOpen]);
|
|
10550
|
-
(0,
|
|
10873
|
+
(0, import_react49.useEffect)(() => {
|
|
10551
10874
|
const handleEscape = (e) => {
|
|
10552
10875
|
if (e.key === "Escape" && isOpen) {
|
|
10553
10876
|
onClose();
|
|
@@ -10556,8 +10879,8 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10556
10879
|
document.addEventListener("keydown", handleEscape);
|
|
10557
10880
|
return () => document.removeEventListener("keydown", handleEscape);
|
|
10558
10881
|
}, [isOpen, onClose]);
|
|
10559
|
-
return /* @__PURE__ */ (0,
|
|
10560
|
-
/* @__PURE__ */ (0,
|
|
10882
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(import_jsx_runtime66.Fragment, { children: [
|
|
10883
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10561
10884
|
"div",
|
|
10562
10885
|
{
|
|
10563
10886
|
className: `fixed inset-0 bg-black/50 z-40 transition-opacity ${isOpen ? "opacity-100" : "opacity-0 pointer-events-none"}`,
|
|
@@ -10565,7 +10888,7 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10565
10888
|
"aria-hidden": "true"
|
|
10566
10889
|
}
|
|
10567
10890
|
),
|
|
10568
|
-
/* @__PURE__ */ (0,
|
|
10891
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
|
|
10569
10892
|
"div",
|
|
10570
10893
|
{
|
|
10571
10894
|
ref: containerRef,
|
|
@@ -10574,26 +10897,26 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10574
10897
|
"aria-modal": "true",
|
|
10575
10898
|
"aria-labelledby": "filters-drawer-title",
|
|
10576
10899
|
children: [
|
|
10577
|
-
/* @__PURE__ */ (0,
|
|
10578
|
-
/* @__PURE__ */ (0,
|
|
10579
|
-
/* @__PURE__ */ (0,
|
|
10900
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "flex items-center justify-between px-4 py-4", children: [
|
|
10901
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("h2", { id: "filters-drawer-title", className: "text-xl font-bold", children: "Filters" }),
|
|
10902
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10580
10903
|
"button",
|
|
10581
10904
|
{
|
|
10582
10905
|
onClick: onClose,
|
|
10583
10906
|
className: "p-2 hover:bg-foreground/5 rounded-full transition-colors",
|
|
10584
10907
|
"aria-label": "Close filters",
|
|
10585
|
-
children: /* @__PURE__ */ (0,
|
|
10908
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(XIcon2, { className: "w-5 h-5" })
|
|
10586
10909
|
}
|
|
10587
10910
|
)
|
|
10588
10911
|
] }),
|
|
10589
|
-
/* @__PURE__ */ (0,
|
|
10912
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "px-4 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("p", { className: "text-sm font-caption text-foreground/60", role: "status", "aria-live": "polite", children: [
|
|
10590
10913
|
nbHits.toLocaleString(),
|
|
10591
10914
|
" ",
|
|
10592
10915
|
nbHits === 1 ? "result" : "results"
|
|
10593
10916
|
] }) }),
|
|
10594
|
-
/* @__PURE__ */ (0,
|
|
10595
|
-
/* @__PURE__ */ (0,
|
|
10596
|
-
/* @__PURE__ */ (0,
|
|
10917
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "flex-1 overflow-y-auto px-4 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "flex flex-col gap-8", children: [
|
|
10918
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(TagsSection, { showCounts, setShowCounts }),
|
|
10919
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(PriceSection, {})
|
|
10597
10920
|
] }) })
|
|
10598
10921
|
]
|
|
10599
10922
|
}
|
|
@@ -10609,9 +10932,9 @@ function TagsSection({
|
|
|
10609
10932
|
sortBy: ["count:desc", "name:asc"],
|
|
10610
10933
|
limit: 100
|
|
10611
10934
|
});
|
|
10612
|
-
const [isExpanded, setIsExpanded] = (0,
|
|
10613
|
-
return /* @__PURE__ */ (0,
|
|
10614
|
-
/* @__PURE__ */ (0,
|
|
10935
|
+
const [isExpanded, setIsExpanded] = (0, import_react49.useState)(true);
|
|
10936
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "bg-foreground/5 rounded-lg p-4", children: [
|
|
10937
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
|
|
10615
10938
|
"button",
|
|
10616
10939
|
{
|
|
10617
10940
|
onClick: () => setIsExpanded(!isExpanded),
|
|
@@ -10619,8 +10942,8 @@ function TagsSection({
|
|
|
10619
10942
|
"aria-expanded": isExpanded,
|
|
10620
10943
|
"aria-controls": "tags-content",
|
|
10621
10944
|
children: [
|
|
10622
|
-
/* @__PURE__ */ (0,
|
|
10623
|
-
/* @__PURE__ */ (0,
|
|
10945
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("h3", { className: "text-base font-semibold text-primary", children: "Tags" }),
|
|
10946
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10624
10947
|
"svg",
|
|
10625
10948
|
{
|
|
10626
10949
|
className: `w-5 h-5 transition-transform text-foreground/40 group-hover:text-foreground/60 ${isExpanded ? "rotate-180" : ""}`,
|
|
@@ -10629,14 +10952,14 @@ function TagsSection({
|
|
|
10629
10952
|
stroke: "currentColor",
|
|
10630
10953
|
strokeWidth: 2.5,
|
|
10631
10954
|
"aria-hidden": "true",
|
|
10632
|
-
children: /* @__PURE__ */ (0,
|
|
10955
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
|
|
10633
10956
|
}
|
|
10634
10957
|
)
|
|
10635
10958
|
]
|
|
10636
10959
|
}
|
|
10637
10960
|
),
|
|
10638
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
10639
|
-
/* @__PURE__ */ (0,
|
|
10961
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "space-y-4", id: "tags-content", children: [
|
|
10962
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "flex flex-wrap gap-2", role: "group", "aria-label": "Product tags filter", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
|
|
10640
10963
|
"button",
|
|
10641
10964
|
{
|
|
10642
10965
|
onClick: () => refine(item.value),
|
|
@@ -10647,15 +10970,15 @@ function TagsSection({
|
|
|
10647
10970
|
"aria-label": `${item.isRefined ? "Remove" : "Apply"} ${item.label} filter${showCounts ? ` (${item.count} products)` : ""}`,
|
|
10648
10971
|
"aria-pressed": item.isRefined,
|
|
10649
10972
|
children: [
|
|
10650
|
-
/* @__PURE__ */ (0,
|
|
10651
|
-
showCounts && /* @__PURE__ */ (0,
|
|
10973
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { "aria-hidden": "true", children: item.label }),
|
|
10974
|
+
showCounts && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: `text-xs font-caption ${item.isRefined ? "opacity-80" : "opacity-60"}`, "aria-hidden": "true", children: item.count })
|
|
10652
10975
|
]
|
|
10653
10976
|
},
|
|
10654
10977
|
item.value
|
|
10655
10978
|
)) }),
|
|
10656
|
-
/* @__PURE__ */ (0,
|
|
10657
|
-
/* @__PURE__ */ (0,
|
|
10658
|
-
/* @__PURE__ */ (0,
|
|
10979
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "flex items-center justify-between pt-2", children: [
|
|
10980
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "text-sm font-label text-foreground/60", id: "show-counts-label", children: "Show counts" }),
|
|
10981
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10659
10982
|
"button",
|
|
10660
10983
|
{
|
|
10661
10984
|
onClick: () => setShowCounts(!showCounts),
|
|
@@ -10663,7 +10986,7 @@ function TagsSection({
|
|
|
10663
10986
|
role: "switch",
|
|
10664
10987
|
"aria-checked": showCounts,
|
|
10665
10988
|
"aria-labelledby": "show-counts-label",
|
|
10666
|
-
children: /* @__PURE__ */ (0,
|
|
10989
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10667
10990
|
"span",
|
|
10668
10991
|
{
|
|
10669
10992
|
className: `inline-block h-4 w-4 transform rounded-full bg-background shadow-sm transition-transform ${showCounts ? "translate-x-6" : "translate-x-1"}`,
|
|
@@ -10680,11 +11003,11 @@ function PriceSection() {
|
|
|
10680
11003
|
const { range, refine, start, canRefine } = (0, import_react_instantsearch4.useRange)({ attribute: "price" });
|
|
10681
11004
|
const rangeMin = typeof range.min === "number" && isFinite(range.min) ? range.min : 0;
|
|
10682
11005
|
const rangeMax = typeof range.max === "number" && isFinite(range.max) ? range.max : 15e3;
|
|
10683
|
-
const [localRange, setLocalRange] = (0,
|
|
11006
|
+
const [localRange, setLocalRange] = (0, import_react49.useState)([
|
|
10684
11007
|
typeof start?.[0] === "number" && isFinite(start[0]) ? start[0] : rangeMin,
|
|
10685
11008
|
typeof start?.[1] === "number" && isFinite(start[1]) ? start[1] : rangeMax
|
|
10686
11009
|
]);
|
|
10687
|
-
(0,
|
|
11010
|
+
(0, import_react49.useEffect)(() => {
|
|
10688
11011
|
if (start && Array.isArray(start)) {
|
|
10689
11012
|
setLocalRange([
|
|
10690
11013
|
typeof start[0] === "number" && isFinite(start[0]) ? start[0] : rangeMin,
|
|
@@ -10694,7 +11017,7 @@ function PriceSection() {
|
|
|
10694
11017
|
setLocalRange([rangeMin, rangeMax]);
|
|
10695
11018
|
}
|
|
10696
11019
|
}, [start, rangeMin, rangeMax]);
|
|
10697
|
-
const [isExpanded, setIsExpanded] = (0,
|
|
11020
|
+
const [isExpanded, setIsExpanded] = (0, import_react49.useState)(true);
|
|
10698
11021
|
if (!canRefine) {
|
|
10699
11022
|
return null;
|
|
10700
11023
|
}
|
|
@@ -10709,8 +11032,8 @@ function PriceSection() {
|
|
|
10709
11032
|
return `$${priceInDollars.toFixed(2)}`;
|
|
10710
11033
|
}
|
|
10711
11034
|
};
|
|
10712
|
-
return /* @__PURE__ */ (0,
|
|
10713
|
-
/* @__PURE__ */ (0,
|
|
11035
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "bg-foreground/5 rounded-lg p-4", children: [
|
|
11036
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
|
|
10714
11037
|
"button",
|
|
10715
11038
|
{
|
|
10716
11039
|
onClick: () => setIsExpanded(!isExpanded),
|
|
@@ -10718,8 +11041,8 @@ function PriceSection() {
|
|
|
10718
11041
|
"aria-expanded": isExpanded,
|
|
10719
11042
|
"aria-controls": "price-content",
|
|
10720
11043
|
children: [
|
|
10721
|
-
/* @__PURE__ */ (0,
|
|
10722
|
-
/* @__PURE__ */ (0,
|
|
11044
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("h3", { className: "text-base font-semibold text-primary", children: "Price" }),
|
|
11045
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10723
11046
|
"svg",
|
|
10724
11047
|
{
|
|
10725
11048
|
className: `w-5 h-5 transition-transform text-foreground/40 group-hover:text-foreground/60 ${isExpanded ? "rotate-180" : ""}`,
|
|
@@ -10728,22 +11051,22 @@ function PriceSection() {
|
|
|
10728
11051
|
stroke: "currentColor",
|
|
10729
11052
|
strokeWidth: 2.5,
|
|
10730
11053
|
"aria-hidden": "true",
|
|
10731
|
-
children: /* @__PURE__ */ (0,
|
|
11054
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
|
|
10732
11055
|
}
|
|
10733
11056
|
)
|
|
10734
11057
|
]
|
|
10735
11058
|
}
|
|
10736
11059
|
),
|
|
10737
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
10738
|
-
/* @__PURE__ */ (0,
|
|
10739
|
-
/* @__PURE__ */ (0,
|
|
10740
|
-
/* @__PURE__ */ (0,
|
|
11060
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "space-y-6", id: "price-content", children: [
|
|
11061
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "flex items-center justify-between text-sm font-display", children: [
|
|
11062
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { children: formatPrice2(localRange[0]) }),
|
|
11063
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "text-foreground/70", children: formatPrice2(localRange[1]) })
|
|
10741
11064
|
] }),
|
|
10742
|
-
/* @__PURE__ */ (0,
|
|
11065
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "relative h-24 flex items-end justify-between gap-0.5 px-1", "aria-hidden": "true", role: "presentation", children: [60, 40, 80, 50, 60, 30, 20, 15, 10, 5, 30, 20, 15, 10, 5, 3, 3, 60, 40].map((height, i) => {
|
|
10743
11066
|
const totalBars = 19;
|
|
10744
11067
|
const barPrice = rangeMin + (rangeMax - rangeMin) / totalBars * i;
|
|
10745
11068
|
const isInRange = barPrice >= localRange[0] && barPrice <= localRange[1];
|
|
10746
|
-
return /* @__PURE__ */ (0,
|
|
11069
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10747
11070
|
"div",
|
|
10748
11071
|
{
|
|
10749
11072
|
className: `flex-1 rounded-t-sm transition-opacity ${isInRange ? "bg-foreground" : "bg-foreground/20"}`,
|
|
@@ -10752,7 +11075,7 @@ function PriceSection() {
|
|
|
10752
11075
|
i
|
|
10753
11076
|
);
|
|
10754
11077
|
}) }),
|
|
10755
|
-
/* @__PURE__ */ (0,
|
|
11078
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { style: { touchAction: "none" }, className: "my-6", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
|
|
10756
11079
|
Slider2.Root,
|
|
10757
11080
|
{
|
|
10758
11081
|
className: "relative flex w-full touch-none select-none items-center",
|
|
@@ -10770,8 +11093,8 @@ function PriceSection() {
|
|
|
10770
11093
|
step: 1,
|
|
10771
11094
|
minStepsBetweenThumbs: 1,
|
|
10772
11095
|
children: [
|
|
10773
|
-
/* @__PURE__ */ (0,
|
|
10774
|
-
/* @__PURE__ */ (0,
|
|
11096
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Slider2.Track, { className: "relative h-3 w-full grow overflow-hidden rounded-full bg-foreground/20", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Slider2.Range, { className: "absolute h-full bg-foreground" }) }),
|
|
11097
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10775
11098
|
Slider2.Thumb,
|
|
10776
11099
|
{
|
|
10777
11100
|
className: "block h-6 w-6 rounded-full bg-background shadow transition-all focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50 cursor-grab active:cursor-grabbing hover:scale-105 border-2 border-primary",
|
|
@@ -10785,7 +11108,7 @@ function PriceSection() {
|
|
|
10785
11108
|
"aria-valuetext": formatPrice2(localRange[0])
|
|
10786
11109
|
}
|
|
10787
11110
|
),
|
|
10788
|
-
/* @__PURE__ */ (0,
|
|
11111
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10789
11112
|
Slider2.Thumb,
|
|
10790
11113
|
{
|
|
10791
11114
|
className: "block h-6 w-6 rounded-full bg-background shadow transition-all focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50 cursor-grab active:cursor-grabbing hover:scale-105 border-2 border-primary",
|
|
@@ -10802,10 +11125,10 @@ function PriceSection() {
|
|
|
10802
11125
|
]
|
|
10803
11126
|
}
|
|
10804
11127
|
) }),
|
|
10805
|
-
/* @__PURE__ */ (0,
|
|
10806
|
-
/* @__PURE__ */ (0,
|
|
10807
|
-
/* @__PURE__ */ (0,
|
|
10808
|
-
/* @__PURE__ */ (0,
|
|
11128
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
11129
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { children: [
|
|
11130
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("label", { htmlFor: "price-min", className: "text-xs font-label text-foreground/60 mb-1.5 block", children: "Min" }),
|
|
11131
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10809
11132
|
"input",
|
|
10810
11133
|
{
|
|
10811
11134
|
id: "price-min",
|
|
@@ -10823,9 +11146,9 @@ function PriceSection() {
|
|
|
10823
11146
|
}
|
|
10824
11147
|
)
|
|
10825
11148
|
] }),
|
|
10826
|
-
/* @__PURE__ */ (0,
|
|
10827
|
-
/* @__PURE__ */ (0,
|
|
10828
|
-
/* @__PURE__ */ (0,
|
|
11149
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { children: [
|
|
11150
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("label", { htmlFor: "price-max", className: "text-xs font-label text-foreground/60 mb-1.5 block", children: "Max" }),
|
|
11151
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
10829
11152
|
"input",
|
|
10830
11153
|
{
|
|
10831
11154
|
id: "price-max",
|
|
@@ -10849,11 +11172,11 @@ function PriceSection() {
|
|
|
10849
11172
|
}
|
|
10850
11173
|
|
|
10851
11174
|
// src/composed/search/Filters.tsx
|
|
10852
|
-
var
|
|
11175
|
+
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
10853
11176
|
function Filters({ buttonClassName, buttonText }) {
|
|
10854
|
-
const [isOpen, setIsOpen] = (0,
|
|
10855
|
-
return /* @__PURE__ */ (0,
|
|
10856
|
-
/* @__PURE__ */ (0,
|
|
11177
|
+
const [isOpen, setIsOpen] = (0, import_react50.useState)(false);
|
|
11178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(import_jsx_runtime67.Fragment, { children: [
|
|
11179
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
10857
11180
|
FiltersButton,
|
|
10858
11181
|
{
|
|
10859
11182
|
onClick: () => setIsOpen(true),
|
|
@@ -10861,14 +11184,14 @@ function Filters({ buttonClassName, buttonText }) {
|
|
|
10861
11184
|
children: buttonText
|
|
10862
11185
|
}
|
|
10863
11186
|
),
|
|
10864
|
-
/* @__PURE__ */ (0,
|
|
11187
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(FiltersDrawer, { isOpen, onClose: () => setIsOpen(false) })
|
|
10865
11188
|
] });
|
|
10866
11189
|
}
|
|
10867
11190
|
|
|
10868
11191
|
// src/composed/search/CurrentRefinements.tsx
|
|
10869
11192
|
var import_react_instantsearch5 = require("react-instantsearch");
|
|
10870
11193
|
var import_lucide_react6 = require("lucide-react");
|
|
10871
|
-
var
|
|
11194
|
+
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
10872
11195
|
var XIcon3 = import_lucide_react6.X;
|
|
10873
11196
|
function CurrentRefinements() {
|
|
10874
11197
|
const { items, refine } = (0, import_react_instantsearch5.useCurrentRefinements)();
|
|
@@ -10914,15 +11237,15 @@ function CurrentRefinements() {
|
|
|
10914
11237
|
if (allRefinements.length === 0) {
|
|
10915
11238
|
return null;
|
|
10916
11239
|
}
|
|
10917
|
-
return /* @__PURE__ */ (0,
|
|
11240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "flex flex-wrap items-center gap-2 mb-4 -mt-1", role: "group", "aria-label": "Active filters", children: allRefinements.map((refinement, index) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
10918
11241
|
"button",
|
|
10919
11242
|
{
|
|
10920
11243
|
className: "bg-primary text-on-primary hover:bg-primary/90 inline-flex h-7 items-center gap-1.5 rounded-full px-3 text-sm transition-colors",
|
|
10921
11244
|
onClick: () => refinement.refine(),
|
|
10922
11245
|
"aria-label": `Remove filter: ${refinement.displayLabel}`,
|
|
10923
11246
|
children: [
|
|
10924
|
-
/* @__PURE__ */ (0,
|
|
10925
|
-
/* @__PURE__ */ (0,
|
|
11247
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "truncate", children: refinement.displayLabel }),
|
|
11248
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(XIcon3, { className: "w-3 h-3" })
|
|
10926
11249
|
]
|
|
10927
11250
|
},
|
|
10928
11251
|
`${refinement.attribute}-${refinement.value}-${index}`
|
|
@@ -10946,12 +11269,12 @@ var FACET_SECTIONS = [
|
|
|
10946
11269
|
];
|
|
10947
11270
|
|
|
10948
11271
|
// src/composed/zoom/ResponsiveZoom.tsx
|
|
10949
|
-
var
|
|
11272
|
+
var import_react53 = require("react");
|
|
10950
11273
|
|
|
10951
11274
|
// src/composed/zoom/ZoomOverlay.tsx
|
|
10952
|
-
var
|
|
11275
|
+
var import_react51 = require("react");
|
|
10953
11276
|
var import_lucide_react7 = require("lucide-react");
|
|
10954
|
-
var
|
|
11277
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
10955
11278
|
var PlusIcon2 = import_lucide_react7.Plus;
|
|
10956
11279
|
var MinusIcon2 = import_lucide_react7.Minus;
|
|
10957
11280
|
function ZoomOverlay({
|
|
@@ -10963,13 +11286,13 @@ function ZoomOverlay({
|
|
|
10963
11286
|
className,
|
|
10964
11287
|
style
|
|
10965
11288
|
}) {
|
|
10966
|
-
const [zoomedImageIndex, setZoomedImageIndex] = (0,
|
|
10967
|
-
const [zoomOrigin, setZoomOrigin] = (0,
|
|
10968
|
-
const [hoveredImageIndex, setHoveredImageIndex] = (0,
|
|
10969
|
-
const [cursorPos, setCursorPos] = (0,
|
|
10970
|
-
const [announcement, setAnnouncement] = (0,
|
|
10971
|
-
const [isZooming, setIsZooming] = (0,
|
|
10972
|
-
const handleZoomClick = (0,
|
|
11289
|
+
const [zoomedImageIndex, setZoomedImageIndex] = (0, import_react51.useState)(null);
|
|
11290
|
+
const [zoomOrigin, setZoomOrigin] = (0, import_react51.useState)({ x: 50, y: 50 });
|
|
11291
|
+
const [hoveredImageIndex, setHoveredImageIndex] = (0, import_react51.useState)(null);
|
|
11292
|
+
const [cursorPos, setCursorPos] = (0, import_react51.useState)({ x: 0, y: 0 });
|
|
11293
|
+
const [announcement, setAnnouncement] = (0, import_react51.useState)("");
|
|
11294
|
+
const [isZooming, setIsZooming] = (0, import_react51.useState)(false);
|
|
11295
|
+
const handleZoomClick = (0, import_react51.useCallback)(
|
|
10973
11296
|
(e) => {
|
|
10974
11297
|
e.stopPropagation();
|
|
10975
11298
|
if (isLargeTouchDevice && onEnhancedViewer) {
|
|
@@ -10994,7 +11317,7 @@ function ZoomOverlay({
|
|
|
10994
11317
|
},
|
|
10995
11318
|
[zoomedImageIndex, isLargeTouchDevice, onEnhancedViewer, imageIndex]
|
|
10996
11319
|
);
|
|
10997
|
-
const handleZoomMouseMove = (0,
|
|
11320
|
+
const handleZoomMouseMove = (0, import_react51.useCallback)(
|
|
10998
11321
|
(e) => {
|
|
10999
11322
|
setCursorPos({ x: e.clientX, y: e.clientY });
|
|
11000
11323
|
if (zoomedImageIndex === imageIndex) {
|
|
@@ -11010,9 +11333,9 @@ function ZoomOverlay({
|
|
|
11010
11333
|
const isZoomed = zoomedImageIndex === imageIndex;
|
|
11011
11334
|
const isHovered = hoveredImageIndex === imageIndex;
|
|
11012
11335
|
const cursorStyle = isLargeTouchDevice ? "pointer" : isTouchDevice ? "default" : "none";
|
|
11013
|
-
return /* @__PURE__ */ (0,
|
|
11014
|
-
/* @__PURE__ */ (0,
|
|
11015
|
-
/* @__PURE__ */ (0,
|
|
11336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
|
|
11337
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement }),
|
|
11338
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
11016
11339
|
"div",
|
|
11017
11340
|
{
|
|
11018
11341
|
className,
|
|
@@ -11020,7 +11343,7 @@ function ZoomOverlay({
|
|
|
11020
11343
|
...style,
|
|
11021
11344
|
position: "relative"
|
|
11022
11345
|
},
|
|
11023
|
-
children: /* @__PURE__ */ (0,
|
|
11346
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
11024
11347
|
"div",
|
|
11025
11348
|
{
|
|
11026
11349
|
style: {
|
|
@@ -11043,7 +11366,7 @@ function ZoomOverlay({
|
|
|
11043
11366
|
handleZoomClick(e);
|
|
11044
11367
|
}
|
|
11045
11368
|
},
|
|
11046
|
-
children: /* @__PURE__ */ (0,
|
|
11369
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
11047
11370
|
"div",
|
|
11048
11371
|
{
|
|
11049
11372
|
style: {
|
|
@@ -11059,7 +11382,7 @@ function ZoomOverlay({
|
|
|
11059
11382
|
)
|
|
11060
11383
|
}
|
|
11061
11384
|
),
|
|
11062
|
-
isHovered && !isTouchDevice && /* @__PURE__ */ (0,
|
|
11385
|
+
isHovered && !isTouchDevice && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
11063
11386
|
"div",
|
|
11064
11387
|
{
|
|
11065
11388
|
className: "fixed pointer-events-none z-50 hidden md:block",
|
|
@@ -11069,7 +11392,7 @@ function ZoomOverlay({
|
|
|
11069
11392
|
transform: "translate(-50%, -50%)"
|
|
11070
11393
|
},
|
|
11071
11394
|
"aria-hidden": "true",
|
|
11072
|
-
children: /* @__PURE__ */ (0,
|
|
11395
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "bg-white dark:bg-gray-800 rounded-full p-2 shadow-sm dark:shadow-gray-950/50", children: isZoomed ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
11073
11396
|
MinusIcon2,
|
|
11074
11397
|
{
|
|
11075
11398
|
size: 20,
|
|
@@ -11077,7 +11400,7 @@ function ZoomOverlay({
|
|
|
11077
11400
|
strokeWidth: 1.5,
|
|
11078
11401
|
"aria-hidden": "true"
|
|
11079
11402
|
}
|
|
11080
|
-
) : /* @__PURE__ */ (0,
|
|
11403
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
11081
11404
|
PlusIcon2,
|
|
11082
11405
|
{
|
|
11083
11406
|
size: 20,
|
|
@@ -11092,11 +11415,11 @@ function ZoomOverlay({
|
|
|
11092
11415
|
}
|
|
11093
11416
|
|
|
11094
11417
|
// src/composed/zoom/EnhancedImageViewer.tsx
|
|
11095
|
-
var
|
|
11096
|
-
var
|
|
11418
|
+
var import_react52 = require("react");
|
|
11419
|
+
var import_react_dom3 = require("react-dom");
|
|
11097
11420
|
var import_react_zoom_pan_pinch = require("react-zoom-pan-pinch");
|
|
11098
11421
|
var import_lucide_react8 = require("lucide-react");
|
|
11099
|
-
var
|
|
11422
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
11100
11423
|
var TransformWrapper = import_react_zoom_pan_pinch.TransformWrapper;
|
|
11101
11424
|
var TransformComponent = import_react_zoom_pan_pinch.TransformComponent;
|
|
11102
11425
|
var EnhancedImageViewer = ({
|
|
@@ -11107,17 +11430,17 @@ var EnhancedImageViewer = ({
|
|
|
11107
11430
|
onIndexChange,
|
|
11108
11431
|
currentIndex: propCurrentIndex
|
|
11109
11432
|
}) => {
|
|
11110
|
-
const [isMounted, setIsMounted] = (0,
|
|
11111
|
-
const [isClient, setIsClient] = (0,
|
|
11112
|
-
const [scale, setScale] = (0,
|
|
11113
|
-
const [cropDimensions, setCropDimensions] = (0,
|
|
11114
|
-
const [currentZoomScale, setCurrentZoomScale] = (0,
|
|
11115
|
-
const imgRef = (0,
|
|
11116
|
-
const touchStartRef = (0,
|
|
11433
|
+
const [isMounted, setIsMounted] = (0, import_react52.useState)(false);
|
|
11434
|
+
const [isClient, setIsClient] = (0, import_react52.useState)(false);
|
|
11435
|
+
const [scale, setScale] = (0, import_react52.useState)({ initial: 1, min: 1, max: 8 });
|
|
11436
|
+
const [cropDimensions, setCropDimensions] = (0, import_react52.useState)({ width: 0, height: 0 });
|
|
11437
|
+
const [currentZoomScale, setCurrentZoomScale] = (0, import_react52.useState)(1);
|
|
11438
|
+
const imgRef = (0, import_react52.useRef)(null);
|
|
11439
|
+
const touchStartRef = (0, import_react52.useRef)(
|
|
11117
11440
|
null
|
|
11118
11441
|
);
|
|
11119
|
-
const isSwipingRef = (0,
|
|
11120
|
-
const calculateScale = (0,
|
|
11442
|
+
const isSwipingRef = (0, import_react52.useRef)(false);
|
|
11443
|
+
const calculateScale = (0, import_react52.useCallback)(() => {
|
|
11121
11444
|
const viewport = {
|
|
11122
11445
|
width: window.innerWidth,
|
|
11123
11446
|
height: window.innerHeight
|
|
@@ -11129,10 +11452,10 @@ var EnhancedImageViewer = ({
|
|
|
11129
11452
|
max: 8
|
|
11130
11453
|
});
|
|
11131
11454
|
}, []);
|
|
11132
|
-
const handleImageLoad = (0,
|
|
11455
|
+
const handleImageLoad = (0, import_react52.useCallback)(() => {
|
|
11133
11456
|
calculateScale();
|
|
11134
11457
|
}, [calculateScale]);
|
|
11135
|
-
(0,
|
|
11458
|
+
(0, import_react52.useLayoutEffect)(() => {
|
|
11136
11459
|
setIsClient(true);
|
|
11137
11460
|
setIsMounted(true);
|
|
11138
11461
|
document.body.style.overflow = "hidden";
|
|
@@ -11141,17 +11464,17 @@ var EnhancedImageViewer = ({
|
|
|
11141
11464
|
document.body.style.overflow = "";
|
|
11142
11465
|
};
|
|
11143
11466
|
}, [calculateScale]);
|
|
11144
|
-
(0,
|
|
11467
|
+
(0, import_react52.useEffect)(() => {
|
|
11145
11468
|
calculateScale();
|
|
11146
11469
|
}, [calculateScale]);
|
|
11147
|
-
(0,
|
|
11470
|
+
(0, import_react52.useEffect)(() => {
|
|
11148
11471
|
const handleResize = () => {
|
|
11149
11472
|
calculateScale();
|
|
11150
11473
|
};
|
|
11151
11474
|
window.addEventListener("resize", handleResize);
|
|
11152
11475
|
return () => window.removeEventListener("resize", handleResize);
|
|
11153
11476
|
}, [calculateScale]);
|
|
11154
|
-
(0,
|
|
11477
|
+
(0, import_react52.useEffect)(() => {
|
|
11155
11478
|
const handleKeyDown = (e) => {
|
|
11156
11479
|
if (e.key === "Escape") {
|
|
11157
11480
|
onClose();
|
|
@@ -11177,7 +11500,7 @@ var EnhancedImageViewer = ({
|
|
|
11177
11500
|
document.addEventListener("keydown", handleKeyDown);
|
|
11178
11501
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
11179
11502
|
}, [onClose, imageUrl, images, onIndexChange, propCurrentIndex]);
|
|
11180
|
-
const handleSwipeNavigation = (0,
|
|
11503
|
+
const handleSwipeNavigation = (0, import_react52.useCallback)(
|
|
11181
11504
|
(direction) => {
|
|
11182
11505
|
let currentIndex = propCurrentIndex !== void 0 ? propCurrentIndex : -1;
|
|
11183
11506
|
if (currentIndex === -1) {
|
|
@@ -11198,7 +11521,7 @@ var EnhancedImageViewer = ({
|
|
|
11198
11521
|
},
|
|
11199
11522
|
[propCurrentIndex, images, imageUrl, onIndexChange]
|
|
11200
11523
|
);
|
|
11201
|
-
const handleTouchStart = (0,
|
|
11524
|
+
const handleTouchStart = (0, import_react52.useCallback)(
|
|
11202
11525
|
(e) => {
|
|
11203
11526
|
const isAtInitialZoom = Math.abs(currentZoomScale - scale.initial) < 0.1;
|
|
11204
11527
|
if (!isAtInitialZoom) return;
|
|
@@ -11212,7 +11535,7 @@ var EnhancedImageViewer = ({
|
|
|
11212
11535
|
},
|
|
11213
11536
|
[currentZoomScale, scale.initial]
|
|
11214
11537
|
);
|
|
11215
|
-
const handleTouchEnd = (0,
|
|
11538
|
+
const handleTouchEnd = (0, import_react52.useCallback)(
|
|
11216
11539
|
(e) => {
|
|
11217
11540
|
if (!touchStartRef.current) return;
|
|
11218
11541
|
const touch = e.changedTouches[0];
|
|
@@ -11235,13 +11558,13 @@ var EnhancedImageViewer = ({
|
|
|
11235
11558
|
[handleSwipeNavigation]
|
|
11236
11559
|
);
|
|
11237
11560
|
if (!isMounted || !isClient) {
|
|
11238
|
-
return (0,
|
|
11239
|
-
/* @__PURE__ */ (0,
|
|
11561
|
+
return (0, import_react_dom3.createPortal)(
|
|
11562
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11240
11563
|
"div",
|
|
11241
11564
|
{
|
|
11242
11565
|
className: "fixed inset-0 bg-black flex items-center justify-center",
|
|
11243
11566
|
style: { zIndex: 999999 },
|
|
11244
|
-
children: /* @__PURE__ */ (0,
|
|
11567
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11245
11568
|
"div",
|
|
11246
11569
|
{
|
|
11247
11570
|
style: {
|
|
@@ -11256,8 +11579,8 @@ var EnhancedImageViewer = ({
|
|
|
11256
11579
|
document.body
|
|
11257
11580
|
);
|
|
11258
11581
|
}
|
|
11259
|
-
return (0,
|
|
11260
|
-
/* @__PURE__ */ (0,
|
|
11582
|
+
return (0, import_react_dom3.createPortal)(
|
|
11583
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
|
|
11261
11584
|
"div",
|
|
11262
11585
|
{
|
|
11263
11586
|
className: "fixed inset-0 bg-black flex items-center justify-center",
|
|
@@ -11266,7 +11589,7 @@ var EnhancedImageViewer = ({
|
|
|
11266
11589
|
"aria-modal": "true",
|
|
11267
11590
|
"aria-label": "Image viewer",
|
|
11268
11591
|
children: [
|
|
11269
|
-
/* @__PURE__ */ (0,
|
|
11592
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11270
11593
|
"button",
|
|
11271
11594
|
{
|
|
11272
11595
|
onClick: (e) => {
|
|
@@ -11292,10 +11615,10 @@ var EnhancedImageViewer = ({
|
|
|
11292
11615
|
touchAction: "manipulation",
|
|
11293
11616
|
marginBottom: "env(safe-area-inset-bottom, 0px)"
|
|
11294
11617
|
},
|
|
11295
|
-
children: /* @__PURE__ */ (0,
|
|
11618
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_lucide_react8.X, { className: "w-7 h-7", strokeWidth: 2.5 })
|
|
11296
11619
|
}
|
|
11297
11620
|
),
|
|
11298
|
-
/* @__PURE__ */ (0,
|
|
11621
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11299
11622
|
TransformWrapper,
|
|
11300
11623
|
{
|
|
11301
11624
|
initialScale: scale.initial,
|
|
@@ -11329,7 +11652,7 @@ var EnhancedImageViewer = ({
|
|
|
11329
11652
|
onTransformed: (ref) => {
|
|
11330
11653
|
setCurrentZoomScale(ref.state.scale);
|
|
11331
11654
|
},
|
|
11332
|
-
children: ({ zoomIn, zoomOut, resetTransform }) => /* @__PURE__ */ (0,
|
|
11655
|
+
children: ({ zoomIn, zoomOut, resetTransform }) => /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
|
|
11333
11656
|
"div",
|
|
11334
11657
|
{
|
|
11335
11658
|
style: {
|
|
@@ -11342,14 +11665,14 @@ var EnhancedImageViewer = ({
|
|
|
11342
11665
|
onTouchStart: handleTouchStart,
|
|
11343
11666
|
onTouchEnd: handleTouchEnd,
|
|
11344
11667
|
children: [
|
|
11345
|
-
/* @__PURE__ */ (0,
|
|
11668
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11346
11669
|
TransformComponent,
|
|
11347
11670
|
{
|
|
11348
11671
|
wrapperStyle: {
|
|
11349
11672
|
width: "100%",
|
|
11350
11673
|
height: "100%"
|
|
11351
11674
|
},
|
|
11352
|
-
children: /* @__PURE__ */ (0,
|
|
11675
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11353
11676
|
"div",
|
|
11354
11677
|
{
|
|
11355
11678
|
style: {
|
|
@@ -11360,7 +11683,7 @@ var EnhancedImageViewer = ({
|
|
|
11360
11683
|
alignItems: "center",
|
|
11361
11684
|
justifyContent: "center"
|
|
11362
11685
|
},
|
|
11363
|
-
children: /* @__PURE__ */ (0,
|
|
11686
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11364
11687
|
"img",
|
|
11365
11688
|
{
|
|
11366
11689
|
ref: imgRef,
|
|
@@ -11381,8 +11704,8 @@ var EnhancedImageViewer = ({
|
|
|
11381
11704
|
)
|
|
11382
11705
|
}
|
|
11383
11706
|
),
|
|
11384
|
-
/* @__PURE__ */ (0,
|
|
11385
|
-
/* @__PURE__ */ (0,
|
|
11707
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "fixed bottom-5 left-0 right-0 z-50", children: [
|
|
11708
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "flex justify-center gap-2", children: (() => {
|
|
11386
11709
|
let currentIndex = propCurrentIndex !== void 0 ? propCurrentIndex : -1;
|
|
11387
11710
|
if (currentIndex === -1) {
|
|
11388
11711
|
currentIndex = images.findIndex(
|
|
@@ -11415,8 +11738,8 @@ var EnhancedImageViewer = ({
|
|
|
11415
11738
|
};
|
|
11416
11739
|
const nextIndex = findNextAvailableIndex(currentIndex, 1);
|
|
11417
11740
|
const prevIndex = findNextAvailableIndex(currentIndex, -1);
|
|
11418
|
-
return /* @__PURE__ */ (0,
|
|
11419
|
-
/* @__PURE__ */ (0,
|
|
11741
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
|
|
11742
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11420
11743
|
"button",
|
|
11421
11744
|
{
|
|
11422
11745
|
onClick: () => {
|
|
@@ -11429,7 +11752,7 @@ var EnhancedImageViewer = ({
|
|
|
11429
11752
|
className: `w-10 h-10 rounded-full shadow-lg flex items-center justify-center transition-all duration-200 ${prevIndex === -1 ? "bg-white/40 text-black opacity-50 cursor-not-allowed" : "bg-white/90 hover:bg-white text-black"}`,
|
|
11430
11753
|
style: { touchAction: "manipulation" },
|
|
11431
11754
|
"aria-label": "Previous image",
|
|
11432
|
-
children: /* @__PURE__ */ (0,
|
|
11755
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11433
11756
|
"svg",
|
|
11434
11757
|
{
|
|
11435
11758
|
className: "w-4 h-4",
|
|
@@ -11437,7 +11760,7 @@ var EnhancedImageViewer = ({
|
|
|
11437
11760
|
stroke: "currentColor",
|
|
11438
11761
|
viewBox: "0 0 24 24",
|
|
11439
11762
|
"aria-hidden": "true",
|
|
11440
|
-
children: /* @__PURE__ */ (0,
|
|
11763
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11441
11764
|
"path",
|
|
11442
11765
|
{
|
|
11443
11766
|
strokeLinecap: "round",
|
|
@@ -11450,7 +11773,7 @@ var EnhancedImageViewer = ({
|
|
|
11450
11773
|
)
|
|
11451
11774
|
}
|
|
11452
11775
|
),
|
|
11453
|
-
/* @__PURE__ */ (0,
|
|
11776
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11454
11777
|
"button",
|
|
11455
11778
|
{
|
|
11456
11779
|
onClick: () => {
|
|
@@ -11463,7 +11786,7 @@ var EnhancedImageViewer = ({
|
|
|
11463
11786
|
className: `w-10 h-10 rounded-full shadow-lg flex items-center justify-center transition-all duration-200 ${nextIndex === -1 ? "bg-white/40 text-black opacity-50 cursor-not-allowed" : "bg-white/90 hover:bg-white text-black"}`,
|
|
11464
11787
|
style: { touchAction: "manipulation" },
|
|
11465
11788
|
"aria-label": "Next image",
|
|
11466
|
-
children: /* @__PURE__ */ (0,
|
|
11789
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11467
11790
|
"svg",
|
|
11468
11791
|
{
|
|
11469
11792
|
className: "w-4 h-4",
|
|
@@ -11471,7 +11794,7 @@ var EnhancedImageViewer = ({
|
|
|
11471
11794
|
stroke: "currentColor",
|
|
11472
11795
|
viewBox: "0 0 24 24",
|
|
11473
11796
|
"aria-hidden": "true",
|
|
11474
|
-
children: /* @__PURE__ */ (0,
|
|
11797
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11475
11798
|
"path",
|
|
11476
11799
|
{
|
|
11477
11800
|
strokeLinecap: "round",
|
|
@@ -11486,7 +11809,7 @@ var EnhancedImageViewer = ({
|
|
|
11486
11809
|
)
|
|
11487
11810
|
] });
|
|
11488
11811
|
})() }),
|
|
11489
|
-
/* @__PURE__ */ (0,
|
|
11812
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { style: { position: "fixed", bottom: 20, left: 24, zIndex: 10, marginBottom: "env(safe-area-inset-bottom, 0px)" }, className: "h-10 px-3 rounded-full bg-white/90 text-black text-sm font-medium flex items-center justify-center shadow-lg", children: (() => {
|
|
11490
11813
|
const total = Math.max(images.length, 1);
|
|
11491
11814
|
const current = propCurrentIndex !== void 0 ? Math.min(propCurrentIndex + 1, total) : 1;
|
|
11492
11815
|
return `${current} / ${total}`;
|
|
@@ -11498,7 +11821,7 @@ var EnhancedImageViewer = ({
|
|
|
11498
11821
|
},
|
|
11499
11822
|
`${scale.initial}-${scale.min}-${scale.max}`
|
|
11500
11823
|
),
|
|
11501
|
-
/* @__PURE__ */ (0,
|
|
11824
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11502
11825
|
"div",
|
|
11503
11826
|
{
|
|
11504
11827
|
className: "absolute inset-0 bg-black",
|
|
@@ -11517,7 +11840,7 @@ var EnhancedImageViewer = ({
|
|
|
11517
11840
|
};
|
|
11518
11841
|
|
|
11519
11842
|
// src/composed/zoom/ResponsiveZoom.tsx
|
|
11520
|
-
var
|
|
11843
|
+
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
11521
11844
|
function ResponsiveZoom({
|
|
11522
11845
|
imageIndex,
|
|
11523
11846
|
children,
|
|
@@ -11527,11 +11850,11 @@ function ResponsiveZoom({
|
|
|
11527
11850
|
imageUrl,
|
|
11528
11851
|
alt = "Product image"
|
|
11529
11852
|
}) {
|
|
11530
|
-
const [isTouchDevice, setIsTouchDevice] = (0,
|
|
11531
|
-
const [showEnhancedViewer, setShowEnhancedViewer] = (0,
|
|
11532
|
-
const [viewerIndex, setViewerIndex] = (0,
|
|
11533
|
-
const [currentImageUrl, setCurrentImageUrl] = (0,
|
|
11534
|
-
(0,
|
|
11853
|
+
const [isTouchDevice, setIsTouchDevice] = (0, import_react53.useState)(false);
|
|
11854
|
+
const [showEnhancedViewer, setShowEnhancedViewer] = (0, import_react53.useState)(false);
|
|
11855
|
+
const [viewerIndex, setViewerIndex] = (0, import_react53.useState)(0);
|
|
11856
|
+
const [currentImageUrl, setCurrentImageUrl] = (0, import_react53.useState)(imageUrl || "");
|
|
11857
|
+
(0, import_react53.useEffect)(() => {
|
|
11535
11858
|
const checkDeviceType = () => {
|
|
11536
11859
|
const hasTouch = "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
11537
11860
|
setIsTouchDevice(hasTouch);
|
|
@@ -11558,8 +11881,8 @@ function ResponsiveZoom({
|
|
|
11558
11881
|
}
|
|
11559
11882
|
}
|
|
11560
11883
|
};
|
|
11561
|
-
return /* @__PURE__ */ (0,
|
|
11562
|
-
isTouchDevice ? /* @__PURE__ */ (0,
|
|
11884
|
+
return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_jsx_runtime71.Fragment, { children: [
|
|
11885
|
+
isTouchDevice ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11563
11886
|
"div",
|
|
11564
11887
|
{
|
|
11565
11888
|
className,
|
|
@@ -11576,7 +11899,7 @@ function ResponsiveZoom({
|
|
|
11576
11899
|
},
|
|
11577
11900
|
children
|
|
11578
11901
|
}
|
|
11579
|
-
) : /* @__PURE__ */ (0,
|
|
11902
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11580
11903
|
ZoomOverlay,
|
|
11581
11904
|
{
|
|
11582
11905
|
imageIndex,
|
|
@@ -11587,7 +11910,7 @@ function ResponsiveZoom({
|
|
|
11587
11910
|
children
|
|
11588
11911
|
}
|
|
11589
11912
|
),
|
|
11590
|
-
showEnhancedViewer && isTouchDevice && currentImageUrl && /* @__PURE__ */ (0,
|
|
11913
|
+
showEnhancedViewer && isTouchDevice && currentImageUrl && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11591
11914
|
EnhancedImageViewer,
|
|
11592
11915
|
{
|
|
11593
11916
|
imageUrl: currentImageUrl,
|
|
@@ -11610,9 +11933,9 @@ function ResponsiveZoom({
|
|
|
11610
11933
|
}
|
|
11611
11934
|
|
|
11612
11935
|
// src/composed/carousels/MobileProductCarousel.tsx
|
|
11613
|
-
var
|
|
11614
|
-
var
|
|
11615
|
-
var MobileProductCarousel = (0,
|
|
11936
|
+
var import_react54 = require("react");
|
|
11937
|
+
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
11938
|
+
var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarousel2({
|
|
11616
11939
|
images,
|
|
11617
11940
|
currentIndex = 0,
|
|
11618
11941
|
onIndexChange,
|
|
@@ -11627,42 +11950,42 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11627
11950
|
mockupWidth,
|
|
11628
11951
|
onMockupUrlGenerated
|
|
11629
11952
|
}) {
|
|
11630
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
11631
|
-
const [touchStart, setTouchStart] = (0,
|
|
11953
|
+
const [activeIndex, setActiveIndex] = (0, import_react54.useState)(currentIndex);
|
|
11954
|
+
const [touchStart, setTouchStart] = (0, import_react54.useState)(
|
|
11632
11955
|
null
|
|
11633
11956
|
);
|
|
11634
|
-
const [touchEnd, setTouchEnd] = (0,
|
|
11957
|
+
const [touchEnd, setTouchEnd] = (0, import_react54.useState)(
|
|
11635
11958
|
null
|
|
11636
11959
|
);
|
|
11637
|
-
const [showImageViewer, setShowImageViewer] = (0,
|
|
11638
|
-
const [viewerKey, setViewerKey] = (0,
|
|
11639
|
-
const [isDragging, setIsDragging] = (0,
|
|
11640
|
-
const [dragOffset, setDragOffset] = (0,
|
|
11641
|
-
const [isTransitioning, setIsTransitioning] = (0,
|
|
11642
|
-
const [isHorizontalSwipe, setIsHorizontalSwipe] = (0,
|
|
11960
|
+
const [showImageViewer, setShowImageViewer] = (0, import_react54.useState)(false);
|
|
11961
|
+
const [viewerKey, setViewerKey] = (0, import_react54.useState)(0);
|
|
11962
|
+
const [isDragging, setIsDragging] = (0, import_react54.useState)(false);
|
|
11963
|
+
const [dragOffset, setDragOffset] = (0, import_react54.useState)(0);
|
|
11964
|
+
const [isTransitioning, setIsTransitioning] = (0, import_react54.useState)(false);
|
|
11965
|
+
const [isHorizontalSwipe, setIsHorizontalSwipe] = (0, import_react54.useState)(
|
|
11643
11966
|
null
|
|
11644
11967
|
);
|
|
11645
|
-
const [isPeeking, setIsPeeking] = (0,
|
|
11646
|
-
const [isPeekReturning, setIsPeekReturning] = (0,
|
|
11647
|
-
const carouselRef = (0,
|
|
11648
|
-
const indicatorRef = (0,
|
|
11649
|
-
const touchStartRef = (0,
|
|
11968
|
+
const [isPeeking, setIsPeeking] = (0, import_react54.useState)(false);
|
|
11969
|
+
const [isPeekReturning, setIsPeekReturning] = (0, import_react54.useState)(false);
|
|
11970
|
+
const carouselRef = (0, import_react54.useRef)(null);
|
|
11971
|
+
const indicatorRef = (0, import_react54.useRef)(null);
|
|
11972
|
+
const touchStartRef = (0, import_react54.useRef)(
|
|
11650
11973
|
null
|
|
11651
11974
|
);
|
|
11652
|
-
const horizontalGestureRef = (0,
|
|
11653
|
-
const hasShownPeekRef = (0,
|
|
11654
|
-
const hasSwipedThisSessionRef = (0,
|
|
11655
|
-
const generatedUrlsRef = (0,
|
|
11656
|
-
const prevArtworkSrcRef = (0,
|
|
11657
|
-
(0,
|
|
11975
|
+
const horizontalGestureRef = (0, import_react54.useRef)(false);
|
|
11976
|
+
const hasShownPeekRef = (0, import_react54.useRef)(false);
|
|
11977
|
+
const hasSwipedThisSessionRef = (0, import_react54.useRef)(false);
|
|
11978
|
+
const generatedUrlsRef = (0, import_react54.useRef)(/* @__PURE__ */ new Map());
|
|
11979
|
+
const prevArtworkSrcRef = (0, import_react54.useRef)(currentArtwork?.src);
|
|
11980
|
+
(0, import_react54.useEffect)(() => {
|
|
11658
11981
|
if (currentArtwork?.src !== prevArtworkSrcRef.current) {
|
|
11659
11982
|
generatedUrlsRef.current.clear();
|
|
11660
11983
|
prevArtworkSrcRef.current = currentArtwork?.src;
|
|
11661
11984
|
}
|
|
11662
11985
|
}, [currentArtwork?.src]);
|
|
11663
|
-
const onMockupUrlGeneratedRef = (0,
|
|
11986
|
+
const onMockupUrlGeneratedRef = (0, import_react54.useRef)(onMockupUrlGenerated);
|
|
11664
11987
|
onMockupUrlGeneratedRef.current = onMockupUrlGenerated;
|
|
11665
|
-
const handleUrlGenerated = (0,
|
|
11988
|
+
const handleUrlGenerated = (0, import_react54.useCallback)((mockupId, url) => {
|
|
11666
11989
|
generatedUrlsRef.current.set(mockupId, url);
|
|
11667
11990
|
onMockupUrlGeneratedRef.current?.(mockupId, url);
|
|
11668
11991
|
}, []);
|
|
@@ -11670,24 +11993,24 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11670
11993
|
const shouldHideDots = stickyHeroContext?.shouldHideDots ?? false;
|
|
11671
11994
|
const priorityContext = useMockupPriorityOptional();
|
|
11672
11995
|
const realtimeContext = useRealtimeOptional();
|
|
11673
|
-
const [urlUpdateCounter, setUrlUpdateCounter] = (0,
|
|
11674
|
-
(0,
|
|
11996
|
+
const [urlUpdateCounter, setUrlUpdateCounter] = (0, import_react54.useState)(0);
|
|
11997
|
+
(0, import_react54.useEffect)(() => {
|
|
11675
11998
|
if (!realtimeContext?.subscribeMockupResults) return;
|
|
11676
11999
|
const unsubscribe = realtimeContext.subscribeMockupResults(() => {
|
|
11677
12000
|
setUrlUpdateCounter((c) => c + 1);
|
|
11678
12001
|
});
|
|
11679
12002
|
return unsubscribe;
|
|
11680
12003
|
}, [realtimeContext?.subscribeMockupResults]);
|
|
11681
|
-
const mockupIds = (0,
|
|
12004
|
+
const mockupIds = (0, import_react54.useMemo)(() => {
|
|
11682
12005
|
return images.filter((img) => img.isRealMockup && img.mockupId).map((img) => img.mockupId);
|
|
11683
12006
|
}, [images]);
|
|
11684
|
-
const realtimeMockupUrls = (0,
|
|
12007
|
+
const realtimeMockupUrls = (0, import_react54.useMemo)(() => {
|
|
11685
12008
|
if (!realtimeContext?.getMockupUrls || mockupIds.length === 0) {
|
|
11686
12009
|
return {};
|
|
11687
12010
|
}
|
|
11688
12011
|
return realtimeContext.getMockupUrls(mockupIds);
|
|
11689
12012
|
}, [realtimeContext?.getMockupUrls, mockupIds, urlUpdateCounter]);
|
|
11690
|
-
const imagesWithRealtimeUrls = (0,
|
|
12013
|
+
const imagesWithRealtimeUrls = (0, import_react54.useMemo)(() => {
|
|
11691
12014
|
return images.map((img) => {
|
|
11692
12015
|
if (img.isRealMockup && img.mockupId && realtimeMockupUrls[img.mockupId]) {
|
|
11693
12016
|
return {
|
|
@@ -11699,10 +12022,10 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11699
12022
|
});
|
|
11700
12023
|
}, [images, realtimeMockupUrls]);
|
|
11701
12024
|
const minSwipeDistance = 50;
|
|
11702
|
-
(0,
|
|
12025
|
+
(0, import_react54.useEffect)(() => {
|
|
11703
12026
|
setActiveIndex(currentIndex);
|
|
11704
12027
|
}, [currentIndex]);
|
|
11705
|
-
(0,
|
|
12028
|
+
(0, import_react54.useEffect)(() => {
|
|
11706
12029
|
if (!priorityContext) return;
|
|
11707
12030
|
const realMockups = images.map((img, idx) => ({ img, originalIdx: idx })).filter(({ img }) => img.isRealMockup && img.mockupId);
|
|
11708
12031
|
const mockupIdsList = realMockups.map(({ img }) => img.mockupId);
|
|
@@ -11730,7 +12053,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11730
12053
|
priorityContext.clearMobileCarouselMode?.();
|
|
11731
12054
|
};
|
|
11732
12055
|
}, [priorityContext, activeIndex, images]);
|
|
11733
|
-
(0,
|
|
12056
|
+
(0, import_react54.useEffect)(() => {
|
|
11734
12057
|
const indicator = indicatorRef.current;
|
|
11735
12058
|
if (!indicator) return;
|
|
11736
12059
|
let ticking = false;
|
|
@@ -11771,7 +12094,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11771
12094
|
}, []);
|
|
11772
12095
|
const SWIPE_TRACKING_KEY = "carousel-swipe-tracking";
|
|
11773
12096
|
const PDP_VIEWS_BEFORE_PEEK = 10;
|
|
11774
|
-
const getSwipeTracking = (0,
|
|
12097
|
+
const getSwipeTracking = (0, import_react54.useCallback)(() => {
|
|
11775
12098
|
try {
|
|
11776
12099
|
const stored = localStorage.getItem(SWIPE_TRACKING_KEY);
|
|
11777
12100
|
if (stored) {
|
|
@@ -11781,7 +12104,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11781
12104
|
}
|
|
11782
12105
|
return { viewsWithoutSwipe: 0, hasEverSwiped: false };
|
|
11783
12106
|
}, []);
|
|
11784
|
-
const recordSwipe = (0,
|
|
12107
|
+
const recordSwipe = (0, import_react54.useCallback)(() => {
|
|
11785
12108
|
if (hasSwipedThisSessionRef.current) return;
|
|
11786
12109
|
hasSwipedThisSessionRef.current = true;
|
|
11787
12110
|
try {
|
|
@@ -11795,7 +12118,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11795
12118
|
} catch {
|
|
11796
12119
|
}
|
|
11797
12120
|
}, []);
|
|
11798
|
-
(0,
|
|
12121
|
+
(0, import_react54.useEffect)(() => {
|
|
11799
12122
|
if (!enablePeekAnimation || images.length <= 1) return;
|
|
11800
12123
|
const tracking = getSwipeTracking();
|
|
11801
12124
|
const newViewCount = tracking.viewsWithoutSwipe + 1;
|
|
@@ -11836,14 +12159,14 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11836
12159
|
clearTimeout(clearTimeout_);
|
|
11837
12160
|
};
|
|
11838
12161
|
}, [images.length, getSwipeTracking, enablePeekAnimation]);
|
|
11839
|
-
const wasTapRef = (0,
|
|
11840
|
-
const handleImageTap = (0,
|
|
12162
|
+
const wasTapRef = (0, import_react54.useRef)(false);
|
|
12163
|
+
const handleImageTap = (0, import_react54.useCallback)(() => {
|
|
11841
12164
|
if (!enableZoom) return;
|
|
11842
12165
|
setViewerKey((prev) => prev + 1);
|
|
11843
12166
|
setShowImageViewer(true);
|
|
11844
12167
|
onZoomChange?.(true);
|
|
11845
12168
|
}, [enableZoom, onZoomChange]);
|
|
11846
|
-
const calculateDragOffset = (0,
|
|
12169
|
+
const calculateDragOffset = (0, import_react54.useCallback)(
|
|
11847
12170
|
(startX, currentX, containerWidth) => {
|
|
11848
12171
|
const distance = startX - currentX;
|
|
11849
12172
|
const offsetPercent = distance / containerWidth * 100;
|
|
@@ -11868,7 +12191,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11868
12191
|
},
|
|
11869
12192
|
[activeIndex, images.length]
|
|
11870
12193
|
);
|
|
11871
|
-
const handleSwipeEnd = (0,
|
|
12194
|
+
const handleSwipeEnd = (0, import_react54.useCallback)(
|
|
11872
12195
|
(startX, endX, containerWidth) => {
|
|
11873
12196
|
const distance = startX - endX;
|
|
11874
12197
|
const distancePercent = Math.abs(distance) / containerWidth * 100;
|
|
@@ -11899,7 +12222,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11899
12222
|
},
|
|
11900
12223
|
[activeIndex, images.length, onIndexChange, recordSwipe]
|
|
11901
12224
|
);
|
|
11902
|
-
(0,
|
|
12225
|
+
(0, import_react54.useEffect)(() => {
|
|
11903
12226
|
const container = carouselRef.current;
|
|
11904
12227
|
if (!container) return;
|
|
11905
12228
|
const handleTouchStart = (e) => {
|
|
@@ -11988,11 +12311,11 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
11988
12311
|
handleSwipeEnd,
|
|
11989
12312
|
handleImageTap
|
|
11990
12313
|
]);
|
|
11991
|
-
const mouseStartRef = (0,
|
|
12314
|
+
const mouseStartRef = (0, import_react54.useRef)(
|
|
11992
12315
|
null
|
|
11993
12316
|
);
|
|
11994
|
-
const isMouseDraggingRef = (0,
|
|
11995
|
-
(0,
|
|
12317
|
+
const isMouseDraggingRef = (0, import_react54.useRef)(false);
|
|
12318
|
+
(0, import_react54.useEffect)(() => {
|
|
11996
12319
|
const container = carouselRef.current;
|
|
11997
12320
|
if (!container) return;
|
|
11998
12321
|
const handleMouseDown = (e) => {
|
|
@@ -12068,7 +12391,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12068
12391
|
container.removeEventListener("mouseleave", handleMouseLeave);
|
|
12069
12392
|
};
|
|
12070
12393
|
}, [calculateDragOffset, handleSwipeEnd, handleImageTap]);
|
|
12071
|
-
const goToSlide = (0,
|
|
12394
|
+
const goToSlide = (0, import_react54.useCallback)(
|
|
12072
12395
|
(index, withTransition = true) => {
|
|
12073
12396
|
if (withTransition) {
|
|
12074
12397
|
setIsTransitioning(true);
|
|
@@ -12086,16 +12409,16 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12086
12409
|
},
|
|
12087
12410
|
[onIndexChange]
|
|
12088
12411
|
);
|
|
12089
|
-
(0,
|
|
12412
|
+
(0, import_react54.useEffect)(() => {
|
|
12090
12413
|
if (stickyHeroContext?.setCarouselIndicator && images.length > 1) {
|
|
12091
|
-
const indicator = /* @__PURE__ */ (0,
|
|
12414
|
+
const indicator = /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12092
12415
|
"div",
|
|
12093
12416
|
{
|
|
12094
12417
|
className: "w-full",
|
|
12095
12418
|
role: "group",
|
|
12096
12419
|
"aria-label": "Product image navigation",
|
|
12097
|
-
children: /* @__PURE__ */ (0,
|
|
12098
|
-
/* @__PURE__ */ (0,
|
|
12420
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "relative h-1", children: [
|
|
12421
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "flex h-full", children: images.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12099
12422
|
"button",
|
|
12100
12423
|
{
|
|
12101
12424
|
onClick: () => goToSlide(index),
|
|
@@ -12105,7 +12428,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12105
12428
|
},
|
|
12106
12429
|
index
|
|
12107
12430
|
)) }),
|
|
12108
|
-
/* @__PURE__ */ (0,
|
|
12431
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12109
12432
|
"div",
|
|
12110
12433
|
{
|
|
12111
12434
|
className: "absolute top-0 h-full bg-primary transition-all duration-300 ease-out",
|
|
@@ -12128,10 +12451,10 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12128
12451
|
};
|
|
12129
12452
|
}, [activeIndex, images.length, goToSlide, stickyHeroContext]);
|
|
12130
12453
|
if (!images || images.length === 0) {
|
|
12131
|
-
return /* @__PURE__ */ (0,
|
|
12454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "w-full aspect-video bg-muted rounded-lg" });
|
|
12132
12455
|
}
|
|
12133
|
-
return /* @__PURE__ */ (0,
|
|
12134
|
-
/* @__PURE__ */ (0,
|
|
12456
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: `relative w-full h-full ${className}`, children: [
|
|
12457
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12135
12458
|
"div",
|
|
12136
12459
|
{
|
|
12137
12460
|
ref: carouselRef,
|
|
@@ -12149,7 +12472,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12149
12472
|
role: "region",
|
|
12150
12473
|
"aria-roledescription": "carousel",
|
|
12151
12474
|
"aria-label": "Product images",
|
|
12152
|
-
children: /* @__PURE__ */ (0,
|
|
12475
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12153
12476
|
"div",
|
|
12154
12477
|
{
|
|
12155
12478
|
className: `flex h-full ${isPeekReturning ? "transition-transform duration-300 ease-[cubic-bezier(0,0,0.2,1)]" : isPeeking ? "transition-transform duration-500 ease-[cubic-bezier(0.4,0,0.2,1)]" : isTransitioning || !isDragging ? "transition-transform duration-300 ease-[cubic-bezier(0.25,0.46,0.45,0.94)]" : ""}`,
|
|
@@ -12159,11 +12482,11 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12159
12482
|
children: images.map((image, index) => {
|
|
12160
12483
|
const DECODE_WINDOW = 1;
|
|
12161
12484
|
const isWithinDecodeWindow = Math.abs(index - activeIndex) <= DECODE_WINDOW;
|
|
12162
|
-
return /* @__PURE__ */ (0,
|
|
12485
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12163
12486
|
"div",
|
|
12164
12487
|
{
|
|
12165
12488
|
className: "w-full h-full flex-shrink-0 relative select-none",
|
|
12166
|
-
children: !isWithinDecodeWindow ? /* @__PURE__ */ (0,
|
|
12489
|
+
children: !isWithinDecodeWindow ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "w-full h-full bg-muted" }) : image.isPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "w-full h-full bg-muted-foreground/20 animate-pulse" }) : image.isRealMockup && currentArtwork ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12167
12490
|
HeroProductImage,
|
|
12168
12491
|
{
|
|
12169
12492
|
productId,
|
|
@@ -12175,7 +12498,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12175
12498
|
onUrlGenerated: image.mockupId ? (url) => handleUrlGenerated(image.mockupId, url) : void 0,
|
|
12176
12499
|
className: "w-full h-full object-cover cursor-pointer pointer-events-none"
|
|
12177
12500
|
}
|
|
12178
|
-
) : image.isRealMockup && !currentArtwork ? /* @__PURE__ */ (0,
|
|
12501
|
+
) : image.isRealMockup && !currentArtwork ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "w-full h-full bg-muted animate-pulse" }) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12179
12502
|
"img",
|
|
12180
12503
|
{
|
|
12181
12504
|
src: image.src,
|
|
@@ -12195,7 +12518,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12195
12518
|
)
|
|
12196
12519
|
}
|
|
12197
12520
|
),
|
|
12198
|
-
showIndicators && images.length > 1 && /* @__PURE__ */ (0,
|
|
12521
|
+
showIndicators && images.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12199
12522
|
"div",
|
|
12200
12523
|
{
|
|
12201
12524
|
ref: indicatorRef,
|
|
@@ -12203,8 +12526,8 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12203
12526
|
className: "relative z-20 w-full",
|
|
12204
12527
|
role: "group",
|
|
12205
12528
|
"aria-label": "Product image navigation",
|
|
12206
|
-
children: /* @__PURE__ */ (0,
|
|
12207
|
-
/* @__PURE__ */ (0,
|
|
12529
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "relative h-1", children: [
|
|
12530
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "flex h-full absolute inset-0", children: images.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12208
12531
|
"button",
|
|
12209
12532
|
{
|
|
12210
12533
|
onClick: () => goToSlide(index),
|
|
@@ -12214,7 +12537,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12214
12537
|
},
|
|
12215
12538
|
index
|
|
12216
12539
|
)) }),
|
|
12217
|
-
/* @__PURE__ */ (0,
|
|
12540
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12218
12541
|
"div",
|
|
12219
12542
|
{
|
|
12220
12543
|
className: `absolute top-0 h-full bg-foreground ${isPeekReturning ? "transition-all duration-300 ease-[cubic-bezier(0,0,0.2,1)]" : isPeeking ? "transition-all duration-500 ease-[cubic-bezier(0.4,0,0.2,1)]" : isDragging ? "" : "transition-all duration-300 ease-out"}`,
|
|
@@ -12249,7 +12572,7 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12249
12572
|
naturalHeight: img.naturalHeight
|
|
12250
12573
|
} : null;
|
|
12251
12574
|
}).filter((img) => img !== null);
|
|
12252
|
-
return /* @__PURE__ */ (0,
|
|
12575
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
12253
12576
|
EnhancedImageViewer,
|
|
12254
12577
|
{
|
|
12255
12578
|
imageUrl,
|
|
@@ -12288,8 +12611,8 @@ var MobileProductCarousel = (0, import_react53.memo)(function MobileProductCarou
|
|
|
12288
12611
|
});
|
|
12289
12612
|
|
|
12290
12613
|
// src/composed/carousels/HeroCarousel.tsx
|
|
12291
|
-
var
|
|
12292
|
-
var
|
|
12614
|
+
var import_react55 = require("react");
|
|
12615
|
+
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
12293
12616
|
function HeroCarousel({
|
|
12294
12617
|
images,
|
|
12295
12618
|
currentIndex = 0,
|
|
@@ -12299,16 +12622,16 @@ function HeroCarousel({
|
|
|
12299
12622
|
productId,
|
|
12300
12623
|
onImageTap
|
|
12301
12624
|
}) {
|
|
12302
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
12303
|
-
const containerRef = (0,
|
|
12304
|
-
const touchStartRef = (0,
|
|
12625
|
+
const [activeIndex, setActiveIndex] = (0, import_react55.useState)(currentIndex);
|
|
12626
|
+
const containerRef = (0, import_react55.useRef)(null);
|
|
12627
|
+
const touchStartRef = (0, import_react55.useRef)(
|
|
12305
12628
|
null
|
|
12306
12629
|
);
|
|
12307
|
-
const isSwipingRef = (0,
|
|
12308
|
-
(0,
|
|
12630
|
+
const isSwipingRef = (0, import_react55.useRef)(false);
|
|
12631
|
+
(0, import_react55.useEffect)(() => {
|
|
12309
12632
|
setActiveIndex(currentIndex);
|
|
12310
12633
|
}, [currentIndex]);
|
|
12311
|
-
const goToSlide = (0,
|
|
12634
|
+
const goToSlide = (0, import_react55.useCallback)(
|
|
12312
12635
|
(index) => {
|
|
12313
12636
|
const clampedIndex = Math.max(0, Math.min(images.length - 1, index));
|
|
12314
12637
|
setActiveIndex(clampedIndex);
|
|
@@ -12316,7 +12639,7 @@ function HeroCarousel({
|
|
|
12316
12639
|
},
|
|
12317
12640
|
[images.length, onIndexChange]
|
|
12318
12641
|
);
|
|
12319
|
-
(0,
|
|
12642
|
+
(0, import_react55.useEffect)(() => {
|
|
12320
12643
|
const container = containerRef.current;
|
|
12321
12644
|
if (!container) return;
|
|
12322
12645
|
const handleTouchStart = (e) => {
|
|
@@ -12368,9 +12691,9 @@ function HeroCarousel({
|
|
|
12368
12691
|
};
|
|
12369
12692
|
}, [activeIndex, images.length, goToSlide, onImageTap]);
|
|
12370
12693
|
if (!images || images.length === 0) {
|
|
12371
|
-
return /* @__PURE__ */ (0,
|
|
12694
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "w-full h-full bg-muted" });
|
|
12372
12695
|
}
|
|
12373
|
-
return /* @__PURE__ */ (0,
|
|
12696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
|
|
12374
12697
|
"div",
|
|
12375
12698
|
{
|
|
12376
12699
|
ref: containerRef,
|
|
@@ -12381,7 +12704,7 @@ function HeroCarousel({
|
|
|
12381
12704
|
overflow: "hidden"
|
|
12382
12705
|
},
|
|
12383
12706
|
children: [
|
|
12384
|
-
/* @__PURE__ */ (0,
|
|
12707
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12385
12708
|
"div",
|
|
12386
12709
|
{
|
|
12387
12710
|
className: "flex h-full transition-transform duration-300 ease-out",
|
|
@@ -12392,14 +12715,14 @@ function HeroCarousel({
|
|
|
12392
12715
|
backfaceVisibility: "hidden",
|
|
12393
12716
|
WebkitBackfaceVisibility: "hidden"
|
|
12394
12717
|
},
|
|
12395
|
-
children: images.map((image, index) => /* @__PURE__ */ (0,
|
|
12718
|
+
children: images.map((image, index) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12396
12719
|
"div",
|
|
12397
12720
|
{
|
|
12398
12721
|
className: "w-full h-full flex-shrink-0",
|
|
12399
12722
|
style: {
|
|
12400
12723
|
contain: "layout paint"
|
|
12401
12724
|
},
|
|
12402
|
-
children: image.isRealMockup && currentArtwork ? /* @__PURE__ */ (0,
|
|
12725
|
+
children: image.isRealMockup && currentArtwork ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12403
12726
|
HeroProductImage,
|
|
12404
12727
|
{
|
|
12405
12728
|
productId,
|
|
@@ -12408,7 +12731,7 @@ function HeroCarousel({
|
|
|
12408
12731
|
mockupId: image.mockupId,
|
|
12409
12732
|
className: "w-full h-full object-cover"
|
|
12410
12733
|
}
|
|
12411
|
-
) : /* @__PURE__ */ (0,
|
|
12734
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12412
12735
|
"img",
|
|
12413
12736
|
{
|
|
12414
12737
|
src: image.src,
|
|
@@ -12425,12 +12748,12 @@ function HeroCarousel({
|
|
|
12425
12748
|
))
|
|
12426
12749
|
}
|
|
12427
12750
|
),
|
|
12428
|
-
images.length > 1 && /* @__PURE__ */ (0,
|
|
12751
|
+
images.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12429
12752
|
"div",
|
|
12430
12753
|
{
|
|
12431
12754
|
className: "absolute bottom-4 left-0 right-0 flex justify-center gap-2 z-10",
|
|
12432
12755
|
style: { contain: "layout style" },
|
|
12433
|
-
children: images.map((_, index) => /* @__PURE__ */ (0,
|
|
12756
|
+
children: images.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12434
12757
|
"button",
|
|
12435
12758
|
{
|
|
12436
12759
|
onClick: () => goToSlide(index),
|
|
@@ -12447,8 +12770,8 @@ function HeroCarousel({
|
|
|
12447
12770
|
}
|
|
12448
12771
|
|
|
12449
12772
|
// src/composed/grids/MasonryGrid.tsx
|
|
12450
|
-
var
|
|
12451
|
-
var
|
|
12773
|
+
var import_react56 = require("react");
|
|
12774
|
+
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
12452
12775
|
var BREAKPOINTS = {
|
|
12453
12776
|
sm: 640,
|
|
12454
12777
|
md: 768,
|
|
@@ -12500,13 +12823,13 @@ function MasonryGrid({
|
|
|
12500
12823
|
className = "",
|
|
12501
12824
|
emptyContent
|
|
12502
12825
|
}) {
|
|
12503
|
-
const [columnCount, setColumnCount] = (0,
|
|
12826
|
+
const [columnCount, setColumnCount] = (0, import_react56.useState)(
|
|
12504
12827
|
() => typeof columns === "number" ? columns : getColumnCount(
|
|
12505
12828
|
typeof window !== "undefined" ? window.innerWidth : 1024,
|
|
12506
12829
|
columns
|
|
12507
12830
|
)
|
|
12508
12831
|
);
|
|
12509
|
-
(0,
|
|
12832
|
+
(0, import_react56.useEffect)(() => {
|
|
12510
12833
|
const updateColumnCount = () => {
|
|
12511
12834
|
setColumnCount(getColumnCount(window.innerWidth, columns));
|
|
12512
12835
|
};
|
|
@@ -12514,30 +12837,30 @@ function MasonryGrid({
|
|
|
12514
12837
|
window.addEventListener("resize", updateColumnCount);
|
|
12515
12838
|
return () => window.removeEventListener("resize", updateColumnCount);
|
|
12516
12839
|
}, [columns]);
|
|
12517
|
-
const distributedColumns = (0,
|
|
12840
|
+
const distributedColumns = (0, import_react56.useMemo)(
|
|
12518
12841
|
() => distributeItems(items, columnCount),
|
|
12519
12842
|
[items, columnCount]
|
|
12520
12843
|
);
|
|
12521
12844
|
if (items.length === 0) {
|
|
12522
12845
|
if (emptyContent) {
|
|
12523
|
-
return /* @__PURE__ */ (0,
|
|
12846
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(import_jsx_runtime74.Fragment, { children: emptyContent });
|
|
12524
12847
|
}
|
|
12525
12848
|
return null;
|
|
12526
12849
|
}
|
|
12527
|
-
return /* @__PURE__ */ (0,
|
|
12850
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12528
12851
|
"div",
|
|
12529
12852
|
{
|
|
12530
12853
|
className: `flex ${className}`,
|
|
12531
12854
|
style: { gap: `${gap}px` },
|
|
12532
12855
|
role: "list",
|
|
12533
|
-
children: distributedColumns.map((columnItems, columnIndex) => /* @__PURE__ */ (0,
|
|
12856
|
+
children: distributedColumns.map((columnItems, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12534
12857
|
"div",
|
|
12535
12858
|
{
|
|
12536
12859
|
className: "flex-1 flex flex-col",
|
|
12537
12860
|
style: { gap: `${gap}px` },
|
|
12538
12861
|
children: columnItems.map((item, itemIndex) => {
|
|
12539
12862
|
const originalIndex = itemIndex * columnCount + columnIndex;
|
|
12540
|
-
return /* @__PURE__ */ (0,
|
|
12863
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { role: "listitem", children: renderItem(item, originalIndex) }, originalIndex);
|
|
12541
12864
|
})
|
|
12542
12865
|
},
|
|
12543
12866
|
columnIndex
|
|
@@ -12550,7 +12873,7 @@ function MasonryGrid({
|
|
|
12550
12873
|
init_dev_warnings();
|
|
12551
12874
|
|
|
12552
12875
|
// src/layouts/hero-zoom/HeroZoomLayout.tsx
|
|
12553
|
-
var
|
|
12876
|
+
var import_react58 = require("react");
|
|
12554
12877
|
|
|
12555
12878
|
// src/layouts/hero-zoom/types.ts
|
|
12556
12879
|
var DEFAULT_HERO_ZOOM_CONFIG = {
|
|
@@ -12562,19 +12885,19 @@ var DEFAULT_HERO_ZOOM_CONFIG = {
|
|
|
12562
12885
|
};
|
|
12563
12886
|
|
|
12564
12887
|
// src/layouts/hero-zoom/useHeroZoomScales.ts
|
|
12565
|
-
var
|
|
12888
|
+
var import_react57 = require("react");
|
|
12566
12889
|
function useHeroZoomScales(config = {}) {
|
|
12567
12890
|
const { initialScale, accountForRetina, maxRetinaMultiplier } = {
|
|
12568
12891
|
...DEFAULT_HERO_ZOOM_CONFIG,
|
|
12569
12892
|
...config
|
|
12570
12893
|
};
|
|
12571
|
-
const [isHydrated, setIsHydrated] = (0,
|
|
12894
|
+
const [isHydrated, setIsHydrated] = (0, import_react57.useState)(false);
|
|
12572
12895
|
const ssrMultiplier = accountForRetina ? maxRetinaMultiplier : 2;
|
|
12573
|
-
const [scales, setScales] = (0,
|
|
12896
|
+
const [scales, setScales] = (0, import_react57.useState)(() => ({
|
|
12574
12897
|
visual: initialScale,
|
|
12575
12898
|
render: initialScale * ssrMultiplier
|
|
12576
12899
|
}));
|
|
12577
|
-
const calculateScales = (0,
|
|
12900
|
+
const calculateScales = (0, import_react57.useCallback)(() => {
|
|
12578
12901
|
const visualScale = Math.max(1, Math.min(4, initialScale));
|
|
12579
12902
|
let renderScale;
|
|
12580
12903
|
if (accountForRetina) {
|
|
@@ -12589,7 +12912,7 @@ function useHeroZoomScales(config = {}) {
|
|
|
12589
12912
|
renderScale = Math.max(1, Math.min(8, renderScale));
|
|
12590
12913
|
return { visual: visualScale, render: renderScale };
|
|
12591
12914
|
}, [initialScale, accountForRetina, maxRetinaMultiplier]);
|
|
12592
|
-
(0,
|
|
12915
|
+
(0, import_react57.useEffect)(() => {
|
|
12593
12916
|
const supportsScrollTimeline = CSS.supports(
|
|
12594
12917
|
"animation-timeline",
|
|
12595
12918
|
"scroll()"
|
|
@@ -12639,7 +12962,7 @@ function useHeroZoomScales(config = {}) {
|
|
|
12639
12962
|
}
|
|
12640
12963
|
|
|
12641
12964
|
// src/layouts/hero-zoom/HeroZoomLayout.tsx
|
|
12642
|
-
var
|
|
12965
|
+
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
12643
12966
|
function HeroZoomLayout({
|
|
12644
12967
|
config = {},
|
|
12645
12968
|
header,
|
|
@@ -12654,9 +12977,9 @@ function HeroZoomLayout({
|
|
|
12654
12977
|
};
|
|
12655
12978
|
const { aspectRatio, initialScale, headerHeight } = mergedConfig;
|
|
12656
12979
|
const { visual, render, isHydrated } = useHeroZoomScales(mergedConfig);
|
|
12657
|
-
const imageContainerRef = (0,
|
|
12658
|
-
const headerRef = (0,
|
|
12659
|
-
(0,
|
|
12980
|
+
const imageContainerRef = (0, import_react58.useRef)(null);
|
|
12981
|
+
const headerRef = (0, import_react58.useRef)(null);
|
|
12982
|
+
(0, import_react58.useEffect)(() => {
|
|
12660
12983
|
if (typeof window === "undefined") return;
|
|
12661
12984
|
const originalRestoration = "scrollRestoration" in history ? history.scrollRestoration : "auto";
|
|
12662
12985
|
if ("scrollRestoration" in history) {
|
|
@@ -12669,7 +12992,7 @@ function HeroZoomLayout({
|
|
|
12669
12992
|
}
|
|
12670
12993
|
};
|
|
12671
12994
|
}, []);
|
|
12672
|
-
(0,
|
|
12995
|
+
(0, import_react58.useEffect)(() => {
|
|
12673
12996
|
const supportsScrollTimeline = CSS.supports(
|
|
12674
12997
|
"animation-timeline",
|
|
12675
12998
|
"scroll()"
|
|
@@ -12798,7 +13121,7 @@ function HeroZoomLayout({
|
|
|
12798
13121
|
The drawer covers the hero completely, so let animation run continuously. */
|
|
12799
13122
|
}
|
|
12800
13123
|
`;
|
|
12801
|
-
return /* @__PURE__ */ (0,
|
|
13124
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(
|
|
12802
13125
|
"div",
|
|
12803
13126
|
{
|
|
12804
13127
|
className: `relative min-h-screen ${className}`,
|
|
@@ -12812,8 +13135,8 @@ function HeroZoomLayout({
|
|
|
12812
13135
|
"--hero-zoom-final-transform": 1 / activeRender
|
|
12813
13136
|
},
|
|
12814
13137
|
children: [
|
|
12815
|
-
/* @__PURE__ */ (0,
|
|
12816
|
-
/* @__PURE__ */ (0,
|
|
13138
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("style", { dangerouslySetInnerHTML: { __html: scopedStyles } }),
|
|
13139
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
12817
13140
|
"div",
|
|
12818
13141
|
{
|
|
12819
13142
|
style: {
|
|
@@ -12821,7 +13144,7 @@ function HeroZoomLayout({
|
|
|
12821
13144
|
}
|
|
12822
13145
|
}
|
|
12823
13146
|
),
|
|
12824
|
-
header && /* @__PURE__ */ (0,
|
|
13147
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
12825
13148
|
"div",
|
|
12826
13149
|
{
|
|
12827
13150
|
ref: headerRef,
|
|
@@ -12834,7 +13157,7 @@ function HeroZoomLayout({
|
|
|
12834
13157
|
children: header
|
|
12835
13158
|
}
|
|
12836
13159
|
),
|
|
12837
|
-
/* @__PURE__ */ (0,
|
|
13160
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
12838
13161
|
"div",
|
|
12839
13162
|
{
|
|
12840
13163
|
ref: imageContainerRef,
|
|
@@ -12854,15 +13177,15 @@ function HeroZoomLayout({
|
|
|
12854
13177
|
children: hero
|
|
12855
13178
|
}
|
|
12856
13179
|
),
|
|
12857
|
-
/* @__PURE__ */ (0,
|
|
13180
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "relative z-10", children })
|
|
12858
13181
|
]
|
|
12859
13182
|
}
|
|
12860
13183
|
);
|
|
12861
13184
|
}
|
|
12862
13185
|
|
|
12863
13186
|
// src/layouts/hero-zoom/HeroShrinkLayout.tsx
|
|
12864
|
-
var
|
|
12865
|
-
var
|
|
13187
|
+
var import_react59 = require("react");
|
|
13188
|
+
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
12866
13189
|
var DEFAULT_CONFIG = {
|
|
12867
13190
|
aspectRatio: 16 / 9,
|
|
12868
13191
|
initialHeightPercent: 70,
|
|
@@ -12882,13 +13205,13 @@ function HeroShrinkLayout({
|
|
|
12882
13205
|
...config
|
|
12883
13206
|
};
|
|
12884
13207
|
const { aspectRatio, initialHeightPercent, minHeightPercent, headerHeight } = mergedConfig;
|
|
12885
|
-
const heroRef = (0,
|
|
12886
|
-
const headerRef = (0,
|
|
12887
|
-
const [isClient, setIsClient] = (0,
|
|
12888
|
-
(0,
|
|
13208
|
+
const heroRef = (0, import_react59.useRef)(null);
|
|
13209
|
+
const headerRef = (0, import_react59.useRef)(null);
|
|
13210
|
+
const [isClient, setIsClient] = (0, import_react59.useState)(false);
|
|
13211
|
+
(0, import_react59.useEffect)(() => {
|
|
12889
13212
|
setIsClient(true);
|
|
12890
13213
|
}, []);
|
|
12891
|
-
(0,
|
|
13214
|
+
(0, import_react59.useEffect)(() => {
|
|
12892
13215
|
if (!isClient) return;
|
|
12893
13216
|
const supportsScrollTimeline = CSS.supports("animation-timeline", "scroll()");
|
|
12894
13217
|
if (supportsScrollTimeline) return;
|
|
@@ -12975,15 +13298,15 @@ function HeroShrinkLayout({
|
|
|
12975
13298
|
}
|
|
12976
13299
|
`;
|
|
12977
13300
|
const spacerHeight = `calc(${initialHeightPercent}svh + ${headerHeight}px)`;
|
|
12978
|
-
return /* @__PURE__ */ (0,
|
|
13301
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
12979
13302
|
"div",
|
|
12980
13303
|
{
|
|
12981
13304
|
className: `relative min-h-screen ${className}`,
|
|
12982
13305
|
style: { ...style, ...cssVars },
|
|
12983
13306
|
children: [
|
|
12984
|
-
/* @__PURE__ */ (0,
|
|
12985
|
-
/* @__PURE__ */ (0,
|
|
12986
|
-
header && /* @__PURE__ */ (0,
|
|
13307
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("style", { dangerouslySetInnerHTML: { __html: scopedStyles } }),
|
|
13308
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { style: { height: spacerHeight } }),
|
|
13309
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
12987
13310
|
"div",
|
|
12988
13311
|
{
|
|
12989
13312
|
ref: headerRef,
|
|
@@ -12992,7 +13315,7 @@ function HeroShrinkLayout({
|
|
|
12992
13315
|
children: header
|
|
12993
13316
|
}
|
|
12994
13317
|
),
|
|
12995
|
-
/* @__PURE__ */ (0,
|
|
13318
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
12996
13319
|
"div",
|
|
12997
13320
|
{
|
|
12998
13321
|
ref: heroRef,
|
|
@@ -13000,15 +13323,15 @@ function HeroShrinkLayout({
|
|
|
13000
13323
|
children: hero
|
|
13001
13324
|
}
|
|
13002
13325
|
),
|
|
13003
|
-
/* @__PURE__ */ (0,
|
|
13326
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "relative z-10 bg-background", children })
|
|
13004
13327
|
]
|
|
13005
13328
|
}
|
|
13006
13329
|
);
|
|
13007
13330
|
}
|
|
13008
13331
|
|
|
13009
13332
|
// src/layouts/pdp/ImageEdgeBlur.tsx
|
|
13010
|
-
var
|
|
13011
|
-
var
|
|
13333
|
+
var import_react60 = __toESM(require("react"), 1);
|
|
13334
|
+
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
13012
13335
|
var BLUR_CONFIG = {
|
|
13013
13336
|
blur: 24,
|
|
13014
13337
|
crossfade: 68
|
|
@@ -13032,7 +13355,7 @@ var BLUR_LAYERS = [
|
|
|
13032
13355
|
{ blur: Math.round(BLUR_CONFIG.blur * 0.5), zone: 0.6 },
|
|
13033
13356
|
{ blur: BLUR_CONFIG.blur, zone: 1 }
|
|
13034
13357
|
];
|
|
13035
|
-
var ImageEdgeBlur =
|
|
13358
|
+
var ImageEdgeBlur = import_react60.default.memo(
|
|
13036
13359
|
function ImageEdgeBlur2({
|
|
13037
13360
|
imageSrc,
|
|
13038
13361
|
imageCapInfo,
|
|
@@ -13063,7 +13386,7 @@ var ImageEdgeBlur = import_react59.default.memo(
|
|
|
13063
13386
|
viewportWidth / LAYOUT_CONFIG2.IMAGE.ASPECT_RATIO,
|
|
13064
13387
|
maxWidthPx / LAYOUT_CONFIG2.IMAGE.ASPECT_RATIO
|
|
13065
13388
|
);
|
|
13066
|
-
return /* @__PURE__ */ (0,
|
|
13389
|
+
return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
13067
13390
|
"div",
|
|
13068
13391
|
{
|
|
13069
13392
|
className: `absolute inset-0 pointer-events-none overflow-hidden ${className}`,
|
|
@@ -13071,7 +13394,7 @@ var ImageEdgeBlur = import_react59.default.memo(
|
|
|
13071
13394
|
children: BLUR_LAYERS.map((layer, index) => {
|
|
13072
13395
|
const layerMask = index === BLUR_LAYERS.length - 1 ? void 0 : `linear-gradient(to right, black 0%, black ${layer.zone * 100}%, transparent ${layer.zone * 100 + 10}%)`;
|
|
13073
13396
|
const blurScale = 1 + layer.blur * 3 / containerHeightPx;
|
|
13074
|
-
return /* @__PURE__ */ (0,
|
|
13397
|
+
return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
13075
13398
|
"img",
|
|
13076
13399
|
{
|
|
13077
13400
|
src: imageSrc,
|
|
@@ -13118,7 +13441,7 @@ var ImageEdgeBlur = import_react59.default.memo(
|
|
|
13118
13441
|
);
|
|
13119
13442
|
|
|
13120
13443
|
// src/layouts/pdp/PDPLayout.tsx
|
|
13121
|
-
var
|
|
13444
|
+
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
13122
13445
|
function PDPLayout({
|
|
13123
13446
|
renderHeroImage,
|
|
13124
13447
|
renderContent,
|
|
@@ -13146,15 +13469,15 @@ function PDPLayout({
|
|
|
13146
13469
|
isDesktop,
|
|
13147
13470
|
isWideMonitor: isWideMonitor2
|
|
13148
13471
|
};
|
|
13149
|
-
return /* @__PURE__ */ (0,
|
|
13150
|
-
(isDesktop === false || isDesktop === null) && /* @__PURE__ */ (0,
|
|
13151
|
-
renderMobileCarousel && /* @__PURE__ */ (0,
|
|
13152
|
-
/* @__PURE__ */ (0,
|
|
13472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `pdp-layout ${className}`, children: [
|
|
13473
|
+
(isDesktop === false || isDesktop === null) && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "md:hidden", children: [
|
|
13474
|
+
renderMobileCarousel && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "mobile-carousel-container", children: renderMobileCarousel({ images: carouselImages }) }),
|
|
13475
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "mobile-content p-4", children: renderContent(contentProps) })
|
|
13153
13476
|
] }),
|
|
13154
|
-
(isDesktop === true || isDesktop === null) && /* @__PURE__ */ (0,
|
|
13155
|
-
/* @__PURE__ */ (0,
|
|
13477
|
+
(isDesktop === true || isDesktop === null) && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "hidden md:block relative", children: [
|
|
13478
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "desktop-hero relative", children: [
|
|
13156
13479
|
renderHeroImage(heroProps),
|
|
13157
|
-
showEdgeBlur && blurImageSrc && isWideMonitor2 && /* @__PURE__ */ (0,
|
|
13480
|
+
showEdgeBlur && blurImageSrc && isWideMonitor2 && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
13158
13481
|
ImageEdgeBlur,
|
|
13159
13482
|
{
|
|
13160
13483
|
imageSrc: blurImageSrc,
|
|
@@ -13165,7 +13488,7 @@ function PDPLayout({
|
|
|
13165
13488
|
}
|
|
13166
13489
|
)
|
|
13167
13490
|
] }),
|
|
13168
|
-
/* @__PURE__ */ (0,
|
|
13491
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
13169
13492
|
"div",
|
|
13170
13493
|
{
|
|
13171
13494
|
className: "desktop-sidebar",
|
|
@@ -13182,8 +13505,8 @@ function PDPLayout({
|
|
|
13182
13505
|
}
|
|
13183
13506
|
|
|
13184
13507
|
// src/layouts/pdp/SimpleImageBlur.tsx
|
|
13185
|
-
var
|
|
13186
|
-
var
|
|
13508
|
+
var import_react61 = __toESM(require("react"), 1);
|
|
13509
|
+
var import_jsx_runtime79 = require("react/jsx-runtime");
|
|
13187
13510
|
var BLUR_CONFIG2 = {
|
|
13188
13511
|
blur: 24,
|
|
13189
13512
|
crossfade: 60
|
|
@@ -13206,7 +13529,7 @@ function getFadeInMask(crossfadeWidth) {
|
|
|
13206
13529
|
black ${crossfadeWidth + 10}px
|
|
13207
13530
|
)`;
|
|
13208
13531
|
}
|
|
13209
|
-
var SimpleImageBlur =
|
|
13532
|
+
var SimpleImageBlur = import_react61.default.memo(function SimpleImageBlur2({
|
|
13210
13533
|
imageSrc,
|
|
13211
13534
|
width,
|
|
13212
13535
|
height = "100%",
|
|
@@ -13216,7 +13539,7 @@ var SimpleImageBlur = import_react60.default.memo(function SimpleImageBlur2({
|
|
|
13216
13539
|
if (!imageSrc || width <= 0) return null;
|
|
13217
13540
|
const fadeInMask = getFadeInMask(BLUR_CONFIG2.crossfade);
|
|
13218
13541
|
const extendedWidth = width + BLUR_CONFIG2.blur * 2;
|
|
13219
|
-
return /* @__PURE__ */ (0,
|
|
13542
|
+
return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
13220
13543
|
"div",
|
|
13221
13544
|
{
|
|
13222
13545
|
className: `relative overflow-hidden ${className}`,
|
|
@@ -13229,7 +13552,7 @@ var SimpleImageBlur = import_react60.default.memo(function SimpleImageBlur2({
|
|
|
13229
13552
|
black 0%,
|
|
13230
13553
|
black ${layer.zone * 100}%,
|
|
13231
13554
|
transparent ${layer.zone * 100 + 10}%)`;
|
|
13232
|
-
return /* @__PURE__ */ (0,
|
|
13555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
13233
13556
|
"img",
|
|
13234
13557
|
{
|
|
13235
13558
|
src: imageSrc,
|
|
@@ -13259,8 +13582,8 @@ var SimpleImageBlur = import_react60.default.memo(function SimpleImageBlur2({
|
|
|
13259
13582
|
});
|
|
13260
13583
|
|
|
13261
13584
|
// src/layouts/pdp/EdgeBlurBox.tsx
|
|
13262
|
-
var
|
|
13263
|
-
var
|
|
13585
|
+
var import_react62 = __toESM(require("react"), 1);
|
|
13586
|
+
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
13264
13587
|
var BLUR_CONFIG3 = {
|
|
13265
13588
|
blur: 24,
|
|
13266
13589
|
crossfade: 60
|
|
@@ -13284,7 +13607,7 @@ function getFadeOutMask(crossfadeWidth) {
|
|
|
13284
13607
|
transparent 100%
|
|
13285
13608
|
)`;
|
|
13286
13609
|
}
|
|
13287
|
-
var EdgeBlurBox =
|
|
13610
|
+
var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
13288
13611
|
imageSrc,
|
|
13289
13612
|
width,
|
|
13290
13613
|
height = "100%",
|
|
@@ -13299,7 +13622,7 @@ var EdgeBlurBox = import_react61.default.memo(function EdgeBlurBox2({
|
|
|
13299
13622
|
const blurExtend = BLUR_CONFIG3.blur * 2;
|
|
13300
13623
|
const actualSharpWidth = sharpImageWidth ?? width + overlapLeft;
|
|
13301
13624
|
const hasOverlap = overlapLeft > 0;
|
|
13302
|
-
return /* @__PURE__ */ (0,
|
|
13625
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
|
|
13303
13626
|
"div",
|
|
13304
13627
|
{
|
|
13305
13628
|
className: `relative ${className}`,
|
|
@@ -13310,7 +13633,7 @@ var EdgeBlurBox = import_react61.default.memo(function EdgeBlurBox2({
|
|
|
13310
13633
|
overflow: hasOverlap ? "visible" : "hidden"
|
|
13311
13634
|
},
|
|
13312
13635
|
children: [
|
|
13313
|
-
/* @__PURE__ */ (0,
|
|
13636
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
13314
13637
|
"div",
|
|
13315
13638
|
{
|
|
13316
13639
|
style: {
|
|
@@ -13324,7 +13647,7 @@ var EdgeBlurBox = import_react61.default.memo(function EdgeBlurBox2({
|
|
|
13324
13647
|
transparent ${100 - (layer.zone * 100 + 10)}%,
|
|
13325
13648
|
black ${100 - layer.zone * 100}%,
|
|
13326
13649
|
black 100%)`;
|
|
13327
|
-
return /* @__PURE__ */ (0,
|
|
13650
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
13328
13651
|
"img",
|
|
13329
13652
|
{
|
|
13330
13653
|
src: imageSrc,
|
|
@@ -13352,7 +13675,7 @@ var EdgeBlurBox = import_react61.default.memo(function EdgeBlurBox2({
|
|
|
13352
13675
|
})
|
|
13353
13676
|
}
|
|
13354
13677
|
),
|
|
13355
|
-
/* @__PURE__ */ (0,
|
|
13678
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
13356
13679
|
"img",
|
|
13357
13680
|
{
|
|
13358
13681
|
src: imageSrc,
|
|
@@ -13380,8 +13703,8 @@ var EdgeBlurBox = import_react61.default.memo(function EdgeBlurBox2({
|
|
|
13380
13703
|
});
|
|
13381
13704
|
|
|
13382
13705
|
// src/layouts/pdp/ImageBlurExtension.tsx
|
|
13383
|
-
var
|
|
13384
|
-
var
|
|
13706
|
+
var import_react63 = __toESM(require("react"), 1);
|
|
13707
|
+
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
13385
13708
|
var BLUR_CONFIG4 = {
|
|
13386
13709
|
blur: 24,
|
|
13387
13710
|
crossfadeWidth: 80
|
|
@@ -13404,7 +13727,7 @@ function getFadeOutMask2(crossfadeWidth) {
|
|
|
13404
13727
|
transparent 100%
|
|
13405
13728
|
)`;
|
|
13406
13729
|
}
|
|
13407
|
-
var ImageBlurExtension =
|
|
13730
|
+
var ImageBlurExtension = import_react63.default.memo(function ImageBlurExtension2({
|
|
13408
13731
|
imageSrc,
|
|
13409
13732
|
width,
|
|
13410
13733
|
height,
|
|
@@ -13418,7 +13741,7 @@ var ImageBlurExtension = import_react62.default.memo(function ImageBlurExtension
|
|
|
13418
13741
|
const internalImageLeft = `calc(${heroImageLeft} - 100vw + ${width}px)`;
|
|
13419
13742
|
const fadeOutMask = getFadeOutMask2(crossfadeWidth);
|
|
13420
13743
|
const heightValue = typeof height === "number" ? `${height}px` : height;
|
|
13421
|
-
return /* @__PURE__ */ (0,
|
|
13744
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
|
|
13422
13745
|
"div",
|
|
13423
13746
|
{
|
|
13424
13747
|
className: `relative overflow-hidden ${className}`,
|
|
@@ -13427,7 +13750,7 @@ var ImageBlurExtension = import_react62.default.memo(function ImageBlurExtension
|
|
|
13427
13750
|
height: heightValue
|
|
13428
13751
|
},
|
|
13429
13752
|
children: [
|
|
13430
|
-
BLUR_LAYERS4.map((layer, index) => /* @__PURE__ */ (0,
|
|
13753
|
+
BLUR_LAYERS4.map((layer, index) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
13431
13754
|
"img",
|
|
13432
13755
|
{
|
|
13433
13756
|
src: imageSrc,
|
|
@@ -13451,7 +13774,7 @@ var ImageBlurExtension = import_react62.default.memo(function ImageBlurExtension
|
|
|
13451
13774
|
},
|
|
13452
13775
|
`blur-${index}`
|
|
13453
13776
|
)),
|
|
13454
|
-
/* @__PURE__ */ (0,
|
|
13777
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
13455
13778
|
"img",
|
|
13456
13779
|
{
|
|
13457
13780
|
src: imageSrc,
|
|
@@ -13479,39 +13802,39 @@ var ImageBlurExtension = import_react62.default.memo(function ImageBlurExtension
|
|
|
13479
13802
|
});
|
|
13480
13803
|
|
|
13481
13804
|
// src/design-system/ColorSwatch.tsx
|
|
13482
|
-
var
|
|
13805
|
+
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
13483
13806
|
function ColorTokenSwatch({ name, cssVar, className = "" }) {
|
|
13484
|
-
return /* @__PURE__ */ (0,
|
|
13485
|
-
/* @__PURE__ */ (0,
|
|
13807
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: `flex flex-col gap-1 ${className}`, children: [
|
|
13808
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
13486
13809
|
"div",
|
|
13487
13810
|
{
|
|
13488
13811
|
className: "h-16 w-full rounded-lg border border-border shadow-sm",
|
|
13489
13812
|
style: { backgroundColor: `var(${cssVar})` }
|
|
13490
13813
|
}
|
|
13491
13814
|
),
|
|
13492
|
-
/* @__PURE__ */ (0,
|
|
13493
|
-
/* @__PURE__ */ (0,
|
|
13815
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "text-sm font-medium text-foreground", children: name }),
|
|
13816
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("code", { className: "text-xs text-muted-foreground font-mono", children: cssVar })
|
|
13494
13817
|
] });
|
|
13495
13818
|
}
|
|
13496
13819
|
function ColorRow({ name, cssVar, description }) {
|
|
13497
|
-
return /* @__PURE__ */ (0,
|
|
13498
|
-
/* @__PURE__ */ (0,
|
|
13820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "flex items-center gap-4 py-2", children: [
|
|
13821
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
13499
13822
|
"div",
|
|
13500
13823
|
{
|
|
13501
13824
|
className: "h-10 w-10 rounded-lg border border-border shadow-sm flex-shrink-0",
|
|
13502
13825
|
style: { backgroundColor: `var(${cssVar})` }
|
|
13503
13826
|
}
|
|
13504
13827
|
),
|
|
13505
|
-
/* @__PURE__ */ (0,
|
|
13506
|
-
/* @__PURE__ */ (0,
|
|
13507
|
-
description && /* @__PURE__ */ (0,
|
|
13828
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
13829
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "text-sm font-medium text-foreground", children: name }),
|
|
13830
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "text-xs text-muted-foreground", children: description })
|
|
13508
13831
|
] }),
|
|
13509
|
-
/* @__PURE__ */ (0,
|
|
13832
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("code", { className: "text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded", children: cssVar })
|
|
13510
13833
|
] });
|
|
13511
13834
|
}
|
|
13512
13835
|
|
|
13513
13836
|
// src/design-system/ColorPalette.tsx
|
|
13514
|
-
var
|
|
13837
|
+
var import_jsx_runtime83 = require("react/jsx-runtime");
|
|
13515
13838
|
var COLOR_GROUPS = [
|
|
13516
13839
|
{
|
|
13517
13840
|
name: "Base",
|
|
@@ -13592,17 +13915,17 @@ var COLOR_GROUPS = [
|
|
|
13592
13915
|
}
|
|
13593
13916
|
];
|
|
13594
13917
|
function ColorPalette({ layout = "list", className = "" }) {
|
|
13595
|
-
return /* @__PURE__ */ (0,
|
|
13596
|
-
/* @__PURE__ */ (0,
|
|
13597
|
-
/* @__PURE__ */ (0,
|
|
13598
|
-
layout === "grid" ? /* @__PURE__ */ (0,
|
|
13918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: `space-y-8 ${className}`, children: COLOR_GROUPS.map((group) => /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("section", { children: [
|
|
13919
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("h3", { className: "text-lg font-semibold text-foreground mb-1", children: group.name }),
|
|
13920
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("p", { className: "text-sm text-muted-foreground mb-4", children: group.description }),
|
|
13921
|
+
layout === "grid" ? /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-4", children: group.colors.map((color) => /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
13599
13922
|
ColorTokenSwatch,
|
|
13600
13923
|
{
|
|
13601
13924
|
name: color.name,
|
|
13602
13925
|
cssVar: color.cssVar
|
|
13603
13926
|
},
|
|
13604
13927
|
color.cssVar
|
|
13605
|
-
)) }) : /* @__PURE__ */ (0,
|
|
13928
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "bg-card rounded-lg border border-border p-4 divide-y divide-border", children: group.colors.map((color) => /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
13606
13929
|
ColorRow,
|
|
13607
13930
|
{
|
|
13608
13931
|
name: color.name,
|
|
@@ -13615,7 +13938,7 @@ function ColorPalette({ layout = "list", className = "" }) {
|
|
|
13615
13938
|
}
|
|
13616
13939
|
|
|
13617
13940
|
// src/design-system/TypographyScale.tsx
|
|
13618
|
-
var
|
|
13941
|
+
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
13619
13942
|
var FONT_SAMPLES = [
|
|
13620
13943
|
{
|
|
13621
13944
|
name: "Heading",
|
|
@@ -13649,14 +13972,14 @@ var FONT_SAMPLES = [
|
|
|
13649
13972
|
}
|
|
13650
13973
|
];
|
|
13651
13974
|
function TypographyScale({ className = "" }) {
|
|
13652
|
-
return /* @__PURE__ */ (0,
|
|
13653
|
-
/* @__PURE__ */ (0,
|
|
13654
|
-
/* @__PURE__ */ (0,
|
|
13655
|
-
/* @__PURE__ */ (0,
|
|
13975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: `space-y-8 ${className}`, children: FONT_SAMPLES.map((font) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("section", { className: "bg-card rounded-lg border border-border p-6", children: [
|
|
13976
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
13977
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("h3", { className: "text-lg font-semibold text-foreground", children: font.name }),
|
|
13978
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("code", { className: "text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded", children: font.cssVar })
|
|
13656
13979
|
] }),
|
|
13657
|
-
/* @__PURE__ */ (0,
|
|
13658
|
-
/* @__PURE__ */ (0,
|
|
13659
|
-
/* @__PURE__ */ (0,
|
|
13980
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "space-y-4", children: font.sizes.map((size) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "flex items-baseline gap-4", children: [
|
|
13981
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-xs text-muted-foreground w-20 flex-shrink-0", children: size }),
|
|
13982
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
13660
13983
|
"p",
|
|
13661
13984
|
{
|
|
13662
13985
|
className: `${size} text-foreground`,
|
|
@@ -13675,8 +13998,8 @@ var RADIUS_SAMPLES = [
|
|
|
13675
13998
|
{ name: "Full", value: "9999px" }
|
|
13676
13999
|
];
|
|
13677
14000
|
function RadiusScale({ className = "" }) {
|
|
13678
|
-
return /* @__PURE__ */ (0,
|
|
13679
|
-
/* @__PURE__ */ (0,
|
|
14001
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: `space-y-4 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "grid grid-cols-5 gap-4", children: RADIUS_SAMPLES.map((radius) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "flex flex-col items-center gap-2", children: [
|
|
14002
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
13680
14003
|
"div",
|
|
13681
14004
|
{
|
|
13682
14005
|
className: "h-16 w-16 bg-primary",
|
|
@@ -13685,13 +14008,13 @@ function RadiusScale({ className = "" }) {
|
|
|
13685
14008
|
}
|
|
13686
14009
|
}
|
|
13687
14010
|
),
|
|
13688
|
-
/* @__PURE__ */ (0,
|
|
13689
|
-
/* @__PURE__ */ (0,
|
|
14011
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-sm font-medium text-foreground", children: radius.name }),
|
|
14012
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("code", { className: "text-xs text-muted-foreground font-mono", children: radius.cssVar || radius.value })
|
|
13690
14013
|
] }, radius.name)) }) });
|
|
13691
14014
|
}
|
|
13692
14015
|
|
|
13693
14016
|
// src/design-system/ThemeSwitcher.tsx
|
|
13694
|
-
var
|
|
14017
|
+
var import_react64 = require("react");
|
|
13695
14018
|
|
|
13696
14019
|
// src/themes/types.ts
|
|
13697
14020
|
var RADIUS_PRESETS = {
|
|
@@ -14859,7 +15182,7 @@ function applyTheme(config) {
|
|
|
14859
15182
|
}
|
|
14860
15183
|
|
|
14861
15184
|
// src/design-system/ThemeSwitcher.tsx
|
|
14862
|
-
var
|
|
15185
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
14863
15186
|
function readThemeFromDOM() {
|
|
14864
15187
|
if (typeof document === "undefined") {
|
|
14865
15188
|
return { themeName: "Linear", isDark: false };
|
|
@@ -14877,10 +15200,10 @@ function readThemeFromDOM() {
|
|
|
14877
15200
|
return { themeName: "Linear", isDark: dark };
|
|
14878
15201
|
}
|
|
14879
15202
|
function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
14880
|
-
const [currentTheme, setCurrentTheme] = (0,
|
|
14881
|
-
const [isDark, setIsDark] = (0,
|
|
14882
|
-
const [isOpen, setIsOpen] = (0,
|
|
14883
|
-
(0,
|
|
15203
|
+
const [currentTheme, setCurrentTheme] = (0, import_react64.useState)("Linear");
|
|
15204
|
+
const [isDark, setIsDark] = (0, import_react64.useState)(false);
|
|
15205
|
+
const [isOpen, setIsOpen] = (0, import_react64.useState)(false);
|
|
15206
|
+
(0, import_react64.useEffect)(() => {
|
|
14884
15207
|
const { themeName, isDark: dark } = readThemeFromDOM();
|
|
14885
15208
|
setCurrentTheme(themeName);
|
|
14886
15209
|
setIsDark(dark);
|
|
@@ -14919,61 +15242,61 @@ function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
|
14919
15242
|
applyTheme(config);
|
|
14920
15243
|
};
|
|
14921
15244
|
const themes = showBaseThemesOnly ? baseThemes : baseThemes;
|
|
14922
|
-
return /* @__PURE__ */ (0,
|
|
14923
|
-
/* @__PURE__ */ (0,
|
|
14924
|
-
/* @__PURE__ */ (0,
|
|
15245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: `flex items-center gap-3 ${className}`, children: [
|
|
15246
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "relative", children: [
|
|
15247
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
|
|
14925
15248
|
"button",
|
|
14926
15249
|
{
|
|
14927
15250
|
onClick: () => setIsOpen(!isOpen),
|
|
14928
15251
|
className: "flex items-center gap-2 px-4 py-2 bg-card border border-border rounded-lg hover:bg-muted transition-colors text-foreground",
|
|
14929
15252
|
children: [
|
|
14930
|
-
/* @__PURE__ */ (0,
|
|
14931
|
-
/* @__PURE__ */ (0,
|
|
14932
|
-
/* @__PURE__ */ (0,
|
|
15253
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" }) }),
|
|
15254
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "font-medium", children: currentTheme }),
|
|
15255
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("svg", { className: `w-4 h-4 transition-transform ${isOpen ? "rotate-180" : ""}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })
|
|
14933
15256
|
]
|
|
14934
15257
|
}
|
|
14935
15258
|
),
|
|
14936
|
-
isOpen && /* @__PURE__ */ (0,
|
|
14937
|
-
/* @__PURE__ */ (0,
|
|
15259
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
15260
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
14938
15261
|
"div",
|
|
14939
15262
|
{
|
|
14940
15263
|
className: "fixed inset-0 z-40",
|
|
14941
15264
|
onClick: () => setIsOpen(false)
|
|
14942
15265
|
}
|
|
14943
15266
|
),
|
|
14944
|
-
/* @__PURE__ */ (0,
|
|
15267
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "absolute top-full left-0 mt-2 w-56 max-h-80 overflow-auto bg-card border border-border rounded-lg shadow-lg z-50", children: themes.map((theme) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
|
|
14945
15268
|
"button",
|
|
14946
15269
|
{
|
|
14947
15270
|
onClick: () => handleThemeSelect(theme.name),
|
|
14948
15271
|
className: `w-full px-4 py-2 text-left hover:bg-muted transition-colors flex items-center gap-3 ${currentTheme === theme.name ? "bg-muted" : ""}`,
|
|
14949
15272
|
children: [
|
|
14950
|
-
/* @__PURE__ */ (0,
|
|
15273
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
14951
15274
|
"div",
|
|
14952
15275
|
{
|
|
14953
15276
|
className: "w-4 h-4 rounded-full border border-border",
|
|
14954
15277
|
style: { backgroundColor: theme.primaryColor || "#888" }
|
|
14955
15278
|
}
|
|
14956
15279
|
),
|
|
14957
|
-
/* @__PURE__ */ (0,
|
|
14958
|
-
currentTheme === theme.name && /* @__PURE__ */ (0,
|
|
15280
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "text-foreground", children: theme.name }),
|
|
15281
|
+
currentTheme === theme.name && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("svg", { className: "w-4 h-4 ml-auto text-primary", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }) })
|
|
14959
15282
|
]
|
|
14960
15283
|
},
|
|
14961
15284
|
theme.name
|
|
14962
15285
|
)) })
|
|
14963
15286
|
] })
|
|
14964
15287
|
] }),
|
|
14965
|
-
/* @__PURE__ */ (0,
|
|
15288
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
|
|
14966
15289
|
"button",
|
|
14967
15290
|
{
|
|
14968
15291
|
onClick: handleDarkModeToggle,
|
|
14969
15292
|
className: "flex items-center gap-2 px-4 py-2 bg-card border border-border rounded-lg hover:bg-muted transition-colors text-foreground",
|
|
14970
15293
|
title: `Switch to ${isDark ? "light" : "dark"} mode`,
|
|
14971
15294
|
children: [
|
|
14972
|
-
isDark ? /* @__PURE__ */ (0,
|
|
14973
|
-
/* @__PURE__ */ (0,
|
|
14974
|
-
/* @__PURE__ */ (0,
|
|
14975
|
-
] }) : /* @__PURE__ */ (0,
|
|
14976
|
-
/* @__PURE__ */ (0,
|
|
15295
|
+
isDark ? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: [
|
|
15296
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("circle", { cx: "12", cy: "12", r: "5" }),
|
|
15297
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("path", { d: "M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" })
|
|
15298
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) }),
|
|
15299
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "text-sm", children: isDark ? "Light" : "Dark" })
|
|
14977
15300
|
]
|
|
14978
15301
|
}
|
|
14979
15302
|
)
|
|
@@ -14981,7 +15304,7 @@ function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
|
14981
15304
|
}
|
|
14982
15305
|
|
|
14983
15306
|
// src/design-system/DesignSystemPage.tsx
|
|
14984
|
-
var
|
|
15307
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
14985
15308
|
function DesignSystemPage({
|
|
14986
15309
|
showThemeSwitcher = true,
|
|
14987
15310
|
showColors = true,
|
|
@@ -14991,29 +15314,29 @@ function DesignSystemPage({
|
|
|
14991
15314
|
colorLayout = "list",
|
|
14992
15315
|
className = ""
|
|
14993
15316
|
}) {
|
|
14994
|
-
return /* @__PURE__ */ (0,
|
|
14995
|
-
/* @__PURE__ */ (0,
|
|
14996
|
-
/* @__PURE__ */ (0,
|
|
14997
|
-
/* @__PURE__ */ (0,
|
|
14998
|
-
/* @__PURE__ */ (0,
|
|
15317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: `max-w-4xl mx-auto px-4 py-8 ${className}`, children: [
|
|
15318
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("header", { className: "mb-12", children: /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-4", children: [
|
|
15319
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { children: [
|
|
15320
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("h1", { className: "text-4xl font-bold text-foreground mb-2", children: "Design System" }),
|
|
15321
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { className: "text-lg text-muted-foreground", children: "Visual reference for theme tokens and styles" })
|
|
14999
15322
|
] }),
|
|
15000
|
-
showThemeSwitcher && /* @__PURE__ */ (0,
|
|
15323
|
+
showThemeSwitcher && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(ThemeSwitcher, {})
|
|
15001
15324
|
] }) }),
|
|
15002
|
-
showColors && /* @__PURE__ */ (0,
|
|
15003
|
-
/* @__PURE__ */ (0,
|
|
15004
|
-
/* @__PURE__ */ (0,
|
|
15325
|
+
showColors && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("section", { className: "mb-16", children: [
|
|
15326
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Color Palette" }),
|
|
15327
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(ColorPalette, { layout: colorLayout })
|
|
15005
15328
|
] }),
|
|
15006
|
-
showTypography && /* @__PURE__ */ (0,
|
|
15007
|
-
/* @__PURE__ */ (0,
|
|
15008
|
-
/* @__PURE__ */ (0,
|
|
15329
|
+
showTypography && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("section", { className: "mb-16", children: [
|
|
15330
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Typography" }),
|
|
15331
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(TypographyScale, {})
|
|
15009
15332
|
] }),
|
|
15010
|
-
showRadius && /* @__PURE__ */ (0,
|
|
15011
|
-
/* @__PURE__ */ (0,
|
|
15012
|
-
/* @__PURE__ */ (0,
|
|
15333
|
+
showRadius && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("section", { className: "mb-16", children: [
|
|
15334
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Border Radius" }),
|
|
15335
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(RadiusScale, {})
|
|
15013
15336
|
] }),
|
|
15014
|
-
showSpacing && /* @__PURE__ */ (0,
|
|
15015
|
-
/* @__PURE__ */ (0,
|
|
15016
|
-
/* @__PURE__ */ (0,
|
|
15337
|
+
showSpacing && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("section", { className: "mb-16", children: [
|
|
15338
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Spacing Scale" }),
|
|
15339
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(SpacingScale, {})
|
|
15017
15340
|
] })
|
|
15018
15341
|
] });
|
|
15019
15342
|
}
|
|
@@ -15028,31 +15351,31 @@ function SpacingScale() {
|
|
|
15028
15351
|
{ name: "12", value: "3rem" },
|
|
15029
15352
|
{ name: "16", value: "4rem" }
|
|
15030
15353
|
];
|
|
15031
|
-
return /* @__PURE__ */ (0,
|
|
15032
|
-
/* @__PURE__ */ (0,
|
|
15033
|
-
/* @__PURE__ */ (0,
|
|
15354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "space-y-2", children: spaces.map((space) => /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "flex items-center gap-4", children: [
|
|
15355
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("code", { className: "text-xs text-muted-foreground font-mono w-8", children: space.name }),
|
|
15356
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
15034
15357
|
"div",
|
|
15035
15358
|
{
|
|
15036
15359
|
className: "h-4 bg-primary rounded",
|
|
15037
15360
|
style: { width: space.value }
|
|
15038
15361
|
}
|
|
15039
15362
|
),
|
|
15040
|
-
/* @__PURE__ */ (0,
|
|
15363
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "text-sm text-muted-foreground", children: space.value })
|
|
15041
15364
|
] }, space.name)) });
|
|
15042
15365
|
}
|
|
15043
15366
|
|
|
15044
15367
|
// src/personalization/PersonalizationProvider.tsx
|
|
15045
|
-
var
|
|
15368
|
+
var import_react67 = __toESM(require("react"), 1);
|
|
15046
15369
|
|
|
15047
15370
|
// src/personalization/PersonalizationContext.ts
|
|
15048
|
-
var
|
|
15049
|
-
var PersonalizationContext = (0,
|
|
15371
|
+
var import_react65 = require("react");
|
|
15372
|
+
var PersonalizationContext = (0, import_react65.createContext)(null);
|
|
15050
15373
|
function usePersonalizationContext() {
|
|
15051
|
-
return (0,
|
|
15374
|
+
return (0, import_react65.useContext)(PersonalizationContext);
|
|
15052
15375
|
}
|
|
15053
15376
|
|
|
15054
15377
|
// src/personalization/utils.ts
|
|
15055
|
-
var
|
|
15378
|
+
var import_react66 = require("react");
|
|
15056
15379
|
function normalizeHex(color) {
|
|
15057
15380
|
let hex = color.trim().toUpperCase();
|
|
15058
15381
|
if (hex.length === 4 && hex.startsWith("#")) {
|
|
@@ -15073,8 +15396,8 @@ function isValidImageUrl(url) {
|
|
|
15073
15396
|
}
|
|
15074
15397
|
}
|
|
15075
15398
|
function useDebouncedValue(value, delay) {
|
|
15076
|
-
const [debounced, setDebounced] = (0,
|
|
15077
|
-
(0,
|
|
15399
|
+
const [debounced, setDebounced] = (0, import_react66.useState)(value);
|
|
15400
|
+
(0, import_react66.useEffect)(() => {
|
|
15078
15401
|
const timer = setTimeout(() => setDebounced(value), delay);
|
|
15079
15402
|
return () => clearTimeout(timer);
|
|
15080
15403
|
}, [value, delay]);
|
|
@@ -15095,18 +15418,18 @@ function scrollInputAboveKeyboard(input) {
|
|
|
15095
15418
|
}
|
|
15096
15419
|
|
|
15097
15420
|
// src/personalization/PersonalizationProvider.tsx
|
|
15098
|
-
var
|
|
15421
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
15099
15422
|
function createBridgeFromCanvas(canvasModule) {
|
|
15100
15423
|
const { useEditor, useCommands, useImageBinding } = canvasModule;
|
|
15101
15424
|
function TextBinder({ name, value }) {
|
|
15102
15425
|
const { elements } = useEditor();
|
|
15103
15426
|
const { executeElementUpdate } = useCommands();
|
|
15104
|
-
const elementsRef =
|
|
15427
|
+
const elementsRef = import_react67.default.useRef(elements);
|
|
15105
15428
|
elementsRef.current = elements;
|
|
15106
|
-
const executeRef =
|
|
15429
|
+
const executeRef = import_react67.default.useRef(executeElementUpdate);
|
|
15107
15430
|
executeRef.current = executeElementUpdate;
|
|
15108
|
-
const hasUserInput =
|
|
15109
|
-
|
|
15431
|
+
const hasUserInput = import_react67.default.useRef(false);
|
|
15432
|
+
import_react67.default.useEffect(() => {
|
|
15110
15433
|
if (value == null) return;
|
|
15111
15434
|
if (value === "" && !hasUserInput.current) return;
|
|
15112
15435
|
hasUserInput.current = true;
|
|
@@ -15124,12 +15447,12 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
15124
15447
|
function ColorBinder({ originalColor, newColor }) {
|
|
15125
15448
|
const { elements } = useEditor();
|
|
15126
15449
|
const { executeElementUpdate } = useCommands();
|
|
15127
|
-
const elementsRef =
|
|
15450
|
+
const elementsRef = import_react67.default.useRef(elements);
|
|
15128
15451
|
elementsRef.current = elements;
|
|
15129
|
-
const executeRef =
|
|
15452
|
+
const executeRef = import_react67.default.useRef(executeElementUpdate);
|
|
15130
15453
|
executeRef.current = executeElementUpdate;
|
|
15131
|
-
const appliedColorRef =
|
|
15132
|
-
|
|
15454
|
+
const appliedColorRef = import_react67.default.useRef(normalizeHex(originalColor));
|
|
15455
|
+
import_react67.default.useEffect(() => {
|
|
15133
15456
|
const normalizedNew = normalizeHex(newColor);
|
|
15134
15457
|
if (normalizedNew === appliedColorRef.current) return;
|
|
15135
15458
|
const matchColor = appliedColorRef.current;
|
|
@@ -15169,11 +15492,11 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
15169
15492
|
}
|
|
15170
15493
|
function ImageBinder({ name, value, fit = "cover" }) {
|
|
15171
15494
|
const { setImageUrl } = useImageBinding(name, { fit });
|
|
15172
|
-
const hasUserInput =
|
|
15495
|
+
const hasUserInput = import_react67.default.useRef(false);
|
|
15173
15496
|
const debouncedValue = useDebouncedValue(value, 500);
|
|
15174
|
-
const setImageUrlRef =
|
|
15497
|
+
const setImageUrlRef = import_react67.default.useRef(setImageUrl);
|
|
15175
15498
|
setImageUrlRef.current = setImageUrl;
|
|
15176
|
-
|
|
15499
|
+
import_react67.default.useEffect(() => {
|
|
15177
15500
|
if (debouncedValue == null) return;
|
|
15178
15501
|
if (debouncedValue === "" && !hasUserInput.current) return;
|
|
15179
15502
|
hasUserInput.current = true;
|
|
@@ -15183,15 +15506,15 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
15183
15506
|
return null;
|
|
15184
15507
|
}
|
|
15185
15508
|
return function PersonalizationBridge({ fields = [], values = {} } = {}) {
|
|
15186
|
-
return /* @__PURE__ */ (0,
|
|
15509
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(import_jsx_runtime87.Fragment, { children: fields.map((field) => {
|
|
15187
15510
|
if (field.type === "text") {
|
|
15188
|
-
return /* @__PURE__ */ (0,
|
|
15511
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(TextBinder, { name: field.name, value: values[field.name] ?? "" }, `text-${field.name}`);
|
|
15189
15512
|
}
|
|
15190
15513
|
if (field.type === "color") {
|
|
15191
|
-
return /* @__PURE__ */ (0,
|
|
15514
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ColorBinder, { originalColor: field.color, newColor: values[field.color] ?? field.color }, `color-${field.color}`);
|
|
15192
15515
|
}
|
|
15193
15516
|
if (field.type === "image") {
|
|
15194
|
-
return /* @__PURE__ */ (0,
|
|
15517
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ImageBinder, { name: field.name, value: values[field.name] ?? "", fit: field.fit ?? "cover" }, `image-${field.name}`);
|
|
15195
15518
|
}
|
|
15196
15519
|
return null;
|
|
15197
15520
|
}) });
|
|
@@ -15213,19 +15536,19 @@ function PersonalizationProvider({
|
|
|
15213
15536
|
children
|
|
15214
15537
|
}) {
|
|
15215
15538
|
const realtime = useRealtimeOptional();
|
|
15216
|
-
const [personValues, setPersonValues] = (0,
|
|
15217
|
-
const [isActive, setIsActive] = (0,
|
|
15218
|
-
const [isExporting, setIsExporting] = (0,
|
|
15219
|
-
const [exportedBlobUrls, setExportedBlobUrls] = (0,
|
|
15220
|
-
const [exportCount, setExportCount] = (0,
|
|
15221
|
-
const blobUrlsRef = (0,
|
|
15222
|
-
const [CanvasComponent, setCanvasComponent] = (0,
|
|
15539
|
+
const [personValues, setPersonValues] = (0, import_react67.useState)(initialValues ?? {});
|
|
15540
|
+
const [isActive, setIsActive] = (0, import_react67.useState)(!!(initialValues && Object.keys(initialValues).length > 0));
|
|
15541
|
+
const [isExporting, setIsExporting] = (0, import_react67.useState)(false);
|
|
15542
|
+
const [exportedBlobUrls, setExportedBlobUrls] = (0, import_react67.useState)({});
|
|
15543
|
+
const [exportCount, setExportCount] = (0, import_react67.useState)(0);
|
|
15544
|
+
const blobUrlsRef = (0, import_react67.useRef)({});
|
|
15545
|
+
const [CanvasComponent, setCanvasComponent] = (0, import_react67.useState)(
|
|
15223
15546
|
cachedCanvasComponent
|
|
15224
15547
|
);
|
|
15225
|
-
const [BridgeComponent, setBridgeComponent] = (0,
|
|
15548
|
+
const [BridgeComponent, setBridgeComponent] = (0, import_react67.useState)(
|
|
15226
15549
|
cachedBridgeComponent
|
|
15227
15550
|
);
|
|
15228
|
-
(0,
|
|
15551
|
+
(0, import_react67.useEffect)(() => {
|
|
15229
15552
|
if (CanvasComponent && BridgeComponent) return;
|
|
15230
15553
|
if (!canvasImport) return;
|
|
15231
15554
|
if (!canvasLoadPromise) {
|
|
@@ -15243,8 +15566,8 @@ function PersonalizationProvider({
|
|
|
15243
15566
|
}
|
|
15244
15567
|
});
|
|
15245
15568
|
}, [CanvasComponent, BridgeComponent, canvasImport]);
|
|
15246
|
-
const realtimeEnabledRef = (0,
|
|
15247
|
-
(0,
|
|
15569
|
+
const realtimeEnabledRef = (0, import_react67.useRef)(false);
|
|
15570
|
+
(0, import_react67.useEffect)(() => {
|
|
15248
15571
|
return () => {
|
|
15249
15572
|
for (const url of Object.values(blobUrlsRef.current)) {
|
|
15250
15573
|
try {
|
|
@@ -15254,16 +15577,16 @@ function PersonalizationProvider({
|
|
|
15254
15577
|
}
|
|
15255
15578
|
};
|
|
15256
15579
|
}, []);
|
|
15257
|
-
const updateField = (0,
|
|
15580
|
+
const updateField = (0, import_react67.useCallback)((key, value) => {
|
|
15258
15581
|
setIsActive(true);
|
|
15259
15582
|
setPersonValues((prev) => ({ ...prev, [key]: value }));
|
|
15260
15583
|
}, []);
|
|
15261
|
-
const reset = (0,
|
|
15584
|
+
const reset = (0, import_react67.useCallback)(() => {
|
|
15262
15585
|
setPersonValues({});
|
|
15263
15586
|
setIsActive(false);
|
|
15264
15587
|
setIsExporting(false);
|
|
15265
15588
|
}, []);
|
|
15266
|
-
const handleExport = (0,
|
|
15589
|
+
const handleExport = (0, import_react67.useCallback)(
|
|
15267
15590
|
(exports2) => {
|
|
15268
15591
|
const newUrls = {};
|
|
15269
15592
|
for (const [name, data] of Object.entries(exports2)) {
|
|
@@ -15297,11 +15620,11 @@ function PersonalizationProvider({
|
|
|
15297
15620
|
},
|
|
15298
15621
|
[realtime, placementOverride]
|
|
15299
15622
|
);
|
|
15300
|
-
const handleExportScheduled = (0,
|
|
15623
|
+
const handleExportScheduled = (0, import_react67.useCallback)(() => {
|
|
15301
15624
|
setIsExporting(true);
|
|
15302
15625
|
}, []);
|
|
15303
15626
|
const shouldMountCanvas = CanvasComponent && BridgeComponent && canvasState?.elements && canvasState.elements.length > 0 && (!lazy || isActive);
|
|
15304
|
-
const contextValue =
|
|
15627
|
+
const contextValue = import_react67.default.useMemo(
|
|
15305
15628
|
() => ({
|
|
15306
15629
|
fields,
|
|
15307
15630
|
personValues,
|
|
@@ -15314,8 +15637,8 @@ function PersonalizationProvider({
|
|
|
15314
15637
|
}),
|
|
15315
15638
|
[fields, personValues, updateField, isActive, isExporting, exportedBlobUrls, exportCount, reset]
|
|
15316
15639
|
);
|
|
15317
|
-
return /* @__PURE__ */ (0,
|
|
15318
|
-
shouldMountCanvas && CanvasComponent && BridgeComponent && /* @__PURE__ */ (0,
|
|
15640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(PersonalizationContext.Provider, { value: contextValue, children: [
|
|
15641
|
+
shouldMountCanvas && CanvasComponent && BridgeComponent && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
15319
15642
|
"div",
|
|
15320
15643
|
{
|
|
15321
15644
|
style: {
|
|
@@ -15328,7 +15651,7 @@ function PersonalizationProvider({
|
|
|
15328
15651
|
pointerEvents: "none"
|
|
15329
15652
|
},
|
|
15330
15653
|
"aria-hidden": true,
|
|
15331
|
-
children: /* @__PURE__ */ (0,
|
|
15654
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
15332
15655
|
CanvasComponent,
|
|
15333
15656
|
{
|
|
15334
15657
|
initialElements: canvasState?.elements,
|
|
@@ -15348,7 +15671,7 @@ function PersonalizationProvider({
|
|
|
15348
15671
|
exportImageQuality: exportConfig?.imageQuality ?? 0.85,
|
|
15349
15672
|
onExport: handleExport,
|
|
15350
15673
|
onExportScheduled: handleExportScheduled,
|
|
15351
|
-
overlay: /* @__PURE__ */ (0,
|
|
15674
|
+
overlay: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(BridgeComponent, { fields, values: personValues })
|
|
15352
15675
|
}
|
|
15353
15676
|
)
|
|
15354
15677
|
},
|
|
@@ -15373,7 +15696,7 @@ function usePersonalizationOptional() {
|
|
|
15373
15696
|
}
|
|
15374
15697
|
|
|
15375
15698
|
// src/personalization/PersonalizationInputs.tsx
|
|
15376
|
-
var
|
|
15699
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
15377
15700
|
function PersonalizationInputs({
|
|
15378
15701
|
className,
|
|
15379
15702
|
inputClassName = "w-full px-4 py-3 rounded-lg border text-base text-foreground placeholder:text-muted-foreground bg-white/50 outline-none focus:ring-2 focus:ring-foreground/20",
|
|
@@ -15397,8 +15720,8 @@ function PersonalizationInputs({
|
|
|
15397
15720
|
scrollInputAboveKeyboard(e.target);
|
|
15398
15721
|
}
|
|
15399
15722
|
};
|
|
15400
|
-
return /* @__PURE__ */ (0,
|
|
15401
|
-
textFields.map((field) => /* @__PURE__ */ (0,
|
|
15723
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { className: className || "flex flex-col gap-3", children: [
|
|
15724
|
+
textFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
15402
15725
|
"input",
|
|
15403
15726
|
{
|
|
15404
15727
|
type: "text",
|
|
@@ -15412,8 +15735,8 @@ function PersonalizationInputs({
|
|
|
15412
15735
|
},
|
|
15413
15736
|
`text-${field.name}`
|
|
15414
15737
|
)),
|
|
15415
|
-
colorFields.map((field) => /* @__PURE__ */ (0,
|
|
15416
|
-
/* @__PURE__ */ (0,
|
|
15738
|
+
colorFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
15739
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
15417
15740
|
"input",
|
|
15418
15741
|
{
|
|
15419
15742
|
type: "color",
|
|
@@ -15422,9 +15745,9 @@ function PersonalizationInputs({
|
|
|
15422
15745
|
onChange: (e) => updateField(field.color, e.target.value)
|
|
15423
15746
|
}
|
|
15424
15747
|
),
|
|
15425
|
-
/* @__PURE__ */ (0,
|
|
15748
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", { className: "text-base text-muted-foreground", children: field.label })
|
|
15426
15749
|
] }, `color-${field.color}`)),
|
|
15427
|
-
imageFields.map((field) => /* @__PURE__ */ (0,
|
|
15750
|
+
imageFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
15428
15751
|
"input",
|
|
15429
15752
|
{
|
|
15430
15753
|
type: "text",
|
|
@@ -15442,15 +15765,15 @@ function PersonalizationInputs({
|
|
|
15442
15765
|
}
|
|
15443
15766
|
|
|
15444
15767
|
// src/personalization/usePersonalizationShimmer.ts
|
|
15445
|
-
var
|
|
15768
|
+
var import_react68 = require("react");
|
|
15446
15769
|
function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
15447
15770
|
const personCtx = usePersonalizationContext();
|
|
15448
15771
|
const realtime = useRealtimeOptional();
|
|
15449
|
-
const [shimmerActive, setShimmerActive] = (0,
|
|
15450
|
-
const sdkSettledRef = (0,
|
|
15451
|
-
const manualTriggerRef = (0,
|
|
15452
|
-
const safetyTimeoutRef = (0,
|
|
15453
|
-
const startShimmer = (0,
|
|
15772
|
+
const [shimmerActive, setShimmerActive] = (0, import_react68.useState)(false);
|
|
15773
|
+
const sdkSettledRef = (0, import_react68.useRef)(false);
|
|
15774
|
+
const manualTriggerRef = (0, import_react68.useRef)(false);
|
|
15775
|
+
const safetyTimeoutRef = (0, import_react68.useRef)(void 0);
|
|
15776
|
+
const startShimmer = (0, import_react68.useCallback)(() => {
|
|
15454
15777
|
setShimmerActive(true);
|
|
15455
15778
|
if (safetyTimeoutRef.current) clearTimeout(safetyTimeoutRef.current);
|
|
15456
15779
|
safetyTimeoutRef.current = setTimeout(
|
|
@@ -15462,25 +15785,25 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
15462
15785
|
safetyTimeoutMs
|
|
15463
15786
|
);
|
|
15464
15787
|
}, [safetyTimeoutMs]);
|
|
15465
|
-
(0,
|
|
15788
|
+
(0, import_react68.useEffect)(() => {
|
|
15466
15789
|
if (!personCtx?.isActive) return;
|
|
15467
15790
|
sdkSettledRef.current = false;
|
|
15468
15791
|
manualTriggerRef.current = false;
|
|
15469
15792
|
realtime?.resetPipelineSettled();
|
|
15470
15793
|
startShimmer();
|
|
15471
15794
|
}, [personCtx?.personValues, personCtx?.isActive, startShimmer]);
|
|
15472
|
-
const triggerShimmer = (0,
|
|
15795
|
+
const triggerShimmer = (0, import_react68.useCallback)(() => {
|
|
15473
15796
|
sdkSettledRef.current = false;
|
|
15474
15797
|
manualTriggerRef.current = true;
|
|
15475
15798
|
startShimmer();
|
|
15476
15799
|
}, [startShimmer]);
|
|
15477
|
-
(0,
|
|
15800
|
+
(0, import_react68.useEffect)(() => {
|
|
15478
15801
|
if (!realtime?.subscribePipelineSettled) return;
|
|
15479
15802
|
return realtime.subscribePipelineSettled(() => {
|
|
15480
15803
|
sdkSettledRef.current = true;
|
|
15481
15804
|
});
|
|
15482
15805
|
}, [realtime]);
|
|
15483
|
-
(0,
|
|
15806
|
+
(0, import_react68.useEffect)(() => {
|
|
15484
15807
|
const container = containerRef.current;
|
|
15485
15808
|
if (!container) return;
|
|
15486
15809
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -15523,7 +15846,7 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
15523
15846
|
});
|
|
15524
15847
|
return () => observer.disconnect();
|
|
15525
15848
|
}, [containerRef]);
|
|
15526
|
-
(0,
|
|
15849
|
+
(0, import_react68.useEffect)(() => {
|
|
15527
15850
|
return () => {
|
|
15528
15851
|
if (safetyTimeoutRef.current) clearTimeout(safetyTimeoutRef.current);
|
|
15529
15852
|
};
|
|
@@ -15629,6 +15952,8 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
15629
15952
|
Link,
|
|
15630
15953
|
LinkIcon,
|
|
15631
15954
|
LoadingOverlayPrism,
|
|
15955
|
+
LoadingOverlayPrismCandy,
|
|
15956
|
+
LoadingOverlayPrismCandyInline,
|
|
15632
15957
|
MasonryGrid,
|
|
15633
15958
|
MobileProductCarousel,
|
|
15634
15959
|
MockupPriorityProvider,
|