Skip to content
Pinky UI

Gooey Menu

A section switcher whose selected surface stretches between items with a restrained shared-origin connection.

  • navigation
  • liquid
  • morph
  • elastic
  • menu
  • gooey
  • nav
  • indicator

Quick usage

usage
import { GooeyMenu } from "@pinky-ui/components";

<GooeyMenu
  aria-label="Sections"
  items={sections}
  onValueChange={setSection}
/>

Presets

Subtle

Almost a plain indicator.

stickiness={0.4}

Default

Visible stretch, still quick.

stickiness={1}

Playful

Long trailing blob.

stickiness={1.6}

Install

Add @pinky-ui/components as a dependency, or use the CLI to copy this component's source directly into your project — no dependency to manage, fully editable.

shell
npm install @pinky-ui/components

Prefer to run the whole repository locally instead?

repository
git clone https://github.com/florash/Pinky-UI.git
cd Pinky-UI
npm install
npm run dev

Props

PropTypeDefaultDescription
itemsGooeyMenuItem[]Each needs an id and a label; href renders a link.
valuestringControlled selection.
defaultValuestringInitial selection when uncontrolled.
onValueChange(value: string) => voidSelection callback.
stickinessnumber1How far the trailing shape lags. 0 disables the goo.
aria-labelstring"Sections"Names the navigation landmark.

Accessibility

  • Renders a nav landmark with real links or buttons — the goo is one aria-hidden layer behind them.
  • Labels sit above the filtered layer, so text stays perfectly crisp.
  • Selection is conveyed by aria-current for links and aria-pressed for buttons, never by the connected surface alone.
  • Standard Tab order; no custom key handling to learn.

Reduced motion

With prefers-reduced-motion: reduce, the blur-and-contrast layer is dropped entirely and the indicator moves instantly to the selected item.

When to use

  • Section switchers with three to five items
  • Playful marketing and portfolio navigation
  • Filter bars where a little personality is welcome

When not to use

  • Dense application chrome
  • Long lists of items — the blob has to travel too far
  • Anywhere the selection must be readable at a glance from across a room