crucıble

Casement

A list or grid of dark-glass cards that morph into a centered overlay via a genuine shared-element FLIP — media, title, and action travel continuously, radii stay unsheared, the frame overshoots ~1% and settles, and body copy fades up only after it lands. Full dialog semantics with focus trap, Escape, and outside-click; reduced motion swaps instantly.

motionfree

Installation

CLI

npx shadcn@latest add @crucible/casement

Manual — install dependencies, then copy the source

npm install motion

Props

PropTypeDefaultDescription
itemsCasementItem[]The cards to render. Each expands into a centered overlay on click.
layout"list" | "grid""list"Collapsed arrangement.
activeIdstring | nullControlled active id (null = closed). Omit for uncontrolled use.
defaultActiveIdstring | nullnullInitial active id in uncontrolled mode.
onActiveChange(id: string | null) => voidFires whenever the active card changes (open with an id, close with null).
onAction(item: CasementItem) => voidCalled when a non-link action button is pressed in the expanded card.
backdropOpacitynumber0.62Backdrop dim opacity, 0–1.
backdropBlurnumber8Backdrop blur radius in px (the "breath of blur").
expandedMaxWidthnumber460Expanded card max width in px.
closeOnOutsideClickbooleantrueClose when the backdrop is clicked.
closeOnEscapebooleantrueClose on the Escape key.
morphMediabooleantrueMorph the media through the FLIP. When false it crossfades instead.
accentstring"#93c5fd"Single cool accent hex for focus rings / hover.
classNamestringExtra classes for the collapsed list/grid wrapper.

Honors prefers-reduced-motion with a designed static fallback, and passes className through.