pixelize-design-library 2.4.2-beta.56 → 2.4.2-beta.57

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 (354) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/COMPONENT-GOTCHAS.md +48 -20
  3. package/DESIGN-GUIDE.md +18 -1
  4. package/dist/Components/AddressCard/AddressCard.d.ts +4 -0
  5. package/dist/Components/AddressCard/AddressCard.js +25 -0
  6. package/dist/Components/AddressCard/AddressCardGroup.d.ts +4 -0
  7. package/dist/Components/AddressCard/AddressCardGroup.js +7 -0
  8. package/dist/Components/AddressCard/AddressCardProps.d.ts +43 -0
  9. package/dist/Components/AddressCard/AddressCardProps.js +2 -0
  10. package/dist/Components/BagBar/BagBar.d.ts +4 -0
  11. package/dist/Components/BagBar/BagBar.js +32 -0
  12. package/dist/Components/BagBar/BagBarProps.d.ts +30 -0
  13. package/dist/Components/BagBar/BagBarProps.js +2 -0
  14. package/dist/Components/CartItem/CartItem.d.ts +4 -0
  15. package/dist/Components/CartItem/CartItem.js +60 -0
  16. package/dist/Components/CartItem/CartItemProps.d.ts +64 -0
  17. package/dist/Components/CartItem/CartItemProps.js +2 -0
  18. package/dist/Components/CartItem/cartItemOptions.d.ts +3 -0
  19. package/dist/Components/CartItem/cartItemOptions.js +13 -0
  20. package/dist/Components/CheckoutKit/selectable.d.ts +58 -0
  21. package/dist/Components/CheckoutKit/selectable.js +120 -0
  22. package/dist/Components/Commerce/commerceTypes.d.ts +52 -0
  23. package/dist/Components/Commerce/commerceTypes.js +2 -0
  24. package/dist/Components/Commerce/commerceVariants.d.ts +13 -0
  25. package/dist/Components/Commerce/commerceVariants.js +51 -0
  26. package/dist/Components/Commerce/index.d.ts +2 -0
  27. package/dist/Components/Commerce/index.js +18 -0
  28. package/dist/Components/Commerce/useContainerWidth.d.ts +3 -0
  29. package/dist/Components/Commerce/useContainerWidth.js +25 -0
  30. package/dist/Components/CouponField/CouponField.d.ts +4 -0
  31. package/dist/Components/CouponField/CouponField.js +72 -0
  32. package/dist/Components/CouponField/CouponFieldProps.d.ts +49 -0
  33. package/dist/Components/CouponField/CouponFieldProps.js +2 -0
  34. package/dist/Components/DatePicker/PickerPortal.d.ts +11 -0
  35. package/dist/Components/DatePicker/PickerPortal.js +26 -0
  36. package/dist/Components/DatePicker/RangeDatePicker.d.ts +1 -1
  37. package/dist/Components/DatePicker/RangeDatePicker.js +67 -32
  38. package/dist/Components/DatePicker/SingleDatePicker.js +49 -13
  39. package/dist/Components/DatePicker/TimeOnlyPicker.js +39 -4
  40. package/dist/Components/DetailSections/DetailSections.d.ts +4 -0
  41. package/dist/Components/DetailSections/DetailSections.js +112 -0
  42. package/dist/Components/DetailSections/DetailSectionsProps.d.ts +58 -0
  43. package/dist/Components/DetailSections/DetailSectionsProps.js +2 -0
  44. package/dist/Components/MediaGallery/MediaFrame.d.ts +31 -0
  45. package/dist/Components/MediaGallery/MediaFrame.js +55 -0
  46. package/dist/Components/MediaGallery/MediaGallery.d.ts +4 -0
  47. package/dist/Components/MediaGallery/MediaGallery.js +206 -0
  48. package/dist/Components/MediaGallery/MediaGalleryProps.d.ts +76 -0
  49. package/dist/Components/MediaGallery/MediaGalleryProps.js +20 -0
  50. package/dist/Components/MediaGallery/MediaLightbox.d.ts +4 -0
  51. package/dist/Components/MediaGallery/MediaLightbox.js +116 -0
  52. package/dist/Components/MediaGallery/MediaLightboxProps.d.ts +40 -0
  53. package/dist/Components/MediaGallery/MediaLightboxProps.js +15 -0
  54. package/dist/Components/MediaGallery/MediaThumb.d.ts +18 -0
  55. package/dist/Components/MediaGallery/MediaThumb.js +25 -0
  56. package/dist/Components/MediaGallery/glass.d.ts +31 -0
  57. package/dist/Components/MediaGallery/glass.js +47 -0
  58. package/dist/Components/MediaGallery/mediaGalleryModel.d.ts +22 -0
  59. package/dist/Components/MediaGallery/mediaGalleryModel.js +83 -0
  60. package/dist/Components/MediaGallery/motion.d.ts +5 -0
  61. package/dist/Components/MediaGallery/motion.js +12 -0
  62. package/dist/Components/MediaGallery/useMatchMedia.d.ts +2 -0
  63. package/dist/Components/MediaGallery/useMatchMedia.js +20 -0
  64. package/dist/Components/OffersList/OffersList.d.ts +4 -0
  65. package/dist/Components/OffersList/OffersList.js +83 -0
  66. package/dist/Components/OffersList/OffersListProps.d.ts +34 -0
  67. package/dist/Components/OffersList/OffersListProps.js +2 -0
  68. package/dist/Components/OptionChip/OptionChip.d.ts +4 -0
  69. package/dist/Components/OptionChip/OptionChip.js +97 -0
  70. package/dist/Components/OptionChip/OptionChipProps.d.ts +33 -0
  71. package/dist/Components/OptionChip/OptionChipProps.js +2 -0
  72. package/dist/Components/OptionChip/optionInk.d.ts +12 -0
  73. package/dist/Components/OptionChip/optionInk.js +25 -0
  74. package/dist/Components/OrderStatusTimeline/OrderStatusTimeline.d.ts +4 -0
  75. package/dist/Components/OrderStatusTimeline/OrderStatusTimeline.js +57 -0
  76. package/dist/Components/OrderStatusTimeline/OrderStatusTimelineProps.d.ts +29 -0
  77. package/dist/Components/OrderStatusTimeline/OrderStatusTimelineProps.js +2 -0
  78. package/dist/Components/OrderSummary/OrderSummary.d.ts +4 -0
  79. package/dist/Components/OrderSummary/OrderSummary.js +63 -0
  80. package/dist/Components/OrderSummary/OrderSummaryProps.d.ts +53 -0
  81. package/dist/Components/OrderSummary/OrderSummaryProps.js +2 -0
  82. package/dist/Components/PaymentOption/PaymentOption.d.ts +4 -0
  83. package/dist/Components/PaymentOption/PaymentOption.js +24 -0
  84. package/dist/Components/PaymentOption/PaymentOptionGroup.d.ts +4 -0
  85. package/dist/Components/PaymentOption/PaymentOptionGroup.js +7 -0
  86. package/dist/Components/PaymentOption/PaymentOptionProps.d.ts +32 -0
  87. package/dist/Components/PaymentOption/PaymentOptionProps.js +2 -0
  88. package/dist/Components/PincodeChecker/PincodeChecker.d.ts +4 -0
  89. package/dist/Components/PincodeChecker/PincodeChecker.js +175 -0
  90. package/dist/Components/PincodeChecker/PincodeCheckerProps.d.ts +57 -0
  91. package/dist/Components/PincodeChecker/PincodeCheckerProps.js +2 -0
  92. package/dist/Components/PriceBlock/PriceBlock.d.ts +4 -0
  93. package/dist/Components/PriceBlock/PriceBlock.js +41 -0
  94. package/dist/Components/PriceBlock/PriceBlockProps.d.ts +39 -0
  95. package/dist/Components/PriceBlock/PriceBlockProps.js +2 -0
  96. package/dist/Components/ProductBadges/ProductBadges.d.ts +4 -0
  97. package/dist/Components/ProductBadges/ProductBadges.js +61 -0
  98. package/dist/Components/ProductBadges/ProductBadgesProps.d.ts +18 -0
  99. package/dist/Components/ProductBadges/ProductBadgesProps.js +2 -0
  100. package/dist/Components/ProductCard/ProductCard.d.ts +3 -2
  101. package/dist/Components/ProductCard/ProductCard.js +103 -52
  102. package/dist/Components/ProductCard/ProductCardAction.d.ts +17 -0
  103. package/dist/Components/ProductCard/ProductCardAction.js +65 -0
  104. package/dist/Components/ProductCard/ProductCardGrid.d.ts +4 -0
  105. package/dist/Components/ProductCard/ProductCardGrid.js +20 -0
  106. package/dist/Components/ProductCard/ProductCardMedia.d.ts +18 -0
  107. package/dist/Components/ProductCard/ProductCardMedia.js +35 -0
  108. package/dist/Components/ProductCard/ProductCardProps.d.ts +138 -56
  109. package/dist/Components/ProductCard/ProductCardSkeleton.d.ts +4 -0
  110. package/dist/Components/ProductCard/ProductCardSkeleton.js +17 -0
  111. package/dist/Components/ProductCard/ProductCardSwatches.d.ts +15 -0
  112. package/dist/Components/ProductCard/ProductCardSwatches.js +37 -0
  113. package/dist/Components/ProductCard/QuickAddSheet.d.ts +4 -0
  114. package/dist/Components/ProductCard/QuickAddSheet.js +109 -0
  115. package/dist/Components/ProductCard/QuickAddSheetProps.d.ts +38 -0
  116. package/dist/Components/ProductCard/QuickAddSheetProps.js +2 -0
  117. package/dist/Components/ProductCard/cardLabels.d.ts +2 -0
  118. package/dist/Components/ProductCard/cardLabels.js +16 -0
  119. package/dist/Components/ProductCard/cardMetrics.d.ts +27 -0
  120. package/dist/Components/ProductCard/cardMetrics.js +55 -0
  121. package/dist/Components/ProductCard/productCardFixtures.d.ts +7 -0
  122. package/dist/Components/ProductCard/productCardFixtures.js +61 -0
  123. package/dist/Components/ProductCard/productCardModel.d.ts +22 -0
  124. package/dist/Components/ProductCard/productCardModel.js +79 -0
  125. package/dist/Components/ProductCard/useMinWidth.d.ts +2 -0
  126. package/dist/Components/ProductCard/useMinWidth.js +20 -0
  127. package/dist/Components/ProductDetails/ProductDetails.d.ts +3 -2
  128. package/dist/Components/ProductDetails/ProductDetails.js +209 -33
  129. package/dist/Components/ProductDetails/ProductDetailsProps.d.ts +143 -41
  130. package/dist/Components/ProductDetails/productDetailsModel.d.ts +14 -0
  131. package/dist/Components/ProductDetails/productDetailsModel.js +45 -0
  132. package/dist/Components/ProductDetails/useInViewport.d.ts +3 -0
  133. package/dist/Components/ProductDetails/useInViewport.js +18 -0
  134. package/dist/Components/QuantityStepper/QuantityStepper.d.ts +4 -0
  135. package/dist/Components/QuantityStepper/QuantityStepper.js +59 -0
  136. package/dist/Components/QuantityStepper/QuantityStepperProps.d.ts +24 -0
  137. package/dist/Components/QuantityStepper/QuantityStepperProps.js +2 -0
  138. package/dist/Components/Rating/Rating.d.ts +4 -0
  139. package/dist/Components/Rating/Rating.js +81 -0
  140. package/dist/Components/Rating/RatingProps.d.ts +27 -0
  141. package/dist/Components/Rating/RatingProps.js +2 -0
  142. package/dist/Components/ReviewList/ReviewList.d.ts +4 -0
  143. package/dist/Components/ReviewList/ReviewList.js +94 -0
  144. package/dist/Components/ReviewList/ReviewListProps.d.ts +68 -0
  145. package/dist/Components/ReviewList/ReviewListProps.js +2 -0
  146. package/dist/Components/ReviewSummary/ReviewSummary.d.ts +4 -0
  147. package/dist/Components/ReviewSummary/ReviewSummary.js +47 -0
  148. package/dist/Components/ReviewSummary/ReviewSummaryProps.d.ts +31 -0
  149. package/dist/Components/ReviewSummary/ReviewSummaryProps.js +2 -0
  150. package/dist/Components/SegmentedControl/SegmentedControl.d.ts +1 -1
  151. package/dist/Components/SegmentedControl/SegmentedControl.js +17 -5
  152. package/dist/Components/SegmentedControl/SegmentedControlProps.d.ts +6 -0
  153. package/dist/Components/SegmentedControl/segmentedInk.d.ts +2 -0
  154. package/dist/Components/SegmentedControl/segmentedInk.js +4 -1
  155. package/dist/Components/SegmentedControl/useSlidingPill.d.ts +2 -0
  156. package/dist/Components/SegmentedControl/useSlidingPill.js +6 -1
  157. package/dist/Components/SideBar/SecondaryBar.js +13 -8
  158. package/dist/Components/SideBar/SideBarProps.d.ts +3 -1
  159. package/dist/Components/SideBar/components/MenuItemBox.js +47 -10
  160. package/dist/Components/SideBar/components/MenuPopoverContent.js +4 -3
  161. package/dist/Components/SpecTable/SpecTable.d.ts +4 -0
  162. package/dist/Components/SpecTable/SpecTable.js +39 -0
  163. package/dist/Components/SpecTable/SpecTableProps.d.ts +25 -0
  164. package/dist/Components/SpecTable/SpecTableProps.js +2 -0
  165. package/dist/Components/Spinner/Spinner.d.ts +1 -1
  166. package/dist/Components/Spinner/Spinner.js +2 -2
  167. package/dist/Components/Spinner/SpinnerProps.d.ts +2 -0
  168. package/dist/Components/StageProgress/StepperStage.js +2 -1
  169. package/dist/Components/StatCard/StatCard.d.ts +1 -1
  170. package/dist/Components/StatCard/StatCard.js +2 -2
  171. package/dist/Components/StatCard/StatCardProps.d.ts +4 -0
  172. package/dist/Components/StickyBuyBar/StickyBuyBar.d.ts +3 -0
  173. package/dist/Components/StickyBuyBar/StickyBuyBar.js +85 -0
  174. package/dist/Components/StickyBuyBar/StickyBuyBarProps.d.ts +54 -0
  175. package/dist/Components/StickyBuyBar/StickyBuyBarProps.js +2 -0
  176. package/dist/Components/StockStatus/StockStatus.d.ts +4 -0
  177. package/dist/Components/StockStatus/StockStatus.js +31 -0
  178. package/dist/Components/StockStatus/StockStatusProps.d.ts +14 -0
  179. package/dist/Components/StockStatus/StockStatusProps.js +2 -0
  180. package/dist/Components/Table/Table.js +2 -1
  181. package/dist/Components/Table/TableProps.d.ts +5 -2
  182. package/dist/Components/Table/columnLabel.d.ts +6 -0
  183. package/dist/Components/Table/columnLabel.js +27 -0
  184. package/dist/Components/Table/components/TableBody.js +5 -1
  185. package/dist/Components/Table/components/TableHeader.js +3 -2
  186. package/dist/Components/Table/filters/ActiveFilters.js +2 -1
  187. package/dist/Components/Table/filters/TableFilters.js +2 -1
  188. package/dist/Components/Table/hooks/useTable.js +3 -2
  189. package/dist/Components/Table/settings/ManageColumns.js +4 -3
  190. package/dist/Components/Table/settings/TableSettings.js +2 -1
  191. package/dist/Components/TrustBadges/TrustBadges.d.ts +4 -0
  192. package/dist/Components/TrustBadges/TrustBadges.js +24 -0
  193. package/dist/Components/TrustBadges/TrustBadgesProps.d.ts +20 -0
  194. package/dist/Components/TrustBadges/TrustBadgesProps.js +2 -0
  195. package/dist/Components/VariantSelector/VariantSelector.d.ts +4 -0
  196. package/dist/Components/VariantSelector/VariantSelector.js +123 -0
  197. package/dist/Components/VariantSelector/VariantSelectorProps.d.ts +27 -0
  198. package/dist/Components/VariantSelector/VariantSelectorProps.js +2 -0
  199. package/dist/Components/VariantSelector/variantSelection.d.ts +6 -0
  200. package/dist/Components/VariantSelector/variantSelection.js +25 -0
  201. package/dist/Components/WishlistToggle/WishlistToggle.d.ts +4 -0
  202. package/dist/Components/WishlistToggle/WishlistToggle.js +65 -0
  203. package/dist/Components/WishlistToggle/WishlistToggleProps.d.ts +19 -0
  204. package/dist/Components/WishlistToggle/WishlistToggleProps.js +2 -0
  205. package/dist/Theme/assertPalette.d.ts +1 -1
  206. package/dist/Theme/assertPalette.js +1 -1
  207. package/dist/Theme/tokens/brands/index.js +2 -0
  208. package/dist/Theme/tokens/brands/zinc/palette.dark.d.ts +1 -0
  209. package/dist/Theme/tokens/builders/buildDarkPalette.js +2 -0
  210. package/dist/Theme/tokens/builders/index.d.ts +1 -0
  211. package/dist/Theme/tokens/builders/index.js +1 -0
  212. package/dist/Theme/tokens/builders/rechartsTheme.d.ts +56 -0
  213. package/dist/Theme/tokens/builders/rechartsTheme.js +43 -0
  214. package/dist/Theme/tokens/builders/star.d.ts +3 -0
  215. package/dist/Theme/tokens/builders/star.js +8 -0
  216. package/dist/Theme/tokens/types.d.ts +3 -1
  217. package/dist/Theme/useChartTheme.d.ts +4 -0
  218. package/dist/Theme/useChartTheme.js +12 -0
  219. package/dist/Utils/price.d.ts +16 -0
  220. package/dist/Utils/price.js +34 -0
  221. package/dist/esm/Components/AddressCard/AddressCard.js +20 -0
  222. package/dist/esm/Components/AddressCard/AddressCardGroup.js +5 -0
  223. package/dist/esm/Components/AddressCard/AddressCardProps.js +1 -0
  224. package/dist/esm/Components/BagBar/BagBar.js +27 -0
  225. package/dist/esm/Components/BagBar/BagBarProps.js +1 -0
  226. package/dist/esm/Components/CartItem/CartItem.js +55 -0
  227. package/dist/esm/Components/CartItem/CartItemProps.js +1 -0
  228. package/dist/esm/Components/CartItem/cartItemOptions.js +9 -0
  229. package/dist/esm/Components/CheckoutKit/selectable.js +112 -0
  230. package/dist/esm/Components/Commerce/commerceTypes.js +1 -0
  231. package/dist/esm/Components/Commerce/commerceVariants.js +41 -0
  232. package/dist/esm/Components/Commerce/index.js +2 -0
  233. package/dist/esm/Components/Commerce/useContainerWidth.js +21 -0
  234. package/dist/esm/Components/CouponField/CouponField.js +67 -0
  235. package/dist/esm/Components/CouponField/CouponFieldProps.js +1 -0
  236. package/dist/esm/Components/DatePicker/PickerPortal.js +21 -0
  237. package/dist/esm/Components/DatePicker/RangeDatePicker.js +34 -32
  238. package/dist/esm/Components/DatePicker/SingleDatePicker.js +16 -13
  239. package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +6 -4
  240. package/dist/esm/Components/DetailSections/DetailSections.js +107 -0
  241. package/dist/esm/Components/DetailSections/DetailSectionsProps.js +1 -0
  242. package/dist/esm/Components/MediaGallery/MediaFrame.js +48 -0
  243. package/dist/esm/Components/MediaGallery/MediaGallery.js +201 -0
  244. package/dist/esm/Components/MediaGallery/MediaGalleryProps.js +17 -0
  245. package/dist/esm/Components/MediaGallery/MediaLightbox.js +78 -0
  246. package/dist/esm/Components/MediaGallery/MediaLightboxProps.js +12 -0
  247. package/dist/esm/Components/MediaGallery/MediaThumb.js +23 -0
  248. package/dist/esm/Components/MediaGallery/glass.js +42 -0
  249. package/dist/esm/Components/MediaGallery/mediaGalleryModel.js +71 -0
  250. package/dist/esm/Components/MediaGallery/motion.js +8 -0
  251. package/dist/esm/Components/MediaGallery/useMatchMedia.js +16 -0
  252. package/dist/esm/Components/OffersList/OffersList.js +81 -0
  253. package/dist/esm/Components/OffersList/OffersListProps.js +1 -0
  254. package/dist/esm/Components/OptionChip/OptionChip.js +95 -0
  255. package/dist/esm/Components/OptionChip/OptionChipProps.js +1 -0
  256. package/dist/esm/Components/OptionChip/optionInk.js +21 -0
  257. package/dist/esm/Components/OrderStatusTimeline/OrderStatusTimeline.js +55 -0
  258. package/dist/esm/Components/OrderStatusTimeline/OrderStatusTimelineProps.js +1 -0
  259. package/dist/esm/Components/OrderSummary/OrderSummary.js +58 -0
  260. package/dist/esm/Components/OrderSummary/OrderSummaryProps.js +1 -0
  261. package/dist/esm/Components/PaymentOption/PaymentOption.js +19 -0
  262. package/dist/esm/Components/PaymentOption/PaymentOptionGroup.js +5 -0
  263. package/dist/esm/Components/PaymentOption/PaymentOptionProps.js +1 -0
  264. package/dist/esm/Components/PincodeChecker/PincodeChecker.js +170 -0
  265. package/dist/esm/Components/PincodeChecker/PincodeCheckerProps.js +1 -0
  266. package/dist/esm/Components/PriceBlock/PriceBlock.js +39 -0
  267. package/dist/esm/Components/PriceBlock/PriceBlockProps.js +1 -0
  268. package/dist/esm/Components/ProductBadges/ProductBadges.js +59 -0
  269. package/dist/esm/Components/ProductBadges/ProductBadgesProps.js +1 -0
  270. package/dist/esm/Components/ProductCard/ProductCard.js +105 -54
  271. package/dist/esm/Components/ProductCard/ProductCardAction.js +60 -0
  272. package/dist/esm/Components/ProductCard/ProductCardGrid.js +18 -0
  273. package/dist/esm/Components/ProductCard/ProductCardMedia.js +33 -0
  274. package/dist/esm/Components/ProductCard/ProductCardSkeleton.js +12 -0
  275. package/dist/esm/Components/ProductCard/ProductCardSwatches.js +35 -0
  276. package/dist/esm/Components/ProductCard/QuickAddSheet.js +71 -0
  277. package/dist/esm/Components/ProductCard/QuickAddSheetProps.js +1 -0
  278. package/dist/esm/Components/ProductCard/cardLabels.js +13 -0
  279. package/dist/esm/Components/ProductCard/cardMetrics.js +52 -0
  280. package/dist/esm/Components/ProductCard/productCardFixtures.js +58 -0
  281. package/dist/esm/Components/ProductCard/productCardModel.js +65 -0
  282. package/dist/esm/Components/ProductCard/useMinWidth.js +16 -0
  283. package/dist/esm/Components/ProductDetails/ProductDetails.js +210 -34
  284. package/dist/esm/Components/ProductDetails/productDetailsModel.js +35 -0
  285. package/dist/esm/Components/ProductDetails/useInViewport.js +14 -0
  286. package/dist/esm/Components/QuantityStepper/QuantityStepper.js +57 -0
  287. package/dist/esm/Components/QuantityStepper/QuantityStepperProps.js +1 -0
  288. package/dist/esm/Components/Rating/Rating.js +79 -0
  289. package/dist/esm/Components/Rating/RatingProps.js +1 -0
  290. package/dist/esm/Components/ReviewList/ReviewList.js +89 -0
  291. package/dist/esm/Components/ReviewList/ReviewListProps.js +1 -0
  292. package/dist/esm/Components/ReviewSummary/ReviewSummary.js +42 -0
  293. package/dist/esm/Components/ReviewSummary/ReviewSummaryProps.js +1 -0
  294. package/dist/esm/Components/SegmentedControl/SegmentedControl.js +19 -7
  295. package/dist/esm/Components/SegmentedControl/segmentedInk.js +2 -0
  296. package/dist/esm/Components/SegmentedControl/useSlidingPill.js +6 -1
  297. package/dist/esm/Components/SideBar/SecondaryBar.js +14 -9
  298. package/dist/esm/Components/SideBar/components/MenuItemBox.js +14 -10
  299. package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +4 -3
  300. package/dist/esm/Components/SpecTable/SpecTable.js +34 -0
  301. package/dist/esm/Components/SpecTable/SpecTableProps.js +1 -0
  302. package/dist/esm/Components/Spinner/Spinner.js +2 -2
  303. package/dist/esm/Components/StageProgress/StepperStage.js +2 -1
  304. package/dist/esm/Components/StatCard/StatCard.js +2 -2
  305. package/dist/esm/Components/StickyBuyBar/StickyBuyBar.js +80 -0
  306. package/dist/esm/Components/StickyBuyBar/StickyBuyBarProps.js +1 -0
  307. package/dist/esm/Components/StockStatus/StockStatus.js +29 -0
  308. package/dist/esm/Components/StockStatus/StockStatusProps.js +1 -0
  309. package/dist/esm/Components/Table/Table.js +2 -1
  310. package/dist/esm/Components/Table/columnLabel.js +21 -0
  311. package/dist/esm/Components/Table/components/TableBody.js +5 -1
  312. package/dist/esm/Components/Table/components/TableHeader.js +3 -2
  313. package/dist/esm/Components/Table/filters/ActiveFilters.js +2 -1
  314. package/dist/esm/Components/Table/filters/TableFilters.js +2 -1
  315. package/dist/esm/Components/Table/hooks/useTable.js +3 -2
  316. package/dist/esm/Components/Table/settings/ManageColumns.js +4 -3
  317. package/dist/esm/Components/Table/settings/TableSettings.js +2 -1
  318. package/dist/esm/Components/TrustBadges/TrustBadges.js +22 -0
  319. package/dist/esm/Components/TrustBadges/TrustBadgesProps.js +1 -0
  320. package/dist/esm/Components/VariantSelector/VariantSelector.js +118 -0
  321. package/dist/esm/Components/VariantSelector/VariantSelectorProps.js +1 -0
  322. package/dist/esm/Components/VariantSelector/variantSelection.js +19 -0
  323. package/dist/esm/Components/WishlistToggle/WishlistToggle.js +63 -0
  324. package/dist/esm/Components/WishlistToggle/WishlistToggleProps.js +1 -0
  325. package/dist/esm/Theme/assertPalette.js +1 -1
  326. package/dist/esm/Theme/tokens/brands/index.js +2 -0
  327. package/dist/esm/Theme/tokens/builders/buildDarkPalette.js +2 -0
  328. package/dist/esm/Theme/tokens/builders/index.js +1 -0
  329. package/dist/esm/Theme/tokens/builders/rechartsTheme.js +37 -0
  330. package/dist/esm/Theme/tokens/builders/star.js +4 -0
  331. package/dist/esm/Theme/useChartTheme.js +8 -0
  332. package/dist/esm/Utils/price.js +27 -0
  333. package/dist/esm/index.js +36 -0
  334. package/dist/index.d.ts +66 -0
  335. package/dist/index.js +86 -4
  336. package/package.json +1 -1
  337. package/dist/Components/ProductCard/ProductLabel.d.ts +0 -7
  338. package/dist/Components/ProductCard/ProductLabel.js +0 -20
  339. package/dist/Components/ProductCard/ProductPrice.d.ts +0 -10
  340. package/dist/Components/ProductCard/ProductPrice.js +0 -126
  341. package/dist/Components/ProductCard/ProductReview.d.ts +0 -8
  342. package/dist/Components/ProductCard/ProductReview.js +0 -30
  343. package/dist/Components/ProductCard/ProductTags.d.ts +0 -8
  344. package/dist/Components/ProductCard/ProductTags.js +0 -53
  345. package/dist/Components/ProductDetails/ProductDtlPrice.d.ts +0 -7
  346. package/dist/Components/ProductDetails/ProductDtlPrice.js +0 -24
  347. package/dist/Components/ProductDetails/ProductImageSlider.d.ts +0 -13
  348. package/dist/Components/ProductDetails/ProductImageSlider.js +0 -240
  349. package/dist/esm/Components/ProductCard/ProductLabel.js +0 -18
  350. package/dist/esm/Components/ProductCard/ProductPrice.js +0 -121
  351. package/dist/esm/Components/ProductCard/ProductReview.js +0 -28
  352. package/dist/esm/Components/ProductCard/ProductTags.js +0 -48
  353. package/dist/esm/Components/ProductDetails/ProductDtlPrice.js +0 -22
  354. package/dist/esm/Components/ProductDetails/ProductImageSlider.js +0 -204
@@ -0,0 +1,95 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { Box, Text } from "@chakra-ui/react";
4
+ import { Check } from "lucide-react";
5
+ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
6
+ import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
7
+ import { reducedMotionSx } from "../../Theme/chakra/motion.js";
8
+ import { focusVisibleStyles } from "../../Theme/chakra/focusRing.styles.js";
9
+ import { optionInk } from "./optionInk.js";
10
+ const CHIP_HEIGHT = { md: "2.75rem", lg: "3.25rem" };
11
+ const PACK_HEIGHT = { md: "3.5rem", lg: "4rem" };
12
+ const DOT = { md: "1.75rem", lg: "2rem" };
13
+ const TILE = { md: { w: "4rem", h: "5rem" }, lg: { w: "4.5rem", h: "5.625rem" } };
14
+ const DIM_OPACITY = 0.5;
15
+ const band = (color, half) => `linear-gradient(to top right, transparent calc(50% - ${half}), ${color} calc(50% - ${half}), ${color} calc(50% + ${half}), transparent calc(50% + ${half}))`;
16
+ const strikeImage = (ink, halo) => `${band(ink, "0.5px")}, ${band(halo, "1.5px")}`;
17
+ const strikeLayer = (image) => ({
18
+ position: "absolute",
19
+ inset: 0,
20
+ borderRadius: "inherit",
21
+ pointerEvents: "none",
22
+ backgroundImage: image,
23
+ });
24
+ const CheckGrow = ({ selected }) => (_jsx(Box, { as: "span", "aria-hidden": true, display: "inline-flex", alignItems: "center", flexShrink: 0, overflow: "hidden", w: selected ? "1.125rem" : 0, opacity: selected ? 1 : 0, transition: transitionFor(["width", "opacity"], "base"), sx: reducedMotionSx(), children: _jsx(Check, { size: 14, strokeWidth: 2.5 }) }));
25
+ const errorRing = (colors) => `inset 0 0 0 1px ${colors.semanticText.error}`;
26
+ /** The one selectable option control: text chip, colour swatch, image tile or pack. Parent group supplies the radiogroup. */
27
+ const OptionChip = forwardRef(function OptionChip({ label, selected = false, disabled = false, unavailable = false, invalid = false, variant = "chip", swatch, image, hint, showLabel = false, size = "md", fullWidth = false, onSelect, onFocus, tabIndex, "data-testid": testId, }, ref) {
28
+ const { colors } = useCustomTheme();
29
+ const { rest, selected: picked } = optionInk(colors);
30
+ const tone = selected ? picked : rest;
31
+ const dimmed = unavailable || disabled;
32
+ const accessibleName = [label, hint, unavailable ? "unavailable" : null].filter(Boolean).join(", ");
33
+ const strikeBackground = strikeImage(colors.text[800], colors.background[50]);
34
+ const base = {
35
+ ref,
36
+ as: "button",
37
+ type: "button",
38
+ role: "radio",
39
+ "aria-checked": selected,
40
+ "aria-disabled": unavailable || undefined,
41
+ "aria-label": accessibleName,
42
+ "data-testid": testId,
43
+ disabled,
44
+ tabIndex,
45
+ onClick: () => onSelect === null || onSelect === void 0 ? void 0 : onSelect(),
46
+ onFocus: () => onFocus === null || onFocus === void 0 ? void 0 : onFocus(),
47
+ position: "relative",
48
+ flexShrink: 0,
49
+ cursor: disabled ? "not-allowed" : "pointer",
50
+ opacity: dimmed ? DIM_OPACITY : 1,
51
+ w: fullWidth ? "100%" : undefined,
52
+ transition: transitionFor(["background-color", "color", "box-shadow", "border-color", "transform"]),
53
+ _active: dimmed ? undefined : { transform: "scale(0.97)" },
54
+ };
55
+ const motion = {
56
+ ...focusVisibleStyles(colors),
57
+ ...reducedMotionSx({ "&:active": { transform: "none" } }),
58
+ };
59
+ if (variant === "swatch") {
60
+ const dot = DOT[size];
61
+ return (_jsxs(Box, { ...base, display: "inline-flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: "0.25rem", minW: CHIP_HEIGHT[size], minH: CHIP_HEIGHT[size], borderRadius: "xl", bg: "transparent", color: colors.text[800], title: showLabel ? undefined : label, sx: {
62
+ ...motion,
63
+ "&:hover:not(:disabled) [data-ring]:not([data-selected])": { borderColor: colors.boxborder[500] },
64
+ }, children: [_jsx(Box, { as: "span", "data-ring": true, "data-selected": selected ? "" : undefined, display: "inline-flex", p: "0.125rem", borderWidth: "2px", borderStyle: "solid", borderRadius: "full", borderColor: selected ? colors.header[900] : invalid ? colors.semanticText.error : "transparent", transition: transitionFor(["border-color"]), sx: reducedMotionSx(), children: _jsx(Box, { as: "span", position: "relative", display: "block", boxSize: dot, borderRadius: "full", backgroundColor: swatch !== null && swatch !== void 0 ? swatch : colors.background[200], boxShadow: `inset 0 0 0 1px ${colors.boxborder[200]}`, sx: unavailable ? { "&::after": { content: '""', ...strikeLayer(strikeBackground) } } : undefined }) }), showLabel ? (_jsx(Text, { as: "span", fontSize: "xs", fontWeight: selected ? 600 : 500, color: selected ? colors.header[900] : rest.ink, lineHeight: "short", children: label })) : null] }));
65
+ }
66
+ if (variant === "image-tile") {
67
+ const tile = TILE[size];
68
+ return (_jsxs(Box, { ...base, display: "inline-flex", flexDirection: "column", alignItems: "center", gap: "0.375rem", bg: "transparent", color: rest.ink, w: fullWidth ? "100%" : undefined, maxW: `calc(${tile.w} + 0.5rem)`, sx: motion, children: [_jsx(Box, { as: "span", display: "block", p: "0.125rem", borderWidth: "2px", borderStyle: "solid", borderRadius: "calc(0.75rem + 4px)", borderColor: selected ? colors.header[900] : invalid ? colors.semanticText.error : "transparent", transition: transitionFor(["border-color"]), sx: reducedMotionSx(), children: _jsxs(Box, { as: "span", position: "relative", display: "block", w: tile.w, h: tile.h, borderRadius: "xl", overflow: "hidden", backgroundColor: swatch !== null && swatch !== void 0 ? swatch : colors.background[100], sx: unavailable ? { "&::after": { content: '""', ...strikeLayer(strikeBackground) } } : undefined, children: [image ? _jsx(Box, { as: "img", src: image, alt: "", loading: "lazy", w: "100%", h: "100%", objectFit: "cover", display: "block" }) : null, _jsx(Box, { as: "span", "aria-hidden": true, position: "absolute", top: "0.25rem", right: "0.25rem", display: "inline-flex", alignItems: "center", justifyContent: "center", boxSize: "1.125rem", borderRadius: "full", bg: picked.fill, color: picked.ink, opacity: selected ? 1 : 0, transform: selected ? "scale(1)" : "scale(0.6)", transition: transitionFor(["opacity", "transform"], "base"), sx: reducedMotionSx({ transform: "none" }), children: _jsx(Check, { size: 12, strokeWidth: 3 }) })] }) }), _jsx(Text, { as: "span", maxW: "100%", fontSize: "xs", fontWeight: selected ? 600 : 500, lineHeight: "short", textAlign: "center", noOfLines: 2, wordBreak: "break-word", children: label }), hint ? (_jsx(Text, { as: "span", fontSize: "xs", lineHeight: "short", color: rest.hint, noOfLines: 1, children: hint })) : null] }));
69
+ }
70
+ const isPack = variant === "pack";
71
+ const surface = {
72
+ display: "inline-flex",
73
+ flexDirection: "column",
74
+ alignItems: "center",
75
+ justifyContent: "center",
76
+ minW: isPack ? "5.75rem" : "3.5rem",
77
+ h: isPack ? PACK_HEIGHT[size] : CHIP_HEIGHT[size],
78
+ px: isPack ? 3 : 4,
79
+ borderRadius: "xl",
80
+ bg: tone.fill,
81
+ color: tone.ink,
82
+ fontSize: size === "lg" ? "md" : "sm",
83
+ fontWeight: 600,
84
+ lineHeight: "short",
85
+ whiteSpace: "nowrap",
86
+ boxShadow: invalid && !selected ? errorRing(colors) : "none",
87
+ };
88
+ const content = (_jsxs(Box, { as: "span", display: "inline-flex", alignItems: "center", children: [_jsx(CheckGrow, { selected: selected }), _jsx(Box, { as: "span", sx: { fontVariantNumeric: "tabular-nums" }, children: label })] }));
89
+ return (_jsxs(Box, { ...base, ...surface, sx: {
90
+ ...motion,
91
+ "&:hover:not(:disabled):not([aria-checked=true])": unavailable ? undefined : { backgroundColor: tone.hoverFill },
92
+ ...(unavailable ? { "&::after": { content: '""', ...strikeLayer(band("currentColor", "0.5px")) } } : {}),
93
+ }, children: [content, isPack && hint ? (_jsx(Text, { as: "span", mt: "0.125rem", fontSize: "0.6875rem", fontWeight: 500, color: tone.hint, sx: { fontVariantNumeric: "tabular-nums" }, children: hint })) : null, !isPack && hint ? (_jsx(Text, { as: "span", position: "absolute", top: "-0.375rem", right: "-0.25rem", px: "0.375rem", py: "0.0625rem", borderRadius: "full", bg: colors.surfaceRaised, color: colors.text[800], fontSize: "0.625rem", fontWeight: 600, lineHeight: "1rem", boxShadow: `0 0 0 1px ${colors.boxborder[200]}`, pointerEvents: "none", children: hint })) : null] }));
94
+ });
95
+ export default OptionChip;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ import { mix } from "../../Theme/tokens/builders/color.js";
2
+ import { AA_NORMAL_TEXT, onFilled } from "../../Theme/tokens/builders/accentText.js";
3
+ import { liftToContrast } from "../../Theme/tokens/builders/outlineRung.js";
4
+ /** Resting and selected fills for an option; selection is the neutral ink fill, never the brand. */
5
+ export const optionInk = (colors) => {
6
+ const selectedFill = colors.header[900];
7
+ const selectedInk = onFilled(selectedFill, colors.white, colors.black);
8
+ const rest = {
9
+ fill: colors.background[300],
10
+ hoverFill: colors.background[400],
11
+ ink: colors.text[800],
12
+ hint: liftToContrast(colors.text[700], colors.background[400], AA_NORMAL_TEXT),
13
+ };
14
+ const selected = {
15
+ fill: selectedFill,
16
+ hoverFill: selectedFill,
17
+ ink: selectedInk,
18
+ hint: liftToContrast(mix(selectedInk, selectedFill, 0.2), selectedFill, AA_NORMAL_TEXT),
19
+ };
20
+ return { rest, selected };
21
+ };
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Flex, Text, VisuallyHidden } from "@chakra-ui/react";
3
+ import { Check } from "lucide-react";
4
+ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
5
+ import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
6
+ import { reducedMotionSx } from "../../Theme/chakra/motion.js";
7
+ import { onFilled } from "../../Theme/tokens/builders/accentText.js";
8
+ const DEFAULT_LABELS = { done: "Completed", current: "In progress", upcoming: "Upcoming" };
9
+ const MARKER = "1.5rem";
10
+ const RULE = "2px";
11
+ const Marker = ({ state, colors }) => {
12
+ const ink = colors.header[900];
13
+ const base = {
14
+ as: "span",
15
+ "aria-hidden": true,
16
+ display: "inline-flex",
17
+ alignItems: "center",
18
+ justifyContent: "center",
19
+ boxSize: MARKER,
20
+ flexShrink: 0,
21
+ borderRadius: "full",
22
+ transition: transitionFor(["background-color", "box-shadow"]),
23
+ sx: reducedMotionSx(),
24
+ };
25
+ if (state === "done") {
26
+ return (_jsx(Box, { ...base, bg: ink, color: onFilled(ink, colors.white, colors.black), children: _jsx(Check, { size: 14, strokeWidth: 3 }) }));
27
+ }
28
+ if (state === "current") {
29
+ return (_jsx(Box, { ...base, bg: "transparent", boxShadow: `inset 0 0 0 2px ${ink}`, children: _jsx(Box, { as: "span", boxSize: "0.5rem", borderRadius: "full", bg: ink }) }));
30
+ }
31
+ return _jsx(Box, { ...base, bg: "transparent", boxShadow: `inset 0 0 0 1.5px ${colors.textMuted}` });
32
+ };
33
+ const StepText = ({ step, copy, align, colors, }) => {
34
+ const active = step.state !== "upcoming";
35
+ return (_jsxs(Box, { textAlign: align, minW: 0, children: [_jsxs(Text, { as: "span", display: "block", fontSize: "sm", fontWeight: active ? 700 : 500, lineHeight: 1.4, color: active ? colors.header[900] : colors.textMuted, children: [_jsxs(VisuallyHidden, { children: [copy[step.state], ": "] }), step.label] }), step.date && (_jsx(Text, { as: "span", display: "block", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, sx: { fontVariantNumeric: "tabular-nums" }, children: step.date })), step.detail && (_jsx(Text, { as: "span", display: "block", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: step.detail }))] }));
36
+ };
37
+ /** Order tracking steps: filled check, ringed dot and hollow ring markers, each backed by spoken state text. */
38
+ const OrderStatusTimeline = ({ steps, orientation = "vertical", labels, "aria-label": ariaLabel = "Order status", "data-testid": testId, }) => {
39
+ const { colors } = useCustomTheme();
40
+ const copy = { ...DEFAULT_LABELS, ...labels };
41
+ const filledRule = colors.header[900];
42
+ const idleRule = colors.boxborder[300];
43
+ if (orientation === "horizontal") {
44
+ return (_jsx(Box, { as: "ol", "aria-label": ariaLabel, display: "grid", gridTemplateColumns: `repeat(${steps.length}, minmax(0, 1fr))`, m: 0, p: 0, listStyleType: "none", "data-testid": testId, children: steps.map((step, i) => {
45
+ const before = i > 0 && steps[i - 1].state === "done";
46
+ const after = step.state === "done";
47
+ return (_jsxs(Flex, { as: "li", direction: "column", align: "center", gap: 2, px: 1, "aria-current": step.state === "current" ? "step" : undefined, "data-state": step.state, children: [_jsxs(Flex, { align: "center", w: "100%", children: [_jsx(Box, { flex: 1, h: RULE, bg: i === 0 ? "transparent" : before ? filledRule : idleRule }), _jsx(Marker, { state: step.state, colors: colors }), _jsx(Box, { flex: 1, h: RULE, bg: i === steps.length - 1 ? "transparent" : after ? filledRule : idleRule })] }), _jsx(StepText, { step: step, copy: copy, align: "center", colors: colors })] }, step.id));
48
+ }) }));
49
+ }
50
+ return (_jsx(Box, { as: "ol", "aria-label": ariaLabel, m: 0, p: 0, listStyleType: "none", "data-testid": testId, children: steps.map((step, i) => {
51
+ const last = i === steps.length - 1;
52
+ return (_jsxs(Flex, { as: "li", gap: 3, "aria-current": step.state === "current" ? "step" : undefined, "data-state": step.state, children: [_jsxs(Flex, { direction: "column", align: "center", flexShrink: 0, children: [_jsx(Marker, { state: step.state, colors: colors }), !last && _jsx(Box, { flex: 1, w: RULE, minH: "1.5rem", my: 1, bg: step.state === "done" ? filledRule : idleRule })] }), _jsx(Box, { pb: last ? 0 : 4, pt: "0.125rem", flex: 1, minW: 0, children: _jsx(StepText, { step: step, copy: copy, align: "left", colors: colors }) })] }, step.id));
53
+ }) }));
54
+ };
55
+ export default OrderStatusTimeline;
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useId } from "react";
3
+ import { Box, Flex, Text } from "@chakra-ui/react";
4
+ import { PartyPopper } from "lucide-react";
5
+ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
6
+ import { resolveSoftTone, toneScale } from "../../Theme/tokens/builders/tone.js";
7
+ import { formatPrice } from "../../Utils/price.js";
8
+ import ProgressBar from "../ProgressBar/ProgressBar.js";
9
+ import Skeletons from "../Skeletons/Skeletons.js";
10
+ const DEFAULT_LABELS = {
11
+ title: "Price details",
12
+ total: "Total",
13
+ free: "FREE",
14
+ savings: (amount) => `You save ${amount} on this order`,
15
+ addMore: (amount) => `Add ${amount} more for free delivery`,
16
+ unlocked: "You've unlocked free delivery",
17
+ progressLabel: "Progress to free delivery",
18
+ };
19
+ const MINUS = "−";
20
+ const tabular = { fontVariantNumeric: "tabular-nums" };
21
+ const SummarySkeleton = () => (_jsxs(Flex, { direction: "column", gap: 4, p: 5, borderRadius: "1.5rem", "aria-busy": "true", "data-testid": "order-summary-skeleton", children: [_jsx(Skeletons, { type: "skeleton", height: 4, width: "40%" }), [0, 1, 2].map((row) => (_jsxs(Flex, { justify: "space-between", children: [_jsx(Skeletons, { type: "skeleton", height: 3, width: "30%" }), _jsx(Skeletons, { type: "skeleton", height: 3, width: "20%" })] }, row))), _jsxs(Flex, { justify: "space-between", pt: 2, children: [_jsx(Skeletons, { type: "skeleton", height: 5, width: "25%" }), _jsx(Skeletons, { type: "skeleton", height: 5, width: "30%" })] })] }));
22
+ /** Tonal price panel: label/amount rows, a large tabular total, a calm savings banner and free-delivery progress. */
23
+ const OrderSummary = ({ lines, total, savings, taxNote, freeShippingProgress, hideTitle = false, isLoading = false, currency, locale, labels, "data-testid": testId, }) => {
24
+ const { colors } = useCustomTheme();
25
+ const headingId = useId();
26
+ const copy = { ...DEFAULT_LABELS, ...labels };
27
+ const fmt = { currency, locale };
28
+ const panel = colors.background[100];
29
+ if (isLoading)
30
+ return _jsx(SummarySkeleton, {});
31
+ const inkFor = (line, isFree, isDeduction) => {
32
+ if (isFree || isDeduction || line.tone === "success")
33
+ return colors.semanticText.success;
34
+ return line.tone === "muted" ? colors.textMuted : colors.header[900];
35
+ };
36
+ const amountText = (line) => {
37
+ if (typeof line.amount === "string")
38
+ return { text: line.amount, isFree: false, isDeduction: false };
39
+ if (line.amount === 0 && line.freeWhenZero)
40
+ return { text: copy.free, isFree: true, isDeduction: false };
41
+ if (line.amount < 0)
42
+ return { text: `${MINUS}${formatPrice(Math.abs(line.amount), fmt)}`, isFree: false, isDeduction: true };
43
+ return { text: formatPrice(line.amount, fmt), isFree: false, isDeduction: false };
44
+ };
45
+ const success = resolveSoftTone(colors, toneScale(colors, "success"), panel);
46
+ const progress = freeShippingProgress;
47
+ const remaining = progress ? Math.max(0, progress.threshold - progress.current) : 0;
48
+ const unlocked = !!progress && remaining === 0;
49
+ const percent = progress && progress.threshold > 0 ? Math.min(100, Math.round((progress.current / progress.threshold) * 100)) : 0;
50
+ const progressText = unlocked ? copy.unlocked : copy.addMore(formatPrice(remaining, fmt));
51
+ return (_jsxs(Flex, { direction: "column", gap: 3, "data-testid": testId, children: [progress && (_jsxs(Flex, { direction: "column", gap: 2, px: 1, "data-testid": "order-summary-progress", children: [_jsx(Text, { as: "p", fontSize: "sm", fontWeight: 600, lineHeight: 1.4, color: unlocked ? colors.semanticText.success : colors.header[900], sx: tabular, children: progressText }), _jsx(ProgressBar, { size: "xs", value: percent, colorScheme: unlocked ? "green" : "primary", borderRadius: "full", "aria-label": copy.progressLabel, "aria-valuetext": progressText })] })), _jsxs(Box, { as: "section", "aria-labelledby": hideTitle ? undefined : headingId, "aria-label": hideTitle ? copy.title : undefined, bg: panel, borderRadius: "1.5rem", p: 5, children: [!hideTitle && (_jsx(Text, { as: "h2", id: headingId, fontSize: "md", fontWeight: 700, lineHeight: 1.4, color: colors.header[900], mb: 4, children: copy.title })), _jsx(Flex, { as: "dl", direction: "column", gap: 3, m: 0, children: lines.map((line) => {
52
+ var _a;
53
+ const { text, isFree, isDeduction } = amountText(line);
54
+ const ink = inkFor(line, isFree, isDeduction);
55
+ return (_jsxs(Flex, { justify: "space-between", align: "flex-start", gap: 4, children: [_jsxs(Box, { as: "dt", minW: 0, children: [_jsx(Text, { as: "span", fontSize: "sm", lineHeight: 1.45, color: line.tone === "muted" ? colors.textMuted : colors.text[800], children: line.label }), line.hint && (_jsx(Text, { as: "span", display: "block", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: line.hint }))] }), _jsx(Box, { as: "dd", m: 0, flexShrink: 0, textAlign: "right", fontSize: "sm", fontWeight: isFree || isDeduction ? 600 : 500, lineHeight: 1.45, color: ink, sx: tabular, children: text })] }, (_a = line.id) !== null && _a !== void 0 ? _a : line.label));
56
+ }) }), _jsxs(Flex, { justify: "space-between", align: "baseline", gap: 4, mt: 6, children: [_jsx(Text, { as: "span", fontSize: "md", fontWeight: 700, color: colors.header[900], children: copy.total }), _jsxs(Box, { textAlign: "right", children: [_jsx(Text, { as: "span", display: "block", fontSize: "1.5rem", fontWeight: 700, lineHeight: 1.2, letterSpacing: "-0.02em", color: colors.header[900], sx: tabular, "data-testid": "order-summary-total", children: formatPrice(total, fmt) }), taxNote && (_jsx(Text, { as: "span", display: "block", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: taxNote }))] })] }), savings !== undefined && savings > 0 && (_jsxs(Flex, { align: "center", gap: 2, mt: 4, px: 3, py: 2.5, borderRadius: "0.75rem", bg: success.bg, color: success.fg, "data-testid": "order-summary-savings", children: [_jsx(PartyPopper, { size: 16, "aria-hidden": true }), _jsx(Text, { as: "span", fontSize: "sm", fontWeight: 600, lineHeight: 1.4, sx: tabular, children: copy.savings(formatPrice(savings, fmt)) })] }))] })] }));
57
+ };
58
+ export default OrderSummary;
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useId } from "react";
3
+ import { Box, Flex, Text } from "@chakra-ui/react";
4
+ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
5
+ import { RadioIndicator, selectableSurface, useSelectable } from "../CheckoutKit/selectable.js";
6
+ import Tag from "../Tag/Tag.js";
7
+ /** Tonal payment-method row: icon well, title, subtitle, offer tag, and an area that opens when it is chosen. */
8
+ const PaymentOption = ({ value, title, subtitle, icon, offer, selected, onSelect, disabled = false, children, "data-testid": testId, }) => {
9
+ const { colors } = useCustomTheme();
10
+ const uid = useId();
11
+ const titleId = `${uid}-title`;
12
+ const subtitleId = `${uid}-subtitle`;
13
+ const regionId = `${uid}-region`;
14
+ const { isSelected, interactive, inGroup, ringed, props } = useSelectable({ value, selected, disabled, onSelect });
15
+ const selectable = inGroup || !!onSelect;
16
+ const expanded = isSelected && !!children;
17
+ return (_jsxs(Flex, { direction: "column", "data-testid": testId, "data-selected": isSelected || undefined, ...selectableSurface(colors, { selected: isSelected && selectable, disabled, interactive, ringed }), children: [_jsxs(Flex, { ...props, "data-radio": true, "aria-disabled": selectable && disabled ? true : undefined, "aria-labelledby": props.role ? titleId : undefined, "aria-describedby": props.role && subtitle ? subtitleId : undefined, "aria-controls": expanded && props.role === "radio" ? regionId : undefined, align: "center", gap: 3, p: 4, borderRadius: "1rem", cursor: interactive ? "pointer" : "default", outline: "none", children: [selectable && _jsx(RadioIndicator, { selected: isSelected }), icon && (_jsx(Flex, { as: "span", "aria-hidden": true, align: "center", justify: "center", boxSize: 10, flexShrink: 0, borderRadius: "0.75rem", bg: colors.background[50], color: colors.header[900], children: icon })), _jsxs(Box, { flex: 1, minW: 0, children: [_jsx(Text, { as: "span", id: titleId, display: "block", fontSize: "sm", fontWeight: 600, lineHeight: 1.4, color: colors.header[900], children: title }), subtitle && (_jsx(Text, { as: "span", id: subtitleId, display: "block", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: subtitle }))] }), offer && _jsx(Tag, { label: offer, size: "xs", tone: "success" })] }), expanded && (_jsx(Box, { id: regionId, role: "group", "aria-labelledby": titleId, px: 4, pb: 4, pl: selectable ? "3.25rem" : 4, children: children }))] }));
18
+ };
19
+ export default PaymentOption;
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { SelectableGroup } from "../CheckoutKit/selectable.js";
3
+ /** Radiogroup wrapper for `PaymentOption`s. */
4
+ const PaymentOptionGroup = (props) => _jsx(SelectableGroup, { ...props });
5
+ export default PaymentOptionGroup;
@@ -0,0 +1,170 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useId, useRef, useState } from "react";
3
+ import { Box, Flex, Text, VisuallyHidden } from "@chakra-ui/react";
4
+ import { keyframes } from "@emotion/react";
5
+ import { Check, CircleAlert, Info } from "lucide-react";
6
+ import Button from "../Button/Button.js";
7
+ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
8
+ import { fieldFocusVisible } from "../../Theme/chakra/focusRing.styles.js";
9
+ import { FIELD_RADIUS, FIELD_TRANSITION, fieldHoverBorder, fieldTextStyles } from "../Common/fieldStyles.js";
10
+ import { placeholderInk } from "../../Theme/tokens/builders/placeholderInk.js";
11
+ import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
12
+ import { reducedMotionSx } from "../../Theme/chakra/motion.js";
13
+ const DEFAULT_LABELS = {
14
+ heading: "Check delivery",
15
+ inputLabel: "Pincode",
16
+ placeholder: "Enter pincode",
17
+ check: "Check",
18
+ change: "Change",
19
+ hint: "Delivery date, COD and returns for your area",
20
+ invalid: "Enter a 6-digit pincode",
21
+ unserviceable: "We don't deliver here yet",
22
+ checking: "Checking delivery",
23
+ deliveryBy: "Delivery by",
24
+ codAvailable: "Cash on Delivery available",
25
+ codUnavailable: "Cash on Delivery not available",
26
+ deliverTo: "Deliver to",
27
+ unserviceableHint: "Try another pincode",
28
+ };
29
+ const PIN_LENGTH = 6;
30
+ const FIELD_HEIGHT = "3rem";
31
+ const ERROR_RING = "1.5px";
32
+ const tabular = { fontVariantNumeric: "tabular-nums" };
33
+ const pulse = keyframes `0%, 100% { opacity: 1; } 50% { opacity: 0.5; }`;
34
+ const digitsOnly = (raw) => raw.replace(/\D/g, "").slice(0, PIN_LENGTH);
35
+ const isPin = (pin) => pin.length === PIN_LENGTH;
36
+ const isThenable = (value) => typeof value === "object" && value !== null && typeof value.then === "function";
37
+ const SkeletonBlock = ({ w, h }) => {
38
+ const { colors } = useCustomTheme();
39
+ return (_jsx(Box, { "aria-hidden": true, w: w, h: h, borderRadius: "md", bg: colors.background[200], animation: `${pulse} 1.2s ease-in-out infinite`, sx: reducedMotionSx() }));
40
+ };
41
+ /** Pincode field that answers with a delivery date, COD availability and a shipping note, held in place so the panel never jumps. */
42
+ const PincodeChecker = ({ value, defaultValue = "", onValueChange, status: statusProp, result: resultProp, onCheck, autoCheck = true, checkOnMount = false, labels, "data-testid": testId, }) => {
43
+ const { colors } = useCustomTheme();
44
+ const copy = { ...DEFAULT_LABELS, ...labels };
45
+ const baseId = useId();
46
+ const inputId = `${baseId}-pin`;
47
+ const hintId = `${baseId}-hint`;
48
+ const errorId = `${baseId}-error`;
49
+ const [innerPin, setInnerPin] = useState(digitsOnly(defaultValue));
50
+ const [innerStatus, setInnerStatus] = useState("idle");
51
+ const [innerResult, setInnerResult] = useState();
52
+ const [editing, setEditing] = useState(false);
53
+ const [localInvalid, setLocalInvalid] = useState(false);
54
+ const inputRef = useRef(null);
55
+ const changeRef = useRef(null);
56
+ const latest = useRef(0);
57
+ const mounted = useRef(true);
58
+ const focusInput = useRef(false);
59
+ const focusChange = useRef(false);
60
+ const pin = value === undefined ? innerPin : digitsOnly(value);
61
+ const status = statusProp !== null && statusProp !== void 0 ? statusProp : innerStatus;
62
+ const result = resultProp !== null && resultProp !== void 0 ? resultProp : innerResult;
63
+ const invalid = localInvalid || status === "invalid";
64
+ const outcome = status === "serviceable" || status === "unserviceable"
65
+ ? status
66
+ : status === "idle" || status === "invalid"
67
+ ? null
68
+ : result
69
+ ? result.ok
70
+ ? "serviceable"
71
+ : "unserviceable"
72
+ : null;
73
+ const checking = status === "checking";
74
+ const showField = editing || status === "idle" || invalid;
75
+ useEffect(() => {
76
+ mounted.current = true;
77
+ return () => {
78
+ mounted.current = false;
79
+ };
80
+ }, []);
81
+ useEffect(() => {
82
+ if (status === "serviceable" || status === "unserviceable")
83
+ setEditing(false);
84
+ }, [status]);
85
+ useEffect(() => {
86
+ var _a, _b;
87
+ if (showField && focusInput.current) {
88
+ focusInput.current = false;
89
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
90
+ }
91
+ if (!showField && focusChange.current) {
92
+ focusChange.current = false;
93
+ (_b = changeRef.current) === null || _b === void 0 ? void 0 : _b.focus();
94
+ }
95
+ }, [showField]);
96
+ const settle = useCallback((answer) => {
97
+ if (document.activeElement === inputRef.current)
98
+ focusChange.current = true;
99
+ setInnerResult(answer);
100
+ setInnerStatus(answer.ok ? "serviceable" : "unserviceable");
101
+ setEditing(false);
102
+ }, []);
103
+ const run = useCallback((code) => {
104
+ if (!isPin(code)) {
105
+ setLocalInvalid(true);
106
+ return;
107
+ }
108
+ setLocalInvalid(false);
109
+ setEditing(showField);
110
+ const ticket = ++latest.current;
111
+ const answer = onCheck === null || onCheck === void 0 ? void 0 : onCheck(code);
112
+ if (answer === undefined)
113
+ return;
114
+ if (!isThenable(answer)) {
115
+ settle(answer);
116
+ return;
117
+ }
118
+ setInnerStatus("checking");
119
+ answer.then((resolved) => {
120
+ if (mounted.current && ticket === latest.current)
121
+ settle(resolved);
122
+ }, () => {
123
+ if (mounted.current && ticket === latest.current)
124
+ settle({ ok: false });
125
+ });
126
+ }, [onCheck, settle, showField]);
127
+ useEffect(() => {
128
+ if (checkOnMount && isPin(pin))
129
+ run(pin);
130
+ // eslint-disable-next-line react-hooks/exhaustive-deps
131
+ }, []);
132
+ const onChange = (event) => {
133
+ const next = digitsOnly(event.target.value);
134
+ if (value === undefined)
135
+ setInnerPin(next);
136
+ onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(next);
137
+ setEditing(true);
138
+ setLocalInvalid(false);
139
+ if (autoCheck && isPin(next))
140
+ run(next);
141
+ };
142
+ const onSubmit = (event) => {
143
+ var _a;
144
+ event.preventDefault();
145
+ if (!isPin(pin))
146
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
147
+ run(pin);
148
+ };
149
+ const reopen = () => {
150
+ focusInput.current = true;
151
+ setEditing(true);
152
+ };
153
+ const fieldRing = invalid
154
+ ? `inset 0 0 0 ${ERROR_RING} ${colors.semanticText.error}`
155
+ : "none";
156
+ const field = (_jsxs(Box, { as: "form", noValidate: true, onSubmit: onSubmit, children: [_jsxs(Flex, { gap: 2, align: "stretch", children: [_jsx(Box, { as: "input", ref: inputRef, id: inputId, type: "text", inputMode: "numeric", autoComplete: "postal-code", maxLength: PIN_LENGTH, value: pin, placeholder: copy.placeholder, onChange: onChange, onBlur: () => {
157
+ if (pin.length > 0 && !isPin(pin))
158
+ setLocalInvalid(true);
159
+ }, "aria-invalid": invalid || undefined, "aria-describedby": invalid ? errorId : hintId, flex: 1, minW: 0, h: FIELD_HEIGHT, px: 4, fontSize: "md", bg: colors.background[50], borderWidth: "1px", borderStyle: "solid", borderColor: "transparent", borderRadius: FIELD_RADIUS, boxShadow: fieldRing, transition: FIELD_TRANSITION, _placeholder: { color: placeholderInk(colors), opacity: 1 }, _hover: invalid ? undefined : { borderColor: fieldHoverBorder(colors) }, _focusVisible: {
160
+ borderColor: invalid ? "transparent" : colors.primary[500],
161
+ ...fieldFocusVisible(colors),
162
+ boxShadow: invalid ? `${fieldRing}, ${fieldFocusVisible(colors).boxShadow}` : fieldFocusVisible(colors).boxShadow,
163
+ }, sx: { ...fieldTextStyles(colors), ...tabular, letterSpacing: "0.08em", ...reducedMotionSx() } }), _jsx(Button, { type: "submit", size: "lg", label: copy.check })] }), invalid ? (_jsxs(Flex, { id: errorId, mt: 2, gap: 1.5, align: "center", fontSize: "sm", fontWeight: 500, color: colors.semanticText.error, children: [_jsx(CircleAlert, { size: 16, "aria-hidden": true, style: { flexShrink: 0 } }), _jsx(Text, { as: "span", children: (status === "invalid" && (result === null || result === void 0 ? void 0 : result.message)) || copy.invalid })] })) : (_jsx(Text, { id: hintId, mt: 2, fontSize: "xs", color: colors.textMuted, children: copy.hint }))] }));
164
+ const changeButton = (_jsx(Button, { ref: changeRef, variant: "link", size: "sm", h: "2.75rem", flexShrink: 0, onClick: reopen, label: copy.change }));
165
+ const savedLine = !showField && outcome === "serviceable" ? (_jsxs(Flex, { align: "center", justify: "space-between", gap: 3, children: [_jsxs(Text, { fontSize: "sm", color: colors.textMuted, sx: tabular, children: [copy.deliverTo, " ", _jsxs(Text, { as: "span", fontWeight: 600, color: colors.header[900], children: [pin, (result === null || result === void 0 ? void 0 : result.city) ? ` · ${result.city}` : ""] })] }), changeButton] })) : null;
166
+ const details = outcome === "serviceable" && result ? (_jsxs(Flex, { direction: "column", gap: 2, children: [result.deliveryBy && (_jsxs(Text, { fontSize: "lg", lineHeight: 1.3, sx: tabular, children: [_jsxs(Text, { as: "span", fontSize: "sm", color: colors.textMuted, children: [copy.deliveryBy, " "] }), _jsx(Text, { as: "span", fontWeight: 700, color: colors.header[900], children: result.deliveryBy })] })), result.cod !== undefined && (_jsxs(Flex, { align: "center", gap: 2, fontSize: "sm", fontWeight: 500, color: colors.header[900], children: [result.cod ? (_jsx(Box, { as: "span", color: colors.semanticText.success, display: "inline-flex", children: _jsx(Check, { size: 16, "aria-hidden": true }) })) : (_jsx(Box, { as: "span", color: colors.semanticText.warning, display: "inline-flex", children: _jsx(Info, { size: 16, "aria-hidden": true }) })), _jsx(Text, { as: "span", children: result.cod ? copy.codAvailable : copy.codUnavailable })] })), result.shippingNote && (_jsx(Text, { fontSize: "xs", color: colors.textMuted, children: result.shippingNote }))] })) : outcome === "unserviceable" ? (_jsxs(Flex, { align: "flex-start", justify: "space-between", gap: 3, children: [_jsxs(Box, { children: [_jsx(Text, { fontSize: "md", fontWeight: 600, color: colors.header[900], children: (result === null || result === void 0 ? void 0 : result.message) || copy.unserviceable }), _jsx(Text, { fontSize: "sm", color: colors.textMuted, children: copy.unserviceableHint })] }), !showField && changeButton] })) : null;
167
+ const skeleton = checking && !outcome && (_jsxs(Flex, { direction: "column", gap: 3, "aria-hidden": true, children: [_jsx(SkeletonBlock, { w: "55%", h: "0.875rem" }), _jsx(SkeletonBlock, { w: "40%", h: "1.5rem" }), _jsx(SkeletonBlock, { w: "70%", h: "0.875rem" })] }));
168
+ return (_jsxs(Box, { "aria-busy": checking || undefined, bg: colors.background[100], borderRadius: "xl", p: 4, "data-testid": testId, children: [_jsx(Text, { as: "h2", fontSize: "md", fontWeight: 600, color: colors.header[900], mb: 3, children: copy.heading }), showField && (_jsxs(_Fragment, { children: [_jsx(VisuallyHidden, { as: "label", htmlFor: inputId, children: copy.inputLabel }), field] })), _jsxs(Flex, { direction: "column", gap: 3, mt: showField && (outcome || skeleton) ? 4 : 0, "aria-live": "polite", opacity: checking && outcome ? 0.6 : 1, transition: transitionFor(["opacity"]), sx: reducedMotionSx(), children: [checking && _jsx(VisuallyHidden, { children: copy.checking }), savedLine, details, skeleton] })] }));
169
+ };
170
+ export default PincodeChecker;
@@ -0,0 +1,39 @@
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Box, Flex, Text, VisuallyHidden } from "@chakra-ui/react";
3
+ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
4
+ import { discountAmount, discountPercent, formatPrice } from "../../Utils/price.js";
5
+ const SCALE = {
6
+ sm: { price: "0.9375rem", priceLine: 1.33, secondary: "0.75rem", secondaryLine: 1.33, note: "0.75rem" },
7
+ md: { price: "1.125rem", priceLine: 1.22, secondary: "0.8125rem", secondaryLine: 1.38, note: "0.75rem" },
8
+ lg: { price: "1.75rem", priceLine: 1.21, secondary: "0.9375rem", secondaryLine: 1.47, note: "0.8125rem" },
9
+ };
10
+ const ALIGN = {
11
+ start: { items: "flex-start", justify: "flex-start", text: "left" },
12
+ center: { items: "center", justify: "center", text: "center" },
13
+ end: { items: "flex-end", justify: "flex-end", text: "right" },
14
+ };
15
+ const DEFAULT_LABELS = {
16
+ price: "Price",
17
+ originalPrice: "Original price",
18
+ off: (percent) => `${percent}% off`,
19
+ save: (amount) => `You save ${amount}`,
20
+ };
21
+ const unitText = (unit, fmt) => typeof unit === "string" ? unit : `${formatPrice(unit.value, fmt)} / ${unit.per === 1 ? "" : `${unit.per} `}${unit.unit}`;
22
+ const tabular = { fontVariantNumeric: "tabular-nums" };
23
+ /** Selling price, struck MRP, discount, savings, tax note and unit price in one tabular, screen-reader-friendly block. */
24
+ const PriceBlock = ({ price, mrp, priceRange, size = "md", align = "start", showSavings = false, taxNote, unitPrice, currency, locale, labels, "data-testid": testId, }) => {
25
+ const { colors } = useCustomTheme();
26
+ const fmt = { currency, locale };
27
+ const copy = { ...DEFAULT_LABELS, ...labels };
28
+ const scale = SCALE[size];
29
+ const a = ALIGN[align];
30
+ const isRange = !!priceRange && priceRange.min !== priceRange.max;
31
+ const selling = priceRange ? priceRange.min : price;
32
+ const priceText = isRange ? `${formatPrice(priceRange.min, fmt)} – ${formatPrice(priceRange.max, fmt)}` : selling === undefined ? null : formatPrice(selling, fmt);
33
+ const percent = !priceRange && selling !== undefined ? discountPercent(selling, mrp) : 0;
34
+ const saved = !priceRange && selling !== undefined ? discountAmount(selling, mrp) : 0;
35
+ const hasDiscount = percent > 0;
36
+ const muted = { fontSize: scale.note, lineHeight: 1.4, color: colors.textMuted, sx: tabular };
37
+ return (_jsxs(Flex, { direction: "column", align: a.items, gap: 0.5, textAlign: a.text, "data-testid": testId, children: [_jsxs(Flex, { align: "baseline", justify: a.justify, columnGap: 2, rowGap: 0, wrap: "wrap", children: [priceText !== null && (_jsxs(Text, { as: "span", fontSize: scale.price, lineHeight: scale.priceLine, fontWeight: 700, letterSpacing: "-0.02em", color: colors.header[900], sx: tabular, children: [_jsxs(VisuallyHidden, { children: [copy.price, " "] }), priceText] })), hasDiscount && mrp !== undefined && (_jsxs(_Fragment, { children: [_jsxs(Box, { as: "del", fontSize: scale.secondary, lineHeight: scale.secondaryLine, color: colors.textMuted, textDecoration: "line-through", sx: tabular, children: [_jsxs(VisuallyHidden, { children: [copy.originalPrice, " "] }), formatPrice(mrp, fmt)] }), _jsx(Text, { as: "span", fontSize: scale.secondary, lineHeight: scale.secondaryLine, fontWeight: 600, color: colors.semanticText.success, sx: tabular, children: copy.off(percent) })] }))] }), showSavings && hasDiscount && (_jsx(Text, { as: "span", fontSize: scale.note, lineHeight: 1.4, fontWeight: 600, color: colors.semanticText.success, sx: tabular, children: copy.save(formatPrice(saved, fmt)) })), taxNote && (_jsx(Text, { as: "span", ...muted, children: taxNote })), unitPrice != null && (_jsx(Text, { as: "span", ...muted, children: unitText(unitPrice, fmt) }))] }));
38
+ };
39
+ export default PriceBlock;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,59 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Flex, Text } from "@chakra-ui/react";
3
+ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
4
+ import { isDarkCanvas } from "../../Theme/tokens/builders/accentText.js";
5
+ import { resolveFilledSurface } from "../../Theme/tokens/builders/filledSurface.js";
6
+ import { overlayScrim } from "../../Theme/tokens/builders/scrim.js";
7
+ import { resolveStatusTone } from "../../Theme/tokens/builders/statusTone.js";
8
+ const scaleFor = (colors, tone) => {
9
+ switch (tone) {
10
+ case "accent":
11
+ return colors.primary;
12
+ case "neutral":
13
+ return colors.gray;
14
+ case "success":
15
+ return colors.semantic.success;
16
+ case "warning":
17
+ return colors.semantic.warning;
18
+ case "danger":
19
+ return colors.semantic.error;
20
+ case "info":
21
+ return colors.semantic.info;
22
+ }
23
+ };
24
+ const SIZE = {
25
+ sm: { h: "1.25rem", font: "0.6875rem", px: 1.5 },
26
+ md: { h: "1.5rem", font: "0.75rem", px: 2 },
27
+ };
28
+ const lookFor = (colors, tone, variant) => {
29
+ if (variant === "glass") {
30
+ const dot = tone === "inverse" || tone === "neutral" ? undefined : resolveFilledSurface(scaleFor(colors, tone), colors).fill;
31
+ return { bg: overlayScrim(colors), color: colors.white, dot };
32
+ }
33
+ if (tone === "inverse") {
34
+ return variant === "soft"
35
+ ? { bg: colors.background[100], color: colors.header[900] }
36
+ : { bg: colors.header[900], color: colors.background[50] };
37
+ }
38
+ const scale = scaleFor(colors, tone);
39
+ if (variant === "soft") {
40
+ const soft = resolveStatusTone(scale, isDarkCanvas(colors.backgroundColor.main) ? "dark" : "light");
41
+ return { bg: soft.bg, color: soft.fg };
42
+ }
43
+ const filled = resolveFilledSurface(scale, colors);
44
+ return { bg: filled.fill, color: filled.color };
45
+ };
46
+ /** Stack of corner badges (sale, new, low stock…) built from `ProductBadge[]`; filled chips resolve ink per brand and mode. */
47
+ const ProductBadges = ({ badges, max = 2, size = "sm", variant = "solid", orientation = "vertical", "data-testid": testId, }) => {
48
+ const { colors } = useCustomTheme();
49
+ const shown = badges.slice(0, Math.max(0, max));
50
+ if (shown.length === 0)
51
+ return null;
52
+ const s = SIZE[size];
53
+ return (_jsx(Flex, { as: "ul", role: "list", listStyleType: "none", m: 0, p: 0, direction: orientation === "vertical" ? "column" : "row", align: "flex-start", wrap: orientation === "vertical" ? "nowrap" : "wrap", gap: 1.5, maxW: "100%", "data-testid": testId, children: shown.map((badge, i) => {
54
+ var _a, _b;
55
+ const look = lookFor(colors, (_a = badge.tone) !== null && _a !== void 0 ? _a : "neutral", variant);
56
+ return (_jsxs(Flex, { as: "li", "data-tone": (_b = badge.tone) !== null && _b !== void 0 ? _b : "neutral", "data-variant": variant, align: "center", gap: 1, h: s.h, px: s.px, maxW: "100%", borderRadius: "md", bg: look.bg, color: look.color, sx: variant === "glass" ? { backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)" } : undefined, children: [look.dot && _jsx(Box, { as: "span", "aria-hidden": true, boxSize: "6px", flexShrink: 0, borderRadius: "full", bg: look.dot }), _jsx(Text, { as: "span", fontSize: s.font, fontWeight: 600, lineHeight: 1, letterSpacing: "0.01em", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", sx: { fontVariantNumeric: "tabular-nums" }, children: badge.label })] }, `${badge.label}-${i}`));
57
+ }) }));
58
+ };
59
+ export default ProductBadges;