Accordion

A component that consists of multiple collapsible sections.

Features

  • Option to hide the content when collapsed instead of unmounting it for better SEO
  • CSS variables to animate the height/width of every item content
  • Full keyboard navigation

Usage

import Accordion from 'corvu/accordion'
// Or
// import { Root, Trigger, ... } from 'corvu/accordion'

Anatomy

<Accordion.Root>
  <Accordion.Item>
    <Accordion.Trigger />
    <Accordion.Content />
  </Accordion.Item>
</Accordion.Root>

The accordion item uses the Disclosure component under the hood. It forwards the same props in the Item children callback and the disclosure context is re-exported as Accordion.useDisclosureContext.

Animation

Corvu sets the --corvu-disclosure-content-height and --corvu-disclosure-content-width css properties on every accordion item content that make it possible to animate the height/width.

[data-corvu-accordion-content][data-collapsed] {
  animation: collapse 200ms linear;
}
[data-corvu-accordion-content][data-expanded] {
  animation: expand 200ms linear;
}

@keyframes collapse {
  0% {
    height: var(--corvu-disclosure-content-height);
  }
  100% {
    height: 0px;
  }
}

@keyframes expand {
  0% {
    height: 0px;
  }
  100% {
    height: var(--corvu-disclosure-content-height);
  }
}

Accessibility

Adheres to the Accordion WAI-ARIA design pattern.

Ensuring items are accessible

Based on the Accordion WAI-ARIA design pattern, every accordion item trigger should include a meaningful title text and should be wrapped in a heading element like this:

<Accordion.Item>
    <h3>
      <Accordion.Trigger>What is corvu?</Accordion.Trigger>
    </h3>
    <Accordion.Content />
  </Accordion.Item>

If you don’t want to use a heading element for some reason, you can instead use the aria-level attribute to define the hierarchical level:

<Accordion.Item>
    <span aria-level="3">
      <Accordion.Trigger>What is corvu?</Accordion.Trigger>
    </span>
    <Accordion.Content />
  </Accordion.Item>

Keyboard navigation

Key Behavior
Space When the trigger of an item is focused, toggles the item content.
Enter When the trigger of an item is focused, toggles the item content.
Tab Moves focus to the next focusable element.
Shift + Tab Moves focus to the previous focusable element.
ArrowDown When the trigger of an item is focused and orientation is 'vertical' (default), moves to the next trigger.
ArrowUp When the trigger of an item is focused and orientation is 'vertical' (default), moves to the previous trigger.
ArrowRight When the trigger of an item is focused and orientation is 'horizontal', moves to the next trigger.
ArrowLeft When the trigger of an item is focused and orientation is 'horizontal', moves to the previous trigger.
Home When the trigger of an item is focused, moves to the first trigger.
End When the trigger of an item is focused, moves to the first trigger.

API reference

The disclosure context is re-exported as Accordion.useDisclosureContext and the item children callback also accepts all props of the disclosure root children callback, which are documented in the Disclosure API reference.

Accordion.Root

Component

Context wrapper for the accordion. Is required for every accordion you create.

Props

multiple

boolean

Whether multiple accordion items can be expanded at the same time. *Default = false*

value

string | string[] | null

The value of the accordion.

onValueChange

(value: string | string[] | null) => void

Callback fired when the value changes.

initialValue

string | string[] | null

The value of the accordion initially. *Default = null*

collapsible

boolean

Whether the accordion can be fully collapsed or not. *Default = true*

disabled

boolean

Whether the accordion is disabled or not. *Default = false*

orientation

'vertical' | 'horizontal'

The orientation of the accordion. *Default = vertical*

loop

boolean

Whether the accordion should loop when navigating with the keyboard. *Default = true*

collapseBehavior

'remove' | 'hide'

Whether the accordion content should be removed or hidden when collapsed. Useful if you want to always render the content for SEO reasons. *Default = remove*

contextId

string

The id of the accordion context. Useful if you have nested accordions and want to create components that belong to a accordion higher up in the tree.

children

JSX.Element | (props: AccordionRootChildrenProps) => JSX.Element

Accordion.Item

Component

Context wrapper for the accordion item. Is required for every accordion item you create.

Props

value

string

Value of the accordion item. If none is provided, createUniqueId will be used to create one.

disabled

boolean

Whether the accordion item is disabled. Used to override the default provided by <​Accordion.Root>.

triggerId

string

The id attribute of the accordion item trigger element. *Default = A unique id.*

collapseBehavior

'remove' | 'hide'

Whether the disclosure content should be removed or hidden when collapsed. Useful if you want to always render the content for SEO reasons. *Default = remove*

disclosureId

string

The id attribute of the disclosure content element. *Default = A unique id.*

contextId

string

The id of the disclosure context. Useful if you have nested disclosures and want to create components that belong to a disclosure higher up in the tree.

children

JSX.Element | (props: ItemChildrenProps) => JSX.Element

as

ValidComponent

Default: Fragment

Component to render the polymorphic component as. *Default = div*

asChild

boolean

Whether to render the polymorphic component as the first <​As /> component found in its children. *Default = false*

Accordion.Trigger

Component

Button that changes the open state of the accordion item when clicked.

Props

as

ValidComponent

Default: button

Component to render the polymorphic component as. *Default = div*

asChild

boolean

Whether to render the polymorphic component as the first <​As /> component found in its children. *Default = false*

contextId

string

The id of the accordion context to use.

Data

Data attributes present on Accordion.Trigger components.

data-corvu-accordion-trigger

Present on every accordion trigger element.

data-expanded

Present when the accordion is expanded.

data-collapsed

Present when the accordion is collapsed.

data-disabled

Present when the accordion trigger is disabled.

CSS props

CSS properties attributes present on Accordion.Trigger components.

Accordion.Content

Component

Content of an accordion item. Can be animated.

Props

forceMount

boolean

Whether the disclosure content should be forced to render. Useful when using third-party animation libraries.

contextId

string

The id of the disclosure context to use.

as

ValidComponent

Default: div

Component to render the polymorphic component as. *Default = div*

asChild

boolean

Whether to render the polymorphic component as the first <​As /> component found in its children. *Default = false*

Data

Data attributes present on Accordion.Content components.

data-corvu-accordion-content

Present on every accordion item content element.

data-expanded

Present when the accordion item is expanded.

data-collapsed

Present when the accordion item is collapsed.

CSS props

CSS properties attributes present on Accordion.Content components.

--corvu-disclosure-content-width

The width of the accordion item content. Useful if you want to animate its width.

--corvu-disclosure-content-height

The height of the accordion item content. Useful if you want to animate its height.

Accordion.useContext

Context

Context which exposes various properties to interact with the accordion. Optionally provide a contextId to access a keyed context.

Returns

multiple

Accessor<boolean>

Whether multiple accordion items can be expanded at the same time.

value

Accessor<string | string[] | null>

The value of the accordion.

setValue

Setter<string | string[] | null>

Callback fired when the value changes.

collapsible

Accessor<boolean>

Whether the accordion can be fully collapsed or not.

disabled

Accessor<boolean>

Whether the accordion is disabled or not.

orientation

Accessor<'horizontal' | 'vertical'>

The orientation of the accordion.

loop

Accessor<boolean>

Whether the accordion should loop when navigating with the keyboard.

collapseBehavior

Accessor<'remove' | 'hide'>

Whether the accordion item content should be removed or hidden when collapsed.

Accordion.useItemContext

Context

Context which exposes various properties to interact with the accordion. Optionally provide a contextId to access a keyed context.

Returns

value

Accessor<string>

Value of the accordion item.

disabled

Accessor<boolean>

Whether the accordion item is disabled.

triggerId

Accessor<string | undefined>

The id attribute of the accordion item trigger element.

Accordion.RootChildrenProps

Type

Props that are passed to the Root component children callback.

Props

multiple

boolean

Whether multiple accordion items can be expanded at the same time.

value

string | string[] | null

The value of the accordion.

setValue

Setter<string | string[] | null>

Callback fired when the value changes.

collapsible

boolean

Whether the accordion can be fully collapsed or not.

disabled

boolean

Whether the accordion is disabled or not.

orientation

'horizontal' | 'vertical'

The orientation of the accordion.

loop

boolean

Whether the accordion should loop when navigating with the keyboard.

collapseBehavior

'remove' | 'hide'

Whether the accordion content should be removed or hidden when collapsed.

Accordion.ItemChildrenProps

Type

Props that are passed to the Item component children callback.

Props

value

string

Value of the accordion item.

disabled

boolean

Whether the accordion item is disabled.

triggerId

string | undefined

The id attribute of the accordion item trigger element.

corvu@0.2.3

Developed and designed by Jasmin