import type { OptionAxis, ProductVariant, VariantSelection } from "../Commerce/commerceTypes"; import type { OptionChipSize } from "../OptionChip/OptionChipProps"; /** How an axis lays out its options: wrapping rows, one horizontal scroller, or an even grid (which also prints swatch names). */ export type VariantSelectorLayout = "wrap" | "scroll" | "grid"; /** Config-driven option picker for any product vertical; every axis label and value comes from `axes`. */ export interface VariantSelectorProps { /** One radiogroup per axis, in order. */ axes: OptionAxis[]; /** Availability is derived per combination from these variants' stock. */ variants: ProductVariant[]; /** Controlled selection, axis id to option value id. */ value?: VariantSelection; /** Initial selection when uncontrolled; ignored once `value` is passed. */ defaultValue?: VariantSelection; /** Receives the new selection and the matching variant, or undefined while the selection is incomplete or has no variant. */ onValueChange?: (selection: VariantSelection, variant: ProductVariant | undefined) => void; /** Prompt such as "Select a size": shown as a status message and rings every axis still unpicked. */ error?: string; /** Prints the picked value beside each axis label ("Colour Indigo Wash"). */ showSelectedLabel?: boolean; /** Tags a value "N left" only when its real remaining stock is at or under LOW_STOCK_THRESHOLD. */ showLowStock?: boolean; /** Size of every option chip. Defaults to "md". */ size?: OptionChipSize; /** How each axis arranges its options. Defaults to "wrap". */ layout?: VariantSelectorLayout; /** Also called when an axis `guide` link is clicked, after the guide's own onClick. */ onGuideClick?: (axisId: string) => void; /** Test id placed on the root element. */ "data-testid"?: string; }