KQ-1278 · SWATCH/CARD

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.

KQ-1278 · SWATCH/CARD

Fernworks

Harbour tote

Waxed canvas · leather patch

£48

ColourMoss

SizeDaily · 14 l

Moss · Daily · £48 · not in bag

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/swatch-card

Props

swatches
ProductSwatch[]
default defaultSwatches
The colours on offer: id, label, CSS colour, price, and the size ids each comes in.
value / defaultValue
string
default the first swatch
The chosen colour id, controlled or initial.
onValueChange
(id: string) => void
default —
Fires from the swatch press or arrow key that chose a colour.
sizes
ProductSize[]
default defaultSizes
The sizes on offer, smallest first: id, label, note, the drawing's scale, and a price difference.
selectedSize / defaultSelectedSize
string
default the middle size
The chosen size id, controlled or initial.
onSelectedSizeChange
(id: string) => void
default —
Fires from the size press, or from a colour press that does not come in the chosen size.
quantity / defaultQuantity
number
default 0
How many are in the bag; 0 shows Add to bag.
onQuantityChange
(quantity: number) => void
default —
Fires from Add to bag, the stepper, or remove, with the new quantity.
maxQuantity
number
default 9
The most the stepper allows.
brand
string
default "Fernworks"
The maker, above the name.
name
string
default "Harbour tote"
The product's name: the card's heading.
detail
string
default "Waxed canvas · leather patch"
A line under the name.
format
(price: number) => string
default whole pounds, en-GB
How a price is printed.
wipe
number
default 0.5
How liquid the dye front is, 0 to 1: a clean circle, or an edge that sloshes as it floods.
wipeDuration
number
default 560
How long the dye takes to flood the product, in ms.
shade
number
default 0.6
How much the drawing is modelled, 0 to 1: flat colour, or deep folds and highlights.
stepper
boolean
default true
Adding morphs into a quantity stepper; off, it becomes an In bag toggle.
addLabel
string
default "Add to bag"
The add button's text.
inBagLabel
string
default "in bag"
After the quantity in the stepper, and the toggle's pressed text.
headingLevel
2 | 3 | 4
default 3
The heading's level.
sound
boolean
default false
A plip for each colour pitched by its place in the row, a pop for each change to the bag.
disabled
boolean
default false
Locks every choice and dims the card.
className
string
default —
Classes for the article.