All components (204)
Variant picker
Choice · VariantPicker · .amset-variants
What it is and when to use it
The metal and the size (or the color and the size) of a product, with availability checked crosswise: size 14 may be left in white gold and sold out in yellow gold. Below, it says how the chosen combination stands: "In stock", "2 units left", "Sold out in this combination" or "Choose size".
When to use it
- On the page of a product with variants, above the quantity and the add to cart button.
- What is sold out is shown struck through, it is said, and it can still be chosen: choosing it is how you get to "notify me when it is back".
- What exists but not with what is chosen (rose gold is not made in size 16) appears dimmed and, when chosen, drops the size and asks to choose it again. Only what is not in any variant disappears from the path.
kind: 'color'on an axis draws round swatches with the color ofsample;'text'(default) draws buttons with the label.size: buttons 30, 36 (default) or 44 px tall, like the controls, and swatches of 24, 32 or 40 px.disabledlets you see what is chosen without letting you change it (while the product loads, for example).
When not to
- A single option that does not depend on another:
RadioGroup, orSegmentedGroupif it applies instantly. - The quantity:
QuantityPicker, below this one.
Keyboard: each axis is a radio group: it is entered with Tab and moved through with the arrow keys, which move and choose at once. The arrow keys also reach what is sold out and what does not match the chosen option.
Accessibility: each axis is a radiogroup named with its name and what is chosen ("Metal: Yellow gold"). Each option states its status in words ("14, sold out in yellow gold", "Rose gold, unavailable in 16"), and color swatches are named by their color, because a circle cannot be read aloud. The stock line is a role="status": it is announced when it changes. Focus is the 2 px ring of the buttons, outside the option. With a mouse, nothing goes below 24 px; with a finger, options and swatches measure at least 44 px.
States: chosen (accent border and soft fill on the buttons; ring in ink on the swatches), sold out (struck through), no combination (dashed border and dimmed swatch), disabled (gray, with the chosen one still marked) and focus. What does not exist in any variant does not appear.
Motion: borders, fills and rings change with a short transition; the swatch grows when pointed at and gives way when pressed, like the button; the stock text enters sliding down a little each time it changes.
Fine-tuning: CSS variables --amset-variants-height, --amset-variants-padding, --amset-variants-font and --amset-variants-radius (the buttons), --amset-variants-name (the name of the axis), --amset-variants-sample (the circle), --amset-variants-ring and --amset-variants-gap (the ring of the chosen one and its gap), --amset-variants-border, --amset-variants-selected, --amset-variants-selected-background, --amset-variants-selected-ink and --amset-variants-ring-color (colors) and --amset-variants-slot (between options). The state classes are amset-variants__option--soldout, --no-combo and --not-found.
What it looks like
In stock
<VariantPicker
axes={ejes}
variants={variantes}
value={eleccion}
onChange={setEleccion}
/>Props
Import it with import { VariantPicker } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
axesrequired | readonly VariantAxis[] | — |
onChangerequired | (selection: Selection) => void | — |
valuerequired | Readonly<Record<string, string>> | — |
variantsrequired | readonly ProductVariant[] | — |
className | string | Merged with the library classes; it does not replace them. |
disabled | boolean | What is chosen is visible but cannot be changed: while the product loads. |
size | "sm" | "md" | "lg" | Buttons 30, 36 (the default) or 44 px tall and swatches 24, 32 or 40 px. With a finger, nothing goes below 44 px. |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-variants-height | var(--amset-height-control) |
--amset-variants-padding | var(--amset-space-3) |
--amset-variants-font | var(--amset-text-sm) |
--amset-variants-name | var(--amset-text-sm) |
--amset-variants-radius | var(--amset-radius) |
--amset-variants-sample | 2rem |
--amset-variants-ring | 2px |
--amset-variants-gap | 2px |
--amset-variants-border | var(--amset-border-bold) |
--amset-variants-selected | var(--amset-accent) |
--amset-variants-selected-background | var(--amset-accent-soft) |
--amset-variants-selected-ink | var(--amset-accent-text) |
--amset-variants-ring-color | var(--amset-ink) |
--amset-variants-slot | var(--amset-space-2) |
How to change it
.amset-variants {
--amset-variants-height: ...;
--amset-variants-padding: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
