Variant pickerPro
Size, color and options with stock per combination, a price that follows the variant and a back in stock note.
On this page
ProColor and size with stock per combination: switch colors and watch the sizes change.
Installation
Usage
import { VariantPicker } from "@/components/ui/chatcn/pro/variant-picker"
<VariantPicker
groups={[
{ name: "Color", options: [{ value: "moss", label: "Moss", swatch: "#6b8f7a" }] },
{ name: "Size (EU)", options: [{ value: "42", label: "42" }] },
]}
variants={[{ options: { Color: "moss", "Size (EU)": "42" }, stock: 2 }]}
price={131}
onAdd={(selection) => cart.add(selection)}
onNotify={(selection) => alerts.add(selection)}
/>Availability is worked out per combination: an option is sold out only when nothing that fits the other picks is in stock, so picking a color strikes through exactly the sizes gone in that color. Options at or under lowStockAt show how many are left under the label (swatches get a small amber dot). A sold out combination can still be picked, because people want to know; the button then becomes a back in stock note. The price rolls to the exact variant's price when variants differ.
Examples
States
ProNothing picked, a sold out combination, a failed add and disabled.
Props
| Prop | Type | Notes |
|---|---|---|
groups | { name, options: { value, label, swatch? }[] }[] | Swatches when any option has one |
variants | { options, stock, price? }[] | Every buyable combination |
price | number | Used when a variant has no price |
currency, locale | string | Prices format with Intl, tabular figures. Default USD, en-US |
selection, defaultSelection, onSelectionChange | Record<string, string> | By group name |
lowStockAt | number | Default 3 |
onAdd, onNotify | (selection) => unknown | Promise<unknown> | Reject to show the error |
disabled | boolean | Locks every group |
labels | Partial<VariantPickerLabels> | Every string, for translation |
Keyboard
| Key | Action |
|---|---|
| Tab | Into each group, then the button |
| Arrow keys | Move within a group (native radios) |
Accessibility
- Each group is a fieldset with a legend that also names the current pick.
- Options are native radios named with sold out or how many are left.
- The stock line is a polite live region, so a new pick announces its availability.
Motion
Selection rings fade in 150 ms; the price rolls changed digits in 300 ms. Nothing moves under reduced motion except the fades.