Skip to content
Sign in
CommerceVariant pickerMenu

Variant pickerPro

Size, color and options with stock per combination, a price that follows the variant and a back in stock note.

ProColor and size with stock per combination: switch colors and watch the sizes change.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/variant-picker

Usage

tsx
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

PropTypeNotes
groups{ name, options: { value, label, swatch? }[] }[]Swatches when any option has one
variants{ options, stock, price? }[]Every buyable combination
pricenumberUsed when a variant has no price
currency, localestringPrices format with Intl, tabular figures. Default USD, en-US
selection, defaultSelection, onSelectionChangeRecord<string, string>By group name
lowStockAtnumberDefault 3
onAdd, onNotify(selection) => unknown | Promise<unknown>Reject to show the error
disabledbooleanLocks every group
labelsPartial<VariantPickerLabels>Every string, for translation

Keyboard

KeyAction
TabInto each group, then the button
Arrow keysMove 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.