VayuUI

Card

A compound card component with header, media, content, and footer sub-components for structured content display.

Installation

npx vayu-ui init #one time only
npx vayu-ui add card
npx vayu-ui add -t card #with test case needs

Usage

Card Example

Abstract gradient art

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> when href is set, or a role="button" div when interactive or onClick is 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 (interactive or onClick).
    • Tab — Moves focus into and out of the card.
  • ARIA Attributes:
    • role="button" is applied to interactive cards (when interactive or onClick is set).
    • aria-disabled is set on the root element when disabled is true.
    • aria-hidden="true" is set on the avatar wrapper to prevent decorative images from being announced.
    • rel="noopener noreferrer" is automatically added for target="_blank" links.
  • Focus Behavior:
    • focus-visible outline uses the semantic outline-focus token with a 2px offset.
    • Disabled cards receive pointer-events-none and 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 reference

Props

Card

PropTypeDefaultDescription
interactivebooleanfalseMake the card clickable with keyboard support.
hrefstringRender as an <a> element.
targetstringAnchor target attribute.
relstringAnchor rel attribute. Auto-sets noopener noreferrer for _blank.
disabledbooleanfalseDisable all interactions and reduce opacity.

Card.Header

PropTypeDefaultDescription
titleReactNodeMain heading rendered as an <h3>.
subtitleReactNodeSecondary text below the title.
actionReactNodeTrailing element (badge, icon button).
avatarReactNodeLeading icon or avatar (decorative, hidden from screen readers).

Card.Media

PropTypeDefaultDescription
srcstringImage source URL. Required.
altstringImage alt text. Required.
aspectRatiostring"16/9"CSS aspect-ratio value.
fit"cover" | "contain" | "fill""cover"Object-fit behavior.
overlayReactNodeContent 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.

On this page