Skip to content

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

Free

Tabs with Tables for Ark UI

All Users, Active and Inactive. Each panel is a table of Name, Email, Role and Status for the matching people.

All Users, Active and Inactive switch a table with columns Name, Email, Role and Status. All Users is selected. Status is a badge, and the table sits in a fixed-height scroll area.

Use tabs instead of a filter menu when a list splits into a few groups, such as users by status. A Select is smaller once there are many groups. In React, Ark UI does not filter the rows.

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-2xl" defaultValue="all">
  <TabsList>
    {views.map((view) => (
      <TabsTrigger key={view.value} value={view.value}>
        {view.label}
      </TabsTrigger>
    ))}
  </TabsList>
  {views.map((view) => (
    <TabsContent key={view.value} value={view.value}>
      <div className="rounded-lg border bg-card shadow-sm">
        <ScrollArea className="h-[400px]">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Name</TableHead>
                <TableHead>Email</TableHead>
                <TableHead>Role</TableHead>
                <TableHead>Status</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {view.rows.map((user) => (
                <TableRow key={user.email}>
                  <TableCell>{user.name}</TableCell>
                  <TableCell className="text-muted-foreground">
                    {user.email}
                  </TableCell>
                  <TableCell>{user.role}</TableCell>
                  <TableCell>
                    <Badge
{/* The rest of the file is under Installation. */}

FAQ

How does each tab choose its rows?

A views array holds each tab's rows. All Users shows all eight people, Active keeps the four with Active status and Inactive the other four.

Why is the table in a ScrollArea?

ScrollArea with h-[400px] keeps every panel the same height, and the table scrolls inside it when there are more rows.

How does the status badge pick a variant?

Active rows get the default Badge and Inactive rows the secondary one.

Which table parts does it use?

Table, TableHeader, TableHead, TableBody, TableRow and TableCell. The columns are Name, Email, Role and Status, and the table sits in a bordered bg-card block.

Where do the users come from?

A typed users array of eight people with a name, email, role (Admin, Editor or Viewer) and status. Replace it with your own data.

Do the triggers show a count?

No. The labels are All Users, Active and Inactive, and All Users is the default. Add a Badge inside a trigger for a count.

API Reference

Tabs

Sets defaultValue="all" and value={view.value}. The rest is on the Tabs page.

Scroll Area

No extra props in this demo. The rest is on the Scroll Area page.

Table

No extra props in this demo. The rest is on the Table page.

Badge

Sets variant. The rest is on the Badge page.