Card
A compound card component with header, media, content, and footer sub-components for structured content display.
Installation
npx vayu-ui init #one time onlynpx vayu-ui add cardnpx vayu-ui add -t card #with test case needsUsage
Card Example
Design Tokens
A unified color palette for every surface.
Ground, primary, secondary, and semantic colors work seamlessly across light and dark mode.
Interactive
Click Me
This card is focusable and keyboard-accessible.
Interactive cards get role="button", tabIndex=0, and Enter / Space key support.
Disabled
Disabled Card
Pointer events are blocked and opacity is reduced.
This card cannot be interacted with.
With Avatar & Action
John Doe
Software Engineer
Building beautiful user interfaces with modern web technologies.
<Card>
<Card.Media src="/photo.jpg" alt="Photo" />
<Card.Header
title="Card Title"
subtitle="Secondary description"
/>
<Card.Content>Body text goes here.</Card.Content>
<Card.Footer>
<button>Action</button>
</Card.Footer>
</Card>
<Card interactive onClick={() => {}}>
<Card.Header title="Clickable Card" subtitle="Press Enter or click" />
<Card.Content>This card responds to keyboard and pointer events.</Card.Content>
</Card>
<Card href="/details" target="_blank">
<Card.Media src="/photo.jpg" alt="Photo" />
<Card.Header title="Link Card" />
<Card.Content>Renders as an anchor element.</Card.Content>
</Card>
<Card>
<Card.Media src="/photo.jpg" alt="Photo" overlay={<span className="text-white font-semibold">Overlay Text</span>} />
<Card.Header title="Card with Overlay" avatar={<div className="w-8 h-8 rounded-full bg-surface" />} action={<span className="text-xs text-muted-content">Badge</span>} />
<Card.Content>Supports avatar, action, and media overlay.</Card.Content>
</Card>Anatomy
<Card>
<Card.Media src="/photo.jpg" alt="Photo" />
<Card.Header title="Title" subtitle="Subtitle" />
<Card.Content>Body text.</Card.Content>
<Card.Footer>
<button>Action</button>
</Card.Footer>
</Card>- Card — Root container. Renders as a
<div>by default,<a>whenhrefis set, or arole="button"div wheninteractiveoronClickis provided. - Card.Header — Displays a title, optional subtitle, leading avatar, and trailing action slot.
- Card.Media — Renders an image with configurable aspect ratio, object-fit, and an optional overlay.
- Card.Content — Body text wrapper with secondary typography styling.
- Card.Footer — Action bar with a top border, right-aligned by default.
Accessibility
- Keyboard Support:
Enter/Space— Activates interactive cards (interactiveoronClick).Tab— Moves focus into and out of the card.
- ARIA Attributes:
role="button"is applied to interactive cards (wheninteractiveoronClickis set).aria-disabledis set on the root element whendisabledistrue.aria-hidden="true"is set on the avatar wrapper to prevent decorative images from being announced.rel="noopener noreferrer"is automatically added fortarget="_blank"links.
- Focus Behavior:
focus-visibleoutline uses the semanticoutline-focustoken with a 2px offset.- Disabled cards receive
pointer-events-noneand reduced opacity.
Screen reader behavior
When a user navigates to a card, the screen reader announces the card contents based on the rendered HTML. For interactive cards, it announces the element as a button (via role="button") with the card title read as the accessible name. For linked cards, the screen reader identifies the element as a link and announces the destination URL. When disabled is set, the screen reader announces the card as disabled (via aria-disabled="true"). Avatar elements are hidden from the assistive technology tree (aria-hidden="true") to avoid redundant announcements. Media images are announced using their alt text.
Component Folder Structure
Card/
├── Card.tsx # Root component with interactive logic and styling
├── CardHeader.tsx # Header with title, subtitle, avatar, and action slots
├── CardMedia.tsx # Image media with overlay support
├── CardContent.tsx # Body content wrapper
├── CardFooter.tsx # Footer action bar with border separator
├── hooks.ts # Keyboard interaction handler (WCAG 2.1.1)
├── types.ts # TypeScript type definitions
├── index.ts # Public API with compound component exports
└── README.md # Component usage referenceProps
Card
| Prop | Type | Default | Description |
|---|---|---|---|
interactive | boolean | false | Make the card clickable with keyboard support. |
href | string | — | Render as an <a> element. |
target | string | — | Anchor target attribute. |
rel | string | — | Anchor rel attribute. Auto-sets noopener noreferrer for _blank. |
disabled | boolean | false | Disable all interactions and reduce opacity. |
Card.Header
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | Main heading rendered as an <h3>. |
subtitle | ReactNode | — | Secondary text below the title. |
action | ReactNode | — | Trailing element (badge, icon button). |
avatar | ReactNode | — | Leading icon or avatar (decorative, hidden from screen readers). |
Card.Media
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | — | Image source URL. Required. |
alt | string | — | Image alt text. Required. |
aspectRatio | string | "16/9" | CSS aspect-ratio value. |
fit | "cover" | "contain" | "fill" | "cover" | Object-fit behavior. |
overlay | ReactNode | — | Content rendered over the image with a gradient backdrop. |
Card.Content
No specific props — accepts standard HTML div attributes.
Card.Footer
No specific props — accepts standard HTML div attributes.