# Tabs

Views of the same thing, switched in place: keys in a tray, the chosen view a raised cap.

Kit part · Free · https://tactileui.dev/parts/tabs

- Element: `role="tablist"`
- Needs: `kit.css` and `kit.mjs` ([how to install the kit](https://tactileui.dev/docs/installation#the-kit))
- Categories: Navigation, Tabs
- Finishes: Aluminium, Graphite, Oak, Walnut, Porcelain, Black, Daylight, Night, Paper, Phosphor, E-paper, AMOLED
- Volumes: Tactile, Quiet

## Variants

### Two tabs

```html
<div class="tui-tabs" role="tablist" aria-label="Two"><button role="tab" aria-selected="true">Code</button><button role="tab">Preview</button></div>
```

### Five tabs

```html
<div class="tui-tabs" role="tablist" aria-label="Five"><button role="tab" aria-selected="true">Day</button><button role="tab">Week</button><button role="tab">Month</button><button role="tab">Year</button><button role="tab">All</button></div>
```

## Every state

- Chosen
- Hover
- Focus

Hover, pressed and focus are forced with `.is-hover`, `.is-down` and `.is-focus`; checked and disabled are real.

## API

| Name | Kind | Values | What it does |
| - | - | - | - |
| .tui-tabs | class | role="tablist" | A tray of tabs. Wider than its container, it scrolls inside itself, never the page. |
| role="tab" · aria-selected | attribute | on | The chosen tab is a raised cap. |
| aria-controls | attribute | panel id | wireTabs shows that panel and hides the others. |
| wireTabs(list) | function | kit.mjs | Selection, roving tabindex, arrows. Runs on every tablist when kit.mjs is imported. |
| tui-tab | event | detail: the tab | Fired on the tablist when a tab is chosen; bubbles. |
| Left/Right · Home/End | keyboard | — | Move and select, wrapping at the ends. |

## Markup

```html
<div class="tui-tabs" role="tablist" aria-label="Range">
  <button role="tab" aria-selected="true" aria-controls="p-day" id="t-day">Day</button>
  <button role="tab" aria-controls="p-week" id="t-week">Week</button>
</div>
<div role="tabpanel" id="p-day" aria-labelledby="t-day">…</div>
<div role="tabpanel" id="p-week" aria-labelledby="t-week" hidden>…</div>
```

```js
import '/kit/kit.mjs';
document.addEventListener('tui-tab', (e) => console.log(e.detail.id));
```

The demo on the page:

```html
<div style="display:grid;gap:14px;width:min(100%,420px)">
  <div class="tui-tabs" role="tablist" aria-label="Range"><button role="tab" aria-selected="true" aria-controls="dp-day" id="dt-day">Day</button><button role="tab" aria-controls="dp-week" id="dt-week">Week</button><button role="tab" aria-controls="dp-month" id="dt-month">Month</button></div>
  <div role="tabpanel" id="dp-day" aria-labelledby="dt-day"><div class="tui-readout"><span class="tui-label">Made today</span><span class="tui-readout__value">31.6<small>kWh</small></span></div></div>
  <div role="tabpanel" id="dp-week" aria-labelledby="dt-week" hidden><div class="tui-readout"><span class="tui-label">Made this week</span><span class="tui-readout__value">184<small>kWh</small></span></div></div>
  <div role="tabpanel" id="dp-month" aria-labelledby="dt-month" hidden><div class="tui-readout"><span class="tui-label">Made in September</span><span class="tui-readout__value">702<small>kWh</small></span></div></div>
</div>
```

## Usage notes

Click a tab, or focus one and use the arrow keys, Home and End.

## Accessibility

- The WAI-ARIA tabs pattern: one Tab stop for the list, arrows inside it, panels linked by `aria-controls` and `aria-labelledby`.
- Selection follows focus, which suits views that render at once.

## How it’s built

A tray with transparent buttons; the chosen one gets a raised face and a small shadow. `wireTabs` is thirty lines in `kit.mjs`: it sets `aria-selected`, the roving `tabindex` and each panel’s `hidden`.

## Rules

Tabs are for views; a selector is for settings. Two to five tabs.

The full rules are in `tabs.rules.md` in the brain, which ships with the Kit.

## Related parts

- [Selector](https://tactileui.dev/parts/selector): One mode of two to five: latching keys in a tray, one down at a time, each with a lamp that lights when chosen.
- [Side rail](https://tactileui.dev/parts/side): App navigation in a panel: the current page is a recess with its lamp lit, links grouped under printed labels.
- [Bar](https://tactileui.dev/parts/bar): The top of a page: a wordmark with a lamp, printed links, and one contrast key at most.
