Appearance
Tabs
Switches between a few panels of content in place, chosen from a row of tabs.
vue
<script setup lang="ts">
import { FsTabs } from '@fivespark/ui'
const items = [
{ value: 'details', label: 'Details' },
{ value: 'regels', label: 'Regels' },
{ value: 'historie', label: 'Historie' },
]
</script>
<template>
<FsTabs :items label="Onderdelen van de offerte" class="w-full">
<template #details><p class="type-body pt-4">Klant, referentie en leverdatum.</p></template>
<template #regels><p class="type-body pt-4">Twaalf regels, samen € 4.250,00.</p></template>
<template #historie><p class="type-body pt-4">Aangemaakt op 3 november 2026.</p></template>
</FsTabs>
</template>Usage
vue
<script setup lang="ts">
import { FsTabs } from '@fivespark/ui'
const items = [
{ value: 'details', label: 'Details' },
{ value: 'regels', label: 'Regels' },
]
</script>
<template>
<FsTabs :items label="Onderdelen van de offerte">
<template #details>Klant en referentie.</template>
<template #regels>De regels.</template>
</FsTabs>
</template>Each item's value is also the name of the slot holding its panel. Every panel is rendered; the inactive ones are hidden. Tabs are for panels on one page. To go to another page, use Navigation menu or Link. Use at least two tabs, and keep nothing interactive inside a tab itself.
Examples
Controlled with v-model
Bind v-model to the selected tab's value. Without it, the first tab is selected.
vue
<script setup lang="ts">
import { FsTabs } from '@fivespark/ui'
import { ref } from 'vue'
const items = [
{ value: 'open', label: 'Open' },
{ value: 'verstuurd', label: 'Verstuurd' },
{ value: 'akkoord', label: 'Akkoord' },
]
const tab = ref('verstuurd')
</script>
<template>
<div class="w-full">
<FsTabs v-model="tab" :items label="Status van offertes">
<template #open><p class="type-body pt-4">Vijf offertes wachten op verzending.</p></template>
<template #verstuurd><p class="type-body pt-4">Acht offertes wachten op een reactie.</p></template>
<template #akkoord><p class="type-body pt-4">Twee offertes zijn goedgekeurd.</p></template>
</FsTabs>
<p class="type-meta mt-4">Gekozen: {{ tab }}</p>
</div>
</template>With counts
count is a whole number shown after the label and read as part of the tab's name.
vue
<script setup lang="ts">
import { FsTabs } from '@fivespark/ui'
const items = [
{ value: 'regels', label: 'Regels', count: 12 },
{ value: 'documenten', label: 'Documenten', count: 3 },
{ value: 'opmerkingen', label: 'Opmerkingen', count: 0 },
]
</script>
<template>
<FsTabs :items label="Onderdelen van de order" class="w-full">
<template #regels><p class="type-body pt-4">Twaalf orderregels.</p></template>
<template #documenten><p class="type-body pt-4">Drie bijlagen.</p></template>
<template #opmerkingen><p class="type-body pt-4">Nog geen opmerkingen.</p></template>
</FsTabs>
</template>Dense
size="dense" makes the tabs 32px high instead of 36px.
vue
<script setup lang="ts">
import { FsTabs } from '@fivespark/ui'
const items = [
{ value: 'week', label: 'Week' },
{ value: 'maand', label: 'Maand' },
]
</script>
<template>
<FsTabs :items size="dense" label="Periode van de planning" class="w-full">
<template #week><p class="type-body pt-4">Planning van deze week.</p></template>
<template #maand><p class="type-body pt-4">Planning van deze maand.</p></template>
</FsTabs>
</template>Keyboard
| Key | Does |
|---|---|
| Tab | Moves focus into the row of tabs, to the selected tab; from the tab it moves on to the panel |
| →, ← | Selects and focuses the next or the previous tab; past either end it wraps. In right-to-left text the arrows swap |
| Home, End | Selects and focuses the first or the last tab |
API Reference
FsTabs
| Prop | Type | Default | Description |
|---|---|---|---|
items | { value: string; label: string; count?: number | undefined; }[] | required | The tabs, in order. `value` names the panel's slot and is the model's value; `count`, a whole number, is shown after the label and read as part of the tab's name. |
label | string | Names the row for assistive technology: for a page with two sets of tabs, or tabs under no heading. | |
size | "default" | "dense" | "default" | `default` is 36px high; `dense` is 32px. |
modelValue | string | The selected tab's value. Without `v-model`, the first tab is selected. |
| Event | Payload | Description |
|---|---|---|
update:modelValue | [value: string | undefined] | Sent with the new `modelValue`, for `v-model`. |