# Tabs

URL: https://ark-ui.com/docs/components/tabs
Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/tabs.mdx

Flexible navigation tool with various modes and features.

---

<ComponentPreview id="Tabs" />

## Anatomy

To set up the tabs correctly, you'll need to understand its anatomy and how we name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.

<Anatomy id="tabs" />

## Examples

Learn how to use the `Tabs` component in your project. Let's take a look at the most basic example:

**Example: basic**

#### React

```tsx
import { Tabs } from '@ark-ui/react/tabs'

export const Basic = () => (
  <Tabs.Root>
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
    <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Solid

```tsx
import { Tabs } from '@ark-ui/solid/tabs'

export const Basic = () => (
  <Tabs.Root>
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Tabs } from '@ark-ui/vue/tabs'
</script>

<template>
  <Tabs.Root>
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Tabs } from '@ark-ui/svelte/tabs'
</script>

<Tabs.Root defaultValue="vue">
  <Tabs.List>
    <Tabs.Trigger value="react">React</Tabs.Trigger>
    <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
    <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="react">React Content</Tabs.Content>
  <Tabs.Content value="vue">Vue Content</Tabs.Content>
  <Tabs.Content value="solid">Solid Content</Tabs.Content>
  <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
</Tabs.Root>

```

### Initial Tab

To set a default tab on initial render, use the `defaultValue` prop:

**Example: initial-tab**

#### React

```tsx
import { Tabs } from '@ark-ui/react/tabs'

export const InitialTab = () => (
  <Tabs.Root defaultValue="react">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
    <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Solid

```tsx
import { Tabs } from '@ark-ui/solid/tabs'

export const InitialTab = () => (
  <Tabs.Root value="react">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Tabs } from '@ark-ui/vue/tabs'
import { ref } from 'vue'

const value = ref('react')
</script>

<template>
  <Tabs.Root v-model="value">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Tabs } from '@ark-ui/svelte/tabs'
</script>

<Tabs.Root defaultValue="react">
  <Tabs.List>
    <Tabs.Trigger value="react">React</Tabs.Trigger>
    <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
    <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="react">React Content</Tabs.Content>
  <Tabs.Content value="vue">Vue Content</Tabs.Content>
  <Tabs.Content value="solid">Solid Content</Tabs.Content>
  <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
</Tabs.Root>

```

### Tab Indicator

To provide a visual cue for the selected tab, use the `Tabs.Indicator` component:

**Example: indicator**

#### React

```tsx
import { Tabs } from '@ark-ui/react/tabs'

export const Indicator = () => (
  <Tabs.Root>
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
      <Tabs.Indicator />
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
    <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Solid

```tsx
import { Tabs } from '@ark-ui/solid/tabs'

export const Indicator = () => (
  <Tabs.Root>
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Indicator />
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Tabs } from '@ark-ui/vue/tabs'
</script>

<template>
  <Tabs.Root>
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Indicator />
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Tabs } from '@ark-ui/svelte/tabs'
</script>

<Tabs.Root defaultValue="react">
  <Tabs.List>
    <Tabs.Trigger value="react">React</Tabs.Trigger>
    <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
    <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
    <Tabs.Indicator style="width: var(--width)" />
  </Tabs.List>
  <Tabs.Content value="react">React Content</Tabs.Content>
  <Tabs.Content value="vue">Vue Content</Tabs.Content>
  <Tabs.Content value="solid">Solid Content</Tabs.Content>
  <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
</Tabs.Root>

```

### Lazy Mounting

Lazy mounting is a feature that allows the content of a tab to be rendered only when the tab is first activated. This is
useful for performance optimization, especially when tab content is large or complex. To enable lazy mounting, use the
`lazyMount` prop on the `Tabs.Content` component.

In addition, the `unmountOnExit` prop can be used in conjunction with `lazyMount` to unmount the tab content when the
tab is deactivated, freeing up resources. The next time the tab is activated, its content will be re-rendered.

**Example: lazy-mount**

#### React

```tsx
import { Tabs } from '@ark-ui/react/tabs'

export const LazyMount = () => (
  <Tabs.Root lazyMount unmountOnExit>
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
      <Tabs.Indicator />
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
    <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Solid

```tsx
import { Tabs } from '@ark-ui/solid/tabs'

export const LazyMount = () => (
  <Tabs.Root lazyMount unmountOnExit>
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Indicator />
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Tabs } from '@ark-ui/vue/tabs'
</script>

<template>
  <Tabs.Root lazyMount unmountOnExit>
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Indicator />
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Tabs } from '@ark-ui/svelte/tabs'
</script>

<Tabs.Root lazyMount unmountOnExit>
  <Tabs.List>
    <Tabs.Trigger value="react">React</Tabs.Trigger>
    <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
    <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
    <Tabs.Indicator />
  </Tabs.List>
  <Tabs.Content value="react">React Content</Tabs.Content>
  <Tabs.Content value="vue">Vue Content</Tabs.Content>
  <Tabs.Content value="solid">Solid Content</Tabs.Content>
  <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
</Tabs.Root>

```

### Disabled Tab

To disable a tab, simply pass the `disabled` prop to the `Tabs.Trigger` component:

**Example: disabled-tab**

#### React

```tsx
import { Tabs } from '@ark-ui/react/tabs'

export const DisabledTab = () => (
  <Tabs.Root defaultValue="react">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue" disabled>
        Vue
      </Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
    <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Solid

```tsx
import { Tabs } from '@ark-ui/solid/tabs'

export const DisabledTab = () => (
  <Tabs.Root value="react">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue" disabled>
        Vue
      </Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Tabs } from '@ark-ui/vue/tabs'
</script>

<template>
  <Tabs.Root defaultValue="react">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue" disabled>Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Tabs } from '@ark-ui/svelte/tabs'
</script>

<Tabs.Root defaultValue="react">
  <Tabs.List>
    <Tabs.Trigger value="react">React</Tabs.Trigger>
    <Tabs.Trigger value="vue" disabled>Vue</Tabs.Trigger>
    <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="react">React Content</Tabs.Content>
  <Tabs.Content value="vue">Vue Content</Tabs.Content>
  <Tabs.Content value="solid">Solid Content</Tabs.Content>
  <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
</Tabs.Root>

```

### Controlled Tabs

To create a controlled Tabs component, manage the current selected tab using the `value` prop and update it when the
`onValueChange` event handler is called:

**Example: controlled**

#### React

```tsx
import { Tabs } from '@ark-ui/react/tabs'
import { useState } from 'react'

export const Controlled = () => {
  const [value, setValue] = useState<string | null>('react')
  return (
    <Tabs.Root value={value} onValueChange={(e) => setValue(e.value)}>
      <Tabs.List>
        <Tabs.Trigger value="react">React</Tabs.Trigger>
        <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
        <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
        <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
      </Tabs.List>
      <Tabs.Content value="react">React Content</Tabs.Content>
      <Tabs.Content value="vue">Vue Content</Tabs.Content>
      <Tabs.Content value="solid">Solid Content</Tabs.Content>
      <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
    </Tabs.Root>
  )
}

```

#### Solid

```tsx
import { Tabs } from '@ark-ui/solid/tabs'
import { createSignal } from 'solid-js'

export const Controlled = () => {
  const [value, setValue] = createSignal<string | null>('react')
  return (
    <Tabs.Root value={value()} onValueChange={(e) => setValue(e.value)}>
      <Tabs.List>
        <Tabs.Trigger value="react">React</Tabs.Trigger>
        <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
        <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      </Tabs.List>
      <Tabs.Content value="react">React Content</Tabs.Content>
      <Tabs.Content value="vue">Vue Content</Tabs.Content>
      <Tabs.Content value="solid">Solid Content</Tabs.Content>
    </Tabs.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Tabs } from '@ark-ui/vue/tabs'
import { ref } from 'vue'

const value = ref('react')
</script>

<template>
  <p>Selected tab: {{ value }}</p>
  <Tabs.Root v-model="value">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Tabs } from '@ark-ui/svelte/tabs'

  let value = $state<string | null>('react')
</script>

<Tabs.Root bind:value>
  <Tabs.List>
    <Tabs.Trigger value="react">React</Tabs.Trigger>
    <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
    <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="react">React Content</Tabs.Content>
  <Tabs.Content value="vue">Vue Content</Tabs.Content>
  <Tabs.Content value="solid">Solid Content</Tabs.Content>
  <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
</Tabs.Root>

```

### Vertical Tabs

The default orientation of the tabs is `horizontal`. To change the orientation, set the `orientation` prop to
`vertical`.

**Example: vertical**

#### React

```tsx
import { Tabs } from '@ark-ui/react/tabs'

export const Vertical = () => (
  <Tabs.Root orientation="vertical" defaultValue="react">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
    <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Solid

```tsx
import { Tabs } from '@ark-ui/solid/tabs'

export const Vertical = () => (
  <Tabs.Root orientation="vertical" value="react">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Tabs } from '@ark-ui/vue/tabs'
import { ref } from 'vue'

const value = ref('react')
</script>

<template>
  <Tabs.Root v-model="value" orientation="vertical">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Tabs } from '@ark-ui/svelte/tabs'
</script>

<Tabs.Root orientation="vertical" defaultValue="react">
  <Tabs.List>
    <Tabs.Trigger value="react">React</Tabs.Trigger>
    <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
    <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="react">React Content</Tabs.Content>
  <Tabs.Content value="vue">Vue Content</Tabs.Content>
  <Tabs.Content value="solid">Solid Content</Tabs.Content>
  <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
</Tabs.Root>

```

### Manual Activation

By default, the tab can be selected when it receives focus from either the keyboard or pointer interaction. This is
called automatic tab activation.

In contrast, manual tab activation means the tab is selected with the

<kbd>Enter</kbd> key or by clicking on the tab.

**Example: manual**

#### React

```tsx
import { Tabs } from '@ark-ui/react/tabs'

export const Manual = () => (
  <Tabs.Root activationMode="manual" defaultValue="react">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
      <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
    <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Solid

```tsx
import { Tabs } from '@ark-ui/solid/tabs'

export const Manual = () => (
  <Tabs.Root activationMode="manual" value="react">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Tabs } from '@ark-ui/vue/tabs'
import { ref } from 'vue'

const value = ref('react')
</script>

<template>
  <Tabs.Root v-model="value" activationMode="manual">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Tabs } from '@ark-ui/svelte/tabs'
</script>

<Tabs.Root activationMode="manual" defaultValue="react">
  <Tabs.List>
    <Tabs.Trigger value="react">React</Tabs.Trigger>
    <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
    <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="react">React Content</Tabs.Content>
  <Tabs.Content value="vue">Vue Content</Tabs.Content>
  <Tabs.Content value="solid">Solid Content</Tabs.Content>
  <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
</Tabs.Root>

```

### Using the Root Provider

The `RootProvider` component provides a context for the tabs. It accepts the value of the `useTabs` hook. You can
leverage it to access the component state and methods from outside the tabs.

**Example: root-provider**

#### React

```tsx
import { Tabs, useTabs } from '@ark-ui/react/tabs'

export const RootProvider = () => {
  const tabs = useTabs()

  return (
    <>
      <button onClick={() => tabs.focus()}>Focus</button>

      <Tabs.RootProvider value={tabs}>
        <Tabs.List>
          <Tabs.Trigger value="react">React</Tabs.Trigger>
          <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
          <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
          <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
        </Tabs.List>
        <Tabs.Content value="react">React Content</Tabs.Content>
        <Tabs.Content value="vue">Vue Content</Tabs.Content>
        <Tabs.Content value="solid">Solid Content</Tabs.Content>
        <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
      </Tabs.RootProvider>
    </>
  )
}

```

#### Solid

```tsx
import { Tabs, useTabs } from '@ark-ui/solid/tabs'

export const RootProvider = () => {
  const tabs = useTabs()

  return (
    <>
      <button onClick={() => tabs().focus()}>Focus</button>

      <Tabs.RootProvider value={tabs}>
        <Tabs.List>
          <Tabs.Trigger value="react">React</Tabs.Trigger>
          <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
          <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
        </Tabs.List>
        <Tabs.Content value="react">React Content</Tabs.Content>
        <Tabs.Content value="vue">Vue Content</Tabs.Content>
        <Tabs.Content value="solid">Solid Content</Tabs.Content>
      </Tabs.RootProvider>
    </>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Tabs, useTabs } from '@ark-ui/vue/tabs'

const tabs = useTabs()
</script>

<template>
  <button @click="tabs.focus()">Focus</button>

  <Tabs.RootProvider :value="tabs">
    <Tabs.List>
      <Tabs.Trigger value="react">React</Tabs.Trigger>
      <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
      <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    </Tabs.List>
    <Tabs.Content value="react">React Content</Tabs.Content>
    <Tabs.Content value="vue">Vue Content</Tabs.Content>
    <Tabs.Content value="solid">Solid Content</Tabs.Content>
  </Tabs.RootProvider>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Tabs, useTabs } from '@ark-ui/svelte/tabs'

  const id = $props.id()

  const tabs = useTabs({
    id,
    defaultValue: 'vue',
  })
</script>

<button onclick={() => tabs().focus()}>Focus</button>

<Tabs.RootProvider value={tabs}>
  <Tabs.List>
    <Tabs.Trigger value="react">React</Tabs.Trigger>
    <Tabs.Trigger value="vue">Vue</Tabs.Trigger>
    <Tabs.Trigger value="solid">Solid</Tabs.Trigger>
    <Tabs.Trigger value="svelte">Svelte</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="react">React Content</Tabs.Content>
  <Tabs.Content value="vue">Vue Content</Tabs.Content>
  <Tabs.Content value="solid">Solid Content</Tabs.Content>
  <Tabs.Content value="svelte">Svelte Content</Tabs.Content>
</Tabs.RootProvider>

```

> If you're using the `RootProvider` component, you don't need to use the `Root` component.

## Guides

### Router Controlled Tabs

When using frameworks like Next.js, Remix, or React Router, controlling the active tabs based on the URL can be useful.

To achieve this, you need to do two things:

- Set the `value` prop to the current URL path.
- Listen to the `onValueChange` event and update the URL path.

Here's an example using Remix Router

```tsx
import { Tabs } from '@ark-ui/react/tabs'
import { useLocation, useNavigate, Link } from '@remix-run/react'

export default function App() {
  const { pathname } = useLocation()
  const navigate = useNavigate()
  const lastPathFragment = pathname.substring(pathname.lastIndexOf('/') + 1)
  const activeTab = lastPathFragment.length > 0 ? lastPathFragment : 'homepage'

  return (
    <Tabs.Root
      value={activeTab}
      onValueChange={({ value }) => {
        navigate(`/${value === 'home' ? '' : value}`)
      }}
    >
      <Tabs.List>
        <Tabs.Trigger asChild value="home">
          <Link to="">Home</Link>
        </Tabs.Trigger>
        <Tabs.Trigger asChild value="page-1">
          <Link to="page-1">Page 1</Link>
        </Tabs.Trigger>
        <Tabs.Trigger asChild value="page-2">
          <Link to="page-2">Page 2</Link>
        </Tabs.Trigger>
      </Tabs.List>
    </Tabs.Root>
  )
}
```

## API Reference

### Props

**Component API Reference**

#### React

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic`
- `manual`: Tabs are activated when clicked or press `enter` key.
- `automatic`: Tabs are activated when receiving focus |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `composite` | `boolean` | No | Whether the tab is composite |
| `defaultValue` | `string` | No | The initial selected tab value when rendered.
Use when you don't need to control the selected tab value. |
| `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  root: string
  trigger: (value: string) => string
  list: string
  content: (value: string) => string
  indicator: string
}>` | No | The ids of the elements in the tabs. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it.
Useful if tab triggers are anchor elements. |
| `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes |
| `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes |
| `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical`
- `horizontal`: only left and right arrow key navigation will work.
- `vertical`: only up and down arrow key navigation will work. |
| `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
| `value` | `string` | No | The controlled selected tab value |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tabs |
| `[data-part]` | root |
| `[data-orientation]` | The orientation of the tabs |
| `[data-focus]` | Present when focused |


**TabContent Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The value of the tab |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TabIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TabList Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TabTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The value of the tab |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `disabled` | `boolean` | No | Whether the tab is disabled |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseTabsReturn` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


#### Solid

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic`
- `manual`: Tabs are activated when clicked or press `enter` key.
- `automatic`: Tabs are activated when receiving focus |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `composite` | `boolean` | No | Whether the tab is composite |
| `defaultValue` | `string` | No | The initial selected tab value when rendered.
Use when you don't need to control the selected tab value. |
| `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. |
| `ids` | `Partial<{
  root: string
  trigger: (value: string) => string
  list: string
  content: (value: string) => string
  indicator: string
}>` | No | The ids of the elements in the tabs. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it.
Useful if tab triggers are anchor elements. |
| `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes |
| `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes |
| `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical`
- `horizontal`: only left and right arrow key navigation will work.
- `vertical`: only up and down arrow key navigation will work. |
| `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
| `value` | `string` | No | The controlled selected tab value |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tabs |
| `[data-part]` | root |
| `[data-orientation]` | The orientation of the tabs |
| `[data-focus]` | Present when focused |


**TabContent Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The value of the tab |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TabIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TabList Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TabTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The value of the tab |
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `disabled` | `boolean` | No | Whether the tab is disabled |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseTabsReturn` | Yes |  |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


#### Vue

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic`
- `manual`: Tabs are activated when clicked or press `enter` key.
- `automatic`: Tabs are activated when receiving focus |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `composite` | `boolean` | No | Whether the tab is composite |
| `defaultValue` | `string` | No | The initial selected tab value when rendered.
Use when you don't need to control the selected tab value. |
| `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  root: string
  trigger: (id: string) => string
  content: (id: string) => string
  list: string
  indicator: string
}>` | No | The ids of the elements in the tabs. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. |
| `modelValue` | `string` | No | The v-model value of the tabs |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it.
Useful if tab triggers are anchor elements. |
| `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical`
- `horizontal`: only left and right arrow key navigation will work.
- `vertical`: only up and down arrow key navigation will work. |
| `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tabs |
| `[data-part]` | root |
| `[data-orientation]` | The orientation of the tabs |
| `[data-focus]` | Present when focused |


**TabContent Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The value of the tab |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TabIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TabList Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TabTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The value of the tab |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `disabled` | `boolean` | No | Whether the tab is disabled |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `TabsApi<PropTypes>` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


#### Svelte

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic`
- `manual`: Tabs are activated when clicked or press `enter` key.
- `automatic`: Tabs are activated when receiving focus |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `composite` | `boolean` | No | Whether the tab is composite |
| `defaultValue` | `string` | No | The initial selected tab value when rendered.
Use when you don't need to control the selected tab value. |
| `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  root: string
  trigger: (value: string) => string
  list: string
  content: (value: string) => string
  indicator: string
}>` | No | The ids of the elements in the tabs. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it.
Useful if tab triggers are anchor elements. |
| `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes |
| `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes |
| `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical`
- `horizontal`: only left and right arrow key navigation will work.
- `vertical`: only up and down arrow key navigation will work. |
| `ref` | `Element` | No |  |
| `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
| `value` | `string` | No | The controlled selected tab value |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tabs |
| `[data-part]` | root |
| `[data-orientation]` | The orientation of the tabs |
| `[data-focus]` | Present when focused |


**Context Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `render` | `Snippet<[UseTabsContext]>` | Yes |  |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseTabsReturn` | Yes |  |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `ref` | `Element` | No |  |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


### Context

These are the properties available when using `Tabs.Context`, `useTabsContext` hook or `useTabs` hook.

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `value` | `string` | The current value of the tabs. |
| `focusedValue` | `string` | The value of the tab that is currently focused. |
| `setValue` | `(value: string) => void` | Sets the value of the tabs. |
| `clearValue` | `VoidFunction` | Clears the value of the tabs. |
| `setIndicatorRect` | `(value: string) => void` | Sets the indicator rect to the tab with the given value |
| `syncTabIndex` | `VoidFunction` | Synchronizes the tab index of the content element.
Useful when rendering tabs within a select or combobox |
| `focus` | `VoidFunction` | Set focus on the selected tab trigger |
| `selectNext` | `(fromValue?: string) => void` | Selects the next tab |
| `selectPrev` | `(fromValue?: string) => void` | Selects the previous tab |
| `getTriggerState` | `(props: TriggerProps) => TriggerState` | Returns the state of the trigger with the given props |


## Accessibility

Complies with the [Tabs WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/).

### Keyboard Support

<KeyBindingsTable id="tabs" />