Tabs

PohonGitHub
A set of tab panels that are displayed one at a time.
This is the content shown for Tab1
<script lang="ts" setup>
import { ATabsContent, ATabsIndicator, ATabsList, ATabsRoot, ATabsTrigger } from 'akar';

const items = [
  {
    label: 'Tab1',
    content: 'This is the content shown for Tab1',
  },
  {
    label: 'Tab2',
    content: 'And, this is the content for Tab2',
  },
  {
    label: 'Tab3',
    content: 'Finally, this is the content for Tab3',
  },
];
</script>

<template>
  <ATabsRoot
    class="flex flex-col gap-2 w-80 items-center"
    default-value="Tab1"
  >
    <ATabsList
      class="group p-1 rounded-lg bg-background-elevated flex w-full relative"
    >
      <ATabsIndicator class="rounded-md bg-primary w-$akar-tabs-indicator-size shadow-xs translate-x-$akar-tabs-indicator-position transition-[transform,width]-200 inset-y-1 left-0 absolute" />

      <ATabsTrigger
        v-for="tabItem in items"
        :key="tabItem.label"
        class="group text-sm font-medium px-3 py-1.5 rounded-md inline-flex grow gap-1.5 min-w-0 transition-colors-280 items-center justify-center relative data-[state=active]:color-text-inverted data-[state=inactive]:color-text-muted focus-visible:(outline-2 outline-primary outline-offset-2) disabled:(opacity-75 cursor-not-allowed) hover:data-[state=inactive]:not-disabled:color-text"
        :value="tabItem.label"
      >
        {{ tabItem.label }}
      </ATabsTrigger>
    </ATabsList>

    <ATabsContent
      v-for="tabItem in items"
      :key="tabItem.label"
      class="w-full focus:outline-none"
      :value="tabItem.label"
    >
      {{ tabItem.content }}
    </ATabsContent>
  </ATabsRoot>
</template>

Features

  • Can be controlled or uncontrolled.
  • Supports horizontal/vertical orientation.
  • Supports automatic/manual activation.
  • Full keyboard navigation.

Anatomy

Import all parts and piece them together.

<script setup>
import { ATabsContent, ATabsIndicator, ATabsList, ATabsRoot, ATabsTrigger } from 'akar';
</script>

<template>
  <ATabsRoot>
    <ATabsList>
      <ATabsIndicator />
      <ATabsTrigger />
    </ATabsList>
    <ATabsContent />
  </ATabsRoot>
</template>

Pohon

One benefit of using Akar is its flexibility and low-level control over the components. However, this also means that you may need to manually construct more complex UI elements by combining multiple Akar components together.

If you feel there's a lot of elements that needs to be constructed manually using Akar, consider using Pohon UI instead. It provides a higher-level abstraction over Akar components with pre-defined styles and behaviors that can help you build UIs faster.

API Reference

Root

Contains all the tabs component parts.

Props

Prop Default Type
as'div'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

activationMode'automatic''automatic' | 'manual'

Whether a tab is activated automatically (on focus) or manually (on click).

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

defaultValuestring | number

The value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs

dir'ltr' | 'rtl'

The reading direction of the combobox when applicable.
If omitted, inherits globally from AConfigProvider or assumes LTR (left-to-right) reading mode.

modelValuestring | number
orientation'horizontal''horizontal' | 'vertical'

The orientation the tabs are laid out. Mainly so arrow navigation is done accordingly (left & right vs. up & down)

unmountOnHidetrueboolean

When true, the element will be unmounted on closed state.

Emits

Event Type
update:modelValue[payload: StringOrNumber]

Event handler called when the value changes

Slots

Slot Type
modelValuestring | number

The controlled value of the tab to activate. Can be bind as v-model.

Data Attributes

Attribute Value
[data-orientation]'vertical' | 'horizontal'

List

Contains the triggers that are aligned along the edge of the active content.

Props

Prop Default Type
as'div'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

looptrueboolean

When true, keyboard navigation will loop from last tab to first, and vice versa.

Data Attributes

Attribute Value
[data-orientation]'vertical' | 'horizontal'

Trigger

The button that activates its associated content.

Props

Prop Default Type
as'button'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

disabledfalseboolean

When true, prevents the user from interacting with the tab.

value*string | number

A unique value that associates the trigger with a content.

Data Attributes

Attribute Value
[data-state]'active' | 'inactive'
[data-disabled]Present when disabled
[data-orientation]'vertical' | 'horizontal'

Indicator

The indicator that highlights the current active tab.

Props

Prop Default Type
as'div'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

CSS Variables

Variable Description
--akar-tabs-indicator-size

The size of the indicator

--akar-tabs-indicator-position

The position of the indicator

Content

Contains the content associated with each trigger.

Built with Presence component - supports any animation techniques while maintaining access to presence emitted events.

Props

Prop Default Type
as'div'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

forceMountboolean

Used to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries.

value*string | number

A unique value that associates the trigger with a content.

Data Attributes

Attribute Value
[data-state]'active' | 'inactive'
[data-orientation]'vertical' | 'horizontal'

Examples

Vertical

You can create vertical tabs by using the orientation prop.

<script setup>
import { ATabsContent, ATabsList, ATabsRoot, ATabsTrigger } from 'akar';
</script>

<template>
  <ATabsRoot
    default-value="tab1"
    orientation="vertical"
  >
    <ATabsList aria-label="tabs example">
      <ATabsTrigger value="tab1">
        One
      </ATabsTrigger>
      <ATabsTrigger value="tab2">
        Two
      </ATabsTrigger>
      <ATabsTrigger value="tab3">
        Three
      </ATabsTrigger>
    </ATabsList>
    <ATabsContent value="tab1">
      Tab one content
    </ATabsContent>
    <ATabsContent value="tab2">
      Tab two content
    </ATabsContent>
    <ATabsContent value="tab3">
      Tab three content
    </ATabsContent>
  </ATabsRoot>
</template>

Accessibility

Adheres to the ATabs WAI-ARIA design pattern.

Keyboard Interactions

Key Description
Tab

When focus moves onto the tabs, focuses the active trigger. When a trigger is focused, moves focus to the active content.

ArrowDown

Moves focus to the next trigger depending on orientation and activates its associated content.

ArrowRight

Moves focus to the next trigger depending on orientation and activates its associated content.

ArrowUp

Moves focus to the previous trigger depending on orientation and activates its associated content.

ArrowLeft

Moves focus to the previous trigger depending on orientation and activates its associated content.

Home

Moves focus to the first trigger and activates its associated content.

End

Moves focus to the last trigger and activates its associated content.