# Tabs

> File tabs. Tabs switches a panel in place; TabNav is a row of route links. One brand underline travels to the active tab, a Phosphor icon fills when active and grows on hover.

Section: Primitives. Docs: https://entrepta.vercel.app/docs/components/tabs

## Install

```bash
npx @entrepta/cli@latest add tabs
```

Files: `primitives/tabs.tsx`, `lib/motion.ts`.
npm packages: `@radix-ui/react-tabs`, `@radix-ui/react-slot`, `@phosphor-icons/react`, `motion`.
Comes with: `motion-lib`.

## Usage

```tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/entrepta/tabs"
import { FileTsxIcon, FileMdIcon, BracketsCurlyIcon } from "@phosphor-icons/react"

<Tabs defaultValue="home">
  <TabsList>
    <TabsTrigger value="home" icon={FileTsxIcon}>home.tsx</TabsTrigger>
    <TabsTrigger value="about" icon={FileMdIcon}>about.md</TabsTrigger>
    <TabsTrigger value="stack" icon={BracketsCurlyIcon}>stack.json</TabsTrigger>
  </TabsList>
  <TabsContent value="home" className="p-5">…</TabsContent>
  <TabsContent value="about" className="p-5">…</TabsContent>
  <TabsContent value="stack" className="p-5">…</TabsContent>
</Tabs>

// A tab with no icon has nothing in front of its label
<TabsTrigger value="home">home.tsx</TabsTrigger>

// Tabs that are routes, as the editor's title bar:
// pass active, render your router's link with asChild
import { TabNav, TabNavLink } from "@/components/entrepta/tabs"

<TabNav aria-label="Pages" variant="window" end={<span>main</span>}>
  <TabNavLink asChild active={pathname === "/"} icon={HouseLineIcon}>
    <Link href="/">home.tsx</Link>
  </TabNavLink>
  <TabNavLink asChild active={pathname === "/about"} icon={UserSquareIcon}>
    <Link href="/about">about.md</Link>
  </TabNavLink>
</TabNav>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `indicator` | `ReactNode` | - | A glyph before the label of the active tab, for tabs with no icon. None by default (Tabs, TabNav) |
| `defaultValue` | `string` | - | Initially active tab (uncontrolled) |
| `value` | `string` | - | Controlled active tab |
| `onValueChange` | `(value: string) => void` | - | Callback when active tab changes |
| `end` | `ReactNode` | - | Pinned right, outside the scroller, as muted meta (TabsList, TabNav) |
| `icon` | `ReactNode \| Icon` | - | An element, or a Phosphor icon that fills when active and grows on hover |
| `active` | `boolean` | false | Marks the current route (TabNavLink) |
| `asChild` | `boolean` | false | Renders your router's link (TabNavLink) |
