pixelize-design-library 2.4.2-beta.55 → 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 +64 -0
- package/COMPONENT-GOTCHAS.md +50 -22
- package/DESIGN-GUIDE.md +19 -2
- 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/DatePickerProps.d.ts +1 -1
- 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/Input/PhoneNumberInputProps.d.ts +1 -1
- 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/MultiSelect/MultiSelectProps.d.ts +1 -1
- 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/PinInput/PinInputProps.d.ts +1 -1
- 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/Search/SearchProps.d.ts +1 -1
- package/dist/Components/SearchSelect/SearchSelectProps.d.ts +1 -1
- 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/Select/SelectProps.d.ts +1 -1
- package/dist/Components/SelectSearch/SelectSearchProps.d.ts +1 -1
- package/dist/Components/SelectV2/SelectV2Props.d.ts +1 -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/primitives/controlSizes.js +1 -1
- 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/tokens/primitives/controlSizes.js +1 -1
- 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
package/CHANGELOG.md
CHANGED
|
@@ -18,11 +18,46 @@ next major.
|
|
|
18
18
|
|
|
19
19
|
### Added
|
|
20
20
|
|
|
21
|
+
- **Commerce kit** — the components for a shop front, designed mobile-first (Pebble principles:
|
|
22
|
+
chromeless tonal cards, one loud action per view, selection never by colour alone). Product:
|
|
23
|
+
`Rating`, `PriceBlock`, `StockStatus`, `ProductBadges`, `WishlistToggle`, `OptionChip`,
|
|
24
|
+
`VariantSelector`, `QuantityStepper`, `MediaGallery` / `MediaLightbox`, `ProductCardGrid`,
|
|
25
|
+
`ProductCardSkeleton`, `QuickAddSheet`. Detail page: `StickyBuyBar`, `PincodeChecker`,
|
|
26
|
+
`TrustBadges`, `OffersList`, `SpecTable`, `ReviewSummary`, `ReviewList`, `DetailSections`.
|
|
27
|
+
Bag and checkout: `CartItem`, `OrderSummary`, `CouponField`, `AddressCard` / `AddressCardGroup`,
|
|
28
|
+
`PaymentOption` / `PaymentOptionGroup`, `OrderStatusTimeline`, `BagBar`. `VariantSelector` is
|
|
29
|
+
config-driven (`axes` + `variants`, any vertical) and derives per-combination availability.
|
|
30
|
+
Helpers: `stockState`, `findVariant`, `isOptionAvailable`, `remainingStock`, `priceRange`,
|
|
31
|
+
`firstAvailableSelection`, `selectionComplete`, `formatPrice`, `discountPercent`,
|
|
32
|
+
`discountAmount`, `unitPrice`. A **Storefront** page example in the playground wires them into a
|
|
33
|
+
working shop app (home, listing, product, wishlist, bag, checkout, order tracking).
|
|
34
|
+
- **`star` palette token.** Rating-star gold, derived (`buildStar`) and identical in every brand.
|
|
35
|
+
|
|
36
|
+
- **`Spinner` — `testId`.** Maps to `data-testid` on the rendered node, wins over a raw
|
|
37
|
+
`data-testid` passthrough. Lets consumers select a loading spinner in tests.
|
|
21
38
|
- **`SegmentedControl` / `Switch` — `surface`.** The background the control is drawn on. Optional:
|
|
22
39
|
the track is an opaque plate on any backdrop, so the labels read without it. Pass it to aim the
|
|
23
40
|
plate's hairline edge at the real backdrop rather than at the page canvas.
|
|
24
41
|
- **`MultiSelect` — `addOnBlur`.** Commits the typed address on focus-out as well as on Enter.
|
|
25
42
|
Defaults to `false`, so existing call sites keep Enter-only behaviour.
|
|
43
|
+
- **`StatCard` — `footer` / `sparkline`.** `footer` pins content below a divider at the bottom of
|
|
44
|
+
the card; `sparkline` sizes and positions a small inline trend chart beside the value (bring your
|
|
45
|
+
own — the library doesn't ship a mini-chart primitive). Neither renders while `isLoading`.
|
|
46
|
+
- **`Table` — `columns[].label` accepts `ReactNode`, plus `labelText`.** A rich header (icon, badge,
|
|
47
|
+
tooltip trigger) is now safe everywhere a header used to be assumed to be text — sort/filter
|
|
48
|
+
button names, Manage Columns, the Group picker, filter chips, and saved column preferences all
|
|
49
|
+
read through a new `columnLabelText()` fallback chain instead of stringifying the node. Pass
|
|
50
|
+
`labelText` to control the derived text explicitly; a wide `ReactNode` header falls back to a
|
|
51
|
+
fixed width rather than auto-sizing from text length. `string`/`number` labels are unaffected.
|
|
52
|
+
- **`SegmentedControl` — `shortLabel` / `orientation`.** `shortLabel` shows in place of `label`
|
|
53
|
+
below the `md` breakpoint (the full label is always restated as the accessible name);
|
|
54
|
+
`orientation="vertical"` stacks segments column-wise. Both optional, default unchanged.
|
|
55
|
+
- **`SideBar` — `lockedReason`.** A tooltip explaining why a menu item is locked, shown on hover/
|
|
56
|
+
focus of a locked row (top-level, submenu, or a top-level item's `secondaryItems`).
|
|
57
|
+
- **`useChartTheme`.** A hook wrapping the existing `chartInk`/`getCategoricalSeriesColors`
|
|
58
|
+
primitives into a ready-made theme for `recharts` consumers — series colors, grid/axis ink, and
|
|
59
|
+
tooltip/legend styling, all dark-mode aware. `recharts` itself is not a dependency of this
|
|
60
|
+
library; bring your own.
|
|
26
61
|
|
|
27
62
|
- **Dark mode.** `PixelizeThemeProvider` (defaults to `system`), `useThemeMode`, `ThemeSwitcher`.
|
|
28
63
|
Dark palettes are derived per brand from that brand's own light palette, so brand hue carries
|
|
@@ -47,6 +82,11 @@ next major.
|
|
|
47
82
|
|
|
48
83
|
### Changed
|
|
49
84
|
|
|
85
|
+
- **`ProductCard` and `ProductDetails` are rewritten** — see Breaking below. `ProductCard` is a
|
|
86
|
+
chromeless 4:5 card (grid / list / rail, swatch dots that swap the photo, quick-add sheet or
|
|
87
|
+
direct add that morphs into a stepper, sold-out "Notify me", slots). `ProductDetails` is a
|
|
88
|
+
composed, controlled/uncontrolled product page with a sticky buy bar on mobile.
|
|
89
|
+
|
|
50
90
|
- **Control heights: `xs` 24px → 30px, `sm` 32px → 38px, `md` 40px → 42px.** `lg` (48px) is
|
|
51
91
|
unchanged. `CONTROL_SIZES` is the one scale behind every field, select and button, so `Button`,
|
|
52
92
|
`TextInput`, `InputTextArea`, `NumberInput`, `PinInput`, `Select`, `SelectV2`, `SearchSelect`,
|
|
@@ -81,6 +121,15 @@ next major.
|
|
|
81
121
|
|
|
82
122
|
### Fixed
|
|
83
123
|
|
|
124
|
+
- **`SingleDatePicker` / `RangeDatePicker` / `TimeOnlyPicker` popovers clipped inside a scrolling or
|
|
125
|
+
`overflow: hidden` modal.** They now portal to `document.body` (via Chakra's own `Portal`,
|
|
126
|
+
matching `Select`), so the calendar is no longer cut off by an ancestor's clipping or scroll
|
|
127
|
+
container. Also fixes Escape not closing the calendar while focus was inside it (it only
|
|
128
|
+
committed the value before).
|
|
129
|
+
- **`SideBar`'s `locked` flag didn't block clicks on a top-level item's `secondaryItems` row.** The
|
|
130
|
+
rail/submenu/flyout rows already no-op'd a locked click; `SecondaryBar`'s own row renderer never
|
|
131
|
+
checked `locked` at all, so a locked secondary item stayed fully clickable with no lock icon. See
|
|
132
|
+
[COMPONENT-GOTCHAS.md](COMPONENT-GOTCHAS.md).
|
|
84
133
|
- **Control-size regression: field and button heights are two scales again, not one.** A
|
|
85
134
|
form-field-only bump had leaked into `Button`, `SegmentedControl`, `Tabs`, `TableToggle` and
|
|
86
135
|
`Dropdown`'s trigger through one shared token. `CONTROL_SIZES` (fields/selects: xs 24 · sm 38 ·
|
|
@@ -89,6 +138,10 @@ next major.
|
|
|
89
138
|
`Common/sizeScaleOwnership.test.ts` so they can't silently merge again. `OPTION_ROW_SIZES`
|
|
90
139
|
(dropdown/select/menu row heights) is reverted to xs 24 · sm 30 · md 34 · lg 40; `OrgSwitcher`/
|
|
91
140
|
`AppSwitcher` are back on their own hardcoded literal sizes, not a shared token.
|
|
141
|
+
- **`CONTROL_SIZES.xs` (fields only) raised 24px → 32px.** `TextInput`, `Select`, `MultiSelect`,
|
|
142
|
+
`SearchSelect`, `SelectSearch`, `SelectV2`, `NumberInput`, `PinInput`, `Search` and the
|
|
143
|
+
`DatePicker` family at `size="xs"` are now 32px tall. `BUTTON_SIZES.xs` (`Button`,
|
|
144
|
+
`SegmentedControl`, `Tabs`, `TableToggle`, `Dropdown`'s trigger) is untouched, still 24px.
|
|
92
145
|
- **`SideBar`'s nav scrollbar thumb was the brand `primary` color.** Every other scrollbar in the
|
|
93
146
|
library reads a neutral chrome token; the sidebar's hand-rolled CSS (`Constants/Sidebar.ts`) was
|
|
94
147
|
the one place still reaching for `primary[500]`/`primary[700]`. It now reads
|
|
@@ -307,6 +360,17 @@ Nothing is removed yet — each of these still ships its full implementation.
|
|
|
307
360
|
|
|
308
361
|
### Breaking — staged for the next major, not yet released
|
|
309
362
|
|
|
363
|
+
**`ProductCard` / `ProductDetails` props are replaced, and `ProductImageSlider` is gone.** Zero
|
|
364
|
+
known consumers in the Pixelize repos. `ProductCard` drops `id`, `label`, `description`,
|
|
365
|
+
`productImage`, `tags`, `reviews`, `options`, `button`, `onClick`, `onAddToCart`, `onNotifyMe`,
|
|
366
|
+
`onOptionChange`, `addToCart`, `goToCart`, `notifyMe`, `OnGoToCart`, `batch`, `size`,
|
|
367
|
+
`avalabilitys`, `isQtyEditable`, `displayRating`; `ProductDetails` drops its old image/video,
|
|
368
|
+
option and cart-callback props (it takes `product`, `selection`, `onAddToBag` and slots). Video
|
|
369
|
+
and YouTube/Vimeo frames are now `ProductMedia` items in `MediaGallery`.
|
|
370
|
+
|
|
371
|
+
**`star` is a required `PaletteProps` token.** A hand-written palette without it throws in
|
|
372
|
+
`assertPixelizePalette` naming `star`; palettes built from the library's builders get it for free.
|
|
373
|
+
|
|
310
374
|
**34 Chakra value passthroughs (and 12 type passthroughs) are removed from the Primitives barrel**,
|
|
311
375
|
because each duplicated a component this library already owns. The point of the library is one
|
|
312
376
|
place to change the UI; a Chakra twin beside an owned component means half the call sites bypass
|
package/COMPONENT-GOTCHAS.md
CHANGED
|
@@ -201,13 +201,13 @@ and wires `aria-controls` to them. Pick by that, never by the picture. A screen
|
|
|
201
201
|
| A themed row of icon + text + icon, optionally a dropdown menu on the right | `ButtonGroupIcon` | The real "group" component despite `Buttons`' plural name suggesting otherwise |
|
|
202
202
|
| *(avoid)* | `Buttons` (plural) | Legacy single-`Button` wrapper, not exported from the package root — see gotcha below |
|
|
203
203
|
|
|
204
|
-
### Which "card" — `Card` / `ProductCard` / `
|
|
204
|
+
### Which "card" — `Card` / `ProductCard` / `StatCard` / `PaymentCard`
|
|
205
205
|
|
|
206
206
|
| Need | Component | Why not the others |
|
|
207
207
|
| --- | --- | --- |
|
|
208
208
|
| Generic bordered/padded container, no commerce semantics | `Card` | Layout wrapper with `header`/`footer` slots and a padded body — see gotcha below |
|
|
209
|
-
|
|
|
210
|
-
|
|
|
209
|
+
| Product tile for a grid, list or rail (photo, price, rating, swatches, quick add) | `ProductCard` | Takes the same `axes` / `variants` as `ProductDetails`; for a whole page use `ProductDetails` |
|
|
210
|
+
| A KPI figure with delta and sparkline | `StatCard` | Not a product or a container |
|
|
211
211
|
| Subscription/pricing-tier card (plans, billing cycle, feature list) | `PaymentCard` | Takes a `Plan` object, unrelated to `options`/`productImage` |
|
|
212
212
|
|
|
213
213
|
### Managing organizations — `OrganizationDetails` vs `OrgSwitcher`
|
|
@@ -312,7 +312,7 @@ not enough when the overlay sits inside a transition wrapper — the wrapper kee
|
|
|
312
312
|
|
|
313
313
|
| Component | beta.43 → beta.44 | Restore the old look |
|
|
314
314
|
| --- | --- | --- |
|
|
315
|
-
| Fields, selects, buttons (`Button`, `TextInput`, `InputTextArea`, `NumberInput`, DatePicker family, `Select`, `SelectV2`, `SearchSelect`, `SelectSearch`, `Search`, `Dropdown`, `SegmentedControl`) | Default size `md` → `sm` (38px). One scale for all: xs 24 / sm 38 / md 40 / lg 48 — the same height in every field, select and button. `TimePicker` has no `size` (fixed `sm`); `SegmentedControl` has no `xs`. **Since decoupled** — fields/selects now read `CONTROL_SIZES` (
|
|
315
|
+
| Fields, selects, buttons (`Button`, `TextInput`, `InputTextArea`, `NumberInput`, DatePicker family, `Select`, `SelectV2`, `SearchSelect`, `SelectSearch`, `Search`, `Dropdown`, `SegmentedControl`) | Default size `md` → `sm` (38px). One scale for all: xs 24 / sm 38 / md 40 / lg 48 — the same height in every field, select and button. `TimePicker` has no `size` (fixed `sm`); `SegmentedControl` has no `xs`. **Since decoupled** — fields/selects now read `CONTROL_SIZES` (xs 24 / sm 38 / md 40 / lg 48 at the time of the split; xs later raised to 32px), `Button`/`SegmentedControl`/`Tabs`/`TableToggle`/`Dropdown`'s trigger read the separate `BUTTON_SIZES` (xs 24 / sm 32 / md 40 / lg 48, back to pre-regression) — see the gotcha below | `size="md"` |
|
|
316
316
|
| `Button` | Text one step smaller (sm 14→13px, md 16→14, lg 18→16). Busy = spinner only, width kept (was "Loading" + spinner). Outline: 1px border, hover is a tint, not a fill | `loadingText="Loading"` |
|
|
317
317
|
| `Tag` | `solid`/`md` → `subtle`/`sm`. Hover + pointer only with `onTagClick`; `maxW` truncates with the full text as a title. Exact heights 20/24/28/32, weight 500, 1px inset ring (never adds height); subtle is a light tint with ink ≥ 6.5:1 | `variant="solid" size="md"` |
|
|
318
318
|
| `resolveSoftTone` | `bg`/`border` are now translucent (alpha hex) — composite onto the surface before `contrastRatio`; optional 3rd `surface` arg; adds `hoverBg`/`activeBg`. Badge/Alert/Toaster/EmptyState follow | — |
|
|
@@ -391,7 +391,7 @@ library's own themed component rather than the Chakra passthrough.
|
|
|
391
391
|
### `CONTROL_SIZES` (fields) and `BUTTON_SIZES` (buttons) are separate scales — changing one never changes the other
|
|
392
392
|
|
|
393
393
|
Fields/selects (`TextInput`, `Select`, `MultiSelect`, `SearchSelect`, `NumberInput`, `PinInput`, the
|
|
394
|
-
`DatePicker` family, …) read `CONTROL_SIZES` — xs
|
|
394
|
+
`DatePicker` family, …) read `CONTROL_SIZES` — xs 32 · sm 38 · md 40 · lg 48. `Button` and every
|
|
395
395
|
button-like trigger (`SegmentedControl`, `Tabs`, `TableToggle`, `Dropdown`'s trigger) read the
|
|
396
396
|
separate `BUTTON_SIZES` — xs 24 · sm 32 · md 40 · lg 48. They used to share one token, which is what
|
|
397
397
|
let a field-only size bump leak into buttons — the split is now gate-tested
|
|
@@ -948,23 +948,27 @@ draw nothing.
|
|
|
948
948
|
|
|
949
949
|
**Apply:** drop the nested `CardBody`, or pass `bodyProps={{ p: 0 }}`.
|
|
950
950
|
|
|
951
|
-
###
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
**
|
|
951
|
+
### Commerce kit — read before building a shop screen
|
|
952
|
+
|
|
953
|
+
`ProductCard`, `ProductDetails`, `VariantSelector` and the bag pieces share one contract: pass
|
|
954
|
+
`axes: OptionAxis[]` + `variants: ProductVariant[]`, never per-vertical props. A variant's
|
|
955
|
+
`options` must set every axis, or `findVariant` returns `undefined`.
|
|
956
|
+
|
|
957
|
+
- **`layout="auto"` on `MediaGallery` and `ProductDetails` follows the container, not the window**
|
|
958
|
+
(560px / 960px). `ProductCard` and `QuickAddSheet` `auto` still read the window; pass `layout` /
|
|
959
|
+
`quickAddPresentation` explicitly inside a phone-width frame.
|
|
960
|
+
- **Drawers and modals portal to the window, never into your phone frame.** `ProductCard`'s quick-add
|
|
961
|
+
sheet needs `quickAddPresentation="drawer"` and `quickAddDrawerProps={{ maxW: "390px !important", mx: "auto" }}`
|
|
962
|
+
there; the `!important` is needed because Chakra's slide sets an inline `max-width: 100vw`.
|
|
963
|
+
- **`OptionChip` `unavailable` is visual and announced only** — `onSelect` still fires so a parent
|
|
964
|
+
can re-derive the other axes. Guard it yourself if the pick must be refused.
|
|
965
|
+
- **`WishlistToggle` flips its default name and `aria-pressed` together** — on cards pass a fixed
|
|
966
|
+
`label` (`Save ${title}`).
|
|
967
|
+
- **Group children must be direct children.** `AddressCardGroup` / `PaymentOptionGroup` read the
|
|
968
|
+
roving tab stop from their children's `value`; a wrapper component hides it.
|
|
969
|
+
- **`BagBar` and `StickyBuyBar` are CSS-sticky, not fixed.** Make them the last child of the
|
|
970
|
+
scrolling container; `StickyBuyBar` also needs a parent taller than the viewport.
|
|
971
|
+
- **"N left" appears only from a real `stock` count** at or below `LOW_STOCK_THRESHOLD` (5).
|
|
968
972
|
|
|
969
973
|
### `PaymentCard`'s `onHover` never fires its `"card"` variant, and the CTA hides unless `isRenewal`
|
|
970
974
|
|
|
@@ -1400,6 +1404,15 @@ and submenu items. `disabled` is unchanged and still works independently.
|
|
|
1400
1404
|
**Apply:** `locked: true` alone now prevents interaction; you no longer need to also set
|
|
1401
1405
|
`disabled: true`.
|
|
1402
1406
|
|
|
1407
|
+
**Follow-up (same trap, missed spot): `SecondaryBar` still ignored `locked`.** `SecondaryBar.tsx`'s
|
|
1408
|
+
`CollapsedItem`/`ExpandedItem` render the same `MenuProps` shape via a top-level item's
|
|
1409
|
+
`secondaryItems`, but their click guards checked only `menuDisabled(item)` — never `item.locked` —
|
|
1410
|
+
and neither rendered the lock icon, so a locked secondary item stayed fully clickable and looked
|
|
1411
|
+
identical to an unlocked one. Fixed the same way as `MenuItemBox`/`MenuPopoverContent`. Also added
|
|
1412
|
+
`lockedReason?: string` (`MenuProps`) — an optional per-item tooltip, shown on hover/focus of a
|
|
1413
|
+
locked row anywhere in `SideBar` (rail row, submenu row, both collapsed-rail flyouts, and
|
|
1414
|
+
`SecondaryBar`), via the library's own `ToolTip`.
|
|
1415
|
+
|
|
1403
1416
|
### `SideBar` menu-item labels clipped the bottom of descenders (g/y/p/q/j) — fixed
|
|
1404
1417
|
|
|
1405
1418
|
`TextTruncation.tsx`'s label used `overflow="hidden"` (both axes) with `lineHeight="1"`, so the line
|
|
@@ -1512,3 +1525,18 @@ sub-line needs. The library's own rows no longer use it.
|
|
|
1512
1525
|
from `optionRowDescriptionInk(theme.colors)` (exported from the package root) rather than
|
|
1513
1526
|
`theme.colors.textMuted`. It is a no-op in light mode. The row's main label is
|
|
1514
1527
|
`optionRowInk(theme.colors, isSelected)` with `optionRowWeight(isSelected)` — never brand ink.
|
|
1528
|
+
|
|
1529
|
+
### `Table`'s node column `label` needs `labelText` unless its text is plain children
|
|
1530
|
+
|
|
1531
|
+
`columns[].label` accepts a node (an icon, a tooltip trigger) as well as a string or number. Every
|
|
1532
|
+
place that cannot render a node — the sort and filter button names, Manage Columns, the Group
|
|
1533
|
+
picker, filter chips, saved preferences and `onRowClick`'s `header.label` — uses a plain-text name
|
|
1534
|
+
instead: `labelText` if set, else the node's literal text children, else the column `id`. A node
|
|
1535
|
+
whose text comes from inside a component (`<MyHeader title="Revenue" />`, a `t()` call inside a
|
|
1536
|
+
child) has no literal children, so those places silently read the raw `id`.
|
|
1537
|
+
|
|
1538
|
+
A wide node header is also **clipped, not ellipsized** — the header's ellipsis only works on bare
|
|
1539
|
+
text. Column widths come from the rendered DOM, never from label length, so sizing is unaffected.
|
|
1540
|
+
|
|
1541
|
+
**Apply:** set `labelText` on every node label; put an `isTruncated` `Text` inside the node if it
|
|
1542
|
+
can outgrow the column.
|
package/DESIGN-GUIDE.md
CHANGED
|
@@ -90,7 +90,7 @@ don't lean on that pair to distinguish two categories; reach for a utility schem
|
|
|
90
90
|
## 5. Controls — two scales, `sm` by default
|
|
91
91
|
|
|
92
92
|
Fields (`TextInput`, `InputTextArea`, `NumberInput`, `Select`, `Search`, `RangeSlider`, the
|
|
93
|
-
`DatePicker` family) sit on `CONTROL_SIZES` — `xs`
|
|
93
|
+
`DatePicker` family) sit on `CONTROL_SIZES` — `xs` 32px · `sm` 38px · `md` 40px · `lg` 48px.
|
|
94
94
|
`Button` and every button-like trigger (`SegmentedControl`, `Tabs`, `TableToggle`, `Dropdown`)
|
|
95
95
|
sit on the separate `BUTTON_SIZES` scale — `xs` 24px · `sm` 32px · `md` 40px · `lg` 48px. Both
|
|
96
96
|
**default to `sm`**, so on a desktop page **don't pass `size`**. They line up at `md`/`lg`; at
|
|
@@ -213,4 +213,21 @@ not shipped in this package). Start from the closest one:
|
|
|
213
213
|
| Settings / long form | `settings.tsx` | section nav, `SettingsSection` + `SettingRow`, `SaveBar`, danger zone |
|
|
214
214
|
| Board | `pipeline.tsx` | `KanbanBoard` with custom cards and column totals (`height`/`maxH` to size it) |
|
|
215
215
|
| Inbox / master–detail | `inbox.tsx` | selectable list rows, conversation pane, composer, mobile list↔detail |
|
|
216
|
-
|
|
216
|
+
| Shop front (home → listing → product → bag → checkout → order) | `storefront/` | `ProductCard` grid / rail / quick-add, `ProductDetails` + `StickyBuyBar`, `CartItem`, `OrderSummary`, `CouponField`, address/payment groups, `OrderStatusTimeline`, `BagBar`; mobile frame + desktop |
|
|
217
|
+
|
|
218
|
+
## 10. Shop screens (e-commerce)
|
|
219
|
+
|
|
220
|
+
For catalogue, product, bag and checkout screens use the commerce kit, not `Card` + `Table`. Detail
|
|
221
|
+
and rules: [COMPONENT-GOTCHAS.md](COMPONENT-GOTCHAS.md) "Commerce kit".
|
|
222
|
+
|
|
223
|
+
- **Model the product once** as `axes` + `variants` (`OptionAxis[]`, `ProductVariant[]`) and hand the
|
|
224
|
+
same objects to `ProductCard`, `QuickAddSheet`, `VariantSelector` and `ProductDetails`. Any vertical
|
|
225
|
+
works — colour/size, pack size, storage, finish, shade — because the components only see axis ids.
|
|
226
|
+
- **Mobile first.** Cards in a 2-up `ProductCardGrid` (`density="compact"`), a swipe `MediaGallery`,
|
|
227
|
+
`StickyBuyBar` and `BagBar` pinned at the bottom, sheets (`QuickAddSheet`, filters) instead of popovers.
|
|
228
|
+
- **One loud action per view:** the single brand-filled button is Add to bag / Place order. Wishlist,
|
|
229
|
+
Buy now, Remove and Move-to-wishlist are soft or ghost.
|
|
230
|
+
- **Be honest:** "N left" only from real stock, delivery as a date (`PincodeChecker`), MRP + discount
|
|
231
|
+
from `PriceBlock`, the tax note and legal-metrology block in `DetailSections`.
|
|
232
|
+
- **Four states per screen** as usual: `ProductCardSkeleton` / `CartItem isLoading`, first-run and
|
|
233
|
+
filtered-empty `EmptyState`, `ErrorState` with Retry.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AddressCardProps } from "./AddressCardProps";
|
|
2
|
+
/** Tonal delivery-address card: name, tags, lines and calm Edit/Remove actions; selection is a ring plus a check. */
|
|
3
|
+
declare const AddressCard: ({ value, name, phone, lines, tag, isDefault, note, selected, onSelect, onEdit, onRemove, disabled, labels, "data-testid": testId, }: AddressCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export default AddressCard;
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const react_2 = require("@chakra-ui/react");
|
|
9
|
+
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
10
|
+
const selectable_1 = require("../CheckoutKit/selectable");
|
|
11
|
+
const Button_1 = __importDefault(require("../Button/Button"));
|
|
12
|
+
const Tag_1 = __importDefault(require("../Tag/Tag"));
|
|
13
|
+
const DEFAULT_LABELS = { default: "Default", edit: "Edit", remove: "Remove" };
|
|
14
|
+
/** Tonal delivery-address card: name, tags, lines and calm Edit/Remove actions; selection is a ring plus a check. */
|
|
15
|
+
const AddressCard = ({ value, name, phone, lines, tag, isDefault = false, note, selected, onSelect, onEdit, onRemove, disabled = false, labels, "data-testid": testId, }) => {
|
|
16
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
17
|
+
const uid = (0, react_1.useId)();
|
|
18
|
+
const nameId = `${uid}-name`;
|
|
19
|
+
const bodyId = `${uid}-body`;
|
|
20
|
+
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
21
|
+
const { isSelected, interactive, inGroup, ringed, props } = (0, selectable_1.useSelectable)({ value, selected, disabled, onSelect });
|
|
22
|
+
const selectable = inGroup || !!onSelect;
|
|
23
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { direction: "column", "data-testid": testId, "data-selected": isSelected || undefined, ...(0, selectable_1.selectableSurface)(colors, { selected: isSelected && selectable, disabled, interactive, ringed }), children: [(0, jsx_runtime_1.jsxs)(react_2.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 && ((0, jsx_runtime_1.jsx)(react_2.Box, { mt: 0.5, children: (0, jsx_runtime_1.jsx)(selectable_1.RadioIndicator, { selected: isSelected }) })), (0, jsx_runtime_1.jsxs)(react_2.Flex, { direction: "column", gap: 1, flex: 1, minW: 0, children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 2, wrap: "wrap", children: [(0, jsx_runtime_1.jsx)(react_2.Text, { as: "span", id: nameId, fontSize: "sm", fontWeight: 700, lineHeight: 1.4, color: colors.header[900], children: name }), tag && (0, jsx_runtime_1.jsx)(Tag_1.default, { label: tag, size: "xs", tone: "neutral" }), isDefault && (0, jsx_runtime_1.jsx)(Tag_1.default, { label: copy.default, size: "xs", tone: "neutral" })] }), (0, jsx_runtime_1.jsxs)(react_2.Box, { id: bodyId, children: [lines.map((line) => ((0, jsx_runtime_1.jsx)(react_2.Text, { as: "span", display: "block", fontSize: "sm", lineHeight: 1.5, color: colors.text[800], children: line }, line))), phone && ((0, jsx_runtime_1.jsx)(react_2.Text, { as: "span", display: "block", mt: 1, fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, sx: { fontVariantNumeric: "tabular-nums" }, children: phone })), note && ((0, jsx_runtime_1.jsx)(react_2.Text, { as: "span", display: "block", mt: 1, fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: note }))] })] })] }), (onEdit || onRemove) && ((0, jsx_runtime_1.jsxs)(react_2.Flex, { gap: 1, pl: selectable ? "2.75rem" : 1, pr: 2, pb: 2, children: [onEdit && ((0, jsx_runtime_1.jsx)(Button_1.default, { variant: "ghost", colorScheme: "gray", size: "sm", onClick: onEdit, "aria-label": `${copy.edit} address: ${name}`, children: copy.edit })), onRemove && ((0, jsx_runtime_1.jsx)(Button_1.default, { variant: "ghost", colorScheme: "gray", size: "sm", onClick: onRemove, "aria-label": `${copy.remove} address: ${name}`, children: copy.remove }))] }))] }));
|
|
24
|
+
};
|
|
25
|
+
exports.default = AddressCard;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
4
|
+
const selectable_1 = require("../CheckoutKit/selectable");
|
|
5
|
+
/** Radiogroup wrapper for `AddressCard`s. */
|
|
6
|
+
const AddressCardGroup = (props) => (0, jsx_runtime_1.jsx)(selectable_1.SelectableGroup, { ...props });
|
|
7
|
+
exports.default = AddressCardGroup;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/** Visible copy; override every string for another language. */
|
|
3
|
+
export interface AddressCardLabels {
|
|
4
|
+
default: string;
|
|
5
|
+
edit: string;
|
|
6
|
+
remove: string;
|
|
7
|
+
}
|
|
8
|
+
/** A saved delivery address. Inside an `AddressCardGroup` it is a radio keyed by `value`; alone, `onSelect` makes it a toggle button. */
|
|
9
|
+
export interface AddressCardProps {
|
|
10
|
+
/** Identifies the card inside an `AddressCardGroup`; required there. */
|
|
11
|
+
value?: string;
|
|
12
|
+
name: string;
|
|
13
|
+
phone?: string;
|
|
14
|
+
/** Address lines in order, e.g. ["12 Palm Grove, Indiranagar", "Bengaluru, Karnataka 560038"]. */
|
|
15
|
+
lines: string[];
|
|
16
|
+
/** Short place tag such as "Home" or "Work". */
|
|
17
|
+
tag?: string;
|
|
18
|
+
/** Adds a "Default" tag. */
|
|
19
|
+
isDefault?: boolean;
|
|
20
|
+
/** Muted line under the address, e.g. "Delivers by Thu, 9 Oct". */
|
|
21
|
+
note?: ReactNode;
|
|
22
|
+
/** Standalone selection state; ignored inside a group, where the group's value decides. */
|
|
23
|
+
selected?: boolean;
|
|
24
|
+
/** Called when the card is chosen; also fires inside a group, after the group updates. */
|
|
25
|
+
onSelect?: () => void;
|
|
26
|
+
onEdit?: () => void;
|
|
27
|
+
onRemove?: () => void;
|
|
28
|
+
/** Dims the card, drops it from the tab order and ignores selection; Edit and Remove still work. */
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
labels?: Partial<AddressCardLabels>;
|
|
31
|
+
"data-testid"?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Radiogroup of `AddressCard`s with a roving tab stop; arrow keys move focus and selection together. */
|
|
34
|
+
export interface AddressCardGroupProps {
|
|
35
|
+
value?: string;
|
|
36
|
+
defaultValue?: string;
|
|
37
|
+
onValueChange?: (value: string) => void;
|
|
38
|
+
/** Direct `AddressCard` children; wrapping them in another component hides their `value` from the roving tab stop. */
|
|
39
|
+
children: ReactNode;
|
|
40
|
+
"aria-label"?: string;
|
|
41
|
+
"aria-labelledby"?: string;
|
|
42
|
+
"data-testid"?: string;
|
|
43
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { BagBarProps } from "./BagBarProps";
|
|
2
|
+
/** Glass bar for the bag and checkout: total and price-details link left, the single primary action right. */
|
|
3
|
+
declare const BagBar: ({ total, note, onViewDetails, ctaLabel, onCta, ctaDisabled, ctaLoading, position, zIndex, currency, locale, labels, "data-testid": testId, }: BagBarProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export default BagBar;
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
const react_1 = require("@chakra-ui/react");
|
|
8
|
+
const lucide_react_1 = require("lucide-react");
|
|
9
|
+
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
10
|
+
const scrim_1 = require("../../Theme/tokens/builders/scrim");
|
|
11
|
+
const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
|
|
12
|
+
const motion_1 = require("../../Theme/tokens/primitives/motion");
|
|
13
|
+
const motion_2 = require("../../Theme/chakra/motion");
|
|
14
|
+
const price_1 = require("../../Utils/price");
|
|
15
|
+
const Button_1 = __importDefault(require("../Button/Button"));
|
|
16
|
+
const DEFAULT_LABELS = { region: "Bag total", total: "Total", viewDetails: "View price details", cta: "Place order" };
|
|
17
|
+
const GLASS_ALPHA = Math.round(0.86 * 255).toString(16);
|
|
18
|
+
const BLUR = "blur(20px) saturate(180%)";
|
|
19
|
+
const NO_BLUR_SUPPORT = "@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)))";
|
|
20
|
+
const SAFE_BOTTOM = "calc(0.75rem + env(safe-area-inset-bottom, 0px))";
|
|
21
|
+
/** Glass bar for the bag and checkout: total and price-details link left, the single primary action right. */
|
|
22
|
+
const BagBar = ({ total, note, onViewDetails, ctaLabel, onCta, ctaDisabled = false, ctaLoading = false, position = "static", zIndex = 10, currency, locale, labels, "data-testid": testId, }) => {
|
|
23
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
24
|
+
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
25
|
+
const sticky = position === "bottom";
|
|
26
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.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 ${(0, scrim_1.overlayScrim)(colors)}` : "none", "data-testid": testId, sx: { WebkitBackdropFilter: BLUR, [NO_BLUR_SUPPORT]: { backgroundColor: colors.surfaceRaised } }, children: [(0, jsx_runtime_1.jsxs)(react_1.Box, { minW: 0, children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "baseline", gap: 2, wrap: "wrap", children: [(0, jsx_runtime_1.jsx)(react_1.Text, { as: "span", fontSize: "xs", fontWeight: 600, color: colors.textMuted, children: copy.total }), (0, jsx_runtime_1.jsx)(react_1.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: (0, price_1.formatPrice)(total, { currency, locale }) })] }), note && ((0, jsx_runtime_1.jsx)(react_1.Text, { as: "span", display: "block", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: note })), onViewDetails && ((0, jsx_runtime_1.jsxs)(react_1.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: (0, motion_1.transitionFor)(["opacity"]), _hover: { opacity: 0.8 }, sx: {
|
|
27
|
+
...(0, focusRing_styles_1.focusVisibleStyles)(colors),
|
|
28
|
+
...(0, motion_2.reducedMotionSx)(),
|
|
29
|
+
"&::before": { content: '""', position: "absolute", inset: "-0.75rem -0.5rem" },
|
|
30
|
+
}, children: [copy.viewDetails, (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronUp, { size: 14, "aria-hidden": true })] }))] }), (0, jsx_runtime_1.jsx)(Button_1.default, { size: "lg", onClick: onCta, isDisabled: ctaDisabled, isLoading: ctaLoading, flexShrink: 0, children: ctaLabel !== null && ctaLabel !== void 0 ? ctaLabel : copy.cta })] }));
|
|
31
|
+
};
|
|
32
|
+
exports.default = BagBar;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PriceFormat } from "../Commerce/commerceTypes";
|
|
2
|
+
/** "static" flows in the page; "bottom" sticks to the bottom edge of its scroll container (CSS sticky, never fixed). */
|
|
3
|
+
export type BagBarPosition = "static" | "bottom";
|
|
4
|
+
/** Visible copy; override every string for another language. */
|
|
5
|
+
export interface BagBarLabels {
|
|
6
|
+
/** Accessible name of the bar landmark. */
|
|
7
|
+
region: string;
|
|
8
|
+
total: string;
|
|
9
|
+
viewDetails: string;
|
|
10
|
+
cta: string;
|
|
11
|
+
}
|
|
12
|
+
/** Mobile bottom bar: the payable total with a price-details link on the left and the one primary action on the right. */
|
|
13
|
+
export interface BagBarProps extends PriceFormat {
|
|
14
|
+
total: number;
|
|
15
|
+
/** Muted line beside the total, e.g. "Inclusive of all taxes". */
|
|
16
|
+
note?: string;
|
|
17
|
+
/** Shows the "View price details" link; use it to scroll to or open the breakdown. */
|
|
18
|
+
onViewDetails?: () => void;
|
|
19
|
+
/** Primary action label, e.g. "Place order" or "Checkout". */
|
|
20
|
+
ctaLabel?: string;
|
|
21
|
+
onCta?: () => void;
|
|
22
|
+
ctaDisabled?: boolean;
|
|
23
|
+
/** Spinner on the primary action while the order is being placed. */
|
|
24
|
+
ctaLoading?: boolean;
|
|
25
|
+
position?: BagBarPosition;
|
|
26
|
+
/** Stacking order when `position` is "bottom"; above page content, below dialogs by default. */
|
|
27
|
+
zIndex?: number;
|
|
28
|
+
labels?: Partial<BagBarLabels>;
|
|
29
|
+
"data-testid"?: string;
|
|
30
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CartItemProps } from "./CartItemProps";
|
|
2
|
+
/** One bag line: tonal thumbnail, linked title, chosen options, line total with struck MRP, stepper and calm text actions. */
|
|
3
|
+
declare const CartItem: ({ title, brand, href, onTitleClick, image, imageAlt, axes, selection, optionsSummary, price, mrp, quantity, onQuantityChange, minQuantity, maxQuantity, onRemove, onMoveToWishlist, stock, stockCount, stockMessage, deliveryBy, unavailable, layout, isLoading, currency, locale, labels, "data-testid": testId, }: CartItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export default CartItem;
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
const react_1 = require("@chakra-ui/react");
|
|
8
|
+
const lucide_react_1 = require("lucide-react");
|
|
9
|
+
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
10
|
+
const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
|
|
11
|
+
const motion_1 = require("../../Theme/tokens/primitives/motion");
|
|
12
|
+
const motion_2 = require("../../Theme/chakra/motion");
|
|
13
|
+
const price_1 = require("../../Utils/price");
|
|
14
|
+
const Button_1 = __importDefault(require("../Button/Button"));
|
|
15
|
+
const PriceBlock_1 = __importDefault(require("../PriceBlock/PriceBlock"));
|
|
16
|
+
const QuantityStepper_1 = __importDefault(require("../QuantityStepper/QuantityStepper"));
|
|
17
|
+
const Skeletons_1 = __importDefault(require("../Skeletons/Skeletons"));
|
|
18
|
+
const StockStatus_1 = __importDefault(require("../StockStatus/StockStatus"));
|
|
19
|
+
const cartItemOptions_1 = require("./cartItemOptions");
|
|
20
|
+
const DEFAULT_LABELS = {
|
|
21
|
+
moveToWishlist: "Move to wishlist",
|
|
22
|
+
remove: "Remove",
|
|
23
|
+
outOfStock: "Out of stock",
|
|
24
|
+
notIncluded: "Not included in your total",
|
|
25
|
+
quantity: (quantity) => `Qty ${quantity}`,
|
|
26
|
+
each: (price) => `${price} each`,
|
|
27
|
+
delivery: (date) => `Delivery by ${date}`,
|
|
28
|
+
};
|
|
29
|
+
const THUMB = {
|
|
30
|
+
row: { w: "5rem", h: "6.25rem", radius: "0.75rem" },
|
|
31
|
+
compact: { w: "3.5rem", h: "4.375rem", radius: "0.625rem" },
|
|
32
|
+
};
|
|
33
|
+
const DIMMED_MEDIA = 0.45;
|
|
34
|
+
const CartItemSkeleton = ({ layout }) => {
|
|
35
|
+
const thumb = THUMB[layout];
|
|
36
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.Flex, { gap: 3, align: "flex-start", "aria-busy": "true", "data-testid": "cart-item-skeleton", children: [(0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "skeleton", height: thumb.h, width: thumb.w, borderRadius: thumb.radius }), (0, jsx_runtime_1.jsxs)(react_1.Flex, { direction: "column", gap: 2, flex: 1, minW: 0, children: [(0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "skeleton", height: 3, width: "35%" }), (0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "skeleton", height: 4, width: "80%" }), (0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "skeleton", height: 3, width: "45%" }), layout === "row" && (0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "skeleton", height: 10, width: "100%", borderRadius: "full" })] })] }));
|
|
37
|
+
};
|
|
38
|
+
/** One bag line: tonal thumbnail, linked title, chosen options, line total with struck MRP, stepper and calm text actions. */
|
|
39
|
+
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, }) => {
|
|
40
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
41
|
+
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
42
|
+
const compact = layout === "compact";
|
|
43
|
+
const thumb = THUMB[layout];
|
|
44
|
+
const fmt = { currency, locale };
|
|
45
|
+
if (isLoading)
|
|
46
|
+
return (0, jsx_runtime_1.jsx)(CartItemSkeleton, { layout: layout });
|
|
47
|
+
const summary = optionsSummary !== null && optionsSummary !== void 0 ? optionsSummary : (0, cartItemOptions_1.summariseOptions)(axes, selection);
|
|
48
|
+
const lineTotal = price * quantity;
|
|
49
|
+
const lineMrp = mrp !== undefined ? mrp * quantity : undefined;
|
|
50
|
+
const titleInk = unavailable ? colors.textMuted : colors.header[900];
|
|
51
|
+
const titleProps = href
|
|
52
|
+
? { as: "a", href }
|
|
53
|
+
: onTitleClick
|
|
54
|
+
? { as: "button", type: "button", onClick: onTitleClick }
|
|
55
|
+
: { as: "span" };
|
|
56
|
+
const linked = !!href || !!onTitleClick;
|
|
57
|
+
const stepper = ((0, jsx_runtime_1.jsx)(QuantityStepper_1.default, { size: "sm", variant: "soft", value: quantity, min: minQuantity, max: maxQuantity, removable: !!onRemove, onRemove: onRemove, onValueChange: onQuantityChange, itemLabel: title }));
|
|
58
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.Flex, { gap: 3, align: "flex-start", "data-testid": testId, "data-unavailable": unavailable || undefined, children: [(0, jsx_runtime_1.jsx)(react_1.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 && (0, jsx_runtime_1.jsx)(react_1.Box, { as: "img", src: image, alt: imageAlt, w: "100%", h: "100%", objectFit: "cover", display: "block" }) }), (0, jsx_runtime_1.jsxs)(react_1.Flex, { direction: "column", flex: 1, minW: 0, gap: 1.5, children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { direction: "column", gap: 0.5, minW: 0, children: [brand && ((0, jsx_runtime_1.jsx)(react_1.Text, { as: "span", fontSize: "xs", fontWeight: 600, lineHeight: 1.4, color: colors.textMuted, noOfLines: 1, children: brand })), (0, jsx_runtime_1.jsx)(react_1.Text, { ...titleProps, display: "block", textAlign: "left", fontSize: "sm", fontWeight: 600, lineHeight: 1.4, color: titleInk, noOfLines: 2, borderRadius: "sm", cursor: linked ? "pointer" : undefined, transition: (0, motion_1.transitionFor)(["color"]), _hover: linked ? { textDecoration: "underline" } : undefined, sx: { ...(0, focusRing_styles_1.focusVisibleStyles)(colors), ...(0, motion_2.reducedMotionSx)() }, children: title }), summary && ((0, jsx_runtime_1.jsx)(react_1.Text, { as: "span", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: summary }))] }), unavailable ? ((0, jsx_runtime_1.jsxs)(react_1.Flex, { direction: "column", gap: 0.5, children: [(0, jsx_runtime_1.jsx)(StockStatus_1.default, { status: "out-of-stock", message: copy.outOfStock, size: "sm" }), (0, jsx_runtime_1.jsx)(react_1.Text, { as: "span", fontSize: "xs", color: colors.textMuted, children: copy.notIncluded })] })) : ((0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "flex-end", justify: "space-between", gap: 3, wrap: "wrap", children: [compact ? ((0, jsx_runtime_1.jsx)(react_1.Text, { as: "span", fontSize: "xs", color: colors.textMuted, sx: { fontVariantNumeric: "tabular-nums" }, children: copy.quantity(quantity) })) : (stepper), (0, jsx_runtime_1.jsx)(react_1.Box, { ml: "auto", children: (0, jsx_runtime_1.jsx)(PriceBlock_1.default, { size: compact ? "sm" : "md", align: "end", price: lineTotal, mrp: lineMrp, taxNote: quantity > 1 ? copy.each((0, price_1.formatPrice)(price, fmt)) : undefined, ...fmt }) })] })), !unavailable && !compact && stock && stock !== "in-stock" && ((0, jsx_runtime_1.jsx)(StockStatus_1.default, { status: stock, count: stockCount, message: stockMessage, size: "sm" })), !unavailable && deliveryBy && ((0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "center", gap: 1.5, color: colors.textMuted, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Truck, { size: 13, "aria-hidden": true }), (0, jsx_runtime_1.jsx)(react_1.Text, { as: "span", fontSize: "xs", lineHeight: 1.4, children: copy.delivery(deliveryBy) })] })), !compact && (onRemove || (onMoveToWishlist && !unavailable)) && ((0, jsx_runtime_1.jsxs)(react_1.Flex, { gap: 1, ml: -3, mt: 0.5, children: [onMoveToWishlist && !unavailable && ((0, jsx_runtime_1.jsx)(Button_1.default, { variant: "ghost", colorScheme: "gray", size: "sm", onClick: onMoveToWishlist, "aria-label": `${copy.moveToWishlist}: ${title}`, children: copy.moveToWishlist })), onRemove && ((0, jsx_runtime_1.jsx)(Button_1.default, { variant: "ghost", colorScheme: "gray", size: "sm", onClick: onRemove, "aria-label": `${copy.remove}: ${title}`, children: copy.remove }))] }))] })] }));
|
|
59
|
+
};
|
|
60
|
+
exports.default = CartItem;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { OptionAxis, PriceFormat, StockState, VariantSelection } from "../Commerce/commerceTypes";
|
|
2
|
+
/** Row is the full bag line with controls; compact is read-only for a mini-bag or order review. */
|
|
3
|
+
export type CartItemLayout = "row" | "compact";
|
|
4
|
+
/** Every visible string; override for another language. */
|
|
5
|
+
export interface CartItemLabels {
|
|
6
|
+
moveToWishlist: string;
|
|
7
|
+
remove: string;
|
|
8
|
+
/** Shown instead of the price when `unavailable`. */
|
|
9
|
+
outOfStock: string;
|
|
10
|
+
/** Muted line under the out-of-stock state. */
|
|
11
|
+
notIncluded: string;
|
|
12
|
+
/** Compact layout quantity text, given the quantity. */
|
|
13
|
+
quantity: (quantity: number) => string;
|
|
14
|
+
/** Muted unit price under a multi-unit line total, given the formatted unit price. */
|
|
15
|
+
each: (price: string) => string;
|
|
16
|
+
/** Delivery line, given `deliveryBy`. */
|
|
17
|
+
delivery: (date: string) => string;
|
|
18
|
+
}
|
|
19
|
+
/** One bag line: thumbnail, title, chosen options, line total, quantity and actions. Totals are computed here, so pass unit prices. */
|
|
20
|
+
export interface CartItemProps extends PriceFormat {
|
|
21
|
+
title: string;
|
|
22
|
+
brand?: string;
|
|
23
|
+
/** Makes the title a link to the product page. */
|
|
24
|
+
href?: string;
|
|
25
|
+
/** Makes the title a button when there is no `href`, for client-side routing. */
|
|
26
|
+
onTitleClick?: () => void;
|
|
27
|
+
/** Product image URL, shown 4:5. */
|
|
28
|
+
image?: string;
|
|
29
|
+
/** Empty by default: the title beside the image already names it. */
|
|
30
|
+
imageAlt?: string;
|
|
31
|
+
/** With `selection`, builds the "Indigo Wash · M" line from the chosen option labels. */
|
|
32
|
+
axes?: OptionAxis[];
|
|
33
|
+
selection?: VariantSelection;
|
|
34
|
+
/** Replaces the line built from `axes` and `selection`. */
|
|
35
|
+
optionsSummary?: string;
|
|
36
|
+
/** Selling price of one unit; the line total is `price * quantity`. */
|
|
37
|
+
price: number;
|
|
38
|
+
/** List price of one unit; the strike only shows when it is above `price`. */
|
|
39
|
+
mrp?: number;
|
|
40
|
+
quantity: number;
|
|
41
|
+
onQuantityChange?: (quantity: number) => void;
|
|
42
|
+
/** Lowest quantity; at this value the minus becomes a trash button when `onRemove` is set. */
|
|
43
|
+
minQuantity?: number;
|
|
44
|
+
/** Highest quantity, usually the stock on hand. */
|
|
45
|
+
maxQuantity?: number;
|
|
46
|
+
onRemove?: () => void;
|
|
47
|
+
/** Adds the "Move to wishlist" action. */
|
|
48
|
+
onMoveToWishlist?: () => void;
|
|
49
|
+
/** Availability line under the price, e.g. low-stock. Omit for in-stock lines. */
|
|
50
|
+
stock?: StockState;
|
|
51
|
+
/** Units left, shown for `low-stock`. */
|
|
52
|
+
stockCount?: number;
|
|
53
|
+
/** Replaces the default stock words. */
|
|
54
|
+
stockMessage?: string;
|
|
55
|
+
/** Pre-formatted date, e.g. "Thu, 9 Oct"; rendered as "Delivery by Thu, 9 Oct". */
|
|
56
|
+
deliveryBy?: string;
|
|
57
|
+
/** Dims the image, drops price and stepper and keeps only Remove. */
|
|
58
|
+
unavailable?: boolean;
|
|
59
|
+
layout?: CartItemLayout;
|
|
60
|
+
/** Skeleton of the same shape; actions are not rendered. */
|
|
61
|
+
isLoading?: boolean;
|
|
62
|
+
labels?: Partial<CartItemLabels>;
|
|
63
|
+
"data-testid"?: string;
|
|
64
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { OptionAxis, VariantSelection } from "../Commerce/commerceTypes";
|
|
2
|
+
/** "Indigo Wash · M" from the chosen option labels, in axis order; axes with no pick are skipped. */
|
|
3
|
+
export declare const summariseOptions: (axes: OptionAxis[] | undefined, selection: VariantSelection | undefined) => string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.summariseOptions = void 0;
|
|
4
|
+
/** "Indigo Wash · M" from the chosen option labels, in axis order; axes with no pick are skipped. */
|
|
5
|
+
const summariseOptions = (axes, selection) => {
|
|
6
|
+
if (!axes || !selection)
|
|
7
|
+
return "";
|
|
8
|
+
return axes
|
|
9
|
+
.map((axis) => { var _a; return (_a = axis.values.find((value) => value.id === selection[axis.id])) === null || _a === void 0 ? void 0 : _a.label; })
|
|
10
|
+
.filter((label) => !!label)
|
|
11
|
+
.join(" · ");
|
|
12
|
+
};
|
|
13
|
+
exports.summariseOptions = summariseOptions;
|