Accordion
Collapsible stacked sections.
<script setup lang="ts">
import { Accordion } from '@shardsui/vue/accordion'
const faqs = [
{
question: 'Kerning or tracking?',
answer:
'Kerning adjusts the space between two specific characters. Tracking spaces a whole word or block uniformly.'
},
{
question: 'Ease-in or ease-out for an entrance?',
answer:
'Ease-out. It starts fast and settles into place, so entrances feel natural — ease-in feels reluctant.'
}
]
</script>
<template>
<Accordion.Root class="flex w-full max-w-80 flex-col text-gray-900">
<Accordion.Item v-for="faq in faqs" :key="faq.question" class="border-b border-gray-200">
<Accordion.Header as="h2">
<Accordion.Trigger
class="group relative flex w-full items-center justify-between gap-4 bg-gray-50 px-3 py-2 text-left text-sm font-normal focus-visible:z-1 focus-visible:outline-2 focus-visible:outline-gray-950"
>
{{ faq.question }}
<svg
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
class="block size-4 shrink-0 transition-transform duration-100 ease-out group-data-panel-open:rotate-45"
>
<path
d="M12 3.75V12M12 12V20.25M12 12H3.75M12 12H20.25"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</Accordion.Trigger>
</Accordion.Header>
<Accordion.Panel
class="h-(--accordion-panel-height) overflow-hidden text-sm text-gray-600 transition-[height] duration-150 ease-out data-ending-style:h-0 data-starting-style:h-0"
>
<div class="px-3 py-2">{{ faq.answer }}</div>
</Accordion.Panel>
</Accordion.Item>
</Accordion.Root>
</template>Anatomy
<script setup>
import { Accordion } from '@shardsui/vue/accordion'
</script>
<template>
<Accordion.Root>
<Accordion.Item>
<Accordion.Header>
<Accordion.Trigger />
</Accordion.Header>
<Accordion.Panel />
</Accordion.Item>
</Accordion.Root>
</template>Examples
Open multiple panels
Set multiple to keep more than one panel open at once.
<script setup lang="ts">
import { Accordion } from '@shardsui/vue/accordion'
const sections = [
{
title: 'Type scale',
content: 'Pick every size from one ratio-based scale so hierarchy stays consistent.'
},
{
title: 'Focus states',
content: 'Keep the keyboard-focused element visible — restyle the outline, never remove it.'
}
]
</script>
<template>
<Accordion.Root multiple class="flex w-full max-w-80 flex-col text-gray-900">
<Accordion.Item
v-for="section in sections"
:key="section.title"
class="border-b border-gray-200"
>
<Accordion.Header>
<Accordion.Trigger
class="group relative flex w-full items-center justify-between gap-4 bg-gray-50 px-3 py-2 text-left text-sm font-normal focus-visible:z-1 focus-visible:outline-2 focus-visible:outline-gray-950"
>
{{ section.title }}
<svg
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
class="block size-4 shrink-0 transition-transform duration-100 ease-out group-data-panel-open:rotate-45"
>
<path
d="M12 3.75V12M12 12V20.25M12 12H3.75M12 12H20.25"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</Accordion.Trigger>
</Accordion.Header>
<Accordion.Panel
class="h-(--accordion-panel-height) overflow-hidden text-sm text-gray-600 transition-[height] duration-150 ease-out data-ending-style:h-0 data-starting-style:h-0"
>
<div class="px-3 py-2">{{ section.content }}</div>
</Accordion.Panel>
</Accordion.Item>
</Accordion.Root>
</template>API reference
Root
Groups all parts of the accordion.
Renders a <div> element.
| Prop | Type | Default | |
|---|---|---|---|
as | keyof HTMLElementTagNameMap | 'div' | |
class | string | — | |
style | string | — | |
value | Value[] | [] | |
disabled | boolean | false | |
hiddenUntilFound | boolean | false | |
multiple | boolean | false | |
keepMounted | boolean | false | |
update:value | (value: Value[]) => void | — | |
default | Slot<{ value, disabled }> | — | |
| Attribute | Description |
|---|---|
data-disabled | Present when the accordion is disabled. |
Item
Groups an accordion header with the corresponding panel.
Renders a <div> element.
| Prop | Type | Default | |
|---|---|---|---|
as | keyof HTMLElementTagNameMap | 'div' | |
class | string | — | |
style | string | — | |
value | unknown | — | |
disabled | boolean | false | |
openChange | (open: boolean) => void | — | |
default | Slot<{ value, disabled, hidden, open }> | — | |
| Attribute | Description |
|---|---|
data-open | Present when the accordion item is open. |
data-closed | Present when the accordion item is closed. |
data-hidden | Present when the panel is closed and not animating out. |
data-disabled | Present when the accordion item is disabled. |
Header
A heading that labels the corresponding panel.
Renders an <h3> element.
| Prop | Type | Default | |
|---|---|---|---|
as | keyof HTMLElementTagNameMap | 'h3' | |
class | string | — | |
style | string | — | |
default | Slot<{ value, disabled, hidden, open }> | — | |
| Attribute | Description |
|---|---|
data-open | Present when the accordion item is open. |
data-closed | Present when the accordion item is closed. |
data-hidden | Present when the panel is closed and not animating out. |
data-disabled | Present when the accordion item is disabled. |
Trigger
A button that opens and closes the corresponding panel.
Renders a <button> element.
| Prop | Type | Default | |
|---|---|---|---|
as | keyof HTMLElementTagNameMap | 'button' | |
class | string | — | |
style | string | — | |
id | string | auto | |
disabled | boolean | — | |
default | Slot<{ value, disabled, hidden, open }> | — | |
| Attribute | Description |
|---|---|
data-panel-open | Present when the accordion panel is open. |
data-hidden | Present when the panel is closed and not animating out. |
data-disabled | Present when the accordion item is disabled. |
Panel
A collapsible panel with the accordion item contents.
Renders a <div> element.
| Prop | Type | Default | |
|---|---|---|---|
as | keyof HTMLElementTagNameMap | 'div' | |
class | string | — | |
style | string | — | |
id | string | auto | |
keepMounted | boolean | — | |
hiddenUntilFound | boolean | — | |
default | Slot<{ value, disabled, hidden, open, transitionStatus }> | — | |
| CSS Variable | Description |
|---|---|
--accordion-panel-height | The panel's computed height. |
--accordion-panel-width | The panel's computed width. |
| Attribute | Description |
|---|---|
data-open | Present when the accordion panel is open. |
data-closed | Present when the accordion panel is closed. |
data-hidden | Present when the panel is closed and not animating out. |
data-disabled | Present when the accordion item is disabled. |
data-starting-style | Present when the panel is animating in. |
data-ending-style | Present when the panel is animating out. |