Components

Accordion

A set of collapsible sections with headings.

A vertically stacked list of items that can be expanded or collapsed. Supports single or multiple open items and full keyboard navigation.

Anatomy

Accordion is a single component. You shape every part through named slots:

  • #trigger: Content rendered inside the trigger button. Defaults to the item label.
  • #icon: Optional chevron or indicator rendered after the trigger content.
  • #content: Panel body revealed when the item is open.
  • #[item.slot]: Per-item override when an item has a slot key.

The trigger button itself is rendered by the component; use the ui.trigger prop to add classes to it.

Usage

Examples

Custom trigger and icon

The #trigger slot is rendered inside the trigger button — use it to customise the label content. Style the button itself with ui.trigger. Use #icon to override the chevron indicator.

<template>
  <Accordion :items="items" :ui="{ trigger: 'px-4 py-3 hover:bg-neutral-50' }">
    <template #trigger="{ item, isOpen }">
      <span :class="['trigger-label', { 'trigger-label--open': isOpen }]">
        {{ item.label }}
      </span>
    </template>

    <template #icon="{ isOpen }">
      <svg :class="['icon', { 'icon--open': isOpen }]" .../>
    </template>
  </Accordion>
</template>

Multiple open items

Use type="multiple" when more than one accordion panel should stay open at the same time.

<template>
  <Accordion :items="items" type="multiple" />
</template>

Per-item custom content

Give an item a slot key to render rich content in its panel.

<script setup lang="ts">
const items = [
  { value: "form", label: "Contact us", slot: "contact-form" },
];
</script>

<template>
  <Accordion :items="items">
    <template #contact-form="{ close }">
      <form @submit.prevent="close">
        <input type="email" placeholder="your@email.com" />
        <button type="submit">Send</button>
      </form>
    </template>
  </Accordion>
</template>

API Reference

Props

PropTypeDefaultDescription
itemsAccordionItem[]Required. List of accordion items.
type"single" | "multiple""single"Whether one or many items can be open simultaneously.
collapsiblebooleanfalseAllow toggling the open item closed again (single mode only).
disabledbooleanfalseDisable all items.
orientation"vertical" | "horizontal""vertical"Orientation of the accordion.
unmountOnHidebooleanfalseRemove content from the DOM when closed instead of hiding it.
valueKeystringProperty to read as the unique item value.
labelKeystring"label"Property to use as the trigger label.
contentKeystringProperty to use as the body text.
disabledKeystring"disabled"Property to read for per-item disabled state.
asstring"div"Root element tag.
uiAccordionUiCSS class overrides.

AccordionItem

KeyTypeDescription
valuestringUnique identifier. Auto-generated if omitted.
labelstringTrigger label text.
contentstringPanel body text (used when no content slot is provided).
disabledbooleanDisables this item.
slotstringNamed slot key for a custom panel content slot.

Slots

SlotScoped propsDescription
trigger{ item, value, isOpen, toggle }Trigger button content for every item.
icon{ isOpen, item }Icon inside the trigger (e.g. chevron).
content{ item, value, isOpen }Panel body content for every item.
[item.slot]{ item, value, isOpen }Per-item panel override when item.slot is set.

Emits

EventPayloadDescription
value-change[value: string | string[], details]Fired when the open item(s) change.

UI Options

KeyDescription
rootRoot accordion element.
itemWrapper element around each trigger + content pair.
triggerThe trigger button element.
iconThe icon container inside the trigger.
contentWrapperAnimated region wrapper.
contentInnerOverflow-hiding inner wrapper.
contentPanel body element.

Styling Hooks

UI keyCSS classData attrs
rootakaza-accordiondata-akaza-orientation
itemakaza-accordion-itemdata-akaza-state, data-akaza-disabled
triggerakaza-accordion-triggerdata-akaza-state, data-akaza-disabled
iconakaza-accordion-icondata-akaza-state
contentWrapperakaza-accordion-contentdata-akaza-state
contentInnerakaza-accordion-content-inner
contentakaza-accordion-content-body