Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Scrollable Tabs for React

January through December in one scrolling row of tabs. January is selected and shows Total Tasks 24 and Completed 18.

Twelve month names sit on one line that scrolls sideways. January is selected. Its panel is titled January 2024 and shows Total Tasks 24 and Completed 18.

Use a scrolling row for a long run of tabs that should stay on one line, such as months. An Accordion lists the same months in a stack. Base UI in React does not supply the month names or the counts.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

Tabs anatomy: root, list, indicator, trigger, content

Usage

<Tabs className="w-full max-w-md" defaultValue="january">
  <ScrollArea className="w-full whitespace-nowrap rounded-md">
    <TabsList>
      {months.map((month) => (
        <TabsTrigger key={month.name} value={month.name.toLowerCase()}>
          {month.name}
        </TabsTrigger>
      ))}
    </TabsList>
    <ScrollBar orientation="horizontal" />
  </ScrollArea>
  {months.map((month) => (
    <TabsContent key={month.name} value={month.name.toLowerCase()}>
      <div className="rounded-lg border bg-card p-6 text-card-foreground shadow-sm">
        <h3 className="mb-2 font-semibold text-lg">{month.name} 2024</h3>
        <p className="text-muted-foreground text-sm">
          View statistics and activity for {month.name}. Track your progress,
          goals, and achievements throughout the month.
        </p>
        <div className="mt-4 grid grid-cols-2 gap-4">
          <div className="rounded-md border p-3">
            <p className="text-muted-foreground text-xs">Total Tasks</p>
            <p className="mt-1 font-semibold text-2xl tabular-nums">
              {month.total}
            </p>
          </div>
          <div className="rounded-md border p-3">
            <p className="text-muted-foreground text-xs">Completed</p>
            <p className="mt-1 font-semibold text-2xl tabular-nums">
              {month.completed}
            </p>
{/* The rest of the file is under Installation. */}

FAQ

How does the tab list scroll?

ScrollArea wraps TabsList with w-full whitespace-nowrap. The list keeps its natural width, so January to December overflow the max-w-md area and scroll. A ScrollBar with orientation="horizontal" sits inside the ScrollArea.

How are the twelve months built?

A months array is mapped twice, once for triggers and once for panels. Each value is the lowercased month name, and the default is january.

Does each month get a panel?

Yes. Each panel shows the month and 2024, a muted paragraph and two stat boxes, Total Tasks and Completed.

Where do the task counts come from?

From the months array: each month has its own total and completed. The numbers are fixed, so they match between server and client renders and stay the same when you come back to a month.

Do the arrow keys move between months?

Yes. Left and Right move between the month triggers, and Home and End jump to January and December. Focusing a month selects it, as on the other bases: TabsList turns on Base UI's activateOnFocus. Set activateOnFocus={false} to select only with Enter or Space.

Do the other months stay mounted?

No. Only the selected month's panel is in the page. Set keepMounted on each TabsContent to keep every month mounted.

API Reference

Tabs

Sets defaultValue="january" and value={month.name.toLowerCase()}. The rest is on the Tabs page.

Scroll Area

Sets orientation="horizontal". The rest is on the Scroll Area page.