Skip to content
v2.5.0
English
Русский
Documentation

Accordion

Accordion is a compound component for grouped expandable sections that share one root state model and item-level parts for headers, triggers, icons, and content.
  • Orders ship in 2–5 business days.
accordion.tsx · 32 lines
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
  Separator,
  Text,
} from '@vega-ui/react';

<Accordion defaultOpened={['shipping']} style={{ width: '100%' }}>
Browser support
Widely available
  • Chrome 111
  • Edge 111
  • Firefox 113
  • Safari 15.4
  • Safari on iOS 15.4
Bundle size
Tested in
25 tests

Summary

Accordion is a compound component for grouped expandable sections that share one root state model and item-level parts for headers, triggers, icons, and content.

Imports

import {
  Accordion,
  AccordionItem,
  AccordionHeader,
  AccordionTrigger,
  AccordionContent,
  AccordionIcon,
  type AccordionProps,
  type AccordionItemProps,
} from '@vega-ui/react';

Exported Types

  • AccordionProps
  • AccordionItemProps
  • AccordionHeaderProps
  • AccordionTriggerProps
  • AccordionContentProps
  • AccordionIconProps

Minimal Composition

minimal-composition.tsx · 24 lines
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
} from '@vega-ui/react';

export default function MinimalComposition() {
  return (
    <Accordion style={{ width: '100%' }}>

Required Parts

  • Accordion: root state and size owner
  • AccordionItem: one expandable section with its own value
  • AccordionHeader: semantic header wrapper for the trigger
  • AccordionTrigger: clickable and keyboard-accessible toggle
  • AccordionContent: expandable content region

Optional Parts

  • AccordionIcon: visual affordance that reflects open state

Composition Order

  1. Accordion
  2. AccordionItem
  3. AccordionHeader
  4. AccordionTrigger
  5. AccordionIcon
  6. AccordionContent

Variants

  • Single-open versus multiple-open groups through multiple
  • Uncontrolled versus controlled opened state
  • Size variants through size
  • Default icon versus custom icon composition

Edge Cases

  • multiple={false} means one newly opened item replaces the currently open item.
  • Rich trigger content should still preserve a full-width clickable trigger surface.
  • Custom wrappers around triggers or content should preserve the root composition contract.

Common Mistakes

  • Rendering AccordionContent outside AccordionItem.
  • Making only the icon clickable instead of the full trigger.
  • Treating Accordion like several unrelated Collapsible instances when one shared state model is intended.

Examples

Basic

Basic: FAQ list

A single-open accordion rendered from data. One item is open by default, and a Separator inside each item except the last keeps the rows visually apart.

faq.tsx · 54 lines
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
  Separator,
  Text,
} from '@vega-ui/react';

const questions = [

Controlled/Stateful

Controlled/Stateful: expand and collapse all

The parent owns opened, so a toolbar button can open or close every section at once and a readout shows how many are open. onChangeOpened keeps the state in sync when the user toggles a single section.

expand-all.tsx · 62 lines
import { useState } from 'react';
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
  Button,
  Separator,
  Text,
} from '@vega-ui/react';

Form/Integration

Form/Integration: settings form split into sections

Inputs inside a collapsed section are hidden, so the browser cannot focus them when native validation fails. The form listens to invalid events in the capture phase and opens the section that holds the invalid field; values are read with FormData on submit.

settings-form.tsx · 95 lines
import { FormEvent, useState } from 'react';
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
  Button,
  Label,
  Separator,
  TextField,

Layout/Overlay

Layout/Overlay: help topics in a drawer

A compact size='sm' accordion inside a scrollable drawer body. The drawer is named by its heading through aria-labelledby, and the accordion headers stay at h3 below the drawer's h2.

help-drawer.tsx · 69 lines
import type { CSSProperties } from 'react';
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
  Button,
  Drawer,
  DrawerClose,
  DrawerContent,

Error

Error: validation error visible on a collapsed section

The IBAN is validated on save. The error is linked to the input with aria-describedby, and the trigger also says “1 error”, so the problem is visible even while the section is collapsed. Fixing the value clears the error.

section-errors.tsx · 79 lines
import { ChangeEvent, useState } from 'react';
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
  Button,
  HelperText,
  Label,
  Text,

Disabled

Disabled: section unavailable on the current plan

AccordionTrigger renders a native button through asChild, so the button can be disabled and point to the reason with aria-describedby. The section stays visible but cannot be opened.

disabled-section.tsx · 47 lines
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
  Separator,
  Text,
} from '@vega-ui/react';

export default function DisabledSection() {

Edge

Edge: long trigger text and content that grows while open

The version string has no spaces, so the trigger text needs overflow-wrap: anywhere to wrap instead of pushing the icon out. “Show more” adds rows to an open section; the content height is re-measured because the content re-renders with the new rows.

release-notes.tsx · 63 lines
import { useState } from 'react';
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
  Button,
  Text,
} from '@vega-ui/react';

Edge: nested accordions and heading levels

An inner accordion lives inside an open section. Its headers use as='h4' so the page outline stays h2 → h3 → h4, and its state is independent from the outer accordion.

nested-sections.tsx · 64 lines
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
  Heading,
  Separator,
  Text,
} from '@vega-ui/react';

Anatomy

Overview

Accordion owns the shared open-state model for a group of expandable items. It is a compound component because the root, item, trigger, and content parts coordinate as one interaction system.

Required Parts

Accordion

Required. Owns size, opened values, and the single-open or multiple-open behavior.

AccordionItem

Required. Declares one section and its stable value.

AccordionHeader

Required in normal composition. Wraps the trigger semantically and keeps heading structure explicit.

AccordionTrigger

Required. Toggles the item and carries the main interaction surface.

AccordionContent

Required. Renders the expandable content for the item.

Optional Parts

AccordionIcon

Optional visual affordance for open and closed state. It should remain part of the trigger, not become a separate click target.

Composition Order

  1. Accordion
  2. AccordionItem
  3. AccordionHeader
  4. AccordionTrigger
  5. AccordionIcon
  6. AccordionContent

Valid Composition Patterns

faq.tsx · 54 lines
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionIcon,
  AccordionItem,
  AccordionTrigger,
  Separator,
  Text,
} from '@vega-ui/react';

const questions = [

Invalid Composition Patterns

AccordionContent outside AccordionItem

This breaks the item-level open-state contract.

Icon used as the only clickable affordance

The trigger should remain the full interaction surface, not just the decoration.

Several independent items when one grouped state model is intended

If the sections are supposed to coordinate, use one Accordion root instead of unrelated collapsibles.