@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.cjs
CHANGED
|
@@ -271,6 +271,7 @@ __export(src_exports, {
|
|
|
271
271
|
RealtimeProvider: () => RealtimeProvider,
|
|
272
272
|
ResponsiveZoom: () => ResponsiveZoom,
|
|
273
273
|
RightToLeftProgressiveBlur: () => RightToLeftProgressiveBlur,
|
|
274
|
+
SafeImg: () => SafeImg,
|
|
274
275
|
ScrollFade: () => ScrollFade,
|
|
275
276
|
SearchBox: () => SearchBox,
|
|
276
277
|
SearchProvider: () => SearchProvider,
|
|
@@ -378,7 +379,7 @@ __export(src_exports, {
|
|
|
378
379
|
useProductSelection: () => useProductSelection,
|
|
379
380
|
useProviderStatus: () => useProviderStatus,
|
|
380
381
|
useRealtime: () => useRealtime,
|
|
381
|
-
useRealtimeMockup: () =>
|
|
382
|
+
useRealtimeMockup: () => import_react70.useRealtimeMockup,
|
|
382
383
|
useRealtimeOptional: () => useRealtimeOptional,
|
|
383
384
|
useRenderCount: () => useRenderCount,
|
|
384
385
|
useRenderGuard: () => useRenderGuard,
|
|
@@ -5979,8 +5980,8 @@ function RealtimeProvider({
|
|
|
5979
5980
|
},
|
|
5980
5981
|
onAllMockupsRendered: (results) => {
|
|
5981
5982
|
},
|
|
5982
|
-
onError: (error) => {
|
|
5983
|
-
console.error(
|
|
5983
|
+
onError: (error, detail) => {
|
|
5984
|
+
console.error(`[RealtimeProvider] Render error [${detail.code}]:`, error);
|
|
5984
5985
|
}
|
|
5985
5986
|
});
|
|
5986
5987
|
const subscribeRTCTiming = (0, import_react24.useCallback)((_callback) => {
|
|
@@ -5990,6 +5991,7 @@ function RealtimeProvider({
|
|
|
5990
5991
|
const {
|
|
5991
5992
|
isConnected,
|
|
5992
5993
|
isConfigured,
|
|
5994
|
+
renderError,
|
|
5993
5995
|
mockupResults: rawMockupResults,
|
|
5994
5996
|
sendCanvasBlob: sendCanvasBlobRaw,
|
|
5995
5997
|
sendCanvasState: sendCanvasStateRaw,
|
|
@@ -6509,6 +6511,7 @@ function RealtimeProvider({
|
|
|
6509
6511
|
isEnabled,
|
|
6510
6512
|
isConnected,
|
|
6511
6513
|
isConfigured,
|
|
6514
|
+
renderError,
|
|
6512
6515
|
// Read from ref - this is a snapshot at render time, NOT reactive
|
|
6513
6516
|
// For reactive updates, use getMockupResultsImmediate() or subscribe functions
|
|
6514
6517
|
get mockupResults() {
|
|
@@ -6552,6 +6555,7 @@ function RealtimeProvider({
|
|
|
6552
6555
|
isEnabled,
|
|
6553
6556
|
isConnected,
|
|
6554
6557
|
isConfigured,
|
|
6558
|
+
renderError,
|
|
6555
6559
|
// mockupResults removed from deps - it's a getter that reads from ref
|
|
6556
6560
|
canvasExportSize,
|
|
6557
6561
|
mockupWidth,
|
|
@@ -9338,7 +9342,7 @@ var LoadingOverlayPrismCandyInline = (0, import_react40.memo)(
|
|
|
9338
9342
|
);
|
|
9339
9343
|
|
|
9340
9344
|
// src/index.ts
|
|
9341
|
-
var
|
|
9345
|
+
var import_react70 = require("@snowcone-app/sdk/react");
|
|
9342
9346
|
var import_sdk11 = require("@snowcone-app/sdk");
|
|
9343
9347
|
|
|
9344
9348
|
// src/patterns/ProductPageProvider.tsx
|
|
@@ -10412,12 +10416,18 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10412
10416
|
const [showNew, setShowNew] = (0, import_react45.useState)(false);
|
|
10413
10417
|
const [renderedUrl, setRenderedUrl] = (0, import_react45.useState)(displayUrl);
|
|
10414
10418
|
const [firstImageLoaded, setFirstImageLoaded] = (0, import_react45.useState)(false);
|
|
10419
|
+
const [loaderMounted, setLoaderMounted] = (0, import_react45.useState)(true);
|
|
10420
|
+
const [imgFailed, setImgFailed] = (0, import_react45.useState)(false);
|
|
10421
|
+
const [retryNonce, setRetryNonce] = (0, import_react45.useState)(0);
|
|
10422
|
+
const retriedUrlRef = (0, import_react45.useRef)(null);
|
|
10415
10423
|
const prevDisplayUrlRef = (0, import_react45.useRef)(displayUrl);
|
|
10416
10424
|
const signHintShownRef = (0, import_react45.useRef)(false);
|
|
10417
10425
|
(0, import_react45.useEffect)(() => {
|
|
10418
10426
|
if (!displayUrl || displayUrl === prevDisplayUrlRef.current) return;
|
|
10419
10427
|
const oldUrl = prevDisplayUrlRef.current;
|
|
10420
10428
|
prevDisplayUrlRef.current = displayUrl;
|
|
10429
|
+
setImgFailed(false);
|
|
10430
|
+
retriedUrlRef.current = null;
|
|
10421
10431
|
if (!oldUrl) {
|
|
10422
10432
|
setRenderedUrl(displayUrl);
|
|
10423
10433
|
return;
|
|
@@ -10443,6 +10453,7 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10443
10453
|
setPrevUrl(null);
|
|
10444
10454
|
setShowNew(false);
|
|
10445
10455
|
}, []);
|
|
10456
|
+
const handleLoaderExited = (0, import_react45.useCallback)(() => setLoaderMounted(false), []);
|
|
10446
10457
|
if (!hasArtwork) {
|
|
10447
10458
|
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10448
10459
|
"div",
|
|
@@ -10491,19 +10502,19 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10491
10502
|
style,
|
|
10492
10503
|
"data-hero-image": "true",
|
|
10493
10504
|
children: [
|
|
10494
|
-
!
|
|
10495
|
-
renderedUrl && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10505
|
+
renderedUrl && !imgFailed && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10496
10506
|
"img",
|
|
10497
10507
|
{
|
|
10498
10508
|
alt: `Product mockup${placement ? ` - ${placement}` : ""}`,
|
|
10499
10509
|
crossOrigin: "anonymous",
|
|
10500
10510
|
className: "absolute inset-0 w-full h-full object-cover",
|
|
10501
10511
|
draggable,
|
|
10502
|
-
src: renderedUrl,
|
|
10512
|
+
src: retriedUrlRef.current === renderedUrl ? `${renderedUrl}${renderedUrl.includes("?") ? "&" : "?"}_cb=${retryNonce}` : renderedUrl,
|
|
10503
10513
|
loading: "eager",
|
|
10504
10514
|
fetchPriority: "high",
|
|
10505
10515
|
onClick,
|
|
10506
10516
|
onLoad: () => {
|
|
10517
|
+
setImgFailed(false);
|
|
10507
10518
|
setFirstImageLoaded(true);
|
|
10508
10519
|
if (!onLoadCalledRef.current && onLoad) {
|
|
10509
10520
|
onLoadCalledRef.current = true;
|
|
@@ -10512,6 +10523,12 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10512
10523
|
onUrlGeneratedRef.current?.(renderedUrl);
|
|
10513
10524
|
},
|
|
10514
10525
|
onError: () => {
|
|
10526
|
+
if (renderedUrl && retriedUrlRef.current !== renderedUrl) {
|
|
10527
|
+
retriedUrlRef.current = renderedUrl;
|
|
10528
|
+
setRetryNonce((n) => n + 1);
|
|
10529
|
+
return;
|
|
10530
|
+
}
|
|
10531
|
+
setImgFailed(true);
|
|
10515
10532
|
setFirstImageLoaded(true);
|
|
10516
10533
|
onError?.();
|
|
10517
10534
|
if (process.env.NODE_ENV !== "production" && !signHintShownRef.current && renderedUrl && /\/[A-Za-z0-9]+\?/.test(renderedUrl) && !/[?&]signature=/.test(renderedUrl)) {
|
|
@@ -10524,6 +10541,16 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10524
10541
|
}
|
|
10525
10542
|
}
|
|
10526
10543
|
),
|
|
10544
|
+
imgFailed && !prevUrl && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "text-muted-foreground text-xs", children: "Preview unavailable" }) }),
|
|
10545
|
+
realtimeContext?.renderError && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10546
|
+
"div",
|
|
10547
|
+
{
|
|
10548
|
+
role: "alert",
|
|
10549
|
+
"data-render-error": realtimeContext.renderError.code,
|
|
10550
|
+
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",
|
|
10551
|
+
children: `Render blocked: ${realtimeContext.renderError.code} \u2014 ${realtimeContext.renderError.message}`
|
|
10552
|
+
}
|
|
10553
|
+
),
|
|
10527
10554
|
prevUrl && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10528
10555
|
"img",
|
|
10529
10556
|
{
|
|
@@ -10538,12 +10565,45 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10538
10565
|
},
|
|
10539
10566
|
onTransitionEnd: handleCrossfadeEnd
|
|
10540
10567
|
}
|
|
10568
|
+
),
|
|
10569
|
+
loaderMounted && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10570
|
+
LoadingOverlayPrismCandyInline,
|
|
10571
|
+
{
|
|
10572
|
+
visible: !firstImageLoaded,
|
|
10573
|
+
variant: "light",
|
|
10574
|
+
onExited: handleLoaderExited
|
|
10575
|
+
}
|
|
10541
10576
|
)
|
|
10542
10577
|
]
|
|
10543
10578
|
}
|
|
10544
10579
|
);
|
|
10545
10580
|
});
|
|
10546
10581
|
|
|
10582
|
+
// src/composed/SafeImg.tsx
|
|
10583
|
+
var import_react46 = __toESM(require("react"), 1);
|
|
10584
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
10585
|
+
var SafeImg = import_react46.default.forwardRef(
|
|
10586
|
+
function SafeImg2({ fallback = null, onError, src, ...rest }, ref) {
|
|
10587
|
+
const [failed, setFailed] = (0, import_react46.useState)(false);
|
|
10588
|
+
(0, import_react46.useEffect)(() => {
|
|
10589
|
+
setFailed(false);
|
|
10590
|
+
}, [src]);
|
|
10591
|
+
if (failed) return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_jsx_runtime61.Fragment, { children: fallback });
|
|
10592
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
10593
|
+
"img",
|
|
10594
|
+
{
|
|
10595
|
+
...rest,
|
|
10596
|
+
ref,
|
|
10597
|
+
src,
|
|
10598
|
+
onError: (e) => {
|
|
10599
|
+
setFailed(true);
|
|
10600
|
+
onError?.(e);
|
|
10601
|
+
}
|
|
10602
|
+
}
|
|
10603
|
+
);
|
|
10604
|
+
}
|
|
10605
|
+
);
|
|
10606
|
+
|
|
10547
10607
|
// src/index.ts
|
|
10548
10608
|
var import_sdk12 = require("@snowcone-app/sdk");
|
|
10549
10609
|
|
|
@@ -10553,7 +10613,7 @@ var import_react_instantsearch = require("react-instantsearch");
|
|
|
10553
10613
|
// src/composed/search/meilisearchAdapter.ts
|
|
10554
10614
|
var import_instant_meilisearch = require("@meilisearch/instant-meilisearch");
|
|
10555
10615
|
var MEILISEARCH_HOST = readEnv("NEXT_PUBLIC_MEILISEARCH_HOST") || "https://ms-e5d999b2eaca-15654.sfo.meilisearch.io";
|
|
10556
|
-
var MEILISEARCH_API_KEY = readEnv("NEXT_PUBLIC_MEILISEARCH_API_KEY") || "
|
|
10616
|
+
var MEILISEARCH_API_KEY = readEnv("NEXT_PUBLIC_MEILISEARCH_API_KEY") || "4a11f6599e39af365f6289dab46b77a30ef78ba1ac078f7d74e152c099b3b63c";
|
|
10557
10617
|
var { searchClient } = (0, import_instant_meilisearch.instantMeiliSearch)(
|
|
10558
10618
|
MEILISEARCH_HOST,
|
|
10559
10619
|
MEILISEARCH_API_KEY,
|
|
@@ -10564,11 +10624,11 @@ var { searchClient } = (0, import_instant_meilisearch.instantMeiliSearch)(
|
|
|
10564
10624
|
);
|
|
10565
10625
|
|
|
10566
10626
|
// src/composed/search/SearchProvider.tsx
|
|
10567
|
-
var
|
|
10568
|
-
var
|
|
10627
|
+
var import_react47 = require("react");
|
|
10628
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
10569
10629
|
function InitialSearchTrigger() {
|
|
10570
10630
|
const { refine } = (0, import_react_instantsearch.useSearchBox)();
|
|
10571
|
-
(0,
|
|
10631
|
+
(0, import_react47.useEffect)(() => {
|
|
10572
10632
|
refine("");
|
|
10573
10633
|
}, [refine]);
|
|
10574
10634
|
return null;
|
|
@@ -10592,7 +10652,7 @@ function SearchProvider({
|
|
|
10592
10652
|
],
|
|
10593
10653
|
children
|
|
10594
10654
|
}) {
|
|
10595
|
-
return /* @__PURE__ */ (0,
|
|
10655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
|
|
10596
10656
|
import_react_instantsearch.InstantSearch,
|
|
10597
10657
|
{
|
|
10598
10658
|
searchClient,
|
|
@@ -10620,7 +10680,7 @@ function SearchProvider({
|
|
|
10620
10680
|
}
|
|
10621
10681
|
},
|
|
10622
10682
|
children: [
|
|
10623
|
-
/* @__PURE__ */ (0,
|
|
10683
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
10624
10684
|
import_react_instantsearch.Configure,
|
|
10625
10685
|
{
|
|
10626
10686
|
hitsPerPage,
|
|
@@ -10629,7 +10689,7 @@ function SearchProvider({
|
|
|
10629
10689
|
attributesToRetrieve
|
|
10630
10690
|
}
|
|
10631
10691
|
),
|
|
10632
|
-
/* @__PURE__ */ (0,
|
|
10692
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(InitialSearchTrigger, {}),
|
|
10633
10693
|
children
|
|
10634
10694
|
]
|
|
10635
10695
|
}
|
|
@@ -10639,17 +10699,17 @@ function SearchProvider({
|
|
|
10639
10699
|
// src/composed/search/SearchBox.tsx
|
|
10640
10700
|
var import_react_instantsearch2 = require("react-instantsearch");
|
|
10641
10701
|
var import_lucide_react3 = require("lucide-react");
|
|
10642
|
-
var
|
|
10643
|
-
var
|
|
10702
|
+
var import_react48 = require("react");
|
|
10703
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
10644
10704
|
function SearchBox() {
|
|
10645
10705
|
const { query, refine, clear } = (0, import_react_instantsearch2.useSearchBox)();
|
|
10646
10706
|
const searchParams = useUiSearchParams();
|
|
10647
10707
|
const router = useUiRouter();
|
|
10648
|
-
const inputRef = (0,
|
|
10649
|
-
const [showShimmer, setShowShimmer] = (0,
|
|
10708
|
+
const inputRef = (0, import_react48.useRef)(null);
|
|
10709
|
+
const [showShimmer, setShowShimmer] = (0, import_react48.useState)(false);
|
|
10650
10710
|
const inputId = "search-products-input";
|
|
10651
10711
|
const descriptionId = "search-description";
|
|
10652
|
-
(0,
|
|
10712
|
+
(0, import_react48.useEffect)(() => {
|
|
10653
10713
|
const handleSpotlight = () => {
|
|
10654
10714
|
inputRef.current?.focus();
|
|
10655
10715
|
inputRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
@@ -10659,7 +10719,7 @@ function SearchBox() {
|
|
|
10659
10719
|
window.addEventListener("search-spotlight", handleSpotlight);
|
|
10660
10720
|
return () => window.removeEventListener("search-spotlight", handleSpotlight);
|
|
10661
10721
|
}, []);
|
|
10662
|
-
(0,
|
|
10722
|
+
(0, import_react48.useEffect)(() => {
|
|
10663
10723
|
const shouldFocus = searchParams.get("focus") === "search";
|
|
10664
10724
|
if (shouldFocus && inputRef.current) {
|
|
10665
10725
|
const timer = setTimeout(() => {
|
|
@@ -10674,8 +10734,8 @@ function SearchBox() {
|
|
|
10674
10734
|
return () => clearTimeout(timer);
|
|
10675
10735
|
}
|
|
10676
10736
|
}, [searchParams, router]);
|
|
10677
|
-
return /* @__PURE__ */ (0,
|
|
10678
|
-
/* @__PURE__ */ (0,
|
|
10737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("form", { role: "search", onSubmit: (e) => e.preventDefault(), children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "relative", children: [
|
|
10738
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10679
10739
|
Input,
|
|
10680
10740
|
{
|
|
10681
10741
|
ref: inputRef,
|
|
@@ -10684,15 +10744,15 @@ function SearchBox() {
|
|
|
10684
10744
|
value: query,
|
|
10685
10745
|
onChange: (e) => refine(e.target.value),
|
|
10686
10746
|
placeholder: "Search products...",
|
|
10687
|
-
startContent: /* @__PURE__ */ (0,
|
|
10688
|
-
endContent: query ? /* @__PURE__ */ (0,
|
|
10747
|
+
startContent: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react3.Search, { className: "w-5 h-5", strokeWidth: 1.5, "aria-hidden": "true" }),
|
|
10748
|
+
endContent: query ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10689
10749
|
"button",
|
|
10690
10750
|
{
|
|
10691
10751
|
type: "button",
|
|
10692
10752
|
onClick: clear,
|
|
10693
10753
|
className: "hover:text-foreground transition-colors",
|
|
10694
10754
|
"aria-label": "Clear search",
|
|
10695
|
-
children: /* @__PURE__ */ (0,
|
|
10755
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react3.X, { className: "w-4 h-4", strokeWidth: 2, "aria-hidden": "true" })
|
|
10696
10756
|
}
|
|
10697
10757
|
) : void 0,
|
|
10698
10758
|
"aria-label": "Search products",
|
|
@@ -10702,11 +10762,11 @@ function SearchBox() {
|
|
|
10702
10762
|
className: "[&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden"
|
|
10703
10763
|
}
|
|
10704
10764
|
),
|
|
10705
|
-
showShimmer && /* @__PURE__ */ (0,
|
|
10765
|
+
showShimmer && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10706
10766
|
"div",
|
|
10707
10767
|
{
|
|
10708
10768
|
className: "absolute inset-0 pointer-events-none rounded-input z-20 overflow-hidden",
|
|
10709
|
-
children: /* @__PURE__ */ (0,
|
|
10769
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10710
10770
|
"div",
|
|
10711
10771
|
{
|
|
10712
10772
|
className: "absolute inset-0",
|
|
@@ -10719,13 +10779,13 @@ function SearchBox() {
|
|
|
10719
10779
|
)
|
|
10720
10780
|
}
|
|
10721
10781
|
),
|
|
10722
|
-
/* @__PURE__ */ (0,
|
|
10782
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("style", { dangerouslySetInnerHTML: { __html: `
|
|
10723
10783
|
@keyframes searchShimmer {
|
|
10724
10784
|
0% { transform: translateX(-100%); }
|
|
10725
10785
|
100% { transform: translateX(100%); }
|
|
10726
10786
|
}
|
|
10727
10787
|
` } }),
|
|
10728
|
-
/* @__PURE__ */ (0,
|
|
10788
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { id: descriptionId, className: "sr-only", children: "Search results will update as you type" })
|
|
10729
10789
|
] }) });
|
|
10730
10790
|
}
|
|
10731
10791
|
|
|
@@ -10733,7 +10793,7 @@ function SearchBox() {
|
|
|
10733
10793
|
var import_react_instantsearch3 = require("react-instantsearch");
|
|
10734
10794
|
|
|
10735
10795
|
// src/composed/search/ProductHit.tsx
|
|
10736
|
-
var
|
|
10796
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
10737
10797
|
function ProductHitComponent({
|
|
10738
10798
|
hit: product,
|
|
10739
10799
|
variant = "overlay"
|
|
@@ -10750,12 +10810,12 @@ function ProductHitComponent({
|
|
|
10750
10810
|
}
|
|
10751
10811
|
return "";
|
|
10752
10812
|
};
|
|
10753
|
-
return /* @__PURE__ */ (0,
|
|
10813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
10754
10814
|
Product,
|
|
10755
10815
|
{
|
|
10756
10816
|
productId,
|
|
10757
10817
|
productData: product,
|
|
10758
|
-
children: /* @__PURE__ */ (0,
|
|
10818
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
10759
10819
|
ProductCard,
|
|
10760
10820
|
{
|
|
10761
10821
|
variant,
|
|
@@ -10776,10 +10836,10 @@ function ProductHitComponent({
|
|
|
10776
10836
|
}
|
|
10777
10837
|
|
|
10778
10838
|
// src/composed/search/ProductGrid.tsx
|
|
10779
|
-
var
|
|
10780
|
-
var
|
|
10839
|
+
var import_react49 = require("react");
|
|
10840
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
10781
10841
|
function ProductGridSkeletonItem() {
|
|
10782
|
-
return /* @__PURE__ */ (0,
|
|
10842
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "aspect-square bg-muted animate-pulse" });
|
|
10783
10843
|
}
|
|
10784
10844
|
function ProductGrid({
|
|
10785
10845
|
className = "",
|
|
@@ -10789,26 +10849,26 @@ function ProductGrid({
|
|
|
10789
10849
|
}) {
|
|
10790
10850
|
const { nbHits } = (0, import_react_instantsearch3.useStats)();
|
|
10791
10851
|
const { status, results } = (0, import_react_instantsearch3.useInstantSearch)();
|
|
10792
|
-
const [announcement, setAnnouncement] = (0,
|
|
10852
|
+
const [announcement, setAnnouncement] = (0, import_react49.useState)("");
|
|
10793
10853
|
const hitsCount = results?.hits?.length ?? 0;
|
|
10794
10854
|
const showSkeleton = hitsCount === 0 && status !== "error";
|
|
10795
|
-
(0,
|
|
10855
|
+
(0, import_react49.useEffect)(() => {
|
|
10796
10856
|
const timer = setTimeout(() => {
|
|
10797
10857
|
setAnnouncement(`${nbHits} ${nbHits === 1 ? "product" : "products"} found`);
|
|
10798
10858
|
}, 1e3);
|
|
10799
10859
|
return () => clearTimeout(timer);
|
|
10800
10860
|
}, [nbHits]);
|
|
10801
|
-
const HitComponent = (0,
|
|
10861
|
+
const HitComponent = (0, import_react49.useCallback)(({ hit }) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
10802
10862
|
ProductHitComponent,
|
|
10803
10863
|
{
|
|
10804
10864
|
hit,
|
|
10805
10865
|
variant
|
|
10806
10866
|
}
|
|
10807
10867
|
), [variant]);
|
|
10808
|
-
return /* @__PURE__ */ (0,
|
|
10809
|
-
/* @__PURE__ */ (0,
|
|
10810
|
-
showSkeleton && /* @__PURE__ */ (0,
|
|
10811
|
-
/* @__PURE__ */ (0,
|
|
10868
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className, children: [
|
|
10869
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement }),
|
|
10870
|
+
showSkeleton && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: `grid ${gridClassName}`, children: Array.from({ length: skeletonCount }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(ProductGridSkeletonItem, {}, i)) }),
|
|
10871
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: showSkeleton ? "hidden" : "", children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
10812
10872
|
import_react_instantsearch3.Hits,
|
|
10813
10873
|
{
|
|
10814
10874
|
hitComponent: HitComponent,
|
|
@@ -10823,18 +10883,18 @@ function ProductGrid({
|
|
|
10823
10883
|
}
|
|
10824
10884
|
|
|
10825
10885
|
// src/composed/search/Filters.tsx
|
|
10826
|
-
var
|
|
10886
|
+
var import_react51 = require("react");
|
|
10827
10887
|
|
|
10828
10888
|
// src/composed/search/FiltersButton.tsx
|
|
10829
10889
|
var import_lucide_react4 = require("lucide-react");
|
|
10830
|
-
var
|
|
10890
|
+
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
10831
10891
|
var SlidersHorizontalIcon = import_lucide_react4.SlidersHorizontal;
|
|
10832
10892
|
function FiltersButton({
|
|
10833
10893
|
onClick,
|
|
10834
10894
|
className = "",
|
|
10835
10895
|
children = "Filters"
|
|
10836
10896
|
}) {
|
|
10837
|
-
return /* @__PURE__ */ (0,
|
|
10897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
|
|
10838
10898
|
Button,
|
|
10839
10899
|
{
|
|
10840
10900
|
variant: "field",
|
|
@@ -10842,8 +10902,8 @@ function FiltersButton({
|
|
|
10842
10902
|
className,
|
|
10843
10903
|
"aria-label": "Open filters",
|
|
10844
10904
|
children: [
|
|
10845
|
-
/* @__PURE__ */ (0,
|
|
10846
|
-
/* @__PURE__ */ (0,
|
|
10905
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(SlidersHorizontalIcon, { className: "w-4 h-4" }),
|
|
10906
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { children })
|
|
10847
10907
|
]
|
|
10848
10908
|
}
|
|
10849
10909
|
);
|
|
@@ -10852,15 +10912,15 @@ function FiltersButton({
|
|
|
10852
10912
|
// src/composed/search/FiltersDrawer.tsx
|
|
10853
10913
|
var import_react_instantsearch4 = require("react-instantsearch");
|
|
10854
10914
|
var import_lucide_react5 = require("lucide-react");
|
|
10855
|
-
var
|
|
10915
|
+
var import_react50 = require("react");
|
|
10856
10916
|
var Slider2 = __toESM(require("@radix-ui/react-slider"), 1);
|
|
10857
|
-
var
|
|
10917
|
+
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
10858
10918
|
var XIcon2 = import_lucide_react5.X;
|
|
10859
10919
|
function FiltersDrawer({ isOpen, onClose }) {
|
|
10860
|
-
const [showCounts, setShowCounts] = (0,
|
|
10920
|
+
const [showCounts, setShowCounts] = (0, import_react50.useState)(false);
|
|
10861
10921
|
const { nbHits } = (0, import_react_instantsearch4.useStats)();
|
|
10862
10922
|
const containerRef = useFocusTrap(isOpen, onClose);
|
|
10863
|
-
(0,
|
|
10923
|
+
(0, import_react50.useEffect)(() => {
|
|
10864
10924
|
if (isOpen) {
|
|
10865
10925
|
document.body.style.overflow = "hidden";
|
|
10866
10926
|
} else {
|
|
@@ -10870,7 +10930,7 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10870
10930
|
document.body.style.overflow = "";
|
|
10871
10931
|
};
|
|
10872
10932
|
}, [isOpen]);
|
|
10873
|
-
(0,
|
|
10933
|
+
(0, import_react50.useEffect)(() => {
|
|
10874
10934
|
const handleEscape = (e) => {
|
|
10875
10935
|
if (e.key === "Escape" && isOpen) {
|
|
10876
10936
|
onClose();
|
|
@@ -10879,8 +10939,8 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10879
10939
|
document.addEventListener("keydown", handleEscape);
|
|
10880
10940
|
return () => document.removeEventListener("keydown", handleEscape);
|
|
10881
10941
|
}, [isOpen, onClose]);
|
|
10882
|
-
return /* @__PURE__ */ (0,
|
|
10883
|
-
/* @__PURE__ */ (0,
|
|
10942
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(import_jsx_runtime67.Fragment, { children: [
|
|
10943
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
10884
10944
|
"div",
|
|
10885
10945
|
{
|
|
10886
10946
|
className: `fixed inset-0 bg-black/50 z-40 transition-opacity ${isOpen ? "opacity-100" : "opacity-0 pointer-events-none"}`,
|
|
@@ -10888,7 +10948,7 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10888
10948
|
"aria-hidden": "true"
|
|
10889
10949
|
}
|
|
10890
10950
|
),
|
|
10891
|
-
/* @__PURE__ */ (0,
|
|
10951
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
10892
10952
|
"div",
|
|
10893
10953
|
{
|
|
10894
10954
|
ref: containerRef,
|
|
@@ -10897,26 +10957,26 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10897
10957
|
"aria-modal": "true",
|
|
10898
10958
|
"aria-labelledby": "filters-drawer-title",
|
|
10899
10959
|
children: [
|
|
10900
|
-
/* @__PURE__ */ (0,
|
|
10901
|
-
/* @__PURE__ */ (0,
|
|
10902
|
-
/* @__PURE__ */ (0,
|
|
10960
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "flex items-center justify-between px-4 py-4", children: [
|
|
10961
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("h2", { id: "filters-drawer-title", className: "text-xl font-bold", children: "Filters" }),
|
|
10962
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
10903
10963
|
"button",
|
|
10904
10964
|
{
|
|
10905
10965
|
onClick: onClose,
|
|
10906
10966
|
className: "p-2 hover:bg-foreground/5 rounded-full transition-colors",
|
|
10907
10967
|
"aria-label": "Close filters",
|
|
10908
|
-
children: /* @__PURE__ */ (0,
|
|
10968
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(XIcon2, { className: "w-5 h-5" })
|
|
10909
10969
|
}
|
|
10910
10970
|
)
|
|
10911
10971
|
] }),
|
|
10912
|
-
/* @__PURE__ */ (0,
|
|
10972
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: "px-4 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("p", { className: "text-sm font-caption text-foreground/60", role: "status", "aria-live": "polite", children: [
|
|
10913
10973
|
nbHits.toLocaleString(),
|
|
10914
10974
|
" ",
|
|
10915
10975
|
nbHits === 1 ? "result" : "results"
|
|
10916
10976
|
] }) }),
|
|
10917
|
-
/* @__PURE__ */ (0,
|
|
10918
|
-
/* @__PURE__ */ (0,
|
|
10919
|
-
/* @__PURE__ */ (0,
|
|
10977
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: "flex-1 overflow-y-auto px-4 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "flex flex-col gap-8", children: [
|
|
10978
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(TagsSection, { showCounts, setShowCounts }),
|
|
10979
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(PriceSection, {})
|
|
10920
10980
|
] }) })
|
|
10921
10981
|
]
|
|
10922
10982
|
}
|
|
@@ -10932,9 +10992,9 @@ function TagsSection({
|
|
|
10932
10992
|
sortBy: ["count:desc", "name:asc"],
|
|
10933
10993
|
limit: 100
|
|
10934
10994
|
});
|
|
10935
|
-
const [isExpanded, setIsExpanded] = (0,
|
|
10936
|
-
return /* @__PURE__ */ (0,
|
|
10937
|
-
/* @__PURE__ */ (0,
|
|
10995
|
+
const [isExpanded, setIsExpanded] = (0, import_react50.useState)(true);
|
|
10996
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "bg-foreground/5 rounded-lg p-4", children: [
|
|
10997
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
10938
10998
|
"button",
|
|
10939
10999
|
{
|
|
10940
11000
|
onClick: () => setIsExpanded(!isExpanded),
|
|
@@ -10942,8 +11002,8 @@ function TagsSection({
|
|
|
10942
11002
|
"aria-expanded": isExpanded,
|
|
10943
11003
|
"aria-controls": "tags-content",
|
|
10944
11004
|
children: [
|
|
10945
|
-
/* @__PURE__ */ (0,
|
|
10946
|
-
/* @__PURE__ */ (0,
|
|
11005
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("h3", { className: "text-base font-semibold text-primary", children: "Tags" }),
|
|
11006
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
10947
11007
|
"svg",
|
|
10948
11008
|
{
|
|
10949
11009
|
className: `w-5 h-5 transition-transform text-foreground/40 group-hover:text-foreground/60 ${isExpanded ? "rotate-180" : ""}`,
|
|
@@ -10952,14 +11012,14 @@ function TagsSection({
|
|
|
10952
11012
|
stroke: "currentColor",
|
|
10953
11013
|
strokeWidth: 2.5,
|
|
10954
11014
|
"aria-hidden": "true",
|
|
10955
|
-
children: /* @__PURE__ */ (0,
|
|
11015
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
|
|
10956
11016
|
}
|
|
10957
11017
|
)
|
|
10958
11018
|
]
|
|
10959
11019
|
}
|
|
10960
11020
|
),
|
|
10961
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
10962
|
-
/* @__PURE__ */ (0,
|
|
11021
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "space-y-4", id: "tags-content", children: [
|
|
11022
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: "flex flex-wrap gap-2", role: "group", "aria-label": "Product tags filter", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
10963
11023
|
"button",
|
|
10964
11024
|
{
|
|
10965
11025
|
onClick: () => refine(item.value),
|
|
@@ -10970,15 +11030,15 @@ function TagsSection({
|
|
|
10970
11030
|
"aria-label": `${item.isRefined ? "Remove" : "Apply"} ${item.label} filter${showCounts ? ` (${item.count} products)` : ""}`,
|
|
10971
11031
|
"aria-pressed": item.isRefined,
|
|
10972
11032
|
children: [
|
|
10973
|
-
/* @__PURE__ */ (0,
|
|
10974
|
-
showCounts && /* @__PURE__ */ (0,
|
|
11033
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { "aria-hidden": "true", children: item.label }),
|
|
11034
|
+
showCounts && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: `text-xs font-caption ${item.isRefined ? "opacity-80" : "opacity-60"}`, "aria-hidden": "true", children: item.count })
|
|
10975
11035
|
]
|
|
10976
11036
|
},
|
|
10977
11037
|
item.value
|
|
10978
11038
|
)) }),
|
|
10979
|
-
/* @__PURE__ */ (0,
|
|
10980
|
-
/* @__PURE__ */ (0,
|
|
10981
|
-
/* @__PURE__ */ (0,
|
|
11039
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "flex items-center justify-between pt-2", children: [
|
|
11040
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "text-sm font-label text-foreground/60", id: "show-counts-label", children: "Show counts" }),
|
|
11041
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
10982
11042
|
"button",
|
|
10983
11043
|
{
|
|
10984
11044
|
onClick: () => setShowCounts(!showCounts),
|
|
@@ -10986,7 +11046,7 @@ function TagsSection({
|
|
|
10986
11046
|
role: "switch",
|
|
10987
11047
|
"aria-checked": showCounts,
|
|
10988
11048
|
"aria-labelledby": "show-counts-label",
|
|
10989
|
-
children: /* @__PURE__ */ (0,
|
|
11049
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
10990
11050
|
"span",
|
|
10991
11051
|
{
|
|
10992
11052
|
className: `inline-block h-4 w-4 transform rounded-full bg-background shadow-sm transition-transform ${showCounts ? "translate-x-6" : "translate-x-1"}`,
|
|
@@ -11003,11 +11063,11 @@ function PriceSection() {
|
|
|
11003
11063
|
const { range, refine, start, canRefine } = (0, import_react_instantsearch4.useRange)({ attribute: "price" });
|
|
11004
11064
|
const rangeMin = typeof range.min === "number" && isFinite(range.min) ? range.min : 0;
|
|
11005
11065
|
const rangeMax = typeof range.max === "number" && isFinite(range.max) ? range.max : 15e3;
|
|
11006
|
-
const [localRange, setLocalRange] = (0,
|
|
11066
|
+
const [localRange, setLocalRange] = (0, import_react50.useState)([
|
|
11007
11067
|
typeof start?.[0] === "number" && isFinite(start[0]) ? start[0] : rangeMin,
|
|
11008
11068
|
typeof start?.[1] === "number" && isFinite(start[1]) ? start[1] : rangeMax
|
|
11009
11069
|
]);
|
|
11010
|
-
(0,
|
|
11070
|
+
(0, import_react50.useEffect)(() => {
|
|
11011
11071
|
if (start && Array.isArray(start)) {
|
|
11012
11072
|
setLocalRange([
|
|
11013
11073
|
typeof start[0] === "number" && isFinite(start[0]) ? start[0] : rangeMin,
|
|
@@ -11017,7 +11077,7 @@ function PriceSection() {
|
|
|
11017
11077
|
setLocalRange([rangeMin, rangeMax]);
|
|
11018
11078
|
}
|
|
11019
11079
|
}, [start, rangeMin, rangeMax]);
|
|
11020
|
-
const [isExpanded, setIsExpanded] = (0,
|
|
11080
|
+
const [isExpanded, setIsExpanded] = (0, import_react50.useState)(true);
|
|
11021
11081
|
if (!canRefine) {
|
|
11022
11082
|
return null;
|
|
11023
11083
|
}
|
|
@@ -11032,8 +11092,8 @@ function PriceSection() {
|
|
|
11032
11092
|
return `$${priceInDollars.toFixed(2)}`;
|
|
11033
11093
|
}
|
|
11034
11094
|
};
|
|
11035
|
-
return /* @__PURE__ */ (0,
|
|
11036
|
-
/* @__PURE__ */ (0,
|
|
11095
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "bg-foreground/5 rounded-lg p-4", children: [
|
|
11096
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
11037
11097
|
"button",
|
|
11038
11098
|
{
|
|
11039
11099
|
onClick: () => setIsExpanded(!isExpanded),
|
|
@@ -11041,8 +11101,8 @@ function PriceSection() {
|
|
|
11041
11101
|
"aria-expanded": isExpanded,
|
|
11042
11102
|
"aria-controls": "price-content",
|
|
11043
11103
|
children: [
|
|
11044
|
-
/* @__PURE__ */ (0,
|
|
11045
|
-
/* @__PURE__ */ (0,
|
|
11104
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("h3", { className: "text-base font-semibold text-primary", children: "Price" }),
|
|
11105
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
11046
11106
|
"svg",
|
|
11047
11107
|
{
|
|
11048
11108
|
className: `w-5 h-5 transition-transform text-foreground/40 group-hover:text-foreground/60 ${isExpanded ? "rotate-180" : ""}`,
|
|
@@ -11051,22 +11111,22 @@ function PriceSection() {
|
|
|
11051
11111
|
stroke: "currentColor",
|
|
11052
11112
|
strokeWidth: 2.5,
|
|
11053
11113
|
"aria-hidden": "true",
|
|
11054
|
-
children: /* @__PURE__ */ (0,
|
|
11114
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
|
|
11055
11115
|
}
|
|
11056
11116
|
)
|
|
11057
11117
|
]
|
|
11058
11118
|
}
|
|
11059
11119
|
),
|
|
11060
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
11061
|
-
/* @__PURE__ */ (0,
|
|
11062
|
-
/* @__PURE__ */ (0,
|
|
11063
|
-
/* @__PURE__ */ (0,
|
|
11120
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "space-y-6", id: "price-content", children: [
|
|
11121
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "flex items-center justify-between text-sm font-display", children: [
|
|
11122
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { children: formatPrice2(localRange[0]) }),
|
|
11123
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "text-foreground/70", children: formatPrice2(localRange[1]) })
|
|
11064
11124
|
] }),
|
|
11065
|
-
/* @__PURE__ */ (0,
|
|
11125
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: "relative h-24 flex items-end justify-between gap-0.5 px-1", "aria-hidden": "true", role: "presentation", children: [60, 40, 80, 50, 60, 30, 20, 15, 10, 5, 30, 20, 15, 10, 5, 3, 3, 60, 40].map((height, i) => {
|
|
11066
11126
|
const totalBars = 19;
|
|
11067
11127
|
const barPrice = rangeMin + (rangeMax - rangeMin) / totalBars * i;
|
|
11068
11128
|
const isInRange = barPrice >= localRange[0] && barPrice <= localRange[1];
|
|
11069
|
-
return /* @__PURE__ */ (0,
|
|
11129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
11070
11130
|
"div",
|
|
11071
11131
|
{
|
|
11072
11132
|
className: `flex-1 rounded-t-sm transition-opacity ${isInRange ? "bg-foreground" : "bg-foreground/20"}`,
|
|
@@ -11075,7 +11135,7 @@ function PriceSection() {
|
|
|
11075
11135
|
i
|
|
11076
11136
|
);
|
|
11077
11137
|
}) }),
|
|
11078
|
-
/* @__PURE__ */ (0,
|
|
11138
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { style: { touchAction: "none" }, className: "my-6", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
11079
11139
|
Slider2.Root,
|
|
11080
11140
|
{
|
|
11081
11141
|
className: "relative flex w-full touch-none select-none items-center",
|
|
@@ -11093,8 +11153,8 @@ function PriceSection() {
|
|
|
11093
11153
|
step: 1,
|
|
11094
11154
|
minStepsBetweenThumbs: 1,
|
|
11095
11155
|
children: [
|
|
11096
|
-
/* @__PURE__ */ (0,
|
|
11097
|
-
/* @__PURE__ */ (0,
|
|
11156
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(Slider2.Track, { className: "relative h-3 w-full grow overflow-hidden rounded-full bg-foreground/20", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(Slider2.Range, { className: "absolute h-full bg-foreground" }) }),
|
|
11157
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
11098
11158
|
Slider2.Thumb,
|
|
11099
11159
|
{
|
|
11100
11160
|
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",
|
|
@@ -11108,7 +11168,7 @@ function PriceSection() {
|
|
|
11108
11168
|
"aria-valuetext": formatPrice2(localRange[0])
|
|
11109
11169
|
}
|
|
11110
11170
|
),
|
|
11111
|
-
/* @__PURE__ */ (0,
|
|
11171
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
11112
11172
|
Slider2.Thumb,
|
|
11113
11173
|
{
|
|
11114
11174
|
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",
|
|
@@ -11125,10 +11185,10 @@ function PriceSection() {
|
|
|
11125
11185
|
]
|
|
11126
11186
|
}
|
|
11127
11187
|
) }),
|
|
11128
|
-
/* @__PURE__ */ (0,
|
|
11129
|
-
/* @__PURE__ */ (0,
|
|
11130
|
-
/* @__PURE__ */ (0,
|
|
11131
|
-
/* @__PURE__ */ (0,
|
|
11188
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
11189
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { children: [
|
|
11190
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("label", { htmlFor: "price-min", className: "text-xs font-label text-foreground/60 mb-1.5 block", children: "Min" }),
|
|
11191
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
11132
11192
|
"input",
|
|
11133
11193
|
{
|
|
11134
11194
|
id: "price-min",
|
|
@@ -11146,9 +11206,9 @@ function PriceSection() {
|
|
|
11146
11206
|
}
|
|
11147
11207
|
)
|
|
11148
11208
|
] }),
|
|
11149
|
-
/* @__PURE__ */ (0,
|
|
11150
|
-
/* @__PURE__ */ (0,
|
|
11151
|
-
/* @__PURE__ */ (0,
|
|
11209
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { children: [
|
|
11210
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("label", { htmlFor: "price-max", className: "text-xs font-label text-foreground/60 mb-1.5 block", children: "Max" }),
|
|
11211
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
11152
11212
|
"input",
|
|
11153
11213
|
{
|
|
11154
11214
|
id: "price-max",
|
|
@@ -11172,11 +11232,11 @@ function PriceSection() {
|
|
|
11172
11232
|
}
|
|
11173
11233
|
|
|
11174
11234
|
// src/composed/search/Filters.tsx
|
|
11175
|
-
var
|
|
11235
|
+
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
11176
11236
|
function Filters({ buttonClassName, buttonText }) {
|
|
11177
|
-
const [isOpen, setIsOpen] = (0,
|
|
11178
|
-
return /* @__PURE__ */ (0,
|
|
11179
|
-
/* @__PURE__ */ (0,
|
|
11237
|
+
const [isOpen, setIsOpen] = (0, import_react51.useState)(false);
|
|
11238
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
|
|
11239
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
11180
11240
|
FiltersButton,
|
|
11181
11241
|
{
|
|
11182
11242
|
onClick: () => setIsOpen(true),
|
|
@@ -11184,14 +11244,14 @@ function Filters({ buttonClassName, buttonText }) {
|
|
|
11184
11244
|
children: buttonText
|
|
11185
11245
|
}
|
|
11186
11246
|
),
|
|
11187
|
-
/* @__PURE__ */ (0,
|
|
11247
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(FiltersDrawer, { isOpen, onClose: () => setIsOpen(false) })
|
|
11188
11248
|
] });
|
|
11189
11249
|
}
|
|
11190
11250
|
|
|
11191
11251
|
// src/composed/search/CurrentRefinements.tsx
|
|
11192
11252
|
var import_react_instantsearch5 = require("react-instantsearch");
|
|
11193
11253
|
var import_lucide_react6 = require("lucide-react");
|
|
11194
|
-
var
|
|
11254
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
11195
11255
|
var XIcon3 = import_lucide_react6.X;
|
|
11196
11256
|
function CurrentRefinements() {
|
|
11197
11257
|
const { items, refine } = (0, import_react_instantsearch5.useCurrentRefinements)();
|
|
@@ -11237,15 +11297,15 @@ function CurrentRefinements() {
|
|
|
11237
11297
|
if (allRefinements.length === 0) {
|
|
11238
11298
|
return null;
|
|
11239
11299
|
}
|
|
11240
|
-
return /* @__PURE__ */ (0,
|
|
11300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "flex flex-wrap items-center gap-2 mb-4 -mt-1", role: "group", "aria-label": "Active filters", children: allRefinements.map((refinement, index) => /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
11241
11301
|
"button",
|
|
11242
11302
|
{
|
|
11243
11303
|
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",
|
|
11244
11304
|
onClick: () => refinement.refine(),
|
|
11245
11305
|
"aria-label": `Remove filter: ${refinement.displayLabel}`,
|
|
11246
11306
|
children: [
|
|
11247
|
-
/* @__PURE__ */ (0,
|
|
11248
|
-
/* @__PURE__ */ (0,
|
|
11307
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "truncate", children: refinement.displayLabel }),
|
|
11308
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(XIcon3, { className: "w-3 h-3" })
|
|
11249
11309
|
]
|
|
11250
11310
|
},
|
|
11251
11311
|
`${refinement.attribute}-${refinement.value}-${index}`
|
|
@@ -11269,12 +11329,12 @@ var FACET_SECTIONS = [
|
|
|
11269
11329
|
];
|
|
11270
11330
|
|
|
11271
11331
|
// src/composed/zoom/ResponsiveZoom.tsx
|
|
11272
|
-
var
|
|
11332
|
+
var import_react54 = require("react");
|
|
11273
11333
|
|
|
11274
11334
|
// src/composed/zoom/ZoomOverlay.tsx
|
|
11275
|
-
var
|
|
11335
|
+
var import_react52 = require("react");
|
|
11276
11336
|
var import_lucide_react7 = require("lucide-react");
|
|
11277
|
-
var
|
|
11337
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
11278
11338
|
var PlusIcon2 = import_lucide_react7.Plus;
|
|
11279
11339
|
var MinusIcon2 = import_lucide_react7.Minus;
|
|
11280
11340
|
function ZoomOverlay({
|
|
@@ -11286,13 +11346,13 @@ function ZoomOverlay({
|
|
|
11286
11346
|
className,
|
|
11287
11347
|
style
|
|
11288
11348
|
}) {
|
|
11289
|
-
const [zoomedImageIndex, setZoomedImageIndex] = (0,
|
|
11290
|
-
const [zoomOrigin, setZoomOrigin] = (0,
|
|
11291
|
-
const [hoveredImageIndex, setHoveredImageIndex] = (0,
|
|
11292
|
-
const [cursorPos, setCursorPos] = (0,
|
|
11293
|
-
const [announcement, setAnnouncement] = (0,
|
|
11294
|
-
const [isZooming, setIsZooming] = (0,
|
|
11295
|
-
const handleZoomClick = (0,
|
|
11349
|
+
const [zoomedImageIndex, setZoomedImageIndex] = (0, import_react52.useState)(null);
|
|
11350
|
+
const [zoomOrigin, setZoomOrigin] = (0, import_react52.useState)({ x: 50, y: 50 });
|
|
11351
|
+
const [hoveredImageIndex, setHoveredImageIndex] = (0, import_react52.useState)(null);
|
|
11352
|
+
const [cursorPos, setCursorPos] = (0, import_react52.useState)({ x: 0, y: 0 });
|
|
11353
|
+
const [announcement, setAnnouncement] = (0, import_react52.useState)("");
|
|
11354
|
+
const [isZooming, setIsZooming] = (0, import_react52.useState)(false);
|
|
11355
|
+
const handleZoomClick = (0, import_react52.useCallback)(
|
|
11296
11356
|
(e) => {
|
|
11297
11357
|
e.stopPropagation();
|
|
11298
11358
|
if (isLargeTouchDevice && onEnhancedViewer) {
|
|
@@ -11317,7 +11377,7 @@ function ZoomOverlay({
|
|
|
11317
11377
|
},
|
|
11318
11378
|
[zoomedImageIndex, isLargeTouchDevice, onEnhancedViewer, imageIndex]
|
|
11319
11379
|
);
|
|
11320
|
-
const handleZoomMouseMove = (0,
|
|
11380
|
+
const handleZoomMouseMove = (0, import_react52.useCallback)(
|
|
11321
11381
|
(e) => {
|
|
11322
11382
|
setCursorPos({ x: e.clientX, y: e.clientY });
|
|
11323
11383
|
if (zoomedImageIndex === imageIndex) {
|
|
@@ -11333,9 +11393,9 @@ function ZoomOverlay({
|
|
|
11333
11393
|
const isZoomed = zoomedImageIndex === imageIndex;
|
|
11334
11394
|
const isHovered = hoveredImageIndex === imageIndex;
|
|
11335
11395
|
const cursorStyle = isLargeTouchDevice ? "pointer" : isTouchDevice ? "default" : "none";
|
|
11336
|
-
return /* @__PURE__ */ (0,
|
|
11337
|
-
/* @__PURE__ */ (0,
|
|
11338
|
-
/* @__PURE__ */ (0,
|
|
11396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
|
|
11397
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement }),
|
|
11398
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11339
11399
|
"div",
|
|
11340
11400
|
{
|
|
11341
11401
|
className,
|
|
@@ -11343,7 +11403,7 @@ function ZoomOverlay({
|
|
|
11343
11403
|
...style,
|
|
11344
11404
|
position: "relative"
|
|
11345
11405
|
},
|
|
11346
|
-
children: /* @__PURE__ */ (0,
|
|
11406
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11347
11407
|
"div",
|
|
11348
11408
|
{
|
|
11349
11409
|
style: {
|
|
@@ -11366,7 +11426,7 @@ function ZoomOverlay({
|
|
|
11366
11426
|
handleZoomClick(e);
|
|
11367
11427
|
}
|
|
11368
11428
|
},
|
|
11369
|
-
children: /* @__PURE__ */ (0,
|
|
11429
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11370
11430
|
"div",
|
|
11371
11431
|
{
|
|
11372
11432
|
style: {
|
|
@@ -11382,7 +11442,7 @@ function ZoomOverlay({
|
|
|
11382
11442
|
)
|
|
11383
11443
|
}
|
|
11384
11444
|
),
|
|
11385
|
-
isHovered && !isTouchDevice && /* @__PURE__ */ (0,
|
|
11445
|
+
isHovered && !isTouchDevice && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11386
11446
|
"div",
|
|
11387
11447
|
{
|
|
11388
11448
|
className: "fixed pointer-events-none z-50 hidden md:block",
|
|
@@ -11392,7 +11452,7 @@ function ZoomOverlay({
|
|
|
11392
11452
|
transform: "translate(-50%, -50%)"
|
|
11393
11453
|
},
|
|
11394
11454
|
"aria-hidden": "true",
|
|
11395
|
-
children: /* @__PURE__ */ (0,
|
|
11455
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "bg-white dark:bg-gray-800 rounded-full p-2 shadow-sm dark:shadow-gray-950/50", children: isZoomed ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11396
11456
|
MinusIcon2,
|
|
11397
11457
|
{
|
|
11398
11458
|
size: 20,
|
|
@@ -11400,7 +11460,7 @@ function ZoomOverlay({
|
|
|
11400
11460
|
strokeWidth: 1.5,
|
|
11401
11461
|
"aria-hidden": "true"
|
|
11402
11462
|
}
|
|
11403
|
-
) : /* @__PURE__ */ (0,
|
|
11463
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11404
11464
|
PlusIcon2,
|
|
11405
11465
|
{
|
|
11406
11466
|
size: 20,
|
|
@@ -11415,11 +11475,11 @@ function ZoomOverlay({
|
|
|
11415
11475
|
}
|
|
11416
11476
|
|
|
11417
11477
|
// src/composed/zoom/EnhancedImageViewer.tsx
|
|
11418
|
-
var
|
|
11478
|
+
var import_react53 = require("react");
|
|
11419
11479
|
var import_react_dom3 = require("react-dom");
|
|
11420
11480
|
var import_react_zoom_pan_pinch = require("react-zoom-pan-pinch");
|
|
11421
11481
|
var import_lucide_react8 = require("lucide-react");
|
|
11422
|
-
var
|
|
11482
|
+
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
11423
11483
|
var TransformWrapper = import_react_zoom_pan_pinch.TransformWrapper;
|
|
11424
11484
|
var TransformComponent = import_react_zoom_pan_pinch.TransformComponent;
|
|
11425
11485
|
var EnhancedImageViewer = ({
|
|
@@ -11430,17 +11490,17 @@ var EnhancedImageViewer = ({
|
|
|
11430
11490
|
onIndexChange,
|
|
11431
11491
|
currentIndex: propCurrentIndex
|
|
11432
11492
|
}) => {
|
|
11433
|
-
const [isMounted, setIsMounted] = (0,
|
|
11434
|
-
const [isClient, setIsClient] = (0,
|
|
11435
|
-
const [scale, setScale] = (0,
|
|
11436
|
-
const [cropDimensions, setCropDimensions] = (0,
|
|
11437
|
-
const [currentZoomScale, setCurrentZoomScale] = (0,
|
|
11438
|
-
const imgRef = (0,
|
|
11439
|
-
const touchStartRef = (0,
|
|
11493
|
+
const [isMounted, setIsMounted] = (0, import_react53.useState)(false);
|
|
11494
|
+
const [isClient, setIsClient] = (0, import_react53.useState)(false);
|
|
11495
|
+
const [scale, setScale] = (0, import_react53.useState)({ initial: 1, min: 1, max: 8 });
|
|
11496
|
+
const [cropDimensions, setCropDimensions] = (0, import_react53.useState)({ width: 0, height: 0 });
|
|
11497
|
+
const [currentZoomScale, setCurrentZoomScale] = (0, import_react53.useState)(1);
|
|
11498
|
+
const imgRef = (0, import_react53.useRef)(null);
|
|
11499
|
+
const touchStartRef = (0, import_react53.useRef)(
|
|
11440
11500
|
null
|
|
11441
11501
|
);
|
|
11442
|
-
const isSwipingRef = (0,
|
|
11443
|
-
const calculateScale = (0,
|
|
11502
|
+
const isSwipingRef = (0, import_react53.useRef)(false);
|
|
11503
|
+
const calculateScale = (0, import_react53.useCallback)(() => {
|
|
11444
11504
|
const viewport = {
|
|
11445
11505
|
width: window.innerWidth,
|
|
11446
11506
|
height: window.innerHeight
|
|
@@ -11452,10 +11512,10 @@ var EnhancedImageViewer = ({
|
|
|
11452
11512
|
max: 8
|
|
11453
11513
|
});
|
|
11454
11514
|
}, []);
|
|
11455
|
-
const handleImageLoad = (0,
|
|
11515
|
+
const handleImageLoad = (0, import_react53.useCallback)(() => {
|
|
11456
11516
|
calculateScale();
|
|
11457
11517
|
}, [calculateScale]);
|
|
11458
|
-
(0,
|
|
11518
|
+
(0, import_react53.useLayoutEffect)(() => {
|
|
11459
11519
|
setIsClient(true);
|
|
11460
11520
|
setIsMounted(true);
|
|
11461
11521
|
document.body.style.overflow = "hidden";
|
|
@@ -11464,17 +11524,17 @@ var EnhancedImageViewer = ({
|
|
|
11464
11524
|
document.body.style.overflow = "";
|
|
11465
11525
|
};
|
|
11466
11526
|
}, [calculateScale]);
|
|
11467
|
-
(0,
|
|
11527
|
+
(0, import_react53.useEffect)(() => {
|
|
11468
11528
|
calculateScale();
|
|
11469
11529
|
}, [calculateScale]);
|
|
11470
|
-
(0,
|
|
11530
|
+
(0, import_react53.useEffect)(() => {
|
|
11471
11531
|
const handleResize = () => {
|
|
11472
11532
|
calculateScale();
|
|
11473
11533
|
};
|
|
11474
11534
|
window.addEventListener("resize", handleResize);
|
|
11475
11535
|
return () => window.removeEventListener("resize", handleResize);
|
|
11476
11536
|
}, [calculateScale]);
|
|
11477
|
-
(0,
|
|
11537
|
+
(0, import_react53.useEffect)(() => {
|
|
11478
11538
|
const handleKeyDown = (e) => {
|
|
11479
11539
|
if (e.key === "Escape") {
|
|
11480
11540
|
onClose();
|
|
@@ -11500,7 +11560,7 @@ var EnhancedImageViewer = ({
|
|
|
11500
11560
|
document.addEventListener("keydown", handleKeyDown);
|
|
11501
11561
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
11502
11562
|
}, [onClose, imageUrl, images, onIndexChange, propCurrentIndex]);
|
|
11503
|
-
const handleSwipeNavigation = (0,
|
|
11563
|
+
const handleSwipeNavigation = (0, import_react53.useCallback)(
|
|
11504
11564
|
(direction) => {
|
|
11505
11565
|
let currentIndex = propCurrentIndex !== void 0 ? propCurrentIndex : -1;
|
|
11506
11566
|
if (currentIndex === -1) {
|
|
@@ -11521,7 +11581,7 @@ var EnhancedImageViewer = ({
|
|
|
11521
11581
|
},
|
|
11522
11582
|
[propCurrentIndex, images, imageUrl, onIndexChange]
|
|
11523
11583
|
);
|
|
11524
|
-
const handleTouchStart = (0,
|
|
11584
|
+
const handleTouchStart = (0, import_react53.useCallback)(
|
|
11525
11585
|
(e) => {
|
|
11526
11586
|
const isAtInitialZoom = Math.abs(currentZoomScale - scale.initial) < 0.1;
|
|
11527
11587
|
if (!isAtInitialZoom) return;
|
|
@@ -11535,7 +11595,7 @@ var EnhancedImageViewer = ({
|
|
|
11535
11595
|
},
|
|
11536
11596
|
[currentZoomScale, scale.initial]
|
|
11537
11597
|
);
|
|
11538
|
-
const handleTouchEnd = (0,
|
|
11598
|
+
const handleTouchEnd = (0, import_react53.useCallback)(
|
|
11539
11599
|
(e) => {
|
|
11540
11600
|
if (!touchStartRef.current) return;
|
|
11541
11601
|
const touch = e.changedTouches[0];
|
|
@@ -11559,12 +11619,12 @@ var EnhancedImageViewer = ({
|
|
|
11559
11619
|
);
|
|
11560
11620
|
if (!isMounted || !isClient) {
|
|
11561
11621
|
return (0, import_react_dom3.createPortal)(
|
|
11562
|
-
/* @__PURE__ */ (0,
|
|
11622
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11563
11623
|
"div",
|
|
11564
11624
|
{
|
|
11565
11625
|
className: "fixed inset-0 bg-black flex items-center justify-center",
|
|
11566
11626
|
style: { zIndex: 999999 },
|
|
11567
|
-
children: /* @__PURE__ */ (0,
|
|
11627
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11568
11628
|
"div",
|
|
11569
11629
|
{
|
|
11570
11630
|
style: {
|
|
@@ -11580,7 +11640,7 @@ var EnhancedImageViewer = ({
|
|
|
11580
11640
|
);
|
|
11581
11641
|
}
|
|
11582
11642
|
return (0, import_react_dom3.createPortal)(
|
|
11583
|
-
/* @__PURE__ */ (0,
|
|
11643
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
|
|
11584
11644
|
"div",
|
|
11585
11645
|
{
|
|
11586
11646
|
className: "fixed inset-0 bg-black flex items-center justify-center",
|
|
@@ -11589,7 +11649,7 @@ var EnhancedImageViewer = ({
|
|
|
11589
11649
|
"aria-modal": "true",
|
|
11590
11650
|
"aria-label": "Image viewer",
|
|
11591
11651
|
children: [
|
|
11592
|
-
/* @__PURE__ */ (0,
|
|
11652
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11593
11653
|
"button",
|
|
11594
11654
|
{
|
|
11595
11655
|
onClick: (e) => {
|
|
@@ -11615,10 +11675,10 @@ var EnhancedImageViewer = ({
|
|
|
11615
11675
|
touchAction: "manipulation",
|
|
11616
11676
|
marginBottom: "env(safe-area-inset-bottom, 0px)"
|
|
11617
11677
|
},
|
|
11618
|
-
children: /* @__PURE__ */ (0,
|
|
11678
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react8.X, { className: "w-7 h-7", strokeWidth: 2.5 })
|
|
11619
11679
|
}
|
|
11620
11680
|
),
|
|
11621
|
-
/* @__PURE__ */ (0,
|
|
11681
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11622
11682
|
TransformWrapper,
|
|
11623
11683
|
{
|
|
11624
11684
|
initialScale: scale.initial,
|
|
@@ -11652,7 +11712,7 @@ var EnhancedImageViewer = ({
|
|
|
11652
11712
|
onTransformed: (ref) => {
|
|
11653
11713
|
setCurrentZoomScale(ref.state.scale);
|
|
11654
11714
|
},
|
|
11655
|
-
children: ({ zoomIn, zoomOut, resetTransform }) => /* @__PURE__ */ (0,
|
|
11715
|
+
children: ({ zoomIn, zoomOut, resetTransform }) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
|
|
11656
11716
|
"div",
|
|
11657
11717
|
{
|
|
11658
11718
|
style: {
|
|
@@ -11665,14 +11725,14 @@ var EnhancedImageViewer = ({
|
|
|
11665
11725
|
onTouchStart: handleTouchStart,
|
|
11666
11726
|
onTouchEnd: handleTouchEnd,
|
|
11667
11727
|
children: [
|
|
11668
|
-
/* @__PURE__ */ (0,
|
|
11728
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11669
11729
|
TransformComponent,
|
|
11670
11730
|
{
|
|
11671
11731
|
wrapperStyle: {
|
|
11672
11732
|
width: "100%",
|
|
11673
11733
|
height: "100%"
|
|
11674
11734
|
},
|
|
11675
|
-
children: /* @__PURE__ */ (0,
|
|
11735
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11676
11736
|
"div",
|
|
11677
11737
|
{
|
|
11678
11738
|
style: {
|
|
@@ -11683,8 +11743,8 @@ var EnhancedImageViewer = ({
|
|
|
11683
11743
|
alignItems: "center",
|
|
11684
11744
|
justifyContent: "center"
|
|
11685
11745
|
},
|
|
11686
|
-
children: /* @__PURE__ */ (0,
|
|
11687
|
-
|
|
11746
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11747
|
+
SafeImg,
|
|
11688
11748
|
{
|
|
11689
11749
|
ref: imgRef,
|
|
11690
11750
|
src: imageUrl,
|
|
@@ -11704,8 +11764,8 @@ var EnhancedImageViewer = ({
|
|
|
11704
11764
|
)
|
|
11705
11765
|
}
|
|
11706
11766
|
),
|
|
11707
|
-
/* @__PURE__ */ (0,
|
|
11708
|
-
/* @__PURE__ */ (0,
|
|
11767
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "fixed bottom-5 left-0 right-0 z-50", children: [
|
|
11768
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "flex justify-center gap-2", children: (() => {
|
|
11709
11769
|
let currentIndex = propCurrentIndex !== void 0 ? propCurrentIndex : -1;
|
|
11710
11770
|
if (currentIndex === -1) {
|
|
11711
11771
|
currentIndex = images.findIndex(
|
|
@@ -11738,8 +11798,8 @@ var EnhancedImageViewer = ({
|
|
|
11738
11798
|
};
|
|
11739
11799
|
const nextIndex = findNextAvailableIndex(currentIndex, 1);
|
|
11740
11800
|
const prevIndex = findNextAvailableIndex(currentIndex, -1);
|
|
11741
|
-
return /* @__PURE__ */ (0,
|
|
11742
|
-
/* @__PURE__ */ (0,
|
|
11801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_jsx_runtime71.Fragment, { children: [
|
|
11802
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11743
11803
|
"button",
|
|
11744
11804
|
{
|
|
11745
11805
|
onClick: () => {
|
|
@@ -11752,7 +11812,7 @@ var EnhancedImageViewer = ({
|
|
|
11752
11812
|
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"}`,
|
|
11753
11813
|
style: { touchAction: "manipulation" },
|
|
11754
11814
|
"aria-label": "Previous image",
|
|
11755
|
-
children: /* @__PURE__ */ (0,
|
|
11815
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11756
11816
|
"svg",
|
|
11757
11817
|
{
|
|
11758
11818
|
className: "w-4 h-4",
|
|
@@ -11760,7 +11820,7 @@ var EnhancedImageViewer = ({
|
|
|
11760
11820
|
stroke: "currentColor",
|
|
11761
11821
|
viewBox: "0 0 24 24",
|
|
11762
11822
|
"aria-hidden": "true",
|
|
11763
|
-
children: /* @__PURE__ */ (0,
|
|
11823
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11764
11824
|
"path",
|
|
11765
11825
|
{
|
|
11766
11826
|
strokeLinecap: "round",
|
|
@@ -11773,7 +11833,7 @@ var EnhancedImageViewer = ({
|
|
|
11773
11833
|
)
|
|
11774
11834
|
}
|
|
11775
11835
|
),
|
|
11776
|
-
/* @__PURE__ */ (0,
|
|
11836
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11777
11837
|
"button",
|
|
11778
11838
|
{
|
|
11779
11839
|
onClick: () => {
|
|
@@ -11786,7 +11846,7 @@ var EnhancedImageViewer = ({
|
|
|
11786
11846
|
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"}`,
|
|
11787
11847
|
style: { touchAction: "manipulation" },
|
|
11788
11848
|
"aria-label": "Next image",
|
|
11789
|
-
children: /* @__PURE__ */ (0,
|
|
11849
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11790
11850
|
"svg",
|
|
11791
11851
|
{
|
|
11792
11852
|
className: "w-4 h-4",
|
|
@@ -11794,7 +11854,7 @@ var EnhancedImageViewer = ({
|
|
|
11794
11854
|
stroke: "currentColor",
|
|
11795
11855
|
viewBox: "0 0 24 24",
|
|
11796
11856
|
"aria-hidden": "true",
|
|
11797
|
-
children: /* @__PURE__ */ (0,
|
|
11857
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11798
11858
|
"path",
|
|
11799
11859
|
{
|
|
11800
11860
|
strokeLinecap: "round",
|
|
@@ -11809,7 +11869,7 @@ var EnhancedImageViewer = ({
|
|
|
11809
11869
|
)
|
|
11810
11870
|
] });
|
|
11811
11871
|
})() }),
|
|
11812
|
-
/* @__PURE__ */ (0,
|
|
11872
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: { position: "fixed", bottom: 20, left: 24, zIndex: 10, marginBottom: "env(safe-area-inset-bottom, 0px)" }, className: "h-10 px-3 rounded-full bg-white/90 text-black text-sm font-medium flex items-center justify-center shadow-lg", children: (() => {
|
|
11813
11873
|
const total = Math.max(images.length, 1);
|
|
11814
11874
|
const current = propCurrentIndex !== void 0 ? Math.min(propCurrentIndex + 1, total) : 1;
|
|
11815
11875
|
return `${current} / ${total}`;
|
|
@@ -11821,7 +11881,7 @@ var EnhancedImageViewer = ({
|
|
|
11821
11881
|
},
|
|
11822
11882
|
`${scale.initial}-${scale.min}-${scale.max}`
|
|
11823
11883
|
),
|
|
11824
|
-
/* @__PURE__ */ (0,
|
|
11884
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11825
11885
|
"div",
|
|
11826
11886
|
{
|
|
11827
11887
|
className: "absolute inset-0 bg-black",
|
|
@@ -11840,7 +11900,7 @@ var EnhancedImageViewer = ({
|
|
|
11840
11900
|
};
|
|
11841
11901
|
|
|
11842
11902
|
// src/composed/zoom/ResponsiveZoom.tsx
|
|
11843
|
-
var
|
|
11903
|
+
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
11844
11904
|
function ResponsiveZoom({
|
|
11845
11905
|
imageIndex,
|
|
11846
11906
|
children,
|
|
@@ -11850,11 +11910,11 @@ function ResponsiveZoom({
|
|
|
11850
11910
|
imageUrl,
|
|
11851
11911
|
alt = "Product image"
|
|
11852
11912
|
}) {
|
|
11853
|
-
const [isTouchDevice, setIsTouchDevice] = (0,
|
|
11854
|
-
const [showEnhancedViewer, setShowEnhancedViewer] = (0,
|
|
11855
|
-
const [viewerIndex, setViewerIndex] = (0,
|
|
11856
|
-
const [currentImageUrl, setCurrentImageUrl] = (0,
|
|
11857
|
-
(0,
|
|
11913
|
+
const [isTouchDevice, setIsTouchDevice] = (0, import_react54.useState)(false);
|
|
11914
|
+
const [showEnhancedViewer, setShowEnhancedViewer] = (0, import_react54.useState)(false);
|
|
11915
|
+
const [viewerIndex, setViewerIndex] = (0, import_react54.useState)(0);
|
|
11916
|
+
const [currentImageUrl, setCurrentImageUrl] = (0, import_react54.useState)(imageUrl || "");
|
|
11917
|
+
(0, import_react54.useEffect)(() => {
|
|
11858
11918
|
const checkDeviceType = () => {
|
|
11859
11919
|
const hasTouch = "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
11860
11920
|
setIsTouchDevice(hasTouch);
|
|
@@ -11881,8 +11941,8 @@ function ResponsiveZoom({
|
|
|
11881
11941
|
}
|
|
11882
11942
|
}
|
|
11883
11943
|
};
|
|
11884
|
-
return /* @__PURE__ */ (0,
|
|
11885
|
-
isTouchDevice ? /* @__PURE__ */ (0,
|
|
11944
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
|
|
11945
|
+
isTouchDevice ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
11886
11946
|
"div",
|
|
11887
11947
|
{
|
|
11888
11948
|
className,
|
|
@@ -11899,7 +11959,7 @@ function ResponsiveZoom({
|
|
|
11899
11959
|
},
|
|
11900
11960
|
children
|
|
11901
11961
|
}
|
|
11902
|
-
) : /* @__PURE__ */ (0,
|
|
11962
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
11903
11963
|
ZoomOverlay,
|
|
11904
11964
|
{
|
|
11905
11965
|
imageIndex,
|
|
@@ -11910,7 +11970,7 @@ function ResponsiveZoom({
|
|
|
11910
11970
|
children
|
|
11911
11971
|
}
|
|
11912
11972
|
),
|
|
11913
|
-
showEnhancedViewer && isTouchDevice && currentImageUrl && /* @__PURE__ */ (0,
|
|
11973
|
+
showEnhancedViewer && isTouchDevice && currentImageUrl && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
11914
11974
|
EnhancedImageViewer,
|
|
11915
11975
|
{
|
|
11916
11976
|
imageUrl: currentImageUrl,
|
|
@@ -11933,9 +11993,32 @@ function ResponsiveZoom({
|
|
|
11933
11993
|
}
|
|
11934
11994
|
|
|
11935
11995
|
// src/composed/carousels/MobileProductCarousel.tsx
|
|
11936
|
-
var
|
|
11937
|
-
var
|
|
11938
|
-
|
|
11996
|
+
var import_react55 = require("react");
|
|
11997
|
+
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
11998
|
+
function StaticCarouselImage({
|
|
11999
|
+
src,
|
|
12000
|
+
alt,
|
|
12001
|
+
className
|
|
12002
|
+
}) {
|
|
12003
|
+
const [failed, setFailed] = (0, import_react55.useState)(false);
|
|
12004
|
+
if (failed || !src) {
|
|
12005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: `bg-muted ${className ?? ""}`, role: "img", "aria-label": alt });
|
|
12006
|
+
}
|
|
12007
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12008
|
+
"img",
|
|
12009
|
+
{
|
|
12010
|
+
src,
|
|
12011
|
+
alt,
|
|
12012
|
+
crossOrigin: "anonymous",
|
|
12013
|
+
className,
|
|
12014
|
+
loading: "lazy",
|
|
12015
|
+
decoding: "async",
|
|
12016
|
+
draggable: false,
|
|
12017
|
+
onError: () => setFailed(true)
|
|
12018
|
+
}
|
|
12019
|
+
);
|
|
12020
|
+
}
|
|
12021
|
+
var MobileProductCarousel = (0, import_react55.memo)(function MobileProductCarousel2({
|
|
11939
12022
|
images,
|
|
11940
12023
|
currentIndex = 0,
|
|
11941
12024
|
onIndexChange,
|
|
@@ -11950,42 +12033,42 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
11950
12033
|
mockupWidth,
|
|
11951
12034
|
onMockupUrlGenerated
|
|
11952
12035
|
}) {
|
|
11953
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
11954
|
-
const [touchStart, setTouchStart] = (0,
|
|
12036
|
+
const [activeIndex, setActiveIndex] = (0, import_react55.useState)(currentIndex);
|
|
12037
|
+
const [touchStart, setTouchStart] = (0, import_react55.useState)(
|
|
11955
12038
|
null
|
|
11956
12039
|
);
|
|
11957
|
-
const [touchEnd, setTouchEnd] = (0,
|
|
12040
|
+
const [touchEnd, setTouchEnd] = (0, import_react55.useState)(
|
|
11958
12041
|
null
|
|
11959
12042
|
);
|
|
11960
|
-
const [showImageViewer, setShowImageViewer] = (0,
|
|
11961
|
-
const [viewerKey, setViewerKey] = (0,
|
|
11962
|
-
const [isDragging, setIsDragging] = (0,
|
|
11963
|
-
const [dragOffset, setDragOffset] = (0,
|
|
11964
|
-
const [isTransitioning, setIsTransitioning] = (0,
|
|
11965
|
-
const [isHorizontalSwipe, setIsHorizontalSwipe] = (0,
|
|
12043
|
+
const [showImageViewer, setShowImageViewer] = (0, import_react55.useState)(false);
|
|
12044
|
+
const [viewerKey, setViewerKey] = (0, import_react55.useState)(0);
|
|
12045
|
+
const [isDragging, setIsDragging] = (0, import_react55.useState)(false);
|
|
12046
|
+
const [dragOffset, setDragOffset] = (0, import_react55.useState)(0);
|
|
12047
|
+
const [isTransitioning, setIsTransitioning] = (0, import_react55.useState)(false);
|
|
12048
|
+
const [isHorizontalSwipe, setIsHorizontalSwipe] = (0, import_react55.useState)(
|
|
11966
12049
|
null
|
|
11967
12050
|
);
|
|
11968
|
-
const [isPeeking, setIsPeeking] = (0,
|
|
11969
|
-
const [isPeekReturning, setIsPeekReturning] = (0,
|
|
11970
|
-
const carouselRef = (0,
|
|
11971
|
-
const indicatorRef = (0,
|
|
11972
|
-
const touchStartRef = (0,
|
|
12051
|
+
const [isPeeking, setIsPeeking] = (0, import_react55.useState)(false);
|
|
12052
|
+
const [isPeekReturning, setIsPeekReturning] = (0, import_react55.useState)(false);
|
|
12053
|
+
const carouselRef = (0, import_react55.useRef)(null);
|
|
12054
|
+
const indicatorRef = (0, import_react55.useRef)(null);
|
|
12055
|
+
const touchStartRef = (0, import_react55.useRef)(
|
|
11973
12056
|
null
|
|
11974
12057
|
);
|
|
11975
|
-
const horizontalGestureRef = (0,
|
|
11976
|
-
const hasShownPeekRef = (0,
|
|
11977
|
-
const hasSwipedThisSessionRef = (0,
|
|
11978
|
-
const generatedUrlsRef = (0,
|
|
11979
|
-
const prevArtworkSrcRef = (0,
|
|
11980
|
-
(0,
|
|
12058
|
+
const horizontalGestureRef = (0, import_react55.useRef)(false);
|
|
12059
|
+
const hasShownPeekRef = (0, import_react55.useRef)(false);
|
|
12060
|
+
const hasSwipedThisSessionRef = (0, import_react55.useRef)(false);
|
|
12061
|
+
const generatedUrlsRef = (0, import_react55.useRef)(/* @__PURE__ */ new Map());
|
|
12062
|
+
const prevArtworkSrcRef = (0, import_react55.useRef)(currentArtwork?.src);
|
|
12063
|
+
(0, import_react55.useEffect)(() => {
|
|
11981
12064
|
if (currentArtwork?.src !== prevArtworkSrcRef.current) {
|
|
11982
12065
|
generatedUrlsRef.current.clear();
|
|
11983
12066
|
prevArtworkSrcRef.current = currentArtwork?.src;
|
|
11984
12067
|
}
|
|
11985
12068
|
}, [currentArtwork?.src]);
|
|
11986
|
-
const onMockupUrlGeneratedRef = (0,
|
|
12069
|
+
const onMockupUrlGeneratedRef = (0, import_react55.useRef)(onMockupUrlGenerated);
|
|
11987
12070
|
onMockupUrlGeneratedRef.current = onMockupUrlGenerated;
|
|
11988
|
-
const handleUrlGenerated = (0,
|
|
12071
|
+
const handleUrlGenerated = (0, import_react55.useCallback)((mockupId, url) => {
|
|
11989
12072
|
generatedUrlsRef.current.set(mockupId, url);
|
|
11990
12073
|
onMockupUrlGeneratedRef.current?.(mockupId, url);
|
|
11991
12074
|
}, []);
|
|
@@ -11993,24 +12076,24 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
11993
12076
|
const shouldHideDots = stickyHeroContext?.shouldHideDots ?? false;
|
|
11994
12077
|
const priorityContext = useMockupPriorityOptional();
|
|
11995
12078
|
const realtimeContext = useRealtimeOptional();
|
|
11996
|
-
const [urlUpdateCounter, setUrlUpdateCounter] = (0,
|
|
11997
|
-
(0,
|
|
12079
|
+
const [urlUpdateCounter, setUrlUpdateCounter] = (0, import_react55.useState)(0);
|
|
12080
|
+
(0, import_react55.useEffect)(() => {
|
|
11998
12081
|
if (!realtimeContext?.subscribeMockupResults) return;
|
|
11999
12082
|
const unsubscribe = realtimeContext.subscribeMockupResults(() => {
|
|
12000
12083
|
setUrlUpdateCounter((c) => c + 1);
|
|
12001
12084
|
});
|
|
12002
12085
|
return unsubscribe;
|
|
12003
12086
|
}, [realtimeContext?.subscribeMockupResults]);
|
|
12004
|
-
const mockupIds = (0,
|
|
12087
|
+
const mockupIds = (0, import_react55.useMemo)(() => {
|
|
12005
12088
|
return images.filter((img) => img.isRealMockup && img.mockupId).map((img) => img.mockupId);
|
|
12006
12089
|
}, [images]);
|
|
12007
|
-
const realtimeMockupUrls = (0,
|
|
12090
|
+
const realtimeMockupUrls = (0, import_react55.useMemo)(() => {
|
|
12008
12091
|
if (!realtimeContext?.getMockupUrls || mockupIds.length === 0) {
|
|
12009
12092
|
return {};
|
|
12010
12093
|
}
|
|
12011
12094
|
return realtimeContext.getMockupUrls(mockupIds);
|
|
12012
12095
|
}, [realtimeContext?.getMockupUrls, mockupIds, urlUpdateCounter]);
|
|
12013
|
-
const imagesWithRealtimeUrls = (0,
|
|
12096
|
+
const imagesWithRealtimeUrls = (0, import_react55.useMemo)(() => {
|
|
12014
12097
|
return images.map((img) => {
|
|
12015
12098
|
if (img.isRealMockup && img.mockupId && realtimeMockupUrls[img.mockupId]) {
|
|
12016
12099
|
return {
|
|
@@ -12022,10 +12105,10 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12022
12105
|
});
|
|
12023
12106
|
}, [images, realtimeMockupUrls]);
|
|
12024
12107
|
const minSwipeDistance = 50;
|
|
12025
|
-
(0,
|
|
12108
|
+
(0, import_react55.useEffect)(() => {
|
|
12026
12109
|
setActiveIndex(currentIndex);
|
|
12027
12110
|
}, [currentIndex]);
|
|
12028
|
-
(0,
|
|
12111
|
+
(0, import_react55.useEffect)(() => {
|
|
12029
12112
|
if (!priorityContext) return;
|
|
12030
12113
|
const realMockups = images.map((img, idx) => ({ img, originalIdx: idx })).filter(({ img }) => img.isRealMockup && img.mockupId);
|
|
12031
12114
|
const mockupIdsList = realMockups.map(({ img }) => img.mockupId);
|
|
@@ -12053,7 +12136,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12053
12136
|
priorityContext.clearMobileCarouselMode?.();
|
|
12054
12137
|
};
|
|
12055
12138
|
}, [priorityContext, activeIndex, images]);
|
|
12056
|
-
(0,
|
|
12139
|
+
(0, import_react55.useEffect)(() => {
|
|
12057
12140
|
const indicator = indicatorRef.current;
|
|
12058
12141
|
if (!indicator) return;
|
|
12059
12142
|
let ticking = false;
|
|
@@ -12094,7 +12177,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12094
12177
|
}, []);
|
|
12095
12178
|
const SWIPE_TRACKING_KEY = "carousel-swipe-tracking";
|
|
12096
12179
|
const PDP_VIEWS_BEFORE_PEEK = 10;
|
|
12097
|
-
const getSwipeTracking = (0,
|
|
12180
|
+
const getSwipeTracking = (0, import_react55.useCallback)(() => {
|
|
12098
12181
|
try {
|
|
12099
12182
|
const stored = localStorage.getItem(SWIPE_TRACKING_KEY);
|
|
12100
12183
|
if (stored) {
|
|
@@ -12104,7 +12187,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12104
12187
|
}
|
|
12105
12188
|
return { viewsWithoutSwipe: 0, hasEverSwiped: false };
|
|
12106
12189
|
}, []);
|
|
12107
|
-
const recordSwipe = (0,
|
|
12190
|
+
const recordSwipe = (0, import_react55.useCallback)(() => {
|
|
12108
12191
|
if (hasSwipedThisSessionRef.current) return;
|
|
12109
12192
|
hasSwipedThisSessionRef.current = true;
|
|
12110
12193
|
try {
|
|
@@ -12118,7 +12201,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12118
12201
|
} catch {
|
|
12119
12202
|
}
|
|
12120
12203
|
}, []);
|
|
12121
|
-
(0,
|
|
12204
|
+
(0, import_react55.useEffect)(() => {
|
|
12122
12205
|
if (!enablePeekAnimation || images.length <= 1) return;
|
|
12123
12206
|
const tracking = getSwipeTracking();
|
|
12124
12207
|
const newViewCount = tracking.viewsWithoutSwipe + 1;
|
|
@@ -12159,14 +12242,14 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12159
12242
|
clearTimeout(clearTimeout_);
|
|
12160
12243
|
};
|
|
12161
12244
|
}, [images.length, getSwipeTracking, enablePeekAnimation]);
|
|
12162
|
-
const wasTapRef = (0,
|
|
12163
|
-
const handleImageTap = (0,
|
|
12245
|
+
const wasTapRef = (0, import_react55.useRef)(false);
|
|
12246
|
+
const handleImageTap = (0, import_react55.useCallback)(() => {
|
|
12164
12247
|
if (!enableZoom) return;
|
|
12165
12248
|
setViewerKey((prev) => prev + 1);
|
|
12166
12249
|
setShowImageViewer(true);
|
|
12167
12250
|
onZoomChange?.(true);
|
|
12168
12251
|
}, [enableZoom, onZoomChange]);
|
|
12169
|
-
const calculateDragOffset = (0,
|
|
12252
|
+
const calculateDragOffset = (0, import_react55.useCallback)(
|
|
12170
12253
|
(startX, currentX, containerWidth) => {
|
|
12171
12254
|
const distance = startX - currentX;
|
|
12172
12255
|
const offsetPercent = distance / containerWidth * 100;
|
|
@@ -12191,7 +12274,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12191
12274
|
},
|
|
12192
12275
|
[activeIndex, images.length]
|
|
12193
12276
|
);
|
|
12194
|
-
const handleSwipeEnd = (0,
|
|
12277
|
+
const handleSwipeEnd = (0, import_react55.useCallback)(
|
|
12195
12278
|
(startX, endX, containerWidth) => {
|
|
12196
12279
|
const distance = startX - endX;
|
|
12197
12280
|
const distancePercent = Math.abs(distance) / containerWidth * 100;
|
|
@@ -12222,7 +12305,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12222
12305
|
},
|
|
12223
12306
|
[activeIndex, images.length, onIndexChange, recordSwipe]
|
|
12224
12307
|
);
|
|
12225
|
-
(0,
|
|
12308
|
+
(0, import_react55.useEffect)(() => {
|
|
12226
12309
|
const container = carouselRef.current;
|
|
12227
12310
|
if (!container) return;
|
|
12228
12311
|
const handleTouchStart = (e) => {
|
|
@@ -12311,11 +12394,11 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12311
12394
|
handleSwipeEnd,
|
|
12312
12395
|
handleImageTap
|
|
12313
12396
|
]);
|
|
12314
|
-
const mouseStartRef = (0,
|
|
12397
|
+
const mouseStartRef = (0, import_react55.useRef)(
|
|
12315
12398
|
null
|
|
12316
12399
|
);
|
|
12317
|
-
const isMouseDraggingRef = (0,
|
|
12318
|
-
(0,
|
|
12400
|
+
const isMouseDraggingRef = (0, import_react55.useRef)(false);
|
|
12401
|
+
(0, import_react55.useEffect)(() => {
|
|
12319
12402
|
const container = carouselRef.current;
|
|
12320
12403
|
if (!container) return;
|
|
12321
12404
|
const handleMouseDown = (e) => {
|
|
@@ -12391,7 +12474,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12391
12474
|
container.removeEventListener("mouseleave", handleMouseLeave);
|
|
12392
12475
|
};
|
|
12393
12476
|
}, [calculateDragOffset, handleSwipeEnd, handleImageTap]);
|
|
12394
|
-
const goToSlide = (0,
|
|
12477
|
+
const goToSlide = (0, import_react55.useCallback)(
|
|
12395
12478
|
(index, withTransition = true) => {
|
|
12396
12479
|
if (withTransition) {
|
|
12397
12480
|
setIsTransitioning(true);
|
|
@@ -12409,16 +12492,16 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12409
12492
|
},
|
|
12410
12493
|
[onIndexChange]
|
|
12411
12494
|
);
|
|
12412
|
-
(0,
|
|
12495
|
+
(0, import_react55.useEffect)(() => {
|
|
12413
12496
|
if (stickyHeroContext?.setCarouselIndicator && images.length > 1) {
|
|
12414
|
-
const indicator = /* @__PURE__ */ (0,
|
|
12497
|
+
const indicator = /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12415
12498
|
"div",
|
|
12416
12499
|
{
|
|
12417
12500
|
className: "w-full",
|
|
12418
12501
|
role: "group",
|
|
12419
12502
|
"aria-label": "Product image navigation",
|
|
12420
|
-
children: /* @__PURE__ */ (0,
|
|
12421
|
-
/* @__PURE__ */ (0,
|
|
12503
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "relative h-1", children: [
|
|
12504
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "flex h-full", children: images.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12422
12505
|
"button",
|
|
12423
12506
|
{
|
|
12424
12507
|
onClick: () => goToSlide(index),
|
|
@@ -12428,7 +12511,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12428
12511
|
},
|
|
12429
12512
|
index
|
|
12430
12513
|
)) }),
|
|
12431
|
-
/* @__PURE__ */ (0,
|
|
12514
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12432
12515
|
"div",
|
|
12433
12516
|
{
|
|
12434
12517
|
className: "absolute top-0 h-full bg-primary transition-all duration-300 ease-out",
|
|
@@ -12451,10 +12534,10 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12451
12534
|
};
|
|
12452
12535
|
}, [activeIndex, images.length, goToSlide, stickyHeroContext]);
|
|
12453
12536
|
if (!images || images.length === 0) {
|
|
12454
|
-
return /* @__PURE__ */ (0,
|
|
12537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "w-full aspect-video bg-muted rounded-lg" });
|
|
12455
12538
|
}
|
|
12456
|
-
return /* @__PURE__ */ (0,
|
|
12457
|
-
/* @__PURE__ */ (0,
|
|
12539
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: `relative w-full h-full ${className}`, children: [
|
|
12540
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12458
12541
|
"div",
|
|
12459
12542
|
{
|
|
12460
12543
|
ref: carouselRef,
|
|
@@ -12472,7 +12555,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12472
12555
|
role: "region",
|
|
12473
12556
|
"aria-roledescription": "carousel",
|
|
12474
12557
|
"aria-label": "Product images",
|
|
12475
|
-
children: /* @__PURE__ */ (0,
|
|
12558
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12476
12559
|
"div",
|
|
12477
12560
|
{
|
|
12478
12561
|
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)]" : ""}`,
|
|
@@ -12482,11 +12565,15 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12482
12565
|
children: images.map((image, index) => {
|
|
12483
12566
|
const DECODE_WINDOW = 1;
|
|
12484
12567
|
const isWithinDecodeWindow = Math.abs(index - activeIndex) <= DECODE_WINDOW;
|
|
12485
|
-
return /* @__PURE__ */ (0,
|
|
12568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12486
12569
|
"div",
|
|
12487
12570
|
{
|
|
12488
12571
|
className: "w-full h-full flex-shrink-0 relative select-none",
|
|
12489
|
-
children: !isWithinDecodeWindow ? /* @__PURE__ */ (0,
|
|
12572
|
+
children: !isWithinDecodeWindow ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "w-full h-full bg-muted" }) : image.isPlaceholder ? (
|
|
12573
|
+
// Rainbow prism loader (same as the /create route) instead of
|
|
12574
|
+
// a flat pulse; fills this relative slide via inset:0.
|
|
12575
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(LoadingOverlayPrismCandyInline, { visible: true, variant: "light" })
|
|
12576
|
+
) : image.isRealMockup && currentArtwork ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12490
12577
|
HeroProductImage,
|
|
12491
12578
|
{
|
|
12492
12579
|
productId,
|
|
@@ -12498,16 +12585,12 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12498
12585
|
onUrlGenerated: image.mockupId ? (url) => handleUrlGenerated(image.mockupId, url) : void 0,
|
|
12499
12586
|
className: "w-full h-full object-cover cursor-pointer pointer-events-none"
|
|
12500
12587
|
}
|
|
12501
|
-
) : image.isRealMockup && !currentArtwork ? /* @__PURE__ */ (0,
|
|
12502
|
-
|
|
12588
|
+
) : image.isRealMockup && !currentArtwork ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(LoadingOverlayPrismCandyInline, { visible: true, variant: "light" }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12589
|
+
StaticCarouselImage,
|
|
12503
12590
|
{
|
|
12504
12591
|
src: image.src,
|
|
12505
|
-
alt: image.label,
|
|
12506
|
-
|
|
12507
|
-
className: "w-full h-full object-cover cursor-pointer pointer-events-none",
|
|
12508
|
-
loading: "lazy",
|
|
12509
|
-
decoding: "async",
|
|
12510
|
-
draggable: false
|
|
12592
|
+
alt: image.label ?? "",
|
|
12593
|
+
className: "w-full h-full object-cover cursor-pointer pointer-events-none"
|
|
12511
12594
|
}
|
|
12512
12595
|
)
|
|
12513
12596
|
},
|
|
@@ -12518,7 +12601,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12518
12601
|
)
|
|
12519
12602
|
}
|
|
12520
12603
|
),
|
|
12521
|
-
showIndicators && images.length > 1 && /* @__PURE__ */ (0,
|
|
12604
|
+
showIndicators && images.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12522
12605
|
"div",
|
|
12523
12606
|
{
|
|
12524
12607
|
ref: indicatorRef,
|
|
@@ -12526,8 +12609,8 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12526
12609
|
className: "relative z-20 w-full",
|
|
12527
12610
|
role: "group",
|
|
12528
12611
|
"aria-label": "Product image navigation",
|
|
12529
|
-
children: /* @__PURE__ */ (0,
|
|
12530
|
-
/* @__PURE__ */ (0,
|
|
12612
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "relative h-1", children: [
|
|
12613
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "flex h-full absolute inset-0", children: images.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12531
12614
|
"button",
|
|
12532
12615
|
{
|
|
12533
12616
|
onClick: () => goToSlide(index),
|
|
@@ -12537,7 +12620,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12537
12620
|
},
|
|
12538
12621
|
index
|
|
12539
12622
|
)) }),
|
|
12540
|
-
/* @__PURE__ */ (0,
|
|
12623
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12541
12624
|
"div",
|
|
12542
12625
|
{
|
|
12543
12626
|
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"}`,
|
|
@@ -12572,7 +12655,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12572
12655
|
naturalHeight: img.naturalHeight
|
|
12573
12656
|
} : null;
|
|
12574
12657
|
}).filter((img) => img !== null);
|
|
12575
|
-
return /* @__PURE__ */ (0,
|
|
12658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12576
12659
|
EnhancedImageViewer,
|
|
12577
12660
|
{
|
|
12578
12661
|
imageUrl,
|
|
@@ -12611,8 +12694,8 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12611
12694
|
});
|
|
12612
12695
|
|
|
12613
12696
|
// src/composed/carousels/HeroCarousel.tsx
|
|
12614
|
-
var
|
|
12615
|
-
var
|
|
12697
|
+
var import_react56 = require("react");
|
|
12698
|
+
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
12616
12699
|
function HeroCarousel({
|
|
12617
12700
|
images,
|
|
12618
12701
|
currentIndex = 0,
|
|
@@ -12622,16 +12705,16 @@ function HeroCarousel({
|
|
|
12622
12705
|
productId,
|
|
12623
12706
|
onImageTap
|
|
12624
12707
|
}) {
|
|
12625
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
12626
|
-
const containerRef = (0,
|
|
12627
|
-
const touchStartRef = (0,
|
|
12708
|
+
const [activeIndex, setActiveIndex] = (0, import_react56.useState)(currentIndex);
|
|
12709
|
+
const containerRef = (0, import_react56.useRef)(null);
|
|
12710
|
+
const touchStartRef = (0, import_react56.useRef)(
|
|
12628
12711
|
null
|
|
12629
12712
|
);
|
|
12630
|
-
const isSwipingRef = (0,
|
|
12631
|
-
(0,
|
|
12713
|
+
const isSwipingRef = (0, import_react56.useRef)(false);
|
|
12714
|
+
(0, import_react56.useEffect)(() => {
|
|
12632
12715
|
setActiveIndex(currentIndex);
|
|
12633
12716
|
}, [currentIndex]);
|
|
12634
|
-
const goToSlide = (0,
|
|
12717
|
+
const goToSlide = (0, import_react56.useCallback)(
|
|
12635
12718
|
(index) => {
|
|
12636
12719
|
const clampedIndex = Math.max(0, Math.min(images.length - 1, index));
|
|
12637
12720
|
setActiveIndex(clampedIndex);
|
|
@@ -12639,7 +12722,7 @@ function HeroCarousel({
|
|
|
12639
12722
|
},
|
|
12640
12723
|
[images.length, onIndexChange]
|
|
12641
12724
|
);
|
|
12642
|
-
(0,
|
|
12725
|
+
(0, import_react56.useEffect)(() => {
|
|
12643
12726
|
const container = containerRef.current;
|
|
12644
12727
|
if (!container) return;
|
|
12645
12728
|
const handleTouchStart = (e) => {
|
|
@@ -12691,9 +12774,9 @@ function HeroCarousel({
|
|
|
12691
12774
|
};
|
|
12692
12775
|
}, [activeIndex, images.length, goToSlide, onImageTap]);
|
|
12693
12776
|
if (!images || images.length === 0) {
|
|
12694
|
-
return /* @__PURE__ */ (0,
|
|
12777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "w-full h-full bg-muted" });
|
|
12695
12778
|
}
|
|
12696
|
-
return /* @__PURE__ */ (0,
|
|
12779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
|
|
12697
12780
|
"div",
|
|
12698
12781
|
{
|
|
12699
12782
|
ref: containerRef,
|
|
@@ -12704,7 +12787,7 @@ function HeroCarousel({
|
|
|
12704
12787
|
overflow: "hidden"
|
|
12705
12788
|
},
|
|
12706
12789
|
children: [
|
|
12707
|
-
/* @__PURE__ */ (0,
|
|
12790
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12708
12791
|
"div",
|
|
12709
12792
|
{
|
|
12710
12793
|
className: "flex h-full transition-transform duration-300 ease-out",
|
|
@@ -12715,14 +12798,14 @@ function HeroCarousel({
|
|
|
12715
12798
|
backfaceVisibility: "hidden",
|
|
12716
12799
|
WebkitBackfaceVisibility: "hidden"
|
|
12717
12800
|
},
|
|
12718
|
-
children: images.map((image, index) => /* @__PURE__ */ (0,
|
|
12801
|
+
children: images.map((image, index) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12719
12802
|
"div",
|
|
12720
12803
|
{
|
|
12721
12804
|
className: "w-full h-full flex-shrink-0",
|
|
12722
12805
|
style: {
|
|
12723
12806
|
contain: "layout paint"
|
|
12724
12807
|
},
|
|
12725
|
-
children: image.isRealMockup && currentArtwork ? /* @__PURE__ */ (0,
|
|
12808
|
+
children: image.isRealMockup && currentArtwork ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12726
12809
|
HeroProductImage,
|
|
12727
12810
|
{
|
|
12728
12811
|
productId,
|
|
@@ -12731,7 +12814,7 @@ function HeroCarousel({
|
|
|
12731
12814
|
mockupId: image.mockupId,
|
|
12732
12815
|
className: "w-full h-full object-cover"
|
|
12733
12816
|
}
|
|
12734
|
-
) : /* @__PURE__ */ (0,
|
|
12817
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12735
12818
|
"img",
|
|
12736
12819
|
{
|
|
12737
12820
|
src: image.src,
|
|
@@ -12748,12 +12831,12 @@ function HeroCarousel({
|
|
|
12748
12831
|
))
|
|
12749
12832
|
}
|
|
12750
12833
|
),
|
|
12751
|
-
images.length > 1 && /* @__PURE__ */ (0,
|
|
12834
|
+
images.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12752
12835
|
"div",
|
|
12753
12836
|
{
|
|
12754
12837
|
className: "absolute bottom-4 left-0 right-0 flex justify-center gap-2 z-10",
|
|
12755
12838
|
style: { contain: "layout style" },
|
|
12756
|
-
children: images.map((_, index) => /* @__PURE__ */ (0,
|
|
12839
|
+
children: images.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12757
12840
|
"button",
|
|
12758
12841
|
{
|
|
12759
12842
|
onClick: () => goToSlide(index),
|
|
@@ -12770,8 +12853,8 @@ function HeroCarousel({
|
|
|
12770
12853
|
}
|
|
12771
12854
|
|
|
12772
12855
|
// src/composed/grids/MasonryGrid.tsx
|
|
12773
|
-
var
|
|
12774
|
-
var
|
|
12856
|
+
var import_react57 = require("react");
|
|
12857
|
+
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
12775
12858
|
var BREAKPOINTS = {
|
|
12776
12859
|
sm: 640,
|
|
12777
12860
|
md: 768,
|
|
@@ -12823,13 +12906,13 @@ function MasonryGrid({
|
|
|
12823
12906
|
className = "",
|
|
12824
12907
|
emptyContent
|
|
12825
12908
|
}) {
|
|
12826
|
-
const [columnCount, setColumnCount] = (0,
|
|
12909
|
+
const [columnCount, setColumnCount] = (0, import_react57.useState)(
|
|
12827
12910
|
() => typeof columns === "number" ? columns : getColumnCount(
|
|
12828
12911
|
typeof window !== "undefined" ? window.innerWidth : 1024,
|
|
12829
12912
|
columns
|
|
12830
12913
|
)
|
|
12831
12914
|
);
|
|
12832
|
-
(0,
|
|
12915
|
+
(0, import_react57.useEffect)(() => {
|
|
12833
12916
|
const updateColumnCount = () => {
|
|
12834
12917
|
setColumnCount(getColumnCount(window.innerWidth, columns));
|
|
12835
12918
|
};
|
|
@@ -12837,30 +12920,30 @@ function MasonryGrid({
|
|
|
12837
12920
|
window.addEventListener("resize", updateColumnCount);
|
|
12838
12921
|
return () => window.removeEventListener("resize", updateColumnCount);
|
|
12839
12922
|
}, [columns]);
|
|
12840
|
-
const distributedColumns = (0,
|
|
12923
|
+
const distributedColumns = (0, import_react57.useMemo)(
|
|
12841
12924
|
() => distributeItems(items, columnCount),
|
|
12842
12925
|
[items, columnCount]
|
|
12843
12926
|
);
|
|
12844
12927
|
if (items.length === 0) {
|
|
12845
12928
|
if (emptyContent) {
|
|
12846
|
-
return /* @__PURE__ */ (0,
|
|
12929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(import_jsx_runtime75.Fragment, { children: emptyContent });
|
|
12847
12930
|
}
|
|
12848
12931
|
return null;
|
|
12849
12932
|
}
|
|
12850
|
-
return /* @__PURE__ */ (0,
|
|
12933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
12851
12934
|
"div",
|
|
12852
12935
|
{
|
|
12853
12936
|
className: `flex ${className}`,
|
|
12854
12937
|
style: { gap: `${gap}px` },
|
|
12855
12938
|
role: "list",
|
|
12856
|
-
children: distributedColumns.map((columnItems, columnIndex) => /* @__PURE__ */ (0,
|
|
12939
|
+
children: distributedColumns.map((columnItems, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
12857
12940
|
"div",
|
|
12858
12941
|
{
|
|
12859
12942
|
className: "flex-1 flex flex-col",
|
|
12860
12943
|
style: { gap: `${gap}px` },
|
|
12861
12944
|
children: columnItems.map((item, itemIndex) => {
|
|
12862
12945
|
const originalIndex = itemIndex * columnCount + columnIndex;
|
|
12863
|
-
return /* @__PURE__ */ (0,
|
|
12946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { role: "listitem", children: renderItem(item, originalIndex) }, originalIndex);
|
|
12864
12947
|
})
|
|
12865
12948
|
},
|
|
12866
12949
|
columnIndex
|
|
@@ -12873,7 +12956,7 @@ function MasonryGrid({
|
|
|
12873
12956
|
init_dev_warnings();
|
|
12874
12957
|
|
|
12875
12958
|
// src/layouts/hero-zoom/HeroZoomLayout.tsx
|
|
12876
|
-
var
|
|
12959
|
+
var import_react59 = require("react");
|
|
12877
12960
|
|
|
12878
12961
|
// src/layouts/hero-zoom/types.ts
|
|
12879
12962
|
var DEFAULT_HERO_ZOOM_CONFIG = {
|
|
@@ -12885,19 +12968,19 @@ var DEFAULT_HERO_ZOOM_CONFIG = {
|
|
|
12885
12968
|
};
|
|
12886
12969
|
|
|
12887
12970
|
// src/layouts/hero-zoom/useHeroZoomScales.ts
|
|
12888
|
-
var
|
|
12971
|
+
var import_react58 = require("react");
|
|
12889
12972
|
function useHeroZoomScales(config = {}) {
|
|
12890
12973
|
const { initialScale, accountForRetina, maxRetinaMultiplier } = {
|
|
12891
12974
|
...DEFAULT_HERO_ZOOM_CONFIG,
|
|
12892
12975
|
...config
|
|
12893
12976
|
};
|
|
12894
|
-
const [isHydrated, setIsHydrated] = (0,
|
|
12977
|
+
const [isHydrated, setIsHydrated] = (0, import_react58.useState)(false);
|
|
12895
12978
|
const ssrMultiplier = accountForRetina ? maxRetinaMultiplier : 2;
|
|
12896
|
-
const [scales, setScales] = (0,
|
|
12979
|
+
const [scales, setScales] = (0, import_react58.useState)(() => ({
|
|
12897
12980
|
visual: initialScale,
|
|
12898
12981
|
render: initialScale * ssrMultiplier
|
|
12899
12982
|
}));
|
|
12900
|
-
const calculateScales = (0,
|
|
12983
|
+
const calculateScales = (0, import_react58.useCallback)(() => {
|
|
12901
12984
|
const visualScale = Math.max(1, Math.min(4, initialScale));
|
|
12902
12985
|
let renderScale;
|
|
12903
12986
|
if (accountForRetina) {
|
|
@@ -12912,7 +12995,7 @@ function useHeroZoomScales(config = {}) {
|
|
|
12912
12995
|
renderScale = Math.max(1, Math.min(8, renderScale));
|
|
12913
12996
|
return { visual: visualScale, render: renderScale };
|
|
12914
12997
|
}, [initialScale, accountForRetina, maxRetinaMultiplier]);
|
|
12915
|
-
(0,
|
|
12998
|
+
(0, import_react58.useEffect)(() => {
|
|
12916
12999
|
const supportsScrollTimeline = CSS.supports(
|
|
12917
13000
|
"animation-timeline",
|
|
12918
13001
|
"scroll()"
|
|
@@ -12962,7 +13045,7 @@ function useHeroZoomScales(config = {}) {
|
|
|
12962
13045
|
}
|
|
12963
13046
|
|
|
12964
13047
|
// src/layouts/hero-zoom/HeroZoomLayout.tsx
|
|
12965
|
-
var
|
|
13048
|
+
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
12966
13049
|
function HeroZoomLayout({
|
|
12967
13050
|
config = {},
|
|
12968
13051
|
header,
|
|
@@ -12977,9 +13060,9 @@ function HeroZoomLayout({
|
|
|
12977
13060
|
};
|
|
12978
13061
|
const { aspectRatio, initialScale, headerHeight } = mergedConfig;
|
|
12979
13062
|
const { visual, render, isHydrated } = useHeroZoomScales(mergedConfig);
|
|
12980
|
-
const imageContainerRef = (0,
|
|
12981
|
-
const headerRef = (0,
|
|
12982
|
-
(0,
|
|
13063
|
+
const imageContainerRef = (0, import_react59.useRef)(null);
|
|
13064
|
+
const headerRef = (0, import_react59.useRef)(null);
|
|
13065
|
+
(0, import_react59.useEffect)(() => {
|
|
12983
13066
|
if (typeof window === "undefined") return;
|
|
12984
13067
|
const originalRestoration = "scrollRestoration" in history ? history.scrollRestoration : "auto";
|
|
12985
13068
|
if ("scrollRestoration" in history) {
|
|
@@ -12992,7 +13075,7 @@ function HeroZoomLayout({
|
|
|
12992
13075
|
}
|
|
12993
13076
|
};
|
|
12994
13077
|
}, []);
|
|
12995
|
-
(0,
|
|
13078
|
+
(0, import_react59.useEffect)(() => {
|
|
12996
13079
|
const supportsScrollTimeline = CSS.supports(
|
|
12997
13080
|
"animation-timeline",
|
|
12998
13081
|
"scroll()"
|
|
@@ -13121,7 +13204,7 @@ function HeroZoomLayout({
|
|
|
13121
13204
|
The drawer covers the hero completely, so let animation run continuously. */
|
|
13122
13205
|
}
|
|
13123
13206
|
`;
|
|
13124
|
-
return /* @__PURE__ */ (0,
|
|
13207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
13125
13208
|
"div",
|
|
13126
13209
|
{
|
|
13127
13210
|
className: `relative min-h-screen ${className}`,
|
|
@@ -13135,8 +13218,8 @@ function HeroZoomLayout({
|
|
|
13135
13218
|
"--hero-zoom-final-transform": 1 / activeRender
|
|
13136
13219
|
},
|
|
13137
13220
|
children: [
|
|
13138
|
-
/* @__PURE__ */ (0,
|
|
13139
|
-
/* @__PURE__ */ (0,
|
|
13221
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("style", { dangerouslySetInnerHTML: { __html: scopedStyles } }),
|
|
13222
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
13140
13223
|
"div",
|
|
13141
13224
|
{
|
|
13142
13225
|
style: {
|
|
@@ -13144,7 +13227,7 @@ function HeroZoomLayout({
|
|
|
13144
13227
|
}
|
|
13145
13228
|
}
|
|
13146
13229
|
),
|
|
13147
|
-
header && /* @__PURE__ */ (0,
|
|
13230
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
13148
13231
|
"div",
|
|
13149
13232
|
{
|
|
13150
13233
|
ref: headerRef,
|
|
@@ -13157,7 +13240,7 @@ function HeroZoomLayout({
|
|
|
13157
13240
|
children: header
|
|
13158
13241
|
}
|
|
13159
13242
|
),
|
|
13160
|
-
/* @__PURE__ */ (0,
|
|
13243
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
13161
13244
|
"div",
|
|
13162
13245
|
{
|
|
13163
13246
|
ref: imageContainerRef,
|
|
@@ -13177,15 +13260,15 @@ function HeroZoomLayout({
|
|
|
13177
13260
|
children: hero
|
|
13178
13261
|
}
|
|
13179
13262
|
),
|
|
13180
|
-
/* @__PURE__ */ (0,
|
|
13263
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "relative z-10", children })
|
|
13181
13264
|
]
|
|
13182
13265
|
}
|
|
13183
13266
|
);
|
|
13184
13267
|
}
|
|
13185
13268
|
|
|
13186
13269
|
// src/layouts/hero-zoom/HeroShrinkLayout.tsx
|
|
13187
|
-
var
|
|
13188
|
-
var
|
|
13270
|
+
var import_react60 = require("react");
|
|
13271
|
+
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
13189
13272
|
var DEFAULT_CONFIG = {
|
|
13190
13273
|
aspectRatio: 16 / 9,
|
|
13191
13274
|
initialHeightPercent: 70,
|
|
@@ -13205,13 +13288,13 @@ function HeroShrinkLayout({
|
|
|
13205
13288
|
...config
|
|
13206
13289
|
};
|
|
13207
13290
|
const { aspectRatio, initialHeightPercent, minHeightPercent, headerHeight } = mergedConfig;
|
|
13208
|
-
const heroRef = (0,
|
|
13209
|
-
const headerRef = (0,
|
|
13210
|
-
const [isClient, setIsClient] = (0,
|
|
13211
|
-
(0,
|
|
13291
|
+
const heroRef = (0, import_react60.useRef)(null);
|
|
13292
|
+
const headerRef = (0, import_react60.useRef)(null);
|
|
13293
|
+
const [isClient, setIsClient] = (0, import_react60.useState)(false);
|
|
13294
|
+
(0, import_react60.useEffect)(() => {
|
|
13212
13295
|
setIsClient(true);
|
|
13213
13296
|
}, []);
|
|
13214
|
-
(0,
|
|
13297
|
+
(0, import_react60.useEffect)(() => {
|
|
13215
13298
|
if (!isClient) return;
|
|
13216
13299
|
const supportsScrollTimeline = CSS.supports("animation-timeline", "scroll()");
|
|
13217
13300
|
if (supportsScrollTimeline) return;
|
|
@@ -13298,15 +13381,15 @@ function HeroShrinkLayout({
|
|
|
13298
13381
|
}
|
|
13299
13382
|
`;
|
|
13300
13383
|
const spacerHeight = `calc(${initialHeightPercent}svh + ${headerHeight}px)`;
|
|
13301
|
-
return /* @__PURE__ */ (0,
|
|
13384
|
+
return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
|
|
13302
13385
|
"div",
|
|
13303
13386
|
{
|
|
13304
13387
|
className: `relative min-h-screen ${className}`,
|
|
13305
13388
|
style: { ...style, ...cssVars },
|
|
13306
13389
|
children: [
|
|
13307
|
-
/* @__PURE__ */ (0,
|
|
13308
|
-
/* @__PURE__ */ (0,
|
|
13309
|
-
header && /* @__PURE__ */ (0,
|
|
13390
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)("style", { dangerouslySetInnerHTML: { __html: scopedStyles } }),
|
|
13391
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { style: { height: spacerHeight } }),
|
|
13392
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
13310
13393
|
"div",
|
|
13311
13394
|
{
|
|
13312
13395
|
ref: headerRef,
|
|
@@ -13315,7 +13398,7 @@ function HeroShrinkLayout({
|
|
|
13315
13398
|
children: header
|
|
13316
13399
|
}
|
|
13317
13400
|
),
|
|
13318
|
-
/* @__PURE__ */ (0,
|
|
13401
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
13319
13402
|
"div",
|
|
13320
13403
|
{
|
|
13321
13404
|
ref: heroRef,
|
|
@@ -13323,15 +13406,15 @@ function HeroShrinkLayout({
|
|
|
13323
13406
|
children: hero
|
|
13324
13407
|
}
|
|
13325
13408
|
),
|
|
13326
|
-
/* @__PURE__ */ (0,
|
|
13409
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "relative z-10 bg-background", children })
|
|
13327
13410
|
]
|
|
13328
13411
|
}
|
|
13329
13412
|
);
|
|
13330
13413
|
}
|
|
13331
13414
|
|
|
13332
13415
|
// src/layouts/pdp/ImageEdgeBlur.tsx
|
|
13333
|
-
var
|
|
13334
|
-
var
|
|
13416
|
+
var import_react61 = __toESM(require("react"), 1);
|
|
13417
|
+
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
13335
13418
|
var BLUR_CONFIG = {
|
|
13336
13419
|
blur: 24,
|
|
13337
13420
|
crossfade: 68
|
|
@@ -13355,7 +13438,7 @@ var BLUR_LAYERS = [
|
|
|
13355
13438
|
{ blur: Math.round(BLUR_CONFIG.blur * 0.5), zone: 0.6 },
|
|
13356
13439
|
{ blur: BLUR_CONFIG.blur, zone: 1 }
|
|
13357
13440
|
];
|
|
13358
|
-
var ImageEdgeBlur =
|
|
13441
|
+
var ImageEdgeBlur = import_react61.default.memo(
|
|
13359
13442
|
function ImageEdgeBlur2({
|
|
13360
13443
|
imageSrc,
|
|
13361
13444
|
imageCapInfo,
|
|
@@ -13386,7 +13469,7 @@ var ImageEdgeBlur = import_react60.default.memo(
|
|
|
13386
13469
|
viewportWidth / LAYOUT_CONFIG2.IMAGE.ASPECT_RATIO,
|
|
13387
13470
|
maxWidthPx / LAYOUT_CONFIG2.IMAGE.ASPECT_RATIO
|
|
13388
13471
|
);
|
|
13389
|
-
return /* @__PURE__ */ (0,
|
|
13472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
13390
13473
|
"div",
|
|
13391
13474
|
{
|
|
13392
13475
|
className: `absolute inset-0 pointer-events-none overflow-hidden ${className}`,
|
|
@@ -13394,7 +13477,7 @@ var ImageEdgeBlur = import_react60.default.memo(
|
|
|
13394
13477
|
children: BLUR_LAYERS.map((layer, index) => {
|
|
13395
13478
|
const layerMask = index === BLUR_LAYERS.length - 1 ? void 0 : `linear-gradient(to right, black 0%, black ${layer.zone * 100}%, transparent ${layer.zone * 100 + 10}%)`;
|
|
13396
13479
|
const blurScale = 1 + layer.blur * 3 / containerHeightPx;
|
|
13397
|
-
return /* @__PURE__ */ (0,
|
|
13480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
13398
13481
|
"img",
|
|
13399
13482
|
{
|
|
13400
13483
|
src: imageSrc,
|
|
@@ -13441,7 +13524,7 @@ var ImageEdgeBlur = import_react60.default.memo(
|
|
|
13441
13524
|
);
|
|
13442
13525
|
|
|
13443
13526
|
// src/layouts/pdp/PDPLayout.tsx
|
|
13444
|
-
var
|
|
13527
|
+
var import_jsx_runtime79 = require("react/jsx-runtime");
|
|
13445
13528
|
function PDPLayout({
|
|
13446
13529
|
renderHeroImage,
|
|
13447
13530
|
renderContent,
|
|
@@ -13469,15 +13552,15 @@ function PDPLayout({
|
|
|
13469
13552
|
isDesktop,
|
|
13470
13553
|
isWideMonitor: isWideMonitor2
|
|
13471
13554
|
};
|
|
13472
|
-
return /* @__PURE__ */ (0,
|
|
13473
|
-
(isDesktop === false || isDesktop === null) && /* @__PURE__ */ (0,
|
|
13474
|
-
renderMobileCarousel && /* @__PURE__ */ (0,
|
|
13475
|
-
/* @__PURE__ */ (0,
|
|
13555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: `pdp-layout ${className}`, children: [
|
|
13556
|
+
(isDesktop === false || isDesktop === null) && /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "md:hidden", children: [
|
|
13557
|
+
renderMobileCarousel && /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "mobile-carousel-container", children: renderMobileCarousel({ images: carouselImages }) }),
|
|
13558
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "mobile-content p-4", children: renderContent(contentProps) })
|
|
13476
13559
|
] }),
|
|
13477
|
-
(isDesktop === true || isDesktop === null) && /* @__PURE__ */ (0,
|
|
13478
|
-
/* @__PURE__ */ (0,
|
|
13560
|
+
(isDesktop === true || isDesktop === null) && /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "hidden md:block relative", children: [
|
|
13561
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "desktop-hero relative", children: [
|
|
13479
13562
|
renderHeroImage(heroProps),
|
|
13480
|
-
showEdgeBlur && blurImageSrc && isWideMonitor2 && /* @__PURE__ */ (0,
|
|
13563
|
+
showEdgeBlur && blurImageSrc && isWideMonitor2 && /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
13481
13564
|
ImageEdgeBlur,
|
|
13482
13565
|
{
|
|
13483
13566
|
imageSrc: blurImageSrc,
|
|
@@ -13488,7 +13571,7 @@ function PDPLayout({
|
|
|
13488
13571
|
}
|
|
13489
13572
|
)
|
|
13490
13573
|
] }),
|
|
13491
|
-
/* @__PURE__ */ (0,
|
|
13574
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
13492
13575
|
"div",
|
|
13493
13576
|
{
|
|
13494
13577
|
className: "desktop-sidebar",
|
|
@@ -13505,8 +13588,8 @@ function PDPLayout({
|
|
|
13505
13588
|
}
|
|
13506
13589
|
|
|
13507
13590
|
// src/layouts/pdp/SimpleImageBlur.tsx
|
|
13508
|
-
var
|
|
13509
|
-
var
|
|
13591
|
+
var import_react62 = __toESM(require("react"), 1);
|
|
13592
|
+
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
13510
13593
|
var BLUR_CONFIG2 = {
|
|
13511
13594
|
blur: 24,
|
|
13512
13595
|
crossfade: 60
|
|
@@ -13529,7 +13612,7 @@ function getFadeInMask(crossfadeWidth) {
|
|
|
13529
13612
|
black ${crossfadeWidth + 10}px
|
|
13530
13613
|
)`;
|
|
13531
13614
|
}
|
|
13532
|
-
var SimpleImageBlur =
|
|
13615
|
+
var SimpleImageBlur = import_react62.default.memo(function SimpleImageBlur2({
|
|
13533
13616
|
imageSrc,
|
|
13534
13617
|
width,
|
|
13535
13618
|
height = "100%",
|
|
@@ -13539,7 +13622,7 @@ var SimpleImageBlur = import_react61.default.memo(function SimpleImageBlur2({
|
|
|
13539
13622
|
if (!imageSrc || width <= 0) return null;
|
|
13540
13623
|
const fadeInMask = getFadeInMask(BLUR_CONFIG2.crossfade);
|
|
13541
13624
|
const extendedWidth = width + BLUR_CONFIG2.blur * 2;
|
|
13542
|
-
return /* @__PURE__ */ (0,
|
|
13625
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
13543
13626
|
"div",
|
|
13544
13627
|
{
|
|
13545
13628
|
className: `relative overflow-hidden ${className}`,
|
|
@@ -13552,7 +13635,7 @@ var SimpleImageBlur = import_react61.default.memo(function SimpleImageBlur2({
|
|
|
13552
13635
|
black 0%,
|
|
13553
13636
|
black ${layer.zone * 100}%,
|
|
13554
13637
|
transparent ${layer.zone * 100 + 10}%)`;
|
|
13555
|
-
return /* @__PURE__ */ (0,
|
|
13638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
13556
13639
|
"img",
|
|
13557
13640
|
{
|
|
13558
13641
|
src: imageSrc,
|
|
@@ -13582,8 +13665,8 @@ var SimpleImageBlur = import_react61.default.memo(function SimpleImageBlur2({
|
|
|
13582
13665
|
});
|
|
13583
13666
|
|
|
13584
13667
|
// src/layouts/pdp/EdgeBlurBox.tsx
|
|
13585
|
-
var
|
|
13586
|
-
var
|
|
13668
|
+
var import_react63 = __toESM(require("react"), 1);
|
|
13669
|
+
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
13587
13670
|
var BLUR_CONFIG3 = {
|
|
13588
13671
|
blur: 24,
|
|
13589
13672
|
crossfade: 60
|
|
@@ -13607,7 +13690,7 @@ function getFadeOutMask(crossfadeWidth) {
|
|
|
13607
13690
|
transparent 100%
|
|
13608
13691
|
)`;
|
|
13609
13692
|
}
|
|
13610
|
-
var EdgeBlurBox =
|
|
13693
|
+
var EdgeBlurBox = import_react63.default.memo(function EdgeBlurBox2({
|
|
13611
13694
|
imageSrc,
|
|
13612
13695
|
width,
|
|
13613
13696
|
height = "100%",
|
|
@@ -13622,7 +13705,7 @@ var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
|
13622
13705
|
const blurExtend = BLUR_CONFIG3.blur * 2;
|
|
13623
13706
|
const actualSharpWidth = sharpImageWidth ?? width + overlapLeft;
|
|
13624
13707
|
const hasOverlap = overlapLeft > 0;
|
|
13625
|
-
return /* @__PURE__ */ (0,
|
|
13708
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
|
|
13626
13709
|
"div",
|
|
13627
13710
|
{
|
|
13628
13711
|
className: `relative ${className}`,
|
|
@@ -13633,7 +13716,7 @@ var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
|
13633
13716
|
overflow: hasOverlap ? "visible" : "hidden"
|
|
13634
13717
|
},
|
|
13635
13718
|
children: [
|
|
13636
|
-
/* @__PURE__ */ (0,
|
|
13719
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
13637
13720
|
"div",
|
|
13638
13721
|
{
|
|
13639
13722
|
style: {
|
|
@@ -13647,7 +13730,7 @@ var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
|
13647
13730
|
transparent ${100 - (layer.zone * 100 + 10)}%,
|
|
13648
13731
|
black ${100 - layer.zone * 100}%,
|
|
13649
13732
|
black 100%)`;
|
|
13650
|
-
return /* @__PURE__ */ (0,
|
|
13733
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
13651
13734
|
"img",
|
|
13652
13735
|
{
|
|
13653
13736
|
src: imageSrc,
|
|
@@ -13675,7 +13758,7 @@ var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
|
13675
13758
|
})
|
|
13676
13759
|
}
|
|
13677
13760
|
),
|
|
13678
|
-
/* @__PURE__ */ (0,
|
|
13761
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
13679
13762
|
"img",
|
|
13680
13763
|
{
|
|
13681
13764
|
src: imageSrc,
|
|
@@ -13703,8 +13786,8 @@ var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
|
13703
13786
|
});
|
|
13704
13787
|
|
|
13705
13788
|
// src/layouts/pdp/ImageBlurExtension.tsx
|
|
13706
|
-
var
|
|
13707
|
-
var
|
|
13789
|
+
var import_react64 = __toESM(require("react"), 1);
|
|
13790
|
+
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
13708
13791
|
var BLUR_CONFIG4 = {
|
|
13709
13792
|
blur: 24,
|
|
13710
13793
|
crossfadeWidth: 80
|
|
@@ -13727,7 +13810,7 @@ function getFadeOutMask2(crossfadeWidth) {
|
|
|
13727
13810
|
transparent 100%
|
|
13728
13811
|
)`;
|
|
13729
13812
|
}
|
|
13730
|
-
var ImageBlurExtension =
|
|
13813
|
+
var ImageBlurExtension = import_react64.default.memo(function ImageBlurExtension2({
|
|
13731
13814
|
imageSrc,
|
|
13732
13815
|
width,
|
|
13733
13816
|
height,
|
|
@@ -13741,7 +13824,7 @@ var ImageBlurExtension = import_react63.default.memo(function ImageBlurExtension
|
|
|
13741
13824
|
const internalImageLeft = `calc(${heroImageLeft} - 100vw + ${width}px)`;
|
|
13742
13825
|
const fadeOutMask = getFadeOutMask2(crossfadeWidth);
|
|
13743
13826
|
const heightValue = typeof height === "number" ? `${height}px` : height;
|
|
13744
|
-
return /* @__PURE__ */ (0,
|
|
13827
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(
|
|
13745
13828
|
"div",
|
|
13746
13829
|
{
|
|
13747
13830
|
className: `relative overflow-hidden ${className}`,
|
|
@@ -13750,7 +13833,7 @@ var ImageBlurExtension = import_react63.default.memo(function ImageBlurExtension
|
|
|
13750
13833
|
height: heightValue
|
|
13751
13834
|
},
|
|
13752
13835
|
children: [
|
|
13753
|
-
BLUR_LAYERS4.map((layer, index) => /* @__PURE__ */ (0,
|
|
13836
|
+
BLUR_LAYERS4.map((layer, index) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
13754
13837
|
"img",
|
|
13755
13838
|
{
|
|
13756
13839
|
src: imageSrc,
|
|
@@ -13774,7 +13857,7 @@ var ImageBlurExtension = import_react63.default.memo(function ImageBlurExtension
|
|
|
13774
13857
|
},
|
|
13775
13858
|
`blur-${index}`
|
|
13776
13859
|
)),
|
|
13777
|
-
/* @__PURE__ */ (0,
|
|
13860
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
13778
13861
|
"img",
|
|
13779
13862
|
{
|
|
13780
13863
|
src: imageSrc,
|
|
@@ -13802,39 +13885,39 @@ var ImageBlurExtension = import_react63.default.memo(function ImageBlurExtension
|
|
|
13802
13885
|
});
|
|
13803
13886
|
|
|
13804
13887
|
// src/design-system/ColorSwatch.tsx
|
|
13805
|
-
var
|
|
13888
|
+
var import_jsx_runtime83 = require("react/jsx-runtime");
|
|
13806
13889
|
function ColorTokenSwatch({ name, cssVar, className = "" }) {
|
|
13807
|
-
return /* @__PURE__ */ (0,
|
|
13808
|
-
/* @__PURE__ */ (0,
|
|
13890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: `flex flex-col gap-1 ${className}`, children: [
|
|
13891
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
13809
13892
|
"div",
|
|
13810
13893
|
{
|
|
13811
13894
|
className: "h-16 w-full rounded-lg border border-border shadow-sm",
|
|
13812
13895
|
style: { backgroundColor: `var(${cssVar})` }
|
|
13813
13896
|
}
|
|
13814
13897
|
),
|
|
13815
|
-
/* @__PURE__ */ (0,
|
|
13816
|
-
/* @__PURE__ */ (0,
|
|
13898
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "text-sm font-medium text-foreground", children: name }),
|
|
13899
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("code", { className: "text-xs text-muted-foreground font-mono", children: cssVar })
|
|
13817
13900
|
] });
|
|
13818
13901
|
}
|
|
13819
13902
|
function ColorRow({ name, cssVar, description }) {
|
|
13820
|
-
return /* @__PURE__ */ (0,
|
|
13821
|
-
/* @__PURE__ */ (0,
|
|
13903
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex items-center gap-4 py-2", children: [
|
|
13904
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
13822
13905
|
"div",
|
|
13823
13906
|
{
|
|
13824
13907
|
className: "h-10 w-10 rounded-lg border border-border shadow-sm flex-shrink-0",
|
|
13825
13908
|
style: { backgroundColor: `var(${cssVar})` }
|
|
13826
13909
|
}
|
|
13827
13910
|
),
|
|
13828
|
-
/* @__PURE__ */ (0,
|
|
13829
|
-
/* @__PURE__ */ (0,
|
|
13830
|
-
description && /* @__PURE__ */ (0,
|
|
13911
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
13912
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "text-sm font-medium text-foreground", children: name }),
|
|
13913
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "text-xs text-muted-foreground", children: description })
|
|
13831
13914
|
] }),
|
|
13832
|
-
/* @__PURE__ */ (0,
|
|
13915
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("code", { className: "text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded", children: cssVar })
|
|
13833
13916
|
] });
|
|
13834
13917
|
}
|
|
13835
13918
|
|
|
13836
13919
|
// src/design-system/ColorPalette.tsx
|
|
13837
|
-
var
|
|
13920
|
+
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
13838
13921
|
var COLOR_GROUPS = [
|
|
13839
13922
|
{
|
|
13840
13923
|
name: "Base",
|
|
@@ -13915,17 +13998,17 @@ var COLOR_GROUPS = [
|
|
|
13915
13998
|
}
|
|
13916
13999
|
];
|
|
13917
14000
|
function ColorPalette({ layout = "list", className = "" }) {
|
|
13918
|
-
return /* @__PURE__ */ (0,
|
|
13919
|
-
/* @__PURE__ */ (0,
|
|
13920
|
-
/* @__PURE__ */ (0,
|
|
13921
|
-
layout === "grid" ? /* @__PURE__ */ (0,
|
|
14001
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: `space-y-8 ${className}`, children: COLOR_GROUPS.map((group) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("section", { children: [
|
|
14002
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("h3", { className: "text-lg font-semibold text-foreground mb-1", children: group.name }),
|
|
14003
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { className: "text-sm text-muted-foreground mb-4", children: group.description }),
|
|
14004
|
+
layout === "grid" ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-4", children: group.colors.map((color) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
13922
14005
|
ColorTokenSwatch,
|
|
13923
14006
|
{
|
|
13924
14007
|
name: color.name,
|
|
13925
14008
|
cssVar: color.cssVar
|
|
13926
14009
|
},
|
|
13927
14010
|
color.cssVar
|
|
13928
|
-
)) }) : /* @__PURE__ */ (0,
|
|
14011
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "bg-card rounded-lg border border-border p-4 divide-y divide-border", children: group.colors.map((color) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
13929
14012
|
ColorRow,
|
|
13930
14013
|
{
|
|
13931
14014
|
name: color.name,
|
|
@@ -13938,7 +14021,7 @@ function ColorPalette({ layout = "list", className = "" }) {
|
|
|
13938
14021
|
}
|
|
13939
14022
|
|
|
13940
14023
|
// src/design-system/TypographyScale.tsx
|
|
13941
|
-
var
|
|
14024
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
13942
14025
|
var FONT_SAMPLES = [
|
|
13943
14026
|
{
|
|
13944
14027
|
name: "Heading",
|
|
@@ -13972,14 +14055,14 @@ var FONT_SAMPLES = [
|
|
|
13972
14055
|
}
|
|
13973
14056
|
];
|
|
13974
14057
|
function TypographyScale({ className = "" }) {
|
|
13975
|
-
return /* @__PURE__ */ (0,
|
|
13976
|
-
/* @__PURE__ */ (0,
|
|
13977
|
-
/* @__PURE__ */ (0,
|
|
13978
|
-
/* @__PURE__ */ (0,
|
|
14058
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: `space-y-8 ${className}`, children: FONT_SAMPLES.map((font) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("section", { className: "bg-card rounded-lg border border-border p-6", children: [
|
|
14059
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
14060
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("h3", { className: "text-lg font-semibold text-foreground", children: font.name }),
|
|
14061
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("code", { className: "text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded", children: font.cssVar })
|
|
13979
14062
|
] }),
|
|
13980
|
-
/* @__PURE__ */ (0,
|
|
13981
|
-
/* @__PURE__ */ (0,
|
|
13982
|
-
/* @__PURE__ */ (0,
|
|
14063
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "space-y-4", children: font.sizes.map((size) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "flex items-baseline gap-4", children: [
|
|
14064
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "text-xs text-muted-foreground w-20 flex-shrink-0", children: size }),
|
|
14065
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
13983
14066
|
"p",
|
|
13984
14067
|
{
|
|
13985
14068
|
className: `${size} text-foreground`,
|
|
@@ -13998,8 +14081,8 @@ var RADIUS_SAMPLES = [
|
|
|
13998
14081
|
{ name: "Full", value: "9999px" }
|
|
13999
14082
|
];
|
|
14000
14083
|
function RadiusScale({ className = "" }) {
|
|
14001
|
-
return /* @__PURE__ */ (0,
|
|
14002
|
-
/* @__PURE__ */ (0,
|
|
14084
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: `space-y-4 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "grid grid-cols-5 gap-4", children: RADIUS_SAMPLES.map((radius) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "flex flex-col items-center gap-2", children: [
|
|
14085
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
14003
14086
|
"div",
|
|
14004
14087
|
{
|
|
14005
14088
|
className: "h-16 w-16 bg-primary",
|
|
@@ -14008,13 +14091,13 @@ function RadiusScale({ className = "" }) {
|
|
|
14008
14091
|
}
|
|
14009
14092
|
}
|
|
14010
14093
|
),
|
|
14011
|
-
/* @__PURE__ */ (0,
|
|
14012
|
-
/* @__PURE__ */ (0,
|
|
14094
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "text-sm font-medium text-foreground", children: radius.name }),
|
|
14095
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("code", { className: "text-xs text-muted-foreground font-mono", children: radius.cssVar || radius.value })
|
|
14013
14096
|
] }, radius.name)) }) });
|
|
14014
14097
|
}
|
|
14015
14098
|
|
|
14016
14099
|
// src/design-system/ThemeSwitcher.tsx
|
|
14017
|
-
var
|
|
14100
|
+
var import_react65 = require("react");
|
|
14018
14101
|
|
|
14019
14102
|
// src/themes/types.ts
|
|
14020
14103
|
var RADIUS_PRESETS = {
|
|
@@ -15182,7 +15265,7 @@ function applyTheme(config) {
|
|
|
15182
15265
|
}
|
|
15183
15266
|
|
|
15184
15267
|
// src/design-system/ThemeSwitcher.tsx
|
|
15185
|
-
var
|
|
15268
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
15186
15269
|
function readThemeFromDOM() {
|
|
15187
15270
|
if (typeof document === "undefined") {
|
|
15188
15271
|
return { themeName: "Linear", isDark: false };
|
|
@@ -15200,10 +15283,10 @@ function readThemeFromDOM() {
|
|
|
15200
15283
|
return { themeName: "Linear", isDark: dark };
|
|
15201
15284
|
}
|
|
15202
15285
|
function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
15203
|
-
const [currentTheme, setCurrentTheme] = (0,
|
|
15204
|
-
const [isDark, setIsDark] = (0,
|
|
15205
|
-
const [isOpen, setIsOpen] = (0,
|
|
15206
|
-
(0,
|
|
15286
|
+
const [currentTheme, setCurrentTheme] = (0, import_react65.useState)("Linear");
|
|
15287
|
+
const [isDark, setIsDark] = (0, import_react65.useState)(false);
|
|
15288
|
+
const [isOpen, setIsOpen] = (0, import_react65.useState)(false);
|
|
15289
|
+
(0, import_react65.useEffect)(() => {
|
|
15207
15290
|
const { themeName, isDark: dark } = readThemeFromDOM();
|
|
15208
15291
|
setCurrentTheme(themeName);
|
|
15209
15292
|
setIsDark(dark);
|
|
@@ -15242,61 +15325,61 @@ function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
|
15242
15325
|
applyTheme(config);
|
|
15243
15326
|
};
|
|
15244
15327
|
const themes = showBaseThemesOnly ? baseThemes : baseThemes;
|
|
15245
|
-
return /* @__PURE__ */ (0,
|
|
15246
|
-
/* @__PURE__ */ (0,
|
|
15247
|
-
/* @__PURE__ */ (0,
|
|
15328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: `flex items-center gap-3 ${className}`, children: [
|
|
15329
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "relative", children: [
|
|
15330
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
|
|
15248
15331
|
"button",
|
|
15249
15332
|
{
|
|
15250
15333
|
onClick: () => setIsOpen(!isOpen),
|
|
15251
15334
|
className: "flex items-center gap-2 px-4 py-2 bg-card border border-border rounded-lg hover:bg-muted transition-colors text-foreground",
|
|
15252
15335
|
children: [
|
|
15253
|
-
/* @__PURE__ */ (0,
|
|
15254
|
-
/* @__PURE__ */ (0,
|
|
15255
|
-
/* @__PURE__ */ (0,
|
|
15336
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" }) }),
|
|
15337
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "font-medium", children: currentTheme }),
|
|
15338
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("svg", { className: `w-4 h-4 transition-transform ${isOpen ? "rotate-180" : ""}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })
|
|
15256
15339
|
]
|
|
15257
15340
|
}
|
|
15258
15341
|
),
|
|
15259
|
-
isOpen && /* @__PURE__ */ (0,
|
|
15260
|
-
/* @__PURE__ */ (0,
|
|
15342
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(import_jsx_runtime86.Fragment, { children: [
|
|
15343
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
15261
15344
|
"div",
|
|
15262
15345
|
{
|
|
15263
15346
|
className: "fixed inset-0 z-40",
|
|
15264
15347
|
onClick: () => setIsOpen(false)
|
|
15265
15348
|
}
|
|
15266
15349
|
),
|
|
15267
|
-
/* @__PURE__ */ (0,
|
|
15350
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "absolute top-full left-0 mt-2 w-56 max-h-80 overflow-auto bg-card border border-border rounded-lg shadow-lg z-50", children: themes.map((theme) => /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
|
|
15268
15351
|
"button",
|
|
15269
15352
|
{
|
|
15270
15353
|
onClick: () => handleThemeSelect(theme.name),
|
|
15271
15354
|
className: `w-full px-4 py-2 text-left hover:bg-muted transition-colors flex items-center gap-3 ${currentTheme === theme.name ? "bg-muted" : ""}`,
|
|
15272
15355
|
children: [
|
|
15273
|
-
/* @__PURE__ */ (0,
|
|
15356
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
15274
15357
|
"div",
|
|
15275
15358
|
{
|
|
15276
15359
|
className: "w-4 h-4 rounded-full border border-border",
|
|
15277
15360
|
style: { backgroundColor: theme.primaryColor || "#888" }
|
|
15278
15361
|
}
|
|
15279
15362
|
),
|
|
15280
|
-
/* @__PURE__ */ (0,
|
|
15281
|
-
currentTheme === theme.name && /* @__PURE__ */ (0,
|
|
15363
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "text-foreground", children: theme.name }),
|
|
15364
|
+
currentTheme === theme.name && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("svg", { className: "w-4 h-4 ml-auto text-primary", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }) })
|
|
15282
15365
|
]
|
|
15283
15366
|
},
|
|
15284
15367
|
theme.name
|
|
15285
15368
|
)) })
|
|
15286
15369
|
] })
|
|
15287
15370
|
] }),
|
|
15288
|
-
/* @__PURE__ */ (0,
|
|
15371
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
|
|
15289
15372
|
"button",
|
|
15290
15373
|
{
|
|
15291
15374
|
onClick: handleDarkModeToggle,
|
|
15292
15375
|
className: "flex items-center gap-2 px-4 py-2 bg-card border border-border rounded-lg hover:bg-muted transition-colors text-foreground",
|
|
15293
15376
|
title: `Switch to ${isDark ? "light" : "dark"} mode`,
|
|
15294
15377
|
children: [
|
|
15295
|
-
isDark ? /* @__PURE__ */ (0,
|
|
15296
|
-
/* @__PURE__ */ (0,
|
|
15297
|
-
/* @__PURE__ */ (0,
|
|
15298
|
-
] }) : /* @__PURE__ */ (0,
|
|
15299
|
-
/* @__PURE__ */ (0,
|
|
15378
|
+
isDark ? /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: [
|
|
15379
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("circle", { cx: "12", cy: "12", r: "5" }),
|
|
15380
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("path", { d: "M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" })
|
|
15381
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) }),
|
|
15382
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "text-sm", children: isDark ? "Light" : "Dark" })
|
|
15300
15383
|
]
|
|
15301
15384
|
}
|
|
15302
15385
|
)
|
|
@@ -15304,7 +15387,7 @@ function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
|
15304
15387
|
}
|
|
15305
15388
|
|
|
15306
15389
|
// src/design-system/DesignSystemPage.tsx
|
|
15307
|
-
var
|
|
15390
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
15308
15391
|
function DesignSystemPage({
|
|
15309
15392
|
showThemeSwitcher = true,
|
|
15310
15393
|
showColors = true,
|
|
@@ -15314,29 +15397,29 @@ function DesignSystemPage({
|
|
|
15314
15397
|
colorLayout = "list",
|
|
15315
15398
|
className = ""
|
|
15316
15399
|
}) {
|
|
15317
|
-
return /* @__PURE__ */ (0,
|
|
15318
|
-
/* @__PURE__ */ (0,
|
|
15319
|
-
/* @__PURE__ */ (0,
|
|
15320
|
-
/* @__PURE__ */ (0,
|
|
15321
|
-
/* @__PURE__ */ (0,
|
|
15400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: `max-w-4xl mx-auto px-4 py-8 ${className}`, children: [
|
|
15401
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("header", { className: "mb-12", children: /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-4", children: [
|
|
15402
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { children: [
|
|
15403
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("h1", { className: "text-4xl font-bold text-foreground mb-2", children: "Design System" }),
|
|
15404
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("p", { className: "text-lg text-muted-foreground", children: "Visual reference for theme tokens and styles" })
|
|
15322
15405
|
] }),
|
|
15323
|
-
showThemeSwitcher && /* @__PURE__ */ (0,
|
|
15406
|
+
showThemeSwitcher && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ThemeSwitcher, {})
|
|
15324
15407
|
] }) }),
|
|
15325
|
-
showColors && /* @__PURE__ */ (0,
|
|
15326
|
-
/* @__PURE__ */ (0,
|
|
15327
|
-
/* @__PURE__ */ (0,
|
|
15408
|
+
showColors && /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("section", { className: "mb-16", children: [
|
|
15409
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Color Palette" }),
|
|
15410
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ColorPalette, { layout: colorLayout })
|
|
15328
15411
|
] }),
|
|
15329
|
-
showTypography && /* @__PURE__ */ (0,
|
|
15330
|
-
/* @__PURE__ */ (0,
|
|
15331
|
-
/* @__PURE__ */ (0,
|
|
15412
|
+
showTypography && /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("section", { className: "mb-16", children: [
|
|
15413
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Typography" }),
|
|
15414
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(TypographyScale, {})
|
|
15332
15415
|
] }),
|
|
15333
|
-
showRadius && /* @__PURE__ */ (0,
|
|
15334
|
-
/* @__PURE__ */ (0,
|
|
15335
|
-
/* @__PURE__ */ (0,
|
|
15416
|
+
showRadius && /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("section", { className: "mb-16", children: [
|
|
15417
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Border Radius" }),
|
|
15418
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(RadiusScale, {})
|
|
15336
15419
|
] }),
|
|
15337
|
-
showSpacing && /* @__PURE__ */ (0,
|
|
15338
|
-
/* @__PURE__ */ (0,
|
|
15339
|
-
/* @__PURE__ */ (0,
|
|
15420
|
+
showSpacing && /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("section", { className: "mb-16", children: [
|
|
15421
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-6 pb-2 border-b border-border", children: "Spacing Scale" }),
|
|
15422
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(SpacingScale, {})
|
|
15340
15423
|
] })
|
|
15341
15424
|
] });
|
|
15342
15425
|
}
|
|
@@ -15351,31 +15434,31 @@ function SpacingScale() {
|
|
|
15351
15434
|
{ name: "12", value: "3rem" },
|
|
15352
15435
|
{ name: "16", value: "4rem" }
|
|
15353
15436
|
];
|
|
15354
|
-
return /* @__PURE__ */ (0,
|
|
15355
|
-
/* @__PURE__ */ (0,
|
|
15356
|
-
/* @__PURE__ */ (0,
|
|
15437
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "space-y-2", children: spaces.map((space) => /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "flex items-center gap-4", children: [
|
|
15438
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("code", { className: "text-xs text-muted-foreground font-mono w-8", children: space.name }),
|
|
15439
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
15357
15440
|
"div",
|
|
15358
15441
|
{
|
|
15359
15442
|
className: "h-4 bg-primary rounded",
|
|
15360
15443
|
style: { width: space.value }
|
|
15361
15444
|
}
|
|
15362
15445
|
),
|
|
15363
|
-
/* @__PURE__ */ (0,
|
|
15446
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "text-sm text-muted-foreground", children: space.value })
|
|
15364
15447
|
] }, space.name)) });
|
|
15365
15448
|
}
|
|
15366
15449
|
|
|
15367
15450
|
// src/personalization/PersonalizationProvider.tsx
|
|
15368
|
-
var
|
|
15451
|
+
var import_react68 = __toESM(require("react"), 1);
|
|
15369
15452
|
|
|
15370
15453
|
// src/personalization/PersonalizationContext.ts
|
|
15371
|
-
var
|
|
15372
|
-
var PersonalizationContext = (0,
|
|
15454
|
+
var import_react66 = require("react");
|
|
15455
|
+
var PersonalizationContext = (0, import_react66.createContext)(null);
|
|
15373
15456
|
function usePersonalizationContext() {
|
|
15374
|
-
return (0,
|
|
15457
|
+
return (0, import_react66.useContext)(PersonalizationContext);
|
|
15375
15458
|
}
|
|
15376
15459
|
|
|
15377
15460
|
// src/personalization/utils.ts
|
|
15378
|
-
var
|
|
15461
|
+
var import_react67 = require("react");
|
|
15379
15462
|
function normalizeHex(color) {
|
|
15380
15463
|
let hex = color.trim().toUpperCase();
|
|
15381
15464
|
if (hex.length === 4 && hex.startsWith("#")) {
|
|
@@ -15396,8 +15479,8 @@ function isValidImageUrl(url) {
|
|
|
15396
15479
|
}
|
|
15397
15480
|
}
|
|
15398
15481
|
function useDebouncedValue(value, delay) {
|
|
15399
|
-
const [debounced, setDebounced] = (0,
|
|
15400
|
-
(0,
|
|
15482
|
+
const [debounced, setDebounced] = (0, import_react67.useState)(value);
|
|
15483
|
+
(0, import_react67.useEffect)(() => {
|
|
15401
15484
|
const timer = setTimeout(() => setDebounced(value), delay);
|
|
15402
15485
|
return () => clearTimeout(timer);
|
|
15403
15486
|
}, [value, delay]);
|
|
@@ -15418,18 +15501,18 @@ function scrollInputAboveKeyboard(input) {
|
|
|
15418
15501
|
}
|
|
15419
15502
|
|
|
15420
15503
|
// src/personalization/PersonalizationProvider.tsx
|
|
15421
|
-
var
|
|
15504
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
15422
15505
|
function createBridgeFromCanvas(canvasModule) {
|
|
15423
15506
|
const { useEditor, useCommands, useImageBinding } = canvasModule;
|
|
15424
15507
|
function TextBinder({ name, value }) {
|
|
15425
15508
|
const { elements } = useEditor();
|
|
15426
15509
|
const { executeElementUpdate } = useCommands();
|
|
15427
|
-
const elementsRef =
|
|
15510
|
+
const elementsRef = import_react68.default.useRef(elements);
|
|
15428
15511
|
elementsRef.current = elements;
|
|
15429
|
-
const executeRef =
|
|
15512
|
+
const executeRef = import_react68.default.useRef(executeElementUpdate);
|
|
15430
15513
|
executeRef.current = executeElementUpdate;
|
|
15431
|
-
const hasUserInput =
|
|
15432
|
-
|
|
15514
|
+
const hasUserInput = import_react68.default.useRef(false);
|
|
15515
|
+
import_react68.default.useEffect(() => {
|
|
15433
15516
|
if (value == null) return;
|
|
15434
15517
|
if (value === "" && !hasUserInput.current) return;
|
|
15435
15518
|
hasUserInput.current = true;
|
|
@@ -15447,12 +15530,12 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
15447
15530
|
function ColorBinder({ originalColor, newColor }) {
|
|
15448
15531
|
const { elements } = useEditor();
|
|
15449
15532
|
const { executeElementUpdate } = useCommands();
|
|
15450
|
-
const elementsRef =
|
|
15533
|
+
const elementsRef = import_react68.default.useRef(elements);
|
|
15451
15534
|
elementsRef.current = elements;
|
|
15452
|
-
const executeRef =
|
|
15535
|
+
const executeRef = import_react68.default.useRef(executeElementUpdate);
|
|
15453
15536
|
executeRef.current = executeElementUpdate;
|
|
15454
|
-
const appliedColorRef =
|
|
15455
|
-
|
|
15537
|
+
const appliedColorRef = import_react68.default.useRef(normalizeHex(originalColor));
|
|
15538
|
+
import_react68.default.useEffect(() => {
|
|
15456
15539
|
const normalizedNew = normalizeHex(newColor);
|
|
15457
15540
|
if (normalizedNew === appliedColorRef.current) return;
|
|
15458
15541
|
const matchColor = appliedColorRef.current;
|
|
@@ -15492,11 +15575,11 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
15492
15575
|
}
|
|
15493
15576
|
function ImageBinder({ name, value, fit = "cover" }) {
|
|
15494
15577
|
const { setImageUrl } = useImageBinding(name, { fit });
|
|
15495
|
-
const hasUserInput =
|
|
15578
|
+
const hasUserInput = import_react68.default.useRef(false);
|
|
15496
15579
|
const debouncedValue = useDebouncedValue(value, 500);
|
|
15497
|
-
const setImageUrlRef =
|
|
15580
|
+
const setImageUrlRef = import_react68.default.useRef(setImageUrl);
|
|
15498
15581
|
setImageUrlRef.current = setImageUrl;
|
|
15499
|
-
|
|
15582
|
+
import_react68.default.useEffect(() => {
|
|
15500
15583
|
if (debouncedValue == null) return;
|
|
15501
15584
|
if (debouncedValue === "" && !hasUserInput.current) return;
|
|
15502
15585
|
hasUserInput.current = true;
|
|
@@ -15506,15 +15589,15 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
15506
15589
|
return null;
|
|
15507
15590
|
}
|
|
15508
15591
|
return function PersonalizationBridge({ fields = [], values = {} } = {}) {
|
|
15509
|
-
return /* @__PURE__ */ (0,
|
|
15592
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(import_jsx_runtime88.Fragment, { children: fields.map((field) => {
|
|
15510
15593
|
if (field.type === "text") {
|
|
15511
|
-
return /* @__PURE__ */ (0,
|
|
15594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(TextBinder, { name: field.name, value: values[field.name] ?? "" }, `text-${field.name}`);
|
|
15512
15595
|
}
|
|
15513
15596
|
if (field.type === "color") {
|
|
15514
|
-
return /* @__PURE__ */ (0,
|
|
15597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(ColorBinder, { originalColor: field.color, newColor: values[field.color] ?? field.color }, `color-${field.color}`);
|
|
15515
15598
|
}
|
|
15516
15599
|
if (field.type === "image") {
|
|
15517
|
-
return /* @__PURE__ */ (0,
|
|
15600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(ImageBinder, { name: field.name, value: values[field.name] ?? "", fit: field.fit ?? "cover" }, `image-${field.name}`);
|
|
15518
15601
|
}
|
|
15519
15602
|
return null;
|
|
15520
15603
|
}) });
|
|
@@ -15536,19 +15619,19 @@ function PersonalizationProvider({
|
|
|
15536
15619
|
children
|
|
15537
15620
|
}) {
|
|
15538
15621
|
const realtime = useRealtimeOptional();
|
|
15539
|
-
const [personValues, setPersonValues] = (0,
|
|
15540
|
-
const [isActive, setIsActive] = (0,
|
|
15541
|
-
const [isExporting, setIsExporting] = (0,
|
|
15542
|
-
const [exportedBlobUrls, setExportedBlobUrls] = (0,
|
|
15543
|
-
const [exportCount, setExportCount] = (0,
|
|
15544
|
-
const blobUrlsRef = (0,
|
|
15545
|
-
const [CanvasComponent, setCanvasComponent] = (0,
|
|
15622
|
+
const [personValues, setPersonValues] = (0, import_react68.useState)(initialValues ?? {});
|
|
15623
|
+
const [isActive, setIsActive] = (0, import_react68.useState)(!!(initialValues && Object.keys(initialValues).length > 0));
|
|
15624
|
+
const [isExporting, setIsExporting] = (0, import_react68.useState)(false);
|
|
15625
|
+
const [exportedBlobUrls, setExportedBlobUrls] = (0, import_react68.useState)({});
|
|
15626
|
+
const [exportCount, setExportCount] = (0, import_react68.useState)(0);
|
|
15627
|
+
const blobUrlsRef = (0, import_react68.useRef)({});
|
|
15628
|
+
const [CanvasComponent, setCanvasComponent] = (0, import_react68.useState)(
|
|
15546
15629
|
cachedCanvasComponent
|
|
15547
15630
|
);
|
|
15548
|
-
const [BridgeComponent, setBridgeComponent] = (0,
|
|
15631
|
+
const [BridgeComponent, setBridgeComponent] = (0, import_react68.useState)(
|
|
15549
15632
|
cachedBridgeComponent
|
|
15550
15633
|
);
|
|
15551
|
-
(0,
|
|
15634
|
+
(0, import_react68.useEffect)(() => {
|
|
15552
15635
|
if (CanvasComponent && BridgeComponent) return;
|
|
15553
15636
|
if (!canvasImport) return;
|
|
15554
15637
|
if (!canvasLoadPromise) {
|
|
@@ -15566,8 +15649,8 @@ function PersonalizationProvider({
|
|
|
15566
15649
|
}
|
|
15567
15650
|
});
|
|
15568
15651
|
}, [CanvasComponent, BridgeComponent, canvasImport]);
|
|
15569
|
-
const realtimeEnabledRef = (0,
|
|
15570
|
-
(0,
|
|
15652
|
+
const realtimeEnabledRef = (0, import_react68.useRef)(false);
|
|
15653
|
+
(0, import_react68.useEffect)(() => {
|
|
15571
15654
|
return () => {
|
|
15572
15655
|
for (const url of Object.values(blobUrlsRef.current)) {
|
|
15573
15656
|
try {
|
|
@@ -15577,16 +15660,16 @@ function PersonalizationProvider({
|
|
|
15577
15660
|
}
|
|
15578
15661
|
};
|
|
15579
15662
|
}, []);
|
|
15580
|
-
const updateField = (0,
|
|
15663
|
+
const updateField = (0, import_react68.useCallback)((key, value) => {
|
|
15581
15664
|
setIsActive(true);
|
|
15582
15665
|
setPersonValues((prev) => ({ ...prev, [key]: value }));
|
|
15583
15666
|
}, []);
|
|
15584
|
-
const reset = (0,
|
|
15667
|
+
const reset = (0, import_react68.useCallback)(() => {
|
|
15585
15668
|
setPersonValues({});
|
|
15586
15669
|
setIsActive(false);
|
|
15587
15670
|
setIsExporting(false);
|
|
15588
15671
|
}, []);
|
|
15589
|
-
const handleExport = (0,
|
|
15672
|
+
const handleExport = (0, import_react68.useCallback)(
|
|
15590
15673
|
(exports2) => {
|
|
15591
15674
|
const newUrls = {};
|
|
15592
15675
|
for (const [name, data] of Object.entries(exports2)) {
|
|
@@ -15620,11 +15703,11 @@ function PersonalizationProvider({
|
|
|
15620
15703
|
},
|
|
15621
15704
|
[realtime, placementOverride]
|
|
15622
15705
|
);
|
|
15623
|
-
const handleExportScheduled = (0,
|
|
15706
|
+
const handleExportScheduled = (0, import_react68.useCallback)(() => {
|
|
15624
15707
|
setIsExporting(true);
|
|
15625
15708
|
}, []);
|
|
15626
15709
|
const shouldMountCanvas = CanvasComponent && BridgeComponent && canvasState?.elements && canvasState.elements.length > 0 && (!lazy || isActive);
|
|
15627
|
-
const contextValue =
|
|
15710
|
+
const contextValue = import_react68.default.useMemo(
|
|
15628
15711
|
() => ({
|
|
15629
15712
|
fields,
|
|
15630
15713
|
personValues,
|
|
@@ -15637,8 +15720,8 @@ function PersonalizationProvider({
|
|
|
15637
15720
|
}),
|
|
15638
15721
|
[fields, personValues, updateField, isActive, isExporting, exportedBlobUrls, exportCount, reset]
|
|
15639
15722
|
);
|
|
15640
|
-
return /* @__PURE__ */ (0,
|
|
15641
|
-
shouldMountCanvas && CanvasComponent && BridgeComponent && /* @__PURE__ */ (0,
|
|
15723
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(PersonalizationContext.Provider, { value: contextValue, children: [
|
|
15724
|
+
shouldMountCanvas && CanvasComponent && BridgeComponent && /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
15642
15725
|
"div",
|
|
15643
15726
|
{
|
|
15644
15727
|
style: {
|
|
@@ -15651,7 +15734,7 @@ function PersonalizationProvider({
|
|
|
15651
15734
|
pointerEvents: "none"
|
|
15652
15735
|
},
|
|
15653
15736
|
"aria-hidden": true,
|
|
15654
|
-
children: /* @__PURE__ */ (0,
|
|
15737
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
15655
15738
|
CanvasComponent,
|
|
15656
15739
|
{
|
|
15657
15740
|
initialElements: canvasState?.elements,
|
|
@@ -15671,7 +15754,7 @@ function PersonalizationProvider({
|
|
|
15671
15754
|
exportImageQuality: exportConfig?.imageQuality ?? 0.85,
|
|
15672
15755
|
onExport: handleExport,
|
|
15673
15756
|
onExportScheduled: handleExportScheduled,
|
|
15674
|
-
overlay: /* @__PURE__ */ (0,
|
|
15757
|
+
overlay: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(BridgeComponent, { fields, values: personValues })
|
|
15675
15758
|
}
|
|
15676
15759
|
)
|
|
15677
15760
|
},
|
|
@@ -15696,7 +15779,7 @@ function usePersonalizationOptional() {
|
|
|
15696
15779
|
}
|
|
15697
15780
|
|
|
15698
15781
|
// src/personalization/PersonalizationInputs.tsx
|
|
15699
|
-
var
|
|
15782
|
+
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
15700
15783
|
function PersonalizationInputs({
|
|
15701
15784
|
className,
|
|
15702
15785
|
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",
|
|
@@ -15720,8 +15803,8 @@ function PersonalizationInputs({
|
|
|
15720
15803
|
scrollInputAboveKeyboard(e.target);
|
|
15721
15804
|
}
|
|
15722
15805
|
};
|
|
15723
|
-
return /* @__PURE__ */ (0,
|
|
15724
|
-
textFields.map((field) => /* @__PURE__ */ (0,
|
|
15806
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: className || "flex flex-col gap-3", children: [
|
|
15807
|
+
textFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
15725
15808
|
"input",
|
|
15726
15809
|
{
|
|
15727
15810
|
type: "text",
|
|
@@ -15735,8 +15818,8 @@ function PersonalizationInputs({
|
|
|
15735
15818
|
},
|
|
15736
15819
|
`text-${field.name}`
|
|
15737
15820
|
)),
|
|
15738
|
-
colorFields.map((field) => /* @__PURE__ */ (0,
|
|
15739
|
-
/* @__PURE__ */ (0,
|
|
15821
|
+
colorFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
15822
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
15740
15823
|
"input",
|
|
15741
15824
|
{
|
|
15742
15825
|
type: "color",
|
|
@@ -15745,9 +15828,9 @@ function PersonalizationInputs({
|
|
|
15745
15828
|
onChange: (e) => updateField(field.color, e.target.value)
|
|
15746
15829
|
}
|
|
15747
15830
|
),
|
|
15748
|
-
/* @__PURE__ */ (0,
|
|
15831
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "text-base text-muted-foreground", children: field.label })
|
|
15749
15832
|
] }, `color-${field.color}`)),
|
|
15750
|
-
imageFields.map((field) => /* @__PURE__ */ (0,
|
|
15833
|
+
imageFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
15751
15834
|
"input",
|
|
15752
15835
|
{
|
|
15753
15836
|
type: "text",
|
|
@@ -15765,15 +15848,15 @@ function PersonalizationInputs({
|
|
|
15765
15848
|
}
|
|
15766
15849
|
|
|
15767
15850
|
// src/personalization/usePersonalizationShimmer.ts
|
|
15768
|
-
var
|
|
15851
|
+
var import_react69 = require("react");
|
|
15769
15852
|
function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
15770
15853
|
const personCtx = usePersonalizationContext();
|
|
15771
15854
|
const realtime = useRealtimeOptional();
|
|
15772
|
-
const [shimmerActive, setShimmerActive] = (0,
|
|
15773
|
-
const sdkSettledRef = (0,
|
|
15774
|
-
const manualTriggerRef = (0,
|
|
15775
|
-
const safetyTimeoutRef = (0,
|
|
15776
|
-
const startShimmer = (0,
|
|
15855
|
+
const [shimmerActive, setShimmerActive] = (0, import_react69.useState)(false);
|
|
15856
|
+
const sdkSettledRef = (0, import_react69.useRef)(false);
|
|
15857
|
+
const manualTriggerRef = (0, import_react69.useRef)(false);
|
|
15858
|
+
const safetyTimeoutRef = (0, import_react69.useRef)(void 0);
|
|
15859
|
+
const startShimmer = (0, import_react69.useCallback)(() => {
|
|
15777
15860
|
setShimmerActive(true);
|
|
15778
15861
|
if (safetyTimeoutRef.current) clearTimeout(safetyTimeoutRef.current);
|
|
15779
15862
|
safetyTimeoutRef.current = setTimeout(
|
|
@@ -15785,25 +15868,25 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
15785
15868
|
safetyTimeoutMs
|
|
15786
15869
|
);
|
|
15787
15870
|
}, [safetyTimeoutMs]);
|
|
15788
|
-
(0,
|
|
15871
|
+
(0, import_react69.useEffect)(() => {
|
|
15789
15872
|
if (!personCtx?.isActive) return;
|
|
15790
15873
|
sdkSettledRef.current = false;
|
|
15791
15874
|
manualTriggerRef.current = false;
|
|
15792
15875
|
realtime?.resetPipelineSettled();
|
|
15793
15876
|
startShimmer();
|
|
15794
15877
|
}, [personCtx?.personValues, personCtx?.isActive, startShimmer]);
|
|
15795
|
-
const triggerShimmer = (0,
|
|
15878
|
+
const triggerShimmer = (0, import_react69.useCallback)(() => {
|
|
15796
15879
|
sdkSettledRef.current = false;
|
|
15797
15880
|
manualTriggerRef.current = true;
|
|
15798
15881
|
startShimmer();
|
|
15799
15882
|
}, [startShimmer]);
|
|
15800
|
-
(0,
|
|
15883
|
+
(0, import_react69.useEffect)(() => {
|
|
15801
15884
|
if (!realtime?.subscribePipelineSettled) return;
|
|
15802
15885
|
return realtime.subscribePipelineSettled(() => {
|
|
15803
15886
|
sdkSettledRef.current = true;
|
|
15804
15887
|
});
|
|
15805
15888
|
}, [realtime]);
|
|
15806
|
-
(0,
|
|
15889
|
+
(0, import_react69.useEffect)(() => {
|
|
15807
15890
|
const container = containerRef.current;
|
|
15808
15891
|
if (!container) return;
|
|
15809
15892
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -15846,7 +15929,7 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
15846
15929
|
});
|
|
15847
15930
|
return () => observer.disconnect();
|
|
15848
15931
|
}, [containerRef]);
|
|
15849
|
-
(0,
|
|
15932
|
+
(0, import_react69.useEffect)(() => {
|
|
15850
15933
|
return () => {
|
|
15851
15934
|
if (safetyTimeoutRef.current) clearTimeout(safetyTimeoutRef.current);
|
|
15852
15935
|
};
|
|
@@ -15988,6 +16071,7 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
15988
16071
|
RealtimeProvider,
|
|
15989
16072
|
ResponsiveZoom,
|
|
15990
16073
|
RightToLeftProgressiveBlur,
|
|
16074
|
+
SafeImg,
|
|
15991
16075
|
ScrollFade,
|
|
15992
16076
|
SearchBox,
|
|
15993
16077
|
SearchProvider,
|