@snowcone-app/ui 0.3.1 → 0.4.1
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 +22 -0
- package/dist/index.cjs +559 -475
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +449 -366
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/composed/HeroProductImage.tsx +92 -10
- package/src/composed/SafeImg.tsx +46 -0
- package/src/composed/carousels/MobileProductCarousel.tsx +42 -8
- package/src/composed/search/meilisearchAdapter.ts +1 -1
- package/src/composed/zoom/EnhancedImageViewer.tsx +2 -1
- package/src/index.ts +1 -0
- package/src/patterns/RealtimeProvider.tsx +17 -2
package/dist/index.js
CHANGED
|
@@ -5624,8 +5624,8 @@ function RealtimeProvider({
|
|
|
5624
5624
|
},
|
|
5625
5625
|
onAllMockupsRendered: (results) => {
|
|
5626
5626
|
},
|
|
5627
|
-
onError: (error) => {
|
|
5628
|
-
console.error(
|
|
5627
|
+
onError: (error, detail) => {
|
|
5628
|
+
console.error(`[RealtimeProvider] Render error [${detail.code}]:`, error);
|
|
5629
5629
|
}
|
|
5630
5630
|
});
|
|
5631
5631
|
const subscribeRTCTiming = useCallback10((_callback) => {
|
|
@@ -5635,6 +5635,7 @@ function RealtimeProvider({
|
|
|
5635
5635
|
const {
|
|
5636
5636
|
isConnected,
|
|
5637
5637
|
isConfigured,
|
|
5638
|
+
renderError,
|
|
5638
5639
|
mockupResults: rawMockupResults,
|
|
5639
5640
|
sendCanvasBlob: sendCanvasBlobRaw,
|
|
5640
5641
|
sendCanvasState: sendCanvasStateRaw,
|
|
@@ -6154,6 +6155,7 @@ function RealtimeProvider({
|
|
|
6154
6155
|
isEnabled,
|
|
6155
6156
|
isConnected,
|
|
6156
6157
|
isConfigured,
|
|
6158
|
+
renderError,
|
|
6157
6159
|
// Read from ref - this is a snapshot at render time, NOT reactive
|
|
6158
6160
|
// For reactive updates, use getMockupResultsImmediate() or subscribe functions
|
|
6159
6161
|
get mockupResults() {
|
|
@@ -6197,6 +6199,7 @@ function RealtimeProvider({
|
|
|
6197
6199
|
isEnabled,
|
|
6198
6200
|
isConnected,
|
|
6199
6201
|
isConfigured,
|
|
6202
|
+
renderError,
|
|
6200
6203
|
// mockupResults removed from deps - it's a getter that reads from ref
|
|
6201
6204
|
canvasExportSize,
|
|
6202
6205
|
mockupWidth,
|
|
@@ -10097,12 +10100,18 @@ var HeroProductImage = memo3(function HeroProductImage2({
|
|
|
10097
10100
|
const [showNew, setShowNew] = useState31(false);
|
|
10098
10101
|
const [renderedUrl, setRenderedUrl] = useState31(displayUrl);
|
|
10099
10102
|
const [firstImageLoaded, setFirstImageLoaded] = useState31(false);
|
|
10103
|
+
const [loaderMounted, setLoaderMounted] = useState31(true);
|
|
10104
|
+
const [imgFailed, setImgFailed] = useState31(false);
|
|
10105
|
+
const [retryNonce, setRetryNonce] = useState31(0);
|
|
10106
|
+
const retriedUrlRef = useRef23(null);
|
|
10100
10107
|
const prevDisplayUrlRef = useRef23(displayUrl);
|
|
10101
10108
|
const signHintShownRef = useRef23(false);
|
|
10102
10109
|
useEffect32(() => {
|
|
10103
10110
|
if (!displayUrl || displayUrl === prevDisplayUrlRef.current) return;
|
|
10104
10111
|
const oldUrl = prevDisplayUrlRef.current;
|
|
10105
10112
|
prevDisplayUrlRef.current = displayUrl;
|
|
10113
|
+
setImgFailed(false);
|
|
10114
|
+
retriedUrlRef.current = null;
|
|
10106
10115
|
if (!oldUrl) {
|
|
10107
10116
|
setRenderedUrl(displayUrl);
|
|
10108
10117
|
return;
|
|
@@ -10128,6 +10137,7 @@ var HeroProductImage = memo3(function HeroProductImage2({
|
|
|
10128
10137
|
setPrevUrl(null);
|
|
10129
10138
|
setShowNew(false);
|
|
10130
10139
|
}, []);
|
|
10140
|
+
const handleLoaderExited = useCallback18(() => setLoaderMounted(false), []);
|
|
10131
10141
|
if (!hasArtwork) {
|
|
10132
10142
|
return /* @__PURE__ */ jsx60(
|
|
10133
10143
|
"div",
|
|
@@ -10176,19 +10186,19 @@ var HeroProductImage = memo3(function HeroProductImage2({
|
|
|
10176
10186
|
style,
|
|
10177
10187
|
"data-hero-image": "true",
|
|
10178
10188
|
children: [
|
|
10179
|
-
!
|
|
10180
|
-
renderedUrl && /* @__PURE__ */ jsx60(
|
|
10189
|
+
renderedUrl && !imgFailed && /* @__PURE__ */ jsx60(
|
|
10181
10190
|
"img",
|
|
10182
10191
|
{
|
|
10183
10192
|
alt: `Product mockup${placement ? ` - ${placement}` : ""}`,
|
|
10184
10193
|
crossOrigin: "anonymous",
|
|
10185
10194
|
className: "absolute inset-0 w-full h-full object-cover",
|
|
10186
10195
|
draggable,
|
|
10187
|
-
src: renderedUrl,
|
|
10196
|
+
src: retriedUrlRef.current === renderedUrl ? `${renderedUrl}${renderedUrl.includes("?") ? "&" : "?"}_cb=${retryNonce}` : renderedUrl,
|
|
10188
10197
|
loading: "eager",
|
|
10189
10198
|
fetchPriority: "high",
|
|
10190
10199
|
onClick,
|
|
10191
10200
|
onLoad: () => {
|
|
10201
|
+
setImgFailed(false);
|
|
10192
10202
|
setFirstImageLoaded(true);
|
|
10193
10203
|
if (!onLoadCalledRef.current && onLoad) {
|
|
10194
10204
|
onLoadCalledRef.current = true;
|
|
@@ -10197,6 +10207,12 @@ var HeroProductImage = memo3(function HeroProductImage2({
|
|
|
10197
10207
|
onUrlGeneratedRef.current?.(renderedUrl);
|
|
10198
10208
|
},
|
|
10199
10209
|
onError: () => {
|
|
10210
|
+
if (renderedUrl && retriedUrlRef.current !== renderedUrl) {
|
|
10211
|
+
retriedUrlRef.current = renderedUrl;
|
|
10212
|
+
setRetryNonce((n) => n + 1);
|
|
10213
|
+
return;
|
|
10214
|
+
}
|
|
10215
|
+
setImgFailed(true);
|
|
10200
10216
|
setFirstImageLoaded(true);
|
|
10201
10217
|
onError?.();
|
|
10202
10218
|
if (process.env.NODE_ENV !== "production" && !signHintShownRef.current && renderedUrl && /\/[A-Za-z0-9]+\?/.test(renderedUrl) && !/[?&]signature=/.test(renderedUrl)) {
|
|
@@ -10209,6 +10225,16 @@ var HeroProductImage = memo3(function HeroProductImage2({
|
|
|
10209
10225
|
}
|
|
10210
10226
|
}
|
|
10211
10227
|
),
|
|
10228
|
+
imgFailed && !prevUrl && /* @__PURE__ */ jsx60("div", { className: "absolute inset-0 flex items-center justify-center bg-muted", children: /* @__PURE__ */ jsx60("p", { className: "text-muted-foreground text-xs", children: "Preview unavailable" }) }),
|
|
10229
|
+
realtimeContext?.renderError && /* @__PURE__ */ jsx60(
|
|
10230
|
+
"div",
|
|
10231
|
+
{
|
|
10232
|
+
role: "alert",
|
|
10233
|
+
"data-render-error": realtimeContext.renderError.code,
|
|
10234
|
+
className: "absolute inset-x-0 bottom-0 z-20 bg-red-600/90 text-white text-xs font-medium px-3 py-2 pointer-events-none",
|
|
10235
|
+
children: `Render blocked: ${realtimeContext.renderError.code} \u2014 ${realtimeContext.renderError.message}`
|
|
10236
|
+
}
|
|
10237
|
+
),
|
|
10212
10238
|
prevUrl && /* @__PURE__ */ jsx60(
|
|
10213
10239
|
"img",
|
|
10214
10240
|
{
|
|
@@ -10223,12 +10249,45 @@ var HeroProductImage = memo3(function HeroProductImage2({
|
|
|
10223
10249
|
},
|
|
10224
10250
|
onTransitionEnd: handleCrossfadeEnd
|
|
10225
10251
|
}
|
|
10252
|
+
),
|
|
10253
|
+
loaderMounted && /* @__PURE__ */ jsx60(
|
|
10254
|
+
LoadingOverlayPrismCandyInline,
|
|
10255
|
+
{
|
|
10256
|
+
visible: !firstImageLoaded,
|
|
10257
|
+
variant: "light",
|
|
10258
|
+
onExited: handleLoaderExited
|
|
10259
|
+
}
|
|
10226
10260
|
)
|
|
10227
10261
|
]
|
|
10228
10262
|
}
|
|
10229
10263
|
);
|
|
10230
10264
|
});
|
|
10231
10265
|
|
|
10266
|
+
// src/composed/SafeImg.tsx
|
|
10267
|
+
import React44, { useEffect as useEffect33, useState as useState32 } from "react";
|
|
10268
|
+
import { Fragment as Fragment12, jsx as jsx61 } from "react/jsx-runtime";
|
|
10269
|
+
var SafeImg = React44.forwardRef(
|
|
10270
|
+
function SafeImg2({ fallback = null, onError, src, ...rest }, ref) {
|
|
10271
|
+
const [failed, setFailed] = useState32(false);
|
|
10272
|
+
useEffect33(() => {
|
|
10273
|
+
setFailed(false);
|
|
10274
|
+
}, [src]);
|
|
10275
|
+
if (failed) return /* @__PURE__ */ jsx61(Fragment12, { children: fallback });
|
|
10276
|
+
return /* @__PURE__ */ jsx61(
|
|
10277
|
+
"img",
|
|
10278
|
+
{
|
|
10279
|
+
...rest,
|
|
10280
|
+
ref,
|
|
10281
|
+
src,
|
|
10282
|
+
onError: (e) => {
|
|
10283
|
+
setFailed(true);
|
|
10284
|
+
onError?.(e);
|
|
10285
|
+
}
|
|
10286
|
+
}
|
|
10287
|
+
);
|
|
10288
|
+
}
|
|
10289
|
+
);
|
|
10290
|
+
|
|
10232
10291
|
// src/index.ts
|
|
10233
10292
|
import {
|
|
10234
10293
|
describeProductArtAlignment as describeProductArtAlignment2,
|
|
@@ -10241,7 +10300,7 @@ import { InstantSearch, Configure, useSearchBox } from "react-instantsearch";
|
|
|
10241
10300
|
// src/composed/search/meilisearchAdapter.ts
|
|
10242
10301
|
import { instantMeiliSearch } from "@meilisearch/instant-meilisearch";
|
|
10243
10302
|
var MEILISEARCH_HOST = readEnv("NEXT_PUBLIC_MEILISEARCH_HOST") || "https://ms-e5d999b2eaca-15654.sfo.meilisearch.io";
|
|
10244
|
-
var MEILISEARCH_API_KEY = readEnv("NEXT_PUBLIC_MEILISEARCH_API_KEY") || "
|
|
10303
|
+
var MEILISEARCH_API_KEY = readEnv("NEXT_PUBLIC_MEILISEARCH_API_KEY") || "4a11f6599e39af365f6289dab46b77a30ef78ba1ac078f7d74e152c099b3b63c";
|
|
10245
10304
|
var { searchClient } = instantMeiliSearch(
|
|
10246
10305
|
MEILISEARCH_HOST,
|
|
10247
10306
|
MEILISEARCH_API_KEY,
|
|
@@ -10252,11 +10311,11 @@ var { searchClient } = instantMeiliSearch(
|
|
|
10252
10311
|
);
|
|
10253
10312
|
|
|
10254
10313
|
// src/composed/search/SearchProvider.tsx
|
|
10255
|
-
import { useEffect as
|
|
10256
|
-
import { jsx as
|
|
10314
|
+
import { useEffect as useEffect34 } from "react";
|
|
10315
|
+
import { jsx as jsx62, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
10257
10316
|
function InitialSearchTrigger() {
|
|
10258
10317
|
const { refine } = useSearchBox();
|
|
10259
|
-
|
|
10318
|
+
useEffect34(() => {
|
|
10260
10319
|
refine("");
|
|
10261
10320
|
}, [refine]);
|
|
10262
10321
|
return null;
|
|
@@ -10308,7 +10367,7 @@ function SearchProvider({
|
|
|
10308
10367
|
}
|
|
10309
10368
|
},
|
|
10310
10369
|
children: [
|
|
10311
|
-
/* @__PURE__ */
|
|
10370
|
+
/* @__PURE__ */ jsx62(
|
|
10312
10371
|
Configure,
|
|
10313
10372
|
{
|
|
10314
10373
|
hitsPerPage,
|
|
@@ -10317,7 +10376,7 @@ function SearchProvider({
|
|
|
10317
10376
|
attributesToRetrieve
|
|
10318
10377
|
}
|
|
10319
10378
|
),
|
|
10320
|
-
/* @__PURE__ */
|
|
10379
|
+
/* @__PURE__ */ jsx62(InitialSearchTrigger, {}),
|
|
10321
10380
|
children
|
|
10322
10381
|
]
|
|
10323
10382
|
}
|
|
@@ -10327,17 +10386,17 @@ function SearchProvider({
|
|
|
10327
10386
|
// src/composed/search/SearchBox.tsx
|
|
10328
10387
|
import { useSearchBox as useSearchBox2 } from "react-instantsearch";
|
|
10329
10388
|
import { Search, X } from "lucide-react";
|
|
10330
|
-
import { useEffect as
|
|
10331
|
-
import { jsx as
|
|
10389
|
+
import { useEffect as useEffect35, useRef as useRef24, useState as useState33 } from "react";
|
|
10390
|
+
import { jsx as jsx63, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
10332
10391
|
function SearchBox() {
|
|
10333
10392
|
const { query, refine, clear } = useSearchBox2();
|
|
10334
10393
|
const searchParams = useUiSearchParams();
|
|
10335
10394
|
const router = useUiRouter();
|
|
10336
10395
|
const inputRef = useRef24(null);
|
|
10337
|
-
const [showShimmer, setShowShimmer] =
|
|
10396
|
+
const [showShimmer, setShowShimmer] = useState33(false);
|
|
10338
10397
|
const inputId = "search-products-input";
|
|
10339
10398
|
const descriptionId = "search-description";
|
|
10340
|
-
|
|
10399
|
+
useEffect35(() => {
|
|
10341
10400
|
const handleSpotlight = () => {
|
|
10342
10401
|
inputRef.current?.focus();
|
|
10343
10402
|
inputRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
@@ -10347,7 +10406,7 @@ function SearchBox() {
|
|
|
10347
10406
|
window.addEventListener("search-spotlight", handleSpotlight);
|
|
10348
10407
|
return () => window.removeEventListener("search-spotlight", handleSpotlight);
|
|
10349
10408
|
}, []);
|
|
10350
|
-
|
|
10409
|
+
useEffect35(() => {
|
|
10351
10410
|
const shouldFocus = searchParams.get("focus") === "search";
|
|
10352
10411
|
if (shouldFocus && inputRef.current) {
|
|
10353
10412
|
const timer = setTimeout(() => {
|
|
@@ -10362,8 +10421,8 @@ function SearchBox() {
|
|
|
10362
10421
|
return () => clearTimeout(timer);
|
|
10363
10422
|
}
|
|
10364
10423
|
}, [searchParams, router]);
|
|
10365
|
-
return /* @__PURE__ */
|
|
10366
|
-
/* @__PURE__ */
|
|
10424
|
+
return /* @__PURE__ */ jsx63("form", { role: "search", onSubmit: (e) => e.preventDefault(), children: /* @__PURE__ */ jsxs41("div", { className: "relative", children: [
|
|
10425
|
+
/* @__PURE__ */ jsx63(
|
|
10367
10426
|
Input,
|
|
10368
10427
|
{
|
|
10369
10428
|
ref: inputRef,
|
|
@@ -10372,15 +10431,15 @@ function SearchBox() {
|
|
|
10372
10431
|
value: query,
|
|
10373
10432
|
onChange: (e) => refine(e.target.value),
|
|
10374
10433
|
placeholder: "Search products...",
|
|
10375
|
-
startContent: /* @__PURE__ */
|
|
10376
|
-
endContent: query ? /* @__PURE__ */
|
|
10434
|
+
startContent: /* @__PURE__ */ jsx63(Search, { className: "w-5 h-5", strokeWidth: 1.5, "aria-hidden": "true" }),
|
|
10435
|
+
endContent: query ? /* @__PURE__ */ jsx63(
|
|
10377
10436
|
"button",
|
|
10378
10437
|
{
|
|
10379
10438
|
type: "button",
|
|
10380
10439
|
onClick: clear,
|
|
10381
10440
|
className: "hover:text-foreground transition-colors",
|
|
10382
10441
|
"aria-label": "Clear search",
|
|
10383
|
-
children: /* @__PURE__ */
|
|
10442
|
+
children: /* @__PURE__ */ jsx63(X, { className: "w-4 h-4", strokeWidth: 2, "aria-hidden": "true" })
|
|
10384
10443
|
}
|
|
10385
10444
|
) : void 0,
|
|
10386
10445
|
"aria-label": "Search products",
|
|
@@ -10390,11 +10449,11 @@ function SearchBox() {
|
|
|
10390
10449
|
className: "[&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden"
|
|
10391
10450
|
}
|
|
10392
10451
|
),
|
|
10393
|
-
showShimmer && /* @__PURE__ */
|
|
10452
|
+
showShimmer && /* @__PURE__ */ jsx63(
|
|
10394
10453
|
"div",
|
|
10395
10454
|
{
|
|
10396
10455
|
className: "absolute inset-0 pointer-events-none rounded-input z-20 overflow-hidden",
|
|
10397
|
-
children: /* @__PURE__ */
|
|
10456
|
+
children: /* @__PURE__ */ jsx63(
|
|
10398
10457
|
"div",
|
|
10399
10458
|
{
|
|
10400
10459
|
className: "absolute inset-0",
|
|
@@ -10407,13 +10466,13 @@ function SearchBox() {
|
|
|
10407
10466
|
)
|
|
10408
10467
|
}
|
|
10409
10468
|
),
|
|
10410
|
-
/* @__PURE__ */
|
|
10469
|
+
/* @__PURE__ */ jsx63("style", { dangerouslySetInnerHTML: { __html: `
|
|
10411
10470
|
@keyframes searchShimmer {
|
|
10412
10471
|
0% { transform: translateX(-100%); }
|
|
10413
10472
|
100% { transform: translateX(100%); }
|
|
10414
10473
|
}
|
|
10415
10474
|
` } }),
|
|
10416
|
-
/* @__PURE__ */
|
|
10475
|
+
/* @__PURE__ */ jsx63("span", { id: descriptionId, className: "sr-only", children: "Search results will update as you type" })
|
|
10417
10476
|
] }) });
|
|
10418
10477
|
}
|
|
10419
10478
|
|
|
@@ -10421,7 +10480,7 @@ function SearchBox() {
|
|
|
10421
10480
|
import { Hits, useStats, useInstantSearch } from "react-instantsearch";
|
|
10422
10481
|
|
|
10423
10482
|
// src/composed/search/ProductHit.tsx
|
|
10424
|
-
import { jsx as
|
|
10483
|
+
import { jsx as jsx64 } from "react/jsx-runtime";
|
|
10425
10484
|
function ProductHitComponent({
|
|
10426
10485
|
hit: product,
|
|
10427
10486
|
variant = "overlay"
|
|
@@ -10438,12 +10497,12 @@ function ProductHitComponent({
|
|
|
10438
10497
|
}
|
|
10439
10498
|
return "";
|
|
10440
10499
|
};
|
|
10441
|
-
return /* @__PURE__ */
|
|
10500
|
+
return /* @__PURE__ */ jsx64(
|
|
10442
10501
|
Product,
|
|
10443
10502
|
{
|
|
10444
10503
|
productId,
|
|
10445
10504
|
productData: product,
|
|
10446
|
-
children: /* @__PURE__ */
|
|
10505
|
+
children: /* @__PURE__ */ jsx64(
|
|
10447
10506
|
ProductCard,
|
|
10448
10507
|
{
|
|
10449
10508
|
variant,
|
|
@@ -10464,10 +10523,10 @@ function ProductHitComponent({
|
|
|
10464
10523
|
}
|
|
10465
10524
|
|
|
10466
10525
|
// src/composed/search/ProductGrid.tsx
|
|
10467
|
-
import { useState as
|
|
10468
|
-
import { jsx as
|
|
10526
|
+
import { useState as useState34, useEffect as useEffect36, useCallback as useCallback19 } from "react";
|
|
10527
|
+
import { jsx as jsx65, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
10469
10528
|
function ProductGridSkeletonItem() {
|
|
10470
|
-
return /* @__PURE__ */
|
|
10529
|
+
return /* @__PURE__ */ jsx65("div", { className: "aspect-square bg-muted animate-pulse" });
|
|
10471
10530
|
}
|
|
10472
10531
|
function ProductGrid({
|
|
10473
10532
|
className = "",
|
|
@@ -10477,16 +10536,16 @@ function ProductGrid({
|
|
|
10477
10536
|
}) {
|
|
10478
10537
|
const { nbHits } = useStats();
|
|
10479
10538
|
const { status, results } = useInstantSearch();
|
|
10480
|
-
const [announcement, setAnnouncement] =
|
|
10539
|
+
const [announcement, setAnnouncement] = useState34("");
|
|
10481
10540
|
const hitsCount = results?.hits?.length ?? 0;
|
|
10482
10541
|
const showSkeleton = hitsCount === 0 && status !== "error";
|
|
10483
|
-
|
|
10542
|
+
useEffect36(() => {
|
|
10484
10543
|
const timer = setTimeout(() => {
|
|
10485
10544
|
setAnnouncement(`${nbHits} ${nbHits === 1 ? "product" : "products"} found`);
|
|
10486
10545
|
}, 1e3);
|
|
10487
10546
|
return () => clearTimeout(timer);
|
|
10488
10547
|
}, [nbHits]);
|
|
10489
|
-
const HitComponent = useCallback19(({ hit }) => /* @__PURE__ */
|
|
10548
|
+
const HitComponent = useCallback19(({ hit }) => /* @__PURE__ */ jsx65(
|
|
10490
10549
|
ProductHitComponent,
|
|
10491
10550
|
{
|
|
10492
10551
|
hit,
|
|
@@ -10494,9 +10553,9 @@ function ProductGrid({
|
|
|
10494
10553
|
}
|
|
10495
10554
|
), [variant]);
|
|
10496
10555
|
return /* @__PURE__ */ jsxs42("div", { className, children: [
|
|
10497
|
-
/* @__PURE__ */
|
|
10498
|
-
showSkeleton && /* @__PURE__ */
|
|
10499
|
-
/* @__PURE__ */
|
|
10556
|
+
/* @__PURE__ */ jsx65("div", { className: "sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement }),
|
|
10557
|
+
showSkeleton && /* @__PURE__ */ jsx65("div", { className: `grid ${gridClassName}`, children: Array.from({ length: skeletonCount }).map((_, i) => /* @__PURE__ */ jsx65(ProductGridSkeletonItem, {}, i)) }),
|
|
10558
|
+
/* @__PURE__ */ jsx65("div", { className: showSkeleton ? "hidden" : "", children: /* @__PURE__ */ jsx65(
|
|
10500
10559
|
Hits,
|
|
10501
10560
|
{
|
|
10502
10561
|
hitComponent: HitComponent,
|
|
@@ -10511,11 +10570,11 @@ function ProductGrid({
|
|
|
10511
10570
|
}
|
|
10512
10571
|
|
|
10513
10572
|
// src/composed/search/Filters.tsx
|
|
10514
|
-
import { useState as
|
|
10573
|
+
import { useState as useState36 } from "react";
|
|
10515
10574
|
|
|
10516
10575
|
// src/composed/search/FiltersButton.tsx
|
|
10517
10576
|
import { SlidersHorizontal as LucideSlidersHorizontal } from "lucide-react";
|
|
10518
|
-
import { jsx as
|
|
10577
|
+
import { jsx as jsx66, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
10519
10578
|
var SlidersHorizontalIcon = LucideSlidersHorizontal;
|
|
10520
10579
|
function FiltersButton({
|
|
10521
10580
|
onClick,
|
|
@@ -10530,8 +10589,8 @@ function FiltersButton({
|
|
|
10530
10589
|
className,
|
|
10531
10590
|
"aria-label": "Open filters",
|
|
10532
10591
|
children: [
|
|
10533
|
-
/* @__PURE__ */
|
|
10534
|
-
/* @__PURE__ */
|
|
10592
|
+
/* @__PURE__ */ jsx66(SlidersHorizontalIcon, { className: "w-4 h-4" }),
|
|
10593
|
+
/* @__PURE__ */ jsx66("span", { children })
|
|
10535
10594
|
]
|
|
10536
10595
|
}
|
|
10537
10596
|
);
|
|
@@ -10540,15 +10599,15 @@ function FiltersButton({
|
|
|
10540
10599
|
// src/composed/search/FiltersDrawer.tsx
|
|
10541
10600
|
import { useRefinementList, useRange, useStats as useStats2 } from "react-instantsearch";
|
|
10542
10601
|
import { X as LucideX2, SlidersHorizontal as LucideSlidersHorizontal2 } from "lucide-react";
|
|
10543
|
-
import { useState as
|
|
10602
|
+
import { useState as useState35, useEffect as useEffect37 } from "react";
|
|
10544
10603
|
import * as Slider2 from "@radix-ui/react-slider";
|
|
10545
|
-
import { Fragment as
|
|
10604
|
+
import { Fragment as Fragment13, jsx as jsx67, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
10546
10605
|
var XIcon2 = LucideX2;
|
|
10547
10606
|
function FiltersDrawer({ isOpen, onClose }) {
|
|
10548
|
-
const [showCounts, setShowCounts] =
|
|
10607
|
+
const [showCounts, setShowCounts] = useState35(false);
|
|
10549
10608
|
const { nbHits } = useStats2();
|
|
10550
10609
|
const containerRef = useFocusTrap(isOpen, onClose);
|
|
10551
|
-
|
|
10610
|
+
useEffect37(() => {
|
|
10552
10611
|
if (isOpen) {
|
|
10553
10612
|
document.body.style.overflow = "hidden";
|
|
10554
10613
|
} else {
|
|
@@ -10558,7 +10617,7 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10558
10617
|
document.body.style.overflow = "";
|
|
10559
10618
|
};
|
|
10560
10619
|
}, [isOpen]);
|
|
10561
|
-
|
|
10620
|
+
useEffect37(() => {
|
|
10562
10621
|
const handleEscape = (e) => {
|
|
10563
10622
|
if (e.key === "Escape" && isOpen) {
|
|
10564
10623
|
onClose();
|
|
@@ -10567,8 +10626,8 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10567
10626
|
document.addEventListener("keydown", handleEscape);
|
|
10568
10627
|
return () => document.removeEventListener("keydown", handleEscape);
|
|
10569
10628
|
}, [isOpen, onClose]);
|
|
10570
|
-
return /* @__PURE__ */ jsxs44(
|
|
10571
|
-
/* @__PURE__ */
|
|
10629
|
+
return /* @__PURE__ */ jsxs44(Fragment13, { children: [
|
|
10630
|
+
/* @__PURE__ */ jsx67(
|
|
10572
10631
|
"div",
|
|
10573
10632
|
{
|
|
10574
10633
|
className: `fixed inset-0 bg-black/50 z-40 transition-opacity ${isOpen ? "opacity-100" : "opacity-0 pointer-events-none"}`,
|
|
@@ -10586,25 +10645,25 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10586
10645
|
"aria-labelledby": "filters-drawer-title",
|
|
10587
10646
|
children: [
|
|
10588
10647
|
/* @__PURE__ */ jsxs44("div", { className: "flex items-center justify-between px-4 py-4", children: [
|
|
10589
|
-
/* @__PURE__ */
|
|
10590
|
-
/* @__PURE__ */
|
|
10648
|
+
/* @__PURE__ */ jsx67("h2", { id: "filters-drawer-title", className: "text-xl font-bold", children: "Filters" }),
|
|
10649
|
+
/* @__PURE__ */ jsx67(
|
|
10591
10650
|
"button",
|
|
10592
10651
|
{
|
|
10593
10652
|
onClick: onClose,
|
|
10594
10653
|
className: "p-2 hover:bg-foreground/5 rounded-full transition-colors",
|
|
10595
10654
|
"aria-label": "Close filters",
|
|
10596
|
-
children: /* @__PURE__ */
|
|
10655
|
+
children: /* @__PURE__ */ jsx67(XIcon2, { className: "w-5 h-5" })
|
|
10597
10656
|
}
|
|
10598
10657
|
)
|
|
10599
10658
|
] }),
|
|
10600
|
-
/* @__PURE__ */
|
|
10659
|
+
/* @__PURE__ */ jsx67("div", { className: "px-4 pb-4", children: /* @__PURE__ */ jsxs44("p", { className: "text-sm font-caption text-foreground/60", role: "status", "aria-live": "polite", children: [
|
|
10601
10660
|
nbHits.toLocaleString(),
|
|
10602
10661
|
" ",
|
|
10603
10662
|
nbHits === 1 ? "result" : "results"
|
|
10604
10663
|
] }) }),
|
|
10605
|
-
/* @__PURE__ */
|
|
10606
|
-
/* @__PURE__ */
|
|
10607
|
-
/* @__PURE__ */
|
|
10664
|
+
/* @__PURE__ */ jsx67("div", { className: "flex-1 overflow-y-auto px-4 pb-4", children: /* @__PURE__ */ jsxs44("div", { className: "flex flex-col gap-8", children: [
|
|
10665
|
+
/* @__PURE__ */ jsx67(TagsSection, { showCounts, setShowCounts }),
|
|
10666
|
+
/* @__PURE__ */ jsx67(PriceSection, {})
|
|
10608
10667
|
] }) })
|
|
10609
10668
|
]
|
|
10610
10669
|
}
|
|
@@ -10620,7 +10679,7 @@ function TagsSection({
|
|
|
10620
10679
|
sortBy: ["count:desc", "name:asc"],
|
|
10621
10680
|
limit: 100
|
|
10622
10681
|
});
|
|
10623
|
-
const [isExpanded, setIsExpanded] =
|
|
10682
|
+
const [isExpanded, setIsExpanded] = useState35(true);
|
|
10624
10683
|
return /* @__PURE__ */ jsxs44("div", { className: "bg-foreground/5 rounded-lg p-4", children: [
|
|
10625
10684
|
/* @__PURE__ */ jsxs44(
|
|
10626
10685
|
"button",
|
|
@@ -10630,8 +10689,8 @@ function TagsSection({
|
|
|
10630
10689
|
"aria-expanded": isExpanded,
|
|
10631
10690
|
"aria-controls": "tags-content",
|
|
10632
10691
|
children: [
|
|
10633
|
-
/* @__PURE__ */
|
|
10634
|
-
/* @__PURE__ */
|
|
10692
|
+
/* @__PURE__ */ jsx67("h3", { className: "text-base font-semibold text-primary", children: "Tags" }),
|
|
10693
|
+
/* @__PURE__ */ jsx67(
|
|
10635
10694
|
"svg",
|
|
10636
10695
|
{
|
|
10637
10696
|
className: `w-5 h-5 transition-transform text-foreground/40 group-hover:text-foreground/60 ${isExpanded ? "rotate-180" : ""}`,
|
|
@@ -10640,14 +10699,14 @@ function TagsSection({
|
|
|
10640
10699
|
stroke: "currentColor",
|
|
10641
10700
|
strokeWidth: 2.5,
|
|
10642
10701
|
"aria-hidden": "true",
|
|
10643
|
-
children: /* @__PURE__ */
|
|
10702
|
+
children: /* @__PURE__ */ jsx67("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
|
|
10644
10703
|
}
|
|
10645
10704
|
)
|
|
10646
10705
|
]
|
|
10647
10706
|
}
|
|
10648
10707
|
),
|
|
10649
10708
|
isExpanded && /* @__PURE__ */ jsxs44("div", { className: "space-y-4", id: "tags-content", children: [
|
|
10650
|
-
/* @__PURE__ */
|
|
10709
|
+
/* @__PURE__ */ jsx67("div", { className: "flex flex-wrap gap-2", role: "group", "aria-label": "Product tags filter", children: items.map((item) => /* @__PURE__ */ jsxs44(
|
|
10651
10710
|
"button",
|
|
10652
10711
|
{
|
|
10653
10712
|
onClick: () => refine(item.value),
|
|
@@ -10658,15 +10717,15 @@ function TagsSection({
|
|
|
10658
10717
|
"aria-label": `${item.isRefined ? "Remove" : "Apply"} ${item.label} filter${showCounts ? ` (${item.count} products)` : ""}`,
|
|
10659
10718
|
"aria-pressed": item.isRefined,
|
|
10660
10719
|
children: [
|
|
10661
|
-
/* @__PURE__ */
|
|
10662
|
-
showCounts && /* @__PURE__ */
|
|
10720
|
+
/* @__PURE__ */ jsx67("span", { "aria-hidden": "true", children: item.label }),
|
|
10721
|
+
showCounts && /* @__PURE__ */ jsx67("span", { className: `text-xs font-caption ${item.isRefined ? "opacity-80" : "opacity-60"}`, "aria-hidden": "true", children: item.count })
|
|
10663
10722
|
]
|
|
10664
10723
|
},
|
|
10665
10724
|
item.value
|
|
10666
10725
|
)) }),
|
|
10667
10726
|
/* @__PURE__ */ jsxs44("div", { className: "flex items-center justify-between pt-2", children: [
|
|
10668
|
-
/* @__PURE__ */
|
|
10669
|
-
/* @__PURE__ */
|
|
10727
|
+
/* @__PURE__ */ jsx67("span", { className: "text-sm font-label text-foreground/60", id: "show-counts-label", children: "Show counts" }),
|
|
10728
|
+
/* @__PURE__ */ jsx67(
|
|
10670
10729
|
"button",
|
|
10671
10730
|
{
|
|
10672
10731
|
onClick: () => setShowCounts(!showCounts),
|
|
@@ -10674,7 +10733,7 @@ function TagsSection({
|
|
|
10674
10733
|
role: "switch",
|
|
10675
10734
|
"aria-checked": showCounts,
|
|
10676
10735
|
"aria-labelledby": "show-counts-label",
|
|
10677
|
-
children: /* @__PURE__ */
|
|
10736
|
+
children: /* @__PURE__ */ jsx67(
|
|
10678
10737
|
"span",
|
|
10679
10738
|
{
|
|
10680
10739
|
className: `inline-block h-4 w-4 transform rounded-full bg-background shadow-sm transition-transform ${showCounts ? "translate-x-6" : "translate-x-1"}`,
|
|
@@ -10691,11 +10750,11 @@ function PriceSection() {
|
|
|
10691
10750
|
const { range, refine, start, canRefine } = useRange({ attribute: "price" });
|
|
10692
10751
|
const rangeMin = typeof range.min === "number" && isFinite(range.min) ? range.min : 0;
|
|
10693
10752
|
const rangeMax = typeof range.max === "number" && isFinite(range.max) ? range.max : 15e3;
|
|
10694
|
-
const [localRange, setLocalRange] =
|
|
10753
|
+
const [localRange, setLocalRange] = useState35([
|
|
10695
10754
|
typeof start?.[0] === "number" && isFinite(start[0]) ? start[0] : rangeMin,
|
|
10696
10755
|
typeof start?.[1] === "number" && isFinite(start[1]) ? start[1] : rangeMax
|
|
10697
10756
|
]);
|
|
10698
|
-
|
|
10757
|
+
useEffect37(() => {
|
|
10699
10758
|
if (start && Array.isArray(start)) {
|
|
10700
10759
|
setLocalRange([
|
|
10701
10760
|
typeof start[0] === "number" && isFinite(start[0]) ? start[0] : rangeMin,
|
|
@@ -10705,7 +10764,7 @@ function PriceSection() {
|
|
|
10705
10764
|
setLocalRange([rangeMin, rangeMax]);
|
|
10706
10765
|
}
|
|
10707
10766
|
}, [start, rangeMin, rangeMax]);
|
|
10708
|
-
const [isExpanded, setIsExpanded] =
|
|
10767
|
+
const [isExpanded, setIsExpanded] = useState35(true);
|
|
10709
10768
|
if (!canRefine) {
|
|
10710
10769
|
return null;
|
|
10711
10770
|
}
|
|
@@ -10729,8 +10788,8 @@ function PriceSection() {
|
|
|
10729
10788
|
"aria-expanded": isExpanded,
|
|
10730
10789
|
"aria-controls": "price-content",
|
|
10731
10790
|
children: [
|
|
10732
|
-
/* @__PURE__ */
|
|
10733
|
-
/* @__PURE__ */
|
|
10791
|
+
/* @__PURE__ */ jsx67("h3", { className: "text-base font-semibold text-primary", children: "Price" }),
|
|
10792
|
+
/* @__PURE__ */ jsx67(
|
|
10734
10793
|
"svg",
|
|
10735
10794
|
{
|
|
10736
10795
|
className: `w-5 h-5 transition-transform text-foreground/40 group-hover:text-foreground/60 ${isExpanded ? "rotate-180" : ""}`,
|
|
@@ -10739,7 +10798,7 @@ function PriceSection() {
|
|
|
10739
10798
|
stroke: "currentColor",
|
|
10740
10799
|
strokeWidth: 2.5,
|
|
10741
10800
|
"aria-hidden": "true",
|
|
10742
|
-
children: /* @__PURE__ */
|
|
10801
|
+
children: /* @__PURE__ */ jsx67("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
|
|
10743
10802
|
}
|
|
10744
10803
|
)
|
|
10745
10804
|
]
|
|
@@ -10747,14 +10806,14 @@ function PriceSection() {
|
|
|
10747
10806
|
),
|
|
10748
10807
|
isExpanded && /* @__PURE__ */ jsxs44("div", { className: "space-y-6", id: "price-content", children: [
|
|
10749
10808
|
/* @__PURE__ */ jsxs44("div", { className: "flex items-center justify-between text-sm font-display", children: [
|
|
10750
|
-
/* @__PURE__ */
|
|
10751
|
-
/* @__PURE__ */
|
|
10809
|
+
/* @__PURE__ */ jsx67("span", { children: formatPrice2(localRange[0]) }),
|
|
10810
|
+
/* @__PURE__ */ jsx67("span", { className: "text-foreground/70", children: formatPrice2(localRange[1]) })
|
|
10752
10811
|
] }),
|
|
10753
|
-
/* @__PURE__ */
|
|
10812
|
+
/* @__PURE__ */ jsx67("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) => {
|
|
10754
10813
|
const totalBars = 19;
|
|
10755
10814
|
const barPrice = rangeMin + (rangeMax - rangeMin) / totalBars * i;
|
|
10756
10815
|
const isInRange = barPrice >= localRange[0] && barPrice <= localRange[1];
|
|
10757
|
-
return /* @__PURE__ */
|
|
10816
|
+
return /* @__PURE__ */ jsx67(
|
|
10758
10817
|
"div",
|
|
10759
10818
|
{
|
|
10760
10819
|
className: `flex-1 rounded-t-sm transition-opacity ${isInRange ? "bg-foreground" : "bg-foreground/20"}`,
|
|
@@ -10763,7 +10822,7 @@ function PriceSection() {
|
|
|
10763
10822
|
i
|
|
10764
10823
|
);
|
|
10765
10824
|
}) }),
|
|
10766
|
-
/* @__PURE__ */
|
|
10825
|
+
/* @__PURE__ */ jsx67("div", { style: { touchAction: "none" }, className: "my-6", children: /* @__PURE__ */ jsxs44(
|
|
10767
10826
|
Slider2.Root,
|
|
10768
10827
|
{
|
|
10769
10828
|
className: "relative flex w-full touch-none select-none items-center",
|
|
@@ -10781,8 +10840,8 @@ function PriceSection() {
|
|
|
10781
10840
|
step: 1,
|
|
10782
10841
|
minStepsBetweenThumbs: 1,
|
|
10783
10842
|
children: [
|
|
10784
|
-
/* @__PURE__ */
|
|
10785
|
-
/* @__PURE__ */
|
|
10843
|
+
/* @__PURE__ */ jsx67(Slider2.Track, { className: "relative h-3 w-full grow overflow-hidden rounded-full bg-foreground/20", children: /* @__PURE__ */ jsx67(Slider2.Range, { className: "absolute h-full bg-foreground" }) }),
|
|
10844
|
+
/* @__PURE__ */ jsx67(
|
|
10786
10845
|
Slider2.Thumb,
|
|
10787
10846
|
{
|
|
10788
10847
|
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",
|
|
@@ -10796,7 +10855,7 @@ function PriceSection() {
|
|
|
10796
10855
|
"aria-valuetext": formatPrice2(localRange[0])
|
|
10797
10856
|
}
|
|
10798
10857
|
),
|
|
10799
|
-
/* @__PURE__ */
|
|
10858
|
+
/* @__PURE__ */ jsx67(
|
|
10800
10859
|
Slider2.Thumb,
|
|
10801
10860
|
{
|
|
10802
10861
|
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",
|
|
@@ -10815,8 +10874,8 @@ function PriceSection() {
|
|
|
10815
10874
|
) }),
|
|
10816
10875
|
/* @__PURE__ */ jsxs44("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
10817
10876
|
/* @__PURE__ */ jsxs44("div", { children: [
|
|
10818
|
-
/* @__PURE__ */
|
|
10819
|
-
/* @__PURE__ */
|
|
10877
|
+
/* @__PURE__ */ jsx67("label", { htmlFor: "price-min", className: "text-xs font-label text-foreground/60 mb-1.5 block", children: "Min" }),
|
|
10878
|
+
/* @__PURE__ */ jsx67(
|
|
10820
10879
|
"input",
|
|
10821
10880
|
{
|
|
10822
10881
|
id: "price-min",
|
|
@@ -10835,8 +10894,8 @@ function PriceSection() {
|
|
|
10835
10894
|
)
|
|
10836
10895
|
] }),
|
|
10837
10896
|
/* @__PURE__ */ jsxs44("div", { children: [
|
|
10838
|
-
/* @__PURE__ */
|
|
10839
|
-
/* @__PURE__ */
|
|
10897
|
+
/* @__PURE__ */ jsx67("label", { htmlFor: "price-max", className: "text-xs font-label text-foreground/60 mb-1.5 block", children: "Max" }),
|
|
10898
|
+
/* @__PURE__ */ jsx67(
|
|
10840
10899
|
"input",
|
|
10841
10900
|
{
|
|
10842
10901
|
id: "price-max",
|
|
@@ -10860,11 +10919,11 @@ function PriceSection() {
|
|
|
10860
10919
|
}
|
|
10861
10920
|
|
|
10862
10921
|
// src/composed/search/Filters.tsx
|
|
10863
|
-
import { Fragment as
|
|
10922
|
+
import { Fragment as Fragment14, jsx as jsx68, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
10864
10923
|
function Filters({ buttonClassName, buttonText }) {
|
|
10865
|
-
const [isOpen, setIsOpen] =
|
|
10866
|
-
return /* @__PURE__ */ jsxs45(
|
|
10867
|
-
/* @__PURE__ */
|
|
10924
|
+
const [isOpen, setIsOpen] = useState36(false);
|
|
10925
|
+
return /* @__PURE__ */ jsxs45(Fragment14, { children: [
|
|
10926
|
+
/* @__PURE__ */ jsx68(
|
|
10868
10927
|
FiltersButton,
|
|
10869
10928
|
{
|
|
10870
10929
|
onClick: () => setIsOpen(true),
|
|
@@ -10872,14 +10931,14 @@ function Filters({ buttonClassName, buttonText }) {
|
|
|
10872
10931
|
children: buttonText
|
|
10873
10932
|
}
|
|
10874
10933
|
),
|
|
10875
|
-
/* @__PURE__ */
|
|
10934
|
+
/* @__PURE__ */ jsx68(FiltersDrawer, { isOpen, onClose: () => setIsOpen(false) })
|
|
10876
10935
|
] });
|
|
10877
10936
|
}
|
|
10878
10937
|
|
|
10879
10938
|
// src/composed/search/CurrentRefinements.tsx
|
|
10880
10939
|
import { useCurrentRefinements } from "react-instantsearch";
|
|
10881
10940
|
import { X as LucideX3 } from "lucide-react";
|
|
10882
|
-
import { jsx as
|
|
10941
|
+
import { jsx as jsx69, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
10883
10942
|
var XIcon3 = LucideX3;
|
|
10884
10943
|
function CurrentRefinements() {
|
|
10885
10944
|
const { items, refine } = useCurrentRefinements();
|
|
@@ -10925,15 +10984,15 @@ function CurrentRefinements() {
|
|
|
10925
10984
|
if (allRefinements.length === 0) {
|
|
10926
10985
|
return null;
|
|
10927
10986
|
}
|
|
10928
|
-
return /* @__PURE__ */
|
|
10987
|
+
return /* @__PURE__ */ jsx69("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__ */ jsxs46(
|
|
10929
10988
|
"button",
|
|
10930
10989
|
{
|
|
10931
10990
|
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",
|
|
10932
10991
|
onClick: () => refinement.refine(),
|
|
10933
10992
|
"aria-label": `Remove filter: ${refinement.displayLabel}`,
|
|
10934
10993
|
children: [
|
|
10935
|
-
/* @__PURE__ */
|
|
10936
|
-
/* @__PURE__ */
|
|
10994
|
+
/* @__PURE__ */ jsx69("span", { className: "truncate", children: refinement.displayLabel }),
|
|
10995
|
+
/* @__PURE__ */ jsx69(XIcon3, { className: "w-3 h-3" })
|
|
10937
10996
|
]
|
|
10938
10997
|
},
|
|
10939
10998
|
`${refinement.attribute}-${refinement.value}-${index}`
|
|
@@ -10957,12 +11016,12 @@ var FACET_SECTIONS = [
|
|
|
10957
11016
|
];
|
|
10958
11017
|
|
|
10959
11018
|
// src/composed/zoom/ResponsiveZoom.tsx
|
|
10960
|
-
import { useState as
|
|
11019
|
+
import { useState as useState39, useEffect as useEffect39 } from "react";
|
|
10961
11020
|
|
|
10962
11021
|
// src/composed/zoom/ZoomOverlay.tsx
|
|
10963
|
-
import { useState as
|
|
11022
|
+
import { useState as useState37, useCallback as useCallback20 } from "react";
|
|
10964
11023
|
import { Plus as LucidePlus2, Minus as LucideMinus2 } from "lucide-react";
|
|
10965
|
-
import { Fragment as
|
|
11024
|
+
import { Fragment as Fragment15, jsx as jsx70, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
10966
11025
|
var PlusIcon2 = LucidePlus2;
|
|
10967
11026
|
var MinusIcon2 = LucideMinus2;
|
|
10968
11027
|
function ZoomOverlay({
|
|
@@ -10974,12 +11033,12 @@ function ZoomOverlay({
|
|
|
10974
11033
|
className,
|
|
10975
11034
|
style
|
|
10976
11035
|
}) {
|
|
10977
|
-
const [zoomedImageIndex, setZoomedImageIndex] =
|
|
10978
|
-
const [zoomOrigin, setZoomOrigin] =
|
|
10979
|
-
const [hoveredImageIndex, setHoveredImageIndex] =
|
|
10980
|
-
const [cursorPos, setCursorPos] =
|
|
10981
|
-
const [announcement, setAnnouncement] =
|
|
10982
|
-
const [isZooming, setIsZooming] =
|
|
11036
|
+
const [zoomedImageIndex, setZoomedImageIndex] = useState37(null);
|
|
11037
|
+
const [zoomOrigin, setZoomOrigin] = useState37({ x: 50, y: 50 });
|
|
11038
|
+
const [hoveredImageIndex, setHoveredImageIndex] = useState37(null);
|
|
11039
|
+
const [cursorPos, setCursorPos] = useState37({ x: 0, y: 0 });
|
|
11040
|
+
const [announcement, setAnnouncement] = useState37("");
|
|
11041
|
+
const [isZooming, setIsZooming] = useState37(false);
|
|
10983
11042
|
const handleZoomClick = useCallback20(
|
|
10984
11043
|
(e) => {
|
|
10985
11044
|
e.stopPropagation();
|
|
@@ -11021,9 +11080,9 @@ function ZoomOverlay({
|
|
|
11021
11080
|
const isZoomed = zoomedImageIndex === imageIndex;
|
|
11022
11081
|
const isHovered = hoveredImageIndex === imageIndex;
|
|
11023
11082
|
const cursorStyle = isLargeTouchDevice ? "pointer" : isTouchDevice ? "default" : "none";
|
|
11024
|
-
return /* @__PURE__ */ jsxs47(
|
|
11025
|
-
/* @__PURE__ */
|
|
11026
|
-
/* @__PURE__ */
|
|
11083
|
+
return /* @__PURE__ */ jsxs47(Fragment15, { children: [
|
|
11084
|
+
/* @__PURE__ */ jsx70("div", { className: "sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement }),
|
|
11085
|
+
/* @__PURE__ */ jsx70(
|
|
11027
11086
|
"div",
|
|
11028
11087
|
{
|
|
11029
11088
|
className,
|
|
@@ -11031,7 +11090,7 @@ function ZoomOverlay({
|
|
|
11031
11090
|
...style,
|
|
11032
11091
|
position: "relative"
|
|
11033
11092
|
},
|
|
11034
|
-
children: /* @__PURE__ */
|
|
11093
|
+
children: /* @__PURE__ */ jsx70(
|
|
11035
11094
|
"div",
|
|
11036
11095
|
{
|
|
11037
11096
|
style: {
|
|
@@ -11054,7 +11113,7 @@ function ZoomOverlay({
|
|
|
11054
11113
|
handleZoomClick(e);
|
|
11055
11114
|
}
|
|
11056
11115
|
},
|
|
11057
|
-
children: /* @__PURE__ */
|
|
11116
|
+
children: /* @__PURE__ */ jsx70(
|
|
11058
11117
|
"div",
|
|
11059
11118
|
{
|
|
11060
11119
|
style: {
|
|
@@ -11070,7 +11129,7 @@ function ZoomOverlay({
|
|
|
11070
11129
|
)
|
|
11071
11130
|
}
|
|
11072
11131
|
),
|
|
11073
|
-
isHovered && !isTouchDevice && /* @__PURE__ */
|
|
11132
|
+
isHovered && !isTouchDevice && /* @__PURE__ */ jsx70(
|
|
11074
11133
|
"div",
|
|
11075
11134
|
{
|
|
11076
11135
|
className: "fixed pointer-events-none z-50 hidden md:block",
|
|
@@ -11080,7 +11139,7 @@ function ZoomOverlay({
|
|
|
11080
11139
|
transform: "translate(-50%, -50%)"
|
|
11081
11140
|
},
|
|
11082
11141
|
"aria-hidden": "true",
|
|
11083
|
-
children: /* @__PURE__ */
|
|
11142
|
+
children: /* @__PURE__ */ jsx70("div", { className: "bg-white dark:bg-gray-800 rounded-full p-2 shadow-sm dark:shadow-gray-950/50", children: isZoomed ? /* @__PURE__ */ jsx70(
|
|
11084
11143
|
MinusIcon2,
|
|
11085
11144
|
{
|
|
11086
11145
|
size: 20,
|
|
@@ -11088,7 +11147,7 @@ function ZoomOverlay({
|
|
|
11088
11147
|
strokeWidth: 1.5,
|
|
11089
11148
|
"aria-hidden": "true"
|
|
11090
11149
|
}
|
|
11091
|
-
) : /* @__PURE__ */
|
|
11150
|
+
) : /* @__PURE__ */ jsx70(
|
|
11092
11151
|
PlusIcon2,
|
|
11093
11152
|
{
|
|
11094
11153
|
size: 20,
|
|
@@ -11104,9 +11163,9 @@ function ZoomOverlay({
|
|
|
11104
11163
|
|
|
11105
11164
|
// src/composed/zoom/EnhancedImageViewer.tsx
|
|
11106
11165
|
import {
|
|
11107
|
-
useState as
|
|
11166
|
+
useState as useState38,
|
|
11108
11167
|
useRef as useRef25,
|
|
11109
|
-
useEffect as
|
|
11168
|
+
useEffect as useEffect38,
|
|
11110
11169
|
useLayoutEffect as useLayoutEffect6,
|
|
11111
11170
|
useCallback as useCallback21
|
|
11112
11171
|
} from "react";
|
|
@@ -11116,7 +11175,7 @@ import {
|
|
|
11116
11175
|
TransformComponent as OriginalTransformComponent
|
|
11117
11176
|
} from "react-zoom-pan-pinch";
|
|
11118
11177
|
import { X as X2 } from "lucide-react";
|
|
11119
|
-
import { Fragment as
|
|
11178
|
+
import { Fragment as Fragment16, jsx as jsx71, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
11120
11179
|
var TransformWrapper = OriginalTransformWrapper;
|
|
11121
11180
|
var TransformComponent = OriginalTransformComponent;
|
|
11122
11181
|
var EnhancedImageViewer = ({
|
|
@@ -11127,11 +11186,11 @@ var EnhancedImageViewer = ({
|
|
|
11127
11186
|
onIndexChange,
|
|
11128
11187
|
currentIndex: propCurrentIndex
|
|
11129
11188
|
}) => {
|
|
11130
|
-
const [isMounted, setIsMounted] =
|
|
11131
|
-
const [isClient, setIsClient] =
|
|
11132
|
-
const [scale, setScale] =
|
|
11133
|
-
const [cropDimensions, setCropDimensions] =
|
|
11134
|
-
const [currentZoomScale, setCurrentZoomScale] =
|
|
11189
|
+
const [isMounted, setIsMounted] = useState38(false);
|
|
11190
|
+
const [isClient, setIsClient] = useState38(false);
|
|
11191
|
+
const [scale, setScale] = useState38({ initial: 1, min: 1, max: 8 });
|
|
11192
|
+
const [cropDimensions, setCropDimensions] = useState38({ width: 0, height: 0 });
|
|
11193
|
+
const [currentZoomScale, setCurrentZoomScale] = useState38(1);
|
|
11135
11194
|
const imgRef = useRef25(null);
|
|
11136
11195
|
const touchStartRef = useRef25(
|
|
11137
11196
|
null
|
|
@@ -11161,17 +11220,17 @@ var EnhancedImageViewer = ({
|
|
|
11161
11220
|
document.body.style.overflow = "";
|
|
11162
11221
|
};
|
|
11163
11222
|
}, [calculateScale]);
|
|
11164
|
-
|
|
11223
|
+
useEffect38(() => {
|
|
11165
11224
|
calculateScale();
|
|
11166
11225
|
}, [calculateScale]);
|
|
11167
|
-
|
|
11226
|
+
useEffect38(() => {
|
|
11168
11227
|
const handleResize = () => {
|
|
11169
11228
|
calculateScale();
|
|
11170
11229
|
};
|
|
11171
11230
|
window.addEventListener("resize", handleResize);
|
|
11172
11231
|
return () => window.removeEventListener("resize", handleResize);
|
|
11173
11232
|
}, [calculateScale]);
|
|
11174
|
-
|
|
11233
|
+
useEffect38(() => {
|
|
11175
11234
|
const handleKeyDown = (e) => {
|
|
11176
11235
|
if (e.key === "Escape") {
|
|
11177
11236
|
onClose();
|
|
@@ -11256,12 +11315,12 @@ var EnhancedImageViewer = ({
|
|
|
11256
11315
|
);
|
|
11257
11316
|
if (!isMounted || !isClient) {
|
|
11258
11317
|
return createPortal3(
|
|
11259
|
-
/* @__PURE__ */
|
|
11318
|
+
/* @__PURE__ */ jsx71(
|
|
11260
11319
|
"div",
|
|
11261
11320
|
{
|
|
11262
11321
|
className: "fixed inset-0 bg-black flex items-center justify-center",
|
|
11263
11322
|
style: { zIndex: 999999 },
|
|
11264
|
-
children: /* @__PURE__ */
|
|
11323
|
+
children: /* @__PURE__ */ jsx71(
|
|
11265
11324
|
"div",
|
|
11266
11325
|
{
|
|
11267
11326
|
style: {
|
|
@@ -11286,7 +11345,7 @@ var EnhancedImageViewer = ({
|
|
|
11286
11345
|
"aria-modal": "true",
|
|
11287
11346
|
"aria-label": "Image viewer",
|
|
11288
11347
|
children: [
|
|
11289
|
-
/* @__PURE__ */
|
|
11348
|
+
/* @__PURE__ */ jsx71(
|
|
11290
11349
|
"button",
|
|
11291
11350
|
{
|
|
11292
11351
|
onClick: (e) => {
|
|
@@ -11312,10 +11371,10 @@ var EnhancedImageViewer = ({
|
|
|
11312
11371
|
touchAction: "manipulation",
|
|
11313
11372
|
marginBottom: "env(safe-area-inset-bottom, 0px)"
|
|
11314
11373
|
},
|
|
11315
|
-
children: /* @__PURE__ */
|
|
11374
|
+
children: /* @__PURE__ */ jsx71(X2, { className: "w-7 h-7", strokeWidth: 2.5 })
|
|
11316
11375
|
}
|
|
11317
11376
|
),
|
|
11318
|
-
/* @__PURE__ */
|
|
11377
|
+
/* @__PURE__ */ jsx71(
|
|
11319
11378
|
TransformWrapper,
|
|
11320
11379
|
{
|
|
11321
11380
|
initialScale: scale.initial,
|
|
@@ -11362,14 +11421,14 @@ var EnhancedImageViewer = ({
|
|
|
11362
11421
|
onTouchStart: handleTouchStart,
|
|
11363
11422
|
onTouchEnd: handleTouchEnd,
|
|
11364
11423
|
children: [
|
|
11365
|
-
/* @__PURE__ */
|
|
11424
|
+
/* @__PURE__ */ jsx71(
|
|
11366
11425
|
TransformComponent,
|
|
11367
11426
|
{
|
|
11368
11427
|
wrapperStyle: {
|
|
11369
11428
|
width: "100%",
|
|
11370
11429
|
height: "100%"
|
|
11371
11430
|
},
|
|
11372
|
-
children: /* @__PURE__ */
|
|
11431
|
+
children: /* @__PURE__ */ jsx71(
|
|
11373
11432
|
"div",
|
|
11374
11433
|
{
|
|
11375
11434
|
style: {
|
|
@@ -11380,8 +11439,8 @@ var EnhancedImageViewer = ({
|
|
|
11380
11439
|
alignItems: "center",
|
|
11381
11440
|
justifyContent: "center"
|
|
11382
11441
|
},
|
|
11383
|
-
children: /* @__PURE__ */
|
|
11384
|
-
|
|
11442
|
+
children: /* @__PURE__ */ jsx71(
|
|
11443
|
+
SafeImg,
|
|
11385
11444
|
{
|
|
11386
11445
|
ref: imgRef,
|
|
11387
11446
|
src: imageUrl,
|
|
@@ -11402,7 +11461,7 @@ var EnhancedImageViewer = ({
|
|
|
11402
11461
|
}
|
|
11403
11462
|
),
|
|
11404
11463
|
/* @__PURE__ */ jsxs48("div", { className: "fixed bottom-5 left-0 right-0 z-50", children: [
|
|
11405
|
-
/* @__PURE__ */
|
|
11464
|
+
/* @__PURE__ */ jsx71("div", { className: "flex justify-center gap-2", children: (() => {
|
|
11406
11465
|
let currentIndex = propCurrentIndex !== void 0 ? propCurrentIndex : -1;
|
|
11407
11466
|
if (currentIndex === -1) {
|
|
11408
11467
|
currentIndex = images.findIndex(
|
|
@@ -11435,8 +11494,8 @@ var EnhancedImageViewer = ({
|
|
|
11435
11494
|
};
|
|
11436
11495
|
const nextIndex = findNextAvailableIndex(currentIndex, 1);
|
|
11437
11496
|
const prevIndex = findNextAvailableIndex(currentIndex, -1);
|
|
11438
|
-
return /* @__PURE__ */ jsxs48(
|
|
11439
|
-
/* @__PURE__ */
|
|
11497
|
+
return /* @__PURE__ */ jsxs48(Fragment16, { children: [
|
|
11498
|
+
/* @__PURE__ */ jsx71(
|
|
11440
11499
|
"button",
|
|
11441
11500
|
{
|
|
11442
11501
|
onClick: () => {
|
|
@@ -11449,7 +11508,7 @@ var EnhancedImageViewer = ({
|
|
|
11449
11508
|
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"}`,
|
|
11450
11509
|
style: { touchAction: "manipulation" },
|
|
11451
11510
|
"aria-label": "Previous image",
|
|
11452
|
-
children: /* @__PURE__ */
|
|
11511
|
+
children: /* @__PURE__ */ jsx71(
|
|
11453
11512
|
"svg",
|
|
11454
11513
|
{
|
|
11455
11514
|
className: "w-4 h-4",
|
|
@@ -11457,7 +11516,7 @@ var EnhancedImageViewer = ({
|
|
|
11457
11516
|
stroke: "currentColor",
|
|
11458
11517
|
viewBox: "0 0 24 24",
|
|
11459
11518
|
"aria-hidden": "true",
|
|
11460
|
-
children: /* @__PURE__ */
|
|
11519
|
+
children: /* @__PURE__ */ jsx71(
|
|
11461
11520
|
"path",
|
|
11462
11521
|
{
|
|
11463
11522
|
strokeLinecap: "round",
|
|
@@ -11470,7 +11529,7 @@ var EnhancedImageViewer = ({
|
|
|
11470
11529
|
)
|
|
11471
11530
|
}
|
|
11472
11531
|
),
|
|
11473
|
-
/* @__PURE__ */
|
|
11532
|
+
/* @__PURE__ */ jsx71(
|
|
11474
11533
|
"button",
|
|
11475
11534
|
{
|
|
11476
11535
|
onClick: () => {
|
|
@@ -11483,7 +11542,7 @@ var EnhancedImageViewer = ({
|
|
|
11483
11542
|
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"}`,
|
|
11484
11543
|
style: { touchAction: "manipulation" },
|
|
11485
11544
|
"aria-label": "Next image",
|
|
11486
|
-
children: /* @__PURE__ */
|
|
11545
|
+
children: /* @__PURE__ */ jsx71(
|
|
11487
11546
|
"svg",
|
|
11488
11547
|
{
|
|
11489
11548
|
className: "w-4 h-4",
|
|
@@ -11491,7 +11550,7 @@ var EnhancedImageViewer = ({
|
|
|
11491
11550
|
stroke: "currentColor",
|
|
11492
11551
|
viewBox: "0 0 24 24",
|
|
11493
11552
|
"aria-hidden": "true",
|
|
11494
|
-
children: /* @__PURE__ */
|
|
11553
|
+
children: /* @__PURE__ */ jsx71(
|
|
11495
11554
|
"path",
|
|
11496
11555
|
{
|
|
11497
11556
|
strokeLinecap: "round",
|
|
@@ -11506,7 +11565,7 @@ var EnhancedImageViewer = ({
|
|
|
11506
11565
|
)
|
|
11507
11566
|
] });
|
|
11508
11567
|
})() }),
|
|
11509
|
-
/* @__PURE__ */
|
|
11568
|
+
/* @__PURE__ */ jsx71("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: (() => {
|
|
11510
11569
|
const total = Math.max(images.length, 1);
|
|
11511
11570
|
const current = propCurrentIndex !== void 0 ? Math.min(propCurrentIndex + 1, total) : 1;
|
|
11512
11571
|
return `${current} / ${total}`;
|
|
@@ -11518,7 +11577,7 @@ var EnhancedImageViewer = ({
|
|
|
11518
11577
|
},
|
|
11519
11578
|
`${scale.initial}-${scale.min}-${scale.max}`
|
|
11520
11579
|
),
|
|
11521
|
-
/* @__PURE__ */
|
|
11580
|
+
/* @__PURE__ */ jsx71(
|
|
11522
11581
|
"div",
|
|
11523
11582
|
{
|
|
11524
11583
|
className: "absolute inset-0 bg-black",
|
|
@@ -11537,7 +11596,7 @@ var EnhancedImageViewer = ({
|
|
|
11537
11596
|
};
|
|
11538
11597
|
|
|
11539
11598
|
// src/composed/zoom/ResponsiveZoom.tsx
|
|
11540
|
-
import { Fragment as
|
|
11599
|
+
import { Fragment as Fragment17, jsx as jsx72, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
11541
11600
|
function ResponsiveZoom({
|
|
11542
11601
|
imageIndex,
|
|
11543
11602
|
children,
|
|
@@ -11547,11 +11606,11 @@ function ResponsiveZoom({
|
|
|
11547
11606
|
imageUrl,
|
|
11548
11607
|
alt = "Product image"
|
|
11549
11608
|
}) {
|
|
11550
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
11551
|
-
const [showEnhancedViewer, setShowEnhancedViewer] =
|
|
11552
|
-
const [viewerIndex, setViewerIndex] =
|
|
11553
|
-
const [currentImageUrl, setCurrentImageUrl] =
|
|
11554
|
-
|
|
11609
|
+
const [isTouchDevice, setIsTouchDevice] = useState39(false);
|
|
11610
|
+
const [showEnhancedViewer, setShowEnhancedViewer] = useState39(false);
|
|
11611
|
+
const [viewerIndex, setViewerIndex] = useState39(0);
|
|
11612
|
+
const [currentImageUrl, setCurrentImageUrl] = useState39(imageUrl || "");
|
|
11613
|
+
useEffect39(() => {
|
|
11555
11614
|
const checkDeviceType = () => {
|
|
11556
11615
|
const hasTouch = "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
11557
11616
|
setIsTouchDevice(hasTouch);
|
|
@@ -11578,8 +11637,8 @@ function ResponsiveZoom({
|
|
|
11578
11637
|
}
|
|
11579
11638
|
}
|
|
11580
11639
|
};
|
|
11581
|
-
return /* @__PURE__ */ jsxs49(
|
|
11582
|
-
isTouchDevice ? /* @__PURE__ */
|
|
11640
|
+
return /* @__PURE__ */ jsxs49(Fragment17, { children: [
|
|
11641
|
+
isTouchDevice ? /* @__PURE__ */ jsx72(
|
|
11583
11642
|
"div",
|
|
11584
11643
|
{
|
|
11585
11644
|
className,
|
|
@@ -11596,7 +11655,7 @@ function ResponsiveZoom({
|
|
|
11596
11655
|
},
|
|
11597
11656
|
children
|
|
11598
11657
|
}
|
|
11599
|
-
) : /* @__PURE__ */
|
|
11658
|
+
) : /* @__PURE__ */ jsx72(
|
|
11600
11659
|
ZoomOverlay,
|
|
11601
11660
|
{
|
|
11602
11661
|
imageIndex,
|
|
@@ -11607,7 +11666,7 @@ function ResponsiveZoom({
|
|
|
11607
11666
|
children
|
|
11608
11667
|
}
|
|
11609
11668
|
),
|
|
11610
|
-
showEnhancedViewer && isTouchDevice && currentImageUrl && /* @__PURE__ */
|
|
11669
|
+
showEnhancedViewer && isTouchDevice && currentImageUrl && /* @__PURE__ */ jsx72(
|
|
11611
11670
|
EnhancedImageViewer,
|
|
11612
11671
|
{
|
|
11613
11672
|
imageUrl: currentImageUrl,
|
|
@@ -11631,14 +11690,37 @@ function ResponsiveZoom({
|
|
|
11631
11690
|
|
|
11632
11691
|
// src/composed/carousels/MobileProductCarousel.tsx
|
|
11633
11692
|
import {
|
|
11634
|
-
useState as
|
|
11693
|
+
useState as useState40,
|
|
11635
11694
|
useRef as useRef26,
|
|
11636
|
-
useEffect as
|
|
11695
|
+
useEffect as useEffect40,
|
|
11637
11696
|
useCallback as useCallback22,
|
|
11638
11697
|
useMemo as useMemo15,
|
|
11639
11698
|
memo as memo4
|
|
11640
11699
|
} from "react";
|
|
11641
|
-
import { jsx as
|
|
11700
|
+
import { jsx as jsx73, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
11701
|
+
function StaticCarouselImage({
|
|
11702
|
+
src,
|
|
11703
|
+
alt,
|
|
11704
|
+
className
|
|
11705
|
+
}) {
|
|
11706
|
+
const [failed, setFailed] = useState40(false);
|
|
11707
|
+
if (failed || !src) {
|
|
11708
|
+
return /* @__PURE__ */ jsx73("div", { className: `bg-muted ${className ?? ""}`, role: "img", "aria-label": alt });
|
|
11709
|
+
}
|
|
11710
|
+
return /* @__PURE__ */ jsx73(
|
|
11711
|
+
"img",
|
|
11712
|
+
{
|
|
11713
|
+
src,
|
|
11714
|
+
alt,
|
|
11715
|
+
crossOrigin: "anonymous",
|
|
11716
|
+
className,
|
|
11717
|
+
loading: "lazy",
|
|
11718
|
+
decoding: "async",
|
|
11719
|
+
draggable: false,
|
|
11720
|
+
onError: () => setFailed(true)
|
|
11721
|
+
}
|
|
11722
|
+
);
|
|
11723
|
+
}
|
|
11642
11724
|
var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
11643
11725
|
images,
|
|
11644
11726
|
currentIndex = 0,
|
|
@@ -11654,23 +11736,23 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
11654
11736
|
mockupWidth,
|
|
11655
11737
|
onMockupUrlGenerated
|
|
11656
11738
|
}) {
|
|
11657
|
-
const [activeIndex, setActiveIndex] =
|
|
11658
|
-
const [touchStart, setTouchStart] =
|
|
11739
|
+
const [activeIndex, setActiveIndex] = useState40(currentIndex);
|
|
11740
|
+
const [touchStart, setTouchStart] = useState40(
|
|
11659
11741
|
null
|
|
11660
11742
|
);
|
|
11661
|
-
const [touchEnd, setTouchEnd] =
|
|
11743
|
+
const [touchEnd, setTouchEnd] = useState40(
|
|
11662
11744
|
null
|
|
11663
11745
|
);
|
|
11664
|
-
const [showImageViewer, setShowImageViewer] =
|
|
11665
|
-
const [viewerKey, setViewerKey] =
|
|
11666
|
-
const [isDragging, setIsDragging] =
|
|
11667
|
-
const [dragOffset, setDragOffset] =
|
|
11668
|
-
const [isTransitioning, setIsTransitioning] =
|
|
11669
|
-
const [isHorizontalSwipe, setIsHorizontalSwipe] =
|
|
11746
|
+
const [showImageViewer, setShowImageViewer] = useState40(false);
|
|
11747
|
+
const [viewerKey, setViewerKey] = useState40(0);
|
|
11748
|
+
const [isDragging, setIsDragging] = useState40(false);
|
|
11749
|
+
const [dragOffset, setDragOffset] = useState40(0);
|
|
11750
|
+
const [isTransitioning, setIsTransitioning] = useState40(false);
|
|
11751
|
+
const [isHorizontalSwipe, setIsHorizontalSwipe] = useState40(
|
|
11670
11752
|
null
|
|
11671
11753
|
);
|
|
11672
|
-
const [isPeeking, setIsPeeking] =
|
|
11673
|
-
const [isPeekReturning, setIsPeekReturning] =
|
|
11754
|
+
const [isPeeking, setIsPeeking] = useState40(false);
|
|
11755
|
+
const [isPeekReturning, setIsPeekReturning] = useState40(false);
|
|
11674
11756
|
const carouselRef = useRef26(null);
|
|
11675
11757
|
const indicatorRef = useRef26(null);
|
|
11676
11758
|
const touchStartRef = useRef26(
|
|
@@ -11681,7 +11763,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
11681
11763
|
const hasSwipedThisSessionRef = useRef26(false);
|
|
11682
11764
|
const generatedUrlsRef = useRef26(/* @__PURE__ */ new Map());
|
|
11683
11765
|
const prevArtworkSrcRef = useRef26(currentArtwork?.src);
|
|
11684
|
-
|
|
11766
|
+
useEffect40(() => {
|
|
11685
11767
|
if (currentArtwork?.src !== prevArtworkSrcRef.current) {
|
|
11686
11768
|
generatedUrlsRef.current.clear();
|
|
11687
11769
|
prevArtworkSrcRef.current = currentArtwork?.src;
|
|
@@ -11697,8 +11779,8 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
11697
11779
|
const shouldHideDots = stickyHeroContext?.shouldHideDots ?? false;
|
|
11698
11780
|
const priorityContext = useMockupPriorityOptional();
|
|
11699
11781
|
const realtimeContext = useRealtimeOptional();
|
|
11700
|
-
const [urlUpdateCounter, setUrlUpdateCounter] =
|
|
11701
|
-
|
|
11782
|
+
const [urlUpdateCounter, setUrlUpdateCounter] = useState40(0);
|
|
11783
|
+
useEffect40(() => {
|
|
11702
11784
|
if (!realtimeContext?.subscribeMockupResults) return;
|
|
11703
11785
|
const unsubscribe = realtimeContext.subscribeMockupResults(() => {
|
|
11704
11786
|
setUrlUpdateCounter((c) => c + 1);
|
|
@@ -11726,10 +11808,10 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
11726
11808
|
});
|
|
11727
11809
|
}, [images, realtimeMockupUrls]);
|
|
11728
11810
|
const minSwipeDistance = 50;
|
|
11729
|
-
|
|
11811
|
+
useEffect40(() => {
|
|
11730
11812
|
setActiveIndex(currentIndex);
|
|
11731
11813
|
}, [currentIndex]);
|
|
11732
|
-
|
|
11814
|
+
useEffect40(() => {
|
|
11733
11815
|
if (!priorityContext) return;
|
|
11734
11816
|
const realMockups = images.map((img, idx) => ({ img, originalIdx: idx })).filter(({ img }) => img.isRealMockup && img.mockupId);
|
|
11735
11817
|
const mockupIdsList = realMockups.map(({ img }) => img.mockupId);
|
|
@@ -11757,7 +11839,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
11757
11839
|
priorityContext.clearMobileCarouselMode?.();
|
|
11758
11840
|
};
|
|
11759
11841
|
}, [priorityContext, activeIndex, images]);
|
|
11760
|
-
|
|
11842
|
+
useEffect40(() => {
|
|
11761
11843
|
const indicator = indicatorRef.current;
|
|
11762
11844
|
if (!indicator) return;
|
|
11763
11845
|
let ticking = false;
|
|
@@ -11822,7 +11904,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
11822
11904
|
} catch {
|
|
11823
11905
|
}
|
|
11824
11906
|
}, []);
|
|
11825
|
-
|
|
11907
|
+
useEffect40(() => {
|
|
11826
11908
|
if (!enablePeekAnimation || images.length <= 1) return;
|
|
11827
11909
|
const tracking = getSwipeTracking();
|
|
11828
11910
|
const newViewCount = tracking.viewsWithoutSwipe + 1;
|
|
@@ -11926,7 +12008,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
11926
12008
|
},
|
|
11927
12009
|
[activeIndex, images.length, onIndexChange, recordSwipe]
|
|
11928
12010
|
);
|
|
11929
|
-
|
|
12011
|
+
useEffect40(() => {
|
|
11930
12012
|
const container = carouselRef.current;
|
|
11931
12013
|
if (!container) return;
|
|
11932
12014
|
const handleTouchStart = (e) => {
|
|
@@ -12019,7 +12101,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12019
12101
|
null
|
|
12020
12102
|
);
|
|
12021
12103
|
const isMouseDraggingRef = useRef26(false);
|
|
12022
|
-
|
|
12104
|
+
useEffect40(() => {
|
|
12023
12105
|
const container = carouselRef.current;
|
|
12024
12106
|
if (!container) return;
|
|
12025
12107
|
const handleMouseDown = (e) => {
|
|
@@ -12113,16 +12195,16 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12113
12195
|
},
|
|
12114
12196
|
[onIndexChange]
|
|
12115
12197
|
);
|
|
12116
|
-
|
|
12198
|
+
useEffect40(() => {
|
|
12117
12199
|
if (stickyHeroContext?.setCarouselIndicator && images.length > 1) {
|
|
12118
|
-
const indicator = /* @__PURE__ */
|
|
12200
|
+
const indicator = /* @__PURE__ */ jsx73(
|
|
12119
12201
|
"div",
|
|
12120
12202
|
{
|
|
12121
12203
|
className: "w-full",
|
|
12122
12204
|
role: "group",
|
|
12123
12205
|
"aria-label": "Product image navigation",
|
|
12124
12206
|
children: /* @__PURE__ */ jsxs50("div", { className: "relative h-1", children: [
|
|
12125
|
-
/* @__PURE__ */
|
|
12207
|
+
/* @__PURE__ */ jsx73("div", { className: "flex h-full", children: images.map((_, index) => /* @__PURE__ */ jsx73(
|
|
12126
12208
|
"button",
|
|
12127
12209
|
{
|
|
12128
12210
|
onClick: () => goToSlide(index),
|
|
@@ -12132,7 +12214,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12132
12214
|
},
|
|
12133
12215
|
index
|
|
12134
12216
|
)) }),
|
|
12135
|
-
/* @__PURE__ */
|
|
12217
|
+
/* @__PURE__ */ jsx73(
|
|
12136
12218
|
"div",
|
|
12137
12219
|
{
|
|
12138
12220
|
className: "absolute top-0 h-full bg-primary transition-all duration-300 ease-out",
|
|
@@ -12155,10 +12237,10 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12155
12237
|
};
|
|
12156
12238
|
}, [activeIndex, images.length, goToSlide, stickyHeroContext]);
|
|
12157
12239
|
if (!images || images.length === 0) {
|
|
12158
|
-
return /* @__PURE__ */
|
|
12240
|
+
return /* @__PURE__ */ jsx73("div", { className: "w-full aspect-video bg-muted rounded-lg" });
|
|
12159
12241
|
}
|
|
12160
12242
|
return /* @__PURE__ */ jsxs50("div", { className: `relative w-full h-full ${className}`, children: [
|
|
12161
|
-
/* @__PURE__ */
|
|
12243
|
+
/* @__PURE__ */ jsx73(
|
|
12162
12244
|
"div",
|
|
12163
12245
|
{
|
|
12164
12246
|
ref: carouselRef,
|
|
@@ -12176,7 +12258,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12176
12258
|
role: "region",
|
|
12177
12259
|
"aria-roledescription": "carousel",
|
|
12178
12260
|
"aria-label": "Product images",
|
|
12179
|
-
children: /* @__PURE__ */
|
|
12261
|
+
children: /* @__PURE__ */ jsx73(
|
|
12180
12262
|
"div",
|
|
12181
12263
|
{
|
|
12182
12264
|
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)]" : ""}`,
|
|
@@ -12186,11 +12268,15 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12186
12268
|
children: images.map((image, index) => {
|
|
12187
12269
|
const DECODE_WINDOW = 1;
|
|
12188
12270
|
const isWithinDecodeWindow = Math.abs(index - activeIndex) <= DECODE_WINDOW;
|
|
12189
|
-
return /* @__PURE__ */
|
|
12271
|
+
return /* @__PURE__ */ jsx73(
|
|
12190
12272
|
"div",
|
|
12191
12273
|
{
|
|
12192
12274
|
className: "w-full h-full flex-shrink-0 relative select-none",
|
|
12193
|
-
children: !isWithinDecodeWindow ? /* @__PURE__ */
|
|
12275
|
+
children: !isWithinDecodeWindow ? /* @__PURE__ */ jsx73("div", { className: "w-full h-full bg-muted" }) : image.isPlaceholder ? (
|
|
12276
|
+
// Rainbow prism loader (same as the /create route) instead of
|
|
12277
|
+
// a flat pulse; fills this relative slide via inset:0.
|
|
12278
|
+
/* @__PURE__ */ jsx73(LoadingOverlayPrismCandyInline, { visible: true, variant: "light" })
|
|
12279
|
+
) : image.isRealMockup && currentArtwork ? /* @__PURE__ */ jsx73(
|
|
12194
12280
|
HeroProductImage,
|
|
12195
12281
|
{
|
|
12196
12282
|
productId,
|
|
@@ -12202,16 +12288,12 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12202
12288
|
onUrlGenerated: image.mockupId ? (url) => handleUrlGenerated(image.mockupId, url) : void 0,
|
|
12203
12289
|
className: "w-full h-full object-cover cursor-pointer pointer-events-none"
|
|
12204
12290
|
}
|
|
12205
|
-
) : image.isRealMockup && !currentArtwork ? /* @__PURE__ */
|
|
12206
|
-
|
|
12291
|
+
) : image.isRealMockup && !currentArtwork ? /* @__PURE__ */ jsx73(LoadingOverlayPrismCandyInline, { visible: true, variant: "light" }) : /* @__PURE__ */ jsx73(
|
|
12292
|
+
StaticCarouselImage,
|
|
12207
12293
|
{
|
|
12208
12294
|
src: image.src,
|
|
12209
|
-
alt: image.label,
|
|
12210
|
-
|
|
12211
|
-
className: "w-full h-full object-cover cursor-pointer pointer-events-none",
|
|
12212
|
-
loading: "lazy",
|
|
12213
|
-
decoding: "async",
|
|
12214
|
-
draggable: false
|
|
12295
|
+
alt: image.label ?? "",
|
|
12296
|
+
className: "w-full h-full object-cover cursor-pointer pointer-events-none"
|
|
12215
12297
|
}
|
|
12216
12298
|
)
|
|
12217
12299
|
},
|
|
@@ -12222,7 +12304,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12222
12304
|
)
|
|
12223
12305
|
}
|
|
12224
12306
|
),
|
|
12225
|
-
showIndicators && images.length > 1 && /* @__PURE__ */
|
|
12307
|
+
showIndicators && images.length > 1 && /* @__PURE__ */ jsx73(
|
|
12226
12308
|
"div",
|
|
12227
12309
|
{
|
|
12228
12310
|
ref: indicatorRef,
|
|
@@ -12231,7 +12313,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12231
12313
|
role: "group",
|
|
12232
12314
|
"aria-label": "Product image navigation",
|
|
12233
12315
|
children: /* @__PURE__ */ jsxs50("div", { className: "relative h-1", children: [
|
|
12234
|
-
/* @__PURE__ */
|
|
12316
|
+
/* @__PURE__ */ jsx73("div", { className: "flex h-full absolute inset-0", children: images.map((_, index) => /* @__PURE__ */ jsx73(
|
|
12235
12317
|
"button",
|
|
12236
12318
|
{
|
|
12237
12319
|
onClick: () => goToSlide(index),
|
|
@@ -12241,7 +12323,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12241
12323
|
},
|
|
12242
12324
|
index
|
|
12243
12325
|
)) }),
|
|
12244
|
-
/* @__PURE__ */
|
|
12326
|
+
/* @__PURE__ */ jsx73(
|
|
12245
12327
|
"div",
|
|
12246
12328
|
{
|
|
12247
12329
|
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"}`,
|
|
@@ -12276,7 +12358,7 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12276
12358
|
naturalHeight: img.naturalHeight
|
|
12277
12359
|
} : null;
|
|
12278
12360
|
}).filter((img) => img !== null);
|
|
12279
|
-
return /* @__PURE__ */
|
|
12361
|
+
return /* @__PURE__ */ jsx73(
|
|
12280
12362
|
EnhancedImageViewer,
|
|
12281
12363
|
{
|
|
12282
12364
|
imageUrl,
|
|
@@ -12315,8 +12397,8 @@ var MobileProductCarousel = memo4(function MobileProductCarousel2({
|
|
|
12315
12397
|
});
|
|
12316
12398
|
|
|
12317
12399
|
// src/composed/carousels/HeroCarousel.tsx
|
|
12318
|
-
import { useState as
|
|
12319
|
-
import { jsx as
|
|
12400
|
+
import { useState as useState41, useRef as useRef27, useCallback as useCallback23, useEffect as useEffect41 } from "react";
|
|
12401
|
+
import { jsx as jsx74, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
12320
12402
|
function HeroCarousel({
|
|
12321
12403
|
images,
|
|
12322
12404
|
currentIndex = 0,
|
|
@@ -12326,13 +12408,13 @@ function HeroCarousel({
|
|
|
12326
12408
|
productId,
|
|
12327
12409
|
onImageTap
|
|
12328
12410
|
}) {
|
|
12329
|
-
const [activeIndex, setActiveIndex] =
|
|
12411
|
+
const [activeIndex, setActiveIndex] = useState41(currentIndex);
|
|
12330
12412
|
const containerRef = useRef27(null);
|
|
12331
12413
|
const touchStartRef = useRef27(
|
|
12332
12414
|
null
|
|
12333
12415
|
);
|
|
12334
12416
|
const isSwipingRef = useRef27(false);
|
|
12335
|
-
|
|
12417
|
+
useEffect41(() => {
|
|
12336
12418
|
setActiveIndex(currentIndex);
|
|
12337
12419
|
}, [currentIndex]);
|
|
12338
12420
|
const goToSlide = useCallback23(
|
|
@@ -12343,7 +12425,7 @@ function HeroCarousel({
|
|
|
12343
12425
|
},
|
|
12344
12426
|
[images.length, onIndexChange]
|
|
12345
12427
|
);
|
|
12346
|
-
|
|
12428
|
+
useEffect41(() => {
|
|
12347
12429
|
const container = containerRef.current;
|
|
12348
12430
|
if (!container) return;
|
|
12349
12431
|
const handleTouchStart = (e) => {
|
|
@@ -12395,7 +12477,7 @@ function HeroCarousel({
|
|
|
12395
12477
|
};
|
|
12396
12478
|
}, [activeIndex, images.length, goToSlide, onImageTap]);
|
|
12397
12479
|
if (!images || images.length === 0) {
|
|
12398
|
-
return /* @__PURE__ */
|
|
12480
|
+
return /* @__PURE__ */ jsx74("div", { className: "w-full h-full bg-muted" });
|
|
12399
12481
|
}
|
|
12400
12482
|
return /* @__PURE__ */ jsxs51(
|
|
12401
12483
|
"div",
|
|
@@ -12408,7 +12490,7 @@ function HeroCarousel({
|
|
|
12408
12490
|
overflow: "hidden"
|
|
12409
12491
|
},
|
|
12410
12492
|
children: [
|
|
12411
|
-
/* @__PURE__ */
|
|
12493
|
+
/* @__PURE__ */ jsx74(
|
|
12412
12494
|
"div",
|
|
12413
12495
|
{
|
|
12414
12496
|
className: "flex h-full transition-transform duration-300 ease-out",
|
|
@@ -12419,14 +12501,14 @@ function HeroCarousel({
|
|
|
12419
12501
|
backfaceVisibility: "hidden",
|
|
12420
12502
|
WebkitBackfaceVisibility: "hidden"
|
|
12421
12503
|
},
|
|
12422
|
-
children: images.map((image, index) => /* @__PURE__ */
|
|
12504
|
+
children: images.map((image, index) => /* @__PURE__ */ jsx74(
|
|
12423
12505
|
"div",
|
|
12424
12506
|
{
|
|
12425
12507
|
className: "w-full h-full flex-shrink-0",
|
|
12426
12508
|
style: {
|
|
12427
12509
|
contain: "layout paint"
|
|
12428
12510
|
},
|
|
12429
|
-
children: image.isRealMockup && currentArtwork ? /* @__PURE__ */
|
|
12511
|
+
children: image.isRealMockup && currentArtwork ? /* @__PURE__ */ jsx74(
|
|
12430
12512
|
HeroProductImage,
|
|
12431
12513
|
{
|
|
12432
12514
|
productId,
|
|
@@ -12435,7 +12517,7 @@ function HeroCarousel({
|
|
|
12435
12517
|
mockupId: image.mockupId,
|
|
12436
12518
|
className: "w-full h-full object-cover"
|
|
12437
12519
|
}
|
|
12438
|
-
) : /* @__PURE__ */
|
|
12520
|
+
) : /* @__PURE__ */ jsx74(
|
|
12439
12521
|
"img",
|
|
12440
12522
|
{
|
|
12441
12523
|
src: image.src,
|
|
@@ -12452,12 +12534,12 @@ function HeroCarousel({
|
|
|
12452
12534
|
))
|
|
12453
12535
|
}
|
|
12454
12536
|
),
|
|
12455
|
-
images.length > 1 && /* @__PURE__ */
|
|
12537
|
+
images.length > 1 && /* @__PURE__ */ jsx74(
|
|
12456
12538
|
"div",
|
|
12457
12539
|
{
|
|
12458
12540
|
className: "absolute bottom-4 left-0 right-0 flex justify-center gap-2 z-10",
|
|
12459
12541
|
style: { contain: "layout style" },
|
|
12460
|
-
children: images.map((_, index) => /* @__PURE__ */
|
|
12542
|
+
children: images.map((_, index) => /* @__PURE__ */ jsx74(
|
|
12461
12543
|
"button",
|
|
12462
12544
|
{
|
|
12463
12545
|
onClick: () => goToSlide(index),
|
|
@@ -12474,8 +12556,8 @@ function HeroCarousel({
|
|
|
12474
12556
|
}
|
|
12475
12557
|
|
|
12476
12558
|
// src/composed/grids/MasonryGrid.tsx
|
|
12477
|
-
import { useState as
|
|
12478
|
-
import { Fragment as
|
|
12559
|
+
import { useState as useState42, useEffect as useEffect42, useMemo as useMemo16 } from "react";
|
|
12560
|
+
import { Fragment as Fragment18, jsx as jsx75 } from "react/jsx-runtime";
|
|
12479
12561
|
var BREAKPOINTS = {
|
|
12480
12562
|
sm: 640,
|
|
12481
12563
|
md: 768,
|
|
@@ -12527,13 +12609,13 @@ function MasonryGrid({
|
|
|
12527
12609
|
className = "",
|
|
12528
12610
|
emptyContent
|
|
12529
12611
|
}) {
|
|
12530
|
-
const [columnCount, setColumnCount] =
|
|
12612
|
+
const [columnCount, setColumnCount] = useState42(
|
|
12531
12613
|
() => typeof columns === "number" ? columns : getColumnCount(
|
|
12532
12614
|
typeof window !== "undefined" ? window.innerWidth : 1024,
|
|
12533
12615
|
columns
|
|
12534
12616
|
)
|
|
12535
12617
|
);
|
|
12536
|
-
|
|
12618
|
+
useEffect42(() => {
|
|
12537
12619
|
const updateColumnCount = () => {
|
|
12538
12620
|
setColumnCount(getColumnCount(window.innerWidth, columns));
|
|
12539
12621
|
};
|
|
@@ -12547,24 +12629,24 @@ function MasonryGrid({
|
|
|
12547
12629
|
);
|
|
12548
12630
|
if (items.length === 0) {
|
|
12549
12631
|
if (emptyContent) {
|
|
12550
|
-
return /* @__PURE__ */
|
|
12632
|
+
return /* @__PURE__ */ jsx75(Fragment18, { children: emptyContent });
|
|
12551
12633
|
}
|
|
12552
12634
|
return null;
|
|
12553
12635
|
}
|
|
12554
|
-
return /* @__PURE__ */
|
|
12636
|
+
return /* @__PURE__ */ jsx75(
|
|
12555
12637
|
"div",
|
|
12556
12638
|
{
|
|
12557
12639
|
className: `flex ${className}`,
|
|
12558
12640
|
style: { gap: `${gap}px` },
|
|
12559
12641
|
role: "list",
|
|
12560
|
-
children: distributedColumns.map((columnItems, columnIndex) => /* @__PURE__ */
|
|
12642
|
+
children: distributedColumns.map((columnItems, columnIndex) => /* @__PURE__ */ jsx75(
|
|
12561
12643
|
"div",
|
|
12562
12644
|
{
|
|
12563
12645
|
className: "flex-1 flex flex-col",
|
|
12564
12646
|
style: { gap: `${gap}px` },
|
|
12565
12647
|
children: columnItems.map((item, itemIndex) => {
|
|
12566
12648
|
const originalIndex = itemIndex * columnCount + columnIndex;
|
|
12567
|
-
return /* @__PURE__ */
|
|
12649
|
+
return /* @__PURE__ */ jsx75("div", { role: "listitem", children: renderItem(item, originalIndex) }, originalIndex);
|
|
12568
12650
|
})
|
|
12569
12651
|
},
|
|
12570
12652
|
columnIndex
|
|
@@ -12574,7 +12656,7 @@ function MasonryGrid({
|
|
|
12574
12656
|
}
|
|
12575
12657
|
|
|
12576
12658
|
// src/layouts/hero-zoom/HeroZoomLayout.tsx
|
|
12577
|
-
import { useEffect as
|
|
12659
|
+
import { useEffect as useEffect44, useRef as useRef28 } from "react";
|
|
12578
12660
|
|
|
12579
12661
|
// src/layouts/hero-zoom/types.ts
|
|
12580
12662
|
var DEFAULT_HERO_ZOOM_CONFIG = {
|
|
@@ -12586,15 +12668,15 @@ var DEFAULT_HERO_ZOOM_CONFIG = {
|
|
|
12586
12668
|
};
|
|
12587
12669
|
|
|
12588
12670
|
// src/layouts/hero-zoom/useHeroZoomScales.ts
|
|
12589
|
-
import { useEffect as
|
|
12671
|
+
import { useEffect as useEffect43, useState as useState43, useCallback as useCallback24 } from "react";
|
|
12590
12672
|
function useHeroZoomScales(config = {}) {
|
|
12591
12673
|
const { initialScale, accountForRetina, maxRetinaMultiplier } = {
|
|
12592
12674
|
...DEFAULT_HERO_ZOOM_CONFIG,
|
|
12593
12675
|
...config
|
|
12594
12676
|
};
|
|
12595
|
-
const [isHydrated, setIsHydrated] =
|
|
12677
|
+
const [isHydrated, setIsHydrated] = useState43(false);
|
|
12596
12678
|
const ssrMultiplier = accountForRetina ? maxRetinaMultiplier : 2;
|
|
12597
|
-
const [scales, setScales] =
|
|
12679
|
+
const [scales, setScales] = useState43(() => ({
|
|
12598
12680
|
visual: initialScale,
|
|
12599
12681
|
render: initialScale * ssrMultiplier
|
|
12600
12682
|
}));
|
|
@@ -12613,7 +12695,7 @@ function useHeroZoomScales(config = {}) {
|
|
|
12613
12695
|
renderScale = Math.max(1, Math.min(8, renderScale));
|
|
12614
12696
|
return { visual: visualScale, render: renderScale };
|
|
12615
12697
|
}, [initialScale, accountForRetina, maxRetinaMultiplier]);
|
|
12616
|
-
|
|
12698
|
+
useEffect43(() => {
|
|
12617
12699
|
const supportsScrollTimeline = CSS.supports(
|
|
12618
12700
|
"animation-timeline",
|
|
12619
12701
|
"scroll()"
|
|
@@ -12663,7 +12745,7 @@ function useHeroZoomScales(config = {}) {
|
|
|
12663
12745
|
}
|
|
12664
12746
|
|
|
12665
12747
|
// src/layouts/hero-zoom/HeroZoomLayout.tsx
|
|
12666
|
-
import { jsx as
|
|
12748
|
+
import { jsx as jsx76, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
12667
12749
|
function HeroZoomLayout({
|
|
12668
12750
|
config = {},
|
|
12669
12751
|
header,
|
|
@@ -12680,7 +12762,7 @@ function HeroZoomLayout({
|
|
|
12680
12762
|
const { visual, render, isHydrated } = useHeroZoomScales(mergedConfig);
|
|
12681
12763
|
const imageContainerRef = useRef28(null);
|
|
12682
12764
|
const headerRef = useRef28(null);
|
|
12683
|
-
|
|
12765
|
+
useEffect44(() => {
|
|
12684
12766
|
if (typeof window === "undefined") return;
|
|
12685
12767
|
const originalRestoration = "scrollRestoration" in history ? history.scrollRestoration : "auto";
|
|
12686
12768
|
if ("scrollRestoration" in history) {
|
|
@@ -12693,7 +12775,7 @@ function HeroZoomLayout({
|
|
|
12693
12775
|
}
|
|
12694
12776
|
};
|
|
12695
12777
|
}, []);
|
|
12696
|
-
|
|
12778
|
+
useEffect44(() => {
|
|
12697
12779
|
const supportsScrollTimeline = CSS.supports(
|
|
12698
12780
|
"animation-timeline",
|
|
12699
12781
|
"scroll()"
|
|
@@ -12836,8 +12918,8 @@ function HeroZoomLayout({
|
|
|
12836
12918
|
"--hero-zoom-final-transform": 1 / activeRender
|
|
12837
12919
|
},
|
|
12838
12920
|
children: [
|
|
12839
|
-
/* @__PURE__ */
|
|
12840
|
-
/* @__PURE__ */
|
|
12921
|
+
/* @__PURE__ */ jsx76("style", { dangerouslySetInnerHTML: { __html: scopedStyles } }),
|
|
12922
|
+
/* @__PURE__ */ jsx76(
|
|
12841
12923
|
"div",
|
|
12842
12924
|
{
|
|
12843
12925
|
style: {
|
|
@@ -12845,7 +12927,7 @@ function HeroZoomLayout({
|
|
|
12845
12927
|
}
|
|
12846
12928
|
}
|
|
12847
12929
|
),
|
|
12848
|
-
header && /* @__PURE__ */
|
|
12930
|
+
header && /* @__PURE__ */ jsx76(
|
|
12849
12931
|
"div",
|
|
12850
12932
|
{
|
|
12851
12933
|
ref: headerRef,
|
|
@@ -12858,7 +12940,7 @@ function HeroZoomLayout({
|
|
|
12858
12940
|
children: header
|
|
12859
12941
|
}
|
|
12860
12942
|
),
|
|
12861
|
-
/* @__PURE__ */
|
|
12943
|
+
/* @__PURE__ */ jsx76(
|
|
12862
12944
|
"div",
|
|
12863
12945
|
{
|
|
12864
12946
|
ref: imageContainerRef,
|
|
@@ -12878,15 +12960,15 @@ function HeroZoomLayout({
|
|
|
12878
12960
|
children: hero
|
|
12879
12961
|
}
|
|
12880
12962
|
),
|
|
12881
|
-
/* @__PURE__ */
|
|
12963
|
+
/* @__PURE__ */ jsx76("div", { className: "relative z-10", children })
|
|
12882
12964
|
]
|
|
12883
12965
|
}
|
|
12884
12966
|
);
|
|
12885
12967
|
}
|
|
12886
12968
|
|
|
12887
12969
|
// src/layouts/hero-zoom/HeroShrinkLayout.tsx
|
|
12888
|
-
import { useEffect as
|
|
12889
|
-
import { jsx as
|
|
12970
|
+
import { useEffect as useEffect45, useRef as useRef29, useState as useState44 } from "react";
|
|
12971
|
+
import { jsx as jsx77, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
12890
12972
|
var DEFAULT_CONFIG = {
|
|
12891
12973
|
aspectRatio: 16 / 9,
|
|
12892
12974
|
initialHeightPercent: 70,
|
|
@@ -12908,11 +12990,11 @@ function HeroShrinkLayout({
|
|
|
12908
12990
|
const { aspectRatio, initialHeightPercent, minHeightPercent, headerHeight } = mergedConfig;
|
|
12909
12991
|
const heroRef = useRef29(null);
|
|
12910
12992
|
const headerRef = useRef29(null);
|
|
12911
|
-
const [isClient, setIsClient] =
|
|
12912
|
-
|
|
12993
|
+
const [isClient, setIsClient] = useState44(false);
|
|
12994
|
+
useEffect45(() => {
|
|
12913
12995
|
setIsClient(true);
|
|
12914
12996
|
}, []);
|
|
12915
|
-
|
|
12997
|
+
useEffect45(() => {
|
|
12916
12998
|
if (!isClient) return;
|
|
12917
12999
|
const supportsScrollTimeline = CSS.supports("animation-timeline", "scroll()");
|
|
12918
13000
|
if (supportsScrollTimeline) return;
|
|
@@ -13005,9 +13087,9 @@ function HeroShrinkLayout({
|
|
|
13005
13087
|
className: `relative min-h-screen ${className}`,
|
|
13006
13088
|
style: { ...style, ...cssVars },
|
|
13007
13089
|
children: [
|
|
13008
|
-
/* @__PURE__ */
|
|
13009
|
-
/* @__PURE__ */
|
|
13010
|
-
header && /* @__PURE__ */
|
|
13090
|
+
/* @__PURE__ */ jsx77("style", { dangerouslySetInnerHTML: { __html: scopedStyles } }),
|
|
13091
|
+
/* @__PURE__ */ jsx77("div", { style: { height: spacerHeight } }),
|
|
13092
|
+
header && /* @__PURE__ */ jsx77(
|
|
13011
13093
|
"div",
|
|
13012
13094
|
{
|
|
13013
13095
|
ref: headerRef,
|
|
@@ -13016,7 +13098,7 @@ function HeroShrinkLayout({
|
|
|
13016
13098
|
children: header
|
|
13017
13099
|
}
|
|
13018
13100
|
),
|
|
13019
|
-
/* @__PURE__ */
|
|
13101
|
+
/* @__PURE__ */ jsx77(
|
|
13020
13102
|
"div",
|
|
13021
13103
|
{
|
|
13022
13104
|
ref: heroRef,
|
|
@@ -13024,15 +13106,15 @@ function HeroShrinkLayout({
|
|
|
13024
13106
|
children: hero
|
|
13025
13107
|
}
|
|
13026
13108
|
),
|
|
13027
|
-
/* @__PURE__ */
|
|
13109
|
+
/* @__PURE__ */ jsx77("div", { className: "relative z-10 bg-background", children })
|
|
13028
13110
|
]
|
|
13029
13111
|
}
|
|
13030
13112
|
);
|
|
13031
13113
|
}
|
|
13032
13114
|
|
|
13033
13115
|
// src/layouts/pdp/ImageEdgeBlur.tsx
|
|
13034
|
-
import
|
|
13035
|
-
import { jsx as
|
|
13116
|
+
import React51 from "react";
|
|
13117
|
+
import { jsx as jsx78 } from "react/jsx-runtime";
|
|
13036
13118
|
var BLUR_CONFIG = {
|
|
13037
13119
|
blur: 24,
|
|
13038
13120
|
crossfade: 68
|
|
@@ -13056,7 +13138,7 @@ var BLUR_LAYERS = [
|
|
|
13056
13138
|
{ blur: Math.round(BLUR_CONFIG.blur * 0.5), zone: 0.6 },
|
|
13057
13139
|
{ blur: BLUR_CONFIG.blur, zone: 1 }
|
|
13058
13140
|
];
|
|
13059
|
-
var ImageEdgeBlur =
|
|
13141
|
+
var ImageEdgeBlur = React51.memo(
|
|
13060
13142
|
function ImageEdgeBlur2({
|
|
13061
13143
|
imageSrc,
|
|
13062
13144
|
imageCapInfo,
|
|
@@ -13087,7 +13169,7 @@ var ImageEdgeBlur = React50.memo(
|
|
|
13087
13169
|
viewportWidth / LAYOUT_CONFIG2.IMAGE.ASPECT_RATIO,
|
|
13088
13170
|
maxWidthPx / LAYOUT_CONFIG2.IMAGE.ASPECT_RATIO
|
|
13089
13171
|
);
|
|
13090
|
-
return /* @__PURE__ */
|
|
13172
|
+
return /* @__PURE__ */ jsx78(
|
|
13091
13173
|
"div",
|
|
13092
13174
|
{
|
|
13093
13175
|
className: `absolute inset-0 pointer-events-none overflow-hidden ${className}`,
|
|
@@ -13095,7 +13177,7 @@ var ImageEdgeBlur = React50.memo(
|
|
|
13095
13177
|
children: BLUR_LAYERS.map((layer, index) => {
|
|
13096
13178
|
const layerMask = index === BLUR_LAYERS.length - 1 ? void 0 : `linear-gradient(to right, black 0%, black ${layer.zone * 100}%, transparent ${layer.zone * 100 + 10}%)`;
|
|
13097
13179
|
const blurScale = 1 + layer.blur * 3 / containerHeightPx;
|
|
13098
|
-
return /* @__PURE__ */
|
|
13180
|
+
return /* @__PURE__ */ jsx78(
|
|
13099
13181
|
"img",
|
|
13100
13182
|
{
|
|
13101
13183
|
src: imageSrc,
|
|
@@ -13142,7 +13224,7 @@ var ImageEdgeBlur = React50.memo(
|
|
|
13142
13224
|
);
|
|
13143
13225
|
|
|
13144
13226
|
// src/layouts/pdp/PDPLayout.tsx
|
|
13145
|
-
import { jsx as
|
|
13227
|
+
import { jsx as jsx79, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
13146
13228
|
function PDPLayout({
|
|
13147
13229
|
renderHeroImage,
|
|
13148
13230
|
renderContent,
|
|
@@ -13172,13 +13254,13 @@ function PDPLayout({
|
|
|
13172
13254
|
};
|
|
13173
13255
|
return /* @__PURE__ */ jsxs54("div", { className: `pdp-layout ${className}`, children: [
|
|
13174
13256
|
(isDesktop === false || isDesktop === null) && /* @__PURE__ */ jsxs54("div", { className: "md:hidden", children: [
|
|
13175
|
-
renderMobileCarousel && /* @__PURE__ */
|
|
13176
|
-
/* @__PURE__ */
|
|
13257
|
+
renderMobileCarousel && /* @__PURE__ */ jsx79("div", { className: "mobile-carousel-container", children: renderMobileCarousel({ images: carouselImages }) }),
|
|
13258
|
+
/* @__PURE__ */ jsx79("div", { className: "mobile-content p-4", children: renderContent(contentProps) })
|
|
13177
13259
|
] }),
|
|
13178
13260
|
(isDesktop === true || isDesktop === null) && /* @__PURE__ */ jsxs54("div", { className: "hidden md:block relative", children: [
|
|
13179
13261
|
/* @__PURE__ */ jsxs54("div", { className: "desktop-hero relative", children: [
|
|
13180
13262
|
renderHeroImage(heroProps),
|
|
13181
|
-
showEdgeBlur && blurImageSrc && isWideMonitor2 && /* @__PURE__ */
|
|
13263
|
+
showEdgeBlur && blurImageSrc && isWideMonitor2 && /* @__PURE__ */ jsx79(
|
|
13182
13264
|
ImageEdgeBlur,
|
|
13183
13265
|
{
|
|
13184
13266
|
imageSrc: blurImageSrc,
|
|
@@ -13189,7 +13271,7 @@ function PDPLayout({
|
|
|
13189
13271
|
}
|
|
13190
13272
|
)
|
|
13191
13273
|
] }),
|
|
13192
|
-
/* @__PURE__ */
|
|
13274
|
+
/* @__PURE__ */ jsx79(
|
|
13193
13275
|
"div",
|
|
13194
13276
|
{
|
|
13195
13277
|
className: "desktop-sidebar",
|
|
@@ -13206,8 +13288,8 @@ function PDPLayout({
|
|
|
13206
13288
|
}
|
|
13207
13289
|
|
|
13208
13290
|
// src/layouts/pdp/SimpleImageBlur.tsx
|
|
13209
|
-
import
|
|
13210
|
-
import { jsx as
|
|
13291
|
+
import React52 from "react";
|
|
13292
|
+
import { jsx as jsx80 } from "react/jsx-runtime";
|
|
13211
13293
|
var BLUR_CONFIG2 = {
|
|
13212
13294
|
blur: 24,
|
|
13213
13295
|
crossfade: 60
|
|
@@ -13230,7 +13312,7 @@ function getFadeInMask(crossfadeWidth) {
|
|
|
13230
13312
|
black ${crossfadeWidth + 10}px
|
|
13231
13313
|
)`;
|
|
13232
13314
|
}
|
|
13233
|
-
var SimpleImageBlur =
|
|
13315
|
+
var SimpleImageBlur = React52.memo(function SimpleImageBlur2({
|
|
13234
13316
|
imageSrc,
|
|
13235
13317
|
width,
|
|
13236
13318
|
height = "100%",
|
|
@@ -13240,7 +13322,7 @@ var SimpleImageBlur = React51.memo(function SimpleImageBlur2({
|
|
|
13240
13322
|
if (!imageSrc || width <= 0) return null;
|
|
13241
13323
|
const fadeInMask = getFadeInMask(BLUR_CONFIG2.crossfade);
|
|
13242
13324
|
const extendedWidth = width + BLUR_CONFIG2.blur * 2;
|
|
13243
|
-
return /* @__PURE__ */
|
|
13325
|
+
return /* @__PURE__ */ jsx80(
|
|
13244
13326
|
"div",
|
|
13245
13327
|
{
|
|
13246
13328
|
className: `relative overflow-hidden ${className}`,
|
|
@@ -13253,7 +13335,7 @@ var SimpleImageBlur = React51.memo(function SimpleImageBlur2({
|
|
|
13253
13335
|
black 0%,
|
|
13254
13336
|
black ${layer.zone * 100}%,
|
|
13255
13337
|
transparent ${layer.zone * 100 + 10}%)`;
|
|
13256
|
-
return /* @__PURE__ */
|
|
13338
|
+
return /* @__PURE__ */ jsx80(
|
|
13257
13339
|
"img",
|
|
13258
13340
|
{
|
|
13259
13341
|
src: imageSrc,
|
|
@@ -13283,8 +13365,8 @@ var SimpleImageBlur = React51.memo(function SimpleImageBlur2({
|
|
|
13283
13365
|
});
|
|
13284
13366
|
|
|
13285
13367
|
// src/layouts/pdp/EdgeBlurBox.tsx
|
|
13286
|
-
import
|
|
13287
|
-
import { jsx as
|
|
13368
|
+
import React53 from "react";
|
|
13369
|
+
import { jsx as jsx81, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
13288
13370
|
var BLUR_CONFIG3 = {
|
|
13289
13371
|
blur: 24,
|
|
13290
13372
|
crossfade: 60
|
|
@@ -13308,7 +13390,7 @@ function getFadeOutMask(crossfadeWidth) {
|
|
|
13308
13390
|
transparent 100%
|
|
13309
13391
|
)`;
|
|
13310
13392
|
}
|
|
13311
|
-
var EdgeBlurBox =
|
|
13393
|
+
var EdgeBlurBox = React53.memo(function EdgeBlurBox2({
|
|
13312
13394
|
imageSrc,
|
|
13313
13395
|
width,
|
|
13314
13396
|
height = "100%",
|
|
@@ -13334,7 +13416,7 @@ var EdgeBlurBox = React52.memo(function EdgeBlurBox2({
|
|
|
13334
13416
|
overflow: hasOverlap ? "visible" : "hidden"
|
|
13335
13417
|
},
|
|
13336
13418
|
children: [
|
|
13337
|
-
/* @__PURE__ */
|
|
13419
|
+
/* @__PURE__ */ jsx81(
|
|
13338
13420
|
"div",
|
|
13339
13421
|
{
|
|
13340
13422
|
style: {
|
|
@@ -13348,7 +13430,7 @@ var EdgeBlurBox = React52.memo(function EdgeBlurBox2({
|
|
|
13348
13430
|
transparent ${100 - (layer.zone * 100 + 10)}%,
|
|
13349
13431
|
black ${100 - layer.zone * 100}%,
|
|
13350
13432
|
black 100%)`;
|
|
13351
|
-
return /* @__PURE__ */
|
|
13433
|
+
return /* @__PURE__ */ jsx81(
|
|
13352
13434
|
"img",
|
|
13353
13435
|
{
|
|
13354
13436
|
src: imageSrc,
|
|
@@ -13376,7 +13458,7 @@ var EdgeBlurBox = React52.memo(function EdgeBlurBox2({
|
|
|
13376
13458
|
})
|
|
13377
13459
|
}
|
|
13378
13460
|
),
|
|
13379
|
-
/* @__PURE__ */
|
|
13461
|
+
/* @__PURE__ */ jsx81(
|
|
13380
13462
|
"img",
|
|
13381
13463
|
{
|
|
13382
13464
|
src: imageSrc,
|
|
@@ -13404,8 +13486,8 @@ var EdgeBlurBox = React52.memo(function EdgeBlurBox2({
|
|
|
13404
13486
|
});
|
|
13405
13487
|
|
|
13406
13488
|
// src/layouts/pdp/ImageBlurExtension.tsx
|
|
13407
|
-
import
|
|
13408
|
-
import { jsx as
|
|
13489
|
+
import React54 from "react";
|
|
13490
|
+
import { jsx as jsx82, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
13409
13491
|
var BLUR_CONFIG4 = {
|
|
13410
13492
|
blur: 24,
|
|
13411
13493
|
crossfadeWidth: 80
|
|
@@ -13428,7 +13510,7 @@ function getFadeOutMask2(crossfadeWidth) {
|
|
|
13428
13510
|
transparent 100%
|
|
13429
13511
|
)`;
|
|
13430
13512
|
}
|
|
13431
|
-
var ImageBlurExtension =
|
|
13513
|
+
var ImageBlurExtension = React54.memo(function ImageBlurExtension2({
|
|
13432
13514
|
imageSrc,
|
|
13433
13515
|
width,
|
|
13434
13516
|
height,
|
|
@@ -13451,7 +13533,7 @@ var ImageBlurExtension = React53.memo(function ImageBlurExtension2({
|
|
|
13451
13533
|
height: heightValue
|
|
13452
13534
|
},
|
|
13453
13535
|
children: [
|
|
13454
|
-
BLUR_LAYERS4.map((layer, index) => /* @__PURE__ */
|
|
13536
|
+
BLUR_LAYERS4.map((layer, index) => /* @__PURE__ */ jsx82(
|
|
13455
13537
|
"img",
|
|
13456
13538
|
{
|
|
13457
13539
|
src: imageSrc,
|
|
@@ -13475,7 +13557,7 @@ var ImageBlurExtension = React53.memo(function ImageBlurExtension2({
|
|
|
13475
13557
|
},
|
|
13476
13558
|
`blur-${index}`
|
|
13477
13559
|
)),
|
|
13478
|
-
/* @__PURE__ */
|
|
13560
|
+
/* @__PURE__ */ jsx82(
|
|
13479
13561
|
"img",
|
|
13480
13562
|
{
|
|
13481
13563
|
src: imageSrc,
|
|
@@ -13503,23 +13585,23 @@ var ImageBlurExtension = React53.memo(function ImageBlurExtension2({
|
|
|
13503
13585
|
});
|
|
13504
13586
|
|
|
13505
13587
|
// src/design-system/ColorSwatch.tsx
|
|
13506
|
-
import { jsx as
|
|
13588
|
+
import { jsx as jsx83, jsxs as jsxs57 } from "react/jsx-runtime";
|
|
13507
13589
|
function ColorTokenSwatch({ name, cssVar, className = "" }) {
|
|
13508
13590
|
return /* @__PURE__ */ jsxs57("div", { className: `flex flex-col gap-1 ${className}`, children: [
|
|
13509
|
-
/* @__PURE__ */
|
|
13591
|
+
/* @__PURE__ */ jsx83(
|
|
13510
13592
|
"div",
|
|
13511
13593
|
{
|
|
13512
13594
|
className: "h-16 w-full rounded-lg border border-border shadow-sm",
|
|
13513
13595
|
style: { backgroundColor: `var(${cssVar})` }
|
|
13514
13596
|
}
|
|
13515
13597
|
),
|
|
13516
|
-
/* @__PURE__ */
|
|
13517
|
-
/* @__PURE__ */
|
|
13598
|
+
/* @__PURE__ */ jsx83("div", { className: "text-sm font-medium text-foreground", children: name }),
|
|
13599
|
+
/* @__PURE__ */ jsx83("code", { className: "text-xs text-muted-foreground font-mono", children: cssVar })
|
|
13518
13600
|
] });
|
|
13519
13601
|
}
|
|
13520
13602
|
function ColorRow({ name, cssVar, description }) {
|
|
13521
13603
|
return /* @__PURE__ */ jsxs57("div", { className: "flex items-center gap-4 py-2", children: [
|
|
13522
|
-
/* @__PURE__ */
|
|
13604
|
+
/* @__PURE__ */ jsx83(
|
|
13523
13605
|
"div",
|
|
13524
13606
|
{
|
|
13525
13607
|
className: "h-10 w-10 rounded-lg border border-border shadow-sm flex-shrink-0",
|
|
@@ -13527,15 +13609,15 @@ function ColorRow({ name, cssVar, description }) {
|
|
|
13527
13609
|
}
|
|
13528
13610
|
),
|
|
13529
13611
|
/* @__PURE__ */ jsxs57("div", { className: "flex-1 min-w-0", children: [
|
|
13530
|
-
/* @__PURE__ */
|
|
13531
|
-
description && /* @__PURE__ */
|
|
13612
|
+
/* @__PURE__ */ jsx83("div", { className: "text-sm font-medium text-foreground", children: name }),
|
|
13613
|
+
description && /* @__PURE__ */ jsx83("div", { className: "text-xs text-muted-foreground", children: description })
|
|
13532
13614
|
] }),
|
|
13533
|
-
/* @__PURE__ */
|
|
13615
|
+
/* @__PURE__ */ jsx83("code", { className: "text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded", children: cssVar })
|
|
13534
13616
|
] });
|
|
13535
13617
|
}
|
|
13536
13618
|
|
|
13537
13619
|
// src/design-system/ColorPalette.tsx
|
|
13538
|
-
import { jsx as
|
|
13620
|
+
import { jsx as jsx84, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
13539
13621
|
var COLOR_GROUPS = [
|
|
13540
13622
|
{
|
|
13541
13623
|
name: "Base",
|
|
@@ -13616,17 +13698,17 @@ var COLOR_GROUPS = [
|
|
|
13616
13698
|
}
|
|
13617
13699
|
];
|
|
13618
13700
|
function ColorPalette({ layout = "list", className = "" }) {
|
|
13619
|
-
return /* @__PURE__ */
|
|
13620
|
-
/* @__PURE__ */
|
|
13621
|
-
/* @__PURE__ */
|
|
13622
|
-
layout === "grid" ? /* @__PURE__ */
|
|
13701
|
+
return /* @__PURE__ */ jsx84("div", { className: `space-y-8 ${className}`, children: COLOR_GROUPS.map((group) => /* @__PURE__ */ jsxs58("section", { children: [
|
|
13702
|
+
/* @__PURE__ */ jsx84("h3", { className: "text-lg font-semibold text-foreground mb-1", children: group.name }),
|
|
13703
|
+
/* @__PURE__ */ jsx84("p", { className: "text-sm text-muted-foreground mb-4", children: group.description }),
|
|
13704
|
+
layout === "grid" ? /* @__PURE__ */ jsx84("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-4", children: group.colors.map((color) => /* @__PURE__ */ jsx84(
|
|
13623
13705
|
ColorTokenSwatch,
|
|
13624
13706
|
{
|
|
13625
13707
|
name: color.name,
|
|
13626
13708
|
cssVar: color.cssVar
|
|
13627
13709
|
},
|
|
13628
13710
|
color.cssVar
|
|
13629
|
-
)) }) : /* @__PURE__ */
|
|
13711
|
+
)) }) : /* @__PURE__ */ jsx84("div", { className: "bg-card rounded-lg border border-border p-4 divide-y divide-border", children: group.colors.map((color) => /* @__PURE__ */ jsx84(
|
|
13630
13712
|
ColorRow,
|
|
13631
13713
|
{
|
|
13632
13714
|
name: color.name,
|
|
@@ -13639,7 +13721,7 @@ function ColorPalette({ layout = "list", className = "" }) {
|
|
|
13639
13721
|
}
|
|
13640
13722
|
|
|
13641
13723
|
// src/design-system/TypographyScale.tsx
|
|
13642
|
-
import { jsx as
|
|
13724
|
+
import { jsx as jsx85, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
13643
13725
|
var FONT_SAMPLES = [
|
|
13644
13726
|
{
|
|
13645
13727
|
name: "Heading",
|
|
@@ -13673,14 +13755,14 @@ var FONT_SAMPLES = [
|
|
|
13673
13755
|
}
|
|
13674
13756
|
];
|
|
13675
13757
|
function TypographyScale({ className = "" }) {
|
|
13676
|
-
return /* @__PURE__ */
|
|
13758
|
+
return /* @__PURE__ */ jsx85("div", { className: `space-y-8 ${className}`, children: FONT_SAMPLES.map((font) => /* @__PURE__ */ jsxs59("section", { className: "bg-card rounded-lg border border-border p-6", children: [
|
|
13677
13759
|
/* @__PURE__ */ jsxs59("div", { className: "flex items-center justify-between mb-4", children: [
|
|
13678
|
-
/* @__PURE__ */
|
|
13679
|
-
/* @__PURE__ */
|
|
13760
|
+
/* @__PURE__ */ jsx85("h3", { className: "text-lg font-semibold text-foreground", children: font.name }),
|
|
13761
|
+
/* @__PURE__ */ jsx85("code", { className: "text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded", children: font.cssVar })
|
|
13680
13762
|
] }),
|
|
13681
|
-
/* @__PURE__ */
|
|
13682
|
-
/* @__PURE__ */
|
|
13683
|
-
/* @__PURE__ */
|
|
13763
|
+
/* @__PURE__ */ jsx85("div", { className: "space-y-4", children: font.sizes.map((size) => /* @__PURE__ */ jsxs59("div", { className: "flex items-baseline gap-4", children: [
|
|
13764
|
+
/* @__PURE__ */ jsx85("span", { className: "text-xs text-muted-foreground w-20 flex-shrink-0", children: size }),
|
|
13765
|
+
/* @__PURE__ */ jsx85(
|
|
13684
13766
|
"p",
|
|
13685
13767
|
{
|
|
13686
13768
|
className: `${size} text-foreground`,
|
|
@@ -13699,8 +13781,8 @@ var RADIUS_SAMPLES = [
|
|
|
13699
13781
|
{ name: "Full", value: "9999px" }
|
|
13700
13782
|
];
|
|
13701
13783
|
function RadiusScale({ className = "" }) {
|
|
13702
|
-
return /* @__PURE__ */
|
|
13703
|
-
/* @__PURE__ */
|
|
13784
|
+
return /* @__PURE__ */ jsx85("div", { className: `space-y-4 ${className}`, children: /* @__PURE__ */ jsx85("div", { className: "grid grid-cols-5 gap-4", children: RADIUS_SAMPLES.map((radius) => /* @__PURE__ */ jsxs59("div", { className: "flex flex-col items-center gap-2", children: [
|
|
13785
|
+
/* @__PURE__ */ jsx85(
|
|
13704
13786
|
"div",
|
|
13705
13787
|
{
|
|
13706
13788
|
className: "h-16 w-16 bg-primary",
|
|
@@ -13709,14 +13791,14 @@ function RadiusScale({ className = "" }) {
|
|
|
13709
13791
|
}
|
|
13710
13792
|
}
|
|
13711
13793
|
),
|
|
13712
|
-
/* @__PURE__ */
|
|
13713
|
-
/* @__PURE__ */
|
|
13794
|
+
/* @__PURE__ */ jsx85("span", { className: "text-sm font-medium text-foreground", children: radius.name }),
|
|
13795
|
+
/* @__PURE__ */ jsx85("code", { className: "text-xs text-muted-foreground font-mono", children: radius.cssVar || radius.value })
|
|
13714
13796
|
] }, radius.name)) }) });
|
|
13715
13797
|
}
|
|
13716
13798
|
|
|
13717
13799
|
// src/design-system/ThemeSwitcher.tsx
|
|
13718
|
-
import { useState as
|
|
13719
|
-
import { Fragment as
|
|
13800
|
+
import { useState as useState45, useEffect as useEffect46 } from "react";
|
|
13801
|
+
import { Fragment as Fragment19, jsx as jsx86, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
13720
13802
|
function readThemeFromDOM() {
|
|
13721
13803
|
if (typeof document === "undefined") {
|
|
13722
13804
|
return { themeName: "Linear", isDark: false };
|
|
@@ -13734,10 +13816,10 @@ function readThemeFromDOM() {
|
|
|
13734
13816
|
return { themeName: "Linear", isDark: dark };
|
|
13735
13817
|
}
|
|
13736
13818
|
function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
13737
|
-
const [currentTheme, setCurrentTheme] =
|
|
13738
|
-
const [isDark, setIsDark] =
|
|
13739
|
-
const [isOpen, setIsOpen] =
|
|
13740
|
-
|
|
13819
|
+
const [currentTheme, setCurrentTheme] = useState45("Linear");
|
|
13820
|
+
const [isDark, setIsDark] = useState45(false);
|
|
13821
|
+
const [isOpen, setIsOpen] = useState45(false);
|
|
13822
|
+
useEffect46(() => {
|
|
13741
13823
|
const { themeName, isDark: dark } = readThemeFromDOM();
|
|
13742
13824
|
setCurrentTheme(themeName);
|
|
13743
13825
|
setIsDark(dark);
|
|
@@ -13784,35 +13866,35 @@ function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
|
13784
13866
|
onClick: () => setIsOpen(!isOpen),
|
|
13785
13867
|
className: "flex items-center gap-2 px-4 py-2 bg-card border border-border rounded-lg hover:bg-muted transition-colors text-foreground",
|
|
13786
13868
|
children: [
|
|
13787
|
-
/* @__PURE__ */
|
|
13788
|
-
/* @__PURE__ */
|
|
13789
|
-
/* @__PURE__ */
|
|
13869
|
+
/* @__PURE__ */ jsx86("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx86("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" }) }),
|
|
13870
|
+
/* @__PURE__ */ jsx86("span", { className: "font-medium", children: currentTheme }),
|
|
13871
|
+
/* @__PURE__ */ jsx86("svg", { className: `w-4 h-4 transition-transform ${isOpen ? "rotate-180" : ""}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx86("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })
|
|
13790
13872
|
]
|
|
13791
13873
|
}
|
|
13792
13874
|
),
|
|
13793
|
-
isOpen && /* @__PURE__ */ jsxs60(
|
|
13794
|
-
/* @__PURE__ */
|
|
13875
|
+
isOpen && /* @__PURE__ */ jsxs60(Fragment19, { children: [
|
|
13876
|
+
/* @__PURE__ */ jsx86(
|
|
13795
13877
|
"div",
|
|
13796
13878
|
{
|
|
13797
13879
|
className: "fixed inset-0 z-40",
|
|
13798
13880
|
onClick: () => setIsOpen(false)
|
|
13799
13881
|
}
|
|
13800
13882
|
),
|
|
13801
|
-
/* @__PURE__ */
|
|
13883
|
+
/* @__PURE__ */ jsx86("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__ */ jsxs60(
|
|
13802
13884
|
"button",
|
|
13803
13885
|
{
|
|
13804
13886
|
onClick: () => handleThemeSelect(theme.name),
|
|
13805
13887
|
className: `w-full px-4 py-2 text-left hover:bg-muted transition-colors flex items-center gap-3 ${currentTheme === theme.name ? "bg-muted" : ""}`,
|
|
13806
13888
|
children: [
|
|
13807
|
-
/* @__PURE__ */
|
|
13889
|
+
/* @__PURE__ */ jsx86(
|
|
13808
13890
|
"div",
|
|
13809
13891
|
{
|
|
13810
13892
|
className: "w-4 h-4 rounded-full border border-border",
|
|
13811
13893
|
style: { backgroundColor: theme.primaryColor || "#888" }
|
|
13812
13894
|
}
|
|
13813
13895
|
),
|
|
13814
|
-
/* @__PURE__ */
|
|
13815
|
-
currentTheme === theme.name && /* @__PURE__ */
|
|
13896
|
+
/* @__PURE__ */ jsx86("span", { className: "text-foreground", children: theme.name }),
|
|
13897
|
+
currentTheme === theme.name && /* @__PURE__ */ jsx86("svg", { className: "w-4 h-4 ml-auto text-primary", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx86("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }) })
|
|
13816
13898
|
]
|
|
13817
13899
|
},
|
|
13818
13900
|
theme.name
|
|
@@ -13827,10 +13909,10 @@ function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
|
13827
13909
|
title: `Switch to ${isDark ? "light" : "dark"} mode`,
|
|
13828
13910
|
children: [
|
|
13829
13911
|
isDark ? /* @__PURE__ */ jsxs60("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: [
|
|
13830
|
-
/* @__PURE__ */
|
|
13831
|
-
/* @__PURE__ */
|
|
13832
|
-
] }) : /* @__PURE__ */
|
|
13833
|
-
/* @__PURE__ */
|
|
13912
|
+
/* @__PURE__ */ jsx86("circle", { cx: "12", cy: "12", r: "5" }),
|
|
13913
|
+
/* @__PURE__ */ jsx86("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" })
|
|
13914
|
+
] }) : /* @__PURE__ */ jsx86("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx86("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) }),
|
|
13915
|
+
/* @__PURE__ */ jsx86("span", { className: "text-sm", children: isDark ? "Light" : "Dark" })
|
|
13834
13916
|
]
|
|
13835
13917
|
}
|
|
13836
13918
|
)
|
|
@@ -13838,7 +13920,7 @@ function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
|
13838
13920
|
}
|
|
13839
13921
|
|
|
13840
13922
|
// src/design-system/DesignSystemPage.tsx
|
|
13841
|
-
import { jsx as
|
|
13923
|
+
import { jsx as jsx87, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
13842
13924
|
function DesignSystemPage({
|
|
13843
13925
|
showThemeSwitcher = true,
|
|
13844
13926
|
showColors = true,
|
|
@@ -13849,28 +13931,28 @@ function DesignSystemPage({
|
|
|
13849
13931
|
className = ""
|
|
13850
13932
|
}) {
|
|
13851
13933
|
return /* @__PURE__ */ jsxs61("div", { className: `max-w-4xl mx-auto px-4 py-8 ${className}`, children: [
|
|
13852
|
-
/* @__PURE__ */
|
|
13934
|
+
/* @__PURE__ */ jsx87("header", { className: "mb-12", children: /* @__PURE__ */ jsxs61("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-4", children: [
|
|
13853
13935
|
/* @__PURE__ */ jsxs61("div", { children: [
|
|
13854
|
-
/* @__PURE__ */
|
|
13855
|
-
/* @__PURE__ */
|
|
13936
|
+
/* @__PURE__ */ jsx87("h1", { className: "text-4xl font-bold text-foreground mb-2", children: "Design System" }),
|
|
13937
|
+
/* @__PURE__ */ jsx87("p", { className: "text-lg text-muted-foreground", children: "Visual reference for theme tokens and styles" })
|
|
13856
13938
|
] }),
|
|
13857
|
-
showThemeSwitcher && /* @__PURE__ */
|
|
13939
|
+
showThemeSwitcher && /* @__PURE__ */ jsx87(ThemeSwitcher, {})
|
|
13858
13940
|
] }) }),
|
|
13859
13941
|
showColors && /* @__PURE__ */ jsxs61("section", { className: "mb-16", children: [
|
|
13860
|
-
/* @__PURE__ */
|
|
13861
|
-
/* @__PURE__ */
|
|
13942
|
+
/* @__PURE__ */ jsx87("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Color Palette" }),
|
|
13943
|
+
/* @__PURE__ */ jsx87(ColorPalette, { layout: colorLayout })
|
|
13862
13944
|
] }),
|
|
13863
13945
|
showTypography && /* @__PURE__ */ jsxs61("section", { className: "mb-16", children: [
|
|
13864
|
-
/* @__PURE__ */
|
|
13865
|
-
/* @__PURE__ */
|
|
13946
|
+
/* @__PURE__ */ jsx87("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Typography" }),
|
|
13947
|
+
/* @__PURE__ */ jsx87(TypographyScale, {})
|
|
13866
13948
|
] }),
|
|
13867
13949
|
showRadius && /* @__PURE__ */ jsxs61("section", { className: "mb-16", children: [
|
|
13868
|
-
/* @__PURE__ */
|
|
13869
|
-
/* @__PURE__ */
|
|
13950
|
+
/* @__PURE__ */ jsx87("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Border Radius" }),
|
|
13951
|
+
/* @__PURE__ */ jsx87(RadiusScale, {})
|
|
13870
13952
|
] }),
|
|
13871
13953
|
showSpacing && /* @__PURE__ */ jsxs61("section", { className: "mb-16", children: [
|
|
13872
|
-
/* @__PURE__ */
|
|
13873
|
-
/* @__PURE__ */
|
|
13954
|
+
/* @__PURE__ */ jsx87("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Spacing Scale" }),
|
|
13955
|
+
/* @__PURE__ */ jsx87(SpacingScale, {})
|
|
13874
13956
|
] })
|
|
13875
13957
|
] });
|
|
13876
13958
|
}
|
|
@@ -13885,25 +13967,25 @@ function SpacingScale() {
|
|
|
13885
13967
|
{ name: "12", value: "3rem" },
|
|
13886
13968
|
{ name: "16", value: "4rem" }
|
|
13887
13969
|
];
|
|
13888
|
-
return /* @__PURE__ */
|
|
13889
|
-
/* @__PURE__ */
|
|
13890
|
-
/* @__PURE__ */
|
|
13970
|
+
return /* @__PURE__ */ jsx87("div", { className: "space-y-2", children: spaces.map((space) => /* @__PURE__ */ jsxs61("div", { className: "flex items-center gap-4", children: [
|
|
13971
|
+
/* @__PURE__ */ jsx87("code", { className: "text-xs text-muted-foreground font-mono w-8", children: space.name }),
|
|
13972
|
+
/* @__PURE__ */ jsx87(
|
|
13891
13973
|
"div",
|
|
13892
13974
|
{
|
|
13893
13975
|
className: "h-4 bg-primary rounded",
|
|
13894
13976
|
style: { width: space.value }
|
|
13895
13977
|
}
|
|
13896
13978
|
),
|
|
13897
|
-
/* @__PURE__ */
|
|
13979
|
+
/* @__PURE__ */ jsx87("span", { className: "text-sm text-muted-foreground", children: space.value })
|
|
13898
13980
|
] }, space.name)) });
|
|
13899
13981
|
}
|
|
13900
13982
|
|
|
13901
13983
|
// src/personalization/PersonalizationProvider.tsx
|
|
13902
|
-
import
|
|
13903
|
-
useState as
|
|
13984
|
+
import React55, {
|
|
13985
|
+
useState as useState46,
|
|
13904
13986
|
useCallback as useCallback26,
|
|
13905
13987
|
useRef as useRef30,
|
|
13906
|
-
useEffect as
|
|
13988
|
+
useEffect as useEffect47
|
|
13907
13989
|
} from "react";
|
|
13908
13990
|
|
|
13909
13991
|
// src/personalization/PersonalizationContext.ts
|
|
@@ -13914,18 +13996,18 @@ function usePersonalizationContext() {
|
|
|
13914
13996
|
}
|
|
13915
13997
|
|
|
13916
13998
|
// src/personalization/PersonalizationProvider.tsx
|
|
13917
|
-
import { Fragment as
|
|
13999
|
+
import { Fragment as Fragment20, jsx as jsx88, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
13918
14000
|
function createBridgeFromCanvas(canvasModule) {
|
|
13919
14001
|
const { useEditor, useCommands, useImageBinding } = canvasModule;
|
|
13920
14002
|
function TextBinder({ name, value }) {
|
|
13921
14003
|
const { elements } = useEditor();
|
|
13922
14004
|
const { executeElementUpdate } = useCommands();
|
|
13923
|
-
const elementsRef =
|
|
14005
|
+
const elementsRef = React55.useRef(elements);
|
|
13924
14006
|
elementsRef.current = elements;
|
|
13925
|
-
const executeRef =
|
|
14007
|
+
const executeRef = React55.useRef(executeElementUpdate);
|
|
13926
14008
|
executeRef.current = executeElementUpdate;
|
|
13927
|
-
const hasUserInput =
|
|
13928
|
-
|
|
14009
|
+
const hasUserInput = React55.useRef(false);
|
|
14010
|
+
React55.useEffect(() => {
|
|
13929
14011
|
if (value == null) return;
|
|
13930
14012
|
if (value === "" && !hasUserInput.current) return;
|
|
13931
14013
|
hasUserInput.current = true;
|
|
@@ -13943,12 +14025,12 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
13943
14025
|
function ColorBinder({ originalColor, newColor }) {
|
|
13944
14026
|
const { elements } = useEditor();
|
|
13945
14027
|
const { executeElementUpdate } = useCommands();
|
|
13946
|
-
const elementsRef =
|
|
14028
|
+
const elementsRef = React55.useRef(elements);
|
|
13947
14029
|
elementsRef.current = elements;
|
|
13948
|
-
const executeRef =
|
|
14030
|
+
const executeRef = React55.useRef(executeElementUpdate);
|
|
13949
14031
|
executeRef.current = executeElementUpdate;
|
|
13950
|
-
const appliedColorRef =
|
|
13951
|
-
|
|
14032
|
+
const appliedColorRef = React55.useRef(normalizeHex(originalColor));
|
|
14033
|
+
React55.useEffect(() => {
|
|
13952
14034
|
const normalizedNew = normalizeHex(newColor);
|
|
13953
14035
|
if (normalizedNew === appliedColorRef.current) return;
|
|
13954
14036
|
const matchColor = appliedColorRef.current;
|
|
@@ -13988,11 +14070,11 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
13988
14070
|
}
|
|
13989
14071
|
function ImageBinder({ name, value, fit = "cover" }) {
|
|
13990
14072
|
const { setImageUrl } = useImageBinding(name, { fit });
|
|
13991
|
-
const hasUserInput =
|
|
14073
|
+
const hasUserInput = React55.useRef(false);
|
|
13992
14074
|
const debouncedValue = useDebouncedValue(value, 500);
|
|
13993
|
-
const setImageUrlRef =
|
|
14075
|
+
const setImageUrlRef = React55.useRef(setImageUrl);
|
|
13994
14076
|
setImageUrlRef.current = setImageUrl;
|
|
13995
|
-
|
|
14077
|
+
React55.useEffect(() => {
|
|
13996
14078
|
if (debouncedValue == null) return;
|
|
13997
14079
|
if (debouncedValue === "" && !hasUserInput.current) return;
|
|
13998
14080
|
hasUserInput.current = true;
|
|
@@ -14002,15 +14084,15 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
14002
14084
|
return null;
|
|
14003
14085
|
}
|
|
14004
14086
|
return function PersonalizationBridge({ fields = [], values = {} } = {}) {
|
|
14005
|
-
return /* @__PURE__ */
|
|
14087
|
+
return /* @__PURE__ */ jsx88(Fragment20, { children: fields.map((field) => {
|
|
14006
14088
|
if (field.type === "text") {
|
|
14007
|
-
return /* @__PURE__ */
|
|
14089
|
+
return /* @__PURE__ */ jsx88(TextBinder, { name: field.name, value: values[field.name] ?? "" }, `text-${field.name}`);
|
|
14008
14090
|
}
|
|
14009
14091
|
if (field.type === "color") {
|
|
14010
|
-
return /* @__PURE__ */
|
|
14092
|
+
return /* @__PURE__ */ jsx88(ColorBinder, { originalColor: field.color, newColor: values[field.color] ?? field.color }, `color-${field.color}`);
|
|
14011
14093
|
}
|
|
14012
14094
|
if (field.type === "image") {
|
|
14013
|
-
return /* @__PURE__ */
|
|
14095
|
+
return /* @__PURE__ */ jsx88(ImageBinder, { name: field.name, value: values[field.name] ?? "", fit: field.fit ?? "cover" }, `image-${field.name}`);
|
|
14014
14096
|
}
|
|
14015
14097
|
return null;
|
|
14016
14098
|
}) });
|
|
@@ -14032,19 +14114,19 @@ function PersonalizationProvider({
|
|
|
14032
14114
|
children
|
|
14033
14115
|
}) {
|
|
14034
14116
|
const realtime = useRealtimeOptional();
|
|
14035
|
-
const [personValues, setPersonValues] =
|
|
14036
|
-
const [isActive, setIsActive] =
|
|
14037
|
-
const [isExporting, setIsExporting] =
|
|
14038
|
-
const [exportedBlobUrls, setExportedBlobUrls] =
|
|
14039
|
-
const [exportCount, setExportCount] =
|
|
14117
|
+
const [personValues, setPersonValues] = useState46(initialValues ?? {});
|
|
14118
|
+
const [isActive, setIsActive] = useState46(!!(initialValues && Object.keys(initialValues).length > 0));
|
|
14119
|
+
const [isExporting, setIsExporting] = useState46(false);
|
|
14120
|
+
const [exportedBlobUrls, setExportedBlobUrls] = useState46({});
|
|
14121
|
+
const [exportCount, setExportCount] = useState46(0);
|
|
14040
14122
|
const blobUrlsRef = useRef30({});
|
|
14041
|
-
const [CanvasComponent, setCanvasComponent] =
|
|
14123
|
+
const [CanvasComponent, setCanvasComponent] = useState46(
|
|
14042
14124
|
cachedCanvasComponent
|
|
14043
14125
|
);
|
|
14044
|
-
const [BridgeComponent, setBridgeComponent] =
|
|
14126
|
+
const [BridgeComponent, setBridgeComponent] = useState46(
|
|
14045
14127
|
cachedBridgeComponent
|
|
14046
14128
|
);
|
|
14047
|
-
|
|
14129
|
+
useEffect47(() => {
|
|
14048
14130
|
if (CanvasComponent && BridgeComponent) return;
|
|
14049
14131
|
if (!canvasImport) return;
|
|
14050
14132
|
if (!canvasLoadPromise) {
|
|
@@ -14063,7 +14145,7 @@ function PersonalizationProvider({
|
|
|
14063
14145
|
});
|
|
14064
14146
|
}, [CanvasComponent, BridgeComponent, canvasImport]);
|
|
14065
14147
|
const realtimeEnabledRef = useRef30(false);
|
|
14066
|
-
|
|
14148
|
+
useEffect47(() => {
|
|
14067
14149
|
return () => {
|
|
14068
14150
|
for (const url of Object.values(blobUrlsRef.current)) {
|
|
14069
14151
|
try {
|
|
@@ -14120,7 +14202,7 @@ function PersonalizationProvider({
|
|
|
14120
14202
|
setIsExporting(true);
|
|
14121
14203
|
}, []);
|
|
14122
14204
|
const shouldMountCanvas = CanvasComponent && BridgeComponent && canvasState?.elements && canvasState.elements.length > 0 && (!lazy || isActive);
|
|
14123
|
-
const contextValue =
|
|
14205
|
+
const contextValue = React55.useMemo(
|
|
14124
14206
|
() => ({
|
|
14125
14207
|
fields,
|
|
14126
14208
|
personValues,
|
|
@@ -14134,7 +14216,7 @@ function PersonalizationProvider({
|
|
|
14134
14216
|
[fields, personValues, updateField, isActive, isExporting, exportedBlobUrls, exportCount, reset]
|
|
14135
14217
|
);
|
|
14136
14218
|
return /* @__PURE__ */ jsxs62(PersonalizationContext.Provider, { value: contextValue, children: [
|
|
14137
|
-
shouldMountCanvas && CanvasComponent && BridgeComponent && /* @__PURE__ */
|
|
14219
|
+
shouldMountCanvas && CanvasComponent && BridgeComponent && /* @__PURE__ */ jsx88(
|
|
14138
14220
|
"div",
|
|
14139
14221
|
{
|
|
14140
14222
|
style: {
|
|
@@ -14147,7 +14229,7 @@ function PersonalizationProvider({
|
|
|
14147
14229
|
pointerEvents: "none"
|
|
14148
14230
|
},
|
|
14149
14231
|
"aria-hidden": true,
|
|
14150
|
-
children: /* @__PURE__ */
|
|
14232
|
+
children: /* @__PURE__ */ jsx88(
|
|
14151
14233
|
CanvasComponent,
|
|
14152
14234
|
{
|
|
14153
14235
|
initialElements: canvasState?.elements,
|
|
@@ -14167,7 +14249,7 @@ function PersonalizationProvider({
|
|
|
14167
14249
|
exportImageQuality: exportConfig?.imageQuality ?? 0.85,
|
|
14168
14250
|
onExport: handleExport,
|
|
14169
14251
|
onExportScheduled: handleExportScheduled,
|
|
14170
|
-
overlay: /* @__PURE__ */
|
|
14252
|
+
overlay: /* @__PURE__ */ jsx88(BridgeComponent, { fields, values: personValues })
|
|
14171
14253
|
}
|
|
14172
14254
|
)
|
|
14173
14255
|
},
|
|
@@ -14192,7 +14274,7 @@ function usePersonalizationOptional() {
|
|
|
14192
14274
|
}
|
|
14193
14275
|
|
|
14194
14276
|
// src/personalization/PersonalizationInputs.tsx
|
|
14195
|
-
import { jsx as
|
|
14277
|
+
import { jsx as jsx89, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
14196
14278
|
function PersonalizationInputs({
|
|
14197
14279
|
className,
|
|
14198
14280
|
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",
|
|
@@ -14217,7 +14299,7 @@ function PersonalizationInputs({
|
|
|
14217
14299
|
}
|
|
14218
14300
|
};
|
|
14219
14301
|
return /* @__PURE__ */ jsxs63("div", { className: className || "flex flex-col gap-3", children: [
|
|
14220
|
-
textFields.map((field) => /* @__PURE__ */
|
|
14302
|
+
textFields.map((field) => /* @__PURE__ */ jsx89(
|
|
14221
14303
|
"input",
|
|
14222
14304
|
{
|
|
14223
14305
|
type: "text",
|
|
@@ -14232,7 +14314,7 @@ function PersonalizationInputs({
|
|
|
14232
14314
|
`text-${field.name}`
|
|
14233
14315
|
)),
|
|
14234
14316
|
colorFields.map((field) => /* @__PURE__ */ jsxs63("div", { className: "flex items-center gap-3", children: [
|
|
14235
|
-
/* @__PURE__ */
|
|
14317
|
+
/* @__PURE__ */ jsx89(
|
|
14236
14318
|
"input",
|
|
14237
14319
|
{
|
|
14238
14320
|
type: "color",
|
|
@@ -14241,9 +14323,9 @@ function PersonalizationInputs({
|
|
|
14241
14323
|
onChange: (e) => updateField(field.color, e.target.value)
|
|
14242
14324
|
}
|
|
14243
14325
|
),
|
|
14244
|
-
/* @__PURE__ */
|
|
14326
|
+
/* @__PURE__ */ jsx89("span", { className: "text-base text-muted-foreground", children: field.label })
|
|
14245
14327
|
] }, `color-${field.color}`)),
|
|
14246
|
-
imageFields.map((field) => /* @__PURE__ */
|
|
14328
|
+
imageFields.map((field) => /* @__PURE__ */ jsx89(
|
|
14247
14329
|
"input",
|
|
14248
14330
|
{
|
|
14249
14331
|
type: "text",
|
|
@@ -14261,11 +14343,11 @@ function PersonalizationInputs({
|
|
|
14261
14343
|
}
|
|
14262
14344
|
|
|
14263
14345
|
// src/personalization/usePersonalizationShimmer.ts
|
|
14264
|
-
import { useState as
|
|
14346
|
+
import { useState as useState47, useEffect as useEffect48, useRef as useRef31, useCallback as useCallback27 } from "react";
|
|
14265
14347
|
function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
14266
14348
|
const personCtx = usePersonalizationContext();
|
|
14267
14349
|
const realtime = useRealtimeOptional();
|
|
14268
|
-
const [shimmerActive, setShimmerActive] =
|
|
14350
|
+
const [shimmerActive, setShimmerActive] = useState47(false);
|
|
14269
14351
|
const sdkSettledRef = useRef31(false);
|
|
14270
14352
|
const manualTriggerRef = useRef31(false);
|
|
14271
14353
|
const safetyTimeoutRef = useRef31(void 0);
|
|
@@ -14281,7 +14363,7 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
14281
14363
|
safetyTimeoutMs
|
|
14282
14364
|
);
|
|
14283
14365
|
}, [safetyTimeoutMs]);
|
|
14284
|
-
|
|
14366
|
+
useEffect48(() => {
|
|
14285
14367
|
if (!personCtx?.isActive) return;
|
|
14286
14368
|
sdkSettledRef.current = false;
|
|
14287
14369
|
manualTriggerRef.current = false;
|
|
@@ -14293,13 +14375,13 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
14293
14375
|
manualTriggerRef.current = true;
|
|
14294
14376
|
startShimmer();
|
|
14295
14377
|
}, [startShimmer]);
|
|
14296
|
-
|
|
14378
|
+
useEffect48(() => {
|
|
14297
14379
|
if (!realtime?.subscribePipelineSettled) return;
|
|
14298
14380
|
return realtime.subscribePipelineSettled(() => {
|
|
14299
14381
|
sdkSettledRef.current = true;
|
|
14300
14382
|
});
|
|
14301
14383
|
}, [realtime]);
|
|
14302
|
-
|
|
14384
|
+
useEffect48(() => {
|
|
14303
14385
|
const container = containerRef.current;
|
|
14304
14386
|
if (!container) return;
|
|
14305
14387
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -14342,7 +14424,7 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
14342
14424
|
});
|
|
14343
14425
|
return () => observer.disconnect();
|
|
14344
14426
|
}, [containerRef]);
|
|
14345
|
-
|
|
14427
|
+
useEffect48(() => {
|
|
14346
14428
|
return () => {
|
|
14347
14429
|
if (safetyTimeoutRef.current) clearTimeout(safetyTimeoutRef.current);
|
|
14348
14430
|
};
|
|
@@ -14483,6 +14565,7 @@ export {
|
|
|
14483
14565
|
RealtimeProvider,
|
|
14484
14566
|
ResponsiveZoom,
|
|
14485
14567
|
RightToLeftProgressiveBlur,
|
|
14568
|
+
SafeImg,
|
|
14486
14569
|
ScrollFade,
|
|
14487
14570
|
SearchBox,
|
|
14488
14571
|
SearchProvider,
|