---
url: /docs/components/tabs/frameworks/elements.md
---
# Tabs - Elements

Tabs are used to group content, allowing users to navigate views without leaving the page.

## Accessibility

The tabs component follows the WAI-ARIA Tabs pattern:

* The tab list gets `role="tablist"`
* Each tab button gets `role="tab"` with `aria-selected` reflecting its active state
* Each tab button gets `aria-controls` pointing to its associated panel
* Each panel gets `role="tabpanel"` with `aria-labelledby` pointing to its associated tab
* Keyboard navigation is supported:
  * `ArrowLeft`/`ArrowRight`: Navigate between tabs
  * `Home`: Move to first tab
  * `End`: Move to last tab

## Usage

The tabs component consists of three custom elements that work together:

* `<w-tabs>` - The container that manages tab state and keyboard navigation
* `<w-tab>` - Individual tab buttons
* `<w-tab-panel>` - Content panels associated with each tab

Each `<w-tab>` has a `for` attribute that matches the `id` of its corresponding `<w-tab-panel>`.

## Examples

```html
<w-tabs>
  <w-tab for="roald-amundsen">Tab 1</w-tab>
  <w-tab for="fridtjof-nansen">Tab 2</w-tab>
  <w-tab for="tor-heyerdahl">Tab 3</w-tab>
  <w-tab-panel id="roald-amundsen">Tab one selected!</w-tab-panel>
  <w-tab-panel id="fridtjof-nansen">Tab two selected!</w-tab-panel>
  <w-tab-panel id="tor-heyerdahl">Tab three selected!</w-tab-panel>
</w-tabs>

<script type="module">
  const tabs = document.querySelector('w-tabs');

  tabs.addEventListener('change', (event) => {
    // event.detail = { panelId: string }
    console.log('Active panel:', event.detail.panelId);
  });
</script>
```

### Tabs with icons

Icons can be added to tabs using the `icon` slot. By default, icons appear beside the label.

```html
<w-tabs active="fridtjof-nansen">
  <w-tab for="roald-amundsen">
    <w-icon name="Info" slot="icon"></w-icon>
    Tab 1
  </w-tab>
  <w-tab for="fridtjof-nansen">
    <w-icon name="Success" slot="icon"></w-icon>
    Tab 2
  </w-tab>
  <w-tab-panel id="roald-amundsen">Content one</w-tab-panel>
  <w-tab-panel id="fridtjof-nansen">Content two</w-tab-panel>
</w-tabs>
```

Use the `over` attribute to position icons above the label:

```html
<w-tabs>
  <w-tab for="roald-amundsen" over>
    <w-icon name="Info" slot="icon"></w-icon>
    Tab 1
  </w-tab>
  <w-tab for="fridtjof-nansen" over>
    <w-icon name="Success" slot="icon"></w-icon>
    Tab 2
  </w-tab>
  <w-tab-panel id="roald-amundsen">Content one</w-tab-panel>
  <w-tab-panel id="fridtjof-nansen">Content two</w-tab-panel>
</w-tabs>
```

## Styling API

Tabs support styling through **component tokens** (CSS custom properties with a `--w-c` prefix) and **parts**.

### Parts

Use `::part(part-name)` from outside the component.

#### `<w-tabs>` parts

* `base` - the root element inside the component.
* `tablist` - the container for all the tabs (not the tab panels).
* `selection` - the indicator for the active tab.

#### `<w-tab>` parts

* `base` - the root element inside the component.
* `icon-inline` - the icon when shown inline with the tab name.
* `icon-block` - the icon when shown above the tab name.

#### `<w-tab-panel>` parts

* `base` - the root element inside the component.

### Component tokens

#### `<w-tabs>` tokens

Set these on `<w-tabs>` to override visuals.

```css
w-tabs {
	--w-c-tabs-selection-color: limegreen;
}
```

* `--w-c-tabs-border-width`
* `--w-c-tabs-border-color`
* `--w-c-tabs-selection-width`
* `--w-c-tabs-selection-color`

#### `<w-tab>` tokens

Set these on `<w-tab>` to override visuals.

```css
w-tab {
	--w-c-tab-active-color: magenta;
}
```

* `--w-c-tab-inactive-color`
* `--w-c-tab-hover-color`
* `--w-c-tab-hover-color-border`
* `--w-c-tab-active-color`
* `--w-c-tab-active-color-border`

#### `<w-tab-panel>` tokens

`<w-tab-panel>` has no tokens.

## `<w-tabs>` API

Unless otherwise noted all properties are HTML attributes (as opposed to JavaScript object properties).

### Properties

| Name | Type | Default | Summary |
|-|-|-|-|
| active | `string \| undefined` | `"" (Shows the first tab)` | The `id` of the panel that should be active. |

### Property Details

#### active

The `id` of the panel that should be active.

* Type: `string | undefined`
* Default: `"" (Shows the first tab)`

### Events

#### change

Includes `details.panelId` with the now active tab panel's ID

* Type: [`WarpTabsChangeEvent`](#warptabschangeevent)

### Types

#### ResizeObserver | undefined

`{ disconnect: {  }, observe: {  }, unobserve: {  } } | undefined`

#### WarpTabsChangeEvent

`{ detail: { panelId: string }, initCustomEvent: {  }, bubbles: boolean, cancelBubble: boolean, cancelable: boolean, composed: boolean, currentTarget: null | { addEventListener: {  }, dispatchEvent: {  }, removeEventListener: {  } }, defaultPrevented: boolean, eventPhase: number, isTrusted: boolean, returnValue: boolean, srcElement: null | { addEventListener: {  }, dispatchEvent: {  }, removeEventListener: {  } }, target: null | { addEventListener: {  }, dispatchEvent: {  }, removeEventListener: {  } }, timeStamp: number, type: string, composedPath: {  }, initEvent: {  }, preventDefault: {  }, stopImmediatePropagation: {  }, stopPropagation: {  }, NONE: 0, CAPTURING_PHASE: 1, AT_TARGET: 2, BUBBLING_PHASE: 3 }`

### `<w-tab>` API

#### Properties

| Name | Type | Default | Summary |
|-|-|-|-|
| \_internals (JS only) | `unknown` | `-` | - |
| for | `string \| undefined` | `-` | The `id` of the `<w-tab-panel>` this tab controls. |
| over | `boolean` | `false` | Whether to show the `icon` slot over the tab title instead of inline. |
| tabindex | `number` | `0` | The host element (`<w-tab>`), the one with `role=tab`, must be the focusable element for assistive technology. |

#### Property Details

##### \_internals (JS only)

* Type: `unknown`
* Default: `-`

##### for

The `id` of the `<w-tab-panel>` this tab controls.

* Type: `string | undefined`
* Default: `-`

##### over

Whether to show the `icon` slot over the tab title instead of inline.

* Type: `boolean`
* Default: `false`

##### tabindex

The host element (`<w-tab>`), the one with `role=tab`, must be the focusable element for assistive technology.

* Type: `number`
* Default: `0`

### `<w-tab-panel>` API

#### Properties

| Name | Type | Default | Summary |
|-|-|-|-|
| id | `string` | `-` | Required so `<w-tab>` has something to target. |

#### Property Details

##### id

Required so `<w-tab>` has something to target.

* Type: `string`
* Default: `-`

#### Types

##### boolean | undefined

`false | true | undefined`
