Skip to content
Pinky UI

Pill Nav

Real navigation links with a shared pill background that slides to whichever one is current.

  • navigation
  • morph
  • indicator
  • links
  • route

Quick usage

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

<PillNav
  aria-label="Main"
  items={[
    { id: "explore", label: "Explore", href: "/explore", active: pathname === "/explore" },
    { id: "docs", label: "Docs", href: "/docs", active: pathname === "/docs" },
  ]}
/>

Presets

Default

Standard header height.

Compact

For a shrunken sticky header state.

size={"sm"}

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
itemsPillNavItem[]Each item is a link (href) or a trigger (onClick, for a dropdown); active is supplied by the caller's own router.
size"sm" | "md""md"Control height and type size.
scrollablebooleanfalseHorizontal scroll for a narrow track. Leave off unless the row can genuinely overflow — an explicit overflow-x forces overflow-y to compute as auto too, clipping any item's dropdown panel.
aria-labelstring"Navigation"Names the nav landmark for assistive technology.

Accessibility

  • Renders real <a> or <button> elements — never a div with a click handler.
  • aria-current="page" marks the active link; trigger items expose aria-expanded and aria-haspopup for their dropdown.
  • The active state and its indicator both come from the caller's router, so back/forward navigation and direct links land on the correct pill without extra wiring.

Reduced motion

With prefers-reduced-motion: reduce, the pill jumps directly to the active item instead of sliding and stretching.

When to use

  • A primary site or app navigation bar with a handful of top-level destinations
  • Route-based navigation where the current page should read as a persistent, moving highlight

When not to use

  • Switching between peer views without a URL change — use Fluid Tabs
  • More than about seven destinations, where the pill row stops reading as a set