Fernworks
Harbour tote
Waxed canvas · leather patch
£48
ColourMoss
SizeDaily · 14 l
KQ-1278 · SWATCH/CARD
A product card whose drawn tote takes the colour you choose: a swatch floods the bag with the new dye from where that swatch sits, a liquid front whose edge sloshes mid-flood on a tween, while one ring slides to the swatch on springs.snap and the swatch dips and lands on recoil. The price rolls its digit columns on snap, sizes a colour does not come in shrink to struck chips as the rest glide wider, the drawing grows to the chosen size about its base on glide, and Add to bag morphs into a quantity stepper whose buttons slide in from the middle on snap. Colours and sizes are radio groups with a roving tabindex, and focus follows the morph to the stepper and back.
Fernworks
Waxed canvas · leather patch
£48
ColourMoss
SizeDaily · 14 l
Moss · Daily · £48 · not in bag
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/swatch-card
| Prop | Type | Default | Description |
|---|---|---|---|
| swatches | ProductSwatch[] | defaultSwatches | The colours on offer: id, label, CSS colour, price, and the size ids each comes in. |
| value / defaultValue | string | the first swatch | The chosen colour id, controlled or initial. |
| onValueChange | (id: string) => void | — | Fires from the swatch press or arrow key that chose a colour. |
| sizes | ProductSize[] | defaultSizes | The sizes on offer, smallest first: id, label, note, the drawing's scale, and a price difference. |
| selectedSize / defaultSelectedSize | string | the middle size | The chosen size id, controlled or initial. |
| onSelectedSizeChange | (id: string) => void | — | Fires from the size press, or from a colour press that does not come in the chosen size. |
| quantity / defaultQuantity | number | 0 | How many are in the bag; 0 shows Add to bag. |
| onQuantityChange | (quantity: number) => void | — | Fires from Add to bag, the stepper, or remove, with the new quantity. |
| maxQuantity | number | 9 | The most the stepper allows. |
| brand | string | "Fernworks" | The maker, above the name. |
| name | string | "Harbour tote" | The product's name: the card's heading. |
| detail | string | "Waxed canvas · leather patch" | A line under the name. |
| format | (price: number) => string | whole pounds, en-GB | How a price is printed. |
| wipe | number | 0.5 | How liquid the dye front is, 0 to 1: a clean circle, or an edge that sloshes as it floods. |
| wipeDuration | number | 560 | How long the dye takes to flood the product, in ms. |
| shade | number | 0.6 | How much the drawing is modelled, 0 to 1: flat colour, or deep folds and highlights. |
| stepper | boolean | true | Adding morphs into a quantity stepper; off, it becomes an In bag toggle. |
| addLabel | string | "Add to bag" | The add button's text. |
| inBagLabel | string | "in bag" | After the quantity in the stepper, and the toggle's pressed text. |
| headingLevel | 2 | 3 | 4 | 3 | The heading's level. |
| sound | boolean | false | A plip for each colour pitched by its place in the row, a pop for each change to the bag. |
| disabled | boolean | false | Locks every choice and dims the card. |
| className | string | — | Classes for the article. |