Keyboard shortcut: Ctrl + K
Get started

Accordion

Sections that fold. It is built on <details> and <summary>, so the open state, the keyboard behaviour and in-page search all come from the browser.

Usage

vue
Does it work with Nuxt?
Yes. The package is SSR-safe and ships as ESM.
Is there a Tailwind preset?
No. The tokens are custom properties, which any framework can read.
<script setup lang="ts">
import { VAccordion, VAccordionItem } from 'vectis-ui'
</script>

<template>
  <VAccordion>
    <VAccordionItem title="Does it work with Nuxt?" default-open>
      Yes. The package is SSR-safe and ships as ESM.
    </VAccordionItem>
    <VAccordionItem title="Is there a Tailwind preset?">
      No. The tokens are custom properties, which any framework can read.
    </VAccordionItem>
  </VAccordion>
</template>

Examples

Variants

variant sets the group decoration: flat (default) draws nothing, outlined adds a raised background, a border and rounded corners.

vue
Flat, the default
Nothing is drawn around the group, which lets it sit on the surface behind it.
No background, no border
Reach for it when the page already provides the frame.
Outlined
A raised background, a border and rounded corners, so the group reads as a card.
Its own surface
Reach for it when the accordion has to stand apart from what surrounds it.
<script setup lang="ts">
import { VAccordion, VAccordionItem } from 'vectis-ui'
</script>

<template>
  <VAccordion>
    <VAccordionItem title="Flat, the default" default-open>
      Nothing is drawn around the group, which lets it sit on the surface behind it.
    </VAccordionItem>
    <VAccordionItem title="No background, no border">
      Reach for it when the page already provides the frame.
    </VAccordionItem>
  </VAccordion>

  <VAccordion variant="outlined">
    <VAccordionItem title="Outlined" default-open>
      A raised background, a border and rounded corners, so the group reads as a card.
    </VAccordionItem>
    <VAccordionItem title="Its own surface">
      Reach for it when the accordion has to stand apart from what surrounds it.
    </VAccordionItem>
  </VAccordion>
</template>

One section at a time

A group keeps a single section open by default. multiple allows several sections to stay open at the same time. VSideNavigation has the opposite default and the opposite prop, exclusive: a sidebar usually lets several sections stay open.

vue
How long does delivery take?
Two working days in France, five anywhere else in Europe.
Do you ship outside Europe?
Yes, to twenty-eight countries. The rate is shown at checkout.
Can I change the address after ordering?
Until the parcel is handed to the carrier, from the order page.
What can I return?
Anything unworn, within thirty days of delivery.
Who pays for the return?
We do, once per order. The label is in your account.
When is the refund issued?
Within three working days of the parcel reaching the warehouse.
<script setup lang="ts">
import { VAccordion, VAccordionItem } from 'vectis-ui'
</script>

<template>
  <VAccordion>
    <VAccordionItem title="How long does delivery take?" default-open>
      Two working days in France, five anywhere else in Europe.
    </VAccordionItem>
    <VAccordionItem title="Do you ship outside Europe?">
      Yes, to twenty-eight countries. The rate is shown at checkout.
    </VAccordionItem>
    <VAccordionItem title="Can I change the address after ordering?">
      Until the parcel is handed to the carrier, from the order page.
    </VAccordionItem>
  </VAccordion>

  <VAccordion variant="outlined" multiple>
    <VAccordionItem title="What can I return?" default-open>
      Anything unworn, within thirty days of delivery.
    </VAccordionItem>
    <VAccordionItem title="Who pays for the return?" default-open>
      We do, once per order. The label is in your account.
    </VAccordionItem>
    <VAccordionItem title="When is the refund issued?">
      Within three working days of the parcel reaching the warehouse.
    </VAccordionItem>
  </VAccordion>
</template>

Subtitles and icons

icon places an icon before the title and subtitle adds a second line under it. The #icon and #subtitle slots take markup instead of plain text.

vue
NotificationsEmail and in-app alerts
Choose which events reach you, and where.
AvailabilityWorking hours and time zone
The hours during which your team can be reached.
DocumentsContracts and invoices
Everything signed or billed on this account.
<script setup lang="ts">
import { VAccordion, VAccordionItem } from 'vectis-ui'
import { description, notifications, schedule } from 'vectis-ui/icons'
</script>

<template>
  <VAccordion variant="outlined">
    <VAccordionItem
      :icon="notifications"
      title="Notifications"
      subtitle="Email and in-app alerts"
      default-open
    >
      Choose which events reach you, and where.
    </VAccordionItem>
    <VAccordionItem :icon="schedule" title="Availability" subtitle="Working hours and time zone">
      The hours during which your team can be reached.
    </VAccordionItem>
    <VAccordionItem :icon="description" title="Documents" subtitle="Contracts and invoices">
      Everything signed or billed on this account.
    </VAccordionItem>
  </VAccordion>
</template>

Compact

compact reduces every padding by 4px, leaving the text and the icons at their size.

vue
RuntimeNode 20.11
The oldest version the package is tested against.
Package managerpnpm 11
Any manager works. The repository itself uses pnpm.
Module formatESM only
There is no CommonJS build, and none is planned.
<script setup lang="ts">
import { VAccordion, VAccordionItem } from 'vectis-ui'
</script>

<template>
  <VAccordion variant="outlined" compact>
    <VAccordionItem title="Runtime" subtitle="Node 20.11" default-open>
      The oldest version the package is tested against.
    </VAccordionItem>
    <VAccordionItem title="Package manager" subtitle="pnpm 11">
      Any manager works. The repository itself uses pnpm.
    </VAccordionItem>
    <VAccordionItem title="Module format" subtitle="ESM only">
      There is no CommonJS build, and none is planned.
    </VAccordionItem>
  </VAccordion>
</template>

Expand and collapse icons

expandIcon replaces the chevron. Adding collapseIcon swaps the two icons when a section opens, instead of rotating the first one.

vue
Where do these two icons come from?
From the icon set wired into the application, since both are given here as names.
And without a collapse icon?
The expand icon stays in place and is rotated when the section opens.
<script setup lang="ts">
import { VAccordion, VAccordionItem } from 'vectis-ui'
</script>

<template>
  <VAccordion variant="outlined" expand-icon="add" collapse-icon="remove">
    <VAccordionItem title="Where do these two icons come from?" default-open>
      From the icon set wired into the application, since both are given here as names.
    </VAccordionItem>
    <VAccordionItem title="And without a collapse icon?">
      The expand icon stays in place and is rotated when the section opens.
    </VAccordionItem>
  </VAccordion>
</template>

Disabled sections

disabled prevents a section from being opened and greys it out. The keyboard steps over it.

vue
Personal details
Your name, your address and how we may contact you.
Payment methods
Available once your email address has been confirmed.
Delivery preferences
Available once a payment method has been added.
Privacy
What we store, and for how long.
<script setup lang="ts">
import { VAccordion, VAccordionItem } from 'vectis-ui'
</script>

<template>
  <VAccordion variant="outlined">
    <VAccordionItem title="Personal details" default-open>
      Your name, your address and how we may contact you.
    </VAccordionItem>
    <VAccordionItem title="Payment methods" disabled>
      Available once your email address has been confirmed.
    </VAccordionItem>
    <VAccordionItem title="Delivery preferences" disabled>
      Available once a payment method has been added.
    </VAccordionItem>
    <VAccordionItem title="Privacy"> What we store, and for how long. </VAccordionItem>
  </VAccordion>
</template>

API

Props

VAccordion
PropTypeDefault
multiplebooleanfalse
Lets the reader keep several sections open at once. Left out, only one stays open and opening one closes the last, which the browser does on its own once every item shares a <details> name.
variantAccordionVariant'flat' | 'outlined''flat'
How the group is decorated. flat draws nothing and lets the accordion sit on the surface behind it; outlined gives it a raised background, a border and rounded corners, so it reads as a card.
expandIconIconSourceexpand_more
The icon shown on a closed section. It is a chevron, which rotates by 180° when the section opens.
collapseIconIconSourcenone
The icon shown on an open section. Leave it out and the expand icon is rotated instead; give one and the two are swapped.
compactbooleanfalse
Reduced density: every padding loses 4px, while the text and the icons keep their size.
VAccordionItem
PropTypeDefault
titlestringnone
The heading of the section, the line that stays visible when it is closed. Use the #title slot when the heading needs markup rather than plain text.
subtitlestringnone
A second line under the title, for a short explanation or a status. The #subtitle slot replaces it when markup is needed.
iconIconSourcenone
An icon before the title. The #icon slot replaces it.
defaultOpenbooleanfalse
Renders the section already open. Only its initial value is read: the browser owns the state afterwards, so changing this later will not close a section the reader has opened.
disabledbooleanfalse
Makes the section inert. It can no longer be opened, the keyboard steps over it, and it greys out through the colour tokens.
v-model:openboolean | nullnull
Whether the section is open, when you want to drive or observe it. Left unbound, the browser keeps that state to itself and defaultOpen gives only the initial value.

Slots

VAccordion
SlotType
default{}
The VAccordionItems that make up the group.
VAccordionItem
SlotType
default{}
The content revealed when the section is open.
title{}
A title made of markup, which replaces the title prop.
subtitle{}
A subtitle made of markup, which replaces the subtitle prop.
icon{}
Free content before the title, which takes the place of icon.

Types

The types the tables above name, written as the library declares them. The ones carrying export can be imported from vectis-ui to type your own code; the others are the shape of what a slot hands out.

export interface BuiltinIcon {
  name: string
  paths: readonly [string] | readonly [string, string]
}
export type IconRender =
  | { path: string; viewBox?: string }
  | { component: Component; props?: Record<string, unknown> }
  | { src: string }
  | { text: string; class?: string }
  | { class: string }
export type IconSource = string | BuiltinIcon | IconRender