Tabs
Tabbed navigation with two variants — animated underline (line) and container pills (solid).
Preview
Overview content goes here.
Variants
TabsList accepts a variant prop with two values:
"line"(default) — Underline indicator that slides between triggers using aMutationObserver+ResizeObserver. Use for primary, page-level tab strips."solid"— Pill triggers inside a tinted, bordered container; the active trigger fills with the page background. Use for nested / second-level tab strips, so they read as visually distinct from the outer line tabs.
Solid (nested) variant
Vessels list goes here.
Pairing line + solid
The two variants are designed to compose: page-level tabs use line, the nested tab strip inside one of those tabs uses solid. The user instantly sees the second level is a sub-navigation, not a peer.
<Tabs defaultValue="catalog">
<TabsList>
{/* primary nav — line variant (default) */}
<TabsTrigger value="catalog">Catalog</TabsTrigger>
<TabsTrigger value="settings">Settings</TabsTrigger>
</TabsList>
<TabsContent value="catalog">
<Tabs defaultValue="vessels">
<TabsList variant="solid" className="w-fit">
{/* secondary nav — solid variant */}
<TabsTrigger value="vessels">Vessels</TabsTrigger>
<TabsTrigger value="ports">Ports</TabsTrigger>
</TabsList>
{/* … */}
</Tabs>
</TabsContent>
</Tabs>Props
TabsList
Prop
Type
Tabs (Radix Root)
Prop
Type
Usage
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
<Tabs defaultValue="tab1">
<TabsList>
<TabsTrigger value="tab1">Tab 1</TabsTrigger>
<TabsTrigger value="tab2">Tab 2</TabsTrigger>
</TabsList>
<TabsContent value="tab1">Content 1</TabsContent>
<TabsContent value="tab2">Content 2</TabsContent>
</Tabs>Install
npx shadcn add @bonsai/tabs