# Tabs Primitive

Tabs is a Starwind Runtime primitive in the controlled-value-group contract family.
Astro and React share one semantic component API. React coordinates reactive state through controlled and default props plus callbacks. Astro renders initial state and coordinates later changes through DOM events and Runtime methods. Raw HTML uses Runtime attributes, DOM events, and imperative methods.
## Anatomy
### Astro
Use the Astro primitive adapter to render Tabs anatomy with the Runtime wiring included.
```astro
---
import { Tabs } from "@starwind-ui/astro/tabs";
---

<Tabs.Root defaultValue="account">
  <Tabs.List>
    <Tabs.Tab value="account">Account</Tabs.Tab>
  </Tabs.List>
  <Tabs.Panel value="account">Account settings</Tabs.Panel>
</Tabs.Root>
```

### React
Use the React primitive adapter when Tabs state participates in React rendering.
```tsx
import { Tabs } from "@starwind-ui/react/tabs";

export function Example() {
  return (
    <Tabs.Root defaultValue="account">
      <Tabs.List>
        <Tabs.Tab value="account">Account</Tabs.Tab>
      </Tabs.List>
      <Tabs.Panel value="account">Account settings</Tabs.Panel>
    </Tabs.Root>
  );
}
```

### HTML
Render the Tabs data-sw-* contract yourself, then initialize createTabs.
```html
<div data-sw-tabs data-default-value="account">
  <div data-sw-tabs-list role="tablist">
    <button data-sw-tabs-tab role="tab" type="button" data-value="account">Account</button>
  </div>
  <div data-sw-tabs-panel role="tabpanel" hidden data-value="account">Account settings</div>
</div>

<script type="module">
  import { createTabs } from "@starwind-ui/runtime/tabs";

  const root = document.querySelector("[data-sw-tabs]");
  if (root) {
    createTabs(root);
  }
</script>
```

### Vue
Use the Vue 3.5 beta adapter to render Tabs anatomy.
```vue
<script setup lang="ts">
import Tabs from "@starwind-ui/vue/tabs";
</script>

<template>
  <Tabs.Root defaultValue="account">
    <Tabs.List>
      <Tabs.Tab value="account">Account</Tabs.Tab>
    </Tabs.List>
    <Tabs.Panel value="account">Account settings</Tabs.Panel>
  </Tabs.Root>
</template>
```
## API Reference
### Root
The main element that owns the Tabs Runtime instance.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-tabs` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| value | `TabsValue` | - | control | Controls the current Tabs value. | **React:** Use value for controlled state and defaultValue for default state, and onValueChange for change proposals.<br>**Astro:** Use value or defaultValue for initial state, listen for starwind:value-change, and call setValue for later updates.<br>**Runtime / HTML:** Use data-default-value for initial state, listen for starwind:value-change, and call setValue for later updates. |
| defaultValue | `TabsValue` | - | control | Sets the initial Tabs value for uncontrolled usage. | **React:** Use value for controlled state and defaultValue for default state, and onValueChange for change proposals.<br>**Astro:** Use value or defaultValue for initial state, listen for starwind:value-change, and call setValue for later updates.<br>**Runtime / HTML:** Use data-default-value for initial state, listen for starwind:value-change, and call setValue for later updates. |
| orientation | `TabsOrientation` | "horizontal" | option | Sets the Tabs orientation. | - |
| syncKey | `string` | - | option | Configures the sync key option for the Root part. | - |
| onValueChange | `(value: TabsValue, details: TabsValueChangeDetails) => void` | - | callback | Runs when the Tabs value changes. | **React:** Use value for controlled state and defaultValue for default state, and onValueChange for change proposals.<br>**Astro:** Use value or defaultValue for initial state, listen for starwind:value-change, and call setValue for later updates.<br>**Runtime / HTML:** Use data-default-value for initial state, listen for starwind:value-change, and call setValue for later updates. |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-tabs` | runtime | - | Marks the Root part so Starwind Runtime can find it. |
| `data-default-value` | prop | - | Reflects the default value prop on the Root part. |
| `data-orientation` | prop | - | Reflects the orientation prop on the Root part. |
| `data-sync-key` | prop | - | Reflects the sync key prop on the Root part. |
| `data-value` | state | - | Reflects the value state on the Root part. |
#### State
| State | Value Type | Controlled Prop | Default Prop | Initial Attribute | Runtime Getter | Runtime Setter | Description | State Control Support |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| value | `TabsValue` | value | defaultValue | `data-default-value` | `getValue` | `setValue` | Tracks the current Tabs value. | **React:** Use value for controlled state and defaultValue for default state, and onValueChange for change proposals.<br>**Astro:** Use value or defaultValue for initial state, listen for starwind:value-change, and call setValue for later updates.<br>**Runtime / HTML:** Use data-default-value for initial state, listen for starwind:value-change, and call setValue for later updates. |
#### Events
| Event | Callback | DOM Event | Value | Details | Timing | Cancelable | Description | Cancellation Sequence |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| valueChange | onValueChange | starwind:value-change | value: `TabsValue` | TabsValueChangeDetails | before-state-commit | Yes | Fires when the value changes for Tabs. | 1. Check internal eligibility and intent.<br>2. Create one details object for the proposal.<br>3. Call the Runtime callback with the details object when the controller exposes one.<br>4. Dispatch the cancelable DOM event with the same details object, including when the callback canceled it.<br>5. Read details.isCanceled, including cancellation caused by preventDefault().<br>6. Apply the accepted state.<br>7. Notify Runtime subscribers and other accepted-only observers. |
#### Runtime Setters
| Method | Target | Options | Suppresses Emit | Description |
| --- | --- | --- | --- | --- |
| `setValue` | state: value | emit: false, sync: true | Yes | Updates the current Tabs value from Runtime code. |
#### Refs
| Part | Public |
| --- | --- |
| root | Yes |
#### Context
| Name | Direction | Values |
| --- | --- | --- |
| tabs | provides | orientation, value |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-tabs`, `data-default-value`, `data-orientation`, `data-sync-key`, `data-value` | The tabs root needs initial value, orientation, and optional sync key before controller hydration. |

### List
The list of selectable Tabs items.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-tabs-list` |
| Role | `tablist` |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| activateOnFocus | `boolean` | false | option | Configures the activate on focus option for the List part. | - |
| loopFocus | `boolean` | true | option | Lets keyboard focus wrap around the Tabs items. | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-tabs-list` | runtime | - | Marks the List part so Starwind Runtime can find it. |
| `data-activate-on-focus` | prop | - | Reflects the activate on focus prop on the List part. |
| `data-loop-focus` | prop | - | Reflects the loop focus prop on the List part. |
| `data-orientation` | prop | - | Reflects the orientation prop on the List part. |
#### Refs
| Part | Public |
| --- | --- |
| list | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-tabs-list`, `data-activate-on-focus`, `data-loop-focus` | The tab list needs focus policy markers before the runtime refreshes orientation, linked tabs, and roles. |

### Tab
A selectable tab inside Tabs.
| Fact | Value |
| --- | --- |
| Default element | `button` |
| Discovery hook | `data-sw-tabs-tab` |
| Role | `tab` |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| disabled | `boolean` | false | option | Disables the Tab part. | - |
| value | `string` | - | option | Controls the current Tabs value. | **React:** Use value for controlled state and defaultValue for default state, and onValueChange for change proposals.<br>**Astro:** Use value or defaultValue for initial state, listen for starwind:value-change, and call setValue for later updates.<br>**Runtime / HTML:** Use data-default-value for initial state, listen for starwind:value-change, and call setValue for later updates. |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-tabs-tab` | runtime | - | Marks the Tab part so Starwind Runtime can find it. |
| `data-active` | state | - | Reflects the active state on the Tab part. |
| `data-disabled` | prop | - | Reflects the disabled prop on the Tab part. |
| `data-orientation` | state | - | Reflects the orientation state on the Tab part. |
| `data-state` | state | - | Reflects the current state on the Tab part. |
| `data-value` | prop | - | Reflects the value prop on the Tab part. |
#### Refs
| Part | Public |
| --- | --- |
| tab | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-tabs-tab`, `data-disabled`, `data-value`, `type` | Tabs need value identity and button semantics before the controller wires ARIA, roving focus, state, and panel ids. |

### Panel
The content panel controlled by Tabs.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-tabs-panel` |
| Role | `tabpanel` |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| keepMounted | `boolean` | false | rendering | Keeps the Panel part in the DOM when hidden. | - |
| value | `string` | - | option | Controls the current Tabs value. | **React:** Use value for controlled state and defaultValue for default state, and onValueChange for change proposals.<br>**Astro:** Use value or defaultValue for initial state, listen for starwind:value-change, and call setValue for later updates.<br>**Runtime / HTML:** Use data-default-value for initial state, listen for starwind:value-change, and call setValue for later updates. |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-tabs-panel` | runtime | - | Marks the Panel part so Starwind Runtime can find it. |
| `data-active` | state | - | Reflects the active state on the Panel part. |
| `data-keep-mounted` | prop | - | Reflects the keep mounted prop on the Panel part. |
| `data-orientation` | state | - | Reflects the orientation state on the Panel part. |
| `data-state` | state | - | Reflects the current state on the Panel part. |
| `data-value` | prop | - | Reflects the value prop on the Panel part. |
#### Refs
| Part | Public |
| --- | --- |
| panel | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-tabs-panel`, `data-keep-mounted`, `data-value` | Panels start from stable value and keep-mounted markers; the runtime links ids and active visibility during refresh. |
#### Presence
| Fact | Value |
| --- | --- |
| Initial hidden | No |
| Unmount policy | runtime-owned-visibility |
| Keep mounted prop | keepMounted |

### Indicator
Visual state indicator rendered by Tabs.
| Fact | Value |
| --- | --- |
| Default element | `span` |
| Discovery hook | `data-sw-tabs-indicator` |
| Role | `presentation` |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-tabs-indicator` | runtime | - | Marks the Indicator part so Starwind Runtime can find it. |
| `data-orientation` | state | - | Reflects the orientation state on the Indicator part. |
#### Refs
| Part | Public |
| --- | --- |
| indicator | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-tabs-indicator` | The indicator receives presentation semantics, visibility, and measured CSS variables from the runtime once an active tab is available. |
## Runtime API
| Fact | Value |
| --- | --- |
| Factory | [`createTabs`](/docs/runtime/#create-tabs) |
| Import | `@starwind-ui/runtime/tabs` |
| Root part | root |
| Option props | defaultValue, orientation, syncKey, value |
| Option lifecycles | - |
## Related Styled Components
| Component | Relationship |
| --- | --- |
| [Tabs](/docs/components/tabs/) | Direct Primitive |
## Exports
| Group | Import | Exports |
| --- | --- | --- |
| Runtime | `@starwind-ui/runtime/tabs` | `createTabs` |
| Astro Primitive | `@starwind-ui/astro/tabs` | `Tabs`, `TabsRoot`, `TabsList`, `TabsTab`, `TabsPanel`, `TabsIndicator` |
| React Primitive | `@starwind-ui/react/tabs` | `Tabs`, `TabsRoot`, `TabsList`, `TabsTab`, `TabsPanel`, `TabsIndicator` |
## Canonical Names
| Kind | Name |
| --- | --- |
| namespace | `Tabs` |
| runtime-factory | `createTabs` |
| part | `Tabs.Root` |
| part | `Tabs.List` |
| part | `Tabs.Tab` |
| part | `Tabs.Panel` |
| part | `Tabs.Indicator` |
## Changelog
### v1.0.1
- Removed obsolete private-release warnings from generated Vue adapters and normalized the resulting blank line in vendored Primitive indexes.
- Measured the active tab indicator in local layout coordinates so scrolling and transforms preserve its alignment.
### v1.0.0
- Promoted this Primitive's vendoring version to the stable 1.0.0 baseline. Its existing API and Runtime behavior carry forward from the previous release.
### v0.1.1
- Marked generated React Primitive files as client modules so vendored installs preserve client boundaries in React server frameworks.
### v0.1.0
- Introduced tab selection, roving focus, panel presence, orientation, and synchronized groups.