# Tabs A tabbed interface component for organizing content into switchable panels. Supports primary and secondary visual styles, icons in tab triggers, and controlled or uncontrolled selection. ```tsx demo import { Tabs } from "@tenstorrent/vesper/tabs"; import { Typography } from "@tenstorrent/vesper/typography"; export default function TabsDemo() { return ( Overview content., }, { label: "Settings", value: "settings", content: Settings content., }, { label: "Activity", value: "activity", content: Activity content., }, ]} /> ); } ``` ## Options | Prop | Type | Description | Default | | ---------------- | -------------------------- | --------------------------------------------------------------------------------- | ------------- | | `variant` | `"primary" \| "secondary"` | The visual style variant of the tabs. | `"primary"` | | `items` | `TabItem[]` | The list of tab items. Each has `label`, `value`, optional `icon`, and `content`. | — | | `value` | `string` | The value for the selected tab (controlled mode). | — | | `defaultValue` | `string` | The value of the tab to select by default (uncontrolled mode). | — | | `onValueChange` | `(value: string) => void` | Callback fired when a new tab is selected. | — | | `activationMode` | `"automatic" \| "manual"` | Whether a tab is activated on focus (`automatic`) or on click (`manual`). | `"automatic"` | All other props are forwarded to the underlying `
` element, which wraps the tab list and its panels. ### TabItem | Prop | Type | Description | Default | | --------- | ----------- | ---------------------------------------------------------- | ------- | | `label` | `string` | The text label displayed in the tab trigger. | — | | `value` | `string` | A unique value identifying this tab. | — | | `icon` | `ReactNode` | An optional icon element rendered before the label. | — | | `content` | `ReactNode` | The content rendered in the panel when this tab is active. | — | ## Examples ### Defining items Each entry in the `items` array describes a tab and the panel it reveals: `label` is the text in the trigger, `value` identifies the tab, and `content` is whatever should be rendered when it is active. Tabs are rendered in the order they are provided: ```tsx demo import { Tabs } from "@tenstorrent/vesper/tabs"; import { Typography } from "@tenstorrent/vesper/typography"; export default function BasicTabs() { return ( Everything you need to know about this item. ), }, { label: "History", value: "history", content: ( A log of every change made to this item. ), }, ]} /> ); } ``` ### Variants `Tabs` can be rendered in one of two variants. The default `primary` variant is meant for page-level navigation, while the more compact `secondary` variant suits switching between views inside a smaller container, such as a card or a panel: ```tsx demo import { Tabs } from "@tenstorrent/vesper/tabs"; import { Typography } from "@tenstorrent/vesper/typography"; export default function TabsVariants() { const items = [ { label: "Preview", value: "preview", content: The rendered output., }, { label: "Code", value: "code", content: The source code., }, ]; return (
); } ``` ### Rendering icons Pass an icon as a `ReactNode` to an item's `icon` prop to render it before that tab's label: ```tsx demo import { Gear, Globe } from "@tenstorrent/vesper/icons"; import { Tabs } from "@tenstorrent/vesper/tabs"; import { Typography } from "@tenstorrent/vesper/typography"; export default function TabsWithIcons() { return ( , content: General settings., }, { label: "Advanced", value: "advanced", icon: , content: Advanced settings., }, ]} /> ); } ``` ### Uncontrolled vs controlled Render `Tabs` in an uncontrolled fashion to let them keep track of their own selection, passing `defaultValue` to choose which tab is active initially. If you omit `defaultValue`, the first tab is selected initially. If you need to control which tab is selected, pass `value` alongside `onValueChange`: ```tsx demo import { useState } from "react"; import { Tabs } from "@tenstorrent/vesper/tabs"; import { Typography } from "@tenstorrent/vesper/typography"; export default function ControlledTabs() { const [tab, setTab] = useState("first"); return ( First panel., }, { label: "Second", value: "second", content: Second panel., }, ]} /> ); } ``` ### Activation mode By default, moving focus between tab triggers with the arrow keys activates each tab as it receives focus. Pass `activationMode="manual"` to require `Enter`, `Space`, or a click before the panel changes, which is the better choice when a panel's content is expensive to render or fetch: ```tsx demo import { Tabs } from "@tenstorrent/vesper/tabs"; import { Typography } from "@tenstorrent/vesper/typography"; export default function ManualTabs() { return ( Focus the tabs and use the arrow keys: the panel only changes once you press Enter or Space. ), }, { label: "Logs", value: "logs", content: Logs panel., }, ]} /> ); } ```