Nav Tabs

Twenty four records, from the first Blue Note session to last spring's live album.
About this component

Nav Tabs

Tabs with one indicator that slides and resizes between them on a spring: a line under the current tab, a filled pill, or a raised segment on a strip. When the tabs outgrow their space the strip scrolls sideways behind soft fades, arrows appear only while there is more to see, and the current tab always scrolls clear of the edges. Tabs take icons and count badges, follow the WAI-ARIA tabs pattern with automatic or manual activation, and either show panels or render as real links through your own router.

Usage

The import and the props worth knowing about, in one place.

import { NavTabs } from "@/components/beste/component/nav-tabs";

// Tabs with panels, controlled
<NavTabs
  value={tab}
  onValueChange={setTab}
  tabs={[
    { value: "overview", label: "Overview", content: <Overview /> },
    { value: "releases", label: "Releases", count: 24, content: <Releases /> },
    { value: "tour", label: "Tour dates", count: 12, content: <Tour /> },
  ]}
/>

// A segmented strip that selects only on Enter or Space
<NavTabs variant="segment" activation="manual" tabs={tabs} />

// Real links through your router; the strip becomes a labelled nav
<NavTabs
  variant="pill"
  value={section}
  tabs={sections}
  getHref={(value) => `/artists/glasper/${value}`}
  renderLink={(props) => <Link {...props} />}
  aria-label="Artist sections"
/>

Keyboard and gestures

Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.

TabMove into the strip onto the current tab, then on into its panel.
Left / RightMove to the previous or next tab, wrapping at the ends and skipping disabled ones.
Home / EndMove to the first or last tab.
Enter / SpaceSelect the focused tab when activation is manual.

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
tabs*NavTab[]—
valuestring—Current tab. Pair with `onValueChange` to control it.
defaultValuestringthe first enabled tab
onValueChange(value: string) => void—
variant"underline" | "pill" | "segment""underline"
activation"automatic" | "manual""automatic"`automatic` selects a tab as the arrow keys reach it; `manual` only moves focus, and Enter or Space selects.
keepMountedboolean—Keep inactive panels mounted (hidden) instead of unmounting them.
getHref(value: string) => string—Render tabs as links to these addresses instead of buttons; panels are then left to your routes.
renderLink(props: NavTabLinkProps) => React.ReactNode—Render the links through your router, e.g. `(props) => <Link {...props} />`.
tone"muted" | "outline" | "ghost""muted"
size"sm" | "default" | "lg""default"
disabledboolean—
panelClassNamestring—Extra classes for the panel.
aria-labelstring"Tabs"
classNamestring—

More Nav components

View all Nav