Product Variants
Product variants provide a way for a product to be customised in some way by the end user. A product may have one or many variants, and each variant has a distinct article number associated with it. Examples of variants are product colors or sizes. Variants may also have their own price, image, and stock status.
useProductVariants
To simplify working with variants, the Flight framework provides a useProductVariants
hook, found at @jetshop/core/hooks/useProductVariants
.
Given a product, this hook provides methods for getting and setting variant values on that product, as well as methods to validate the current and proposed combination of values.
const {
selectedVariant,
validation,
getSelectedValue,
selectValue,
validateSelection,
getVariantForSelection,
missingOptions,
} = useProductVariants(product, options);
Arguments
Argument | Type | Required? | Description |
---|---|---|---|
product |
Product |
true | The product that you are acting on |
options |
Options | false | Additional options |
Options
Option | Type | Description |
---|---|---|
initialVariant |
ProductVariant | This can be used if you would like a variant to be selected when the hook is first run. |
preselectCheapest |
boolean | Will preselect the cheapest combination availiable. If passed both initialVariant and preselectCheapest , then initialVariant will have priority to be preselected. |
Result
Property | Type | Description | |||
---|---|---|---|---|---|
selectedVariant | ProductVariant | The currently selected ProductVariant |
|||
validation | 'outOfStock' | 'valid' | 'incomplete' | 'invalid' |
The validation state of the currently selected ProductVariant |
|||
getSelectedValue | (option: ProductVariantOption) => string | Given a ProductVariantOption , returns the currently selected value for that option |
|||
selectValue | (value: string, option: ProductVariantOption) => void | Selects the value for the given option |
|||
validateSelection | (value: string, option: ProductVariantOption) => 'outOfStock' | 'valid' | 'incomplete' | 'invalid' |
Given a value and an option, returns the validation state if that value was selected | |||
getVariantForSelection | (value: string, option: ProductVariantOption) => ProductVariant | Given a value and an option, returns the final ProductVariant if that value was selected | |||
missingOptions | ProductVariantOption[] | Any options that do not yet have a value selected |
Examples
const {
selectedVariant,
selectValue,
getSelectedValue,
validation,
validateSelection,
getVariantForSelection,
missingOptions,
} = useProductVariants(product);
return (
<div>
<h1>{product.name}</h1>
{product.variants.options.map((option) => {
return (
<div key={option.name}>
<label>{option.name}</label>
<ul style={{ listStyle: "none" }}>
{option.values.map((value) => {
const variant = getVariantForSelection(value, option);
return (
<li key={value}>
<button
style={{
color:
getSelectedValue(option) === value ? "red" : "black",
}}
onClick={() => selectValue(value, option)}
>
{value}
</button>
<span style={{ fontSize: "0.75em" }}>
Selecting this value will result in:{" "}
{validateSelection(value, option)} -{" "}
{variant && variant.articleNumber}
</span>
</li>
);
})}
</ul>
</div>
);
})}
{selectedVariant && <div>selectedVariant.articleNumber</div>}
{validation && <div>{validation}</div>}
{missingOptions && (
<div>
<label>Missing options:</label>
{missingOptions.map((option) => (
<span style={{ paddingLeft: "1em" }}>{option.name}</span>
))}
</div>
)}
</div>
);