Gooey Stack
godui/gooey-stackFreeComponent
A stack of cards that fuse with a liquid metaball bridge and collapse behind an anchor with a spring.
Install it
npx shadcn@latest add https://godui.design/r/gooey-stack.jsonSource
1"use client";23import {4 motion,5 useMotionValue,6 useReducedMotion,7 useSpring,8 useTransform,9} from "framer-motion";10import * as React from "react";1112export type GooeyStackProps = Omit<13 React.HTMLAttributes<HTMLDivElement>,14 "onChange"15> & {16 /**17 * The inner content of each card, top to bottom — the last is the anchor.18 * GooeyStack renders the fused `bg-card` surface itself, so children should19 * be transparent content (padding + text/controls), not their own cards.20 * Provide 2+.21 */22 children?: React.ReactNode;23 /**24 * Controlled vertical gap (px) between cards. Negative values overlap and25 * merge them. When set, this overrides `collapsed` — drive it from a slider26 * for the full continuous effect.27 */28 gap?: number;29 /** Convenience toggle: springs between `expandedGap` and `collapsedGap`. Default `false`. */30 collapsed?: boolean;31 /** Resting gap (px) when expanded. Default `18`. */32 expandedGap?: number;33 /** Gap (px) the `collapsed` toggle merges to. Default `-48`. */34 collapsedGap?: number;35 /** Blur radius feeding the goo filter — larger fuses cards from further. Default `10`. */36 gooeyness?: number;37 /** Corner radius (px) of the fused silhouettes. Match your cards. Default `28`. */38 radius?: number;39};4041// SPRING.smooth — surfaces / morph (see motion/tokens.ts).42const SPRING = {43 type: "spring",44 stiffness: 320,45 damping: 32,46 mass: 0.9,47} as const;4849const clamp = (v: number, lo: number, hi: number) =>50 Math.min(hi, Math.max(lo, v));5152// How much the cards are *necking* at a given gap: a band-pass that is 0 at both53// rest ends (fanned out, or fully merged) and peaks while surfaces are close.54const nearnessAt = (55 g: number,56 expandedGap: number,57 collapsedGap: number,58): number =>59 clamp((expandedGap - g) / Math.max(1, expandedGap - 4), 0, 1) *60 clamp((g - collapsedGap) / 20, 0, 1);6162const GooeyStack = React.forwardRef<HTMLDivElement, GooeyStackProps>(63 (64 {65 children,66 gap,67 collapsed = false,68 expandedGap = 18,69 collapsedGap = -48,70 gooeyness = 10,71 radius = 28,72 className,73 style,74 ...props75 },76 forwardedRef,77 ) => {78 const reduce = useReducedMotion() ?? false;79 const filterId = React.useId().replace(/:/g, "");8081 const items = React.Children.toArray(children);82 const n = items.length;8384 // The effective gap: an explicit `gap` wins, else the toggle picks a preset.85// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from godui
All 105 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | godui | Components | Free | 1 dep | |
| Agent Flowagent-flow | godui | Components | Free | 1 dep | |
| Agent Timelineagent-timeline | godui | Components | Free | 1 dep | |
| Animated Beamanimated-beam | godui | Components | Free | 1 dep | |
| Animated Testimonialsanimated-testimonials | godui | Components | Free | 1 dep | |
| Animated Tooltipanimated-tooltip | godui | Components | Free | 1 dep | |
| App Showcaseapp-showcase | godui | Components | Free | 1 dep | |
| Aurora Textaurora-text | godui | Components | Free | no deps |
