# Tabs

> Cherry Tabs component - accessible tabbed panels with keyboard navigation and controlled or uncontrolled selection.

Source: https://cherry.al/code/tabs

> For the complete documentation index, see [llms.txt](https://cherry.al/llms.txt).

# Tabs

<iframe className="light-only" src="https://demo.cherry.al/preview/tabs?theme=light" title="Tabs" loading="lazy" style={{ width: "100%", height: "360px", border: "1px solid var(--color-grayLight)", borderRadius: "12px" }} />
<iframe className="dark-only" src="https://demo.cherry.al/preview/tabs?theme=dark" title="Tabs" loading="lazy" style={{ width: "100%", height: "360px", border: "1px solid var(--color-grayLight)", borderRadius: "12px" }} />

The Tabs component groups related content into panels behind a horizontal list of triggers. Wrap each panel in a `TabContent` with a `title`; only the active panel is rendered.

Tabs follow the WAI-ARIA tabs pattern: the triggers form a `tablist` with roving tabindex, ArrowLeft and ArrowRight cycle through the tabs (wrapping at the edges), Home and End jump to the first and last tab, and moving focus also selects the tab.

For design guidelines and all interactive states, see the [Tabs](/tabs) design page.

```jsx
import React from "react";
import { Tabs, TabContent } from "cherry-styled-components";

export default function Page() {
  return (
    <Tabs>
      <TabContent title="Overview">Overview panel content.</TabContent>
      <TabContent title="Details">Details panel content.</TabContent>
      <TabContent title="Settings">Settings panel content.</TabContent>
    </Tabs>
  );
}
```

By default Tabs manage their own selection, starting at `defaultActiveTab` (index 0 if omitted). Pass `activeTab` to control the selection from the parent, paired with `onTabChange`:

```jsx
const [tab, setTab] = useState(0);

<Tabs activeTab={tab} onTabChange={setTab}>
  <TabContent title="Overview">Overview panel content.</TabContent>
  <TabContent title="Details">Details panel content.</TabContent>
</Tabs>;
```

## Properties

### Tabs

<Field value="children" type="React.ReactNode">
  The panels, typically `TabContent` elements. Any valid React element with a
  non-empty string `title` prop becomes a tab (the element type itself is not
  checked); children without one are ignored.
</Field>

<Field value="activeTab" type="number">
  Optional controlled active tab index. When provided the parent owns the
  selection; pair it with `onTabChange`.
</Field>

<Field value="defaultActiveTab" type="number">
  Initial tab index for uncontrolled usage. Defaults to `0`.
</Field>

<Field value="onTabChange" type="(index: number) => void">
  Called with the new index whenever a tab is selected, by click or keyboard.
</Field>

All other standard `div` attributes (`className`, `id`, `style`, `aria-*`, and
so on) are passed through to the root element; only the native `onChange`
attribute is excluded.

### TabContent

<Field value="title" type="string" required>
  The tab trigger label. Required and must be non-empty.
</Field>

<Field value="children" type="React.ReactNode">
  The panel content rendered while this tab is active.
</Field>

<Button href="https://github.com/cherry-design-system/styled-components/blob/main/src/lib/tabs.tsx" icon="code" iconPosition="left">
  View Source
</Button>
