Organizes content into collapsible sections, allowing users to focus on one or more sections at a time.
To become a better person, to help others, and to leave the world a better place than you found it.
Read books, listen to podcasts, and surround yourself with people who inspire you.
Give them your time, attention, and love.
Overview
The Accordion component is a versatile UI element that organizes content into collapsible sections, enabling users to focus on specific information while reducing visual clutter. It's particularly useful for presenting large amounts of related content in a compact, navigable format.
Key Features
Customizable Behavior: Can be configured for single or multiple open sections.
Accessibility: ARIA attributes for screen reader compatibility and keyboard navigation.
Transition Support: CSS variables and data attributes for smooth transitions between states.
Flexible State Management: Supports controlled and uncontrolled state, take control if needed.
Compound Component Structure: Provides a set of sub-components that work together to create a fully-featured accordion.
Architecture
The Accordion component is composed of several sub-components, each with a specific role:
Root: The root element that wraps all accordion items and manages the overall state.
Item: Individual sections within the accordion.
Trigger: The button that toggles the visibility of the content.
Header: The title or heading of each item.
Content: The expandable/collapsible body of each item.
Structure
Here's an overview of how the Accordion component is structured in code:
Reusable Components
If you're planning to use the Accordion component throughout your application, it's recommended to create reusable wrapper components to reduce the amount of code you need to write each time.
For each individual item, you need an Accordion.Item, Accordion.Header, Accordion.Trigger and Accordion.Content component. We can combine these into a single MyAccordionItem component that makes it easier to reuse.
We used the WithoutChildrenOrChild type helper to omit the child and children snippet props from Accordion.ItemProps, since we are opting out of using Delegation and are already taking care of rendering the children as text via the content prop.
For our MyAccordion component, we'll accept all the props that Accordion.Root accepts, as well as an additional items prop that will be used to render the MyAccordionItem components.
Managing Value State
Bits UI offers several approaches to manage and synchronize the Accordion's value state, catering to different levels of control and integration needs.
1. Two-Way Binding
For seamless state synchronization, use Svelte's bind:value directive. This method automatically keeps your local state in sync with the accordion's internal state.
Key Benefits
Simplifies state management
Automatically updates myValue when the accordion changes (e.g., via clicking on an item's trigger)
Allows external control (e.g., opening an item via a separate button)
2. Change Handler
For more granular control or to perform additional logic on state changes, use the onValueChange prop. This approach is useful when you need to execute custom logic alongside state updates.
Use Cases
Implementing custom behaviors on value change
Integrating with external state management solutions
Triggering side effects (e.g., logging, data fetching)
3. Fully Controlled
For complete control over the accordion's value state, use the controlledValue prop. This approach requires you to manually manage the value state, giving you full control over when and how the accordion responds to value change events.
To implement controlled state:
Set the controlledValue prop to true on the Accordion.Root component.
Provide a value prop to Accordion.Root, which should be a variable holding the current state.
Implement an onValueChange handler to update the state when the internal state changes.
When to Use
Implementing complex open/close logic
Coordinating multiple UI elements
Debugging state-related issues
Note
While powerful, fully controlled state should be used judiciously as it increases complexity and can cause unexpected behaviors if not handled carefully.
For more in-depth information on controlled components and advanced state management techniques, refer to our Controlled State documentation.
Single Type
Set the type prop to "single" to allow only one accordion item to be open at a time.
Content A
Content B
Content C
Multiple Type
Set the type prop to "multiple" to allow multiple accordion items to be open at the same time.
Content A
Content B
Content C
Default Open Items
To set default open items, pass them as the value prop, which will be an array if the type is "multiple", or a string if the type is "single".
Content A
Content B
Content C
Disable Items
To disable an individual accordion item, set the disabled prop to true. This will prevent users from interacting with the item.
Svelte Transitions
The Accordion component can be enhanced with Svelte's built-in transition effects or other animation libraries.
Using forceMount and child Snippets
To apply Svelte transitions to Accordion components, use the forceMount prop in combination with the child snippet. This approach gives you full control over the mounting behavior and animation of the Accordion.Content.
In this example:
The forceMount prop ensures the components are always in the DOM.
The child snippet provides access to the open state and component props.
Svelte's #if block controls when the content is visible.
Transition directives (transition:fade and transition:fly) apply the animations.
Best Practices
For cleaner code and better maintainability, consider creating custom reusable components that encapsulate this transition logic.
You can then use the MyAccordionContent component alongside the other Accordion primitives throughout your application:
API Reference
Accordion.Root
The root accordion component used to set and manage the state of the accordion.
Property
Type
Description
typerequired
enum
The type of accordion. If set to 'multiple', the accordion will allow multiple items to be open at the same time. If set to single, the accordion will only allow a single item to be open.
Default: ——undefined
value$bindable
union
The value of the currently active accordion item. If type is 'single', this should be a string. If type is 'multiple', this should be an array of strings.
Default: ——undefined
onValueChange
function
A callback function called when the active accordion item value changes. If the type is 'single', the argument will be a string. If type is 'multiple', the argument will be an array of strings.
Default: ——undefined
controlledValue
boolean
Whether or not the value is controlled or not. If true, the component will not update the value state internally, instead it will call onValueChange when it would have otherwise, and it is up to you to update the value prop that is passed to the component.
Default: false
disabled
boolean
Whether or not the accordion is disabled. When disabled, the accordion cannot be interacted with.
Default: false
loop
boolean
Whether or not the accordion should loop through items when reaching the end.
Default: false
orientation
enum
The orientation of the accordion.
Default: vertical
ref$bindable
HTMLDivElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See delegation docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-orientation
enum
The orientation of the component.
data-disabled
''
Present when the component is disabled.
data-accordion-root
''
Present on the root element.
Accordion.Item
An accordion item.
Property
Type
Description
disabled
boolean
Whether or not the accordion item is disabled.
Default: false
value
string
The value of the accordion item. This is used to identify when the item is open or closed. If not provided, a unique ID will be generated for this value.
Default: A random unique ID
ref$bindable
HTMLDivElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See delegation docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-state
enum
Whether the accordion item is open or closed.
data-disabled
''
Present when the component is disabled.
data-orientation
enum
The orientation of the component.
data-accordion-item
''
Present on the item element.
Accordion.Header
The header of the accordion item.
Property
Type
Description
level
union
The heading level of the header. This will be set as the aria-level attribute.
Default: 3
ref$bindable
HTMLDivElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See delegation docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-orientation
enum
The orientation of the component.
data-disabled
''
Present when the component is disabled.
data-heading-level
enum
The heading level of the element.
data-accordion-header
''
Present on the header element.
Accordion.Trigger
The button responsible for toggling the accordion item.
Property
Type
Description
ref$bindable
HTMLButtonElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See delegation docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-orientation
enum
The orientation of the component.
data-disabled
''
Present when the component is disabled.
data-accordion-trigger
''
Present on the trigger element.
Accordion.Content
The accordion item content, which is displayed when the item is open.
Property
Type
Description
forceMount
boolean
Whether or not to forcefully mount the content. This is useful if you want to use Svelte transitions or another animation library for the content.
Default: false
ref$bindable
HTMLDivElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See delegation docs for more information.