Expandable card

Give a dense card more room when requested.

disclosurelayout
Preview
Expandable card preview

The card grows into a larger view in place, so the page around it never moves.

When to use

  • A single summary card with optional details, like a plan, order, or log entry.
  • Cards whose summary line updates and should roll changed words in place.

When not to use

  • Use accordion for a list of mutually exclusive sections.
  • Use card when there is nothing to reveal.
  • Use card-stack for browsing several cards in one spot.

shadcn CLI

Also installs (1)

  • manicat-foundation
Manual install(+)
registry.jsonjson
{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "expandable-card",
  "type": "registry:ui",
  "title": "Expandable card",
  "description": "Give a dense card more room when requested.",
  "categories": [
    "disclosure"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://manicat.viraza.net/r/manicat-foundation.json"
  ],
  "files": [
    {
      "path": "registry/components/expandable-card/expandable-card.tsx",
      "type": "registry:component",
      "target": "@components/manicat/expandable-card/expandable-card.tsx"
    },
    {
      "path": "registry/components/expandable-card/expandable-card.module.css",
      "type": "registry:component",
      "target": "@components/manicat/expandable-card/expandable-card.module.css"
    }
  ],
  "docs": "Docs and live preview: https://uiarc.dev/components/expandable-card",
  "meta": {
    "tier": "free",
    "kind": "component",
    "docs": "https://manicat.viraza.net/components/expandable-card",
    "markdown": "https://uiarc.dev/components/expandable-card/markdown",
    "tags": [
      "disclosure",
      "layout"
    ]
  }
}

Usage

Install the component, then copy this into your app. Change the content and the props to fit your screen.

example.tsxtsx
"use client";

import { ExpandableCard } from "@/components/manicat/expandable-card/expandable-card";

export function ExpandableCardExample() {
  return (
    <ExpandableCard title="Quarterly plan" description="Three tracks, reviewed every Friday.">
      <p className="text-sm text-(color:--text-muted)">
        The card grows into a larger view in place, so the page around it never moves.
      </p>
    </ExpandableCard>
  );
}

Examples

Real screens rather than isolated props. Switch to Code to copy a whole example into your project.

Plan details The card opens into a larger view in place, so the page around it never moves.

Plan details The card opens into a larger view in place, so the page around it never moves. preview
  • Design system: tokens and dark mode
  • Docs: examples for every component
  • Registry: framework ports

Keyboard interactions

KeysAction
Enter / SpaceToggles the card from its header button.
EscapeCloses the card while focus is inside it and returns focus to the header.

Accessibility

  • The header is a native button with aria-expanded and aria-controls pointing at the panel.
  • The rolling description keeps a screen-reader-only copy of the full text; animated words are aria-hidden.
  • The collapsed panel is inert, so its content is not reachable by keyboard or screen readers while closed.

Motion

  • Open and close are one morph: width and height move together on the smooth spring, which never overshoots, and the arrow turns on the same spring.
  • Details fade in once the box has made room and fade out before it shrinks. They are laid out at their open width throughout, so text never reflows or stretches.
  • Clicking again mid-animation reverses from the current size with its velocity. Changed words in the description rise in; unchanged words hold still.
  • Reduced motion applies end states instantly and swaps the description without animation.

Responsive behavior

  • Without width caps the card fills its container. With width and expandedWidth it stays centered and grows sideways to the open cap, never wider than its container, so on a phone it simply uses the full width.
  • The whole header is the toggle with a 64px minimum height, so it is an easy touch target.

Performance

  • The panel stays mounted but inert at zero height when collapsed, so a second click mid-animation reverses smoothly.
  • Width and height are animated for real on one spring rather than scaled, so text and corners never stretch; keep the details short.
  • The description splits into one span per word for the roll; keep it to a short line.

Notes for AI

  • Use for a single standalone expandable summary such as a plan, order, or log entry. Use accordion for a list of mutually exclusive sections.
  • State is internal; there is no controlled prop.