> ## Documentation Index
> Fetch the complete documentation index at: https://neo.tvk.company/llms.txt
> Use this file to discover all available pages before exploring further.

# Tab Bar

> A navigation component that allows users to switch between different views or content sections.

## Examples

<Tabs>
  <Tab title="Basic Usage">
    <Frame caption="A simple tab bar with text-only tabs.">
      <img src="https://mintcdn.com/tvk/xOcwrKRVA4J0vbxn/images/widgets/navigation/tab-bar/tab_bar_basic_light.png?fit=max&auto=format&n=xOcwrKRVA4J0vbxn&q=85&s=27aab2e050059010ecb76791a5acc580" alt="Basic tab bar example" noZoom className="block dark:hidden" width="1536" height="384" data-path="images/widgets/navigation/tab-bar/tab_bar_basic_light.png" />

      <img src="https://mintcdn.com/tvk/xOcwrKRVA4J0vbxn/images/widgets/navigation/tab-bar/tab_bar_basic_dark.png?fit=max&auto=format&n=xOcwrKRVA4J0vbxn&q=85&s=876b0c2ce499d5f0366f97740b1273a4" alt="Basic tab bar example" noZoom className="hidden dark:block" width="1536" height="384" data-path="images/widgets/navigation/tab-bar/tab_bar_basic_dark.png" />
    </Frame>

    <CodeGroup>
      ```dart Basic Tab Bar lines theme={null}
      NeoTabBar(
        tabs: [
          NeoTab(id: "dashboard", label: "Dashboard"),
          NeoTab(id: "products", label: "Products"),
          NeoTab(id: "settings", label: "Settings"),
        ],
        activeTabId: "dashboard",
        onChange: (value) {
          // Handle state change
        },
      ),
      ```
    </CodeGroup>
  </Tab>

  <Tab title="With Icons">
    <Frame caption="Tab bar with icons for better visual recognition.">
      <img src="https://mintcdn.com/tvk/xOcwrKRVA4J0vbxn/images/widgets/navigation/tab-bar/tab_bar_icons_light.png?fit=max&auto=format&n=xOcwrKRVA4J0vbxn&q=85&s=03aec86439709b8420fdb7393d1f5e6d" alt="Tab bar with icons example" noZoom className="block dark:hidden" width="1536" height="384" data-path="images/widgets/navigation/tab-bar/tab_bar_icons_light.png" />

      <img src="https://mintcdn.com/tvk/xOcwrKRVA4J0vbxn/images/widgets/navigation/tab-bar/tab_bar_icons_dark.png?fit=max&auto=format&n=xOcwrKRVA4J0vbxn&q=85&s=b9d7c143fe93a4394f8fa97c69b246aa" alt="Tab bar with icons example" noZoom className="hidden dark:block" width="1536" height="384" data-path="images/widgets/navigation/tab-bar/tab_bar_icons_dark.png" />
    </Frame>

    <CodeGroup>
      ```dart With Icons lines theme={null}
      NeoTabBar(
        tabs: [
          NeoTab(id: "dashboard", label: "Dashboard", icon: PhosphorIconsRegular.house),
          NeoTab(id: "products", label: "Products", icon: PhosphorIconsRegular.package),
          NeoTab(id: "settings", label: "Settings", icon: PhosphorIconsRegular.gear),
        ],
        activeTabId: "dashboard",
        onChange: (value) {
          // Handle state change
        },
      ),
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Expanded Layout">
    <Frame caption="Tab bar with expanded layout that fills the available width.">
      <img src="https://mintcdn.com/tvk/xOcwrKRVA4J0vbxn/images/widgets/navigation/tab-bar/tab_bar_expanded_light.png?fit=max&auto=format&n=xOcwrKRVA4J0vbxn&q=85&s=2e004e1648dba7ec111db1b0d22d2c05" alt="Expanded tab bar example" noZoom className="block dark:hidden" width="1536" height="384" data-path="images/widgets/navigation/tab-bar/tab_bar_expanded_light.png" />

      <img src="https://mintcdn.com/tvk/xOcwrKRVA4J0vbxn/images/widgets/navigation/tab-bar/tab_bar_expanded_dark.png?fit=max&auto=format&n=xOcwrKRVA4J0vbxn&q=85&s=a04c32f9f0d041df0ecd80062f9e762e" alt="Expanded tab bar example" noZoom className="hidden dark:block" width="1536" height="384" data-path="images/widgets/navigation/tab-bar/tab_bar_expanded_dark.png" />
    </Frame>

    <CodeGroup>
      ```dart Expanded Layout lines theme={null}
      NeoTabBar(
        tabs: [
          NeoTab(id: "dashboard", label: "Dashboard"),
          NeoTab(id: "products", label: "Products"),
          NeoTab(id: "settings", label: "Settings"),
        ],
        isExpanded: true,
        activeTabId: "dashboard",
        onChange: (value) {
          // Handle state change
        },
      ),
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Properties

### Required

<ParamField path="tabs" type="List<NeoTab>" required>
  A list of tabs to display in the tab bar. Each tab must have a unique `id`.
</ParamField>

<ParamField path="activeTabId" type="String" required>
  The ID of the currently active tab. Must match one of the tab IDs in the `tabs` list.
</ParamField>

<ParamField path="onChange" type="ValueChanged<String>" required>
  Callback function called when a tab is selected. Receives the ID of the selected tab.
</ParamField>

### Content

<ParamField path="spacing" type="double">
  Custom spacing between tabs. If not provided, uses theme default spacing.
</ParamField>

### Layout

<ParamField path="isExpanded" type="bool" default="false">
  Whether the tab bar should expand to fill the available width. When true, tabs are distributed evenly. When false, tabs wrap naturally.
</ParamField>

## Tab Properties

The `NeoTab` class represents individual tabs within the tab bar:

### Required

<ParamField path="id" type="String">
  A unique identifier for the tab. This is used to track the active tab and is passed to the `onChange` callback.
</ParamField>

<ParamField path="label" type="String">
  The text label displayed on the tab.
</ParamField>

### Content

<ParamField path="icon" type="PhosphorIconData">
  An optional icon to display alongside the label.
</ParamField>

## Best Practices

* **Width Constraints**: When using `isExpanded: true`, always provide width constraints to prevent layout issues by wrapping in `Expanded`, `ConstrainedBox`, `SizedBox`, etc.
* Combine with [`NeoHaptics`](/utilities/haptics) in the `onChanged` callback for enhanced user experience on supported devices.
* Always ensure tab IDs are unique within a single `NeoTabBar` to prevent errors.

## Integration Notes

* `NeoTabBar` uses [`NeoButton`](/widgets/buttons/button) widgets internally, which means it inherits all the theming and interaction behaviors of buttons.
* The active tab uses the [`filled`](/widgets/buttons/button#neobuttonvariant) variant while inactive tabs use the [`ghost`](/widgets/buttons/button#neobuttonvariant) variant.
