Expand Card

A card that opens into a full article, growing from its place in the page to fill the screen, and shrinks back into its slot when you pull it down, like the App Store's Today tab.

  • Card
  • Gesture
  • Motion

Uses motion, clsx, tailwind-merge

Open in ChatGPTOpen in Claude

Thursday, October 9

Today

Installation

Add the component on its own with the CLI, or copy the file in by hand.

The CLI writes components/ui/expand-card.tsx and installs motion, clsx and tailwind-merge. It needs the @keyframeui registry in components.json; add it once per project.

npx shadcn@latest add @keyframeui/expand-card

Examples

Finished sections built with Expand Card. Each one installs whole, with the component included.

Changelog With Links

Each post has its own link. Opening one updates the URL, the back button closes it, and loading a post's link opens it directly. The notes load while the cover grows.

Shop

Product cards that open into a product page with close-ups and a size picker. Add something to the bag, then pull the page down to watch the count behind it change.

Spring drop

New arrivals

0 items in your bag

Props

coverRequired

TypeReact.ReactNode

The card's face, and the top of the open article. It fills the card, then the article's header, at its own size: nothing is scaled, so it uncrops as it widens. Give its text a max width so it wraps the same in both.

children

TypeReact.ReactNode

The article's body, revealed under the cover. Only rendered while open. If it suspends, the cover still animates straight away and fallback shows until the body is ready.

id

Typestring

Gives the article a link of its own, #id. Opening it adds a history entry, so the back button closes it, and loading the link opens it. Also the card's DOM id; with it the card is a link, without it a button.

open / onOpenChange

Typeboolean / (open: boolean) => void

Control it yourself. onOpenChange is also called when the reader opens or closes it.

width

TypenumberDefault720

Width of the open article on screens 640px and wider, in px, shown over the dimmed page. Narrower screens get the whole screen.

coverHeight

Typenumber

Height of the cover in the open article, in px. Defaults to the card's height. Taller suits portrait photos, like products.

className

Typestring

Classes for the card: size, corners, background. Its corners, background and text styles carry into the open article's cover. Other props pass through to the card, a button (or an a with id).

articleClassName

TypestringDefault"bg-background text-foreground"

Classes for the open article, such as its background and text color.

fallback

TypeReact.ReactNode

Shown in place of the body while it suspends. Defaults to a few placeholder lines.