Gooey nav

A gooey navigation bar that separates the selected item from the group.

Dependencies

motion

Interaction Type

Click an item to lift it out of the bar; the rest close back into one piece behind it.

Props

Options you can pass to customize this component.

Prop
Type
Description
items*
(string | { label: string; href?: string; icon?: ReactNode })[]

Nav entries. A string is a button, an object with href is a link, and icon renders before the label.

value
number

Index of the selected item. Pass it to control the nav yourself; leave it out and the nav follows the url when the items have hrefs, and its own state otherwise.

defaultValue
number

Index the nav starts on when it is uncontrolled. Ignored once value is passed, and ignored when an item href matches the current url.

onChange
(index: number) => void

Fires with the index of the item that was clicked.

size
xssmmdlg

Scale of the bar. Sets the label padding, text size and icon size, and picks the matching separation and radius so the shape stays in proportion. Use xs on phones, where it fits a 360px screen.

activeColor
string

Fill of the selected tile. The unselected bar follows the theme instead, light grey on light and near black on dark.

activeLabelColor
string

Label color of the selected item. Set it when a light activeColor leaves white text unreadable.

separation
number

Gap in pixels that opens on each side of the selected item, which is what pushes the rest of the bar aside. Defaults to the size: 14 (xs), 16 (sm), 20 (md), 24 (lg).

radius
number

Corner radius of the tiles in pixels. Only the outer corners of the bar and the corners along an open gap use it; a closed seam sits at 0 so the tiles read as one shape. Defaults to the size: 8 (xs), 10 (sm), 12 (md), 14 (lg).

className
string

Extra classes merged onto the root element (data-slot="gooey-nav"). The bar sizes to its content and never wraps, so add an overflow container here if it can outgrow its parent.

Installation

npx shadcn@latest add swamimalode07/rare-ui/gooey-nav

How to use

"use client"
import { GooeyNav } from "@/components/ui/gooey-nav"
export function Demo() {
return (
// hrefs make it track the url on its own, no value needed
<GooeyNav
items={[
{ label: "Home", href: "/", icon: <HouseIcon /> },
{ label: "Changelog", href: "/changelog" },
{ label: "About", href: "/about" },
]}
/>
)
}
// strings render buttons instead, for a segmented control:
// <GooeyNav items={["Day", "Week", "Month"]} onChange={setRange} />
// size is a single value, so step it down yourself on small screens:
// <GooeyNav items={items} size={useIsMobile() ? "xs" : "md"} />

Source Code

Click the code icon in the top-right corner to view the source code.

Keep in mind

Most components here are recreations of great work from around the web. I don't claim to be the original creator - this is my attempt to reverse-engineer, replicate, and often add a few extra features. I've tried to credit everyone; if I missed someone, let me know.

Contact

Found a bug or issue? Feel free to drop a DM.

License & Usage

  • Free to use and modify in both personal and commercial projects.
  • Attribution to Rare UI is appreciated when using a component.
  • Please don't resell the components as your own kit.
Gooey nav