diff --git a/CHANGELOG.md b/CHANGELOG.md index 99b6f5ba9..d0a0cbde6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Added + +- Prop `hideUnavailableVariations` that enables hiding unavailable variations from DOM + ## [3.176.1] - 2024-11-08 ## [3.176.0] - 2024-11-06 diff --git a/docs/SKUSelector.md b/docs/SKUSelector.md index ff58a6cb5..2f8040181 100644 --- a/docs/SKUSelector.md +++ b/docs/SKUSelector.md @@ -64,6 +64,7 @@ The `sku-selector` block is mainly used in Product Details Pages (PDPs) to displ | `variationsSpacing` | `number` | Defines the `margin-bottom` size to be applied in the rendered product variations. Possible values range from `0` to `11` (the prop value is not in `px`; every value represents a tachyon class). | `7` | | `visibility` | `enum` | Defines the scenarios in which the SKU selector should be displayed. Possible values are: `always` (it will always be displayed, even if the product has only one SKU option) or `more-than-one` (the SKU selector is only displayed when the product has more than one SKU option). | `always` | | `visibleVariations` | `array` | Specifies which product variations should be displayed on the product details page. Please note that no variations will be displayed if you declare a name that does not represent a real product variation or an empty array. There is more information regarding this prop structure below this table. | `undefined` | +| `hideUnavailableVariations`|`boolean`| When this prop is set to `true` all unavailable variations will not be rendered.|`false`| - **`visibleVariations` props** diff --git a/react/components/SKUSelector/Wrapper.tsx b/react/components/SKUSelector/Wrapper.tsx index 6ca6e15be..b8e17f199 100644 --- a/react/components/SKUSelector/Wrapper.tsx +++ b/react/components/SKUSelector/Wrapper.tsx @@ -170,6 +170,7 @@ interface Props { sliderArrowSize?: number sliderItemsPerPage?: ResponsiveValuesTypes.ResponsiveValue sortVariationsByLabel?: boolean + hideUnavailableVariations?: boolean /** Used to override default CSS handles */ classes?: CssHandlesTypes.CustomClasses } @@ -262,6 +263,7 @@ function SKUSelectorWrapper(props: Props) { sliderArrowSize={props.sliderArrowSize} sliderDisplayThreshold={props.sliderDisplayThreshold} sortVariationsByLabel={props.sortVariationsByLabel} + hideUnavailableVariations={props.hideUnavailableVariations} /> ) diff --git a/react/components/SKUSelector/components/SKUSelector.tsx b/react/components/SKUSelector/components/SKUSelector.tsx index 479cb5c2d..6ad272ea2 100644 --- a/react/components/SKUSelector/components/SKUSelector.tsx +++ b/react/components/SKUSelector/components/SKUSelector.tsx @@ -68,6 +68,7 @@ interface Props { sliderArrowSize: number sliderItemsPerPage: ResponsiveValuesTypes.ResponsiveValue sortVariationsByLabel?: boolean + hideUnavailableVariations?: boolean } function isSkuAvailable(item?: SelectorProductItem) { @@ -360,6 +361,7 @@ function SKUSelector({ sliderArrowSize, sliderItemsPerPage, sortVariationsByLabel = false, + hideUnavailableVariations, }: Props) { const { handles } = useSKUSelectorCssHandles() const variationsSpacing = getValidMarginBottom(marginBottomProp) @@ -454,6 +456,7 @@ function SKUSelector({ sliderDisplayThreshold={sliderDisplayThreshold} sliderArrowSize={sliderArrowSize} sliderItemsPerPage={sliderItemsPerPage} + hideUnavailableVariations={hideUnavailableVariations} /> ) })} diff --git a/react/components/SKUSelector/components/Variation.tsx b/react/components/SKUSelector/components/Variation.tsx index 673b02efe..4e5541750 100644 --- a/react/components/SKUSelector/components/Variation.tsx +++ b/react/components/SKUSelector/components/Variation.tsx @@ -33,6 +33,7 @@ interface Props { sliderDisplayThreshold: number sliderArrowSize: number sliderItemsPerPage: ResponsiveValuesTypes.ResponsiveValue + hideUnavailableVariations?: boolean } const ITEMS_VISIBLE_THRESHOLD = 2 @@ -60,8 +61,13 @@ const Variation: FC = ({ sliderArrowSize, sliderDisplayThreshold, sliderItemsPerPage, + hideUnavailableVariations, }) => { - const { originalName, name, options } = variation + const { originalName, name, options: initialOptions } = variation + + const options = hideUnavailableVariations + ? initialOptions.filter(option => option.available) + : [...initialOptions] const visibleItemsWhenCollapsed = maxItems - ITEMS_VISIBLE_THRESHOLD @@ -88,6 +94,11 @@ const Variation: FC = ({ ) const showAllAction = useCallback(() => setShowAll(true), [setShowAll]) + + if (options.length === 0) { + return null + } + const containerClasses = classnames( 'flex flex-column', containerClassesProp, diff --git a/react/components/SKUSelector/index.tsx b/react/components/SKUSelector/index.tsx index 3e562cdde..9728d9f01 100644 --- a/react/components/SKUSelector/index.tsx +++ b/react/components/SKUSelector/index.tsx @@ -187,6 +187,7 @@ interface Props { sliderArrowSize?: number sliderItemsPerPage?: ResponsiveValuesTypes.ResponsiveValue sortVariationsByLabel?: boolean + hideUnavailableVariations?: boolean } const getNewSelectedVariations = ( @@ -254,6 +255,7 @@ const SKUSelectorContainer: FC = ({ tablet: 2, phone: 1, }, + hideUnavailableVariations = false, }) => { const productContext = useProduct() const selectedItem = productContext?.selectedItem @@ -425,6 +427,7 @@ const SKUSelectorContainer: FC = ({ sliderArrowSize={sliderArrowSize} sliderItemsPerPage={sliderItemsPerPage} sortVariationsByLabel={sortVariationsByLabel} + hideUnavailableVariations={hideUnavailableVariations} /> ) }