# React Tabs Components

> The CoreUI React Tabs component provides a flexible and accessible way to create tabbed navigation in your application. It supports various styles and configurations to meet different design requirements.

## Example

The basic React tabs example uses the `variant="tabs"` props to generate a tabbed interface.

```html
import React from 'react'
import { CTab, CTabContent, CTabList, CTabPanel, CTabs } from '@coreui/react'

export const TabsExample = () => {
  return (
    <CTabs defaultActiveItemKey="profile">
      <CTabList variant="tabs">
        <CTab itemKey="home">Home</CTab>
        <CTab itemKey="profile">Profile</CTab>
        <CTab itemKey="contact">Contact</CTab>
        <CTab disabled itemKey="disabled">
          Disabled
        </CTab>
      </CTabList>
      <CTabContent>
        <CTabPanel className="p-3" itemKey="home">
          Home tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="profile">
          Profile tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="contact">
          Contact tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="disabled">
          Disabled tab content
        </CTabPanel>
      </CTabContent>
    </CTabs>
  )
}
```

## Available styles

Change the style of `<CTabs>`'s component with modifiers and utilities. Mix and match as needed, or build your own.

### Unstyled

If you don’t provide the `variant` prop, the component will default to a basic style.

```html
import React from 'react'
import { CTab, CTabContent, CTabList, CTabPanel, CTabs } from '@coreui/react'

export const TabsUnstyledExample = () => {
  return (
    <CTabs defaultActiveItemKey="profile">
      <CTabList>
        <CTab itemKey="home">Home</CTab>
        <CTab itemKey="profile">Profile</CTab>
        <CTab itemKey="contact">Contact</CTab>
        <CTab disabled itemKey="disabled">
          Disabled
        </CTab>
      </CTabList>
      <CTabContent>
        <CTabPanel className="p-3" itemKey="home">
          Home tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="profile">
          Profile tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="contact">
          Contact tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="disabled">
          Disabled tab content
        </CTabPanel>
      </CTabContent>
    </CTabs>
  )
}
```

### Pills

Take that same code, but use `variant="pills"` instead:

```html
import React from 'react'
import { CTab, CTabContent, CTabList, CTabPanel, CTabs } from '@coreui/react'

export const TabsPillsExample = () => {
  return (
    <CTabs defaultActiveItemKey={2}>
      <CTabList variant="pills">
        <CTab aria-controls="home-tab-pane" itemKey={1}>
          Home
        </CTab>
        <CTab aria-controls="profile-tab-pane" itemKey={2}>
          Profile
        </CTab>
        <CTab aria-controls="contact-tab-pane" itemKey={3}>
          Contact
        </CTab>
        <CTab aria-controls="disabled-tab-pane" disabled itemKey={4}>
          Disabled
        </CTab>
      </CTabList>
      <CTabContent>
        <CTabPanel className="p-3" aria-labelledby="home-tab-pane" itemKey={1}>
          Home tab content
        </CTabPanel>
        <CTabPanel className="p-3" aria-labelledby="profile-tab-pane" itemKey={2}>
          Profile tab content
        </CTabPanel>
        <CTabPanel className="p-3" aria-labelledby="contact-tab-pane" itemKey={3}>
          Contact tab content
        </CTabPanel>
        <CTabPanel className="p-3" aria-labelledby="disabled-tab-pane" itemKey={4}>
          Disabled tab content
        </CTabPanel>
      </CTabContent>
    </CTabs>
  )
}
```

### Underline

Take that same code, but use `variant="underline"` instead:

```html
import React from 'react'
import { CTab, CTabContent, CTabList, CTabPanel, CTabs } from '@coreui/react'

export const TabsUnderlineExample = () => {
  return (
    <CTabs defaultActiveItemKey={2}>
      <CTabList variant="underline">
        <CTab aria-controls="home-tab-pane" itemKey={1}>
          Home
        </CTab>
        <CTab aria-controls="profile-tab-pane" itemKey={2}>
          Profile
        </CTab>
        <CTab aria-controls="contact-tab-pane" itemKey={3}>
          Contact
        </CTab>
        <CTab aria-controls="disabled-tab-pane" disabled itemKey={4}>
          Disabled
        </CTab>
      </CTabList>
      <CTabContent>
        <CTabPanel className="p-3" aria-labelledby="home-tab-pane" itemKey={1}>
          Home tab content
        </CTabPanel>
        <CTabPanel className="p-3" aria-labelledby="profile-tab-pane" itemKey={2}>
          Profile tab content
        </CTabPanel>
        <CTabPanel className="p-3" aria-labelledby="contact-tab-pane" itemKey={3}>
          Contact tab content
        </CTabPanel>
        <CTabPanel className="p-3" aria-labelledby="disabled-tab-pane" itemKey={4}>
          Disabled tab content
        </CTabPanel>
      </CTabContent>
    </CTabs>
  )
}
```

### Underline border

Take that same code, but use `variant="underline-border"` instead:

```html
import React from 'react'
import { CTab, CTabContent, CTabList, CTabPanel, CTabs } from '@coreui/react'

export const TabsUnderlineBorderExample = () => {
  return (
    <CTabs defaultActiveItemKey={2}>
      <CTabList variant="underline-border">
        <CTab aria-controls="home-tab-pane" itemKey={1}>
          Home
        </CTab>
        <CTab aria-controls="profile-tab-pane" itemKey={2}>
          Profile
        </CTab>
        <CTab aria-controls="contact-tab-pane" itemKey={3}>
          Contact
        </CTab>
        <CTab aria-controls="disabled-tab-pane" disabled itemKey={4}>
          Disabled
        </CTab>
      </CTabList>
      <CTabContent>
        <CTabPanel className="p-3" aria-labelledby="home-tab-pane" itemKey={1}>
          Home tab content
        </CTabPanel>
        <CTabPanel className="p-3" aria-labelledby="profile-tab-pane" itemKey={2}>
          Profile tab content
        </CTabPanel>
        <CTabPanel className="p-3" aria-labelledby="contact-tab-pane" itemKey={3}>
          Contact tab content
        </CTabPanel>
        <CTabPanel className="p-3" aria-labelledby="disabled-tab-pane" itemKey={4}>
          Disabled tab content
        </CTabPanel>
      </CTabContent>
    </CTabs>
  )
}
```

### Enclosed

Use the `variant="enclosed"` class to give your navigation items a subtle border and rounded styling.

```html
import React from 'react'
import { CTab, CTabContent, CTabList, CTabPanel, CTabs } from '@coreui/react'

export const TabsEnclosedExample = () => {
  return (
    <CTabs defaultActiveItemKey="profile">
      <CTabList variant="enclosed">
        <CTab itemKey="home">Home</CTab>
        <CTab itemKey="profile">Profile</CTab>
        <CTab itemKey="contact">Contact</CTab>
        <CTab disabled itemKey="disabled">
          Disabled
        </CTab>
      </CTabList>
      <CTabContent>
        <CTabPanel className="p-3" itemKey="home">
          Home tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="profile">
          Profile tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="contact">
          Contact tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="disabled">
          Disabled tab content
        </CTabPanel>
      </CTabContent>
    </CTabs>
  )
}
```

### Enclosed pills 

Use the `variant="enclosed-pills"` to achieve a pill-style appearance for each nav item, using pill-shaped borders and smoother outlines.

```html
import React from 'react'
import { CTab, CTabContent, CTabList, CTabPanel, CTabs } from '@coreui/react'

export const TabsEnclosedPillsExample = () => {
  return (
    <CTabs defaultActiveItemKey="profile">
      <CTabList variant="enclosed-pills">
        <CTab itemKey="home">Home</CTab>
        <CTab itemKey="profile">Profile</CTab>
        <CTab itemKey="contact">Contact</CTab>
        <CTab disabled itemKey="disabled">
          Disabled
        </CTab>
      </CTabList>
      <CTabContent>
        <CTabPanel className="p-3" itemKey="home">
          Home tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="profile">
          Profile tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="contact">
          Contact tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="disabled">
          Disabled tab content
        </CTabPanel>
      </CTabContent>
    </CTabs>
  )
}
```

### Fill and justify

Force your `<CTabs>`'s contents to extend the full available width one of two modifier classes. To proportionately fill all available space use `layout="fill"`. Notice that all horizontal space is occupied, but not every nav item has the same width.

```html
import React from 'react'
import { CTab, CTabContent, CTabList, CTabPanel, CTabs } from '@coreui/react'

export const TabsUnstyledFillAndJustifyExample = () => {
  return (
    <CTabs defaultActiveItemKey={2}>
      <CTabList variant="tabs" layout="fill">
        <CTab aria-controls="home-tab-pane" itemKey={1}>
          Home
        </CTab>
        <CTab aria-controls="profile-tab-pane" itemKey={2}>
          Profile tab with longer content
        </CTab>
        <CTab aria-controls="contact-tab-pane" itemKey={3}>
          Contact
        </CTab>
        <CTab aria-controls="disabled-tab-pane" disabled itemKey={4}>
          Disabled
        </CTab>
      </CTabList>
      <CTabContent>
        <CTabPanel className="py-3" aria-labelledby="home-tab-pane" itemKey={1}>
          Home tab content
        </CTabPanel>
        <CTabPanel className="py-3" aria-labelledby="profile-tab-pane" itemKey={2}>
          Profile tab content
        </CTabPanel>
        <CTabPanel className="py-3" aria-labelledby="contact-tab-pane" itemKey={3}>
          Contact tab content
        </CTabPanel>
        <CTabPanel className="py-3" aria-labelledby="disabled-tab-pane" itemKey={4}>
          Disabled tab content
        </CTabPanel>
      </CTabContent>
    </CTabs>
  )
}
```

For equal-width elements, use `layout="justified"`. All horizontal space will be occupied by nav links, but unlike the `layout="fill"` above, every nav item will be the same width.

```html
import React from 'react'
import { CTab, CTabContent, CTabList, CTabPanel, CTabs } from '@coreui/react'

export const TabsUnstyledFillAndJustify2Example = () => {
  return (
    <CTabs defaultActiveItemKey={2}>
      <CTabList variant="tabs" layout="justified">
        <CTab aria-controls="home-tab-pane" itemKey={1}>
          Home
        </CTab>
        <CTab aria-controls="profile-tab-pane" itemKey={2}>
          Profile
        </CTab>
        <CTab aria-controls="contact-tab-pane" itemKey={3}>
          Contact
        </CTab>
        <CTab aria-controls="disabled-tab-pane" disabled itemKey={4}>
          Disabled
        </CTab>
      </CTabList>
      <CTabContent>
        <CTabPanel className="py-3" aria-labelledby="home-tab-pane" itemKey={1}>
          Home tab content
        </CTabPanel>
        <CTabPanel className="py-3" aria-labelledby="profile-tab-pane" itemKey={2}>
          Profile tab content
        </CTabPanel>
        <CTabPanel className="py-3" aria-labelledby="contact-tab-pane" itemKey={3}>
          Contact tab content
        </CTabPanel>
        <CTabPanel className="py-3" aria-labelledby="disabled-tab-pane" itemKey={4}>
          Disabled tab content
        </CTabPanel>
      </CTabContent>
    </CTabs>
  )
}
```

Sure! Here's a polished, production-ready **documentation section** (Markdown-style) explaining the **controlled usage** of the `<CTabs>` component, with a clear example:

---

## Controlled Tabs

Use the `activeItemKey` prop to control which tab is currently active. In this mode, the parent component is responsible for managing the active state and responding to user interactions via the `onChange` callback.

This is useful when you need to synchronize the tab state with your application logic, such as routing or complex UI state management.

**Key Points**

- `activeItemKey` sets the currently active tab.
- `onChange` receives the new `itemKey` when a tab is clicked.
- You must manually update `activeItemKey` in your state based on `onChange`.

> 💡 If you prefer the tabs to manage their own state, use `defaultActiveItemKey` instead.

```html
import React, { useState } from 'react'
import { CTab, CTabContent, CTabList, CTabPanel, CTabs } from '@coreui/react'

export const TabsControlledExample = () => {
  const [activeTab, setActiveTab] = useState<number | string>('profile')

  return (
    <CTabs activeItemKey={activeTab} onChange={setActiveTab}>
      <CTabList variant="tabs">
        <CTab itemKey="home">Home</CTab>
        <CTab itemKey="profile">Profile</CTab>
        <CTab itemKey="contact">Contact</CTab>
        <CTab disabled itemKey="disabled">
          Disabled
        </CTab>
      </CTabList>
      <CTabContent>
        <CTabPanel className="p-3" itemKey="home">
          Home tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="profile">
          Profile tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="contact">
          Contact tab content
        </CTabPanel>
        <CTabPanel className="p-3" itemKey="disabled">
          Disabled tab content
        </CTabPanel>
      </CTabContent>
    </CTabs>
  )
}
```

## Accessibility

Dynamic tabbed interfaces, as described in the [<abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr> Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#tabpanel), require `role="tablist"`, `role="tab"`, `role="tabpanel"`, and additional `aria-` attributes in order to convey their structure, functionality and current state to users of assistive technologies (such as screen readers).

### WAI-ARIA Roles

- The element that serves as the container for the set of tabs has the role `tablist`.
- Each element that serves as a tab has the role `tab` and is contained within the element with the role `tablist`.
- Each element that contains the content panel for a tab has the role `tabpanel`.
- If the tab list has a visible label, the element with the role `tablist` has `aria-labelledby` set to a value that refers to the labeling element. Otherwise, the `tablist` element has a label provided by `aria-label`.
- Each element with the role `tab` has the property `aria-controls` referring to its associated `tabpanel` element.
- The active tab element has the state `aria-selected` set to `true`, and all other tab elements have it set to `false`.
- Each element with the role `tabpanel` has the property `aria-labelledby` referring to its associated `tab` element.

Our React Tabs component automatically manages all `role="..."` and `aria-` attributes for accessibility. It also handles the selected state by adding `aria-selected="true"` to the active tab. Additionally, you have the flexibility to manually set these attributes, as shown in the example below:

```jsx
<CTabs activeItemKey={2}>
  <CTabList variant="tabs">
    <CTab id="home-tab" aria-controls="home-tab-pane" itemKey={1}>Home</CTab>
    <CTab id="profile-tab" aria-controls="profile-tab-pane" itemKey={2}>Profile</CTab>
    <CTab id="contact-tab" aria-controls="contact-tab-pane" itemKey={3}>Contact</CTab>
    <CTab id="disabled-tab" aria-controls="disabled-tab-pane" disabled itemKey={4}>Disabled</CTab>
  </CTabList>
  <CTabContent>
    <CTabPanel id="home-tab-pane" className="p-3" aria-labelledby="home-tab-pane" aria-labelledby="home-tab" itemKey={1}>
      Home tab content
    </CTabPanel>
    <CTabPanel id="profile-tab-pane" className="p-3" aria-labelledby="profile-tab-pane" aria-labelledby="profile-tab" itemKey={2}>
      Profile tab content
    </CTabPanel>
    <CTabPanel id="contact-tab-pane" className="p-3" aria-labelledby="contact-tab-pane" aria-labelledby="contact-tab" itemKey={3}>
      Contact tab content
    </CTabPanel>
    <CTabPanel id="disabled-tab-pane" className="p-3" aria-labelledby="disabled-tab-pane" aria-labelledby="disabled-tab" itemKey={4}>
      Disabled tab content
    </CTabPanel>
  </CTabContent>
</CTabs>
```

This example demonstrates how to manually set `aria-selected`, `aria-controls`, and `aria-labelledby` attributes on your `<CTab>`'s and `<CTabPanels>`'s.

### Keyboard Interaction

**When focus enters the tab list:**

<kbd>Tab</kbd>: It places focus on the active `tab` element.

**When focus is on a tab element:**

<kbd>Tab</kbd>: Moves focus to the next element in the tab sequence, typically the tabpanel unless the first focusable element inside the tabpanel is found earlier.

<kbd>Left Arrow</kbd>: Moves focus to the previous tab. If on the first tab, it wraps around to the last tab.

<kbd>Right Arrow</kbd>: Moves focus to the next tab. If on the last tab, it wraps around to the first tab.

<kbd>Home</kbd>: Moves focus to the first tab.

<kbd>End</kbd>: Moves focus to the last tab.

## API

Check out the documentation below for a comprehensive guide to all the props you can use with the components mentioned here.

- [&lt;CTab /&gt;](./api/#ctab)
- [&lt;CTabContent /&gt;](./api/#ctabcontent)
- [&lt;CTabList /&gt;](./api/#ctablist)
- [&lt;CTabPanel /&gt;](./api/#ctabpanel)
- [&lt;CTabs /&gt;](./api/#ctabs)
