@thefittingroom/shop-ui 5.0.27 → 5.0.29

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.
Files changed (2) hide show
  1. package/dist/index.js +158 -38
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -19358,7 +19358,7 @@ const loading$1 = "Loading...";
19358
19358
  const add_to_fitting_room$1 = "Add to Fitting Room";
19359
19359
  const added_to_fitting_room$1 = "In Fitting Room";
19360
19360
  const view_fitting_room$1 = "Fitting Room";
19361
- const fitting_room$1 = { "title": "Fitting Room", "empty": "Your fitting room is empty.", "size_not_chosen": "Size not chosen — pick one before trying on.", "remove": "Remove", "ungrouped": "Other", "try_it_on": "Try it on", "view_product_details": "View product details", "hide_product_details": "Hide product details", "add_to_cart": "Add to cart", "recommended_sizes": "Recommended sizes", "shop_now": "Shop now", "sign_out": "Sign out", "try_it_tucked_in": "Try it tucked in", "try_it_untucked": "Try it untucked", "avatar_placeholder_empty": "Add clothes to try on by selecting items in the rails.", "avatar_placeholder_selected": "Avatar render will appear here once VTO is wired up.", "see_selected_items": "See Selected Items", "no_selection": "Nothing selected yet.", "tuck_in": "Tuck In", "untuck": "Untuck", "zoom_in": "Zoom In", "zoom_out": "Zoom Out", "vto_error": "Couldn't load the try-on. Please try again." };
19361
+ const fitting_room$1 = { "title": "Fitting Room", "empty": "Your fitting room is empty.", "size_not_chosen": "Size not chosen — pick one before trying on.", "remove": "Remove", "ungrouped": "Other", "try_it_on": "Try it on", "view_product_details": "View product details", "hide_product_details": "Hide product details", "add_to_cart": "Add to cart", "recommended_sizes": "Recommended sizes", "shop_now": "Shop now", "sign_out": "Sign out", "clear_all": "Clear All", "try_it_tucked_in": "Try it tucked in", "try_it_untucked": "Try it untucked", "avatar_placeholder_empty": "Add clothes to try on by selecting items in the rails.", "avatar_placeholder_selected": "Avatar render will appear here once VTO is wired up.", "see_selected_items": "See Selected Items", "no_selection": "Nothing selected yet.", "tuck_in": "Tuck In", "untuck": "Untuck", "zoom_in": "Zoom In", "zoom_out": "Zoom Out", "vto_error": "Couldn't load the try-on. Please try again." };
19362
19362
  const landing$1 = { "header": "Meet your mini me!", "description": "Loose on your waist but tight on your hips? We’ll show you.", "get_the_app": "Get the app", "already_have_account": "Already have an account?", "sign_in": "Sign in." };
19363
19363
  const en$1 = {
19364
19364
  try_it_on: try_it_on$1,
@@ -41432,7 +41432,7 @@ async function _init$4() {
41432
41432
  config,
41433
41433
  testHooks
41434
41434
  } = getStaticData();
41435
- if (testHooks !== void 0) {
41435
+ if (testHooks && (testHooks.auth !== void 0 || testHooks.firestore !== void 0)) {
41436
41436
  const seedDocs = {
41437
41437
  ...testHooks.firestore?.docs ?? {}
41438
41438
  };
@@ -42769,7 +42769,17 @@ function ProductCard({
42769
42769
  onClick();
42770
42770
  };
42771
42771
  const name2 = item.merchantProduct?.productName ?? item.externalId;
42772
- const selectedVariant = item.merchantProduct?.variants.find((v) => v.color === item.storage.color && (!item.storage.size || v.size === item.storage.size));
42772
+ let effectiveColor = item.storage.color;
42773
+ if (!effectiveColor && item.loadedProduct) {
42774
+ const sizeRec = item.loadedProduct.sizeFitRecommendation;
42775
+ const recommendedSize = sizeRec.available_sizes.find((s) => s.id === sizeRec.recommended_size.id);
42776
+ const firstCsa = recommendedSize?.colorway_size_assets[0];
42777
+ if (firstCsa) {
42778
+ const variant = item.merchantProduct?.variants.find((v) => v.sku === firstCsa.sku);
42779
+ effectiveColor = variant?.color ?? null;
42780
+ }
42781
+ }
42782
+ const selectedVariant = item.merchantProduct?.variants.find((v) => v.color === effectiveColor && (!item.storage.size || v.size === item.storage.size));
42773
42783
  const imageUrl = selectedVariant?.imageUrl ?? item.merchantProduct?.imageUrl ?? null;
42774
42784
  const price = selectedVariant?.priceFormatted ?? item.merchantProduct?.variants[0]?.priceFormatted ?? null;
42775
42785
  return /* @__PURE__ */ jsxs("div", { css: /* @__PURE__ */ css$1({
@@ -43653,7 +43663,8 @@ function DesktopLayout$1({
43653
43663
  onChangeColor,
43654
43664
  onAddToCart,
43655
43665
  onToggleUntuck,
43656
- onSignOut
43666
+ onSignOut,
43667
+ onClearAll
43657
43668
  }) {
43658
43669
  const hasSelection = selectedItems.length > 0;
43659
43670
  const [avatarHovered, setAvatarHovered] = reactExports.useState(false);
@@ -43714,32 +43725,44 @@ function DesktopLayout$1({
43714
43725
  gap: "24px",
43715
43726
  padding: `26px ${EDGE_INSET_PX}px ${EDGE_INSET_PX}px 8px`
43716
43727
  },
43717
- // Sign-out is overlaid on the top-right corner of the rails column so it
43718
- // shares a row with the first card-rail header rather than reserving its
43719
- // own row. It scrolls away with the content, which is fine — it only
43720
- // needs to overlap that first header.
43721
- signOutWrapper: {
43722
- position: "absolute",
43723
- // Near the overlay top, partially overlapping the first card-rail
43724
- // header row below it.
43725
- top: "15px",
43726
- right: "24px",
43727
- zIndex: 3,
43728
+ // Shared icon+link visual for the rails column's two utility actions
43729
+ // (Clear All in the top-right corner, Sign Out at the bottom). Callers
43730
+ // add their own positioning on top.
43731
+ utilityLink: {
43728
43732
  display: "inline-flex",
43729
43733
  alignItems: "center",
43730
43734
  gap: "8px",
43731
43735
  cursor: "pointer",
43732
43736
  color: _theme.color_tfr_800
43733
43737
  },
43734
- signOutIcon: {
43738
+ utilityIcon: {
43735
43739
  width: "12px",
43736
43740
  height: "22px",
43737
43741
  fill: _theme.color_tfr_800,
43738
43742
  flex: "none"
43739
43743
  },
43740
- signOut: {
43744
+ utilityText: {
43741
43745
  color: _theme.color_tfr_800,
43742
43746
  fontSize: "14px"
43747
+ },
43748
+ // Clear All is overlaid on the top-right corner of the rails column so it
43749
+ // shares a row with the first card-rail header rather than reserving its
43750
+ // own row. It scrolls away with the content, which is fine — it only
43751
+ // needs to overlap that first header.
43752
+ clearAllWrapper: {
43753
+ position: "absolute",
43754
+ top: "15px",
43755
+ right: "24px",
43756
+ zIndex: 3
43757
+ },
43758
+ // Sign Out sits at the bottom of the rails column, after the last card
43759
+ // rail. It scrolls with the content — visible once the shopper reaches
43760
+ // the end of their items. marginTop: auto in a flex column would only
43761
+ // help with a non-scrolling parent; here the scroll context makes a
43762
+ // top margin enough to separate it from the last rail above.
43763
+ signOutWrapper: {
43764
+ marginTop: "8px",
43765
+ justifyContent: "center"
43743
43766
  }
43744
43767
  }));
43745
43768
  const controls = hasSelection ? /* @__PURE__ */ jsx$1(AvatarControls, { selectedItems, canTuck, forceUntuck, zoomed: zoomOpen, expanded: avatarHovered, onToggleUntuck, onToggleZoom: () => setZoomOpen(true), onRemoveItem }) : null;
@@ -43749,11 +43772,18 @@ function DesktopLayout$1({
43749
43772
  /* @__PURE__ */ jsx$1("div", { css: css2.avatarColumn, onMouseEnter: () => setAvatarHovered(true), onMouseLeave: () => setAvatarHovered(false), children: /* @__PURE__ */ jsx$1(AvatarPane, { hasSelection, frameUrls, controls, selectedFrameIndex, setSelectedFrameIndex, autoRotateTrigger }) }),
43750
43773
  hasSelection ? /* @__PURE__ */ jsx$1("div", { css: css2.detailColumn, children: /* @__PURE__ */ jsx$1(DetailAccordion, { items: selectedItems, openItemExternalId: openAccordionItemId, platform: "desktop", detailMode, isMobileQuickRow: false, forceUntuck, canTuck, onOpenItem: onOpenAccordionItem, onChangeDetailMode, onChangeSize, onChangeColor, onAddToCart, onToggleUntuck }) }) : null,
43751
43774
  /* @__PURE__ */ jsxs("div", { css: css2.railsColumn, children: [
43752
- /* @__PURE__ */ jsxs("span", { css: css2.signOutWrapper, onClick: onSignOut, children: [
43753
- /* @__PURE__ */ jsx$1(SvgTfrIcon, { css: css2.signOutIcon }),
43754
- /* @__PURE__ */ jsx$1(LinkT, { variant: "underline", css: css2.signOut, t: "fitting_room.sign_out" })
43755
- ] }),
43756
- resolved.groups.map((group) => /* @__PURE__ */ jsx$1(CardRail, { group, availabilityByExternalId, onSelectItem, onRemoveItem }, group.group.name))
43775
+ /* @__PURE__ */ jsx$1("span", { css: /* @__PURE__ */ css$1({
43776
+ ...css2.utilityLink,
43777
+ ...css2.clearAllWrapper
43778
+ }, "", ""), onClick: onClearAll, children: /* @__PURE__ */ jsx$1(LinkT, { variant: "underline", css: css2.utilityText, t: "fitting_room.clear_all" }) }),
43779
+ resolved.groups.map((group) => /* @__PURE__ */ jsx$1(CardRail, { group, availabilityByExternalId, onSelectItem, onRemoveItem }, group.group.name)),
43780
+ /* @__PURE__ */ jsxs("span", { css: /* @__PURE__ */ css$1({
43781
+ ...css2.utilityLink,
43782
+ ...css2.signOutWrapper
43783
+ }, "", ""), onClick: onSignOut, children: [
43784
+ /* @__PURE__ */ jsx$1(SvgTfrIcon, { css: css2.utilityIcon }),
43785
+ /* @__PURE__ */ jsx$1(LinkT, { variant: "underline", css: css2.utilityText, t: "fitting_room.sign_out" })
43786
+ ] })
43757
43787
  ] }),
43758
43788
  zoomOpen && frameUrls && frameUrls.length > 0 ? /* @__PURE__ */ jsx$1(ZoomModal, { frameUrls, selectedFrameIndex, setSelectedFrameIndex, onClose: () => setZoomOpen(false) }) : null
43759
43789
  ] });
@@ -43885,10 +43915,12 @@ function MobileLayout$1({
43885
43915
  onChangeSize,
43886
43916
  onChangeColor,
43887
43917
  onAddToCart,
43888
- onToggleUntuck
43918
+ onToggleUntuck,
43919
+ onSignOut,
43920
+ onClearAll
43889
43921
  }) {
43890
43922
  if (mode === "browse") {
43891
- return /* @__PURE__ */ jsx$1(BrowseView, { resolved, availabilityByExternalId, selectedCount: selectedItems.length, onSelectItem, onRemoveItem, onTryItOn });
43923
+ return /* @__PURE__ */ jsx$1(BrowseView, { resolved, availabilityByExternalId, selectedCount: selectedItems.length, onSelectItem, onRemoveItem, onTryItOn, onSignOut, onClearAll });
43892
43924
  }
43893
43925
  return /* @__PURE__ */ jsx$1(TryOnView, { selectedItems, openAccordionItemId, detailMode, forceUntuck, canTuck, frameUrls, autoRotateTrigger, sheetSnap, sheetTouchStart, onBackToBrowse, onOpenAccordionItem, onChangeDetailMode, onChangeSize, onChangeColor, onAddToCart, onToggleUntuck });
43894
43926
  }
@@ -43898,7 +43930,9 @@ function BrowseView({
43898
43930
  selectedCount,
43899
43931
  onSelectItem,
43900
43932
  onRemoveItem,
43901
- onTryItOn
43933
+ onTryItOn,
43934
+ onSignOut,
43935
+ onClearAll
43902
43936
  }) {
43903
43937
  const railsAreaRef = reactExports.useRef(null);
43904
43938
  const sectionRefs = reactExports.useRef(/* @__PURE__ */ new Map());
@@ -43941,13 +43975,13 @@ function BrowseView({
43941
43975
  behavior: "smooth"
43942
43976
  });
43943
43977
  }, []);
43944
- const css2 = useCss((_theme) => ({
43978
+ const css2 = useCss((theme) => ({
43945
43979
  container: {
43946
43980
  display: "flex",
43947
43981
  flexDirection: "column",
43948
43982
  height: "100%",
43949
43983
  width: "100%",
43950
- // Positioning context for the floating SectionNav pill.
43984
+ // Positioning context for the floating SectionNav + Clear All pills.
43951
43985
  position: "relative"
43952
43986
  },
43953
43987
  railsArea: {
@@ -43958,6 +43992,62 @@ function BrowseView({
43958
43992
  flexDirection: "column",
43959
43993
  gap: "24px"
43960
43994
  },
43995
+ // Sign Out lives at the very bottom of the scrollable card list — same
43996
+ // pattern as desktop. Centered icon+link in TFR teal. Scrolls into view
43997
+ // once the shopper reaches the end of their items.
43998
+ signOutWrapper: {
43999
+ display: "inline-flex",
44000
+ alignItems: "center",
44001
+ justifyContent: "center",
44002
+ gap: "8px",
44003
+ cursor: "pointer",
44004
+ color: theme.color_tfr_800,
44005
+ marginTop: "8px"
44006
+ },
44007
+ signOutIcon: {
44008
+ width: "12px",
44009
+ height: "22px",
44010
+ fill: theme.color_tfr_800,
44011
+ flex: "none"
44012
+ },
44013
+ signOutText: {
44014
+ color: theme.color_tfr_800,
44015
+ fontSize: "14px"
44016
+ },
44017
+ // Clear All — white pill with thin black border, black text. Positioned
44018
+ // absolute over the BrowseView container, bottom-right, offset to clear
44019
+ // the Try It On CTA bar below it. Pill shape matches the SectionNav
44020
+ // pill at the top-right, but inverted on color for visual contrast.
44021
+ clearAllPill: {
44022
+ position: "absolute",
44023
+ bottom: "96px",
44024
+ right: "16px",
44025
+ zIndex: 5,
44026
+ display: "inline-flex",
44027
+ alignItems: "center",
44028
+ gap: "8px",
44029
+ padding: "6px 16px",
44030
+ borderRadius: "999px",
44031
+ backgroundColor: "#FFFFFF",
44032
+ color: theme.color_fg_text,
44033
+ border: `1px solid ${theme.color_fg_text}`,
44034
+ cursor: "pointer",
44035
+ fontSize: "13px",
44036
+ fontWeight: "500",
44037
+ letterSpacing: "0.5px",
44038
+ textTransform: "uppercase",
44039
+ whiteSpace: "nowrap"
44040
+ },
44041
+ clearAllText: {
44042
+ color: theme.color_fg_text
44043
+ },
44044
+ clearAllIcon: {
44045
+ width: "12px",
44046
+ height: "12px",
44047
+ flex: "none"
44048
+ // close-icon.svg's <path>s have a hardcoded dark fill — already matches
44049
+ // the new black-on-white pill, no override needed.
44050
+ },
43961
44051
  bottomBar: {
43962
44052
  flex: "none",
43963
44053
  padding: "16px",
@@ -43967,13 +44057,23 @@ function BrowseView({
43967
44057
  }));
43968
44058
  return /* @__PURE__ */ jsxs("div", { css: css2.container, children: [
43969
44059
  !resolved.isLoading && resolved.groups.length > 0 ? /* @__PURE__ */ jsx$1(SectionNav, { sections, activeName: activeSectionName, onSelect: scrollToSection }) : null,
43970
- /* @__PURE__ */ jsx$1("div", { ref: railsAreaRef, css: css2.railsArea, onScroll: recomputeActiveSection, children: resolved.groups.map((group) => /* @__PURE__ */ jsx$1("div", { ref: (el) => {
43971
- if (el) {
43972
- sectionRefs.current.set(group.group.name, el);
43973
- } else {
43974
- sectionRefs.current.delete(group.group.name);
43975
- }
43976
- }, children: /* @__PURE__ */ jsx$1(CardRail, { group, availabilityByExternalId, onSelectItem, onRemoveItem }) }, group.group.name)) }),
44060
+ /* @__PURE__ */ jsxs("div", { ref: railsAreaRef, css: css2.railsArea, onScroll: recomputeActiveSection, children: [
44061
+ resolved.groups.map((group) => /* @__PURE__ */ jsx$1("div", { ref: (el) => {
44062
+ if (el) {
44063
+ sectionRefs.current.set(group.group.name, el);
44064
+ } else {
44065
+ sectionRefs.current.delete(group.group.name);
44066
+ }
44067
+ }, children: /* @__PURE__ */ jsx$1(CardRail, { group, availabilityByExternalId, onSelectItem, onRemoveItem }) }, group.group.name)),
44068
+ /* @__PURE__ */ jsxs("span", { css: css2.signOutWrapper, onClick: onSignOut, children: [
44069
+ /* @__PURE__ */ jsx$1(SvgTfrIcon, { css: css2.signOutIcon }),
44070
+ /* @__PURE__ */ jsx$1(LinkT, { variant: "underline", css: css2.signOutText, t: "fitting_room.sign_out" })
44071
+ ] })
44072
+ ] }),
44073
+ /* @__PURE__ */ jsxs(Button, { variant: "base", css: css2.clearAllPill, onClick: onClearAll, children: [
44074
+ /* @__PURE__ */ jsx$1(TextT, { variant: "base", css: css2.clearAllText, t: "fitting_room.clear_all" }),
44075
+ /* @__PURE__ */ jsx$1(SvgCloseIcon, { css: css2.clearAllIcon })
44076
+ ] }),
43977
44077
  resolved.groups.length > 0 ? /* @__PURE__ */ jsx$1("div", { css: css2.bottomBar, children: /* @__PURE__ */ jsx$1(ButtonT, { variant: "brand", t: "fitting_room.try_it_on", onClick: onTryItOn, disabled: selectedCount === 0 }) }) : null
43978
44078
  ] });
43979
44079
  }
@@ -44231,6 +44331,7 @@ function FittingRoomOverlay({
44231
44331
  const openOverlay = useMainStore((state) => state.openOverlay);
44232
44332
  const updateFittingRoomItem = useMainStore((state) => state.updateFittingRoomItem);
44233
44333
  const removeFromFittingRoom = useMainStore((state) => state.removeFromFittingRoom);
44334
+ const clearFittingRoom = useMainStore((state) => state.clearFittingRoom);
44234
44335
  const resolved = useResolvedFittingRoom();
44235
44336
  const [topOffset, setTopOffset] = reactExports.useState(0);
44236
44337
  const [selectedExternalIds, setSelectedExternalIds] = reactExports.useState(() => /* @__PURE__ */ new Set());
@@ -44448,6 +44549,13 @@ function FittingRoomOverlay({
44448
44549
  setOpenAccordionItemId(null);
44449
44550
  }
44450
44551
  }, [openAccordionItemId, selectedExternalIds]);
44552
+ reactExports.useEffect(() => {
44553
+ if (sheetSnap !== "full" || openAccordionItemId !== null || selectedItems.length === 0) {
44554
+ return;
44555
+ }
44556
+ const lastAddedSelected = lastAddedExternalId && selectedExternalIds.has(lastAddedExternalId) ? lastAddedExternalId : null;
44557
+ setOpenAccordionItemId(lastAddedSelected ?? selectedItems[0].externalId);
44558
+ }, [sheetSnap, openAccordionItemId, selectedItems, lastAddedExternalId, selectedExternalIds]);
44451
44559
  const preselectAppliedRef = reactExports.useRef(false);
44452
44560
  reactExports.useEffect(() => {
44453
44561
  if (preselectAppliedRef.current || !preselectExternalId) {
@@ -44509,6 +44617,11 @@ function FittingRoomOverlay({
44509
44617
  });
44510
44618
  });
44511
44619
  }, [closeOverlay]);
44620
+ const handleClearAll = reactExports.useCallback(() => {
44621
+ clearFittingRoom();
44622
+ setSelectedExternalIds(/* @__PURE__ */ new Set());
44623
+ setOpenAccordionItemId(null);
44624
+ }, [clearFittingRoom]);
44512
44625
  const handleShopNow = reactExports.useCallback(() => {
44513
44626
  closeOverlay();
44514
44627
  }, [closeOverlay]);
@@ -44581,7 +44694,7 @@ function FittingRoomOverlay({
44581
44694
  /* @__PURE__ */ jsx$1(TextT, { variant: "base", css: css2.emptyTagline, t: "landing.description" }),
44582
44695
  /* @__PURE__ */ jsx$1("div", { css: css2.emptyShopNow, children: /* @__PURE__ */ jsx$1(ButtonT, { variant: "primary", t: "fitting_room.shop_now", onClick: handleShopNow }) }),
44583
44696
  userIsLoggedIn ? /* @__PURE__ */ jsx$1(LinkT, { variant: "underline", css: css2.emptySignOut, t: "fitting_room.sign_out", onClick: handleSignOut }) : null
44584
- ] }) }) : isMobileLayout ? /* @__PURE__ */ jsx$1(MobileLayout$1, { mode: mobileMode, resolved, selectedItems, availabilityByExternalId, openAccordionItemId, detailMode, forceUntuck, canTuck, frameUrls, autoRotateTrigger, sheetSnap, sheetTouchStart, onSelectItem: handleSelectItem, onRemoveItem: handleRemoveItem, onTryItOn: handleTryItOn, onBackToBrowse: handleBackToBrowse, onOpenAccordionItem: setOpenAccordionItemId, onChangeDetailMode: setDetailMode, onChangeSize: handleChangeSize, onChangeColor: handleChangeColor, onAddToCart: handleAddToCart, onToggleUntuck: handleToggleUntuck }) : /* @__PURE__ */ jsx$1(DesktopLayout$1, { resolved, selectedItems, availabilityByExternalId, openAccordionItemId, detailMode, forceUntuck, canTuck, frameUrls, autoRotateTrigger, onSelectItem: handleSelectItem, onRemoveItem: handleRemoveItem, onOpenAccordionItem: setOpenAccordionItemId, onChangeDetailMode: setDetailMode, onChangeSize: handleChangeSize, onChangeColor: handleChangeColor, onAddToCart: handleAddToCart, onToggleUntuck: handleToggleUntuck, onSignOut: handleSignOut }),
44697
+ ] }) }) : isMobileLayout ? /* @__PURE__ */ jsx$1(MobileLayout$1, { mode: mobileMode, resolved, selectedItems, availabilityByExternalId, openAccordionItemId, detailMode, forceUntuck, canTuck, frameUrls, autoRotateTrigger, sheetSnap, sheetTouchStart, onSelectItem: handleSelectItem, onRemoveItem: handleRemoveItem, onTryItOn: handleTryItOn, onBackToBrowse: handleBackToBrowse, onOpenAccordionItem: setOpenAccordionItemId, onChangeDetailMode: setDetailMode, onChangeSize: handleChangeSize, onChangeColor: handleChangeColor, onAddToCart: handleAddToCart, onToggleUntuck: handleToggleUntuck, onSignOut: handleSignOut, onClearAll: handleClearAll }) : /* @__PURE__ */ jsx$1(DesktopLayout$1, { resolved, selectedItems, availabilityByExternalId, openAccordionItemId, detailMode, forceUntuck, canTuck, frameUrls, autoRotateTrigger, onSelectItem: handleSelectItem, onRemoveItem: handleRemoveItem, onOpenAccordionItem: setOpenAccordionItemId, onChangeDetailMode: setDetailMode, onChangeSize: handleChangeSize, onChangeColor: handleChangeColor, onAddToCart: handleAddToCart, onToggleUntuck: handleToggleUntuck, onSignOut: handleSignOut, onClearAll: handleClearAll }),
44585
44698
  vtoError ? /* @__PURE__ */ jsx$1(Snackbar, { messageKey: "fitting_room.vto_error", onDismiss: clearVtoError }) : null
44586
44699
  ] }) });
44587
44700
  }
@@ -46719,6 +46832,13 @@ var DeviceLayout = /* @__PURE__ */ ((DeviceLayout2) => {
46719
46832
  })(DeviceLayout || {});
46720
46833
  function _init$1() {
46721
46834
  function getDeviceData() {
46835
+ const testDevice = getStaticData().testHooks?.device;
46836
+ if (testDevice) {
46837
+ return {
46838
+ isMobileDevice: testDevice.isMobileDevice ?? testDevice.layout.startsWith("mobile"),
46839
+ deviceLayout: testDevice.layout
46840
+ };
46841
+ }
46722
46842
  const bowserParser = Bowser.getParser(window.navigator.userAgent);
46723
46843
  const {
46724
46844
  width,
@@ -46983,9 +47103,9 @@ const SHARED_CONFIG = {
46983
47103
  appGooglePlayUrl: "https://play.google.com/store/apps/details?id=com.thefittingroom.marketplace"
46984
47104
  },
46985
47105
  build: {
46986
- version: `${"5.0.27"}`,
46987
- commitHash: `${"9e3e717"}`,
46988
- date: `${"2026-05-24T21:00:26.048Z"}`
47106
+ version: `${"5.0.29"}`,
47107
+ commitHash: `${"538bbd3"}`,
47108
+ date: `${"2026-05-25T01:10:21.610Z"}`
46989
47109
  }
46990
47110
  };
46991
47111
  const CONFIGS = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thefittingroom/shop-ui",
3
- "version": "5.0.27",
3
+ "version": "5.0.29",
4
4
  "description": "the fitting room UI library",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",