KQ-1849 · CARTWHEEL/DECK
Cartwheel Deck
A row of cards standing on a floor, front card at the left and each further card a little smaller. Advancing sends the front card cartwheeling end over end along the floor to the back: it turns whole turns while it travels, always resting on its lowest corner so it rises onto each corner and drops onto each edge, shrinking to the back card's size, with a floor shadow as wide as its projection; it lands upright with a squash on the recoil spring, a hop sized by bounce and a thud, while the rest shuffle forward on springs.glide in a short cascade. The tumble runs on the glide calibration retimed to the duration, so a card tipped by hand carries its throw into it; Right, Enter and Space advance, Left reverses the tumble, and Home and End tumble through to the first and last card.
Coldbrook Tea
Five teas to taste
Ember Oolong
Roasted · 4 min
Click, or press Right, Enter or Space, to send the front card to the back; Left brings the back card to the front. Home and End go to the first and last card. The front card is Ember Oolong.
Ember Oolong · 1 of 5 · Roasted · 4 min · next: Harbour Black
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/cartwheel-deck
Props
- items
- CartwheelCard[]
- default defaultCartwheelCards
- The cards, front to back: { src?, alt, caption?, detail?, art? }.
- value / defaultValue
- number
- default 0
- The card at the front; controlled or initial.
- onValueChange
- (index: number) => void
- default —
- Fires from the click, swipe or key that moved the deck, with the new front card.
- spin
- number
- default 1
- Whole turns a card makes on its way to the back, 1 to 3.
- bounce
- number
- default 0.5
- How lively the landing is, 0 (lands dead) to 1 (hops twice).
- gap
- number
- default 14
- Space between cards when the row fits, px; a narrow row overlaps them evenly instead.
- depth
- number
- default 0.08
- How much smaller each card further back stands, 0 to 0.2 of the front card.
- duration
- number
- default 640
- Roughly how long one tumble takes at one turn, ms.
- aspect
- number
- default 0.72
- A card's width as a share of its height.
- height
- number
- default 240
- Height of the stage, px; the cards are sized so a tumbling card always clears its top.
- shadow
- boolean
- default true
- Shadows on the floor that stretch as a card turns.
- label
- string
- default "Cards"
- The deck's accessible name.
- sound
- boolean
- default false
- Play a thud as each card lands. Off unless asked for.
- disabled
- boolean
- default false
- No clicks, swipes or keys; the deck dims.
- className
- string
- default —
- Classes for the root region.
| Prop | Type | Default | Description |
|---|---|---|---|
| items | CartwheelCard[] | defaultCartwheelCards | The cards, front to back: { src?, alt, caption?, detail?, art? }. |
| value / defaultValue | number | 0 | The card at the front; controlled or initial. |
| onValueChange | (index: number) => void | — | Fires from the click, swipe or key that moved the deck, with the new front card. |
| spin | number | 1 | Whole turns a card makes on its way to the back, 1 to 3. |
| bounce | number | 0.5 | How lively the landing is, 0 (lands dead) to 1 (hops twice). |
| gap | number | 14 | Space between cards when the row fits, px; a narrow row overlaps them evenly instead. |
| depth | number | 0.08 | How much smaller each card further back stands, 0 to 0.2 of the front card. |
| duration | number | 640 | Roughly how long one tumble takes at one turn, ms. |
| aspect | number | 0.72 | A card's width as a share of its height. |
| height | number | 240 | Height of the stage, px; the cards are sized so a tumbling card always clears its top. |
| shadow | boolean | true | Shadows on the floor that stretch as a card turns. |
| label | string | "Cards" | The deck's accessible name. |
| sound | boolean | false | Play a thud as each card lands. Off unless asked for. |
| disabled | boolean | false | No clicks, swipes or keys; the deck dims. |
| className | string | — | Classes for the root region. |