@snowcone-app/ui 0.4.0 → 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 +9 -0
- package/dist/index.cjs +545 -473
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.js +435 -364
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/composed/HeroProductImage.tsx +78 -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/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,
|
|
@@ -9341,7 +9342,7 @@ var LoadingOverlayPrismCandyInline = (0, import_react40.memo)(
|
|
|
9341
9342
|
);
|
|
9342
9343
|
|
|
9343
9344
|
// src/index.ts
|
|
9344
|
-
var
|
|
9345
|
+
var import_react70 = require("@snowcone-app/sdk/react");
|
|
9345
9346
|
var import_sdk11 = require("@snowcone-app/sdk");
|
|
9346
9347
|
|
|
9347
9348
|
// src/patterns/ProductPageProvider.tsx
|
|
@@ -10415,12 +10416,18 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10415
10416
|
const [showNew, setShowNew] = (0, import_react45.useState)(false);
|
|
10416
10417
|
const [renderedUrl, setRenderedUrl] = (0, import_react45.useState)(displayUrl);
|
|
10417
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);
|
|
10418
10423
|
const prevDisplayUrlRef = (0, import_react45.useRef)(displayUrl);
|
|
10419
10424
|
const signHintShownRef = (0, import_react45.useRef)(false);
|
|
10420
10425
|
(0, import_react45.useEffect)(() => {
|
|
10421
10426
|
if (!displayUrl || displayUrl === prevDisplayUrlRef.current) return;
|
|
10422
10427
|
const oldUrl = prevDisplayUrlRef.current;
|
|
10423
10428
|
prevDisplayUrlRef.current = displayUrl;
|
|
10429
|
+
setImgFailed(false);
|
|
10430
|
+
retriedUrlRef.current = null;
|
|
10424
10431
|
if (!oldUrl) {
|
|
10425
10432
|
setRenderedUrl(displayUrl);
|
|
10426
10433
|
return;
|
|
@@ -10446,6 +10453,7 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10446
10453
|
setPrevUrl(null);
|
|
10447
10454
|
setShowNew(false);
|
|
10448
10455
|
}, []);
|
|
10456
|
+
const handleLoaderExited = (0, import_react45.useCallback)(() => setLoaderMounted(false), []);
|
|
10449
10457
|
if (!hasArtwork) {
|
|
10450
10458
|
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10451
10459
|
"div",
|
|
@@ -10494,19 +10502,19 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10494
10502
|
style,
|
|
10495
10503
|
"data-hero-image": "true",
|
|
10496
10504
|
children: [
|
|
10497
|
-
!
|
|
10498
|
-
renderedUrl && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10505
|
+
renderedUrl && !imgFailed && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10499
10506
|
"img",
|
|
10500
10507
|
{
|
|
10501
10508
|
alt: `Product mockup${placement ? ` - ${placement}` : ""}`,
|
|
10502
10509
|
crossOrigin: "anonymous",
|
|
10503
10510
|
className: "absolute inset-0 w-full h-full object-cover",
|
|
10504
10511
|
draggable,
|
|
10505
|
-
src: renderedUrl,
|
|
10512
|
+
src: retriedUrlRef.current === renderedUrl ? `${renderedUrl}${renderedUrl.includes("?") ? "&" : "?"}_cb=${retryNonce}` : renderedUrl,
|
|
10506
10513
|
loading: "eager",
|
|
10507
10514
|
fetchPriority: "high",
|
|
10508
10515
|
onClick,
|
|
10509
10516
|
onLoad: () => {
|
|
10517
|
+
setImgFailed(false);
|
|
10510
10518
|
setFirstImageLoaded(true);
|
|
10511
10519
|
if (!onLoadCalledRef.current && onLoad) {
|
|
10512
10520
|
onLoadCalledRef.current = true;
|
|
@@ -10515,6 +10523,12 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10515
10523
|
onUrlGeneratedRef.current?.(renderedUrl);
|
|
10516
10524
|
},
|
|
10517
10525
|
onError: () => {
|
|
10526
|
+
if (renderedUrl && retriedUrlRef.current !== renderedUrl) {
|
|
10527
|
+
retriedUrlRef.current = renderedUrl;
|
|
10528
|
+
setRetryNonce((n) => n + 1);
|
|
10529
|
+
return;
|
|
10530
|
+
}
|
|
10531
|
+
setImgFailed(true);
|
|
10518
10532
|
setFirstImageLoaded(true);
|
|
10519
10533
|
onError?.();
|
|
10520
10534
|
if (process.env.NODE_ENV !== "production" && !signHintShownRef.current && renderedUrl && /\/[A-Za-z0-9]+\?/.test(renderedUrl) && !/[?&]signature=/.test(renderedUrl)) {
|
|
@@ -10527,6 +10541,7 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10527
10541
|
}
|
|
10528
10542
|
}
|
|
10529
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" }) }),
|
|
10530
10545
|
realtimeContext?.renderError && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10531
10546
|
"div",
|
|
10532
10547
|
{
|
|
@@ -10550,12 +10565,45 @@ var HeroProductImage = (0, import_react45.memo)(function HeroProductImage2({
|
|
|
10550
10565
|
},
|
|
10551
10566
|
onTransitionEnd: handleCrossfadeEnd
|
|
10552
10567
|
}
|
|
10568
|
+
),
|
|
10569
|
+
loaderMounted && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10570
|
+
LoadingOverlayPrismCandyInline,
|
|
10571
|
+
{
|
|
10572
|
+
visible: !firstImageLoaded,
|
|
10573
|
+
variant: "light",
|
|
10574
|
+
onExited: handleLoaderExited
|
|
10575
|
+
}
|
|
10553
10576
|
)
|
|
10554
10577
|
]
|
|
10555
10578
|
}
|
|
10556
10579
|
);
|
|
10557
10580
|
});
|
|
10558
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
|
+
|
|
10559
10607
|
// src/index.ts
|
|
10560
10608
|
var import_sdk12 = require("@snowcone-app/sdk");
|
|
10561
10609
|
|
|
@@ -10565,7 +10613,7 @@ var import_react_instantsearch = require("react-instantsearch");
|
|
|
10565
10613
|
// src/composed/search/meilisearchAdapter.ts
|
|
10566
10614
|
var import_instant_meilisearch = require("@meilisearch/instant-meilisearch");
|
|
10567
10615
|
var MEILISEARCH_HOST = readEnv("NEXT_PUBLIC_MEILISEARCH_HOST") || "https://ms-e5d999b2eaca-15654.sfo.meilisearch.io";
|
|
10568
|
-
var MEILISEARCH_API_KEY = readEnv("NEXT_PUBLIC_MEILISEARCH_API_KEY") || "
|
|
10616
|
+
var MEILISEARCH_API_KEY = readEnv("NEXT_PUBLIC_MEILISEARCH_API_KEY") || "4a11f6599e39af365f6289dab46b77a30ef78ba1ac078f7d74e152c099b3b63c";
|
|
10569
10617
|
var { searchClient } = (0, import_instant_meilisearch.instantMeiliSearch)(
|
|
10570
10618
|
MEILISEARCH_HOST,
|
|
10571
10619
|
MEILISEARCH_API_KEY,
|
|
@@ -10576,11 +10624,11 @@ var { searchClient } = (0, import_instant_meilisearch.instantMeiliSearch)(
|
|
|
10576
10624
|
);
|
|
10577
10625
|
|
|
10578
10626
|
// src/composed/search/SearchProvider.tsx
|
|
10579
|
-
var
|
|
10580
|
-
var
|
|
10627
|
+
var import_react47 = require("react");
|
|
10628
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
10581
10629
|
function InitialSearchTrigger() {
|
|
10582
10630
|
const { refine } = (0, import_react_instantsearch.useSearchBox)();
|
|
10583
|
-
(0,
|
|
10631
|
+
(0, import_react47.useEffect)(() => {
|
|
10584
10632
|
refine("");
|
|
10585
10633
|
}, [refine]);
|
|
10586
10634
|
return null;
|
|
@@ -10604,7 +10652,7 @@ function SearchProvider({
|
|
|
10604
10652
|
],
|
|
10605
10653
|
children
|
|
10606
10654
|
}) {
|
|
10607
|
-
return /* @__PURE__ */ (0,
|
|
10655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
|
|
10608
10656
|
import_react_instantsearch.InstantSearch,
|
|
10609
10657
|
{
|
|
10610
10658
|
searchClient,
|
|
@@ -10632,7 +10680,7 @@ function SearchProvider({
|
|
|
10632
10680
|
}
|
|
10633
10681
|
},
|
|
10634
10682
|
children: [
|
|
10635
|
-
/* @__PURE__ */ (0,
|
|
10683
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
10636
10684
|
import_react_instantsearch.Configure,
|
|
10637
10685
|
{
|
|
10638
10686
|
hitsPerPage,
|
|
@@ -10641,7 +10689,7 @@ function SearchProvider({
|
|
|
10641
10689
|
attributesToRetrieve
|
|
10642
10690
|
}
|
|
10643
10691
|
),
|
|
10644
|
-
/* @__PURE__ */ (0,
|
|
10692
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(InitialSearchTrigger, {}),
|
|
10645
10693
|
children
|
|
10646
10694
|
]
|
|
10647
10695
|
}
|
|
@@ -10651,17 +10699,17 @@ function SearchProvider({
|
|
|
10651
10699
|
// src/composed/search/SearchBox.tsx
|
|
10652
10700
|
var import_react_instantsearch2 = require("react-instantsearch");
|
|
10653
10701
|
var import_lucide_react3 = require("lucide-react");
|
|
10654
|
-
var
|
|
10655
|
-
var
|
|
10702
|
+
var import_react48 = require("react");
|
|
10703
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
10656
10704
|
function SearchBox() {
|
|
10657
10705
|
const { query, refine, clear } = (0, import_react_instantsearch2.useSearchBox)();
|
|
10658
10706
|
const searchParams = useUiSearchParams();
|
|
10659
10707
|
const router = useUiRouter();
|
|
10660
|
-
const inputRef = (0,
|
|
10661
|
-
const [showShimmer, setShowShimmer] = (0,
|
|
10708
|
+
const inputRef = (0, import_react48.useRef)(null);
|
|
10709
|
+
const [showShimmer, setShowShimmer] = (0, import_react48.useState)(false);
|
|
10662
10710
|
const inputId = "search-products-input";
|
|
10663
10711
|
const descriptionId = "search-description";
|
|
10664
|
-
(0,
|
|
10712
|
+
(0, import_react48.useEffect)(() => {
|
|
10665
10713
|
const handleSpotlight = () => {
|
|
10666
10714
|
inputRef.current?.focus();
|
|
10667
10715
|
inputRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
@@ -10671,7 +10719,7 @@ function SearchBox() {
|
|
|
10671
10719
|
window.addEventListener("search-spotlight", handleSpotlight);
|
|
10672
10720
|
return () => window.removeEventListener("search-spotlight", handleSpotlight);
|
|
10673
10721
|
}, []);
|
|
10674
|
-
(0,
|
|
10722
|
+
(0, import_react48.useEffect)(() => {
|
|
10675
10723
|
const shouldFocus = searchParams.get("focus") === "search";
|
|
10676
10724
|
if (shouldFocus && inputRef.current) {
|
|
10677
10725
|
const timer = setTimeout(() => {
|
|
@@ -10686,8 +10734,8 @@ function SearchBox() {
|
|
|
10686
10734
|
return () => clearTimeout(timer);
|
|
10687
10735
|
}
|
|
10688
10736
|
}, [searchParams, router]);
|
|
10689
|
-
return /* @__PURE__ */ (0,
|
|
10690
|
-
/* @__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)(
|
|
10691
10739
|
Input,
|
|
10692
10740
|
{
|
|
10693
10741
|
ref: inputRef,
|
|
@@ -10696,15 +10744,15 @@ function SearchBox() {
|
|
|
10696
10744
|
value: query,
|
|
10697
10745
|
onChange: (e) => refine(e.target.value),
|
|
10698
10746
|
placeholder: "Search products...",
|
|
10699
|
-
startContent: /* @__PURE__ */ (0,
|
|
10700
|
-
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)(
|
|
10701
10749
|
"button",
|
|
10702
10750
|
{
|
|
10703
10751
|
type: "button",
|
|
10704
10752
|
onClick: clear,
|
|
10705
10753
|
className: "hover:text-foreground transition-colors",
|
|
10706
10754
|
"aria-label": "Clear search",
|
|
10707
|
-
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" })
|
|
10708
10756
|
}
|
|
10709
10757
|
) : void 0,
|
|
10710
10758
|
"aria-label": "Search products",
|
|
@@ -10714,11 +10762,11 @@ function SearchBox() {
|
|
|
10714
10762
|
className: "[&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden"
|
|
10715
10763
|
}
|
|
10716
10764
|
),
|
|
10717
|
-
showShimmer && /* @__PURE__ */ (0,
|
|
10765
|
+
showShimmer && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10718
10766
|
"div",
|
|
10719
10767
|
{
|
|
10720
10768
|
className: "absolute inset-0 pointer-events-none rounded-input z-20 overflow-hidden",
|
|
10721
|
-
children: /* @__PURE__ */ (0,
|
|
10769
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10722
10770
|
"div",
|
|
10723
10771
|
{
|
|
10724
10772
|
className: "absolute inset-0",
|
|
@@ -10731,13 +10779,13 @@ function SearchBox() {
|
|
|
10731
10779
|
)
|
|
10732
10780
|
}
|
|
10733
10781
|
),
|
|
10734
|
-
/* @__PURE__ */ (0,
|
|
10782
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("style", { dangerouslySetInnerHTML: { __html: `
|
|
10735
10783
|
@keyframes searchShimmer {
|
|
10736
10784
|
0% { transform: translateX(-100%); }
|
|
10737
10785
|
100% { transform: translateX(100%); }
|
|
10738
10786
|
}
|
|
10739
10787
|
` } }),
|
|
10740
|
-
/* @__PURE__ */ (0,
|
|
10788
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { id: descriptionId, className: "sr-only", children: "Search results will update as you type" })
|
|
10741
10789
|
] }) });
|
|
10742
10790
|
}
|
|
10743
10791
|
|
|
@@ -10745,7 +10793,7 @@ function SearchBox() {
|
|
|
10745
10793
|
var import_react_instantsearch3 = require("react-instantsearch");
|
|
10746
10794
|
|
|
10747
10795
|
// src/composed/search/ProductHit.tsx
|
|
10748
|
-
var
|
|
10796
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
10749
10797
|
function ProductHitComponent({
|
|
10750
10798
|
hit: product,
|
|
10751
10799
|
variant = "overlay"
|
|
@@ -10762,12 +10810,12 @@ function ProductHitComponent({
|
|
|
10762
10810
|
}
|
|
10763
10811
|
return "";
|
|
10764
10812
|
};
|
|
10765
|
-
return /* @__PURE__ */ (0,
|
|
10813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
10766
10814
|
Product,
|
|
10767
10815
|
{
|
|
10768
10816
|
productId,
|
|
10769
10817
|
productData: product,
|
|
10770
|
-
children: /* @__PURE__ */ (0,
|
|
10818
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
10771
10819
|
ProductCard,
|
|
10772
10820
|
{
|
|
10773
10821
|
variant,
|
|
@@ -10788,10 +10836,10 @@ function ProductHitComponent({
|
|
|
10788
10836
|
}
|
|
10789
10837
|
|
|
10790
10838
|
// src/composed/search/ProductGrid.tsx
|
|
10791
|
-
var
|
|
10792
|
-
var
|
|
10839
|
+
var import_react49 = require("react");
|
|
10840
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
10793
10841
|
function ProductGridSkeletonItem() {
|
|
10794
|
-
return /* @__PURE__ */ (0,
|
|
10842
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "aspect-square bg-muted animate-pulse" });
|
|
10795
10843
|
}
|
|
10796
10844
|
function ProductGrid({
|
|
10797
10845
|
className = "",
|
|
@@ -10801,26 +10849,26 @@ function ProductGrid({
|
|
|
10801
10849
|
}) {
|
|
10802
10850
|
const { nbHits } = (0, import_react_instantsearch3.useStats)();
|
|
10803
10851
|
const { status, results } = (0, import_react_instantsearch3.useInstantSearch)();
|
|
10804
|
-
const [announcement, setAnnouncement] = (0,
|
|
10852
|
+
const [announcement, setAnnouncement] = (0, import_react49.useState)("");
|
|
10805
10853
|
const hitsCount = results?.hits?.length ?? 0;
|
|
10806
10854
|
const showSkeleton = hitsCount === 0 && status !== "error";
|
|
10807
|
-
(0,
|
|
10855
|
+
(0, import_react49.useEffect)(() => {
|
|
10808
10856
|
const timer = setTimeout(() => {
|
|
10809
10857
|
setAnnouncement(`${nbHits} ${nbHits === 1 ? "product" : "products"} found`);
|
|
10810
10858
|
}, 1e3);
|
|
10811
10859
|
return () => clearTimeout(timer);
|
|
10812
10860
|
}, [nbHits]);
|
|
10813
|
-
const HitComponent = (0,
|
|
10861
|
+
const HitComponent = (0, import_react49.useCallback)(({ hit }) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
10814
10862
|
ProductHitComponent,
|
|
10815
10863
|
{
|
|
10816
10864
|
hit,
|
|
10817
10865
|
variant
|
|
10818
10866
|
}
|
|
10819
10867
|
), [variant]);
|
|
10820
|
-
return /* @__PURE__ */ (0,
|
|
10821
|
-
/* @__PURE__ */ (0,
|
|
10822
|
-
showSkeleton && /* @__PURE__ */ (0,
|
|
10823
|
-
/* @__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)(
|
|
10824
10872
|
import_react_instantsearch3.Hits,
|
|
10825
10873
|
{
|
|
10826
10874
|
hitComponent: HitComponent,
|
|
@@ -10835,18 +10883,18 @@ function ProductGrid({
|
|
|
10835
10883
|
}
|
|
10836
10884
|
|
|
10837
10885
|
// src/composed/search/Filters.tsx
|
|
10838
|
-
var
|
|
10886
|
+
var import_react51 = require("react");
|
|
10839
10887
|
|
|
10840
10888
|
// src/composed/search/FiltersButton.tsx
|
|
10841
10889
|
var import_lucide_react4 = require("lucide-react");
|
|
10842
|
-
var
|
|
10890
|
+
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
10843
10891
|
var SlidersHorizontalIcon = import_lucide_react4.SlidersHorizontal;
|
|
10844
10892
|
function FiltersButton({
|
|
10845
10893
|
onClick,
|
|
10846
10894
|
className = "",
|
|
10847
10895
|
children = "Filters"
|
|
10848
10896
|
}) {
|
|
10849
|
-
return /* @__PURE__ */ (0,
|
|
10897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
|
|
10850
10898
|
Button,
|
|
10851
10899
|
{
|
|
10852
10900
|
variant: "field",
|
|
@@ -10854,8 +10902,8 @@ function FiltersButton({
|
|
|
10854
10902
|
className,
|
|
10855
10903
|
"aria-label": "Open filters",
|
|
10856
10904
|
children: [
|
|
10857
|
-
/* @__PURE__ */ (0,
|
|
10858
|
-
/* @__PURE__ */ (0,
|
|
10905
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(SlidersHorizontalIcon, { className: "w-4 h-4" }),
|
|
10906
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { children })
|
|
10859
10907
|
]
|
|
10860
10908
|
}
|
|
10861
10909
|
);
|
|
@@ -10864,15 +10912,15 @@ function FiltersButton({
|
|
|
10864
10912
|
// src/composed/search/FiltersDrawer.tsx
|
|
10865
10913
|
var import_react_instantsearch4 = require("react-instantsearch");
|
|
10866
10914
|
var import_lucide_react5 = require("lucide-react");
|
|
10867
|
-
var
|
|
10915
|
+
var import_react50 = require("react");
|
|
10868
10916
|
var Slider2 = __toESM(require("@radix-ui/react-slider"), 1);
|
|
10869
|
-
var
|
|
10917
|
+
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
10870
10918
|
var XIcon2 = import_lucide_react5.X;
|
|
10871
10919
|
function FiltersDrawer({ isOpen, onClose }) {
|
|
10872
|
-
const [showCounts, setShowCounts] = (0,
|
|
10920
|
+
const [showCounts, setShowCounts] = (0, import_react50.useState)(false);
|
|
10873
10921
|
const { nbHits } = (0, import_react_instantsearch4.useStats)();
|
|
10874
10922
|
const containerRef = useFocusTrap(isOpen, onClose);
|
|
10875
|
-
(0,
|
|
10923
|
+
(0, import_react50.useEffect)(() => {
|
|
10876
10924
|
if (isOpen) {
|
|
10877
10925
|
document.body.style.overflow = "hidden";
|
|
10878
10926
|
} else {
|
|
@@ -10882,7 +10930,7 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10882
10930
|
document.body.style.overflow = "";
|
|
10883
10931
|
};
|
|
10884
10932
|
}, [isOpen]);
|
|
10885
|
-
(0,
|
|
10933
|
+
(0, import_react50.useEffect)(() => {
|
|
10886
10934
|
const handleEscape = (e) => {
|
|
10887
10935
|
if (e.key === "Escape" && isOpen) {
|
|
10888
10936
|
onClose();
|
|
@@ -10891,8 +10939,8 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10891
10939
|
document.addEventListener("keydown", handleEscape);
|
|
10892
10940
|
return () => document.removeEventListener("keydown", handleEscape);
|
|
10893
10941
|
}, [isOpen, onClose]);
|
|
10894
|
-
return /* @__PURE__ */ (0,
|
|
10895
|
-
/* @__PURE__ */ (0,
|
|
10942
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(import_jsx_runtime67.Fragment, { children: [
|
|
10943
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
10896
10944
|
"div",
|
|
10897
10945
|
{
|
|
10898
10946
|
className: `fixed inset-0 bg-black/50 z-40 transition-opacity ${isOpen ? "opacity-100" : "opacity-0 pointer-events-none"}`,
|
|
@@ -10900,7 +10948,7 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10900
10948
|
"aria-hidden": "true"
|
|
10901
10949
|
}
|
|
10902
10950
|
),
|
|
10903
|
-
/* @__PURE__ */ (0,
|
|
10951
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
10904
10952
|
"div",
|
|
10905
10953
|
{
|
|
10906
10954
|
ref: containerRef,
|
|
@@ -10909,26 +10957,26 @@ function FiltersDrawer({ isOpen, onClose }) {
|
|
|
10909
10957
|
"aria-modal": "true",
|
|
10910
10958
|
"aria-labelledby": "filters-drawer-title",
|
|
10911
10959
|
children: [
|
|
10912
|
-
/* @__PURE__ */ (0,
|
|
10913
|
-
/* @__PURE__ */ (0,
|
|
10914
|
-
/* @__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)(
|
|
10915
10963
|
"button",
|
|
10916
10964
|
{
|
|
10917
10965
|
onClick: onClose,
|
|
10918
10966
|
className: "p-2 hover:bg-foreground/5 rounded-full transition-colors",
|
|
10919
10967
|
"aria-label": "Close filters",
|
|
10920
|
-
children: /* @__PURE__ */ (0,
|
|
10968
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(XIcon2, { className: "w-5 h-5" })
|
|
10921
10969
|
}
|
|
10922
10970
|
)
|
|
10923
10971
|
] }),
|
|
10924
|
-
/* @__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: [
|
|
10925
10973
|
nbHits.toLocaleString(),
|
|
10926
10974
|
" ",
|
|
10927
10975
|
nbHits === 1 ? "result" : "results"
|
|
10928
10976
|
] }) }),
|
|
10929
|
-
/* @__PURE__ */ (0,
|
|
10930
|
-
/* @__PURE__ */ (0,
|
|
10931
|
-
/* @__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, {})
|
|
10932
10980
|
] }) })
|
|
10933
10981
|
]
|
|
10934
10982
|
}
|
|
@@ -10944,9 +10992,9 @@ function TagsSection({
|
|
|
10944
10992
|
sortBy: ["count:desc", "name:asc"],
|
|
10945
10993
|
limit: 100
|
|
10946
10994
|
});
|
|
10947
|
-
const [isExpanded, setIsExpanded] = (0,
|
|
10948
|
-
return /* @__PURE__ */ (0,
|
|
10949
|
-
/* @__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)(
|
|
10950
10998
|
"button",
|
|
10951
10999
|
{
|
|
10952
11000
|
onClick: () => setIsExpanded(!isExpanded),
|
|
@@ -10954,8 +11002,8 @@ function TagsSection({
|
|
|
10954
11002
|
"aria-expanded": isExpanded,
|
|
10955
11003
|
"aria-controls": "tags-content",
|
|
10956
11004
|
children: [
|
|
10957
|
-
/* @__PURE__ */ (0,
|
|
10958
|
-
/* @__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)(
|
|
10959
11007
|
"svg",
|
|
10960
11008
|
{
|
|
10961
11009
|
className: `w-5 h-5 transition-transform text-foreground/40 group-hover:text-foreground/60 ${isExpanded ? "rotate-180" : ""}`,
|
|
@@ -10964,14 +11012,14 @@ function TagsSection({
|
|
|
10964
11012
|
stroke: "currentColor",
|
|
10965
11013
|
strokeWidth: 2.5,
|
|
10966
11014
|
"aria-hidden": "true",
|
|
10967
|
-
children: /* @__PURE__ */ (0,
|
|
11015
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
|
|
10968
11016
|
}
|
|
10969
11017
|
)
|
|
10970
11018
|
]
|
|
10971
11019
|
}
|
|
10972
11020
|
),
|
|
10973
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
10974
|
-
/* @__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)(
|
|
10975
11023
|
"button",
|
|
10976
11024
|
{
|
|
10977
11025
|
onClick: () => refine(item.value),
|
|
@@ -10982,15 +11030,15 @@ function TagsSection({
|
|
|
10982
11030
|
"aria-label": `${item.isRefined ? "Remove" : "Apply"} ${item.label} filter${showCounts ? ` (${item.count} products)` : ""}`,
|
|
10983
11031
|
"aria-pressed": item.isRefined,
|
|
10984
11032
|
children: [
|
|
10985
|
-
/* @__PURE__ */ (0,
|
|
10986
|
-
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 })
|
|
10987
11035
|
]
|
|
10988
11036
|
},
|
|
10989
11037
|
item.value
|
|
10990
11038
|
)) }),
|
|
10991
|
-
/* @__PURE__ */ (0,
|
|
10992
|
-
/* @__PURE__ */ (0,
|
|
10993
|
-
/* @__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)(
|
|
10994
11042
|
"button",
|
|
10995
11043
|
{
|
|
10996
11044
|
onClick: () => setShowCounts(!showCounts),
|
|
@@ -10998,7 +11046,7 @@ function TagsSection({
|
|
|
10998
11046
|
role: "switch",
|
|
10999
11047
|
"aria-checked": showCounts,
|
|
11000
11048
|
"aria-labelledby": "show-counts-label",
|
|
11001
|
-
children: /* @__PURE__ */ (0,
|
|
11049
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
11002
11050
|
"span",
|
|
11003
11051
|
{
|
|
11004
11052
|
className: `inline-block h-4 w-4 transform rounded-full bg-background shadow-sm transition-transform ${showCounts ? "translate-x-6" : "translate-x-1"}`,
|
|
@@ -11015,11 +11063,11 @@ function PriceSection() {
|
|
|
11015
11063
|
const { range, refine, start, canRefine } = (0, import_react_instantsearch4.useRange)({ attribute: "price" });
|
|
11016
11064
|
const rangeMin = typeof range.min === "number" && isFinite(range.min) ? range.min : 0;
|
|
11017
11065
|
const rangeMax = typeof range.max === "number" && isFinite(range.max) ? range.max : 15e3;
|
|
11018
|
-
const [localRange, setLocalRange] = (0,
|
|
11066
|
+
const [localRange, setLocalRange] = (0, import_react50.useState)([
|
|
11019
11067
|
typeof start?.[0] === "number" && isFinite(start[0]) ? start[0] : rangeMin,
|
|
11020
11068
|
typeof start?.[1] === "number" && isFinite(start[1]) ? start[1] : rangeMax
|
|
11021
11069
|
]);
|
|
11022
|
-
(0,
|
|
11070
|
+
(0, import_react50.useEffect)(() => {
|
|
11023
11071
|
if (start && Array.isArray(start)) {
|
|
11024
11072
|
setLocalRange([
|
|
11025
11073
|
typeof start[0] === "number" && isFinite(start[0]) ? start[0] : rangeMin,
|
|
@@ -11029,7 +11077,7 @@ function PriceSection() {
|
|
|
11029
11077
|
setLocalRange([rangeMin, rangeMax]);
|
|
11030
11078
|
}
|
|
11031
11079
|
}, [start, rangeMin, rangeMax]);
|
|
11032
|
-
const [isExpanded, setIsExpanded] = (0,
|
|
11080
|
+
const [isExpanded, setIsExpanded] = (0, import_react50.useState)(true);
|
|
11033
11081
|
if (!canRefine) {
|
|
11034
11082
|
return null;
|
|
11035
11083
|
}
|
|
@@ -11044,8 +11092,8 @@ function PriceSection() {
|
|
|
11044
11092
|
return `$${priceInDollars.toFixed(2)}`;
|
|
11045
11093
|
}
|
|
11046
11094
|
};
|
|
11047
|
-
return /* @__PURE__ */ (0,
|
|
11048
|
-
/* @__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)(
|
|
11049
11097
|
"button",
|
|
11050
11098
|
{
|
|
11051
11099
|
onClick: () => setIsExpanded(!isExpanded),
|
|
@@ -11053,8 +11101,8 @@ function PriceSection() {
|
|
|
11053
11101
|
"aria-expanded": isExpanded,
|
|
11054
11102
|
"aria-controls": "price-content",
|
|
11055
11103
|
children: [
|
|
11056
|
-
/* @__PURE__ */ (0,
|
|
11057
|
-
/* @__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)(
|
|
11058
11106
|
"svg",
|
|
11059
11107
|
{
|
|
11060
11108
|
className: `w-5 h-5 transition-transform text-foreground/40 group-hover:text-foreground/60 ${isExpanded ? "rotate-180" : ""}`,
|
|
@@ -11063,22 +11111,22 @@ function PriceSection() {
|
|
|
11063
11111
|
stroke: "currentColor",
|
|
11064
11112
|
strokeWidth: 2.5,
|
|
11065
11113
|
"aria-hidden": "true",
|
|
11066
|
-
children: /* @__PURE__ */ (0,
|
|
11114
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
|
|
11067
11115
|
}
|
|
11068
11116
|
)
|
|
11069
11117
|
]
|
|
11070
11118
|
}
|
|
11071
11119
|
),
|
|
11072
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
11073
|
-
/* @__PURE__ */ (0,
|
|
11074
|
-
/* @__PURE__ */ (0,
|
|
11075
|
-
/* @__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]) })
|
|
11076
11124
|
] }),
|
|
11077
|
-
/* @__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) => {
|
|
11078
11126
|
const totalBars = 19;
|
|
11079
11127
|
const barPrice = rangeMin + (rangeMax - rangeMin) / totalBars * i;
|
|
11080
11128
|
const isInRange = barPrice >= localRange[0] && barPrice <= localRange[1];
|
|
11081
|
-
return /* @__PURE__ */ (0,
|
|
11129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
11082
11130
|
"div",
|
|
11083
11131
|
{
|
|
11084
11132
|
className: `flex-1 rounded-t-sm transition-opacity ${isInRange ? "bg-foreground" : "bg-foreground/20"}`,
|
|
@@ -11087,7 +11135,7 @@ function PriceSection() {
|
|
|
11087
11135
|
i
|
|
11088
11136
|
);
|
|
11089
11137
|
}) }),
|
|
11090
|
-
/* @__PURE__ */ (0,
|
|
11138
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { style: { touchAction: "none" }, className: "my-6", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
11091
11139
|
Slider2.Root,
|
|
11092
11140
|
{
|
|
11093
11141
|
className: "relative flex w-full touch-none select-none items-center",
|
|
@@ -11105,8 +11153,8 @@ function PriceSection() {
|
|
|
11105
11153
|
step: 1,
|
|
11106
11154
|
minStepsBetweenThumbs: 1,
|
|
11107
11155
|
children: [
|
|
11108
|
-
/* @__PURE__ */ (0,
|
|
11109
|
-
/* @__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)(
|
|
11110
11158
|
Slider2.Thumb,
|
|
11111
11159
|
{
|
|
11112
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",
|
|
@@ -11120,7 +11168,7 @@ function PriceSection() {
|
|
|
11120
11168
|
"aria-valuetext": formatPrice2(localRange[0])
|
|
11121
11169
|
}
|
|
11122
11170
|
),
|
|
11123
|
-
/* @__PURE__ */ (0,
|
|
11171
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
11124
11172
|
Slider2.Thumb,
|
|
11125
11173
|
{
|
|
11126
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",
|
|
@@ -11137,10 +11185,10 @@ function PriceSection() {
|
|
|
11137
11185
|
]
|
|
11138
11186
|
}
|
|
11139
11187
|
) }),
|
|
11140
|
-
/* @__PURE__ */ (0,
|
|
11141
|
-
/* @__PURE__ */ (0,
|
|
11142
|
-
/* @__PURE__ */ (0,
|
|
11143
|
-
/* @__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)(
|
|
11144
11192
|
"input",
|
|
11145
11193
|
{
|
|
11146
11194
|
id: "price-min",
|
|
@@ -11158,9 +11206,9 @@ function PriceSection() {
|
|
|
11158
11206
|
}
|
|
11159
11207
|
)
|
|
11160
11208
|
] }),
|
|
11161
|
-
/* @__PURE__ */ (0,
|
|
11162
|
-
/* @__PURE__ */ (0,
|
|
11163
|
-
/* @__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)(
|
|
11164
11212
|
"input",
|
|
11165
11213
|
{
|
|
11166
11214
|
id: "price-max",
|
|
@@ -11184,11 +11232,11 @@ function PriceSection() {
|
|
|
11184
11232
|
}
|
|
11185
11233
|
|
|
11186
11234
|
// src/composed/search/Filters.tsx
|
|
11187
|
-
var
|
|
11235
|
+
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
11188
11236
|
function Filters({ buttonClassName, buttonText }) {
|
|
11189
|
-
const [isOpen, setIsOpen] = (0,
|
|
11190
|
-
return /* @__PURE__ */ (0,
|
|
11191
|
-
/* @__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)(
|
|
11192
11240
|
FiltersButton,
|
|
11193
11241
|
{
|
|
11194
11242
|
onClick: () => setIsOpen(true),
|
|
@@ -11196,14 +11244,14 @@ function Filters({ buttonClassName, buttonText }) {
|
|
|
11196
11244
|
children: buttonText
|
|
11197
11245
|
}
|
|
11198
11246
|
),
|
|
11199
|
-
/* @__PURE__ */ (0,
|
|
11247
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(FiltersDrawer, { isOpen, onClose: () => setIsOpen(false) })
|
|
11200
11248
|
] });
|
|
11201
11249
|
}
|
|
11202
11250
|
|
|
11203
11251
|
// src/composed/search/CurrentRefinements.tsx
|
|
11204
11252
|
var import_react_instantsearch5 = require("react-instantsearch");
|
|
11205
11253
|
var import_lucide_react6 = require("lucide-react");
|
|
11206
|
-
var
|
|
11254
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
11207
11255
|
var XIcon3 = import_lucide_react6.X;
|
|
11208
11256
|
function CurrentRefinements() {
|
|
11209
11257
|
const { items, refine } = (0, import_react_instantsearch5.useCurrentRefinements)();
|
|
@@ -11249,15 +11297,15 @@ function CurrentRefinements() {
|
|
|
11249
11297
|
if (allRefinements.length === 0) {
|
|
11250
11298
|
return null;
|
|
11251
11299
|
}
|
|
11252
|
-
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)(
|
|
11253
11301
|
"button",
|
|
11254
11302
|
{
|
|
11255
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",
|
|
11256
11304
|
onClick: () => refinement.refine(),
|
|
11257
11305
|
"aria-label": `Remove filter: ${refinement.displayLabel}`,
|
|
11258
11306
|
children: [
|
|
11259
|
-
/* @__PURE__ */ (0,
|
|
11260
|
-
/* @__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" })
|
|
11261
11309
|
]
|
|
11262
11310
|
},
|
|
11263
11311
|
`${refinement.attribute}-${refinement.value}-${index}`
|
|
@@ -11281,12 +11329,12 @@ var FACET_SECTIONS = [
|
|
|
11281
11329
|
];
|
|
11282
11330
|
|
|
11283
11331
|
// src/composed/zoom/ResponsiveZoom.tsx
|
|
11284
|
-
var
|
|
11332
|
+
var import_react54 = require("react");
|
|
11285
11333
|
|
|
11286
11334
|
// src/composed/zoom/ZoomOverlay.tsx
|
|
11287
|
-
var
|
|
11335
|
+
var import_react52 = require("react");
|
|
11288
11336
|
var import_lucide_react7 = require("lucide-react");
|
|
11289
|
-
var
|
|
11337
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
11290
11338
|
var PlusIcon2 = import_lucide_react7.Plus;
|
|
11291
11339
|
var MinusIcon2 = import_lucide_react7.Minus;
|
|
11292
11340
|
function ZoomOverlay({
|
|
@@ -11298,13 +11346,13 @@ function ZoomOverlay({
|
|
|
11298
11346
|
className,
|
|
11299
11347
|
style
|
|
11300
11348
|
}) {
|
|
11301
|
-
const [zoomedImageIndex, setZoomedImageIndex] = (0,
|
|
11302
|
-
const [zoomOrigin, setZoomOrigin] = (0,
|
|
11303
|
-
const [hoveredImageIndex, setHoveredImageIndex] = (0,
|
|
11304
|
-
const [cursorPos, setCursorPos] = (0,
|
|
11305
|
-
const [announcement, setAnnouncement] = (0,
|
|
11306
|
-
const [isZooming, setIsZooming] = (0,
|
|
11307
|
-
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)(
|
|
11308
11356
|
(e) => {
|
|
11309
11357
|
e.stopPropagation();
|
|
11310
11358
|
if (isLargeTouchDevice && onEnhancedViewer) {
|
|
@@ -11329,7 +11377,7 @@ function ZoomOverlay({
|
|
|
11329
11377
|
},
|
|
11330
11378
|
[zoomedImageIndex, isLargeTouchDevice, onEnhancedViewer, imageIndex]
|
|
11331
11379
|
);
|
|
11332
|
-
const handleZoomMouseMove = (0,
|
|
11380
|
+
const handleZoomMouseMove = (0, import_react52.useCallback)(
|
|
11333
11381
|
(e) => {
|
|
11334
11382
|
setCursorPos({ x: e.clientX, y: e.clientY });
|
|
11335
11383
|
if (zoomedImageIndex === imageIndex) {
|
|
@@ -11345,9 +11393,9 @@ function ZoomOverlay({
|
|
|
11345
11393
|
const isZoomed = zoomedImageIndex === imageIndex;
|
|
11346
11394
|
const isHovered = hoveredImageIndex === imageIndex;
|
|
11347
11395
|
const cursorStyle = isLargeTouchDevice ? "pointer" : isTouchDevice ? "default" : "none";
|
|
11348
|
-
return /* @__PURE__ */ (0,
|
|
11349
|
-
/* @__PURE__ */ (0,
|
|
11350
|
-
/* @__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)(
|
|
11351
11399
|
"div",
|
|
11352
11400
|
{
|
|
11353
11401
|
className,
|
|
@@ -11355,7 +11403,7 @@ function ZoomOverlay({
|
|
|
11355
11403
|
...style,
|
|
11356
11404
|
position: "relative"
|
|
11357
11405
|
},
|
|
11358
|
-
children: /* @__PURE__ */ (0,
|
|
11406
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11359
11407
|
"div",
|
|
11360
11408
|
{
|
|
11361
11409
|
style: {
|
|
@@ -11378,7 +11426,7 @@ function ZoomOverlay({
|
|
|
11378
11426
|
handleZoomClick(e);
|
|
11379
11427
|
}
|
|
11380
11428
|
},
|
|
11381
|
-
children: /* @__PURE__ */ (0,
|
|
11429
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11382
11430
|
"div",
|
|
11383
11431
|
{
|
|
11384
11432
|
style: {
|
|
@@ -11394,7 +11442,7 @@ function ZoomOverlay({
|
|
|
11394
11442
|
)
|
|
11395
11443
|
}
|
|
11396
11444
|
),
|
|
11397
|
-
isHovered && !isTouchDevice && /* @__PURE__ */ (0,
|
|
11445
|
+
isHovered && !isTouchDevice && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11398
11446
|
"div",
|
|
11399
11447
|
{
|
|
11400
11448
|
className: "fixed pointer-events-none z-50 hidden md:block",
|
|
@@ -11404,7 +11452,7 @@ function ZoomOverlay({
|
|
|
11404
11452
|
transform: "translate(-50%, -50%)"
|
|
11405
11453
|
},
|
|
11406
11454
|
"aria-hidden": "true",
|
|
11407
|
-
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)(
|
|
11408
11456
|
MinusIcon2,
|
|
11409
11457
|
{
|
|
11410
11458
|
size: 20,
|
|
@@ -11412,7 +11460,7 @@ function ZoomOverlay({
|
|
|
11412
11460
|
strokeWidth: 1.5,
|
|
11413
11461
|
"aria-hidden": "true"
|
|
11414
11462
|
}
|
|
11415
|
-
) : /* @__PURE__ */ (0,
|
|
11463
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
11416
11464
|
PlusIcon2,
|
|
11417
11465
|
{
|
|
11418
11466
|
size: 20,
|
|
@@ -11427,11 +11475,11 @@ function ZoomOverlay({
|
|
|
11427
11475
|
}
|
|
11428
11476
|
|
|
11429
11477
|
// src/composed/zoom/EnhancedImageViewer.tsx
|
|
11430
|
-
var
|
|
11478
|
+
var import_react53 = require("react");
|
|
11431
11479
|
var import_react_dom3 = require("react-dom");
|
|
11432
11480
|
var import_react_zoom_pan_pinch = require("react-zoom-pan-pinch");
|
|
11433
11481
|
var import_lucide_react8 = require("lucide-react");
|
|
11434
|
-
var
|
|
11482
|
+
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
11435
11483
|
var TransformWrapper = import_react_zoom_pan_pinch.TransformWrapper;
|
|
11436
11484
|
var TransformComponent = import_react_zoom_pan_pinch.TransformComponent;
|
|
11437
11485
|
var EnhancedImageViewer = ({
|
|
@@ -11442,17 +11490,17 @@ var EnhancedImageViewer = ({
|
|
|
11442
11490
|
onIndexChange,
|
|
11443
11491
|
currentIndex: propCurrentIndex
|
|
11444
11492
|
}) => {
|
|
11445
|
-
const [isMounted, setIsMounted] = (0,
|
|
11446
|
-
const [isClient, setIsClient] = (0,
|
|
11447
|
-
const [scale, setScale] = (0,
|
|
11448
|
-
const [cropDimensions, setCropDimensions] = (0,
|
|
11449
|
-
const [currentZoomScale, setCurrentZoomScale] = (0,
|
|
11450
|
-
const imgRef = (0,
|
|
11451
|
-
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)(
|
|
11452
11500
|
null
|
|
11453
11501
|
);
|
|
11454
|
-
const isSwipingRef = (0,
|
|
11455
|
-
const calculateScale = (0,
|
|
11502
|
+
const isSwipingRef = (0, import_react53.useRef)(false);
|
|
11503
|
+
const calculateScale = (0, import_react53.useCallback)(() => {
|
|
11456
11504
|
const viewport = {
|
|
11457
11505
|
width: window.innerWidth,
|
|
11458
11506
|
height: window.innerHeight
|
|
@@ -11464,10 +11512,10 @@ var EnhancedImageViewer = ({
|
|
|
11464
11512
|
max: 8
|
|
11465
11513
|
});
|
|
11466
11514
|
}, []);
|
|
11467
|
-
const handleImageLoad = (0,
|
|
11515
|
+
const handleImageLoad = (0, import_react53.useCallback)(() => {
|
|
11468
11516
|
calculateScale();
|
|
11469
11517
|
}, [calculateScale]);
|
|
11470
|
-
(0,
|
|
11518
|
+
(0, import_react53.useLayoutEffect)(() => {
|
|
11471
11519
|
setIsClient(true);
|
|
11472
11520
|
setIsMounted(true);
|
|
11473
11521
|
document.body.style.overflow = "hidden";
|
|
@@ -11476,17 +11524,17 @@ var EnhancedImageViewer = ({
|
|
|
11476
11524
|
document.body.style.overflow = "";
|
|
11477
11525
|
};
|
|
11478
11526
|
}, [calculateScale]);
|
|
11479
|
-
(0,
|
|
11527
|
+
(0, import_react53.useEffect)(() => {
|
|
11480
11528
|
calculateScale();
|
|
11481
11529
|
}, [calculateScale]);
|
|
11482
|
-
(0,
|
|
11530
|
+
(0, import_react53.useEffect)(() => {
|
|
11483
11531
|
const handleResize = () => {
|
|
11484
11532
|
calculateScale();
|
|
11485
11533
|
};
|
|
11486
11534
|
window.addEventListener("resize", handleResize);
|
|
11487
11535
|
return () => window.removeEventListener("resize", handleResize);
|
|
11488
11536
|
}, [calculateScale]);
|
|
11489
|
-
(0,
|
|
11537
|
+
(0, import_react53.useEffect)(() => {
|
|
11490
11538
|
const handleKeyDown = (e) => {
|
|
11491
11539
|
if (e.key === "Escape") {
|
|
11492
11540
|
onClose();
|
|
@@ -11512,7 +11560,7 @@ var EnhancedImageViewer = ({
|
|
|
11512
11560
|
document.addEventListener("keydown", handleKeyDown);
|
|
11513
11561
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
11514
11562
|
}, [onClose, imageUrl, images, onIndexChange, propCurrentIndex]);
|
|
11515
|
-
const handleSwipeNavigation = (0,
|
|
11563
|
+
const handleSwipeNavigation = (0, import_react53.useCallback)(
|
|
11516
11564
|
(direction) => {
|
|
11517
11565
|
let currentIndex = propCurrentIndex !== void 0 ? propCurrentIndex : -1;
|
|
11518
11566
|
if (currentIndex === -1) {
|
|
@@ -11533,7 +11581,7 @@ var EnhancedImageViewer = ({
|
|
|
11533
11581
|
},
|
|
11534
11582
|
[propCurrentIndex, images, imageUrl, onIndexChange]
|
|
11535
11583
|
);
|
|
11536
|
-
const handleTouchStart = (0,
|
|
11584
|
+
const handleTouchStart = (0, import_react53.useCallback)(
|
|
11537
11585
|
(e) => {
|
|
11538
11586
|
const isAtInitialZoom = Math.abs(currentZoomScale - scale.initial) < 0.1;
|
|
11539
11587
|
if (!isAtInitialZoom) return;
|
|
@@ -11547,7 +11595,7 @@ var EnhancedImageViewer = ({
|
|
|
11547
11595
|
},
|
|
11548
11596
|
[currentZoomScale, scale.initial]
|
|
11549
11597
|
);
|
|
11550
|
-
const handleTouchEnd = (0,
|
|
11598
|
+
const handleTouchEnd = (0, import_react53.useCallback)(
|
|
11551
11599
|
(e) => {
|
|
11552
11600
|
if (!touchStartRef.current) return;
|
|
11553
11601
|
const touch = e.changedTouches[0];
|
|
@@ -11571,12 +11619,12 @@ var EnhancedImageViewer = ({
|
|
|
11571
11619
|
);
|
|
11572
11620
|
if (!isMounted || !isClient) {
|
|
11573
11621
|
return (0, import_react_dom3.createPortal)(
|
|
11574
|
-
/* @__PURE__ */ (0,
|
|
11622
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11575
11623
|
"div",
|
|
11576
11624
|
{
|
|
11577
11625
|
className: "fixed inset-0 bg-black flex items-center justify-center",
|
|
11578
11626
|
style: { zIndex: 999999 },
|
|
11579
|
-
children: /* @__PURE__ */ (0,
|
|
11627
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11580
11628
|
"div",
|
|
11581
11629
|
{
|
|
11582
11630
|
style: {
|
|
@@ -11592,7 +11640,7 @@ var EnhancedImageViewer = ({
|
|
|
11592
11640
|
);
|
|
11593
11641
|
}
|
|
11594
11642
|
return (0, import_react_dom3.createPortal)(
|
|
11595
|
-
/* @__PURE__ */ (0,
|
|
11643
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
|
|
11596
11644
|
"div",
|
|
11597
11645
|
{
|
|
11598
11646
|
className: "fixed inset-0 bg-black flex items-center justify-center",
|
|
@@ -11601,7 +11649,7 @@ var EnhancedImageViewer = ({
|
|
|
11601
11649
|
"aria-modal": "true",
|
|
11602
11650
|
"aria-label": "Image viewer",
|
|
11603
11651
|
children: [
|
|
11604
|
-
/* @__PURE__ */ (0,
|
|
11652
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11605
11653
|
"button",
|
|
11606
11654
|
{
|
|
11607
11655
|
onClick: (e) => {
|
|
@@ -11627,10 +11675,10 @@ var EnhancedImageViewer = ({
|
|
|
11627
11675
|
touchAction: "manipulation",
|
|
11628
11676
|
marginBottom: "env(safe-area-inset-bottom, 0px)"
|
|
11629
11677
|
},
|
|
11630
|
-
children: /* @__PURE__ */ (0,
|
|
11678
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react8.X, { className: "w-7 h-7", strokeWidth: 2.5 })
|
|
11631
11679
|
}
|
|
11632
11680
|
),
|
|
11633
|
-
/* @__PURE__ */ (0,
|
|
11681
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11634
11682
|
TransformWrapper,
|
|
11635
11683
|
{
|
|
11636
11684
|
initialScale: scale.initial,
|
|
@@ -11664,7 +11712,7 @@ var EnhancedImageViewer = ({
|
|
|
11664
11712
|
onTransformed: (ref) => {
|
|
11665
11713
|
setCurrentZoomScale(ref.state.scale);
|
|
11666
11714
|
},
|
|
11667
|
-
children: ({ zoomIn, zoomOut, resetTransform }) => /* @__PURE__ */ (0,
|
|
11715
|
+
children: ({ zoomIn, zoomOut, resetTransform }) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
|
|
11668
11716
|
"div",
|
|
11669
11717
|
{
|
|
11670
11718
|
style: {
|
|
@@ -11677,14 +11725,14 @@ var EnhancedImageViewer = ({
|
|
|
11677
11725
|
onTouchStart: handleTouchStart,
|
|
11678
11726
|
onTouchEnd: handleTouchEnd,
|
|
11679
11727
|
children: [
|
|
11680
|
-
/* @__PURE__ */ (0,
|
|
11728
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11681
11729
|
TransformComponent,
|
|
11682
11730
|
{
|
|
11683
11731
|
wrapperStyle: {
|
|
11684
11732
|
width: "100%",
|
|
11685
11733
|
height: "100%"
|
|
11686
11734
|
},
|
|
11687
|
-
children: /* @__PURE__ */ (0,
|
|
11735
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11688
11736
|
"div",
|
|
11689
11737
|
{
|
|
11690
11738
|
style: {
|
|
@@ -11695,8 +11743,8 @@ var EnhancedImageViewer = ({
|
|
|
11695
11743
|
alignItems: "center",
|
|
11696
11744
|
justifyContent: "center"
|
|
11697
11745
|
},
|
|
11698
|
-
children: /* @__PURE__ */ (0,
|
|
11699
|
-
|
|
11746
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11747
|
+
SafeImg,
|
|
11700
11748
|
{
|
|
11701
11749
|
ref: imgRef,
|
|
11702
11750
|
src: imageUrl,
|
|
@@ -11716,8 +11764,8 @@ var EnhancedImageViewer = ({
|
|
|
11716
11764
|
)
|
|
11717
11765
|
}
|
|
11718
11766
|
),
|
|
11719
|
-
/* @__PURE__ */ (0,
|
|
11720
|
-
/* @__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: (() => {
|
|
11721
11769
|
let currentIndex = propCurrentIndex !== void 0 ? propCurrentIndex : -1;
|
|
11722
11770
|
if (currentIndex === -1) {
|
|
11723
11771
|
currentIndex = images.findIndex(
|
|
@@ -11750,8 +11798,8 @@ var EnhancedImageViewer = ({
|
|
|
11750
11798
|
};
|
|
11751
11799
|
const nextIndex = findNextAvailableIndex(currentIndex, 1);
|
|
11752
11800
|
const prevIndex = findNextAvailableIndex(currentIndex, -1);
|
|
11753
|
-
return /* @__PURE__ */ (0,
|
|
11754
|
-
/* @__PURE__ */ (0,
|
|
11801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_jsx_runtime71.Fragment, { children: [
|
|
11802
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11755
11803
|
"button",
|
|
11756
11804
|
{
|
|
11757
11805
|
onClick: () => {
|
|
@@ -11764,7 +11812,7 @@ var EnhancedImageViewer = ({
|
|
|
11764
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"}`,
|
|
11765
11813
|
style: { touchAction: "manipulation" },
|
|
11766
11814
|
"aria-label": "Previous image",
|
|
11767
|
-
children: /* @__PURE__ */ (0,
|
|
11815
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11768
11816
|
"svg",
|
|
11769
11817
|
{
|
|
11770
11818
|
className: "w-4 h-4",
|
|
@@ -11772,7 +11820,7 @@ var EnhancedImageViewer = ({
|
|
|
11772
11820
|
stroke: "currentColor",
|
|
11773
11821
|
viewBox: "0 0 24 24",
|
|
11774
11822
|
"aria-hidden": "true",
|
|
11775
|
-
children: /* @__PURE__ */ (0,
|
|
11823
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11776
11824
|
"path",
|
|
11777
11825
|
{
|
|
11778
11826
|
strokeLinecap: "round",
|
|
@@ -11785,7 +11833,7 @@ var EnhancedImageViewer = ({
|
|
|
11785
11833
|
)
|
|
11786
11834
|
}
|
|
11787
11835
|
),
|
|
11788
|
-
/* @__PURE__ */ (0,
|
|
11836
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11789
11837
|
"button",
|
|
11790
11838
|
{
|
|
11791
11839
|
onClick: () => {
|
|
@@ -11798,7 +11846,7 @@ var EnhancedImageViewer = ({
|
|
|
11798
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"}`,
|
|
11799
11847
|
style: { touchAction: "manipulation" },
|
|
11800
11848
|
"aria-label": "Next image",
|
|
11801
|
-
children: /* @__PURE__ */ (0,
|
|
11849
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11802
11850
|
"svg",
|
|
11803
11851
|
{
|
|
11804
11852
|
className: "w-4 h-4",
|
|
@@ -11806,7 +11854,7 @@ var EnhancedImageViewer = ({
|
|
|
11806
11854
|
stroke: "currentColor",
|
|
11807
11855
|
viewBox: "0 0 24 24",
|
|
11808
11856
|
"aria-hidden": "true",
|
|
11809
|
-
children: /* @__PURE__ */ (0,
|
|
11857
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11810
11858
|
"path",
|
|
11811
11859
|
{
|
|
11812
11860
|
strokeLinecap: "round",
|
|
@@ -11821,7 +11869,7 @@ var EnhancedImageViewer = ({
|
|
|
11821
11869
|
)
|
|
11822
11870
|
] });
|
|
11823
11871
|
})() }),
|
|
11824
|
-
/* @__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: (() => {
|
|
11825
11873
|
const total = Math.max(images.length, 1);
|
|
11826
11874
|
const current = propCurrentIndex !== void 0 ? Math.min(propCurrentIndex + 1, total) : 1;
|
|
11827
11875
|
return `${current} / ${total}`;
|
|
@@ -11833,7 +11881,7 @@ var EnhancedImageViewer = ({
|
|
|
11833
11881
|
},
|
|
11834
11882
|
`${scale.initial}-${scale.min}-${scale.max}`
|
|
11835
11883
|
),
|
|
11836
|
-
/* @__PURE__ */ (0,
|
|
11884
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
11837
11885
|
"div",
|
|
11838
11886
|
{
|
|
11839
11887
|
className: "absolute inset-0 bg-black",
|
|
@@ -11852,7 +11900,7 @@ var EnhancedImageViewer = ({
|
|
|
11852
11900
|
};
|
|
11853
11901
|
|
|
11854
11902
|
// src/composed/zoom/ResponsiveZoom.tsx
|
|
11855
|
-
var
|
|
11903
|
+
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
11856
11904
|
function ResponsiveZoom({
|
|
11857
11905
|
imageIndex,
|
|
11858
11906
|
children,
|
|
@@ -11862,11 +11910,11 @@ function ResponsiveZoom({
|
|
|
11862
11910
|
imageUrl,
|
|
11863
11911
|
alt = "Product image"
|
|
11864
11912
|
}) {
|
|
11865
|
-
const [isTouchDevice, setIsTouchDevice] = (0,
|
|
11866
|
-
const [showEnhancedViewer, setShowEnhancedViewer] = (0,
|
|
11867
|
-
const [viewerIndex, setViewerIndex] = (0,
|
|
11868
|
-
const [currentImageUrl, setCurrentImageUrl] = (0,
|
|
11869
|
-
(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)(() => {
|
|
11870
11918
|
const checkDeviceType = () => {
|
|
11871
11919
|
const hasTouch = "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
11872
11920
|
setIsTouchDevice(hasTouch);
|
|
@@ -11893,8 +11941,8 @@ function ResponsiveZoom({
|
|
|
11893
11941
|
}
|
|
11894
11942
|
}
|
|
11895
11943
|
};
|
|
11896
|
-
return /* @__PURE__ */ (0,
|
|
11897
|
-
isTouchDevice ? /* @__PURE__ */ (0,
|
|
11944
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
|
|
11945
|
+
isTouchDevice ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
11898
11946
|
"div",
|
|
11899
11947
|
{
|
|
11900
11948
|
className,
|
|
@@ -11911,7 +11959,7 @@ function ResponsiveZoom({
|
|
|
11911
11959
|
},
|
|
11912
11960
|
children
|
|
11913
11961
|
}
|
|
11914
|
-
) : /* @__PURE__ */ (0,
|
|
11962
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
11915
11963
|
ZoomOverlay,
|
|
11916
11964
|
{
|
|
11917
11965
|
imageIndex,
|
|
@@ -11922,7 +11970,7 @@ function ResponsiveZoom({
|
|
|
11922
11970
|
children
|
|
11923
11971
|
}
|
|
11924
11972
|
),
|
|
11925
|
-
showEnhancedViewer && isTouchDevice && currentImageUrl && /* @__PURE__ */ (0,
|
|
11973
|
+
showEnhancedViewer && isTouchDevice && currentImageUrl && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
11926
11974
|
EnhancedImageViewer,
|
|
11927
11975
|
{
|
|
11928
11976
|
imageUrl: currentImageUrl,
|
|
@@ -11945,9 +11993,32 @@ function ResponsiveZoom({
|
|
|
11945
11993
|
}
|
|
11946
11994
|
|
|
11947
11995
|
// src/composed/carousels/MobileProductCarousel.tsx
|
|
11948
|
-
var
|
|
11949
|
-
var
|
|
11950
|
-
|
|
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({
|
|
11951
12022
|
images,
|
|
11952
12023
|
currentIndex = 0,
|
|
11953
12024
|
onIndexChange,
|
|
@@ -11962,42 +12033,42 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
11962
12033
|
mockupWidth,
|
|
11963
12034
|
onMockupUrlGenerated
|
|
11964
12035
|
}) {
|
|
11965
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
11966
|
-
const [touchStart, setTouchStart] = (0,
|
|
12036
|
+
const [activeIndex, setActiveIndex] = (0, import_react55.useState)(currentIndex);
|
|
12037
|
+
const [touchStart, setTouchStart] = (0, import_react55.useState)(
|
|
11967
12038
|
null
|
|
11968
12039
|
);
|
|
11969
|
-
const [touchEnd, setTouchEnd] = (0,
|
|
12040
|
+
const [touchEnd, setTouchEnd] = (0, import_react55.useState)(
|
|
11970
12041
|
null
|
|
11971
12042
|
);
|
|
11972
|
-
const [showImageViewer, setShowImageViewer] = (0,
|
|
11973
|
-
const [viewerKey, setViewerKey] = (0,
|
|
11974
|
-
const [isDragging, setIsDragging] = (0,
|
|
11975
|
-
const [dragOffset, setDragOffset] = (0,
|
|
11976
|
-
const [isTransitioning, setIsTransitioning] = (0,
|
|
11977
|
-
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)(
|
|
11978
12049
|
null
|
|
11979
12050
|
);
|
|
11980
|
-
const [isPeeking, setIsPeeking] = (0,
|
|
11981
|
-
const [isPeekReturning, setIsPeekReturning] = (0,
|
|
11982
|
-
const carouselRef = (0,
|
|
11983
|
-
const indicatorRef = (0,
|
|
11984
|
-
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)(
|
|
11985
12056
|
null
|
|
11986
12057
|
);
|
|
11987
|
-
const horizontalGestureRef = (0,
|
|
11988
|
-
const hasShownPeekRef = (0,
|
|
11989
|
-
const hasSwipedThisSessionRef = (0,
|
|
11990
|
-
const generatedUrlsRef = (0,
|
|
11991
|
-
const prevArtworkSrcRef = (0,
|
|
11992
|
-
(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)(() => {
|
|
11993
12064
|
if (currentArtwork?.src !== prevArtworkSrcRef.current) {
|
|
11994
12065
|
generatedUrlsRef.current.clear();
|
|
11995
12066
|
prevArtworkSrcRef.current = currentArtwork?.src;
|
|
11996
12067
|
}
|
|
11997
12068
|
}, [currentArtwork?.src]);
|
|
11998
|
-
const onMockupUrlGeneratedRef = (0,
|
|
12069
|
+
const onMockupUrlGeneratedRef = (0, import_react55.useRef)(onMockupUrlGenerated);
|
|
11999
12070
|
onMockupUrlGeneratedRef.current = onMockupUrlGenerated;
|
|
12000
|
-
const handleUrlGenerated = (0,
|
|
12071
|
+
const handleUrlGenerated = (0, import_react55.useCallback)((mockupId, url) => {
|
|
12001
12072
|
generatedUrlsRef.current.set(mockupId, url);
|
|
12002
12073
|
onMockupUrlGeneratedRef.current?.(mockupId, url);
|
|
12003
12074
|
}, []);
|
|
@@ -12005,24 +12076,24 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12005
12076
|
const shouldHideDots = stickyHeroContext?.shouldHideDots ?? false;
|
|
12006
12077
|
const priorityContext = useMockupPriorityOptional();
|
|
12007
12078
|
const realtimeContext = useRealtimeOptional();
|
|
12008
|
-
const [urlUpdateCounter, setUrlUpdateCounter] = (0,
|
|
12009
|
-
(0,
|
|
12079
|
+
const [urlUpdateCounter, setUrlUpdateCounter] = (0, import_react55.useState)(0);
|
|
12080
|
+
(0, import_react55.useEffect)(() => {
|
|
12010
12081
|
if (!realtimeContext?.subscribeMockupResults) return;
|
|
12011
12082
|
const unsubscribe = realtimeContext.subscribeMockupResults(() => {
|
|
12012
12083
|
setUrlUpdateCounter((c) => c + 1);
|
|
12013
12084
|
});
|
|
12014
12085
|
return unsubscribe;
|
|
12015
12086
|
}, [realtimeContext?.subscribeMockupResults]);
|
|
12016
|
-
const mockupIds = (0,
|
|
12087
|
+
const mockupIds = (0, import_react55.useMemo)(() => {
|
|
12017
12088
|
return images.filter((img) => img.isRealMockup && img.mockupId).map((img) => img.mockupId);
|
|
12018
12089
|
}, [images]);
|
|
12019
|
-
const realtimeMockupUrls = (0,
|
|
12090
|
+
const realtimeMockupUrls = (0, import_react55.useMemo)(() => {
|
|
12020
12091
|
if (!realtimeContext?.getMockupUrls || mockupIds.length === 0) {
|
|
12021
12092
|
return {};
|
|
12022
12093
|
}
|
|
12023
12094
|
return realtimeContext.getMockupUrls(mockupIds);
|
|
12024
12095
|
}, [realtimeContext?.getMockupUrls, mockupIds, urlUpdateCounter]);
|
|
12025
|
-
const imagesWithRealtimeUrls = (0,
|
|
12096
|
+
const imagesWithRealtimeUrls = (0, import_react55.useMemo)(() => {
|
|
12026
12097
|
return images.map((img) => {
|
|
12027
12098
|
if (img.isRealMockup && img.mockupId && realtimeMockupUrls[img.mockupId]) {
|
|
12028
12099
|
return {
|
|
@@ -12034,10 +12105,10 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12034
12105
|
});
|
|
12035
12106
|
}, [images, realtimeMockupUrls]);
|
|
12036
12107
|
const minSwipeDistance = 50;
|
|
12037
|
-
(0,
|
|
12108
|
+
(0, import_react55.useEffect)(() => {
|
|
12038
12109
|
setActiveIndex(currentIndex);
|
|
12039
12110
|
}, [currentIndex]);
|
|
12040
|
-
(0,
|
|
12111
|
+
(0, import_react55.useEffect)(() => {
|
|
12041
12112
|
if (!priorityContext) return;
|
|
12042
12113
|
const realMockups = images.map((img, idx) => ({ img, originalIdx: idx })).filter(({ img }) => img.isRealMockup && img.mockupId);
|
|
12043
12114
|
const mockupIdsList = realMockups.map(({ img }) => img.mockupId);
|
|
@@ -12065,7 +12136,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12065
12136
|
priorityContext.clearMobileCarouselMode?.();
|
|
12066
12137
|
};
|
|
12067
12138
|
}, [priorityContext, activeIndex, images]);
|
|
12068
|
-
(0,
|
|
12139
|
+
(0, import_react55.useEffect)(() => {
|
|
12069
12140
|
const indicator = indicatorRef.current;
|
|
12070
12141
|
if (!indicator) return;
|
|
12071
12142
|
let ticking = false;
|
|
@@ -12106,7 +12177,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12106
12177
|
}, []);
|
|
12107
12178
|
const SWIPE_TRACKING_KEY = "carousel-swipe-tracking";
|
|
12108
12179
|
const PDP_VIEWS_BEFORE_PEEK = 10;
|
|
12109
|
-
const getSwipeTracking = (0,
|
|
12180
|
+
const getSwipeTracking = (0, import_react55.useCallback)(() => {
|
|
12110
12181
|
try {
|
|
12111
12182
|
const stored = localStorage.getItem(SWIPE_TRACKING_KEY);
|
|
12112
12183
|
if (stored) {
|
|
@@ -12116,7 +12187,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12116
12187
|
}
|
|
12117
12188
|
return { viewsWithoutSwipe: 0, hasEverSwiped: false };
|
|
12118
12189
|
}, []);
|
|
12119
|
-
const recordSwipe = (0,
|
|
12190
|
+
const recordSwipe = (0, import_react55.useCallback)(() => {
|
|
12120
12191
|
if (hasSwipedThisSessionRef.current) return;
|
|
12121
12192
|
hasSwipedThisSessionRef.current = true;
|
|
12122
12193
|
try {
|
|
@@ -12130,7 +12201,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12130
12201
|
} catch {
|
|
12131
12202
|
}
|
|
12132
12203
|
}, []);
|
|
12133
|
-
(0,
|
|
12204
|
+
(0, import_react55.useEffect)(() => {
|
|
12134
12205
|
if (!enablePeekAnimation || images.length <= 1) return;
|
|
12135
12206
|
const tracking = getSwipeTracking();
|
|
12136
12207
|
const newViewCount = tracking.viewsWithoutSwipe + 1;
|
|
@@ -12171,14 +12242,14 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12171
12242
|
clearTimeout(clearTimeout_);
|
|
12172
12243
|
};
|
|
12173
12244
|
}, [images.length, getSwipeTracking, enablePeekAnimation]);
|
|
12174
|
-
const wasTapRef = (0,
|
|
12175
|
-
const handleImageTap = (0,
|
|
12245
|
+
const wasTapRef = (0, import_react55.useRef)(false);
|
|
12246
|
+
const handleImageTap = (0, import_react55.useCallback)(() => {
|
|
12176
12247
|
if (!enableZoom) return;
|
|
12177
12248
|
setViewerKey((prev) => prev + 1);
|
|
12178
12249
|
setShowImageViewer(true);
|
|
12179
12250
|
onZoomChange?.(true);
|
|
12180
12251
|
}, [enableZoom, onZoomChange]);
|
|
12181
|
-
const calculateDragOffset = (0,
|
|
12252
|
+
const calculateDragOffset = (0, import_react55.useCallback)(
|
|
12182
12253
|
(startX, currentX, containerWidth) => {
|
|
12183
12254
|
const distance = startX - currentX;
|
|
12184
12255
|
const offsetPercent = distance / containerWidth * 100;
|
|
@@ -12203,7 +12274,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12203
12274
|
},
|
|
12204
12275
|
[activeIndex, images.length]
|
|
12205
12276
|
);
|
|
12206
|
-
const handleSwipeEnd = (0,
|
|
12277
|
+
const handleSwipeEnd = (0, import_react55.useCallback)(
|
|
12207
12278
|
(startX, endX, containerWidth) => {
|
|
12208
12279
|
const distance = startX - endX;
|
|
12209
12280
|
const distancePercent = Math.abs(distance) / containerWidth * 100;
|
|
@@ -12234,7 +12305,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12234
12305
|
},
|
|
12235
12306
|
[activeIndex, images.length, onIndexChange, recordSwipe]
|
|
12236
12307
|
);
|
|
12237
|
-
(0,
|
|
12308
|
+
(0, import_react55.useEffect)(() => {
|
|
12238
12309
|
const container = carouselRef.current;
|
|
12239
12310
|
if (!container) return;
|
|
12240
12311
|
const handleTouchStart = (e) => {
|
|
@@ -12323,11 +12394,11 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12323
12394
|
handleSwipeEnd,
|
|
12324
12395
|
handleImageTap
|
|
12325
12396
|
]);
|
|
12326
|
-
const mouseStartRef = (0,
|
|
12397
|
+
const mouseStartRef = (0, import_react55.useRef)(
|
|
12327
12398
|
null
|
|
12328
12399
|
);
|
|
12329
|
-
const isMouseDraggingRef = (0,
|
|
12330
|
-
(0,
|
|
12400
|
+
const isMouseDraggingRef = (0, import_react55.useRef)(false);
|
|
12401
|
+
(0, import_react55.useEffect)(() => {
|
|
12331
12402
|
const container = carouselRef.current;
|
|
12332
12403
|
if (!container) return;
|
|
12333
12404
|
const handleMouseDown = (e) => {
|
|
@@ -12403,7 +12474,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12403
12474
|
container.removeEventListener("mouseleave", handleMouseLeave);
|
|
12404
12475
|
};
|
|
12405
12476
|
}, [calculateDragOffset, handleSwipeEnd, handleImageTap]);
|
|
12406
|
-
const goToSlide = (0,
|
|
12477
|
+
const goToSlide = (0, import_react55.useCallback)(
|
|
12407
12478
|
(index, withTransition = true) => {
|
|
12408
12479
|
if (withTransition) {
|
|
12409
12480
|
setIsTransitioning(true);
|
|
@@ -12421,16 +12492,16 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12421
12492
|
},
|
|
12422
12493
|
[onIndexChange]
|
|
12423
12494
|
);
|
|
12424
|
-
(0,
|
|
12495
|
+
(0, import_react55.useEffect)(() => {
|
|
12425
12496
|
if (stickyHeroContext?.setCarouselIndicator && images.length > 1) {
|
|
12426
|
-
const indicator = /* @__PURE__ */ (0,
|
|
12497
|
+
const indicator = /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12427
12498
|
"div",
|
|
12428
12499
|
{
|
|
12429
12500
|
className: "w-full",
|
|
12430
12501
|
role: "group",
|
|
12431
12502
|
"aria-label": "Product image navigation",
|
|
12432
|
-
children: /* @__PURE__ */ (0,
|
|
12433
|
-
/* @__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)(
|
|
12434
12505
|
"button",
|
|
12435
12506
|
{
|
|
12436
12507
|
onClick: () => goToSlide(index),
|
|
@@ -12440,7 +12511,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12440
12511
|
},
|
|
12441
12512
|
index
|
|
12442
12513
|
)) }),
|
|
12443
|
-
/* @__PURE__ */ (0,
|
|
12514
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12444
12515
|
"div",
|
|
12445
12516
|
{
|
|
12446
12517
|
className: "absolute top-0 h-full bg-primary transition-all duration-300 ease-out",
|
|
@@ -12463,10 +12534,10 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12463
12534
|
};
|
|
12464
12535
|
}, [activeIndex, images.length, goToSlide, stickyHeroContext]);
|
|
12465
12536
|
if (!images || images.length === 0) {
|
|
12466
|
-
return /* @__PURE__ */ (0,
|
|
12537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "w-full aspect-video bg-muted rounded-lg" });
|
|
12467
12538
|
}
|
|
12468
|
-
return /* @__PURE__ */ (0,
|
|
12469
|
-
/* @__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)(
|
|
12470
12541
|
"div",
|
|
12471
12542
|
{
|
|
12472
12543
|
ref: carouselRef,
|
|
@@ -12484,7 +12555,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12484
12555
|
role: "region",
|
|
12485
12556
|
"aria-roledescription": "carousel",
|
|
12486
12557
|
"aria-label": "Product images",
|
|
12487
|
-
children: /* @__PURE__ */ (0,
|
|
12558
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12488
12559
|
"div",
|
|
12489
12560
|
{
|
|
12490
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)]" : ""}`,
|
|
@@ -12494,11 +12565,15 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12494
12565
|
children: images.map((image, index) => {
|
|
12495
12566
|
const DECODE_WINDOW = 1;
|
|
12496
12567
|
const isWithinDecodeWindow = Math.abs(index - activeIndex) <= DECODE_WINDOW;
|
|
12497
|
-
return /* @__PURE__ */ (0,
|
|
12568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12498
12569
|
"div",
|
|
12499
12570
|
{
|
|
12500
12571
|
className: "w-full h-full flex-shrink-0 relative select-none",
|
|
12501
|
-
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)(
|
|
12502
12577
|
HeroProductImage,
|
|
12503
12578
|
{
|
|
12504
12579
|
productId,
|
|
@@ -12510,16 +12585,12 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12510
12585
|
onUrlGenerated: image.mockupId ? (url) => handleUrlGenerated(image.mockupId, url) : void 0,
|
|
12511
12586
|
className: "w-full h-full object-cover cursor-pointer pointer-events-none"
|
|
12512
12587
|
}
|
|
12513
|
-
) : image.isRealMockup && !currentArtwork ? /* @__PURE__ */ (0,
|
|
12514
|
-
|
|
12588
|
+
) : image.isRealMockup && !currentArtwork ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(LoadingOverlayPrismCandyInline, { visible: true, variant: "light" }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12589
|
+
StaticCarouselImage,
|
|
12515
12590
|
{
|
|
12516
12591
|
src: image.src,
|
|
12517
|
-
alt: image.label,
|
|
12518
|
-
|
|
12519
|
-
className: "w-full h-full object-cover cursor-pointer pointer-events-none",
|
|
12520
|
-
loading: "lazy",
|
|
12521
|
-
decoding: "async",
|
|
12522
|
-
draggable: false
|
|
12592
|
+
alt: image.label ?? "",
|
|
12593
|
+
className: "w-full h-full object-cover cursor-pointer pointer-events-none"
|
|
12523
12594
|
}
|
|
12524
12595
|
)
|
|
12525
12596
|
},
|
|
@@ -12530,7 +12601,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12530
12601
|
)
|
|
12531
12602
|
}
|
|
12532
12603
|
),
|
|
12533
|
-
showIndicators && images.length > 1 && /* @__PURE__ */ (0,
|
|
12604
|
+
showIndicators && images.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12534
12605
|
"div",
|
|
12535
12606
|
{
|
|
12536
12607
|
ref: indicatorRef,
|
|
@@ -12538,8 +12609,8 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12538
12609
|
className: "relative z-20 w-full",
|
|
12539
12610
|
role: "group",
|
|
12540
12611
|
"aria-label": "Product image navigation",
|
|
12541
|
-
children: /* @__PURE__ */ (0,
|
|
12542
|
-
/* @__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)(
|
|
12543
12614
|
"button",
|
|
12544
12615
|
{
|
|
12545
12616
|
onClick: () => goToSlide(index),
|
|
@@ -12549,7 +12620,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12549
12620
|
},
|
|
12550
12621
|
index
|
|
12551
12622
|
)) }),
|
|
12552
|
-
/* @__PURE__ */ (0,
|
|
12623
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12553
12624
|
"div",
|
|
12554
12625
|
{
|
|
12555
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"}`,
|
|
@@ -12584,7 +12655,7 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12584
12655
|
naturalHeight: img.naturalHeight
|
|
12585
12656
|
} : null;
|
|
12586
12657
|
}).filter((img) => img !== null);
|
|
12587
|
-
return /* @__PURE__ */ (0,
|
|
12658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
12588
12659
|
EnhancedImageViewer,
|
|
12589
12660
|
{
|
|
12590
12661
|
imageUrl,
|
|
@@ -12623,8 +12694,8 @@ var MobileProductCarousel = (0, import_react54.memo)(function MobileProductCarou
|
|
|
12623
12694
|
});
|
|
12624
12695
|
|
|
12625
12696
|
// src/composed/carousels/HeroCarousel.tsx
|
|
12626
|
-
var
|
|
12627
|
-
var
|
|
12697
|
+
var import_react56 = require("react");
|
|
12698
|
+
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
12628
12699
|
function HeroCarousel({
|
|
12629
12700
|
images,
|
|
12630
12701
|
currentIndex = 0,
|
|
@@ -12634,16 +12705,16 @@ function HeroCarousel({
|
|
|
12634
12705
|
productId,
|
|
12635
12706
|
onImageTap
|
|
12636
12707
|
}) {
|
|
12637
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
12638
|
-
const containerRef = (0,
|
|
12639
|
-
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)(
|
|
12640
12711
|
null
|
|
12641
12712
|
);
|
|
12642
|
-
const isSwipingRef = (0,
|
|
12643
|
-
(0,
|
|
12713
|
+
const isSwipingRef = (0, import_react56.useRef)(false);
|
|
12714
|
+
(0, import_react56.useEffect)(() => {
|
|
12644
12715
|
setActiveIndex(currentIndex);
|
|
12645
12716
|
}, [currentIndex]);
|
|
12646
|
-
const goToSlide = (0,
|
|
12717
|
+
const goToSlide = (0, import_react56.useCallback)(
|
|
12647
12718
|
(index) => {
|
|
12648
12719
|
const clampedIndex = Math.max(0, Math.min(images.length - 1, index));
|
|
12649
12720
|
setActiveIndex(clampedIndex);
|
|
@@ -12651,7 +12722,7 @@ function HeroCarousel({
|
|
|
12651
12722
|
},
|
|
12652
12723
|
[images.length, onIndexChange]
|
|
12653
12724
|
);
|
|
12654
|
-
(0,
|
|
12725
|
+
(0, import_react56.useEffect)(() => {
|
|
12655
12726
|
const container = containerRef.current;
|
|
12656
12727
|
if (!container) return;
|
|
12657
12728
|
const handleTouchStart = (e) => {
|
|
@@ -12703,9 +12774,9 @@ function HeroCarousel({
|
|
|
12703
12774
|
};
|
|
12704
12775
|
}, [activeIndex, images.length, goToSlide, onImageTap]);
|
|
12705
12776
|
if (!images || images.length === 0) {
|
|
12706
|
-
return /* @__PURE__ */ (0,
|
|
12777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "w-full h-full bg-muted" });
|
|
12707
12778
|
}
|
|
12708
|
-
return /* @__PURE__ */ (0,
|
|
12779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
|
|
12709
12780
|
"div",
|
|
12710
12781
|
{
|
|
12711
12782
|
ref: containerRef,
|
|
@@ -12716,7 +12787,7 @@ function HeroCarousel({
|
|
|
12716
12787
|
overflow: "hidden"
|
|
12717
12788
|
},
|
|
12718
12789
|
children: [
|
|
12719
|
-
/* @__PURE__ */ (0,
|
|
12790
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12720
12791
|
"div",
|
|
12721
12792
|
{
|
|
12722
12793
|
className: "flex h-full transition-transform duration-300 ease-out",
|
|
@@ -12727,14 +12798,14 @@ function HeroCarousel({
|
|
|
12727
12798
|
backfaceVisibility: "hidden",
|
|
12728
12799
|
WebkitBackfaceVisibility: "hidden"
|
|
12729
12800
|
},
|
|
12730
|
-
children: images.map((image, index) => /* @__PURE__ */ (0,
|
|
12801
|
+
children: images.map((image, index) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12731
12802
|
"div",
|
|
12732
12803
|
{
|
|
12733
12804
|
className: "w-full h-full flex-shrink-0",
|
|
12734
12805
|
style: {
|
|
12735
12806
|
contain: "layout paint"
|
|
12736
12807
|
},
|
|
12737
|
-
children: image.isRealMockup && currentArtwork ? /* @__PURE__ */ (0,
|
|
12808
|
+
children: image.isRealMockup && currentArtwork ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12738
12809
|
HeroProductImage,
|
|
12739
12810
|
{
|
|
12740
12811
|
productId,
|
|
@@ -12743,7 +12814,7 @@ function HeroCarousel({
|
|
|
12743
12814
|
mockupId: image.mockupId,
|
|
12744
12815
|
className: "w-full h-full object-cover"
|
|
12745
12816
|
}
|
|
12746
|
-
) : /* @__PURE__ */ (0,
|
|
12817
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12747
12818
|
"img",
|
|
12748
12819
|
{
|
|
12749
12820
|
src: image.src,
|
|
@@ -12760,12 +12831,12 @@ function HeroCarousel({
|
|
|
12760
12831
|
))
|
|
12761
12832
|
}
|
|
12762
12833
|
),
|
|
12763
|
-
images.length > 1 && /* @__PURE__ */ (0,
|
|
12834
|
+
images.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12764
12835
|
"div",
|
|
12765
12836
|
{
|
|
12766
12837
|
className: "absolute bottom-4 left-0 right-0 flex justify-center gap-2 z-10",
|
|
12767
12838
|
style: { contain: "layout style" },
|
|
12768
|
-
children: images.map((_, index) => /* @__PURE__ */ (0,
|
|
12839
|
+
children: images.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
12769
12840
|
"button",
|
|
12770
12841
|
{
|
|
12771
12842
|
onClick: () => goToSlide(index),
|
|
@@ -12782,8 +12853,8 @@ function HeroCarousel({
|
|
|
12782
12853
|
}
|
|
12783
12854
|
|
|
12784
12855
|
// src/composed/grids/MasonryGrid.tsx
|
|
12785
|
-
var
|
|
12786
|
-
var
|
|
12856
|
+
var import_react57 = require("react");
|
|
12857
|
+
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
12787
12858
|
var BREAKPOINTS = {
|
|
12788
12859
|
sm: 640,
|
|
12789
12860
|
md: 768,
|
|
@@ -12835,13 +12906,13 @@ function MasonryGrid({
|
|
|
12835
12906
|
className = "",
|
|
12836
12907
|
emptyContent
|
|
12837
12908
|
}) {
|
|
12838
|
-
const [columnCount, setColumnCount] = (0,
|
|
12909
|
+
const [columnCount, setColumnCount] = (0, import_react57.useState)(
|
|
12839
12910
|
() => typeof columns === "number" ? columns : getColumnCount(
|
|
12840
12911
|
typeof window !== "undefined" ? window.innerWidth : 1024,
|
|
12841
12912
|
columns
|
|
12842
12913
|
)
|
|
12843
12914
|
);
|
|
12844
|
-
(0,
|
|
12915
|
+
(0, import_react57.useEffect)(() => {
|
|
12845
12916
|
const updateColumnCount = () => {
|
|
12846
12917
|
setColumnCount(getColumnCount(window.innerWidth, columns));
|
|
12847
12918
|
};
|
|
@@ -12849,30 +12920,30 @@ function MasonryGrid({
|
|
|
12849
12920
|
window.addEventListener("resize", updateColumnCount);
|
|
12850
12921
|
return () => window.removeEventListener("resize", updateColumnCount);
|
|
12851
12922
|
}, [columns]);
|
|
12852
|
-
const distributedColumns = (0,
|
|
12923
|
+
const distributedColumns = (0, import_react57.useMemo)(
|
|
12853
12924
|
() => distributeItems(items, columnCount),
|
|
12854
12925
|
[items, columnCount]
|
|
12855
12926
|
);
|
|
12856
12927
|
if (items.length === 0) {
|
|
12857
12928
|
if (emptyContent) {
|
|
12858
|
-
return /* @__PURE__ */ (0,
|
|
12929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(import_jsx_runtime75.Fragment, { children: emptyContent });
|
|
12859
12930
|
}
|
|
12860
12931
|
return null;
|
|
12861
12932
|
}
|
|
12862
|
-
return /* @__PURE__ */ (0,
|
|
12933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
12863
12934
|
"div",
|
|
12864
12935
|
{
|
|
12865
12936
|
className: `flex ${className}`,
|
|
12866
12937
|
style: { gap: `${gap}px` },
|
|
12867
12938
|
role: "list",
|
|
12868
|
-
children: distributedColumns.map((columnItems, columnIndex) => /* @__PURE__ */ (0,
|
|
12939
|
+
children: distributedColumns.map((columnItems, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
12869
12940
|
"div",
|
|
12870
12941
|
{
|
|
12871
12942
|
className: "flex-1 flex flex-col",
|
|
12872
12943
|
style: { gap: `${gap}px` },
|
|
12873
12944
|
children: columnItems.map((item, itemIndex) => {
|
|
12874
12945
|
const originalIndex = itemIndex * columnCount + columnIndex;
|
|
12875
|
-
return /* @__PURE__ */ (0,
|
|
12946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { role: "listitem", children: renderItem(item, originalIndex) }, originalIndex);
|
|
12876
12947
|
})
|
|
12877
12948
|
},
|
|
12878
12949
|
columnIndex
|
|
@@ -12885,7 +12956,7 @@ function MasonryGrid({
|
|
|
12885
12956
|
init_dev_warnings();
|
|
12886
12957
|
|
|
12887
12958
|
// src/layouts/hero-zoom/HeroZoomLayout.tsx
|
|
12888
|
-
var
|
|
12959
|
+
var import_react59 = require("react");
|
|
12889
12960
|
|
|
12890
12961
|
// src/layouts/hero-zoom/types.ts
|
|
12891
12962
|
var DEFAULT_HERO_ZOOM_CONFIG = {
|
|
@@ -12897,19 +12968,19 @@ var DEFAULT_HERO_ZOOM_CONFIG = {
|
|
|
12897
12968
|
};
|
|
12898
12969
|
|
|
12899
12970
|
// src/layouts/hero-zoom/useHeroZoomScales.ts
|
|
12900
|
-
var
|
|
12971
|
+
var import_react58 = require("react");
|
|
12901
12972
|
function useHeroZoomScales(config = {}) {
|
|
12902
12973
|
const { initialScale, accountForRetina, maxRetinaMultiplier } = {
|
|
12903
12974
|
...DEFAULT_HERO_ZOOM_CONFIG,
|
|
12904
12975
|
...config
|
|
12905
12976
|
};
|
|
12906
|
-
const [isHydrated, setIsHydrated] = (0,
|
|
12977
|
+
const [isHydrated, setIsHydrated] = (0, import_react58.useState)(false);
|
|
12907
12978
|
const ssrMultiplier = accountForRetina ? maxRetinaMultiplier : 2;
|
|
12908
|
-
const [scales, setScales] = (0,
|
|
12979
|
+
const [scales, setScales] = (0, import_react58.useState)(() => ({
|
|
12909
12980
|
visual: initialScale,
|
|
12910
12981
|
render: initialScale * ssrMultiplier
|
|
12911
12982
|
}));
|
|
12912
|
-
const calculateScales = (0,
|
|
12983
|
+
const calculateScales = (0, import_react58.useCallback)(() => {
|
|
12913
12984
|
const visualScale = Math.max(1, Math.min(4, initialScale));
|
|
12914
12985
|
let renderScale;
|
|
12915
12986
|
if (accountForRetina) {
|
|
@@ -12924,7 +12995,7 @@ function useHeroZoomScales(config = {}) {
|
|
|
12924
12995
|
renderScale = Math.max(1, Math.min(8, renderScale));
|
|
12925
12996
|
return { visual: visualScale, render: renderScale };
|
|
12926
12997
|
}, [initialScale, accountForRetina, maxRetinaMultiplier]);
|
|
12927
|
-
(0,
|
|
12998
|
+
(0, import_react58.useEffect)(() => {
|
|
12928
12999
|
const supportsScrollTimeline = CSS.supports(
|
|
12929
13000
|
"animation-timeline",
|
|
12930
13001
|
"scroll()"
|
|
@@ -12974,7 +13045,7 @@ function useHeroZoomScales(config = {}) {
|
|
|
12974
13045
|
}
|
|
12975
13046
|
|
|
12976
13047
|
// src/layouts/hero-zoom/HeroZoomLayout.tsx
|
|
12977
|
-
var
|
|
13048
|
+
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
12978
13049
|
function HeroZoomLayout({
|
|
12979
13050
|
config = {},
|
|
12980
13051
|
header,
|
|
@@ -12989,9 +13060,9 @@ function HeroZoomLayout({
|
|
|
12989
13060
|
};
|
|
12990
13061
|
const { aspectRatio, initialScale, headerHeight } = mergedConfig;
|
|
12991
13062
|
const { visual, render, isHydrated } = useHeroZoomScales(mergedConfig);
|
|
12992
|
-
const imageContainerRef = (0,
|
|
12993
|
-
const headerRef = (0,
|
|
12994
|
-
(0,
|
|
13063
|
+
const imageContainerRef = (0, import_react59.useRef)(null);
|
|
13064
|
+
const headerRef = (0, import_react59.useRef)(null);
|
|
13065
|
+
(0, import_react59.useEffect)(() => {
|
|
12995
13066
|
if (typeof window === "undefined") return;
|
|
12996
13067
|
const originalRestoration = "scrollRestoration" in history ? history.scrollRestoration : "auto";
|
|
12997
13068
|
if ("scrollRestoration" in history) {
|
|
@@ -13004,7 +13075,7 @@ function HeroZoomLayout({
|
|
|
13004
13075
|
}
|
|
13005
13076
|
};
|
|
13006
13077
|
}, []);
|
|
13007
|
-
(0,
|
|
13078
|
+
(0, import_react59.useEffect)(() => {
|
|
13008
13079
|
const supportsScrollTimeline = CSS.supports(
|
|
13009
13080
|
"animation-timeline",
|
|
13010
13081
|
"scroll()"
|
|
@@ -13133,7 +13204,7 @@ function HeroZoomLayout({
|
|
|
13133
13204
|
The drawer covers the hero completely, so let animation run continuously. */
|
|
13134
13205
|
}
|
|
13135
13206
|
`;
|
|
13136
|
-
return /* @__PURE__ */ (0,
|
|
13207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
13137
13208
|
"div",
|
|
13138
13209
|
{
|
|
13139
13210
|
className: `relative min-h-screen ${className}`,
|
|
@@ -13147,8 +13218,8 @@ function HeroZoomLayout({
|
|
|
13147
13218
|
"--hero-zoom-final-transform": 1 / activeRender
|
|
13148
13219
|
},
|
|
13149
13220
|
children: [
|
|
13150
|
-
/* @__PURE__ */ (0,
|
|
13151
|
-
/* @__PURE__ */ (0,
|
|
13221
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("style", { dangerouslySetInnerHTML: { __html: scopedStyles } }),
|
|
13222
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
13152
13223
|
"div",
|
|
13153
13224
|
{
|
|
13154
13225
|
style: {
|
|
@@ -13156,7 +13227,7 @@ function HeroZoomLayout({
|
|
|
13156
13227
|
}
|
|
13157
13228
|
}
|
|
13158
13229
|
),
|
|
13159
|
-
header && /* @__PURE__ */ (0,
|
|
13230
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
13160
13231
|
"div",
|
|
13161
13232
|
{
|
|
13162
13233
|
ref: headerRef,
|
|
@@ -13169,7 +13240,7 @@ function HeroZoomLayout({
|
|
|
13169
13240
|
children: header
|
|
13170
13241
|
}
|
|
13171
13242
|
),
|
|
13172
|
-
/* @__PURE__ */ (0,
|
|
13243
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
13173
13244
|
"div",
|
|
13174
13245
|
{
|
|
13175
13246
|
ref: imageContainerRef,
|
|
@@ -13189,15 +13260,15 @@ function HeroZoomLayout({
|
|
|
13189
13260
|
children: hero
|
|
13190
13261
|
}
|
|
13191
13262
|
),
|
|
13192
|
-
/* @__PURE__ */ (0,
|
|
13263
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "relative z-10", children })
|
|
13193
13264
|
]
|
|
13194
13265
|
}
|
|
13195
13266
|
);
|
|
13196
13267
|
}
|
|
13197
13268
|
|
|
13198
13269
|
// src/layouts/hero-zoom/HeroShrinkLayout.tsx
|
|
13199
|
-
var
|
|
13200
|
-
var
|
|
13270
|
+
var import_react60 = require("react");
|
|
13271
|
+
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
13201
13272
|
var DEFAULT_CONFIG = {
|
|
13202
13273
|
aspectRatio: 16 / 9,
|
|
13203
13274
|
initialHeightPercent: 70,
|
|
@@ -13217,13 +13288,13 @@ function HeroShrinkLayout({
|
|
|
13217
13288
|
...config
|
|
13218
13289
|
};
|
|
13219
13290
|
const { aspectRatio, initialHeightPercent, minHeightPercent, headerHeight } = mergedConfig;
|
|
13220
|
-
const heroRef = (0,
|
|
13221
|
-
const headerRef = (0,
|
|
13222
|
-
const [isClient, setIsClient] = (0,
|
|
13223
|
-
(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)(() => {
|
|
13224
13295
|
setIsClient(true);
|
|
13225
13296
|
}, []);
|
|
13226
|
-
(0,
|
|
13297
|
+
(0, import_react60.useEffect)(() => {
|
|
13227
13298
|
if (!isClient) return;
|
|
13228
13299
|
const supportsScrollTimeline = CSS.supports("animation-timeline", "scroll()");
|
|
13229
13300
|
if (supportsScrollTimeline) return;
|
|
@@ -13310,15 +13381,15 @@ function HeroShrinkLayout({
|
|
|
13310
13381
|
}
|
|
13311
13382
|
`;
|
|
13312
13383
|
const spacerHeight = `calc(${initialHeightPercent}svh + ${headerHeight}px)`;
|
|
13313
|
-
return /* @__PURE__ */ (0,
|
|
13384
|
+
return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
|
|
13314
13385
|
"div",
|
|
13315
13386
|
{
|
|
13316
13387
|
className: `relative min-h-screen ${className}`,
|
|
13317
13388
|
style: { ...style, ...cssVars },
|
|
13318
13389
|
children: [
|
|
13319
|
-
/* @__PURE__ */ (0,
|
|
13320
|
-
/* @__PURE__ */ (0,
|
|
13321
|
-
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)(
|
|
13322
13393
|
"div",
|
|
13323
13394
|
{
|
|
13324
13395
|
ref: headerRef,
|
|
@@ -13327,7 +13398,7 @@ function HeroShrinkLayout({
|
|
|
13327
13398
|
children: header
|
|
13328
13399
|
}
|
|
13329
13400
|
),
|
|
13330
|
-
/* @__PURE__ */ (0,
|
|
13401
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
13331
13402
|
"div",
|
|
13332
13403
|
{
|
|
13333
13404
|
ref: heroRef,
|
|
@@ -13335,15 +13406,15 @@ function HeroShrinkLayout({
|
|
|
13335
13406
|
children: hero
|
|
13336
13407
|
}
|
|
13337
13408
|
),
|
|
13338
|
-
/* @__PURE__ */ (0,
|
|
13409
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "relative z-10 bg-background", children })
|
|
13339
13410
|
]
|
|
13340
13411
|
}
|
|
13341
13412
|
);
|
|
13342
13413
|
}
|
|
13343
13414
|
|
|
13344
13415
|
// src/layouts/pdp/ImageEdgeBlur.tsx
|
|
13345
|
-
var
|
|
13346
|
-
var
|
|
13416
|
+
var import_react61 = __toESM(require("react"), 1);
|
|
13417
|
+
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
13347
13418
|
var BLUR_CONFIG = {
|
|
13348
13419
|
blur: 24,
|
|
13349
13420
|
crossfade: 68
|
|
@@ -13367,7 +13438,7 @@ var BLUR_LAYERS = [
|
|
|
13367
13438
|
{ blur: Math.round(BLUR_CONFIG.blur * 0.5), zone: 0.6 },
|
|
13368
13439
|
{ blur: BLUR_CONFIG.blur, zone: 1 }
|
|
13369
13440
|
];
|
|
13370
|
-
var ImageEdgeBlur =
|
|
13441
|
+
var ImageEdgeBlur = import_react61.default.memo(
|
|
13371
13442
|
function ImageEdgeBlur2({
|
|
13372
13443
|
imageSrc,
|
|
13373
13444
|
imageCapInfo,
|
|
@@ -13398,7 +13469,7 @@ var ImageEdgeBlur = import_react60.default.memo(
|
|
|
13398
13469
|
viewportWidth / LAYOUT_CONFIG2.IMAGE.ASPECT_RATIO,
|
|
13399
13470
|
maxWidthPx / LAYOUT_CONFIG2.IMAGE.ASPECT_RATIO
|
|
13400
13471
|
);
|
|
13401
|
-
return /* @__PURE__ */ (0,
|
|
13472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
13402
13473
|
"div",
|
|
13403
13474
|
{
|
|
13404
13475
|
className: `absolute inset-0 pointer-events-none overflow-hidden ${className}`,
|
|
@@ -13406,7 +13477,7 @@ var ImageEdgeBlur = import_react60.default.memo(
|
|
|
13406
13477
|
children: BLUR_LAYERS.map((layer, index) => {
|
|
13407
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}%)`;
|
|
13408
13479
|
const blurScale = 1 + layer.blur * 3 / containerHeightPx;
|
|
13409
|
-
return /* @__PURE__ */ (0,
|
|
13480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
13410
13481
|
"img",
|
|
13411
13482
|
{
|
|
13412
13483
|
src: imageSrc,
|
|
@@ -13453,7 +13524,7 @@ var ImageEdgeBlur = import_react60.default.memo(
|
|
|
13453
13524
|
);
|
|
13454
13525
|
|
|
13455
13526
|
// src/layouts/pdp/PDPLayout.tsx
|
|
13456
|
-
var
|
|
13527
|
+
var import_jsx_runtime79 = require("react/jsx-runtime");
|
|
13457
13528
|
function PDPLayout({
|
|
13458
13529
|
renderHeroImage,
|
|
13459
13530
|
renderContent,
|
|
@@ -13481,15 +13552,15 @@ function PDPLayout({
|
|
|
13481
13552
|
isDesktop,
|
|
13482
13553
|
isWideMonitor: isWideMonitor2
|
|
13483
13554
|
};
|
|
13484
|
-
return /* @__PURE__ */ (0,
|
|
13485
|
-
(isDesktop === false || isDesktop === null) && /* @__PURE__ */ (0,
|
|
13486
|
-
renderMobileCarousel && /* @__PURE__ */ (0,
|
|
13487
|
-
/* @__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) })
|
|
13488
13559
|
] }),
|
|
13489
|
-
(isDesktop === true || isDesktop === null) && /* @__PURE__ */ (0,
|
|
13490
|
-
/* @__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: [
|
|
13491
13562
|
renderHeroImage(heroProps),
|
|
13492
|
-
showEdgeBlur && blurImageSrc && isWideMonitor2 && /* @__PURE__ */ (0,
|
|
13563
|
+
showEdgeBlur && blurImageSrc && isWideMonitor2 && /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
13493
13564
|
ImageEdgeBlur,
|
|
13494
13565
|
{
|
|
13495
13566
|
imageSrc: blurImageSrc,
|
|
@@ -13500,7 +13571,7 @@ function PDPLayout({
|
|
|
13500
13571
|
}
|
|
13501
13572
|
)
|
|
13502
13573
|
] }),
|
|
13503
|
-
/* @__PURE__ */ (0,
|
|
13574
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
13504
13575
|
"div",
|
|
13505
13576
|
{
|
|
13506
13577
|
className: "desktop-sidebar",
|
|
@@ -13517,8 +13588,8 @@ function PDPLayout({
|
|
|
13517
13588
|
}
|
|
13518
13589
|
|
|
13519
13590
|
// src/layouts/pdp/SimpleImageBlur.tsx
|
|
13520
|
-
var
|
|
13521
|
-
var
|
|
13591
|
+
var import_react62 = __toESM(require("react"), 1);
|
|
13592
|
+
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
13522
13593
|
var BLUR_CONFIG2 = {
|
|
13523
13594
|
blur: 24,
|
|
13524
13595
|
crossfade: 60
|
|
@@ -13541,7 +13612,7 @@ function getFadeInMask(crossfadeWidth) {
|
|
|
13541
13612
|
black ${crossfadeWidth + 10}px
|
|
13542
13613
|
)`;
|
|
13543
13614
|
}
|
|
13544
|
-
var SimpleImageBlur =
|
|
13615
|
+
var SimpleImageBlur = import_react62.default.memo(function SimpleImageBlur2({
|
|
13545
13616
|
imageSrc,
|
|
13546
13617
|
width,
|
|
13547
13618
|
height = "100%",
|
|
@@ -13551,7 +13622,7 @@ var SimpleImageBlur = import_react61.default.memo(function SimpleImageBlur2({
|
|
|
13551
13622
|
if (!imageSrc || width <= 0) return null;
|
|
13552
13623
|
const fadeInMask = getFadeInMask(BLUR_CONFIG2.crossfade);
|
|
13553
13624
|
const extendedWidth = width + BLUR_CONFIG2.blur * 2;
|
|
13554
|
-
return /* @__PURE__ */ (0,
|
|
13625
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
13555
13626
|
"div",
|
|
13556
13627
|
{
|
|
13557
13628
|
className: `relative overflow-hidden ${className}`,
|
|
@@ -13564,7 +13635,7 @@ var SimpleImageBlur = import_react61.default.memo(function SimpleImageBlur2({
|
|
|
13564
13635
|
black 0%,
|
|
13565
13636
|
black ${layer.zone * 100}%,
|
|
13566
13637
|
transparent ${layer.zone * 100 + 10}%)`;
|
|
13567
|
-
return /* @__PURE__ */ (0,
|
|
13638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
13568
13639
|
"img",
|
|
13569
13640
|
{
|
|
13570
13641
|
src: imageSrc,
|
|
@@ -13594,8 +13665,8 @@ var SimpleImageBlur = import_react61.default.memo(function SimpleImageBlur2({
|
|
|
13594
13665
|
});
|
|
13595
13666
|
|
|
13596
13667
|
// src/layouts/pdp/EdgeBlurBox.tsx
|
|
13597
|
-
var
|
|
13598
|
-
var
|
|
13668
|
+
var import_react63 = __toESM(require("react"), 1);
|
|
13669
|
+
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
13599
13670
|
var BLUR_CONFIG3 = {
|
|
13600
13671
|
blur: 24,
|
|
13601
13672
|
crossfade: 60
|
|
@@ -13619,7 +13690,7 @@ function getFadeOutMask(crossfadeWidth) {
|
|
|
13619
13690
|
transparent 100%
|
|
13620
13691
|
)`;
|
|
13621
13692
|
}
|
|
13622
|
-
var EdgeBlurBox =
|
|
13693
|
+
var EdgeBlurBox = import_react63.default.memo(function EdgeBlurBox2({
|
|
13623
13694
|
imageSrc,
|
|
13624
13695
|
width,
|
|
13625
13696
|
height = "100%",
|
|
@@ -13634,7 +13705,7 @@ var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
|
13634
13705
|
const blurExtend = BLUR_CONFIG3.blur * 2;
|
|
13635
13706
|
const actualSharpWidth = sharpImageWidth ?? width + overlapLeft;
|
|
13636
13707
|
const hasOverlap = overlapLeft > 0;
|
|
13637
|
-
return /* @__PURE__ */ (0,
|
|
13708
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
|
|
13638
13709
|
"div",
|
|
13639
13710
|
{
|
|
13640
13711
|
className: `relative ${className}`,
|
|
@@ -13645,7 +13716,7 @@ var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
|
13645
13716
|
overflow: hasOverlap ? "visible" : "hidden"
|
|
13646
13717
|
},
|
|
13647
13718
|
children: [
|
|
13648
|
-
/* @__PURE__ */ (0,
|
|
13719
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
13649
13720
|
"div",
|
|
13650
13721
|
{
|
|
13651
13722
|
style: {
|
|
@@ -13659,7 +13730,7 @@ var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
|
13659
13730
|
transparent ${100 - (layer.zone * 100 + 10)}%,
|
|
13660
13731
|
black ${100 - layer.zone * 100}%,
|
|
13661
13732
|
black 100%)`;
|
|
13662
|
-
return /* @__PURE__ */ (0,
|
|
13733
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
13663
13734
|
"img",
|
|
13664
13735
|
{
|
|
13665
13736
|
src: imageSrc,
|
|
@@ -13687,7 +13758,7 @@ var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
|
13687
13758
|
})
|
|
13688
13759
|
}
|
|
13689
13760
|
),
|
|
13690
|
-
/* @__PURE__ */ (0,
|
|
13761
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
13691
13762
|
"img",
|
|
13692
13763
|
{
|
|
13693
13764
|
src: imageSrc,
|
|
@@ -13715,8 +13786,8 @@ var EdgeBlurBox = import_react62.default.memo(function EdgeBlurBox2({
|
|
|
13715
13786
|
});
|
|
13716
13787
|
|
|
13717
13788
|
// src/layouts/pdp/ImageBlurExtension.tsx
|
|
13718
|
-
var
|
|
13719
|
-
var
|
|
13789
|
+
var import_react64 = __toESM(require("react"), 1);
|
|
13790
|
+
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
13720
13791
|
var BLUR_CONFIG4 = {
|
|
13721
13792
|
blur: 24,
|
|
13722
13793
|
crossfadeWidth: 80
|
|
@@ -13739,7 +13810,7 @@ function getFadeOutMask2(crossfadeWidth) {
|
|
|
13739
13810
|
transparent 100%
|
|
13740
13811
|
)`;
|
|
13741
13812
|
}
|
|
13742
|
-
var ImageBlurExtension =
|
|
13813
|
+
var ImageBlurExtension = import_react64.default.memo(function ImageBlurExtension2({
|
|
13743
13814
|
imageSrc,
|
|
13744
13815
|
width,
|
|
13745
13816
|
height,
|
|
@@ -13753,7 +13824,7 @@ var ImageBlurExtension = import_react63.default.memo(function ImageBlurExtension
|
|
|
13753
13824
|
const internalImageLeft = `calc(${heroImageLeft} - 100vw + ${width}px)`;
|
|
13754
13825
|
const fadeOutMask = getFadeOutMask2(crossfadeWidth);
|
|
13755
13826
|
const heightValue = typeof height === "number" ? `${height}px` : height;
|
|
13756
|
-
return /* @__PURE__ */ (0,
|
|
13827
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(
|
|
13757
13828
|
"div",
|
|
13758
13829
|
{
|
|
13759
13830
|
className: `relative overflow-hidden ${className}`,
|
|
@@ -13762,7 +13833,7 @@ var ImageBlurExtension = import_react63.default.memo(function ImageBlurExtension
|
|
|
13762
13833
|
height: heightValue
|
|
13763
13834
|
},
|
|
13764
13835
|
children: [
|
|
13765
|
-
BLUR_LAYERS4.map((layer, index) => /* @__PURE__ */ (0,
|
|
13836
|
+
BLUR_LAYERS4.map((layer, index) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
13766
13837
|
"img",
|
|
13767
13838
|
{
|
|
13768
13839
|
src: imageSrc,
|
|
@@ -13786,7 +13857,7 @@ var ImageBlurExtension = import_react63.default.memo(function ImageBlurExtension
|
|
|
13786
13857
|
},
|
|
13787
13858
|
`blur-${index}`
|
|
13788
13859
|
)),
|
|
13789
|
-
/* @__PURE__ */ (0,
|
|
13860
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
13790
13861
|
"img",
|
|
13791
13862
|
{
|
|
13792
13863
|
src: imageSrc,
|
|
@@ -13814,39 +13885,39 @@ var ImageBlurExtension = import_react63.default.memo(function ImageBlurExtension
|
|
|
13814
13885
|
});
|
|
13815
13886
|
|
|
13816
13887
|
// src/design-system/ColorSwatch.tsx
|
|
13817
|
-
var
|
|
13888
|
+
var import_jsx_runtime83 = require("react/jsx-runtime");
|
|
13818
13889
|
function ColorTokenSwatch({ name, cssVar, className = "" }) {
|
|
13819
|
-
return /* @__PURE__ */ (0,
|
|
13820
|
-
/* @__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)(
|
|
13821
13892
|
"div",
|
|
13822
13893
|
{
|
|
13823
13894
|
className: "h-16 w-full rounded-lg border border-border shadow-sm",
|
|
13824
13895
|
style: { backgroundColor: `var(${cssVar})` }
|
|
13825
13896
|
}
|
|
13826
13897
|
),
|
|
13827
|
-
/* @__PURE__ */ (0,
|
|
13828
|
-
/* @__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 })
|
|
13829
13900
|
] });
|
|
13830
13901
|
}
|
|
13831
13902
|
function ColorRow({ name, cssVar, description }) {
|
|
13832
|
-
return /* @__PURE__ */ (0,
|
|
13833
|
-
/* @__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)(
|
|
13834
13905
|
"div",
|
|
13835
13906
|
{
|
|
13836
13907
|
className: "h-10 w-10 rounded-lg border border-border shadow-sm flex-shrink-0",
|
|
13837
13908
|
style: { backgroundColor: `var(${cssVar})` }
|
|
13838
13909
|
}
|
|
13839
13910
|
),
|
|
13840
|
-
/* @__PURE__ */ (0,
|
|
13841
|
-
/* @__PURE__ */ (0,
|
|
13842
|
-
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 })
|
|
13843
13914
|
] }),
|
|
13844
|
-
/* @__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 })
|
|
13845
13916
|
] });
|
|
13846
13917
|
}
|
|
13847
13918
|
|
|
13848
13919
|
// src/design-system/ColorPalette.tsx
|
|
13849
|
-
var
|
|
13920
|
+
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
13850
13921
|
var COLOR_GROUPS = [
|
|
13851
13922
|
{
|
|
13852
13923
|
name: "Base",
|
|
@@ -13927,17 +13998,17 @@ var COLOR_GROUPS = [
|
|
|
13927
13998
|
}
|
|
13928
13999
|
];
|
|
13929
14000
|
function ColorPalette({ layout = "list", className = "" }) {
|
|
13930
|
-
return /* @__PURE__ */ (0,
|
|
13931
|
-
/* @__PURE__ */ (0,
|
|
13932
|
-
/* @__PURE__ */ (0,
|
|
13933
|
-
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)(
|
|
13934
14005
|
ColorTokenSwatch,
|
|
13935
14006
|
{
|
|
13936
14007
|
name: color.name,
|
|
13937
14008
|
cssVar: color.cssVar
|
|
13938
14009
|
},
|
|
13939
14010
|
color.cssVar
|
|
13940
|
-
)) }) : /* @__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)(
|
|
13941
14012
|
ColorRow,
|
|
13942
14013
|
{
|
|
13943
14014
|
name: color.name,
|
|
@@ -13950,7 +14021,7 @@ function ColorPalette({ layout = "list", className = "" }) {
|
|
|
13950
14021
|
}
|
|
13951
14022
|
|
|
13952
14023
|
// src/design-system/TypographyScale.tsx
|
|
13953
|
-
var
|
|
14024
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
13954
14025
|
var FONT_SAMPLES = [
|
|
13955
14026
|
{
|
|
13956
14027
|
name: "Heading",
|
|
@@ -13984,14 +14055,14 @@ var FONT_SAMPLES = [
|
|
|
13984
14055
|
}
|
|
13985
14056
|
];
|
|
13986
14057
|
function TypographyScale({ className = "" }) {
|
|
13987
|
-
return /* @__PURE__ */ (0,
|
|
13988
|
-
/* @__PURE__ */ (0,
|
|
13989
|
-
/* @__PURE__ */ (0,
|
|
13990
|
-
/* @__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 })
|
|
13991
14062
|
] }),
|
|
13992
|
-
/* @__PURE__ */ (0,
|
|
13993
|
-
/* @__PURE__ */ (0,
|
|
13994
|
-
/* @__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)(
|
|
13995
14066
|
"p",
|
|
13996
14067
|
{
|
|
13997
14068
|
className: `${size} text-foreground`,
|
|
@@ -14010,8 +14081,8 @@ var RADIUS_SAMPLES = [
|
|
|
14010
14081
|
{ name: "Full", value: "9999px" }
|
|
14011
14082
|
];
|
|
14012
14083
|
function RadiusScale({ className = "" }) {
|
|
14013
|
-
return /* @__PURE__ */ (0,
|
|
14014
|
-
/* @__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)(
|
|
14015
14086
|
"div",
|
|
14016
14087
|
{
|
|
14017
14088
|
className: "h-16 w-16 bg-primary",
|
|
@@ -14020,13 +14091,13 @@ function RadiusScale({ className = "" }) {
|
|
|
14020
14091
|
}
|
|
14021
14092
|
}
|
|
14022
14093
|
),
|
|
14023
|
-
/* @__PURE__ */ (0,
|
|
14024
|
-
/* @__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 })
|
|
14025
14096
|
] }, radius.name)) }) });
|
|
14026
14097
|
}
|
|
14027
14098
|
|
|
14028
14099
|
// src/design-system/ThemeSwitcher.tsx
|
|
14029
|
-
var
|
|
14100
|
+
var import_react65 = require("react");
|
|
14030
14101
|
|
|
14031
14102
|
// src/themes/types.ts
|
|
14032
14103
|
var RADIUS_PRESETS = {
|
|
@@ -15194,7 +15265,7 @@ function applyTheme(config) {
|
|
|
15194
15265
|
}
|
|
15195
15266
|
|
|
15196
15267
|
// src/design-system/ThemeSwitcher.tsx
|
|
15197
|
-
var
|
|
15268
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
15198
15269
|
function readThemeFromDOM() {
|
|
15199
15270
|
if (typeof document === "undefined") {
|
|
15200
15271
|
return { themeName: "Linear", isDark: false };
|
|
@@ -15212,10 +15283,10 @@ function readThemeFromDOM() {
|
|
|
15212
15283
|
return { themeName: "Linear", isDark: dark };
|
|
15213
15284
|
}
|
|
15214
15285
|
function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
15215
|
-
const [currentTheme, setCurrentTheme] = (0,
|
|
15216
|
-
const [isDark, setIsDark] = (0,
|
|
15217
|
-
const [isOpen, setIsOpen] = (0,
|
|
15218
|
-
(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)(() => {
|
|
15219
15290
|
const { themeName, isDark: dark } = readThemeFromDOM();
|
|
15220
15291
|
setCurrentTheme(themeName);
|
|
15221
15292
|
setIsDark(dark);
|
|
@@ -15254,61 +15325,61 @@ function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
|
15254
15325
|
applyTheme(config);
|
|
15255
15326
|
};
|
|
15256
15327
|
const themes = showBaseThemesOnly ? baseThemes : baseThemes;
|
|
15257
|
-
return /* @__PURE__ */ (0,
|
|
15258
|
-
/* @__PURE__ */ (0,
|
|
15259
|
-
/* @__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)(
|
|
15260
15331
|
"button",
|
|
15261
15332
|
{
|
|
15262
15333
|
onClick: () => setIsOpen(!isOpen),
|
|
15263
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",
|
|
15264
15335
|
children: [
|
|
15265
|
-
/* @__PURE__ */ (0,
|
|
15266
|
-
/* @__PURE__ */ (0,
|
|
15267
|
-
/* @__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" }) })
|
|
15268
15339
|
]
|
|
15269
15340
|
}
|
|
15270
15341
|
),
|
|
15271
|
-
isOpen && /* @__PURE__ */ (0,
|
|
15272
|
-
/* @__PURE__ */ (0,
|
|
15342
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(import_jsx_runtime86.Fragment, { children: [
|
|
15343
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
15273
15344
|
"div",
|
|
15274
15345
|
{
|
|
15275
15346
|
className: "fixed inset-0 z-40",
|
|
15276
15347
|
onClick: () => setIsOpen(false)
|
|
15277
15348
|
}
|
|
15278
15349
|
),
|
|
15279
|
-
/* @__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)(
|
|
15280
15351
|
"button",
|
|
15281
15352
|
{
|
|
15282
15353
|
onClick: () => handleThemeSelect(theme.name),
|
|
15283
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" : ""}`,
|
|
15284
15355
|
children: [
|
|
15285
|
-
/* @__PURE__ */ (0,
|
|
15356
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
15286
15357
|
"div",
|
|
15287
15358
|
{
|
|
15288
15359
|
className: "w-4 h-4 rounded-full border border-border",
|
|
15289
15360
|
style: { backgroundColor: theme.primaryColor || "#888" }
|
|
15290
15361
|
}
|
|
15291
15362
|
),
|
|
15292
|
-
/* @__PURE__ */ (0,
|
|
15293
|
-
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" }) })
|
|
15294
15365
|
]
|
|
15295
15366
|
},
|
|
15296
15367
|
theme.name
|
|
15297
15368
|
)) })
|
|
15298
15369
|
] })
|
|
15299
15370
|
] }),
|
|
15300
|
-
/* @__PURE__ */ (0,
|
|
15371
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
|
|
15301
15372
|
"button",
|
|
15302
15373
|
{
|
|
15303
15374
|
onClick: handleDarkModeToggle,
|
|
15304
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",
|
|
15305
15376
|
title: `Switch to ${isDark ? "light" : "dark"} mode`,
|
|
15306
15377
|
children: [
|
|
15307
|
-
isDark ? /* @__PURE__ */ (0,
|
|
15308
|
-
/* @__PURE__ */ (0,
|
|
15309
|
-
/* @__PURE__ */ (0,
|
|
15310
|
-
] }) : /* @__PURE__ */ (0,
|
|
15311
|
-
/* @__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" })
|
|
15312
15383
|
]
|
|
15313
15384
|
}
|
|
15314
15385
|
)
|
|
@@ -15316,7 +15387,7 @@ function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
|
|
|
15316
15387
|
}
|
|
15317
15388
|
|
|
15318
15389
|
// src/design-system/DesignSystemPage.tsx
|
|
15319
|
-
var
|
|
15390
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
15320
15391
|
function DesignSystemPage({
|
|
15321
15392
|
showThemeSwitcher = true,
|
|
15322
15393
|
showColors = true,
|
|
@@ -15326,29 +15397,29 @@ function DesignSystemPage({
|
|
|
15326
15397
|
colorLayout = "list",
|
|
15327
15398
|
className = ""
|
|
15328
15399
|
}) {
|
|
15329
|
-
return /* @__PURE__ */ (0,
|
|
15330
|
-
/* @__PURE__ */ (0,
|
|
15331
|
-
/* @__PURE__ */ (0,
|
|
15332
|
-
/* @__PURE__ */ (0,
|
|
15333
|
-
/* @__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" })
|
|
15334
15405
|
] }),
|
|
15335
|
-
showThemeSwitcher && /* @__PURE__ */ (0,
|
|
15406
|
+
showThemeSwitcher && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ThemeSwitcher, {})
|
|
15336
15407
|
] }) }),
|
|
15337
|
-
showColors && /* @__PURE__ */ (0,
|
|
15338
|
-
/* @__PURE__ */ (0,
|
|
15339
|
-
/* @__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 })
|
|
15340
15411
|
] }),
|
|
15341
|
-
showTypography && /* @__PURE__ */ (0,
|
|
15342
|
-
/* @__PURE__ */ (0,
|
|
15343
|
-
/* @__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, {})
|
|
15344
15415
|
] }),
|
|
15345
|
-
showRadius && /* @__PURE__ */ (0,
|
|
15346
|
-
/* @__PURE__ */ (0,
|
|
15347
|
-
/* @__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, {})
|
|
15348
15419
|
] }),
|
|
15349
|
-
showSpacing && /* @__PURE__ */ (0,
|
|
15350
|
-
/* @__PURE__ */ (0,
|
|
15351
|
-
/* @__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, {})
|
|
15352
15423
|
] })
|
|
15353
15424
|
] });
|
|
15354
15425
|
}
|
|
@@ -15363,31 +15434,31 @@ function SpacingScale() {
|
|
|
15363
15434
|
{ name: "12", value: "3rem" },
|
|
15364
15435
|
{ name: "16", value: "4rem" }
|
|
15365
15436
|
];
|
|
15366
|
-
return /* @__PURE__ */ (0,
|
|
15367
|
-
/* @__PURE__ */ (0,
|
|
15368
|
-
/* @__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)(
|
|
15369
15440
|
"div",
|
|
15370
15441
|
{
|
|
15371
15442
|
className: "h-4 bg-primary rounded",
|
|
15372
15443
|
style: { width: space.value }
|
|
15373
15444
|
}
|
|
15374
15445
|
),
|
|
15375
|
-
/* @__PURE__ */ (0,
|
|
15446
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "text-sm text-muted-foreground", children: space.value })
|
|
15376
15447
|
] }, space.name)) });
|
|
15377
15448
|
}
|
|
15378
15449
|
|
|
15379
15450
|
// src/personalization/PersonalizationProvider.tsx
|
|
15380
|
-
var
|
|
15451
|
+
var import_react68 = __toESM(require("react"), 1);
|
|
15381
15452
|
|
|
15382
15453
|
// src/personalization/PersonalizationContext.ts
|
|
15383
|
-
var
|
|
15384
|
-
var PersonalizationContext = (0,
|
|
15454
|
+
var import_react66 = require("react");
|
|
15455
|
+
var PersonalizationContext = (0, import_react66.createContext)(null);
|
|
15385
15456
|
function usePersonalizationContext() {
|
|
15386
|
-
return (0,
|
|
15457
|
+
return (0, import_react66.useContext)(PersonalizationContext);
|
|
15387
15458
|
}
|
|
15388
15459
|
|
|
15389
15460
|
// src/personalization/utils.ts
|
|
15390
|
-
var
|
|
15461
|
+
var import_react67 = require("react");
|
|
15391
15462
|
function normalizeHex(color) {
|
|
15392
15463
|
let hex = color.trim().toUpperCase();
|
|
15393
15464
|
if (hex.length === 4 && hex.startsWith("#")) {
|
|
@@ -15408,8 +15479,8 @@ function isValidImageUrl(url) {
|
|
|
15408
15479
|
}
|
|
15409
15480
|
}
|
|
15410
15481
|
function useDebouncedValue(value, delay) {
|
|
15411
|
-
const [debounced, setDebounced] = (0,
|
|
15412
|
-
(0,
|
|
15482
|
+
const [debounced, setDebounced] = (0, import_react67.useState)(value);
|
|
15483
|
+
(0, import_react67.useEffect)(() => {
|
|
15413
15484
|
const timer = setTimeout(() => setDebounced(value), delay);
|
|
15414
15485
|
return () => clearTimeout(timer);
|
|
15415
15486
|
}, [value, delay]);
|
|
@@ -15430,18 +15501,18 @@ function scrollInputAboveKeyboard(input) {
|
|
|
15430
15501
|
}
|
|
15431
15502
|
|
|
15432
15503
|
// src/personalization/PersonalizationProvider.tsx
|
|
15433
|
-
var
|
|
15504
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
15434
15505
|
function createBridgeFromCanvas(canvasModule) {
|
|
15435
15506
|
const { useEditor, useCommands, useImageBinding } = canvasModule;
|
|
15436
15507
|
function TextBinder({ name, value }) {
|
|
15437
15508
|
const { elements } = useEditor();
|
|
15438
15509
|
const { executeElementUpdate } = useCommands();
|
|
15439
|
-
const elementsRef =
|
|
15510
|
+
const elementsRef = import_react68.default.useRef(elements);
|
|
15440
15511
|
elementsRef.current = elements;
|
|
15441
|
-
const executeRef =
|
|
15512
|
+
const executeRef = import_react68.default.useRef(executeElementUpdate);
|
|
15442
15513
|
executeRef.current = executeElementUpdate;
|
|
15443
|
-
const hasUserInput =
|
|
15444
|
-
|
|
15514
|
+
const hasUserInput = import_react68.default.useRef(false);
|
|
15515
|
+
import_react68.default.useEffect(() => {
|
|
15445
15516
|
if (value == null) return;
|
|
15446
15517
|
if (value === "" && !hasUserInput.current) return;
|
|
15447
15518
|
hasUserInput.current = true;
|
|
@@ -15459,12 +15530,12 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
15459
15530
|
function ColorBinder({ originalColor, newColor }) {
|
|
15460
15531
|
const { elements } = useEditor();
|
|
15461
15532
|
const { executeElementUpdate } = useCommands();
|
|
15462
|
-
const elementsRef =
|
|
15533
|
+
const elementsRef = import_react68.default.useRef(elements);
|
|
15463
15534
|
elementsRef.current = elements;
|
|
15464
|
-
const executeRef =
|
|
15535
|
+
const executeRef = import_react68.default.useRef(executeElementUpdate);
|
|
15465
15536
|
executeRef.current = executeElementUpdate;
|
|
15466
|
-
const appliedColorRef =
|
|
15467
|
-
|
|
15537
|
+
const appliedColorRef = import_react68.default.useRef(normalizeHex(originalColor));
|
|
15538
|
+
import_react68.default.useEffect(() => {
|
|
15468
15539
|
const normalizedNew = normalizeHex(newColor);
|
|
15469
15540
|
if (normalizedNew === appliedColorRef.current) return;
|
|
15470
15541
|
const matchColor = appliedColorRef.current;
|
|
@@ -15504,11 +15575,11 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
15504
15575
|
}
|
|
15505
15576
|
function ImageBinder({ name, value, fit = "cover" }) {
|
|
15506
15577
|
const { setImageUrl } = useImageBinding(name, { fit });
|
|
15507
|
-
const hasUserInput =
|
|
15578
|
+
const hasUserInput = import_react68.default.useRef(false);
|
|
15508
15579
|
const debouncedValue = useDebouncedValue(value, 500);
|
|
15509
|
-
const setImageUrlRef =
|
|
15580
|
+
const setImageUrlRef = import_react68.default.useRef(setImageUrl);
|
|
15510
15581
|
setImageUrlRef.current = setImageUrl;
|
|
15511
|
-
|
|
15582
|
+
import_react68.default.useEffect(() => {
|
|
15512
15583
|
if (debouncedValue == null) return;
|
|
15513
15584
|
if (debouncedValue === "" && !hasUserInput.current) return;
|
|
15514
15585
|
hasUserInput.current = true;
|
|
@@ -15518,15 +15589,15 @@ function createBridgeFromCanvas(canvasModule) {
|
|
|
15518
15589
|
return null;
|
|
15519
15590
|
}
|
|
15520
15591
|
return function PersonalizationBridge({ fields = [], values = {} } = {}) {
|
|
15521
|
-
return /* @__PURE__ */ (0,
|
|
15592
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(import_jsx_runtime88.Fragment, { children: fields.map((field) => {
|
|
15522
15593
|
if (field.type === "text") {
|
|
15523
|
-
return /* @__PURE__ */ (0,
|
|
15594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(TextBinder, { name: field.name, value: values[field.name] ?? "" }, `text-${field.name}`);
|
|
15524
15595
|
}
|
|
15525
15596
|
if (field.type === "color") {
|
|
15526
|
-
return /* @__PURE__ */ (0,
|
|
15597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(ColorBinder, { originalColor: field.color, newColor: values[field.color] ?? field.color }, `color-${field.color}`);
|
|
15527
15598
|
}
|
|
15528
15599
|
if (field.type === "image") {
|
|
15529
|
-
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}`);
|
|
15530
15601
|
}
|
|
15531
15602
|
return null;
|
|
15532
15603
|
}) });
|
|
@@ -15548,19 +15619,19 @@ function PersonalizationProvider({
|
|
|
15548
15619
|
children
|
|
15549
15620
|
}) {
|
|
15550
15621
|
const realtime = useRealtimeOptional();
|
|
15551
|
-
const [personValues, setPersonValues] = (0,
|
|
15552
|
-
const [isActive, setIsActive] = (0,
|
|
15553
|
-
const [isExporting, setIsExporting] = (0,
|
|
15554
|
-
const [exportedBlobUrls, setExportedBlobUrls] = (0,
|
|
15555
|
-
const [exportCount, setExportCount] = (0,
|
|
15556
|
-
const blobUrlsRef = (0,
|
|
15557
|
-
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)(
|
|
15558
15629
|
cachedCanvasComponent
|
|
15559
15630
|
);
|
|
15560
|
-
const [BridgeComponent, setBridgeComponent] = (0,
|
|
15631
|
+
const [BridgeComponent, setBridgeComponent] = (0, import_react68.useState)(
|
|
15561
15632
|
cachedBridgeComponent
|
|
15562
15633
|
);
|
|
15563
|
-
(0,
|
|
15634
|
+
(0, import_react68.useEffect)(() => {
|
|
15564
15635
|
if (CanvasComponent && BridgeComponent) return;
|
|
15565
15636
|
if (!canvasImport) return;
|
|
15566
15637
|
if (!canvasLoadPromise) {
|
|
@@ -15578,8 +15649,8 @@ function PersonalizationProvider({
|
|
|
15578
15649
|
}
|
|
15579
15650
|
});
|
|
15580
15651
|
}, [CanvasComponent, BridgeComponent, canvasImport]);
|
|
15581
|
-
const realtimeEnabledRef = (0,
|
|
15582
|
-
(0,
|
|
15652
|
+
const realtimeEnabledRef = (0, import_react68.useRef)(false);
|
|
15653
|
+
(0, import_react68.useEffect)(() => {
|
|
15583
15654
|
return () => {
|
|
15584
15655
|
for (const url of Object.values(blobUrlsRef.current)) {
|
|
15585
15656
|
try {
|
|
@@ -15589,16 +15660,16 @@ function PersonalizationProvider({
|
|
|
15589
15660
|
}
|
|
15590
15661
|
};
|
|
15591
15662
|
}, []);
|
|
15592
|
-
const updateField = (0,
|
|
15663
|
+
const updateField = (0, import_react68.useCallback)((key, value) => {
|
|
15593
15664
|
setIsActive(true);
|
|
15594
15665
|
setPersonValues((prev) => ({ ...prev, [key]: value }));
|
|
15595
15666
|
}, []);
|
|
15596
|
-
const reset = (0,
|
|
15667
|
+
const reset = (0, import_react68.useCallback)(() => {
|
|
15597
15668
|
setPersonValues({});
|
|
15598
15669
|
setIsActive(false);
|
|
15599
15670
|
setIsExporting(false);
|
|
15600
15671
|
}, []);
|
|
15601
|
-
const handleExport = (0,
|
|
15672
|
+
const handleExport = (0, import_react68.useCallback)(
|
|
15602
15673
|
(exports2) => {
|
|
15603
15674
|
const newUrls = {};
|
|
15604
15675
|
for (const [name, data] of Object.entries(exports2)) {
|
|
@@ -15632,11 +15703,11 @@ function PersonalizationProvider({
|
|
|
15632
15703
|
},
|
|
15633
15704
|
[realtime, placementOverride]
|
|
15634
15705
|
);
|
|
15635
|
-
const handleExportScheduled = (0,
|
|
15706
|
+
const handleExportScheduled = (0, import_react68.useCallback)(() => {
|
|
15636
15707
|
setIsExporting(true);
|
|
15637
15708
|
}, []);
|
|
15638
15709
|
const shouldMountCanvas = CanvasComponent && BridgeComponent && canvasState?.elements && canvasState.elements.length > 0 && (!lazy || isActive);
|
|
15639
|
-
const contextValue =
|
|
15710
|
+
const contextValue = import_react68.default.useMemo(
|
|
15640
15711
|
() => ({
|
|
15641
15712
|
fields,
|
|
15642
15713
|
personValues,
|
|
@@ -15649,8 +15720,8 @@ function PersonalizationProvider({
|
|
|
15649
15720
|
}),
|
|
15650
15721
|
[fields, personValues, updateField, isActive, isExporting, exportedBlobUrls, exportCount, reset]
|
|
15651
15722
|
);
|
|
15652
|
-
return /* @__PURE__ */ (0,
|
|
15653
|
-
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)(
|
|
15654
15725
|
"div",
|
|
15655
15726
|
{
|
|
15656
15727
|
style: {
|
|
@@ -15663,7 +15734,7 @@ function PersonalizationProvider({
|
|
|
15663
15734
|
pointerEvents: "none"
|
|
15664
15735
|
},
|
|
15665
15736
|
"aria-hidden": true,
|
|
15666
|
-
children: /* @__PURE__ */ (0,
|
|
15737
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
15667
15738
|
CanvasComponent,
|
|
15668
15739
|
{
|
|
15669
15740
|
initialElements: canvasState?.elements,
|
|
@@ -15683,7 +15754,7 @@ function PersonalizationProvider({
|
|
|
15683
15754
|
exportImageQuality: exportConfig?.imageQuality ?? 0.85,
|
|
15684
15755
|
onExport: handleExport,
|
|
15685
15756
|
onExportScheduled: handleExportScheduled,
|
|
15686
|
-
overlay: /* @__PURE__ */ (0,
|
|
15757
|
+
overlay: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(BridgeComponent, { fields, values: personValues })
|
|
15687
15758
|
}
|
|
15688
15759
|
)
|
|
15689
15760
|
},
|
|
@@ -15708,7 +15779,7 @@ function usePersonalizationOptional() {
|
|
|
15708
15779
|
}
|
|
15709
15780
|
|
|
15710
15781
|
// src/personalization/PersonalizationInputs.tsx
|
|
15711
|
-
var
|
|
15782
|
+
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
15712
15783
|
function PersonalizationInputs({
|
|
15713
15784
|
className,
|
|
15714
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",
|
|
@@ -15732,8 +15803,8 @@ function PersonalizationInputs({
|
|
|
15732
15803
|
scrollInputAboveKeyboard(e.target);
|
|
15733
15804
|
}
|
|
15734
15805
|
};
|
|
15735
|
-
return /* @__PURE__ */ (0,
|
|
15736
|
-
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)(
|
|
15737
15808
|
"input",
|
|
15738
15809
|
{
|
|
15739
15810
|
type: "text",
|
|
@@ -15747,8 +15818,8 @@ function PersonalizationInputs({
|
|
|
15747
15818
|
},
|
|
15748
15819
|
`text-${field.name}`
|
|
15749
15820
|
)),
|
|
15750
|
-
colorFields.map((field) => /* @__PURE__ */ (0,
|
|
15751
|
-
/* @__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)(
|
|
15752
15823
|
"input",
|
|
15753
15824
|
{
|
|
15754
15825
|
type: "color",
|
|
@@ -15757,9 +15828,9 @@ function PersonalizationInputs({
|
|
|
15757
15828
|
onChange: (e) => updateField(field.color, e.target.value)
|
|
15758
15829
|
}
|
|
15759
15830
|
),
|
|
15760
|
-
/* @__PURE__ */ (0,
|
|
15831
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "text-base text-muted-foreground", children: field.label })
|
|
15761
15832
|
] }, `color-${field.color}`)),
|
|
15762
|
-
imageFields.map((field) => /* @__PURE__ */ (0,
|
|
15833
|
+
imageFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
15763
15834
|
"input",
|
|
15764
15835
|
{
|
|
15765
15836
|
type: "text",
|
|
@@ -15777,15 +15848,15 @@ function PersonalizationInputs({
|
|
|
15777
15848
|
}
|
|
15778
15849
|
|
|
15779
15850
|
// src/personalization/usePersonalizationShimmer.ts
|
|
15780
|
-
var
|
|
15851
|
+
var import_react69 = require("react");
|
|
15781
15852
|
function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
15782
15853
|
const personCtx = usePersonalizationContext();
|
|
15783
15854
|
const realtime = useRealtimeOptional();
|
|
15784
|
-
const [shimmerActive, setShimmerActive] = (0,
|
|
15785
|
-
const sdkSettledRef = (0,
|
|
15786
|
-
const manualTriggerRef = (0,
|
|
15787
|
-
const safetyTimeoutRef = (0,
|
|
15788
|
-
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)(() => {
|
|
15789
15860
|
setShimmerActive(true);
|
|
15790
15861
|
if (safetyTimeoutRef.current) clearTimeout(safetyTimeoutRef.current);
|
|
15791
15862
|
safetyTimeoutRef.current = setTimeout(
|
|
@@ -15797,25 +15868,25 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
15797
15868
|
safetyTimeoutMs
|
|
15798
15869
|
);
|
|
15799
15870
|
}, [safetyTimeoutMs]);
|
|
15800
|
-
(0,
|
|
15871
|
+
(0, import_react69.useEffect)(() => {
|
|
15801
15872
|
if (!personCtx?.isActive) return;
|
|
15802
15873
|
sdkSettledRef.current = false;
|
|
15803
15874
|
manualTriggerRef.current = false;
|
|
15804
15875
|
realtime?.resetPipelineSettled();
|
|
15805
15876
|
startShimmer();
|
|
15806
15877
|
}, [personCtx?.personValues, personCtx?.isActive, startShimmer]);
|
|
15807
|
-
const triggerShimmer = (0,
|
|
15878
|
+
const triggerShimmer = (0, import_react69.useCallback)(() => {
|
|
15808
15879
|
sdkSettledRef.current = false;
|
|
15809
15880
|
manualTriggerRef.current = true;
|
|
15810
15881
|
startShimmer();
|
|
15811
15882
|
}, [startShimmer]);
|
|
15812
|
-
(0,
|
|
15883
|
+
(0, import_react69.useEffect)(() => {
|
|
15813
15884
|
if (!realtime?.subscribePipelineSettled) return;
|
|
15814
15885
|
return realtime.subscribePipelineSettled(() => {
|
|
15815
15886
|
sdkSettledRef.current = true;
|
|
15816
15887
|
});
|
|
15817
15888
|
}, [realtime]);
|
|
15818
|
-
(0,
|
|
15889
|
+
(0, import_react69.useEffect)(() => {
|
|
15819
15890
|
const container = containerRef.current;
|
|
15820
15891
|
if (!container) return;
|
|
15821
15892
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -15858,7 +15929,7 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
15858
15929
|
});
|
|
15859
15930
|
return () => observer.disconnect();
|
|
15860
15931
|
}, [containerRef]);
|
|
15861
|
-
(0,
|
|
15932
|
+
(0, import_react69.useEffect)(() => {
|
|
15862
15933
|
return () => {
|
|
15863
15934
|
if (safetyTimeoutRef.current) clearTimeout(safetyTimeoutRef.current);
|
|
15864
15935
|
};
|
|
@@ -16000,6 +16071,7 @@ function usePersonalizationShimmer(containerRef, safetyTimeoutMs = 1e4) {
|
|
|
16000
16071
|
RealtimeProvider,
|
|
16001
16072
|
ResponsiveZoom,
|
|
16002
16073
|
RightToLeftProgressiveBlur,
|
|
16074
|
+
SafeImg,
|
|
16003
16075
|
ScrollFade,
|
|
16004
16076
|
SearchBox,
|
|
16005
16077
|
SearchProvider,
|