- Accordion
- Action Bar
- Action Toast
- Alert Banner
- Alert Dialog
- Alert
- Alphabet Index
- Amount Field
- Aspect Ratio
- Attachment
- Availability List
- Avatar
- Badge
- Bank Card
- Breadcrumb
- Bubble
- Button Group
- Button
- Calendar
- Camera Frame
- Card Design Picker
- Card Details
- Card Peek
- Card Stack
- Card
- Carousel
- Chart
- Chat Thread
- Checkbox
- Chip Group
- Choice Tile
- Code Block
- Code Dots
- Collapsible
- Combobox
- Command
- Context Menu
- Copy Field
- Countdown
- Country Select
- Data Table
- Date Field
- Date Picker
- Date Range Picker
- Dialog
- Direction
- Document Paper
- Drawer
- Dropdown Menu
- Empty
- Entity Avatar
- Field
- File Trigger
- File Upload Item
- Hover Card
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Key Value
- Keypad
- Label
- Live Region
- Marker
- Message Scroller
- Message
- Money Amount
- Native Select
- Number Field
- Pagination
- Percent Split Editor
- Phone Field
- Popover
- Progress
- QR Code
- Questionnaire
- Radio Group
- Range Histogram
- Rating
- Resizable
- Scroll Area
- Search Field
- Select
- Separator
- Share Bar
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Sortable List
- Spinner
- Status Timeline
- Step Header
- Steps List
- Swipe Row
- Switch
- Table
- Tabs
- Text Field
- Textarea
- Tier Ladder
- Toggle Group
- Toggle
- Token Search Field
- Tooltip
- Trace
- Transaction Row
- Usage Meter
import { Badge } from "@/components/ui/badge"
import { BankCard } from "@/components/ui/bank-card"
import { CardStack } from "@/components/ui/card-stack"The CardStack component piles up to three BankCards: the last one lies on top in full, and the others peek out above it, each a little narrower. Use it on a cards page to show that there is more than one card, or to offer a new one on the card behind. To pick between cards, use a list or a carousel instead.
Installation#
pnpm dlx shadcn@latest add @dots/card-stack
Usage#
import { BankCard } from "@/components/ui/bank-card"
import { CardStack } from "@/components/ui/card-stack"<CardStack offer={<Badge>Get a virtual card</Badge>}>
<BankCard skin="lime" />
<BankCard skin="frost" />
<BankCard skin="onyx" mark={<IssuerLogo />} network="visa" last4="4242" />
</CardStack>Composition#
The last child is the top card. Earlier children peek out above it, the first one farthest back.
CardStack
├── BankCard (farthest)
├── BankCard
└── BankCard (top)Features#
- Children-based: pass any
BankCards, in back-to-front order - Up to three cards; extra children are dropped from the back
- Cards behind the top one show their real plastic and artwork on the strip
- An
offerslot on the farthest edge for a badge or a short note - One width for the whole pile; every card follows it
Two cards#
With two children the pile is shorter: one strip above the top card.
import { BankCard } from "@/components/ui/bank-card"
import { CardStack } from "@/components/ui/card-stack"
Width#
The stack is 340px wide and never wider than its parent. Set a width class, such as w-[280px], to change it. The cards fill the stack, so a width on a card inside it has no effect.
Offer#
Pass any node to offer, such as a Badge. It sits at the top end of the farthest card. To make the offer actionable, wrap the stack in a link or a button and name that control, for example "Get a virtual card".
Accessibility#
CardStack is a <div> with no role of its own.
- Only the top card is exposed to assistive tech. The cards behind it are
aria-hidden, since they show only a strip of plastic. - The
offeris read as normal content. Keep it short and specific. - If the cards behind stand for real cards, say so in nearby text, such as "3 cards", because they are not read out.
API Reference#
CardStack#
Accepts all <div> props.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | - | BankCards, back to front. The last is on top; at most three are shown. |
offer | React.ReactNode | - | A short note on the farthest card's edge, such as a Badge. |
className | string | - | Additional classes to apply to the root, such as a width. |