@timmbr/ui 1.9.0 → 1.11.0

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 (175) hide show
  1. package/dist/components/Breadcrumb/Breadcrumb.d.ts +9 -0
  2. package/dist/components/Breadcrumb/Breadcrumb.d.ts.map +1 -0
  3. package/dist/components/Breadcrumb/Breadcrumb.js +32 -0
  4. package/dist/components/Breadcrumb/Breadcrumb.styles.d.ts +8 -0
  5. package/dist/components/Breadcrumb/Breadcrumb.styles.d.ts.map +1 -0
  6. package/dist/components/Breadcrumb/Breadcrumb.styles.js +20 -0
  7. package/dist/components/Breadcrumb/Breadcrumb.types.d.ts +27 -0
  8. package/dist/components/Breadcrumb/Breadcrumb.types.d.ts.map +1 -0
  9. package/dist/components/Breadcrumb/index.d.ts +4 -0
  10. package/dist/components/Breadcrumb/index.d.ts.map +1 -0
  11. package/dist/components/Chip/Chip.d.ts.map +1 -1
  12. package/dist/components/Chip/Chip.js +13 -3
  13. package/dist/components/Chip/Chip.types.d.ts +5 -0
  14. package/dist/components/Chip/Chip.types.d.ts.map +1 -1
  15. package/dist/components/Drawer/Drawer.d.ts.map +1 -1
  16. package/dist/components/Drawer/Drawer.js +4 -4
  17. package/dist/components/Drawer/Drawer.styles.d.ts +1 -0
  18. package/dist/components/Drawer/Drawer.styles.d.ts.map +1 -1
  19. package/dist/components/Drawer/Drawer.styles.js +7 -1
  20. package/dist/components/Drawer/Drawer.types.d.ts +2 -0
  21. package/dist/components/Drawer/Drawer.types.d.ts.map +1 -1
  22. package/dist/components/FilterChips/FilterChips.d.ts +8 -0
  23. package/dist/components/FilterChips/FilterChips.d.ts.map +1 -0
  24. package/dist/components/FilterChips/FilterChips.js +39 -0
  25. package/dist/components/FilterChips/FilterChips.types.d.ts +17 -0
  26. package/dist/components/FilterChips/FilterChips.types.d.ts.map +1 -0
  27. package/dist/components/FilterChips/index.d.ts +3 -0
  28. package/dist/components/FilterChips/index.d.ts.map +1 -0
  29. package/dist/components/FilterDrawer/FilterDrawer.d.ts +12 -0
  30. package/dist/components/FilterDrawer/FilterDrawer.d.ts.map +1 -0
  31. package/dist/components/FilterDrawer/FilterDrawer.js +157 -0
  32. package/dist/components/FilterDrawer/FilterDrawer.styles.d.ts +12 -0
  33. package/dist/components/FilterDrawer/FilterDrawer.styles.d.ts.map +1 -0
  34. package/dist/components/FilterDrawer/FilterDrawer.styles.js +30 -0
  35. package/dist/components/FilterDrawer/FilterDrawer.types.d.ts +28 -0
  36. package/dist/components/FilterDrawer/FilterDrawer.types.d.ts.map +1 -0
  37. package/dist/components/FilterDrawer/index.d.ts +4 -0
  38. package/dist/components/FilterDrawer/index.d.ts.map +1 -0
  39. package/dist/components/FilterPanel/FilterPanel.d.ts +33 -0
  40. package/dist/components/FilterPanel/FilterPanel.d.ts.map +1 -0
  41. package/dist/components/FilterPanel/FilterPanel.js +239 -0
  42. package/dist/components/FilterPanel/FilterPanel.styles.d.ts +16 -0
  43. package/dist/components/FilterPanel/FilterPanel.styles.d.ts.map +1 -0
  44. package/dist/components/FilterPanel/FilterPanel.styles.js +31 -0
  45. package/dist/components/FilterPanel/FilterPanel.types.d.ts +80 -0
  46. package/dist/components/FilterPanel/FilterPanel.types.d.ts.map +1 -0
  47. package/dist/components/FilterPanel/FilterPanel.types.js +3 -0
  48. package/dist/components/FilterPanel/index.d.ts +4 -0
  49. package/dist/components/FilterPanel/index.d.ts.map +1 -0
  50. package/dist/components/ImageUpload/ImageUpload.styles.d.ts +3 -3
  51. package/dist/components/MediaCard/MediaCard.d.ts.map +1 -1
  52. package/dist/components/MediaCard/MediaCard.js +3 -1
  53. package/dist/components/NavHeader/NavHeader.styles.d.ts +7 -0
  54. package/dist/components/NavHeader/NavHeader.styles.d.ts.map +1 -1
  55. package/dist/components/NavHeader/NavHeader.styles.js +20 -2
  56. package/dist/components/NavHeader/NavHeader.types.d.ts +59 -9
  57. package/dist/components/NavHeader/NavHeader.types.d.ts.map +1 -1
  58. package/dist/components/NavHeader/index.d.ts +3 -2
  59. package/dist/components/NavHeader/index.d.ts.map +1 -1
  60. package/dist/components/NavHeader/subcomponents/NavActions.d.ts +4 -4
  61. package/dist/components/NavHeader/subcomponents/NavActions.d.ts.map +1 -1
  62. package/dist/components/NavHeader/subcomponents/NavActions.js +31 -25
  63. package/dist/components/NavHeader/subcomponents/NavMobileSearchDrawer.d.ts.map +1 -1
  64. package/dist/components/NavHeader/subcomponents/NavMobileSearchDrawer.js +15 -33
  65. package/dist/components/NavHeader/subcomponents/NavSearch.d.ts.map +1 -1
  66. package/dist/components/NavHeader/subcomponents/NavSearch.js +37 -83
  67. package/dist/components/NavHeader/subcomponents/NavSearchPanel.d.ts +63 -0
  68. package/dist/components/NavHeader/subcomponents/NavSearchPanel.d.ts.map +1 -0
  69. package/dist/components/NavHeader/subcomponents/NavSearchPanel.js +289 -0
  70. package/dist/components/NavMenuColumns/NavMenuColumns.styles.js +1 -1
  71. package/dist/components/OptionPicker/OptionPicker.d.ts +10 -0
  72. package/dist/components/OptionPicker/OptionPicker.d.ts.map +1 -0
  73. package/dist/components/OptionPicker/OptionPicker.js +116 -0
  74. package/dist/components/OptionPicker/OptionPicker.styles.d.ts +20 -0
  75. package/dist/components/OptionPicker/OptionPicker.styles.d.ts.map +1 -0
  76. package/dist/components/OptionPicker/OptionPicker.styles.js +60 -0
  77. package/dist/components/OptionPicker/OptionPicker.types.d.ts +39 -0
  78. package/dist/components/OptionPicker/OptionPicker.types.d.ts.map +1 -0
  79. package/dist/components/OptionPicker/index.d.ts +4 -0
  80. package/dist/components/OptionPicker/index.d.ts.map +1 -0
  81. package/dist/components/Price/Price.styles.d.ts.map +1 -1
  82. package/dist/components/Price/Price.styles.js +3 -2
  83. package/dist/components/ProductGallery/ProductGallery.d.ts +10 -0
  84. package/dist/components/ProductGallery/ProductGallery.d.ts.map +1 -0
  85. package/dist/components/ProductGallery/ProductGallery.js +306 -0
  86. package/dist/components/ProductGallery/ProductGallery.styles.d.ts +32 -0
  87. package/dist/components/ProductGallery/ProductGallery.styles.d.ts.map +1 -0
  88. package/dist/components/ProductGallery/ProductGallery.styles.js +86 -0
  89. package/dist/components/ProductGallery/ProductGallery.types.d.ts +55 -0
  90. package/dist/components/ProductGallery/ProductGallery.types.d.ts.map +1 -0
  91. package/dist/components/ProductGallery/ProductGalleryLightbox.d.ts +20 -0
  92. package/dist/components/ProductGallery/ProductGalleryLightbox.d.ts.map +1 -0
  93. package/dist/components/ProductGallery/ProductGalleryLightbox.js +210 -0
  94. package/dist/components/ProductGallery/index.d.ts +4 -0
  95. package/dist/components/ProductGallery/index.d.ts.map +1 -0
  96. package/dist/components/QuantityStepper/QuantityStepper.d.ts +8 -0
  97. package/dist/components/QuantityStepper/QuantityStepper.d.ts.map +1 -0
  98. package/dist/components/QuantityStepper/QuantityStepper.js +65 -0
  99. package/dist/components/QuantityStepper/QuantityStepper.styles.d.ts +8 -0
  100. package/dist/components/QuantityStepper/QuantityStepper.styles.d.ts.map +1 -0
  101. package/dist/components/QuantityStepper/QuantityStepper.styles.js +24 -0
  102. package/dist/components/QuantityStepper/QuantityStepper.types.d.ts +20 -0
  103. package/dist/components/QuantityStepper/QuantityStepper.types.d.ts.map +1 -0
  104. package/dist/components/QuantityStepper/index.d.ts +4 -0
  105. package/dist/components/QuantityStepper/index.d.ts.map +1 -0
  106. package/dist/components/RadioCard/RadioCard.d.ts +9 -0
  107. package/dist/components/RadioCard/RadioCard.d.ts.map +1 -0
  108. package/dist/components/RadioCard/RadioCard.js +40 -0
  109. package/dist/components/RadioCard/RadioCard.styles.d.ts +9 -0
  110. package/dist/components/RadioCard/RadioCard.styles.d.ts.map +1 -0
  111. package/dist/components/RadioCard/RadioCard.styles.js +24 -0
  112. package/dist/components/RadioCard/RadioCard.types.d.ts +28 -0
  113. package/dist/components/RadioCard/RadioCard.types.d.ts.map +1 -0
  114. package/dist/components/RadioCard/index.d.ts +4 -0
  115. package/dist/components/RadioCard/index.d.ts.map +1 -0
  116. package/dist/components/RangeSlider/RangeSlider.d.ts.map +1 -1
  117. package/dist/components/RangeSlider/RangeSlider.js +5 -3
  118. package/dist/components/RangeSlider/RangeSlider.types.d.ts +7 -0
  119. package/dist/components/RangeSlider/RangeSlider.types.d.ts.map +1 -1
  120. package/dist/components/Select/Select.d.ts.map +1 -1
  121. package/dist/components/Select/Select.js +14 -1
  122. package/dist/components/Select/Select.types.d.ts +4 -0
  123. package/dist/components/Select/Select.types.d.ts.map +1 -1
  124. package/dist/components/Skeleton/Skeleton.styles.d.ts +1 -1
  125. package/dist/components/Snackbar/Snackbar.d.ts +9 -0
  126. package/dist/components/Snackbar/Snackbar.d.ts.map +1 -0
  127. package/dist/components/Snackbar/Snackbar.js +108 -0
  128. package/dist/components/Snackbar/Snackbar.styles.d.ts +17 -0
  129. package/dist/components/Snackbar/Snackbar.styles.d.ts.map +1 -0
  130. package/dist/components/Snackbar/Snackbar.styles.js +37 -0
  131. package/dist/components/Snackbar/Snackbar.types.d.ts +36 -0
  132. package/dist/components/Snackbar/Snackbar.types.d.ts.map +1 -0
  133. package/dist/components/Snackbar/SnackbarHost.d.ts +4 -0
  134. package/dist/components/Snackbar/SnackbarHost.d.ts.map +1 -0
  135. package/dist/components/Snackbar/SnackbarHost.js +24 -0
  136. package/dist/components/Snackbar/index.d.ts +6 -0
  137. package/dist/components/Snackbar/index.d.ts.map +1 -0
  138. package/dist/components/Snackbar/snackbarStore.d.ts +42 -0
  139. package/dist/components/Snackbar/snackbarStore.d.ts.map +1 -0
  140. package/dist/components/Snackbar/snackbarStore.js +87 -0
  141. package/dist/components/StockMeter/StockMeter.d.ts +8 -0
  142. package/dist/components/StockMeter/StockMeter.d.ts.map +1 -0
  143. package/dist/components/StockMeter/StockMeter.js +19 -0
  144. package/dist/components/StockMeter/StockMeter.styles.d.ts +4 -0
  145. package/dist/components/StockMeter/StockMeter.styles.d.ts.map +1 -0
  146. package/dist/components/StockMeter/StockMeter.styles.js +7 -0
  147. package/dist/components/StockMeter/StockMeter.types.d.ts +10 -0
  148. package/dist/components/StockMeter/StockMeter.types.d.ts.map +1 -0
  149. package/dist/components/StockMeter/index.d.ts +4 -0
  150. package/dist/components/StockMeter/index.d.ts.map +1 -0
  151. package/dist/components/Swatch/Swatch.d.ts +11 -0
  152. package/dist/components/Swatch/Swatch.d.ts.map +1 -0
  153. package/dist/components/Swatch/Swatch.js +40 -0
  154. package/dist/components/Swatch/Swatch.styles.d.ts +8 -0
  155. package/dist/components/Swatch/Swatch.styles.d.ts.map +1 -0
  156. package/dist/components/Swatch/Swatch.styles.js +26 -0
  157. package/dist/components/Swatch/Swatch.types.d.ts +11 -0
  158. package/dist/components/Swatch/Swatch.types.d.ts.map +1 -0
  159. package/dist/components/Swatch/index.d.ts +4 -0
  160. package/dist/components/Swatch/index.d.ts.map +1 -0
  161. package/dist/components/Toast/Toast.d.ts.map +1 -1
  162. package/dist/components/Toast/Toast.js +49 -42
  163. package/dist/components/Toast/Toast.types.d.ts +7 -0
  164. package/dist/components/Toast/Toast.types.d.ts.map +1 -1
  165. package/dist/components/Toast/ToastContainer.d.ts.map +1 -1
  166. package/dist/components/Toast/ToastContainer.js +5 -0
  167. package/dist/components/Toast/toastStore.d.ts +11 -0
  168. package/dist/components/Toast/toastStore.d.ts.map +1 -1
  169. package/dist/components/Toast/toastStore.js +70 -30
  170. package/dist/index.d.ts +11 -0
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +26 -1
  173. package/dist/providers/TimmbrConfigProvider.d.ts.map +1 -1
  174. package/dist/providers/TimmbrConfigProvider.js +5 -9
  175. package/package.json +5 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterDrawer.types.d.ts","sourceRoot":"","sources":["../../../src/components/FilterDrawer/FilterDrawer.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAE1G,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC;CAC/C;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,6FAA6F;IAC7F,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,6EAA6E;IAC7E,KAAK,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;IACvD,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,qEAAqE;IACrE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B"}
@@ -0,0 +1,4 @@
1
+ export * from './FilterDrawer';
2
+ export * from './FilterDrawer.types';
3
+ export * from './FilterDrawer.styles';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FilterDrawer/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import * as React from 'react';
2
+ import { type FilterGroup, type FilterOption, type FilterOptionListProps, type FilterPanelLabels, type FilterPanelProps, type FilterPriceConfig } from './FilterPanel.types';
3
+ export declare const DEFAULT_FILTER_LABELS: FilterPanelLabels;
4
+ /** An option is unavailable when picking it would show nothing (and it isn't picked already). */
5
+ export declare const isOptionDisabled: (option: FilterOption) => boolean;
6
+ /**
7
+ * The options of one group as checkboxes (with a colour dot for swatch groups) and counts.
8
+ * Long groups show the first `limit` options plus every selected one behind "Show more", and
9
+ * very long groups get a search box. Options that would show nothing are disabled, not hidden,
10
+ * so the list doesn't jump as filters change.
11
+ */
12
+ export declare function FilterOptionList({ group, onToggle, limit, searchThreshold, labels: labelOverrides, className, }: FilterOptionListProps): React.JSX.Element;
13
+ /** Yes/no groups as switches: "Fast Delivery (12)". */
14
+ export declare function FilterToggleRow({ group, onToggle, }: {
15
+ group: FilterGroup;
16
+ onToggle: (key: string, value: string) => void;
17
+ }): React.JSX.Element | null;
18
+ /** The price slider with Apply/Reset; the slider value is local until Apply. */
19
+ export declare function FilterPriceSlider({ price, labels: labelOverrides, onValueChange, showActions, }: {
20
+ price: FilterPriceConfig;
21
+ labels?: Partial<FilterPanelLabels>;
22
+ /** Called while dragging (the drawer stages the value instead of using Apply). */
23
+ onValueChange?: (min: number, max: number) => void;
24
+ showActions?: boolean;
25
+ }): React.JSX.Element;
26
+ /**
27
+ * Filter sidebar for a listing (Figma PLP): yes/no toggles first, then a price slider and
28
+ * collapsible groups of checkbox or swatch options with result counts. Purely presentational:
29
+ * selections come in through `groups`, changes go out through `onToggle` — the page decides
30
+ * when to apply them (see the listing-state helpers in @timmbr/utils).
31
+ */
32
+ export declare const FilterPanel: React.ForwardRefExoticComponent<FilterPanelProps & React.RefAttributes<HTMLDivElement>>;
33
+ //# sourceMappingURL=FilterPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterPanel.d.ts","sourceRoot":"","sources":["../../../src/components/FilterPanel/FilterPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAsB/B,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,qBAAqB,EAAE,iBAYnC,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,gBAAgB,GAAI,QAAQ,YAAY,YAAgE,CAAC;AActH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,KAAS,EACT,eAAoB,EACpB,MAAM,EAAE,cAAc,EACtB,SAAS,GACV,EAAE,qBAAqB,qBA2DvB;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD,4BAmBA;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,MAAM,EAAE,cAAc,EACtB,aAAa,EACb,WAAkB,GACnB,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpC,kFAAkF;IAClF,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,qBAkCA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,yFA2FvB,CAAC"}
@@ -0,0 +1,239 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import * as React from 'react';
4
+ import { Search } from '@timmbr/icons';
5
+ import { cn } from '@timmbr/utils';
6
+ import { filterOptionRowVariants, filterLinkButtonVariants, filterPanelTitleVariants, filterPanelHeaderVariants, filterToggleListVariants, filterSectionTriggerVariants, filterSectionContentVariants, filterPanelBodyVariants, filterPanelVariants, filterOptionCountVariants, filterOptionLabelVariants } from './FilterPanel.styles.js';
7
+ import { PRICE_GROUP_KEY } from './FilterPanel.types.js';
8
+ import { Input } from '../Input/Input.js';
9
+ import { Checkbox } from '../Checkbox/Checkbox.js';
10
+ import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '../Accordion/Accordion.js';
11
+ import { RangeSlider } from '../RangeSlider/RangeSlider.js';
12
+ import { Switch } from '../Switch/Switch.js';
13
+ import { Swatch } from '../Swatch/Swatch.js';
14
+
15
+ const DEFAULT_FILTER_LABELS = {
16
+ title: "Filters",
17
+ price: "Price range",
18
+ apply: "Apply",
19
+ reset: "Reset",
20
+ clear: "Clear",
21
+ showLess: "Show less",
22
+ showMore: (hidden) => `Show more (${hidden})`,
23
+ searchPlaceholder: (group) => `Search ${group.toLowerCase()}`,
24
+ noMatches: "No matches",
25
+ thumbMin: "Minimum price",
26
+ thumbMax: "Maximum price"
27
+ };
28
+ const isOptionDisabled = (option) => option.disabled ?? (option.count === 0 && !option.selected);
29
+ const selectedCount = (group) => group.options.filter((o) => o.selected).length;
30
+ function OptionLabel({ option, display }) {
31
+ return /* @__PURE__ */ jsxs("span", { className: filterOptionLabelVariants(), children: [
32
+ display === "swatch" && option.swatch && /* @__PURE__ */ jsx(Swatch, { color: option.swatch, size: "sm" }),
33
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: option.label }),
34
+ option.count !== void 0 && /* @__PURE__ */ jsxs("span", { className: filterOptionCountVariants(), children: [
35
+ "(",
36
+ option.count,
37
+ ")"
38
+ ] })
39
+ ] });
40
+ }
41
+ function FilterOptionList({
42
+ group,
43
+ onToggle,
44
+ limit = 5,
45
+ searchThreshold = 15,
46
+ labels: labelOverrides,
47
+ className
48
+ }) {
49
+ const labels = { ...DEFAULT_FILTER_LABELS, ...labelOverrides };
50
+ const [expanded, setExpanded] = React.useState(false);
51
+ const [query, setQuery] = React.useState("");
52
+ const searchable = group.options.length > searchThreshold;
53
+ const needle = query.trim().toLowerCase();
54
+ const ordered = [
55
+ ...group.options.filter((o) => !isOptionDisabled(o)),
56
+ ...group.options.filter((o) => isOptionDisabled(o))
57
+ ];
58
+ const matching = needle ? ordered.filter((o) => o.label.toLowerCase().includes(needle)) : ordered;
59
+ const visible = expanded || needle ? matching : matching.filter((o, i) => i < limit || o.selected);
60
+ const hidden = matching.length - visible.length;
61
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-3 pb-4", className), "data-slot": "filter-option-list", children: [
62
+ searchable && /* @__PURE__ */ jsx(
63
+ Input,
64
+ {
65
+ size: "sm",
66
+ type: "search",
67
+ value: query,
68
+ onChange: (e) => setQuery(e.target.value),
69
+ placeholder: labels.searchPlaceholder(group.label),
70
+ "aria-label": labels.searchPlaceholder(group.label),
71
+ leftAdornment: /* @__PURE__ */ jsx(Search, { className: "size-4" })
72
+ }
73
+ ),
74
+ /* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-3", children: [
75
+ visible.map((option) => {
76
+ const disabled = isOptionDisabled(option);
77
+ return /* @__PURE__ */ jsx("li", { className: filterOptionRowVariants({ disabled }), children: /* @__PURE__ */ jsx(
78
+ Checkbox,
79
+ {
80
+ size: "sm",
81
+ checked: !!option.selected,
82
+ disabled,
83
+ onCheckedChange: () => onToggle(group.key, option.value),
84
+ label: /* @__PURE__ */ jsx(OptionLabel, { option, display: group.display })
85
+ }
86
+ ) }, option.value);
87
+ }),
88
+ visible.length === 0 && /* @__PURE__ */ jsx("li", { className: "text-body-3 text-grey-500", children: labels.noMatches })
89
+ ] }),
90
+ !needle && (hidden > 0 || expanded) && matching.length > limit && /* @__PURE__ */ jsx(
91
+ "button",
92
+ {
93
+ type: "button",
94
+ className: filterLinkButtonVariants(),
95
+ "aria-expanded": expanded,
96
+ onClick: () => setExpanded((e) => !e),
97
+ children: expanded ? labels.showLess : labels.showMore(hidden)
98
+ }
99
+ )
100
+ ] });
101
+ }
102
+ function FilterToggleRow({
103
+ group,
104
+ onToggle
105
+ }) {
106
+ const option = group.options[0];
107
+ if (!option) return null;
108
+ const disabled = isOptionDisabled(option);
109
+ return /* @__PURE__ */ jsx(
110
+ Switch,
111
+ {
112
+ size: "sm",
113
+ checked: !!option.selected,
114
+ disabled,
115
+ onCheckedChange: () => onToggle(group.key, option.value),
116
+ containerClassName: cn(disabled && "opacity-50"),
117
+ label: /* @__PURE__ */ jsxs("span", { className: filterOptionLabelVariants(), children: [
118
+ group.label,
119
+ option.count !== void 0 && /* @__PURE__ */ jsxs("span", { className: filterOptionCountVariants(), children: [
120
+ "(",
121
+ option.count,
122
+ ")"
123
+ ] })
124
+ ] })
125
+ }
126
+ );
127
+ }
128
+ function FilterPriceSlider({
129
+ price,
130
+ labels: labelOverrides,
131
+ onValueChange,
132
+ showActions = true
133
+ }) {
134
+ const labels = { ...DEFAULT_FILTER_LABELS, ...labelOverrides };
135
+ const applied = price.value ?? [price.min, price.max];
136
+ const atBounds = (v) => v[0] <= price.min && v[1] >= price.max;
137
+ const appliedKey = `${applied[0]}-${applied[1]}-${price.min}-${price.max}-${price.resetKey ?? ""}`;
138
+ const [local, setLocal] = React.useState({
139
+ key: appliedKey,
140
+ value: applied
141
+ });
142
+ const draft = local.key === appliedKey ? local.value : applied;
143
+ const setDraft = (value) => setLocal({ key: appliedKey, value });
144
+ return /* @__PURE__ */ jsx(
145
+ RangeSlider,
146
+ {
147
+ min: price.min,
148
+ max: price.max,
149
+ step: price.step,
150
+ value: draft,
151
+ formatValue: price.format,
152
+ showActions,
153
+ applyLabel: labels.apply,
154
+ resetLabel: labels.reset,
155
+ thumbLabels: [labels.thumbMin, labels.thumbMax],
156
+ resetDisabled: atBounds(applied) && atBounds(draft),
157
+ onValueChange: (values) => {
158
+ setDraft(values);
159
+ onValueChange?.(values[0], values[1]);
160
+ },
161
+ onApply: (values) => price.onApply(values[0], values[1]),
162
+ onReset: () => price.onReset()
163
+ }
164
+ );
165
+ }
166
+ const FilterPanel = React.forwardRef(
167
+ ({
168
+ groups,
169
+ onToggle,
170
+ onClearGroup,
171
+ price,
172
+ defaultOpen,
173
+ optionLimit,
174
+ searchThreshold,
175
+ labels: labelOverrides,
176
+ headerAction,
177
+ className
178
+ }, ref) => {
179
+ const labels = { ...DEFAULT_FILTER_LABELS, ...labelOverrides };
180
+ const toggles = groups.filter((g) => g.display === "toggle");
181
+ const sections = groups.filter((g) => g.display !== "toggle");
182
+ const showPrice = !!price && price.max - price.min >= price.step && price.step > 0;
183
+ const [initialOpen] = React.useState(
184
+ () => defaultOpen ?? [PRICE_GROUP_KEY, ...sections.slice(0, 3).map((g) => g.key)]
185
+ );
186
+ return /* @__PURE__ */ jsxs("div", { ref, "data-slot": "filter-panel", className: cn(filterPanelVariants(), className), children: [
187
+ /* @__PURE__ */ jsxs("div", { className: filterPanelHeaderVariants(), children: [
188
+ /* @__PURE__ */ jsx("h2", { className: filterPanelTitleVariants(), children: labels.title }),
189
+ headerAction
190
+ ] }),
191
+ /* @__PURE__ */ jsxs("div", { "data-slot": "filter-panel-body", className: filterPanelBodyVariants(), children: [
192
+ toggles.length > 0 && /* @__PURE__ */ jsx("div", { className: filterToggleListVariants(), children: toggles.map((group) => /* @__PURE__ */ jsx(FilterToggleRow, { group, onToggle }, group.key)) }),
193
+ /* @__PURE__ */ jsxs(Accordion, { type: "multiple", defaultValue: initialOpen, className: "border-t border-grey-200", children: [
194
+ showPrice && price && /* @__PURE__ */ jsxs(AccordionItem, { value: PRICE_GROUP_KEY, className: "border-grey-200", children: [
195
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: filterSectionTriggerVariants(), children: labels.price }),
196
+ /* @__PURE__ */ jsx(AccordionContent, { className: filterSectionContentVariants(), children: /* @__PURE__ */ jsx("div", { className: "pb-4", children: /* @__PURE__ */ jsx(FilterPriceSlider, { price, labels }) }) })
197
+ ] }),
198
+ sections.map((group) => {
199
+ const count = selectedCount(group);
200
+ return /* @__PURE__ */ jsxs(AccordionItem, { value: group.key, className: "border-grey-200", children: [
201
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: filterSectionTriggerVariants(), children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
202
+ group.label,
203
+ count > 0 && /* @__PURE__ */ jsxs("span", { className: "text-primary", children: [
204
+ "(",
205
+ count,
206
+ ")"
207
+ ] })
208
+ ] }) }),
209
+ /* @__PURE__ */ jsxs(AccordionContent, { className: filterSectionContentVariants(), children: [
210
+ count > 0 && onClearGroup && /* @__PURE__ */ jsx(
211
+ "button",
212
+ {
213
+ type: "button",
214
+ className: cn(filterLinkButtonVariants(), "mb-3"),
215
+ onClick: () => onClearGroup(group.key),
216
+ children: labels.clear
217
+ }
218
+ ),
219
+ /* @__PURE__ */ jsx(
220
+ FilterOptionList,
221
+ {
222
+ group,
223
+ onToggle,
224
+ limit: optionLimit,
225
+ searchThreshold,
226
+ labels
227
+ }
228
+ )
229
+ ] })
230
+ ] }, group.key);
231
+ })
232
+ ] })
233
+ ] })
234
+ ] });
235
+ }
236
+ );
237
+ FilterPanel.displayName = "FilterPanel";
238
+
239
+ export { DEFAULT_FILTER_LABELS, FilterOptionList, FilterPanel, FilterPriceSlider, FilterToggleRow, isOptionDisabled };
@@ -0,0 +1,16 @@
1
+ /** Card: white surface, light shadow (Figma PLP filter sidebar). */
2
+ export declare const filterPanelVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
3
+ export declare const filterPanelHeaderVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
4
+ /** Everything below the header; scrolls inside the card when the card has a max height. */
5
+ export declare const filterPanelBodyVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
6
+ export declare const filterPanelTitleVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
7
+ export declare const filterToggleListVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
8
+ export declare const filterSectionTriggerVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
9
+ export declare const filterSectionContentVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
10
+ export declare const filterOptionRowVariants: (props?: ({
11
+ disabled?: boolean | null | undefined;
12
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
13
+ export declare const filterOptionLabelVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
14
+ export declare const filterOptionCountVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
15
+ export declare const filterLinkButtonVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
16
+ //# sourceMappingURL=FilterPanel.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterPanel.styles.d.ts","sourceRoot":"","sources":["../../../src/components/FilterPanel/FilterPanel.styles.ts"],"names":[],"mappings":"AAEA,oEAAoE;AACpE,eAAO,MAAM,mBAAmB,oFAAiF,CAAC;AAElH,eAAO,MAAM,yBAAyB,oFAErC,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,uBAAuB,oFAEnC,CAAC;AAEF,eAAO,MAAM,wBAAwB,oFAA6D,CAAC;AAEnG,eAAO,MAAM,wBAAwB,oFAAuC,CAAC;AAE7E,eAAO,MAAM,4BAA4B,oFAExC,CAAC;AAEF,eAAO,MAAM,4BAA4B,oFAAc,CAAC;AAExD,eAAO,MAAM,uBAAuB;;8EAQlC,CAAC;AAEH,eAAO,MAAM,yBAAyB,oFAA0E,CAAC;AAEjH,eAAO,MAAM,yBAAyB,oFAAmC,CAAC;AAE1E,eAAO,MAAM,wBAAwB,oFAEpC,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { cva } from 'class-variance-authority';
2
+
3
+ const filterPanelVariants = cva("flex flex-col overflow-hidden rounded-sm bg-grey-50 font-sans shadow-md");
4
+ const filterPanelHeaderVariants = cva(
5
+ "flex shrink-0 items-center justify-between gap-2 border-b border-grey-100 px-5 py-4"
6
+ );
7
+ const filterPanelBodyVariants = cva(
8
+ "min-h-0 flex-1 overflow-y-auto [scrollbar-gutter:stable] [scrollbar-width:thin]"
9
+ );
10
+ const filterPanelTitleVariants = cva("text-body-1 font-medium tracking-wide text-grey-950");
11
+ const filterToggleListVariants = cva("flex flex-col gap-4 px-5 py-4");
12
+ const filterSectionTriggerVariants = cva(
13
+ "px-4 py-4 text-body-3 font-medium uppercase tracking-wider text-grey-950 hover:no-underline"
14
+ );
15
+ const filterSectionContentVariants = cva("px-4");
16
+ const filterOptionRowVariants = cva("min-w-0", {
17
+ variants: {
18
+ disabled: {
19
+ true: "opacity-50",
20
+ false: ""
21
+ }
22
+ },
23
+ defaultVariants: { disabled: false }
24
+ });
25
+ const filterOptionLabelVariants = cva("inline-flex min-w-0 items-center gap-2 text-body-2 text-grey-700");
26
+ const filterOptionCountVariants = cva("text-body-3 text-grey-500");
27
+ const filterLinkButtonVariants = cva(
28
+ "self-start rounded-sm text-body-3 font-semibold text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50"
29
+ );
30
+
31
+ export { filterLinkButtonVariants, filterOptionCountVariants, filterOptionLabelVariants, filterOptionRowVariants, filterPanelBodyVariants, filterPanelHeaderVariants, filterPanelTitleVariants, filterPanelVariants, filterSectionContentVariants, filterSectionTriggerVariants, filterToggleListVariants };
@@ -0,0 +1,80 @@
1
+ import type * as React from 'react';
2
+ /** How a group's options are shown. */
3
+ export type FilterGroupDisplay = 'checkbox' | 'swatch' | 'toggle';
4
+ export interface FilterOption {
5
+ /** Value sent back in `onToggle` (e.g. a URL slug). */
6
+ value: string;
7
+ label: string;
8
+ /** Matching results if this option were picked; shown as "(12)". */
9
+ count?: number;
10
+ selected?: boolean;
11
+ /** Defaults to true when `count` is 0 and the option isn't selected. */
12
+ disabled?: boolean;
13
+ /** Colour for swatch groups. */
14
+ swatch?: string | null;
15
+ }
16
+ export interface FilterGroup {
17
+ key: string;
18
+ label: string;
19
+ display: FilterGroupDisplay;
20
+ options: FilterOption[];
21
+ }
22
+ export interface FilterPriceConfig {
23
+ /** Slider bounds and step. */
24
+ min: number;
25
+ max: number;
26
+ step: number;
27
+ /** The applied range (the slider starts here). */
28
+ value?: [number, number];
29
+ /** Shown on the readouts, e.g. (v) => `₹${v}`. */
30
+ format?: (value: number) => string;
31
+ onApply: (min: number, max: number) => void;
32
+ onReset: () => void;
33
+ /**
34
+ * Changes whenever the slider should drop an un-applied drag and show `value` again, e.g.
35
+ * the URL of the applied listing (so "Clear all" also resets the slider).
36
+ */
37
+ resetKey?: string;
38
+ }
39
+ export interface FilterPanelLabels {
40
+ title: string;
41
+ price: string;
42
+ apply: string;
43
+ reset: string;
44
+ clear: string;
45
+ showLess: string;
46
+ showMore: (hidden: number) => string;
47
+ searchPlaceholder: (groupLabel: string) => string;
48
+ noMatches: string;
49
+ thumbMin: string;
50
+ thumbMax: string;
51
+ }
52
+ export interface FilterOptionListProps {
53
+ group: FilterGroup;
54
+ onToggle: (key: string, value: string) => void;
55
+ /** Options shown before "Show more" (selected ones always show). @default 5 */
56
+ limit?: number;
57
+ /** Groups with more options than this get a search box. @default 15 */
58
+ searchThreshold?: number;
59
+ labels?: Partial<FilterPanelLabels>;
60
+ className?: string;
61
+ }
62
+ export interface FilterPanelProps {
63
+ groups: FilterGroup[];
64
+ onToggle: (key: string, value: string) => void;
65
+ /** Clears one group; adds a "Clear" link to groups with a selection. */
66
+ onClearGroup?: (key: string) => void;
67
+ /** Price slider, shown first when the range is wider than one step. */
68
+ price?: FilterPriceConfig;
69
+ /** Groups open at first ("price" is the slider). Default: price and the first three groups. */
70
+ defaultOpen?: string[];
71
+ optionLimit?: number;
72
+ searchThreshold?: number;
73
+ labels?: Partial<FilterPanelLabels>;
74
+ /** Right side of the header, e.g. a "Clear all" button. */
75
+ headerAction?: React.ReactNode;
76
+ className?: string;
77
+ }
78
+ /** Group key used by the panel and drawer for the price slider. */
79
+ export declare const PRICE_GROUP_KEY = "price";
80
+ //# sourceMappingURL=FilterPanel.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterPanel.types.d.ts","sourceRoot":"","sources":["../../../src/components/FilterPanel/FilterPanel.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ const PRICE_GROUP_KEY = "price";
2
+
3
+ export { PRICE_GROUP_KEY };
@@ -0,0 +1,4 @@
1
+ export * from './FilterPanel';
2
+ export * from './FilterPanel.types';
3
+ export * from './FilterPanel.styles';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FilterPanel/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
@@ -1,16 +1,16 @@
1
1
  import { type VariantProps } from 'class-variance-authority';
2
2
  export declare const imageUploadZoneVariants: (props?: ({
3
- aspectRatio?: "video" | "auto" | "square" | "wide" | null | undefined;
3
+ aspectRatio?: "auto" | "video" | "square" | "wide" | null | undefined;
4
4
  size?: "default" | "compact" | null | undefined;
5
5
  isDragging?: boolean | null | undefined;
6
6
  isError?: boolean | null | undefined;
7
7
  isDisabled?: boolean | null | undefined;
8
8
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
9
  export declare const imagePreviewContainerVariants: (props?: ({
10
- aspectRatio?: "video" | "auto" | "square" | "wide" | null | undefined;
10
+ aspectRatio?: "auto" | "video" | "square" | "wide" | null | undefined;
11
11
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
12
12
  export declare const thumbnailCardVariants: (props?: ({
13
- aspectRatio?: "video" | "auto" | "square" | "wide" | null | undefined;
13
+ aspectRatio?: "auto" | "video" | "square" | "wide" | null | undefined;
14
14
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
15
15
  export type ImageUploadZoneVariants = VariantProps<typeof imageUploadZoneVariants>;
16
16
  export type ImagePreviewContainerVariants = VariantProps<typeof imagePreviewContainerVariants>;
@@ -1 +1 @@
1
- {"version":3,"file":"MediaCard.d.ts","sourceRoot":"","sources":["../../../src/components/MediaCard/MediaCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAsB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAc5E;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,oFAgJrB,CAAC"}
1
+ {"version":3,"file":"MediaCard.d.ts","sourceRoot":"","sources":["../../../src/components/MediaCard/MediaCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAsB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAc5E;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,oFAkJrB,CAAC"}
@@ -113,7 +113,9 @@ const MediaCard = React.forwardRef(
113
113
  ]
114
114
  }
115
115
  ),
116
- footer && /* @__PURE__ */ jsx("div", { className: "relative z-10 mt-2 flex flex-wrap items-center gap-2", "data-slot": "media-card-footer", children: footer })
116
+ footer && // mt-auto: pinned to the card's bottom, so footers line up across a grid row even when
117
+ // titles or prices wrap differently.
118
+ /* @__PURE__ */ jsx("div", { className: "relative z-10 mt-auto flex flex-wrap items-center gap-2 pt-2", "data-slot": "media-card-footer", children: footer })
117
119
  ] })
118
120
  ]
119
121
  }
@@ -34,7 +34,14 @@ export declare const megaMenuCardVariants: (props?: import("class-variance-autho
34
34
  /**
35
35
  * Search popover suggestions card styles.
36
36
  */
37
+ /** Right-aligned under the input and wider than it, so product suggestions have room. */
37
38
  export declare const searchPopoverCardVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
39
+ /** A row of the search panel (recent search, suggested product, "see all"). */
40
+ export declare const searchPanelOptionVariants: (props?: ({
41
+ active?: boolean | null | undefined;
42
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
43
+ export declare const searchPanelSectionTitleVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
44
+ export declare const searchPanelTextButtonVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
38
45
  /**
39
46
  * Overflow action menu dropdown popover container.
40
47
  */
@@ -1 +1 @@
1
- {"version":3,"file":"NavHeader.styles.d.ts","sourceRoot":"","sources":["../../../src/components/NavHeader/NavHeader.styles.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,mBAAmB,oFAE/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB;;8EAa7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B;;8EAiBtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;8EAkBjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB;;8EAa7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,oFAEhC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,oFAErC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,6BAA6B,oFAEzC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B;;8EAatC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,oFAEnC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;8EAkBjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,6BAA6B,oFAEzC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B,oFAEtC,CAAC"}
1
+ {"version":3,"file":"NavHeader.styles.d.ts","sourceRoot":"","sources":["../../../src/components/NavHeader/NavHeader.styles.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,mBAAmB,oFAE/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB;;8EAa7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B;;8EAiBtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;8EAkBjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB;;8EAa7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,oFAEhC,CAAC;AAEF;;GAEG;AACH,yFAAyF;AACzF,eAAO,MAAM,yBAAyB,oFAErC,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,yBAAyB;;8EAWrC,CAAC;AAEF,eAAO,MAAM,+BAA+B,oFAE3C,CAAC;AAEF,eAAO,MAAM,6BAA6B,oFAEzC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,6BAA6B,oFAEzC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B;;8EAatC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,oFAEnC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;8EAkBjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,6BAA6B,oFAEzC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B,oFAEtC,CAAC"}
@@ -72,7 +72,25 @@ const megaMenuCardVariants = cva(
72
72
  "w-full max-w-[1216px] mx-auto bg-grey-50 border border-grey-200/80 shadow-2xl rounded-b-xl z-50 overflow-hidden"
73
73
  );
74
74
  const searchPopoverCardVariants = cva(
75
- "absolute top-full left-0 right-0 w-full mt-2 bg-grey-50 border border-grey-200 shadow-2xl rounded-2xl p-4 sm:p-5 z-50 text-left"
75
+ "absolute top-full right-0 mt-2 w-[min(26rem,calc(100vw-2rem))] max-h-[min(32rem,calc(100dvh-8rem))] overflow-y-auto bg-grey-50 border border-grey-200 shadow-2xl rounded-2xl p-3 sm:p-4 z-50 text-left"
76
+ );
77
+ const searchPanelOptionVariants = cva(
78
+ "flex w-full cursor-pointer items-center gap-3 rounded-lg px-2 py-2 text-left transition-colors",
79
+ {
80
+ variants: {
81
+ active: {
82
+ true: "bg-grey-100",
83
+ false: "hover:bg-grey-100"
84
+ }
85
+ },
86
+ defaultVariants: { active: false }
87
+ }
88
+ );
89
+ const searchPanelSectionTitleVariants = cva(
90
+ "px-2 text-caption font-semibold uppercase tracking-wider text-grey-500"
91
+ );
92
+ const searchPanelTextButtonVariants = cva(
93
+ "rounded-sm px-2 text-body-3 font-semibold text-grey-700 underline underline-offset-4 hover:text-grey-950 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
76
94
  );
77
95
  const actionOverflowPopoverVariants = cva(
78
96
  "absolute top-full right-0 mt-3 w-60 bg-grey-50 border border-border-warm shadow-2xl rounded-2xl p-2 z-50 text-left overflow-hidden divide-y divide-grey-100"
@@ -120,4 +138,4 @@ const mobileSearchDrawerVariants = cva(
120
138
  "fixed inset-0 z-[9999] h-[100dvh] w-screen bg-[var(--color-bg-2,#F7F1E6)] flex flex-col overflow-hidden"
121
139
  );
122
140
 
123
- export { actionOverflowItemVariants, actionOverflowPopoverVariants, megaMenuCardVariants, mobileSearchDrawerVariants, mobileTabContentPanelVariants, mobileTabItemVariants, mobileTabSliderVariants, navActionVariants, navHeaderContainerVariants, navHeaderItemVariants, navHeaderVariants, offerBannerVariants, searchPopoverCardVariants };
141
+ export { actionOverflowItemVariants, actionOverflowPopoverVariants, megaMenuCardVariants, mobileSearchDrawerVariants, mobileTabContentPanelVariants, mobileTabItemVariants, mobileTabSliderVariants, navActionVariants, navHeaderContainerVariants, navHeaderItemVariants, navHeaderVariants, offerBannerVariants, searchPanelOptionVariants, searchPanelSectionTitleVariants, searchPanelTextButtonVariants, searchPopoverCardVariants };