Components / Ferrofluid Nav
Ferrofluid Nav
A nav whose active pill does not slide. Two capsule fields are blended with a polynomial smooth-minimum, so below the blend radius they fuse into one surface with a real neck between them — the pill stretches out of the item it is leaving and gathers into the one it is entering. A translate has no surface tension; this does.
Usage
import FerrofluidNav from '@/components/ferrofluid-nav'
<FerrofluidNav
items={[
{ id: 'overview', label: 'Overview' },
{ id: 'components', label: 'Components' },
]}
blend={26}
stretch={34}
onSelect={(id) => setTab(id)}
/>Installation
npx shadcn@latest add https://morphiq.prathampatel.design/r/ferrofluid-nav.jsonModel
smin(a, b, k) = min(a, b) − h²k/4, h = max(k − |a − b|, 0)/ka, b distances to the two blobs · k the blend radius
Props
| Property | Type | Default | Description |
|---|---|---|---|
items | FerrofluidNavItem[] | [] | The nav's items, in order. Each becomes a real role="tab" button. |
activeId | string | — | Controlled selection. |
defaultActiveId | string | — | Starting selection when uncontrolled. Defaults to the first item. |
onSelect | (id: string, item: FerrofluidNavItem, index: number) => void | — | Called on click, tap, or arrow / Home / End keys, with the item and its index. |
blend | number | 26 | Blend radius across the neck, in px, before speed adds to it — how readily the two ends fuse once they are drawn apart. It never inflates the resting pill. Default 26. |
stretch | number | 34 | Extra blend radius at full travel speed, in px, so a fast body holds together across a longer neck. Default 34. |
padding | number | 10 | How far the resting pill overhangs an item's box, in px (0 to 120). Default 10. |
reach | number | 6 | How far the fluid is drawn toward a hovered item, in px; doubled while it is pressed. 0 turns it off. Default 6. |
stiffness | number | 210 | Spring constant for the leading end's travel, per s². Default 210. |
damping | number | 22 | Damping coefficient for that spring, per s. Default 22 (ζ ≈ 0.76). |
color | string | — | Fill colour, any CSS colour. Overrides the --ffn-fill custom property. |