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.
- package/CHANGELOG.md +60 -0
- package/COMPONENT-GOTCHAS.md +48 -20
- package/DESIGN-GUIDE.md +18 -1
- package/dist/Components/AddressCard/AddressCard.d.ts +4 -0
- package/dist/Components/AddressCard/AddressCard.js +25 -0
- package/dist/Components/AddressCard/AddressCardGroup.d.ts +4 -0
- package/dist/Components/AddressCard/AddressCardGroup.js +7 -0
- package/dist/Components/AddressCard/AddressCardProps.d.ts +43 -0
- package/dist/Components/AddressCard/AddressCardProps.js +2 -0
- package/dist/Components/BagBar/BagBar.d.ts +4 -0
- package/dist/Components/BagBar/BagBar.js +32 -0
- package/dist/Components/BagBar/BagBarProps.d.ts +30 -0
- package/dist/Components/BagBar/BagBarProps.js +2 -0
- package/dist/Components/CartItem/CartItem.d.ts +4 -0
- package/dist/Components/CartItem/CartItem.js +60 -0
- package/dist/Components/CartItem/CartItemProps.d.ts +64 -0
- package/dist/Components/CartItem/CartItemProps.js +2 -0
- package/dist/Components/CartItem/cartItemOptions.d.ts +3 -0
- package/dist/Components/CartItem/cartItemOptions.js +13 -0
- package/dist/Components/CheckoutKit/selectable.d.ts +58 -0
- package/dist/Components/CheckoutKit/selectable.js +120 -0
- package/dist/Components/Commerce/commerceTypes.d.ts +52 -0
- package/dist/Components/Commerce/commerceTypes.js +2 -0
- package/dist/Components/Commerce/commerceVariants.d.ts +13 -0
- package/dist/Components/Commerce/commerceVariants.js +51 -0
- package/dist/Components/Commerce/index.d.ts +2 -0
- package/dist/Components/Commerce/index.js +18 -0
- package/dist/Components/Commerce/useContainerWidth.d.ts +3 -0
- package/dist/Components/Commerce/useContainerWidth.js +25 -0
- package/dist/Components/CouponField/CouponField.d.ts +4 -0
- package/dist/Components/CouponField/CouponField.js +72 -0
- package/dist/Components/CouponField/CouponFieldProps.d.ts +49 -0
- package/dist/Components/CouponField/CouponFieldProps.js +2 -0
- package/dist/Components/DatePicker/PickerPortal.d.ts +11 -0
- package/dist/Components/DatePicker/PickerPortal.js +26 -0
- package/dist/Components/DatePicker/RangeDatePicker.d.ts +1 -1
- package/dist/Components/DatePicker/RangeDatePicker.js +67 -32
- package/dist/Components/DatePicker/SingleDatePicker.js +49 -13
- package/dist/Components/DatePicker/TimeOnlyPicker.js +39 -4
- package/dist/Components/DetailSections/DetailSections.d.ts +4 -0
- package/dist/Components/DetailSections/DetailSections.js +112 -0
- package/dist/Components/DetailSections/DetailSectionsProps.d.ts +58 -0
- package/dist/Components/DetailSections/DetailSectionsProps.js +2 -0
- package/dist/Components/MediaGallery/MediaFrame.d.ts +31 -0
- package/dist/Components/MediaGallery/MediaFrame.js +55 -0
- package/dist/Components/MediaGallery/MediaGallery.d.ts +4 -0
- package/dist/Components/MediaGallery/MediaGallery.js +206 -0
- package/dist/Components/MediaGallery/MediaGalleryProps.d.ts +76 -0
- package/dist/Components/MediaGallery/MediaGalleryProps.js +20 -0
- package/dist/Components/MediaGallery/MediaLightbox.d.ts +4 -0
- package/dist/Components/MediaGallery/MediaLightbox.js +116 -0
- package/dist/Components/MediaGallery/MediaLightboxProps.d.ts +40 -0
- package/dist/Components/MediaGallery/MediaLightboxProps.js +15 -0
- package/dist/Components/MediaGallery/MediaThumb.d.ts +18 -0
- package/dist/Components/MediaGallery/MediaThumb.js +25 -0
- package/dist/Components/MediaGallery/glass.d.ts +31 -0
- package/dist/Components/MediaGallery/glass.js +47 -0
- package/dist/Components/MediaGallery/mediaGalleryModel.d.ts +22 -0
- package/dist/Components/MediaGallery/mediaGalleryModel.js +83 -0
- package/dist/Components/MediaGallery/motion.d.ts +5 -0
- package/dist/Components/MediaGallery/motion.js +12 -0
- package/dist/Components/MediaGallery/useMatchMedia.d.ts +2 -0
- package/dist/Components/MediaGallery/useMatchMedia.js +20 -0
- package/dist/Components/OffersList/OffersList.d.ts +4 -0
- package/dist/Components/OffersList/OffersList.js +83 -0
- package/dist/Components/OffersList/OffersListProps.d.ts +34 -0
- package/dist/Components/OffersList/OffersListProps.js +2 -0
- package/dist/Components/OptionChip/OptionChip.d.ts +4 -0
- package/dist/Components/OptionChip/OptionChip.js +97 -0
- package/dist/Components/OptionChip/OptionChipProps.d.ts +33 -0
- package/dist/Components/OptionChip/OptionChipProps.js +2 -0
- package/dist/Components/OptionChip/optionInk.d.ts +12 -0
- package/dist/Components/OptionChip/optionInk.js +25 -0
- package/dist/Components/OrderStatusTimeline/OrderStatusTimeline.d.ts +4 -0
- package/dist/Components/OrderStatusTimeline/OrderStatusTimeline.js +57 -0
- package/dist/Components/OrderStatusTimeline/OrderStatusTimelineProps.d.ts +29 -0
- package/dist/Components/OrderStatusTimeline/OrderStatusTimelineProps.js +2 -0
- package/dist/Components/OrderSummary/OrderSummary.d.ts +4 -0
- package/dist/Components/OrderSummary/OrderSummary.js +63 -0
- package/dist/Components/OrderSummary/OrderSummaryProps.d.ts +53 -0
- package/dist/Components/OrderSummary/OrderSummaryProps.js +2 -0
- package/dist/Components/PaymentOption/PaymentOption.d.ts +4 -0
- package/dist/Components/PaymentOption/PaymentOption.js +24 -0
- package/dist/Components/PaymentOption/PaymentOptionGroup.d.ts +4 -0
- package/dist/Components/PaymentOption/PaymentOptionGroup.js +7 -0
- package/dist/Components/PaymentOption/PaymentOptionProps.d.ts +32 -0
- package/dist/Components/PaymentOption/PaymentOptionProps.js +2 -0
- package/dist/Components/PincodeChecker/PincodeChecker.d.ts +4 -0
- package/dist/Components/PincodeChecker/PincodeChecker.js +175 -0
- package/dist/Components/PincodeChecker/PincodeCheckerProps.d.ts +57 -0
- package/dist/Components/PincodeChecker/PincodeCheckerProps.js +2 -0
- package/dist/Components/PriceBlock/PriceBlock.d.ts +4 -0
- package/dist/Components/PriceBlock/PriceBlock.js +41 -0
- package/dist/Components/PriceBlock/PriceBlockProps.d.ts +39 -0
- package/dist/Components/PriceBlock/PriceBlockProps.js +2 -0
- package/dist/Components/ProductBadges/ProductBadges.d.ts +4 -0
- package/dist/Components/ProductBadges/ProductBadges.js +61 -0
- package/dist/Components/ProductBadges/ProductBadgesProps.d.ts +18 -0
- package/dist/Components/ProductBadges/ProductBadgesProps.js +2 -0
- package/dist/Components/ProductCard/ProductCard.d.ts +3 -2
- package/dist/Components/ProductCard/ProductCard.js +103 -52
- package/dist/Components/ProductCard/ProductCardAction.d.ts +17 -0
- package/dist/Components/ProductCard/ProductCardAction.js +65 -0
- package/dist/Components/ProductCard/ProductCardGrid.d.ts +4 -0
- package/dist/Components/ProductCard/ProductCardGrid.js +20 -0
- package/dist/Components/ProductCard/ProductCardMedia.d.ts +18 -0
- package/dist/Components/ProductCard/ProductCardMedia.js +35 -0
- package/dist/Components/ProductCard/ProductCardProps.d.ts +138 -56
- package/dist/Components/ProductCard/ProductCardSkeleton.d.ts +4 -0
- package/dist/Components/ProductCard/ProductCardSkeleton.js +17 -0
- package/dist/Components/ProductCard/ProductCardSwatches.d.ts +15 -0
- package/dist/Components/ProductCard/ProductCardSwatches.js +37 -0
- package/dist/Components/ProductCard/QuickAddSheet.d.ts +4 -0
- package/dist/Components/ProductCard/QuickAddSheet.js +109 -0
- package/dist/Components/ProductCard/QuickAddSheetProps.d.ts +38 -0
- package/dist/Components/ProductCard/QuickAddSheetProps.js +2 -0
- package/dist/Components/ProductCard/cardLabels.d.ts +2 -0
- package/dist/Components/ProductCard/cardLabels.js +16 -0
- package/dist/Components/ProductCard/cardMetrics.d.ts +27 -0
- package/dist/Components/ProductCard/cardMetrics.js +55 -0
- package/dist/Components/ProductCard/productCardFixtures.d.ts +7 -0
- package/dist/Components/ProductCard/productCardFixtures.js +61 -0
- package/dist/Components/ProductCard/productCardModel.d.ts +22 -0
- package/dist/Components/ProductCard/productCardModel.js +79 -0
- package/dist/Components/ProductCard/useMinWidth.d.ts +2 -0
- package/dist/Components/ProductCard/useMinWidth.js +20 -0
- package/dist/Components/ProductDetails/ProductDetails.d.ts +3 -2
- package/dist/Components/ProductDetails/ProductDetails.js +209 -33
- package/dist/Components/ProductDetails/ProductDetailsProps.d.ts +143 -41
- package/dist/Components/ProductDetails/productDetailsModel.d.ts +14 -0
- package/dist/Components/ProductDetails/productDetailsModel.js +45 -0
- package/dist/Components/ProductDetails/useInViewport.d.ts +3 -0
- package/dist/Components/ProductDetails/useInViewport.js +18 -0
- package/dist/Components/QuantityStepper/QuantityStepper.d.ts +4 -0
- package/dist/Components/QuantityStepper/QuantityStepper.js +59 -0
- package/dist/Components/QuantityStepper/QuantityStepperProps.d.ts +24 -0
- package/dist/Components/QuantityStepper/QuantityStepperProps.js +2 -0
- package/dist/Components/Rating/Rating.d.ts +4 -0
- package/dist/Components/Rating/Rating.js +81 -0
- package/dist/Components/Rating/RatingProps.d.ts +27 -0
- package/dist/Components/Rating/RatingProps.js +2 -0
- package/dist/Components/ReviewList/ReviewList.d.ts +4 -0
- package/dist/Components/ReviewList/ReviewList.js +94 -0
- package/dist/Components/ReviewList/ReviewListProps.d.ts +68 -0
- package/dist/Components/ReviewList/ReviewListProps.js +2 -0
- package/dist/Components/ReviewSummary/ReviewSummary.d.ts +4 -0
- package/dist/Components/ReviewSummary/ReviewSummary.js +47 -0
- package/dist/Components/ReviewSummary/ReviewSummaryProps.d.ts +31 -0
- package/dist/Components/ReviewSummary/ReviewSummaryProps.js +2 -0
- package/dist/Components/SegmentedControl/SegmentedControl.d.ts +1 -1
- package/dist/Components/SegmentedControl/SegmentedControl.js +17 -5
- package/dist/Components/SegmentedControl/SegmentedControlProps.d.ts +6 -0
- package/dist/Components/SegmentedControl/segmentedInk.d.ts +2 -0
- package/dist/Components/SegmentedControl/segmentedInk.js +4 -1
- package/dist/Components/SegmentedControl/useSlidingPill.d.ts +2 -0
- package/dist/Components/SegmentedControl/useSlidingPill.js +6 -1
- package/dist/Components/SideBar/SecondaryBar.js +13 -8
- package/dist/Components/SideBar/SideBarProps.d.ts +3 -1
- package/dist/Components/SideBar/components/MenuItemBox.js +47 -10
- package/dist/Components/SideBar/components/MenuPopoverContent.js +4 -3
- package/dist/Components/SpecTable/SpecTable.d.ts +4 -0
- package/dist/Components/SpecTable/SpecTable.js +39 -0
- package/dist/Components/SpecTable/SpecTableProps.d.ts +25 -0
- package/dist/Components/SpecTable/SpecTableProps.js +2 -0
- package/dist/Components/Spinner/Spinner.d.ts +1 -1
- package/dist/Components/Spinner/Spinner.js +2 -2
- package/dist/Components/Spinner/SpinnerProps.d.ts +2 -0
- package/dist/Components/StageProgress/StepperStage.js +2 -1
- package/dist/Components/StatCard/StatCard.d.ts +1 -1
- package/dist/Components/StatCard/StatCard.js +2 -2
- package/dist/Components/StatCard/StatCardProps.d.ts +4 -0
- package/dist/Components/StickyBuyBar/StickyBuyBar.d.ts +3 -0
- package/dist/Components/StickyBuyBar/StickyBuyBar.js +85 -0
- package/dist/Components/StickyBuyBar/StickyBuyBarProps.d.ts +54 -0
- package/dist/Components/StickyBuyBar/StickyBuyBarProps.js +2 -0
- package/dist/Components/StockStatus/StockStatus.d.ts +4 -0
- package/dist/Components/StockStatus/StockStatus.js +31 -0
- package/dist/Components/StockStatus/StockStatusProps.d.ts +14 -0
- package/dist/Components/StockStatus/StockStatusProps.js +2 -0
- package/dist/Components/Table/Table.js +2 -1
- package/dist/Components/Table/TableProps.d.ts +5 -2
- package/dist/Components/Table/columnLabel.d.ts +6 -0
- package/dist/Components/Table/columnLabel.js +27 -0
- package/dist/Components/Table/components/TableBody.js +5 -1
- package/dist/Components/Table/components/TableHeader.js +3 -2
- package/dist/Components/Table/filters/ActiveFilters.js +2 -1
- package/dist/Components/Table/filters/TableFilters.js +2 -1
- package/dist/Components/Table/hooks/useTable.js +3 -2
- package/dist/Components/Table/settings/ManageColumns.js +4 -3
- package/dist/Components/Table/settings/TableSettings.js +2 -1
- package/dist/Components/TrustBadges/TrustBadges.d.ts +4 -0
- package/dist/Components/TrustBadges/TrustBadges.js +24 -0
- package/dist/Components/TrustBadges/TrustBadgesProps.d.ts +20 -0
- package/dist/Components/TrustBadges/TrustBadgesProps.js +2 -0
- package/dist/Components/VariantSelector/VariantSelector.d.ts +4 -0
- package/dist/Components/VariantSelector/VariantSelector.js +123 -0
- package/dist/Components/VariantSelector/VariantSelectorProps.d.ts +27 -0
- package/dist/Components/VariantSelector/VariantSelectorProps.js +2 -0
- package/dist/Components/VariantSelector/variantSelection.d.ts +6 -0
- package/dist/Components/VariantSelector/variantSelection.js +25 -0
- package/dist/Components/WishlistToggle/WishlistToggle.d.ts +4 -0
- package/dist/Components/WishlistToggle/WishlistToggle.js +65 -0
- package/dist/Components/WishlistToggle/WishlistToggleProps.d.ts +19 -0
- package/dist/Components/WishlistToggle/WishlistToggleProps.js +2 -0
- package/dist/Theme/assertPalette.d.ts +1 -1
- package/dist/Theme/assertPalette.js +1 -1
- package/dist/Theme/tokens/brands/index.js +2 -0
- package/dist/Theme/tokens/brands/zinc/palette.dark.d.ts +1 -0
- package/dist/Theme/tokens/builders/buildDarkPalette.js +2 -0
- package/dist/Theme/tokens/builders/index.d.ts +1 -0
- package/dist/Theme/tokens/builders/index.js +1 -0
- package/dist/Theme/tokens/builders/rechartsTheme.d.ts +56 -0
- package/dist/Theme/tokens/builders/rechartsTheme.js +43 -0
- package/dist/Theme/tokens/builders/star.d.ts +3 -0
- package/dist/Theme/tokens/builders/star.js +8 -0
- package/dist/Theme/tokens/types.d.ts +3 -1
- package/dist/Theme/useChartTheme.d.ts +4 -0
- package/dist/Theme/useChartTheme.js +12 -0
- package/dist/Utils/price.d.ts +16 -0
- package/dist/Utils/price.js +34 -0
- package/dist/esm/Components/AddressCard/AddressCard.js +20 -0
- package/dist/esm/Components/AddressCard/AddressCardGroup.js +5 -0
- package/dist/esm/Components/AddressCard/AddressCardProps.js +1 -0
- package/dist/esm/Components/BagBar/BagBar.js +27 -0
- package/dist/esm/Components/BagBar/BagBarProps.js +1 -0
- package/dist/esm/Components/CartItem/CartItem.js +55 -0
- package/dist/esm/Components/CartItem/CartItemProps.js +1 -0
- package/dist/esm/Components/CartItem/cartItemOptions.js +9 -0
- package/dist/esm/Components/CheckoutKit/selectable.js +112 -0
- package/dist/esm/Components/Commerce/commerceTypes.js +1 -0
- package/dist/esm/Components/Commerce/commerceVariants.js +41 -0
- package/dist/esm/Components/Commerce/index.js +2 -0
- package/dist/esm/Components/Commerce/useContainerWidth.js +21 -0
- package/dist/esm/Components/CouponField/CouponField.js +67 -0
- package/dist/esm/Components/CouponField/CouponFieldProps.js +1 -0
- package/dist/esm/Components/DatePicker/PickerPortal.js +21 -0
- package/dist/esm/Components/DatePicker/RangeDatePicker.js +34 -32
- package/dist/esm/Components/DatePicker/SingleDatePicker.js +16 -13
- package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +6 -4
- package/dist/esm/Components/DetailSections/DetailSections.js +107 -0
- package/dist/esm/Components/DetailSections/DetailSectionsProps.js +1 -0
- package/dist/esm/Components/MediaGallery/MediaFrame.js +48 -0
- package/dist/esm/Components/MediaGallery/MediaGallery.js +201 -0
- package/dist/esm/Components/MediaGallery/MediaGalleryProps.js +17 -0
- package/dist/esm/Components/MediaGallery/MediaLightbox.js +78 -0
- package/dist/esm/Components/MediaGallery/MediaLightboxProps.js +12 -0
- package/dist/esm/Components/MediaGallery/MediaThumb.js +23 -0
- package/dist/esm/Components/MediaGallery/glass.js +42 -0
- package/dist/esm/Components/MediaGallery/mediaGalleryModel.js +71 -0
- package/dist/esm/Components/MediaGallery/motion.js +8 -0
- package/dist/esm/Components/MediaGallery/useMatchMedia.js +16 -0
- package/dist/esm/Components/OffersList/OffersList.js +81 -0
- package/dist/esm/Components/OffersList/OffersListProps.js +1 -0
- package/dist/esm/Components/OptionChip/OptionChip.js +95 -0
- package/dist/esm/Components/OptionChip/OptionChipProps.js +1 -0
- package/dist/esm/Components/OptionChip/optionInk.js +21 -0
- package/dist/esm/Components/OrderStatusTimeline/OrderStatusTimeline.js +55 -0
- package/dist/esm/Components/OrderStatusTimeline/OrderStatusTimelineProps.js +1 -0
- package/dist/esm/Components/OrderSummary/OrderSummary.js +58 -0
- package/dist/esm/Components/OrderSummary/OrderSummaryProps.js +1 -0
- package/dist/esm/Components/PaymentOption/PaymentOption.js +19 -0
- package/dist/esm/Components/PaymentOption/PaymentOptionGroup.js +5 -0
- package/dist/esm/Components/PaymentOption/PaymentOptionProps.js +1 -0
- package/dist/esm/Components/PincodeChecker/PincodeChecker.js +170 -0
- package/dist/esm/Components/PincodeChecker/PincodeCheckerProps.js +1 -0
- package/dist/esm/Components/PriceBlock/PriceBlock.js +39 -0
- package/dist/esm/Components/PriceBlock/PriceBlockProps.js +1 -0
- package/dist/esm/Components/ProductBadges/ProductBadges.js +59 -0
- package/dist/esm/Components/ProductBadges/ProductBadgesProps.js +1 -0
- package/dist/esm/Components/ProductCard/ProductCard.js +105 -54
- package/dist/esm/Components/ProductCard/ProductCardAction.js +60 -0
- package/dist/esm/Components/ProductCard/ProductCardGrid.js +18 -0
- package/dist/esm/Components/ProductCard/ProductCardMedia.js +33 -0
- package/dist/esm/Components/ProductCard/ProductCardSkeleton.js +12 -0
- package/dist/esm/Components/ProductCard/ProductCardSwatches.js +35 -0
- package/dist/esm/Components/ProductCard/QuickAddSheet.js +71 -0
- package/dist/esm/Components/ProductCard/QuickAddSheetProps.js +1 -0
- package/dist/esm/Components/ProductCard/cardLabels.js +13 -0
- package/dist/esm/Components/ProductCard/cardMetrics.js +52 -0
- package/dist/esm/Components/ProductCard/productCardFixtures.js +58 -0
- package/dist/esm/Components/ProductCard/productCardModel.js +65 -0
- package/dist/esm/Components/ProductCard/useMinWidth.js +16 -0
- package/dist/esm/Components/ProductDetails/ProductDetails.js +210 -34
- package/dist/esm/Components/ProductDetails/productDetailsModel.js +35 -0
- package/dist/esm/Components/ProductDetails/useInViewport.js +14 -0
- package/dist/esm/Components/QuantityStepper/QuantityStepper.js +57 -0
- package/dist/esm/Components/QuantityStepper/QuantityStepperProps.js +1 -0
- package/dist/esm/Components/Rating/Rating.js +79 -0
- package/dist/esm/Components/Rating/RatingProps.js +1 -0
- package/dist/esm/Components/ReviewList/ReviewList.js +89 -0
- package/dist/esm/Components/ReviewList/ReviewListProps.js +1 -0
- package/dist/esm/Components/ReviewSummary/ReviewSummary.js +42 -0
- package/dist/esm/Components/ReviewSummary/ReviewSummaryProps.js +1 -0
- package/dist/esm/Components/SegmentedControl/SegmentedControl.js +19 -7
- package/dist/esm/Components/SegmentedControl/segmentedInk.js +2 -0
- package/dist/esm/Components/SegmentedControl/useSlidingPill.js +6 -1
- package/dist/esm/Components/SideBar/SecondaryBar.js +14 -9
- package/dist/esm/Components/SideBar/components/MenuItemBox.js +14 -10
- package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +4 -3
- package/dist/esm/Components/SpecTable/SpecTable.js +34 -0
- package/dist/esm/Components/SpecTable/SpecTableProps.js +1 -0
- package/dist/esm/Components/Spinner/Spinner.js +2 -2
- package/dist/esm/Components/StageProgress/StepperStage.js +2 -1
- package/dist/esm/Components/StatCard/StatCard.js +2 -2
- package/dist/esm/Components/StickyBuyBar/StickyBuyBar.js +80 -0
- package/dist/esm/Components/StickyBuyBar/StickyBuyBarProps.js +1 -0
- package/dist/esm/Components/StockStatus/StockStatus.js +29 -0
- package/dist/esm/Components/StockStatus/StockStatusProps.js +1 -0
- package/dist/esm/Components/Table/Table.js +2 -1
- package/dist/esm/Components/Table/columnLabel.js +21 -0
- package/dist/esm/Components/Table/components/TableBody.js +5 -1
- package/dist/esm/Components/Table/components/TableHeader.js +3 -2
- package/dist/esm/Components/Table/filters/ActiveFilters.js +2 -1
- package/dist/esm/Components/Table/filters/TableFilters.js +2 -1
- package/dist/esm/Components/Table/hooks/useTable.js +3 -2
- package/dist/esm/Components/Table/settings/ManageColumns.js +4 -3
- package/dist/esm/Components/Table/settings/TableSettings.js +2 -1
- package/dist/esm/Components/TrustBadges/TrustBadges.js +22 -0
- package/dist/esm/Components/TrustBadges/TrustBadgesProps.js +1 -0
- package/dist/esm/Components/VariantSelector/VariantSelector.js +118 -0
- package/dist/esm/Components/VariantSelector/VariantSelectorProps.js +1 -0
- package/dist/esm/Components/VariantSelector/variantSelection.js +19 -0
- package/dist/esm/Components/WishlistToggle/WishlistToggle.js +63 -0
- package/dist/esm/Components/WishlistToggle/WishlistToggleProps.js +1 -0
- package/dist/esm/Theme/assertPalette.js +1 -1
- package/dist/esm/Theme/tokens/brands/index.js +2 -0
- package/dist/esm/Theme/tokens/builders/buildDarkPalette.js +2 -0
- package/dist/esm/Theme/tokens/builders/index.js +1 -0
- package/dist/esm/Theme/tokens/builders/rechartsTheme.js +37 -0
- package/dist/esm/Theme/tokens/builders/star.js +4 -0
- package/dist/esm/Theme/useChartTheme.js +8 -0
- package/dist/esm/Utils/price.js +27 -0
- package/dist/esm/index.js +36 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +86 -4
- package/package.json +1 -1
- package/dist/Components/ProductCard/ProductLabel.d.ts +0 -7
- package/dist/Components/ProductCard/ProductLabel.js +0 -20
- package/dist/Components/ProductCard/ProductPrice.d.ts +0 -10
- package/dist/Components/ProductCard/ProductPrice.js +0 -126
- package/dist/Components/ProductCard/ProductReview.d.ts +0 -8
- package/dist/Components/ProductCard/ProductReview.js +0 -30
- package/dist/Components/ProductCard/ProductTags.d.ts +0 -8
- package/dist/Components/ProductCard/ProductTags.js +0 -53
- package/dist/Components/ProductDetails/ProductDtlPrice.d.ts +0 -7
- package/dist/Components/ProductDetails/ProductDtlPrice.js +0 -24
- package/dist/Components/ProductDetails/ProductImageSlider.d.ts +0 -13
- package/dist/Components/ProductDetails/ProductImageSlider.js +0 -240
- package/dist/esm/Components/ProductCard/ProductLabel.js +0 -18
- package/dist/esm/Components/ProductCard/ProductPrice.js +0 -121
- package/dist/esm/Components/ProductCard/ProductReview.js +0 -28
- package/dist/esm/Components/ProductCard/ProductTags.js +0 -48
- package/dist/esm/Components/ProductDetails/ProductDtlPrice.js +0 -22
- package/dist/esm/Components/ProductDetails/ProductImageSlider.js +0 -204
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Button sizes: sm 32 px, md 40 px with a 44 px hit area, lg 48 px. */
|
|
2
|
+
export type WishlistToggleSize = "sm" | "md" | "lg";
|
|
3
|
+
/** glass: translucent dark disc for use on photos; soft: tonal disc on the page; ghost: icon only. */
|
|
4
|
+
export type WishlistToggleVariant = "glass" | "soft" | "ghost";
|
|
5
|
+
/** Heart toggle button with `aria-pressed`, a spring pop on save and a 44 px touch target from md up. */
|
|
6
|
+
export interface WishlistToggleProps {
|
|
7
|
+
/** Controlled state; pair with `onSelectedChange`. */
|
|
8
|
+
selected?: boolean;
|
|
9
|
+
/** Initial state when `selected` is not controlled. */
|
|
10
|
+
defaultSelected?: boolean;
|
|
11
|
+
/** Fires with the next state on click or keyboard activation. */
|
|
12
|
+
onSelectedChange?: (selected: boolean) => void;
|
|
13
|
+
size?: WishlistToggleSize;
|
|
14
|
+
variant?: WishlistToggleVariant;
|
|
15
|
+
/** Fixed accessible name, e.g. "Save Denim Jacket"; defaults to "Add to wishlist" / "Remove from wishlist". */
|
|
16
|
+
label?: string;
|
|
17
|
+
isDisabled?: boolean;
|
|
18
|
+
"data-testid"?: string;
|
|
19
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PaletteProps } from "./tokens/types";
|
|
2
|
-
declare const REQUIRED_GROUPS: readonly ["gradient", "primary", "secondary", "tertiary", "transparent", "black", "white", "semantic", "gray", "red", "orange", "yellow", "green", "teal", "blue", "cyan", "purple", "pink", "backgroundColor", "background", "text", "header", "placeholder", "boxShadow", "focusRing", "sidebar", "boxborder", "border", "table", "disabled", "accentText", "textMuted", "semanticText", "onPrimary", "onSemantic", "surfaceRaised"];
|
|
2
|
+
declare const REQUIRED_GROUPS: readonly ["gradient", "primary", "secondary", "tertiary", "transparent", "black", "white", "semantic", "gray", "red", "orange", "yellow", "green", "teal", "blue", "cyan", "purple", "pink", "backgroundColor", "background", "text", "header", "placeholder", "boxShadow", "focusRing", "sidebar", "boxborder", "border", "table", "disabled", "accentText", "textMuted", "semanticText", "onPrimary", "onSemantic", "surfaceRaised", "star"];
|
|
3
3
|
type Unlisted = Exclude<keyof PaletteProps, (typeof REQUIRED_GROUPS)[number]>;
|
|
4
4
|
export type AllPaletteTokensListed = Unlisted extends never ? true : ["unlisted token", Unlisted];
|
|
5
5
|
export declare const allPaletteTokensListed: AllPaletteTokensListed;
|
|
@@ -6,7 +6,7 @@ const REQUIRED_GROUPS = [
|
|
|
6
6
|
"semantic", "gray", "red", "orange", "yellow", "green", "teal", "blue", "cyan",
|
|
7
7
|
"purple", "pink", "backgroundColor", "background", "text", "header", "placeholder",
|
|
8
8
|
"boxShadow", "focusRing", "sidebar", "boxborder", "border", "table", "disabled",
|
|
9
|
-
"accentText", "textMuted", "semanticText", "onPrimary", "onSemantic", "surfaceRaised",
|
|
9
|
+
"accentText", "textMuted", "semanticText", "onPrimary", "onSemantic", "surfaceRaised", "star",
|
|
10
10
|
];
|
|
11
11
|
exports.allPaletteTokensListed = true;
|
|
12
12
|
const NESTED = [
|
|
@@ -49,6 +49,7 @@ const resolvedRungs_1 = require("../builders/resolvedRungs");
|
|
|
49
49
|
const focusRing_1 = require("../builders/focusRing");
|
|
50
50
|
const surfaceRungs_1 = require("../builders/surfaceRungs");
|
|
51
51
|
const surfaceRaised_1 = require("../builders/surfaceRaised");
|
|
52
|
+
const star_1 = require("../builders/star");
|
|
52
53
|
/** Derived, never hand-written: a copied hex goes stale the moment a canvas moves. */
|
|
53
54
|
const finalizeLightPalette = (source) => ({
|
|
54
55
|
...source,
|
|
@@ -60,6 +61,7 @@ const finalizeLightPalette = (source) => ({
|
|
|
60
61
|
onSemantic: (0, semanticText_1.buildOnSemantic)(source.semantic, source.white, source.black),
|
|
61
62
|
focusRing: (0, focusRing_1.buildFocusRing)(source),
|
|
62
63
|
surfaceRaised: (0, surfaceRaised_1.buildSurfaceRaised)(source),
|
|
64
|
+
star: (0, star_1.buildStar)(source.backgroundColor.main),
|
|
63
65
|
});
|
|
64
66
|
exports.finalizeLightPalette = finalizeLightPalette;
|
|
65
67
|
// NOTE: withFocusRing is outermost — it must see primary and surfaces together, after every earlier step.
|
|
@@ -10,6 +10,7 @@ const mutedText_1 = require("./mutedText");
|
|
|
10
10
|
const semanticText_1 = require("./semanticText");
|
|
11
11
|
const focusRing_1 = require("./focusRing");
|
|
12
12
|
const surfaceRaised_1 = require("./surfaceRaised");
|
|
13
|
+
const star_1 = require("./star");
|
|
13
14
|
// Structural ramps are rebuilt at explicit targets (not reversed — light ramps bottom near 35%);
|
|
14
15
|
// utility hues are reversed so index roles survive; brand/semantic ramps shift one step lighter.
|
|
15
16
|
const SCALE_KEYS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];
|
|
@@ -211,6 +212,7 @@ function buildDarkPalette(light) {
|
|
|
211
212
|
onSemantic: (0, semanticText_1.buildOnSemantic)(semantic, light.white, light.black),
|
|
212
213
|
focusRing: (0, focusRing_1.buildFocusRing)({ primary, background, backgroundColor: namedSurfaces }),
|
|
213
214
|
surfaceRaised: (0, surfaceRaised_1.buildSurfaceRaised)({ backgroundColor: namedSurfaces, background, white }),
|
|
215
|
+
star: (0, star_1.buildStar)(namedSurfaces.main),
|
|
214
216
|
sidebar: (0, sidebarAccent_1.withSidebarTokens)(light),
|
|
215
217
|
boxShadow: {
|
|
216
218
|
primary: (0, buildBrandTokens_1.buildPrimaryShadowTint)(primary[500]),
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { PaletteProps } from "../types";
|
|
2
|
+
export interface RechartsGridTheme {
|
|
3
|
+
stroke: string;
|
|
4
|
+
strokeDasharray: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RechartsAxisTheme {
|
|
7
|
+
stroke: string;
|
|
8
|
+
tick: {
|
|
9
|
+
fill: string;
|
|
10
|
+
fontSize: string;
|
|
11
|
+
fontFamily: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface RechartsTooltipTheme {
|
|
15
|
+
contentStyle: {
|
|
16
|
+
backgroundColor: string;
|
|
17
|
+
border: string;
|
|
18
|
+
borderRadius: string;
|
|
19
|
+
color: string;
|
|
20
|
+
fontSize: string;
|
|
21
|
+
fontFamily: string;
|
|
22
|
+
};
|
|
23
|
+
labelStyle: {
|
|
24
|
+
color: string;
|
|
25
|
+
fontWeight: number;
|
|
26
|
+
};
|
|
27
|
+
itemStyle: {
|
|
28
|
+
color: string;
|
|
29
|
+
};
|
|
30
|
+
cursor: {
|
|
31
|
+
stroke: string;
|
|
32
|
+
strokeDasharray: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export interface RechartsLegendTheme {
|
|
36
|
+
wrapperStyle: {
|
|
37
|
+
color: string;
|
|
38
|
+
fontSize: string;
|
|
39
|
+
fontFamily: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface RechartsChartTheme {
|
|
43
|
+
seriesColors: string[];
|
|
44
|
+
grid: RechartsGridTheme;
|
|
45
|
+
axis: RechartsAxisTheme;
|
|
46
|
+
tooltip: RechartsTooltipTheme;
|
|
47
|
+
legend: RechartsLegendTheme;
|
|
48
|
+
referenceLine: {
|
|
49
|
+
stroke: string;
|
|
50
|
+
strokeDasharray: string;
|
|
51
|
+
};
|
|
52
|
+
surface: string;
|
|
53
|
+
text: string;
|
|
54
|
+
muted: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function buildRechartsTheme(colors: PaletteProps): RechartsChartTheme;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildRechartsTheme = buildRechartsTheme;
|
|
7
|
+
const radii_1 = __importDefault(require("../primitives/radii"));
|
|
8
|
+
const chartColorsFromTheme_1 = require("./chartColorsFromTheme");
|
|
9
|
+
const FONT = "inherit";
|
|
10
|
+
const FONT_SIZE = "12px";
|
|
11
|
+
const DASH = "4 4";
|
|
12
|
+
// Reuses chartInk/getCategoricalSeriesColors — no parallel color derivation. No recharts import.
|
|
13
|
+
function buildRechartsTheme(colors) {
|
|
14
|
+
const ink = (0, chartColorsFromTheme_1.chartInk)(colors);
|
|
15
|
+
return {
|
|
16
|
+
seriesColors: (0, chartColorsFromTheme_1.getCategoricalSeriesColors)(colors),
|
|
17
|
+
grid: { stroke: ink.grid, strokeDasharray: DASH },
|
|
18
|
+
axis: {
|
|
19
|
+
stroke: ink.grid,
|
|
20
|
+
tick: { fill: ink.axis, fontSize: FONT_SIZE, fontFamily: FONT },
|
|
21
|
+
},
|
|
22
|
+
tooltip: {
|
|
23
|
+
contentStyle: {
|
|
24
|
+
backgroundColor: ink.tooltipBg,
|
|
25
|
+
border: `1px solid ${ink.grid}`,
|
|
26
|
+
borderRadius: radii_1.default.md,
|
|
27
|
+
color: ink.text,
|
|
28
|
+
fontSize: FONT_SIZE,
|
|
29
|
+
fontFamily: FONT,
|
|
30
|
+
},
|
|
31
|
+
labelStyle: { color: ink.text, fontWeight: 600 },
|
|
32
|
+
itemStyle: { color: ink.text },
|
|
33
|
+
cursor: { stroke: ink.grid, strokeDasharray: DASH },
|
|
34
|
+
},
|
|
35
|
+
legend: {
|
|
36
|
+
wrapperStyle: { color: ink.muted, fontSize: FONT_SIZE, fontFamily: FONT },
|
|
37
|
+
},
|
|
38
|
+
referenceLine: { stroke: ink.muted, strokeDasharray: DASH },
|
|
39
|
+
surface: ink.surface,
|
|
40
|
+
text: ink.text,
|
|
41
|
+
muted: ink.muted,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildStar = exports.STAR_ON_DARK = exports.STAR_ON_LIGHT = void 0;
|
|
4
|
+
const color_1 = require("./color");
|
|
5
|
+
exports.STAR_ON_LIGHT = "#f5a70a";
|
|
6
|
+
exports.STAR_ON_DARK = "#f6b93b";
|
|
7
|
+
const buildStar = (canvas) => (0, color_1.relativeLuminance)(canvas) > 0.18 ? exports.STAR_ON_LIGHT : exports.STAR_ON_DARK;
|
|
8
|
+
exports.buildStar = buildStar;
|
|
@@ -122,10 +122,12 @@ export type PaletteProps = {
|
|
|
122
122
|
onSemantic: SemanticTextTokens;
|
|
123
123
|
/** Dialog/drawer/popover/menu surface: `background[50]` in light, one elevation step up in dark. */
|
|
124
124
|
surfaceRaised: string;
|
|
125
|
+
/** Rating-star gold, the same hue in every brand. Decorative: always pair it with a numeric rating. */
|
|
126
|
+
star: string;
|
|
125
127
|
};
|
|
126
128
|
/** What a brand writes by hand; every token required, so a gap is a compile error. */
|
|
127
129
|
/** Derived tokens are excluded — `finalizeLightPalette` resolves them per brand. */
|
|
128
|
-
export type BrandPaletteSource = Omit<PaletteProps, "accentText" | "textMuted" | "semanticText" | "sidebar" | "onPrimary" | "onSemantic" | "focusRing" | "surfaceRaised"> & {
|
|
130
|
+
export type BrandPaletteSource = Omit<PaletteProps, "accentText" | "textMuted" | "semanticText" | "sidebar" | "onPrimary" | "onSemantic" | "focusRing" | "surfaceRaised" | "star"> & {
|
|
129
131
|
sidebar: {
|
|
130
132
|
background: ColorScale;
|
|
131
133
|
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RechartsAxisTheme, RechartsChartTheme, RechartsGridTheme, RechartsLegendTheme, RechartsTooltipTheme } from "./tokens/builders/rechartsTheme";
|
|
2
|
+
export type { RechartsAxisTheme, RechartsChartTheme, RechartsGridTheme, RechartsLegendTheme, RechartsTooltipTheme, };
|
|
3
|
+
export declare const useChartTheme: () => RechartsChartTheme;
|
|
4
|
+
export default useChartTheme;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useChartTheme = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const useCustomTheme_1 = require("./useCustomTheme");
|
|
6
|
+
const rechartsTheme_1 = require("./tokens/builders/rechartsTheme");
|
|
7
|
+
const useChartTheme = () => {
|
|
8
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
9
|
+
return (0, react_1.useMemo)(() => (0, rechartsTheme_1.buildRechartsTheme)(colors), [colors]);
|
|
10
|
+
};
|
|
11
|
+
exports.useChartTheme = useChartTheme;
|
|
12
|
+
exports.default = exports.useChartTheme;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type PriceFormatOptions = {
|
|
2
|
+
currency?: string;
|
|
3
|
+
locale?: string;
|
|
4
|
+
maximumFractionDigits?: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const DEFAULT_CURRENCY = "INR";
|
|
7
|
+
export declare const DEFAULT_LOCALE = "en-IN";
|
|
8
|
+
export declare function formatPrice(value: number, options?: PriceFormatOptions): string;
|
|
9
|
+
export declare function discountPercent(price: number, mrp?: number): number;
|
|
10
|
+
export declare function discountAmount(price: number, mrp?: number): number;
|
|
11
|
+
export type UnitPrice = {
|
|
12
|
+
value: number;
|
|
13
|
+
per: number;
|
|
14
|
+
unit: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function unitPrice(price: number, quantity: number, unit: string, per?: number): UnitPrice | null;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_LOCALE = exports.DEFAULT_CURRENCY = void 0;
|
|
4
|
+
exports.formatPrice = formatPrice;
|
|
5
|
+
exports.discountPercent = discountPercent;
|
|
6
|
+
exports.discountAmount = discountAmount;
|
|
7
|
+
exports.unitPrice = unitPrice;
|
|
8
|
+
exports.DEFAULT_CURRENCY = "INR";
|
|
9
|
+
exports.DEFAULT_LOCALE = "en-IN";
|
|
10
|
+
function formatPrice(value, options = {}) {
|
|
11
|
+
const { currency = exports.DEFAULT_CURRENCY, locale = exports.DEFAULT_LOCALE, maximumFractionDigits } = options;
|
|
12
|
+
const whole = Number.isInteger(value);
|
|
13
|
+
return new Intl.NumberFormat(locale, {
|
|
14
|
+
style: "currency",
|
|
15
|
+
currency,
|
|
16
|
+
minimumFractionDigits: whole ? 0 : 2,
|
|
17
|
+
maximumFractionDigits: maximumFractionDigits !== null && maximumFractionDigits !== void 0 ? maximumFractionDigits : (whole ? 0 : 2),
|
|
18
|
+
}).format(value);
|
|
19
|
+
}
|
|
20
|
+
function discountPercent(price, mrp) {
|
|
21
|
+
if (mrp === undefined || mrp <= price || mrp <= 0)
|
|
22
|
+
return 0;
|
|
23
|
+
return Math.round(((mrp - price) / mrp) * 100);
|
|
24
|
+
}
|
|
25
|
+
function discountAmount(price, mrp) {
|
|
26
|
+
if (mrp === undefined || mrp <= price)
|
|
27
|
+
return 0;
|
|
28
|
+
return mrp - price;
|
|
29
|
+
}
|
|
30
|
+
function unitPrice(price, quantity, unit, per = 1) {
|
|
31
|
+
if (!(quantity > 0))
|
|
32
|
+
return null;
|
|
33
|
+
return { value: Math.round((price / quantity) * per * 100) / 100, per, unit };
|
|
34
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
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 Button from "../Button/Button.js";
|
|
7
|
+
import Tag from "../Tag/Tag.js";
|
|
8
|
+
const DEFAULT_LABELS = { default: "Default", edit: "Edit", remove: "Remove" };
|
|
9
|
+
/** Tonal delivery-address card: name, tags, lines and calm Edit/Remove actions; selection is a ring plus a check. */
|
|
10
|
+
const AddressCard = ({ value, name, phone, lines, tag, isDefault = false, note, selected, onSelect, onEdit, onRemove, disabled = false, labels, "data-testid": testId, }) => {
|
|
11
|
+
const { colors } = useCustomTheme();
|
|
12
|
+
const uid = useId();
|
|
13
|
+
const nameId = `${uid}-name`;
|
|
14
|
+
const bodyId = `${uid}-body`;
|
|
15
|
+
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
16
|
+
const { isSelected, interactive, inGroup, ringed, props } = useSelectable({ value, selected, disabled, onSelect });
|
|
17
|
+
const selectable = inGroup || !!onSelect;
|
|
18
|
+
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 ? nameId : undefined, "aria-describedby": props.role ? bodyId : undefined, gap: 3, p: 4, pb: onEdit || onRemove ? 2 : 4, borderRadius: "1rem", cursor: interactive ? "pointer" : "default", outline: "none", align: "flex-start", children: [selectable && (_jsx(Box, { mt: 0.5, children: _jsx(RadioIndicator, { selected: isSelected }) })), _jsxs(Flex, { direction: "column", gap: 1, flex: 1, minW: 0, children: [_jsxs(Flex, { align: "center", gap: 2, wrap: "wrap", children: [_jsx(Text, { as: "span", id: nameId, fontSize: "sm", fontWeight: 700, lineHeight: 1.4, color: colors.header[900], children: name }), tag && _jsx(Tag, { label: tag, size: "xs", tone: "neutral" }), isDefault && _jsx(Tag, { label: copy.default, size: "xs", tone: "neutral" })] }), _jsxs(Box, { id: bodyId, children: [lines.map((line) => (_jsx(Text, { as: "span", display: "block", fontSize: "sm", lineHeight: 1.5, color: colors.text[800], children: line }, line))), phone && (_jsx(Text, { as: "span", display: "block", mt: 1, fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, sx: { fontVariantNumeric: "tabular-nums" }, children: phone })), note && (_jsx(Text, { as: "span", display: "block", mt: 1, fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: note }))] })] })] }), (onEdit || onRemove) && (_jsxs(Flex, { gap: 1, pl: selectable ? "2.75rem" : 1, pr: 2, pb: 2, children: [onEdit && (_jsx(Button, { variant: "ghost", colorScheme: "gray", size: "sm", onClick: onEdit, "aria-label": `${copy.edit} address: ${name}`, children: copy.edit })), onRemove && (_jsx(Button, { variant: "ghost", colorScheme: "gray", size: "sm", onClick: onRemove, "aria-label": `${copy.remove} address: ${name}`, children: copy.remove }))] }))] }));
|
|
19
|
+
};
|
|
20
|
+
export default AddressCard;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { SelectableGroup } from "../CheckoutKit/selectable.js";
|
|
3
|
+
/** Radiogroup wrapper for `AddressCard`s. */
|
|
4
|
+
const AddressCardGroup = (props) => _jsx(SelectableGroup, { ...props });
|
|
5
|
+
export default AddressCardGroup;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Flex, Text } from "@chakra-ui/react";
|
|
3
|
+
import { ChevronUp } from "lucide-react";
|
|
4
|
+
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
5
|
+
import { overlayScrim } from "../../Theme/tokens/builders/scrim.js";
|
|
6
|
+
import { focusVisibleStyles } from "../../Theme/chakra/focusRing.styles.js";
|
|
7
|
+
import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
|
|
8
|
+
import { reducedMotionSx } from "../../Theme/chakra/motion.js";
|
|
9
|
+
import { formatPrice } from "../../Utils/price.js";
|
|
10
|
+
import Button from "../Button/Button.js";
|
|
11
|
+
const DEFAULT_LABELS = { region: "Bag total", total: "Total", viewDetails: "View price details", cta: "Place order" };
|
|
12
|
+
const GLASS_ALPHA = Math.round(0.86 * 255).toString(16);
|
|
13
|
+
const BLUR = "blur(20px) saturate(180%)";
|
|
14
|
+
const NO_BLUR_SUPPORT = "@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)))";
|
|
15
|
+
const SAFE_BOTTOM = "calc(0.75rem + env(safe-area-inset-bottom, 0px))";
|
|
16
|
+
/** Glass bar for the bag and checkout: total and price-details link left, the single primary action right. */
|
|
17
|
+
const BagBar = ({ total, note, onViewDetails, ctaLabel, onCta, ctaDisabled = false, ctaLoading = false, position = "static", zIndex = 10, currency, locale, labels, "data-testid": testId, }) => {
|
|
18
|
+
const { colors } = useCustomTheme();
|
|
19
|
+
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
20
|
+
const sticky = position === "bottom";
|
|
21
|
+
return (_jsxs(Flex, { as: "section", "aria-label": copy.region, align: "center", justify: "space-between", gap: 4, px: 4, pt: 3, pb: SAFE_BOTTOM, borderTopRadius: "1.5rem", bg: `${colors.surfaceRaised}${GLASS_ALPHA}`, backdropFilter: BLUR, position: sticky ? "sticky" : "static", bottom: sticky ? 0 : undefined, zIndex: sticky ? zIndex : undefined, boxShadow: sticky ? `0 -12px 32px -16px ${overlayScrim(colors)}` : "none", "data-testid": testId, sx: { WebkitBackdropFilter: BLUR, [NO_BLUR_SUPPORT]: { backgroundColor: colors.surfaceRaised } }, children: [_jsxs(Box, { minW: 0, children: [_jsxs(Flex, { align: "baseline", gap: 2, wrap: "wrap", children: [_jsx(Text, { as: "span", fontSize: "xs", fontWeight: 600, color: colors.textMuted, children: copy.total }), _jsx(Text, { as: "span", fontSize: "1.25rem", fontWeight: 700, lineHeight: 1.2, letterSpacing: "-0.02em", color: colors.header[900], sx: { fontVariantNumeric: "tabular-nums" }, "data-testid": "bag-bar-total", children: formatPrice(total, { currency, locale }) })] }), note && (_jsx(Text, { as: "span", display: "block", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: note })), onViewDetails && (_jsxs(Box, { as: "button", type: "button", onClick: onViewDetails, display: "inline-flex", alignItems: "center", gap: 1, position: "relative", fontSize: "xs", fontWeight: 600, color: colors.accentText, borderRadius: "sm", transition: transitionFor(["opacity"]), _hover: { opacity: 0.8 }, sx: {
|
|
22
|
+
...focusVisibleStyles(colors),
|
|
23
|
+
...reducedMotionSx(),
|
|
24
|
+
"&::before": { content: '""', position: "absolute", inset: "-0.75rem -0.5rem" },
|
|
25
|
+
}, children: [copy.viewDetails, _jsx(ChevronUp, { size: 14, "aria-hidden": true })] }))] }), _jsx(Button, { size: "lg", onClick: onCta, isDisabled: ctaDisabled, isLoading: ctaLoading, flexShrink: 0, children: ctaLabel !== null && ctaLabel !== void 0 ? ctaLabel : copy.cta })] }));
|
|
26
|
+
};
|
|
27
|
+
export default BagBar;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Flex, Text } from "@chakra-ui/react";
|
|
3
|
+
import { Truck } from "lucide-react";
|
|
4
|
+
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
5
|
+
import { focusVisibleStyles } from "../../Theme/chakra/focusRing.styles.js";
|
|
6
|
+
import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
|
|
7
|
+
import { reducedMotionSx } from "../../Theme/chakra/motion.js";
|
|
8
|
+
import { formatPrice } from "../../Utils/price.js";
|
|
9
|
+
import Button from "../Button/Button.js";
|
|
10
|
+
import PriceBlock from "../PriceBlock/PriceBlock.js";
|
|
11
|
+
import QuantityStepper from "../QuantityStepper/QuantityStepper.js";
|
|
12
|
+
import Skeletons from "../Skeletons/Skeletons.js";
|
|
13
|
+
import StockStatus from "../StockStatus/StockStatus.js";
|
|
14
|
+
import { summariseOptions } from "./cartItemOptions.js";
|
|
15
|
+
const DEFAULT_LABELS = {
|
|
16
|
+
moveToWishlist: "Move to wishlist",
|
|
17
|
+
remove: "Remove",
|
|
18
|
+
outOfStock: "Out of stock",
|
|
19
|
+
notIncluded: "Not included in your total",
|
|
20
|
+
quantity: (quantity) => `Qty ${quantity}`,
|
|
21
|
+
each: (price) => `${price} each`,
|
|
22
|
+
delivery: (date) => `Delivery by ${date}`,
|
|
23
|
+
};
|
|
24
|
+
const THUMB = {
|
|
25
|
+
row: { w: "5rem", h: "6.25rem", radius: "0.75rem" },
|
|
26
|
+
compact: { w: "3.5rem", h: "4.375rem", radius: "0.625rem" },
|
|
27
|
+
};
|
|
28
|
+
const DIMMED_MEDIA = 0.45;
|
|
29
|
+
const CartItemSkeleton = ({ layout }) => {
|
|
30
|
+
const thumb = THUMB[layout];
|
|
31
|
+
return (_jsxs(Flex, { gap: 3, align: "flex-start", "aria-busy": "true", "data-testid": "cart-item-skeleton", children: [_jsx(Skeletons, { type: "skeleton", height: thumb.h, width: thumb.w, borderRadius: thumb.radius }), _jsxs(Flex, { direction: "column", gap: 2, flex: 1, minW: 0, children: [_jsx(Skeletons, { type: "skeleton", height: 3, width: "35%" }), _jsx(Skeletons, { type: "skeleton", height: 4, width: "80%" }), _jsx(Skeletons, { type: "skeleton", height: 3, width: "45%" }), layout === "row" && _jsx(Skeletons, { type: "skeleton", height: 10, width: "100%", borderRadius: "full" })] })] }));
|
|
32
|
+
};
|
|
33
|
+
/** One bag line: tonal thumbnail, linked title, chosen options, line total with struck MRP, stepper and calm text actions. */
|
|
34
|
+
const CartItem = ({ title, brand, href, onTitleClick, image, imageAlt = "", axes, selection, optionsSummary, price, mrp, quantity, onQuantityChange, minQuantity = 1, maxQuantity, onRemove, onMoveToWishlist, stock, stockCount, stockMessage, deliveryBy, unavailable = false, layout = "row", isLoading = false, currency, locale, labels, "data-testid": testId, }) => {
|
|
35
|
+
const { colors } = useCustomTheme();
|
|
36
|
+
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
37
|
+
const compact = layout === "compact";
|
|
38
|
+
const thumb = THUMB[layout];
|
|
39
|
+
const fmt = { currency, locale };
|
|
40
|
+
if (isLoading)
|
|
41
|
+
return _jsx(CartItemSkeleton, { layout: layout });
|
|
42
|
+
const summary = optionsSummary !== null && optionsSummary !== void 0 ? optionsSummary : summariseOptions(axes, selection);
|
|
43
|
+
const lineTotal = price * quantity;
|
|
44
|
+
const lineMrp = mrp !== undefined ? mrp * quantity : undefined;
|
|
45
|
+
const titleInk = unavailable ? colors.textMuted : colors.header[900];
|
|
46
|
+
const titleProps = href
|
|
47
|
+
? { as: "a", href }
|
|
48
|
+
: onTitleClick
|
|
49
|
+
? { as: "button", type: "button", onClick: onTitleClick }
|
|
50
|
+
: { as: "span" };
|
|
51
|
+
const linked = !!href || !!onTitleClick;
|
|
52
|
+
const stepper = (_jsx(QuantityStepper, { size: "sm", variant: "soft", value: quantity, min: minQuantity, max: maxQuantity, removable: !!onRemove, onRemove: onRemove, onValueChange: onQuantityChange, itemLabel: title }));
|
|
53
|
+
return (_jsxs(Flex, { gap: 3, align: "flex-start", "data-testid": testId, "data-unavailable": unavailable || undefined, children: [_jsx(Box, { flexShrink: 0, w: thumb.w, h: thumb.h, borderRadius: thumb.radius, overflow: "hidden", bg: colors.background[100], opacity: unavailable ? DIMMED_MEDIA : 1, children: image && _jsx(Box, { as: "img", src: image, alt: imageAlt, w: "100%", h: "100%", objectFit: "cover", display: "block" }) }), _jsxs(Flex, { direction: "column", flex: 1, minW: 0, gap: 1.5, children: [_jsxs(Flex, { direction: "column", gap: 0.5, minW: 0, children: [brand && (_jsx(Text, { as: "span", fontSize: "xs", fontWeight: 600, lineHeight: 1.4, color: colors.textMuted, noOfLines: 1, children: brand })), _jsx(Text, { ...titleProps, display: "block", textAlign: "left", fontSize: "sm", fontWeight: 600, lineHeight: 1.4, color: titleInk, noOfLines: 2, borderRadius: "sm", cursor: linked ? "pointer" : undefined, transition: transitionFor(["color"]), _hover: linked ? { textDecoration: "underline" } : undefined, sx: { ...focusVisibleStyles(colors), ...reducedMotionSx() }, children: title }), summary && (_jsx(Text, { as: "span", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: summary }))] }), unavailable ? (_jsxs(Flex, { direction: "column", gap: 0.5, children: [_jsx(StockStatus, { status: "out-of-stock", message: copy.outOfStock, size: "sm" }), _jsx(Text, { as: "span", fontSize: "xs", color: colors.textMuted, children: copy.notIncluded })] })) : (_jsxs(Flex, { align: "flex-end", justify: "space-between", gap: 3, wrap: "wrap", children: [compact ? (_jsx(Text, { as: "span", fontSize: "xs", color: colors.textMuted, sx: { fontVariantNumeric: "tabular-nums" }, children: copy.quantity(quantity) })) : (stepper), _jsx(Box, { ml: "auto", children: _jsx(PriceBlock, { size: compact ? "sm" : "md", align: "end", price: lineTotal, mrp: lineMrp, taxNote: quantity > 1 ? copy.each(formatPrice(price, fmt)) : undefined, ...fmt }) })] })), !unavailable && !compact && stock && stock !== "in-stock" && (_jsx(StockStatus, { status: stock, count: stockCount, message: stockMessage, size: "sm" })), !unavailable && deliveryBy && (_jsxs(Flex, { align: "center", gap: 1.5, color: colors.textMuted, children: [_jsx(Truck, { size: 13, "aria-hidden": true }), _jsx(Text, { as: "span", fontSize: "xs", lineHeight: 1.4, children: copy.delivery(deliveryBy) })] })), !compact && (onRemove || (onMoveToWishlist && !unavailable)) && (_jsxs(Flex, { gap: 1, ml: -3, mt: 0.5, children: [onMoveToWishlist && !unavailable && (_jsx(Button, { variant: "ghost", colorScheme: "gray", size: "sm", onClick: onMoveToWishlist, "aria-label": `${copy.moveToWishlist}: ${title}`, children: copy.moveToWishlist })), onRemove && (_jsx(Button, { variant: "ghost", colorScheme: "gray", size: "sm", onClick: onRemove, "aria-label": `${copy.remove}: ${title}`, children: copy.remove }))] }))] })] }));
|
|
54
|
+
};
|
|
55
|
+
export default CartItem;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** "Indigo Wash · M" from the chosen option labels, in axis order; axes with no pick are skipped. */
|
|
2
|
+
export const summariseOptions = (axes, selection) => {
|
|
3
|
+
if (!axes || !selection)
|
|
4
|
+
return "";
|
|
5
|
+
return axes
|
|
6
|
+
.map((axis) => { var _a; return (_a = axis.values.find((value) => value.id === selection[axis.id])) === null || _a === void 0 ? void 0 : _a.label; })
|
|
7
|
+
.filter((label) => !!label)
|
|
8
|
+
.join(" · ");
|
|
9
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Children, createContext, isValidElement, useContext, useMemo, useState } from "react";
|
|
3
|
+
import { Box, Flex } 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 { focusVisibleRing } from "../../Theme/chakra/focusRing.styles.js";
|
|
9
|
+
import { onFilled } from "../../Theme/tokens/builders/accentText.js";
|
|
10
|
+
const GroupContext = createContext(null);
|
|
11
|
+
export const useSelectableGroup = () => useContext(GroupContext);
|
|
12
|
+
const firstEnabledValue = (children) => {
|
|
13
|
+
for (const child of Children.toArray(children)) {
|
|
14
|
+
if (!isValidElement(child))
|
|
15
|
+
continue;
|
|
16
|
+
const { value, disabled } = child.props;
|
|
17
|
+
if (typeof value === "string" && !disabled)
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
};
|
|
22
|
+
const STEP = { ArrowDown: 1, ArrowRight: 1, ArrowUp: -1, ArrowLeft: -1 };
|
|
23
|
+
/** Radiogroup with a roving tab stop; arrows move focus and selection together, like native radios. */
|
|
24
|
+
export const SelectableGroup = ({ value, defaultValue, onValueChange, gap = 3, children, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "data-testid": testId, }) => {
|
|
25
|
+
const [inner, setInner] = useState(defaultValue);
|
|
26
|
+
const current = value !== null && value !== void 0 ? value : inner;
|
|
27
|
+
const state = useMemo(() => ({
|
|
28
|
+
value: current,
|
|
29
|
+
tabStop: current !== null && current !== void 0 ? current : firstEnabledValue(children),
|
|
30
|
+
select: (next) => {
|
|
31
|
+
if (value === undefined)
|
|
32
|
+
setInner(next);
|
|
33
|
+
if (next !== current)
|
|
34
|
+
onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(next);
|
|
35
|
+
},
|
|
36
|
+
}), [current, children, value, onValueChange]);
|
|
37
|
+
const onKeyDown = (event) => {
|
|
38
|
+
const edge = event.key === "Home" ? 0 : event.key === "End" ? -1 : null;
|
|
39
|
+
const step = STEP[event.key];
|
|
40
|
+
if (edge === null && step === undefined)
|
|
41
|
+
return;
|
|
42
|
+
const radios = Array.from(event.currentTarget.querySelectorAll('[role="radio"]:not([aria-disabled="true"])'));
|
|
43
|
+
const at = radios.indexOf(document.activeElement);
|
|
44
|
+
if (at < 0)
|
|
45
|
+
return;
|
|
46
|
+
event.preventDefault();
|
|
47
|
+
const index = edge === null ? (at + step + radios.length) % radios.length : edge < 0 ? radios.length - 1 : 0;
|
|
48
|
+
const target = radios[index];
|
|
49
|
+
target.focus();
|
|
50
|
+
const next = target.getAttribute("data-value");
|
|
51
|
+
if (next !== null)
|
|
52
|
+
state.select(next);
|
|
53
|
+
};
|
|
54
|
+
return (_jsx(GroupContext.Provider, { value: state, children: _jsx(Flex, { role: "radiogroup", "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, direction: "column", gap: gap, onKeyDown: onKeyDown, "data-testid": testId, children: children }) }));
|
|
55
|
+
};
|
|
56
|
+
/** Tonal card surface; selection is a 2px ink ring plus a check, never colour alone. */
|
|
57
|
+
export const selectableSurface = (colors, { selected, disabled, interactive, ringed }) => ({
|
|
58
|
+
bg: colors.background[100],
|
|
59
|
+
borderRadius: "1rem",
|
|
60
|
+
boxShadow: selected ? `inset 0 0 0 2px ${colors.header[900]}` : "none",
|
|
61
|
+
opacity: disabled ? 0.6 : 1,
|
|
62
|
+
transition: transitionFor(["background-color", "box-shadow"]),
|
|
63
|
+
_hover: interactive && !selected && !disabled ? { bg: colors.background[200] } : undefined,
|
|
64
|
+
sx: { ...(ringed ? focusVisibleRing(colors) : {}), ...reducedMotionSx() },
|
|
65
|
+
});
|
|
66
|
+
/** The 20px circle that carries selection state beside the text. */
|
|
67
|
+
export const RadioIndicator = ({ selected }) => {
|
|
68
|
+
const { colors } = useCustomTheme();
|
|
69
|
+
const fill = colors.header[900];
|
|
70
|
+
return (_jsx(Box, { as: "span", "aria-hidden": true, display: "inline-flex", alignItems: "center", justifyContent: "center", boxSize: "1.25rem", flexShrink: 0, borderRadius: "full", bg: selected ? fill : "transparent", color: onFilled(fill, colors.white, colors.black), boxShadow: selected ? "none" : `inset 0 0 0 1.5px ${colors.textMuted}`, transition: transitionFor(["background-color", "box-shadow"]), sx: reducedMotionSx(), children: selected && _jsx(Check, { size: 12, strokeWidth: 3 }) }));
|
|
71
|
+
};
|
|
72
|
+
/** Radio inside a group, toggle button when only `onSelect` is given, inert otherwise. */
|
|
73
|
+
export const useSelectable = ({ value, selected, disabled, onSelect, }) => {
|
|
74
|
+
const group = useSelectableGroup();
|
|
75
|
+
const [ringed, setRinged] = useState(false);
|
|
76
|
+
const inGroup = group !== null && value !== undefined;
|
|
77
|
+
const isSelected = inGroup ? group.value === value : !!selected;
|
|
78
|
+
const interactive = (inGroup || !!onSelect) && !disabled;
|
|
79
|
+
const choose = () => {
|
|
80
|
+
if (!interactive)
|
|
81
|
+
return;
|
|
82
|
+
if (inGroup)
|
|
83
|
+
group.select(value);
|
|
84
|
+
onSelect === null || onSelect === void 0 ? void 0 : onSelect();
|
|
85
|
+
};
|
|
86
|
+
const props = {
|
|
87
|
+
role: inGroup ? "radio" : onSelect ? "button" : undefined,
|
|
88
|
+
"aria-checked": inGroup ? isSelected : undefined,
|
|
89
|
+
"aria-pressed": !inGroup && onSelect ? isSelected : undefined,
|
|
90
|
+
tabIndex: inGroup ? (group.tabStop === value && !disabled ? 0 : -1) : onSelect && !disabled ? 0 : undefined,
|
|
91
|
+
"data-value": inGroup ? value : undefined,
|
|
92
|
+
onClick: choose,
|
|
93
|
+
onKeyDown: (event) => {
|
|
94
|
+
if (event.target !== event.currentTarget)
|
|
95
|
+
return;
|
|
96
|
+
if (event.key === " " || event.key === "Enter") {
|
|
97
|
+
event.preventDefault();
|
|
98
|
+
choose();
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
onFocus: (event) => {
|
|
102
|
+
try {
|
|
103
|
+
setRinged(event.currentTarget.matches(":focus-visible"));
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
setRinged(true);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
onBlur: () => setRinged(false),
|
|
110
|
+
};
|
|
111
|
+
return { isSelected, interactive, inGroup, ringed, props };
|
|
112
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export const LOW_STOCK_THRESHOLD = 5;
|
|
2
|
+
export function stockState(variant, threshold = LOW_STOCK_THRESHOLD) {
|
|
3
|
+
if (!variant || variant.stock === undefined)
|
|
4
|
+
return "in-stock";
|
|
5
|
+
if (variant.stock > 0)
|
|
6
|
+
return variant.stock <= threshold ? "low-stock" : "in-stock";
|
|
7
|
+
return variant.backorder ? "backorder" : "out-of-stock";
|
|
8
|
+
}
|
|
9
|
+
const sellable = (variant) => stockState(variant) !== "out-of-stock";
|
|
10
|
+
const matches = (variant, selection) => Object.entries(selection).every(([axisId, valueId]) => variant.options[axisId] === valueId);
|
|
11
|
+
export function selectionComplete(axes, selection) {
|
|
12
|
+
return axes.every((axis) => selection[axis.id] !== undefined);
|
|
13
|
+
}
|
|
14
|
+
export function findVariant(axes, variants, selection) {
|
|
15
|
+
if (!selectionComplete(axes, selection))
|
|
16
|
+
return undefined;
|
|
17
|
+
return variants.find((variant) => matches(variant, selection));
|
|
18
|
+
}
|
|
19
|
+
/** A value is offered when some sellable variant has it alongside the other axes' current picks. */
|
|
20
|
+
export function isOptionAvailable(variants, selection, axisId, valueId) {
|
|
21
|
+
const probe = { ...selection, [axisId]: valueId };
|
|
22
|
+
return variants.some((variant) => sellable(variant) && matches(variant, probe));
|
|
23
|
+
}
|
|
24
|
+
export function remainingStock(variants, selection, axisId, valueId) {
|
|
25
|
+
const probe = { ...selection, [axisId]: valueId };
|
|
26
|
+
const hits = variants.filter((variant) => matches(variant, probe) && sellable(variant));
|
|
27
|
+
if (hits.length === 0 || hits.some((variant) => variant.stock === undefined))
|
|
28
|
+
return undefined;
|
|
29
|
+
return hits.reduce((sum, variant) => { var _a; return sum + ((_a = variant.stock) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
30
|
+
}
|
|
31
|
+
export function priceRange(variants) {
|
|
32
|
+
if (variants.length === 0)
|
|
33
|
+
return null;
|
|
34
|
+
const prices = variants.map((variant) => variant.price);
|
|
35
|
+
return { min: Math.min(...prices), max: Math.max(...prices) };
|
|
36
|
+
}
|
|
37
|
+
export function firstAvailableSelection(variants) {
|
|
38
|
+
var _a;
|
|
39
|
+
const first = (_a = variants.find(sellable)) !== null && _a !== void 0 ? _a : variants[0];
|
|
40
|
+
return first ? { ...first.options } : {};
|
|
41
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useLayoutEffect, useState } from "react";
|
|
2
|
+
/** Width of the referenced element, or undefined until measurable (SSR, jsdom, no ResizeObserver). */
|
|
3
|
+
export const useContainerWidth = (ref) => {
|
|
4
|
+
const [width, setWidth] = useState(undefined);
|
|
5
|
+
useLayoutEffect(() => {
|
|
6
|
+
const node = ref.current;
|
|
7
|
+
if (!node)
|
|
8
|
+
return undefined;
|
|
9
|
+
const measure = () => {
|
|
10
|
+
const next = node.getBoundingClientRect().width;
|
|
11
|
+
setWidth(next > 0 ? Math.round(next) : undefined);
|
|
12
|
+
};
|
|
13
|
+
measure();
|
|
14
|
+
if (typeof ResizeObserver === "undefined")
|
|
15
|
+
return undefined;
|
|
16
|
+
const observer = new ResizeObserver(measure);
|
|
17
|
+
observer.observe(node);
|
|
18
|
+
return () => observer.disconnect();
|
|
19
|
+
}, [ref]);
|
|
20
|
+
return width;
|
|
21
|
+
};
|