GodUIGodUI
43

Gooey Stack

A stack of cards that fuse with a liquid metaball bridge and collapse behind an anchor with a spring.

Stack content and let the surfaces behave like liquid. As the gap between cards shrinks their rounded surfaces bulge and fuse through a gooey metaball bridge; push it negative and the upper cards frost over — heavy blur, fading opacity — and dissolve into the anchor. Toggle collapsed, or drive gap from a slider for the full continuous sweep.

MCP Connector

GitHub

Examples

Stacks with more than two children collapse rank by rank — the ones furthest from the anchor recede and frost the most, with a staggered spring. A notification tray folds its history into the newest alert:

S

Dana Lee

5m

Can you review the PR when you get a sec?

L

Issue assigned to you

2m

GOD-142 · Fix card stacking

CI passed

now

main · deploy is ready to ship

The same shape reads as a wallet — three cards fanned out, folding into a stack. Keep children on the fused bg-card surface and let color come from small accents, so the metaball bridge stays seamless:

VISA
•••• 4242Personal
Mastercard
•••• 8210Business
Amex
•••• 0005Travel

Installation

pnpm dlx shadcn@latest add "https://godui.design/r/gooey-stack.json"

Two layers do the work. GooeyStack draws a surface layer — one bg-card rounded rect per child — and runs it through an SVG goo filter (feGaussianBlurfeColorMatrix threshold), so surfaces that come close bulge and fuse into one continuous shape. Your children render sharp and unfiltered on top, so text and controls stay crisp while only the surfaces merge and the receding ones frost.

Usage

tsx
 
import { GooeyStack } from "@/components/godui/gooey-stack";

Children are the inner content of each card — GooeyStack supplies the fused bg-card surface, so give children padding and content, not their own background:

tsx
 
<GooeyStack collapsed={collapsed}>
  <div className="px-5 py-4">First</div>
  <div className="px-5 py-4">Second</div>
</GooeyStack>

The last child is the anchor — it stays pinned while the others slide down and merge into it.

Driving it with a slider

Set gap (px) directly for the full continuous effect — positive values space the cards out, small values neck them together, negative values overlap and frost:

tsx
 
<GooeyStack gap={gap}>{/* content */}</GooeyStack>

Tuning the merge

gooeyness is the blur radius feeding the filter: raise it to fuse from further, lower it for a tighter neck. expandedGap sets the resting spacing, collapsedGap how deep the collapsed toggle merges.

tsx
 
<GooeyStack gooeyness={10} expandedGap={18} collapsedGap={-48} radius={28}>
  {/* content */}
</GooeyStack>

Accessibility

The stack is presentational — drive collapsed or gap from your own control (a button, switch, slider, or route). The surface layer is aria-hidden, so only your content is read. When prefers-reduced-motion is set, the goo filter is dropped and the cards snap between states instead of springing.

Props

PropTypeDefaultDescription
childrenReact.ReactNodeInner content of each card (transparent). The last child is the anchor.
gapnumberControlled gap (px); negative overlaps. Overrides collapsed.
collapsedbooleanfalseConvenience toggle between expandedGap and collapsedGap.
expandedGapnumber18Resting gap (px) when expanded.
collapsedGapnumber-48Gap (px) the collapsed toggle merges to.
gooeynessnumber10Blur radius feeding the goo filter — larger fuses from further.
radiusnumber28Corner radius (px) of the fused surfaces.

GooeyStack also forwards every standard <div> attribute to the root element.

On this page

Built with GodUI

Beautifully crafted motion components for modern interfaces.

Star on GitHub