Card
a surface container with variants for grouping content
Installation
bunx @prototyperco/cli add cardpnpm dlx shadcn@latest add https://prototyper-ui.com/r/card.jsonnpx shadcn@latest add https://prototyper-ui.com/r/card.jsonyarn dlx shadcn@latest add https://prototyper-ui.com/r/card.jsonbunx --bun shadcn@latest add https://prototyper-ui.com/r/card.jsonThis will add the following files to your project:
components/ui/card.tsx
Usage
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter,
} from "@/components/ui/card";<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
<CardDescription>Description</CardDescription>
</CardHeader>
<CardContent>Content</CardContent>
<CardFooter>Footer</CardFooter>
</Card>Anatomy
<Card>
<CardHeader>
<CardTitle />
<CardDescription />
</CardHeader>
<CardContent />
<CardFooter />
</Card>| Sub-component | data-slot | Purpose | Required |
|---|---|---|---|
Card | card | Root container with surface variants | Yes |
CardHeader | card-header | Flex column for title and description | No |
CardTitle | card-title | Heading for the card | No |
CardDescription | card-description | Supporting text below the title | No |
CardContent | card-content | Main content area with flex-1 growth | No |
CardFooter | card-footer | Horizontal flex container for actions | No |
Examples
Elevated
Interactive
With Form
Styling
Data Slots
Use data-slot attributes to target specific parts of the card:
| Slot name | Element |
|---|---|
card | Root <div> wrapper |
card-header | Header container |
card-title | Title <h3> |
card-description | Description <p> |
card-content | Content container |
card-footer | Footer container |
Customization Examples
/* Make all cards have a larger radius */
[data-slot="card"] {
@apply rounded-2xl;
}
/* Give card titles more weight */
[data-slot="card-title"] {
@apply text-lg font-bold;
}{
/* Override styles via className */
}
<Card className="rounded-2xl p-6">{/* ... */}</Card>;API Reference
Card
The root container with surface-tier variants.
Prop
Type
Extends React.ComponentProps<"div">. All standard div props are forwarded via ...props.
CardHeader
Flex column container for title and description.
Prop
Type
Extends React.ComponentProps<"div">. All standard div props are forwarded via ...props.
CardTitle
Card heading rendered as an <h3>.
Prop
Type
Extends React.ComponentProps<"h3">. All standard h3 props are forwarded via ...props.
CardDescription
Muted supporting text rendered as a <p>.
Prop
Type
Extends React.ComponentProps<"p">. All standard p props are forwarded via ...props.
CardContent
Main content area with flex-1 growth.
Prop
Type
Extends React.ComponentProps<"div">. All standard div props are forwarded via ...props.
CardFooter
Horizontal flex container for action buttons.
Prop
Type
Extends React.ComponentProps<"div">. All standard div props are forwarded via ...props.
cardVariants
Use cardVariants to apply card styles to non-card elements:
import { cardVariants } from "@/components/ui/card";
<div className={cardVariants({ variant: "elevated", interactive: true })}>
Custom card element
</div>;Accessibility
Keyboard Interactions
Card is a non-interactive presentational container and does not have keyboard interactions. When the interactive prop is set, the card gains a pointer cursor but remains a <div> -- wrap it in an <a> or <button> if it should be keyboard-focusable.
ARIA Attributes
- Card renders as a plain
<div>with no implicit ARIA role. - Use
role="region"witharia-labelif the card represents a distinct landmark. - When used with
interactive, consider wrapping in an interactive element (<a>,<button>) for proper keyboard and screen reader support.
Compose
This component is available in @prototyperco/compose.
Catalog Definition
import { z } from "zod";
import { defineComponent } from "@prototyperco/compose/catalog";
export default defineComponent({
description:
"A container card with optional header, content, and footer sections",
props: z.object({
title: z.string().optional().describe("Card header title"),
description: z.string().optional().describe("Card header description"),
variant: z
.enum(["default", "secondary", "tertiary", "elevated", "transparent"])
.optional()
.describe(
"Visual style variant controlling background, border, and shadow",
),
interactive: z
.boolean()
.optional()
.describe("When true, adds hover lift and press effects"),
className: z.string().optional().describe("Additional CSS classes"),
}),
slots: ["header", "content", "footer"],
example: {
title: "Welcome",
description: "Get started with your dashboard",
variant: "default",
},
});Example Spec
{
"root": "card",
"elements": {
"card": {
"type": "Card",
"props": {
"title": "Welcome",
"description": "Get started with your dashboard",
"variant": "default"
},
"children": ["card_content"]
},
"card_content": {
"type": "Text",
"props": { "content": "Here is your main content area." }
}
}
}Learn more in the Compose documentation.