@thefittingroom/shop-ui 5.0.30 → 5.0.31

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 +66 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -42073,14 +42073,38 @@ function pairCompatible(a, b, group) {
42073
42073
  }
42074
42074
  return aIncl.includes(bName) || bIncl.includes(aName);
42075
42075
  }
42076
+ function getSameCategoryConflicts(item, selectedExternalIds, resolved) {
42077
+ if (!item.styleCategory) {
42078
+ return [];
42079
+ }
42080
+ const itemName = catName(item.styleCategory);
42081
+ const out = [];
42082
+ for (const sel of resolved.items) {
42083
+ if (sel.externalId === item.externalId) {
42084
+ continue;
42085
+ }
42086
+ if (!selectedExternalIds.has(sel.externalId)) {
42087
+ continue;
42088
+ }
42089
+ if (!sel.styleCategory) {
42090
+ continue;
42091
+ }
42092
+ if (catName(sel.styleCategory) === itemName) {
42093
+ out.push(sel.externalId);
42094
+ }
42095
+ }
42096
+ return out;
42097
+ }
42076
42098
  function computeAvailability(item, selectedExternalIds, resolved) {
42077
42099
  if (selectedExternalIds.has(item.externalId)) {
42078
42100
  return "selected";
42079
42101
  }
42080
- if (selectedExternalIds.size >= MAX_OUTFIT_ITEMS) {
42102
+ if (!item.styleCategory) {
42081
42103
  return "disabled";
42082
42104
  }
42083
- if (!item.styleCategory) {
42105
+ const sameCategoryEvictions = new Set(getSameCategoryConflicts(item, selectedExternalIds, resolved));
42106
+ const effectiveSize = selectedExternalIds.size - sameCategoryEvictions.size + 1;
42107
+ if (effectiveSize > MAX_OUTFIT_ITEMS) {
42084
42108
  return "disabled";
42085
42109
  }
42086
42110
  const itemCat = item.styleCategory;
@@ -42088,6 +42112,9 @@ function computeAvailability(item, selectedExternalIds, resolved) {
42088
42112
  if (!selectedExternalIds.has(sel.externalId)) {
42089
42113
  continue;
42090
42114
  }
42115
+ if (sameCategoryEvictions.has(sel.externalId)) {
42116
+ continue;
42117
+ }
42091
42118
  if (!sel.styleCategory) {
42092
42119
  continue;
42093
42120
  }
@@ -42824,6 +42851,24 @@ function ProductCard({
42824
42851
  removeIcon: {
42825
42852
  width: "12px",
42826
42853
  height: "12px"
42854
+ },
42855
+ // Selected badge — mirrors the X button at the top-right, green-filled
42856
+ // circle at top-left with an inline white checkmark. Only rendered when
42857
+ // availability === 'selected'. Decorative: pointer-events: none so the
42858
+ // shopper still taps the card body underneath to toggle off.
42859
+ selectedBadge: {
42860
+ position: "absolute",
42861
+ top: "4px",
42862
+ left: "4px",
42863
+ width: "24px",
42864
+ height: "24px",
42865
+ borderRadius: "12px",
42866
+ backgroundColor: "#22C55E",
42867
+ display: "flex",
42868
+ alignItems: "center",
42869
+ justifyContent: "center",
42870
+ pointerEvents: "none",
42871
+ zIndex: 1
42827
42872
  }
42828
42873
  }));
42829
42874
  const disabled = availability === "disabled";
@@ -42880,6 +42925,7 @@ function ProductCard({
42880
42925
  e.stopPropagation();
42881
42926
  onRemove();
42882
42927
  }, "aria-label": "Remove from fitting room", children: /* @__PURE__ */ jsx$1(SvgCloseIcon, { css: css2.removeIcon }) }),
42928
+ selected ? /* @__PURE__ */ jsx$1("div", { css: css2.selectedBadge, "aria-hidden": "true", children: /* @__PURE__ */ jsx$1("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx$1("path", { d: "M3 8.5L6.5 12L13 4.5", stroke: "#FFFFFF", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }) : null,
42883
42929
  /* @__PURE__ */ jsxs(Button, { variant: "base", css: /* @__PURE__ */ css$1({
42884
42930
  ...css2.cardBody,
42885
42931
  ...disabled && css2.cardBodyDisabled
@@ -42896,7 +42942,8 @@ function CardRail({
42896
42942
  availabilityByExternalId,
42897
42943
  onSelectItem,
42898
42944
  onRemoveItem,
42899
- onChangeColor
42945
+ onChangeColor,
42946
+ sortSelectedFirst
42900
42947
  }) {
42901
42948
  const [collapsed, setCollapsed] = reactExports.useState(false);
42902
42949
  const scrollRef = reactExports.useRef(null);
@@ -43000,7 +43047,12 @@ function CardRail({
43000
43047
  right: 0
43001
43048
  }
43002
43049
  }));
43003
- const cards = group.items.map((item) => /* @__PURE__ */ jsx$1(ProductCard, { item, availability: availabilityByExternalId[item.externalId] ?? "disabled", onClick: () => onSelectItem(item.externalId), onRemove: () => onRemoveItem(item.externalId), onChangeColor }, item.externalId));
43050
+ const orderedItems = sortSelectedFirst ? [...group.items].sort((a, b) => {
43051
+ const aSel = availabilityByExternalId[a.externalId] === "selected" ? 0 : 1;
43052
+ const bSel = availabilityByExternalId[b.externalId] === "selected" ? 0 : 1;
43053
+ return aSel - bSel;
43054
+ }) : group.items;
43055
+ const cards = orderedItems.map((item) => /* @__PURE__ */ jsx$1(ProductCard, { item, availability: availabilityByExternalId[item.externalId] ?? "disabled", onClick: () => onSelectItem(item.externalId), onRemove: () => onRemoveItem(item.externalId), onChangeColor }, item.externalId));
43004
43056
  return /* @__PURE__ */ jsxs("div", { css: css2.container, children: [
43005
43057
  /* @__PURE__ */ jsxs(Button, { variant: "base", css: css2.header, onClick: () => setCollapsed((c) => !c), children: [
43006
43058
  /* @__PURE__ */ jsx$1(Text, { variant: "base", css: css2.headerLabel, children: group.group.label }),
@@ -43867,7 +43919,7 @@ function DesktopLayout$1({
43867
43919
  ...css2.utilityLink,
43868
43920
  ...css2.clearAllWrapper
43869
43921
  }, "", ""), onClick: onClearAll, children: /* @__PURE__ */ jsx$1(LinkT, { variant: "underline", css: css2.utilityText, t: "fitting_room.clear_all" }) }),
43870
- resolved.groups.map((group) => /* @__PURE__ */ jsx$1(CardRail, { group, availabilityByExternalId, onSelectItem, onRemoveItem, onChangeColor }, group.group.name)),
43922
+ resolved.groups.map((group) => /* @__PURE__ */ jsx$1(CardRail, { group, availabilityByExternalId, onSelectItem, onRemoveItem, onChangeColor, sortSelectedFirst: true }, group.group.name)),
43871
43923
  /* @__PURE__ */ jsxs("span", { css: /* @__PURE__ */ css$1({
43872
43924
  ...css2.utilityLink,
43873
43925
  ...css2.signOutWrapper
@@ -44531,6 +44583,12 @@ function FittingRoomOverlay({
44531
44583
  setOpenAccordionItemId(null);
44532
44584
  }
44533
44585
  } else {
44586
+ for (const evictedId of getSameCategoryConflicts(item, selectedExternalIds, resolved)) {
44587
+ nextSelected.delete(evictedId);
44588
+ if (openAccordionItemId === evictedId) {
44589
+ setOpenAccordionItemId(null);
44590
+ }
44591
+ }
44534
44592
  nextSelected.add(externalId);
44535
44593
  ensureSizeForItem(item);
44536
44594
  setLastAddedExternalId(externalId);
@@ -47202,9 +47260,9 @@ const SHARED_CONFIG = {
47202
47260
  appGooglePlayUrl: "https://play.google.com/store/apps/details?id=com.thefittingroom.marketplace"
47203
47261
  },
47204
47262
  build: {
47205
- version: `${"5.0.30"}`,
47206
- commitHash: `${"e4427c3"}`,
47207
- date: `${"2026-06-07T13:46:16.711Z"}`
47263
+ version: `${"5.0.31"}`,
47264
+ commitHash: `${"992c5c6"}`,
47265
+ date: `${"2026-06-07T14:43:50.848Z"}`
47208
47266
  }
47209
47267
  };
47210
47268
  const CONFIGS = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thefittingroom/shop-ui",
3
- "version": "5.0.30",
3
+ "version": "5.0.31",
4
4
  "description": "the fitting room UI library",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",