Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions components/product/variant-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function VariantSelector({
}) {
const { state, updateOption } = useProduct();
const updateURL = useUpdateURL();

const hasNoOptionsOrJustOneOption =
!options.length || (options.length === 1 && options[0]?.values.length === 1);

Expand All @@ -43,20 +44,30 @@ export function VariantSelector({
{option.values.map((value) => {
const optionNameLowerCase = option.name.toLowerCase();

// Base option params on current selectedOptions so we can preserve any other param state.
const optionParams = { ...state, [optionNameLowerCase]: value };
// For checking availability, we only consider the current option being changed
// and any other selected options that differ from this one
const testParams = { ...state, [optionNameLowerCase]: value };

// Filter out invalid options and check if the option combination is available for sale.
const filtered = Object.entries(optionParams).filter(([key, value]) =>
options.find(
(option) => option.name.toLowerCase() === key && option.values.includes(value)
)
);
const isAvailableForSale = combinations.find((combination) =>
filtered.every(
([key, value]) => combination[key] === value && combination.availableForSale
)
);
// Find if there's any variant available with this specific option value
// We check if at least one combination exists where:
// 1. This option has the selected value
// 2. The variant is available for sale
const isAvailableForSale = combinations.some((combination) => {
// Check if this combination has the option value we're testing
if (combination[optionNameLowerCase] !== value) {
return false;
}

// Check if the combination is available for sale
if (!combination.availableForSale) {
return false;
}

// For multi-option products, check if there's a valid path:
// A value is clickable if there exists at least one valid combination
// where this option has this value
return true;
});

// The option is active if it's in the selected options.
const isActive = state[optionNameLowerCase] === value;
Expand Down