# Tabs

Import: `import { Tabs } from '@neo4j-ndl/react'`

## Props

### Tabs

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `as` | `ElementType<any, keyof IntrinsicElements>` |  |  | An override of the default HTML tag of the root of the component. Can also be another React component. |
| `children` | `ReactNode` | ✅ |  | The content dislayed in the tabs |
| `fill` | `'filled' \| 'underline'` |  | `underline` | The fill type of the tabs |
| `onBackground` | `'default' \| 'weak'` |  | `weak` | What background the Tabs is placed on. This affects the gradient background of the scroll navigation buttons. |
| `onChange` | `(e: U) => void` | ✅ |  | Callback function triggered when a new tab is selected |
| `ref` | `any` |  |  | A ref to apply to the root element. |
| `size` | `'large' \| 'small'` |  | `large` | The size of the tabs |
| `value` | `string` | ✅ |  | The currently active tabId |

### Tabs.Badge

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `children` | `ReactNode` | ✅ |  | The content of the badge |
| `ref` | `Ref<HTMLSpanElement>` |  |  | A ref to apply to the root element. |

### Tabs.Tab

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `as` | `ElementType<any, keyof IntrinsicElements>` |  |  | An override of the default HTML tag of the root of the component. Can also be another React component. |
| `children` | `ReactNode` | ✅ |  | The content of the tab |
| `description` | `string` |  |  | A string that will be shown as a tooltip when hovering over the button  it also acts as an aria-label- {@link https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label} |
| `id` | `string` | ✅ |  | The id of the tab |
| `isDisabled` | `boolean` |  | `false` | Whether the tab is disabled |
| `ref` | `any` |  |  | A ref to apply to the root element. |
| `tooltipProps` | `TooltipObjectProps` |  |  | Props for the tooltip component. |

When the `description` prop is set, hovering over the tab will show a tooltip with the text provided in the `description` prop. `tooltipProps` can be used to customize the tooltip appearance. The `TooltipObjectProps` type is defined as: `{ root?: Partial<React.ComponentProps<typeof Tooltip>>; trigger?: Partial<React.ComponentProps<typeof Tooltip.Trigger>>; content?: Partial<React.ComponentProps<typeof Tooltip.Content>>; }`, see the Tooltip component for more details.

### Tabs.TabPanel

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `as` | `ElementType<any, keyof IntrinsicElements>` |  |  | An override of the default HTML tag of the root of the component. Can also be another React component. |
| `children` | `ReactNode` | ✅ |  | The content displayed in the tab panel |
| `ref` | `any` |  |  | A ref to apply to the root element. |
| `tabId` | `string` | ✅ |  | The id of the tab panel |
| `value` | `string` | ✅ |  | The currently selected tabId. The tab is visible if the value is equal to the tabId |

## Accessibility

## Implementation guidelines

The tabs is using the `role='tablist'` to convey related selection options and keyboard navigation is supported using the `role='tab'` and `role='tabpanel'`. It's important to give each tab an id and each tab panel an id.

## Examples

### Default

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { Tabs, Typography } from '@neo4j-ndl/react';
import { useState } from 'react';

type TabValues = '0' | '1' | '2';

const Component = () => {
  const [value, setValue] = useState<TabValues>('0');

  return (
    <div>
      <Tabs value={value} onChange={setValue} className="n-mb-token-8">
        <Tabs.Tab id="0">Tab 1</Tabs.Tab>
        <Tabs.Tab id="1">Tab 2</Tabs.Tab>
        <Tabs.Tab id="2">Tab 3</Tabs.Tab>
      </Tabs>
      <Tabs.TabPanel value={value} tabId="0">
        <Typography variant="body-medium">Tab 1 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="1">
        <Typography variant="body-medium">Tab 2 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="2">
        <Typography variant="body-medium">Tab 3 content</Typography>
      </Tabs.TabPanel>
    </div>
  );
};

export default Component;
```

### Badge

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { Tabs, Typography } from '@neo4j-ndl/react';
import { useState } from 'react';

type TabValues = '0' | '1' | '2';

const Component = () => {
  const [value, setValue] = useState<TabValues>('0');

  return (
    <div>
      <Tabs value={value} onChange={setValue} className="n-mb-token-8">
        <Tabs.Tab id="0">Tab 1</Tabs.Tab>
        <Tabs.Tab id="1">
          Tab 2 <Tabs.Badge>5</Tabs.Badge>
        </Tabs.Tab>
        <Tabs.Tab id="2">Tab 3</Tabs.Tab>
      </Tabs>
      <Tabs.TabPanel value={value} tabId="0">
        <Typography variant="body-medium">Tab 1 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="1">
        <Typography variant="body-medium">Tab 2 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="2">
        <Typography variant="body-medium">Tab 3 content</Typography>
      </Tabs.TabPanel>
    </div>
  );
};

export default Component;
```

### Disabled

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { Tabs, Typography } from '@neo4j-ndl/react';
import { useState } from 'react';

type TabValues = '0' | '1' | '2';

const Component = () => {
  const [value, setValue] = useState<TabValues>('0');

  return (
    <div>
      <Tabs value={value} onChange={setValue} className="n-mb-token-8">
        <Tabs.Tab id="0">Tab 1</Tabs.Tab>
        <Tabs.Tab id="1">Tab 2</Tabs.Tab>
        <Tabs.Tab id="2" isDisabled={true}>
          Tab 3
        </Tabs.Tab>
      </Tabs>
      <Tabs.TabPanel value={value} tabId="0">
        <Typography variant="body-medium">Tab 1 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="1">
        <Typography variant="body-medium">Tab 2 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="2">
        <Typography variant="body-medium">Tab 3 content</Typography>
      </Tabs.TabPanel>
    </div>
  );
};

export default Component;
```

### Fill Variants

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { Tabs, Typography } from '@neo4j-ndl/react';
import { useState } from 'react';

type TabValues = '0' | '1' | '2';

const Component = () => {
  const [underlineValue, setUnderlineValue] = useState<TabValues>('0');
  const [filledValue, setFilledValue] = useState<TabValues>('0');

  return (
    <div className="n-flex n-gap-token-8">
      <div className="n-flex n-flex-col n-gap-token-32">
        <Typography variant="label">Underline (Default)</Typography>
        <div>
          <Tabs
            value={underlineValue}
            onChange={setUnderlineValue}
            className="n-mb-token-8"
          >
            <Tabs.Tab id="0">Tab 1</Tabs.Tab>
            <Tabs.Tab id="1">Tab 2</Tabs.Tab>
            <Tabs.Tab id="2">Tab 3</Tabs.Tab>
          </Tabs>
          <Tabs.TabPanel value={underlineValue} tabId="0">
            <Typography variant="body-medium">Tab 1 content</Typography>
          </Tabs.TabPanel>
          <Tabs.TabPanel value={underlineValue} tabId="1">
            <Typography variant="body-medium">Tab 2 content</Typography>
          </Tabs.TabPanel>
          <Tabs.TabPanel value={underlineValue} tabId="2">
            <Typography variant="body-medium">Tab 3 content</Typography>
          </Tabs.TabPanel>
        </div>
      </div>

      <div className="n-flex n-flex-col n-gap-token-8">
        <Typography variant="label">Filled</Typography>
        <div>
          <Tabs
            value={filledValue}
            onChange={setFilledValue}
            fill="filled"
            className="n-mb-token-8"
          >
            <Tabs.Tab id="0">Tab 1</Tabs.Tab>
            <Tabs.Tab id="1">Tab 2</Tabs.Tab>
            <Tabs.Tab id="2">Tab 3</Tabs.Tab>
          </Tabs>
          <Tabs.TabPanel value={filledValue} tabId="0">
            <Typography variant="body-medium">Tab 1 content</Typography>
          </Tabs.TabPanel>
          <Tabs.TabPanel value={filledValue} tabId="1">
            <Typography variant="body-medium">Tab 2 content</Typography>
          </Tabs.TabPanel>
          <Tabs.TabPanel value={filledValue} tabId="2">
            <Typography variant="body-medium">Tab 3 content</Typography>
          </Tabs.TabPanel>
        </div>
      </div>
    </div>
  );
};

export default Component;
```

### Overflow

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { Tabs, Typography } from '@neo4j-ndl/react';
import { useState } from 'react';

const Component = () => {
  const [value, setValue] = useState<string>('0');

  return (
    <div className="n-w-80">
      <Tabs value={value} onChange={setValue} className="n-mb-token-8">
        <Tabs.Tab id="0">Tab 1</Tabs.Tab>
        <Tabs.Tab id="1">Tab 2</Tabs.Tab>
        <Tabs.Tab id="2">Tab 3</Tabs.Tab>
        <Tabs.Tab id="3">Tab 4</Tabs.Tab>
        <Tabs.Tab id="4">Tab 5</Tabs.Tab>
        <Tabs.Tab id="5">Tab 6</Tabs.Tab>
        <Tabs.Tab id="6">Tab 7</Tabs.Tab>
        <Tabs.Tab id="7">Tab 8</Tabs.Tab>
        <Tabs.Tab id="8">Tab 9</Tabs.Tab>
        <Tabs.Tab id="9">
          Tab 10 is waay too long and will be cut off on smaller screens
        </Tabs.Tab>
      </Tabs>
      <Tabs.TabPanel value={value} tabId="0">
        <Typography variant="body-medium">Tab 1 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="1">
        <Typography variant="body-medium">Tab 2 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="2">
        <Typography variant="body-medium">Tab 3 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="3">
        <Typography variant="body-medium">Tab 4 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="4">
        <Typography variant="body-medium">Tab 5 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="5">
        <Typography variant="body-medium">Tab 6 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="6">
        <Typography variant="body-medium">Tab 7 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="7">
        <Typography variant="body-medium">Tab 8 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="8">
        <Typography variant="body-medium">Tab 9 content</Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="9">
        <Typography variant="body-medium">Tab 10 content</Typography>
      </Tabs.TabPanel>
    </div>
  );
};

export default Component;
```

### Sizes

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { Tabs, Typography } from '@neo4j-ndl/react';
import { useState } from 'react';

type TabValues = '0' | '1' | '2';

const Component = () => {
  const [smallValue, setSmallValue] = useState<TabValues>('0');
  const [largeValue, setLargeValue] = useState<TabValues>('0');

  return (
    <div className="n-flex n-gap-token-8">
      <div className="n-flex n-flex-col n-gap-token-8">
        <Typography variant="label">Small Size</Typography>
        <div className="n-w-fit">
          <Tabs
            value={smallValue}
            onChange={setSmallValue}
            size="small"
            className="n-mb-token-8"
          >
            <Tabs.Tab id="0">Tab 1</Tabs.Tab>
            <Tabs.Tab id="1">Tab 2</Tabs.Tab>
            <Tabs.Tab id="2">Tab 3</Tabs.Tab>
          </Tabs>
          <Tabs.TabPanel value={smallValue} tabId="0">
            <Typography variant="body-small">
              Content for small tab 1
            </Typography>
          </Tabs.TabPanel>
          <Tabs.TabPanel value={smallValue} tabId="1">
            <Typography variant="body-small">
              Content for small tab 2
            </Typography>
          </Tabs.TabPanel>
          <Tabs.TabPanel value={smallValue} tabId="2">
            <Typography variant="body-small">
              Content for small tab 3
            </Typography>
          </Tabs.TabPanel>
        </div>
      </div>

      <div className="n-flex n-flex-col n-gap-token-8">
        <Typography variant="label">Large Size (Default)</Typography>
        <Tabs
          value={largeValue}
          onChange={setLargeValue}
          size="large"
          className="n-mb-token-8"
        >
          <Tabs.Tab id="0">Tab 1</Tabs.Tab>
          <Tabs.Tab id="1">Tab 2</Tabs.Tab>
          <Tabs.Tab id="2">Tab 3</Tabs.Tab>
        </Tabs>
        <Tabs.TabPanel value={largeValue} tabId="0">
          <Typography variant="body-medium">Content for large tab 1</Typography>
        </Tabs.TabPanel>
        <Tabs.TabPanel value={largeValue} tabId="1">
          <Typography variant="body-medium">Content for large tab 2</Typography>
        </Tabs.TabPanel>
        <Tabs.TabPanel value={largeValue} tabId="2">
          <Typography variant="body-medium">Content for large tab 3</Typography>
        </Tabs.TabPanel>
      </div>
    </div>
  );
};

export default Component;
```

### With Icons

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { Tabs, Typography } from '@neo4j-ndl/react';
import {
  CircleStackIconOutline,
  DatabasePlusIcon,
  InboxArrowDownIconOutline,
} from '@neo4j-ndl/react/icons';
import { useState } from 'react';

type TabValues = 'database' | 'add' | 'inbox';

const Component = () => {
  const [value, setValue] = useState<TabValues>('database');

  return (
    <div className="n-mt-5">
      <Tabs value={value} onChange={setValue} className="n-mb-token-8">
        <Tabs.Tab id="database" description="Database">
          <CircleStackIconOutline />
        </Tabs.Tab>
        <Tabs.Tab id="add" description="Add database">
          <DatabasePlusIcon />
        </Tabs.Tab>
        <Tabs.Tab id="inbox" description="Inbox">
          <InboxArrowDownIconOutline />
        </Tabs.Tab>
      </Tabs>
      <Tabs.TabPanel value={value} tabId="database">
        <Typography variant="body-medium">
          Database management and operations.
        </Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="add">
        <Typography variant="body-medium">
          Add new database or connection.
        </Typography>
      </Tabs.TabPanel>
      <Tabs.TabPanel value={value} tabId="inbox">
        <Typography variant="body-medium">
          Inbox notifications and messages.
        </Typography>
      </Tabs.TabPanel>
    </div>
  );
};

export default Component;
```
