Card Stack
betaA pile of cards you step through as a receding deck, or that fans out into an arc on hover and focus.
- Display
- 2 files
- 1 npm package
- Accessibility notes
Loading the example…
pnpm dlx @dowel-ui/cli add card-stacknpm packages installed: class-variance-authority.
import { CardStack } from "@/components/ui/card-stack";Default
Gallery
Fan
Fan With Six Cards
Fan Forced Open
Deck Starting On Third
<CardStack>
| Prop | Type | Default |
|---|---|---|
children (required)One card per child. | ReactNode | — |
defaultIndex
| number | — |
getCardLabel
| (index: number, count: number) => string | — |
index
| number | — |
onIndexChange
| (index: number) => void | — |
open
| boolean | — |
scatter
| number | — |
spread
| number | — |
variant | "deck" | "fan" | "deck" |
Plus every attribute of <div>.
The deck is a carousel region (aria-roledescription="carousel") of labelled slides; only the top card is exposed — the others are aria-hidden and inert. Indicator dots are buttons with a roving tabindex and aria-current; arrow keys (mirrored in right-to-left layouts), Home and End step the deck and move focus with it, and a polite status region announces the new card. Wheel and swipe are conveniences on top of that, and the wheel releases the page at either end. The fan is a labelled list that opens on focus as well as hover; its motion is decoration and settles instantly under reduced motion.
10/10
checks passed
- Tested — passes
- axe assertion — passes
- Keyboard tested — passes
- Storybook examples — passes
- Accessibility documented — passes
- Semantic tokens only — passes
- Motion from tokens — passes
- className merged — passes
- Visible focus — passes
- No fixed widths — passes