Skip to content

Accordion ​

Lets people open and close sections of a page, so a long page shows only what they need.

vue
<script setup lang="ts">
import { type AccordionItem, FsAccordion } from '@fivespark/ui'

const items: AccordionItem[] = [
  { value: 'levering', title: 'Afleveradres' },
  { value: 'factuur', title: 'Facturatie' },
  { value: 'notities', title: 'Notities' },
]
</script>

<template>
  <FsAccordion :items :level="3" class="w-full max-w-120">
    <template #levering><p class="type-body text-text">Hoofdstraat 1, Utrecht.</p></template>
    <template #factuur><p class="type-body text-text">Per maand, op rekening, 30 dagen.</p></template>
    <template #notities><p class="type-body text-text">Levering alleen op werkdagen voor 12:00.</p></template>
  </FsAccordion>
</template>

Usage ​

vue
<script setup lang="ts">
import { FsAccordion } from '@fivespark/ui'
</script>

<template>
  <FsAccordion :level="3" :items="[{ value: 'levering', title: 'Afleveradres' }]">
    <template #levering>Hoofdstraat 1, Utrecht.</template>
  </FsAccordion>
</template>

level is the heading level of the section titles: pick the one that fits the page around it. Each section's body is the slot named after its value. For content that is always visible, use Card; for switching between views, use Tabs.

Examples ​

With hints ​

A hint adds a few words after the title, such as a count, so people know what is inside before they open it.

vue
<script setup lang="ts">
import { type AccordionItem, FsAccordion } from '@fivespark/ui'

const items: AccordionItem[] = [
  { value: 'levering', title: 'Afleveradressen', hint: '3 adressen' },
  { value: 'notities', title: 'Notities', hint: '1 notitie' },
]
</script>

<template>
  <FsAccordion :items :level="3" class="w-full max-w-120">
    <template #levering><p class="type-body text-text">Hoofdstraat 1, Utrecht; Kade 4, Rotterdam; Markt 9, Breda.</p></template>
    <template #notities><p class="type-body text-text">Levering alleen op werkdagen voor 12:00.</p></template>
  </FsAccordion>
</template>

Controlled ​

Bind the open sections with v-model, an array of values. Without it every section starts closed.

vue
<script setup lang="ts">
import { type AccordionItem, FsAccordion, FsButton } from '@fivespark/ui'
import { ref } from 'vue'

const items: AccordionItem[] = [
  { value: 'levering', title: 'Afleveradres' },
  { value: 'factuur', title: 'Facturatie' },
]
const open = ref(['levering'])
</script>

<template>
  <div class="flex w-full max-w-120 flex-col gap-3">
    <FsAccordion v-model="open" :items :level="3">
      <template #levering><p class="type-body text-text">Hoofdstraat 1, Utrecht.</p></template>
      <template #factuur><p class="type-body text-text">Per maand, op rekening, 30 dagen.</p></template>
    </FsAccordion>
    <FsButton label="Alles sluiten" @click="open = []" />
  </div>
</template>

Exclusive ​

Opening a section closes the others, where the browser supports <details name>; in an older browser the sections open independently.

vue
<script setup lang="ts">
import { type AccordionItem, FsAccordion } from '@fivespark/ui'

const items: AccordionItem[] = [
  { value: 'standaard', title: 'Standaard levering' },
  { value: 'spoed', title: 'Spoedlevering' },
]
</script>

<template>
  <FsAccordion exclusive :items :level="3" class="w-full max-w-120">
    <template #standaard><p class="type-body text-text">Binnen vijf werkdagen geleverd.</p></template>
    <template #spoed><p class="type-body text-text">Binnen twee werkdagen, tegen een toeslag.</p></template>
  </FsAccordion>
</template>

Dense ​

vue
<script setup lang="ts">
import { type AccordionItem, FsAccordion } from '@fivespark/ui'

const items: AccordionItem[] = [
  { value: 'levering', title: 'Afleveradres' },
  { value: 'factuur', title: 'Facturatie' },
]
</script>

<template>
  <FsAccordion size="dense" :items :level="3" class="w-full max-w-120">
    <template #levering><p class="type-body text-text">Hoofdstraat 1, Utrecht.</p></template>
    <template #factuur><p class="type-body text-text">Per maand, op rekening, 30 dagen.</p></template>
  </FsAccordion>
</template>

Keyboard ​

KeyDoes
Enter, SpaceOpens or closes the focused section
TabMoves to the next section title, or into an open body

API Reference ​

FsAccordion ​

PropTypeDefaultDescription
itemsAccordionItem[]requiredThe sections, in order. Each one's body is the slot named by its `value`.
level2 | 3 | 4 | 5 | 6requiredThe titles' heading level, as the page around the accordion needs. Every level looks the same.
exclusivebooleanfalseOpening a section closes the others, where the browser supports it; elsewhere several stay open.
size"default" | "dense""default"`dense` beside dense controls.
modelValuestring[][]The open sections' values. Without `v-model`, every section starts closed.
EventPayloadDescription
update:modelValue[value: string[]]Sent with the new `modelValue`, for `v-model`.