Skip to content

Layout

IAccordion

A list of panels where opening one is the whole interaction. Use it for questions with long answers, or settings a reader visits rarely — not for content they need side by side, which wants ITabs or no disclosure at all.

Net 30 by default. Change it per client, or per invoice when a job warrants it.

The panel animates its height, so the rows below slide rather than jump. v-model holds the open item's value, which defaults to its label — give an item an explicit value when the label is long or likely to be reworded.

One panel or several

type="multiple" lets any number stand open, and the model becomes an array.

Net 30 by default. Change it per client, or per invoice when a job warrants it.

In single mode, collapsible (on by default) lets the open panel be closed again by clicking its own trigger. Turn it off when something must always be showing.

Outline

Invoices, estimates and payment terms.

plain is rules between rows and nothing else — the quieter of the two, and right when the accordion is the page. outline gives each item its own panel, which holds together better on a busy page where the rules would compete with everything around them.

An item can carry an icon, on either variant.

Markup in a panel

content is for text. Anything else goes in the content slot, which receives the item.

The trigger slot replaces the row's own content the same way — a badge beside the label, a count, a second line.

Props

PropTypeDefaultDescription
itemsAccordionItemData[]The rows
type'single' | 'multiple''single'One panel open, or several
collapsiblebooleantrueLet the open panel close again. single only
variant'plain' | 'outline''plain'Rules between rows, or a panel each
disabledbooleanDisable every row
unstyledbooleanDrop built-in classes
classstringMerged with the built-in classes
ui{ root?, item?, header?, trigger?, icon?, content?, contentInner? }Per-slot class overrides

v-model is a string for single and a string[] for multiple.

Slots

SlotPropsWhen to use it
trigger{ item }Replace the row's label — a badge, a count, a second line
content{ item }Panel contents with markup

Item shape

ts
interface AccordionItemData {
  label: string
  content?: string
  /** Identity in the model. Defaults to the label. */
  value?: string
  icon?: IconLike
  disabled?: boolean
}

Panel spacing lives on an inner wrapper, reachable as ui.contentInner. Put padding there rather than on ui.content, whose height is animated.