smooth-tabs

A React tab bar for content that doesn’t fit. Native scrolling with overflow-aware arrows, an animated indicator, WAI‑ARIA keyboard support, and a useScrollSpy hook that keeps tabs in sync with page sections.

npm install smooth-tabs
ProductTabs.tsx
import { useState } from "react";
import { ScrollableTabs } from "smooth-tabs";
import "smooth-tabs/styles.css";

export function ProductTabs() {
  const [tab, setTab] = useState("overview");
  return (
    <ScrollableTabs
      aria-label="Product"
      tabs={tabs}
      value={tab}
      onChange={setTab}
    />
  );
}
Latest on npm
loading
Downloads
loading
Size (min+gzip)
3.4 kB
Dependencies
0
TypeScript
Types included
React
≥ 16.8.0
License
ISC

Live example

Overflowing tabs with icons, badges and a disabled tab. Swipe, scroll or use the arrows. Click a tab, then try ← → Home End.

File changes

22 files changed since your last visit. Review them before the next sync.

Added
+1,840
Removed
−392
Reviewers
4

Styling variants

Style it with CSS variables, class names or your design system. The stylesheet never touches the rest of your page.

Profile

Vertical

A settings sidebar. Give it a height and the arrows appear when it overflows. Use ↑ ↓ to move.

Segmented

The same component restyled with a few CSS variables. The indicator becomes the sliding pill.

Badges & disabled tabs

Badges accept a number, any node, or a colored pill. Disabled tabs are skipped by the keyboard.

Right-to-left

Under dir="rtl" the scrolling, arrow keys, buttons and edge fades all flip.

Scroll-spy, built in

useScrollSpy highlights the section you’re reading and keeps it visible in the bar. Click a category to glide there without the tabs flickering on the way.

const { activeId, scrollTo } = useScrollSpy(ids, { offset: 76 });

<ScrollableTabs tabs={tabs} value={activeId} onChange={scrollTo} />