navigation
Tabs
A set of tab panels that are displayed one at a time.
Usage
Pass an array to the items prop of the Tabs component. Each item can have the following properties:
label- The label of the item.slot- A key to customize the item with a slot.content- The content to display in the panel by default.disabled- Determines whether the item is disabled or not.
<script setup>const items = [{  label: 'Tab1',  content: 'This is the content shown for Tab1'}, {  label: 'Tab2',  disabled: true,  content: 'And, this is the content for Tab2'}, {  label: 'Tab3',  content: 'Finally, this is the content for Tab3'}]</script><template>  <UTabs :items="items" /></template>Vertical
You can change the orientation of the tabs by setting the orientation prop to vertical.
<script setup>const items = [...]</script><template>  <UTabs :items="items" orientation="vertical" :ui="{ wrapper: 'flex items-center gap-4', list: { width: 'w-48' } }" /></template>Default index
You can set the default index of the tabs by setting the default-index prop.
<script setup>const items = [...]</script><template>  <UTabs :items="items" :default-index="2" /></template>v-model to control the selected index.Listen to changes
You can listen to changes by using the @change event. The event will emit the index of the selected item.
<script setup>const items = [...]function onChange (index) {  const item = items[index]  alert(`${item.label} was clicked!`)}</script><template>  <UTabs :items="items" @change="onChange" /></template>Control the selected index
Use a v-model to control the selected index.
<script setup>const items = [...]const route = useRoute()const router = useRouter()const selected = computed({  get () {    const index = items.findIndex((item) => item.label === route.query.tab)    if (index === -1) {      return 0    }    return index  },  set (value) {    // Hash is specified here to prevent the page from scrolling to the top    router.replace({ query: { tab: items[value].label }, hash: '#control-the-selected-index' })  }})</script><template>  <UTabs v-model="selected" :items="items" /></template>Slots
You can use slots to customize the buttons and items content of the Accordion.
default
Use the #default slot to customize the content of the trigger buttons. You will have access to the item, index, selected and disabled in the slot scope.
<script setup>const items = [{  label: 'Introduction',  icon: 'i-heroicons-information-circle',  content: 'This is the content shown for Tab1'}, {  label: 'Installation',  icon: 'i-heroicons-arrow-down-tray',  content: 'And, this is the content for Tab2'}, {  label: 'Theming',  icon: 'i-heroicons-eye-dropper',  content: 'Finally, this is the content for Tab3'}]</script><template>  <UTabs :items="items" class="w-full">    <template #default="{ item, index, selected }">      <div class="flex items-center gap-2 relative truncate">        <UIcon :name="item.icon" class="w-4 h-4 flex-shrink-0" />        <span class="truncate">{{ index + 1 }}. {{ item.label }}</span>        <span v-if="selected" class="absolute -right-4 w-2 h-2 rounded-full bg-primary-500 dark:bg-primary-400" />      </div>    </template>  </UTabs></template>item
Use the #item slot to customize the items content. You will have access to the item, index and selected properties in the slot scope.
<script setup>const items = [{  key: 'account',  label: 'Account',  description: 'Make changes to your account here. Click save when you\'re done.'}, {  key: 'password',  label: 'Password',  description: 'Change your password here. After saving, you\'ll be logged out.'}]const accountForm = reactive({ name: 'Benjamin', username: 'benjamincanac'  })const passwordForm = reactive({ currentPassword: '', newPassword: '' })function onSubmit (form) {  console.log('Submitted form:', form)}</script><template>  <UTabs :items="items" class="w-full">    <template #item="{ item }">      <UCard @submit.prevent="() => onSubmit(item.key === 'account' ? accountForm : passwordForm)">        <template #header>          <h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white">            {{ item.label }}          </h3>          <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">            {{ item.description }}          </p>        </template>        <div v-if="item.key === 'account'" class="space-y-3">          <UFormGroup label="Name" name="name">            <UInput v-model="accountForm.name" />          </UFormGroup>          <UFormGroup label="Username" name="username">            <UInput v-model="accountForm.username" />          </UFormGroup>        </div>        <div v-else-if="item.key === 'password'" class="space-y-3">          <UFormGroup label="Current Password" name="current" required>            <UInput v-model="passwordForm.currentPassword" type="password" required />          </UFormGroup>          <UFormGroup label="New Password" name="new" required>            <UInput v-model="passwordForm.newPassword" type="password" required />          </UFormGroup>        </div>        <template #footer>          <UButton type="submit" color="black">            Save {{ item.key === 'account' ? 'account' : 'password' }}          </UButton>        </template>      </UCard>    </template>  </UTabs></template>You can also pass a slot property to customize a specific item.
<script setup>const items = [{  slot: 'account',  label: 'Account'}, {  slot: 'password',  label: 'Password'}]const accountForm = reactive({ name: 'Benjamin', username: 'benjamincanac'  })const passwordForm = reactive({ currentPassword: '', newPassword: '' })function onSubmitAccount () {  console.log('Submitted form:', accountForm)}function onSubmitPassword () {  console.log('Submitted form:', passwordForm)}</script><template>  <UTabs :items="items" class="w-full">    <template #account="{ item }">      <UCard @submit.prevent="onSubmitAccount">        <template #header>          <h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white">            {{ item.label }}          </h3>          <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">            Make changes to your account here. Click save when you're done.          </p>        </template>        <UFormGroup label="Name" name="name" class="mb-3">          <UInput v-model="accountForm.name" />        </UFormGroup>        <UFormGroup label="Username" name="username">          <UInput v-model="accountForm.username" />        </UFormGroup>        <template #footer>          <UButton type="submit" color="black">            Save account          </UButton>        </template>      </UCard>    </template>    <template #password="{ item }">      <UCard @submit.prevent="onSubmitPassword">        <template #header>          <h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white">            {{ item.label }}          </h3>          <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">            Change your password here. After saving, you'll be logged out.          </p>        </template>        <UFormGroup label="Current Password" name="current" required class="mb-3">          <UInput v-model="passwordForm.currentPassword" type="password" required />        </UFormGroup>        <UFormGroup label="New Password" name="new" required>          <UInput v-model="passwordForm.newPassword" type="password" required />        </UFormGroup>        <template #footer>          <UButton type="submit" color="black">            Save password          </UButton>        </template>      </UCard>    </template>  </UTabs></template>Props
"horizontal"undefined[]undefined0Preset
{  "wrapper": "relative space-y-2",  "container": "relative w-full",  "base": "focus:outline-none",  "list": {    "base": "relative",    "background": "bg-gray-100 dark:bg-gray-800",    "rounded": "rounded-lg",    "shadow": "",    "padding": "p-1",    "height": "h-10",    "width": "w-full",    "marker": {      "wrapper": "absolute top-[4px] left-[4px] duration-200 ease-out focus:outline-none",      "base": "w-full h-full",      "background": "bg-white dark:bg-gray-900",      "rounded": "rounded-md",      "shadow": "shadow-sm"    },    "tab": {      "base": "relative inline-flex items-center justify-center flex-shrink-0 w-full ui-focus-visible:outline-0 ui-focus-visible:ring-2 ui-focus-visible:ring-primary-500 dark:ui-focus-visible:ring-primary-400 ui-not-focus-visible:outline-none focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 transition-colors duration-200 ease-out",      "background": "",      "active": "text-gray-900 dark:text-white",      "inactive": "text-gray-500 dark:text-gray-400",      "height": "h-8",      "padding": "px-3",      "size": "text-sm",      "font": "font-medium",      "rounded": "rounded-md",      "shadow": ""    }  }}