# Accordion Documentation Organizes content into collapsible sections, allowing users to focus on one or more sections at a time. This is a documentation section that potentially contains examples, demos, and other useful information related to a specific part of Bits UI. When helping users with this documentation, you can ignore the classnames applied to the demos unless they are relevant to the user's issue. ```svelte {#each items as item (item.value)} {item.title}
{item.content}
{/each}
``` ## Overview The Accordion component is a versatile UI element designed to organize content into collapsible sections, helping users focus on specific information without being overwhelmed by visual clutter. ## Quick Start ```svelte Item 1 Title This is the collapsible content for this section. Item 2 Title This is the collapsible content for this section. ``` ## Key Features - **Single or Multiple Mode**: Toggle between allowing one open section or multiple sections at once. - **Accessible by Default**: Built-in ARIA attributes and keyboard navigation support. - **Smooth Transitions**: Leverage CSS variables or Svelte transitions for animated open/close effects. - **Flexible State**: Use uncontrolled defaults or take full control with bound values. ## Structure The Accordion is a compound component made up of several parts: - `Accordion.Root` : Container that manages overall state - `Accordion.Item` : Individual collapsible section - `Accordion.Header` : Contains the visible heading - `Accordion.Trigger` : The clickable element that toggles content visibility - `Accordion.Content` : The collapsible body content ## Reusable Components To streamline usage in larger applications, create custom wrapper components for repeated patterns. Below is an example of a reusable `MyAccordionItem` and `MyAccordion`. ### Item Wrapper Combines `Item`, `Header`, `Trigger`, and `Content` into a single component: MyAccordionItem.svelte ```svelte {item.title} {content} ``` ### Accordion Wrapper Wraps `Root` and renders multiple `MyAccordionItem` components: MyAccordion.svelte ```svelte {#each items as item, i (item.title + i)} {/each} ``` ### Usage Example +page.svelte ```svelte ``` ##### Tip Use unique `value` props for each `Item` if you plan to control the state programatically. ## Managing Value State This section covers how to manage the `value` state of the Accordion. ### Two-Way Binding Use `bind:value` for simple, automatic state synchronization: ```svelte ``` ### Fully Controlled Use a [Function Binding](https://svelte.dev/docs/svelte/bind#Function-bindings) for complete control over the state's reads and writes. ```svelte ``` See the [State Management](/docs/state-management) documentation for more information. ## Customization ### Single vs. Multiple Set the `type` prop to `"single"` to allow only one accordion item to be open at a time. ```svelte ``` Set the `type` prop to `"multiple"` to allow multiple accordion items to be open at the same time. ```svelte ``` ### Default Open Items Set the `value` prop to pre-open items: ```svelte ``` ### Disable Items Disable specific items with the `disabled` prop: ```svelte ``` ### 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`. ```svelte {#snippet child({ props, open })} {#if open}
This is the accordion content that will transition in and out.
{/if} {/snippet}
``` 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. ```svelte {#each items as item, i} {item.title} {#snippet child({ props, open })} {#if open}
{item.content}
{/if} {/snippet}
{/each}
``` #### Best Practices For cleaner code and better maintainability, consider creating custom reusable components that encapsulate this transition logic. MyAccordionContent.svelte ```svelte {#snippet child({ props, open })} {#if open}
{@render children?.()}
{/if} {/snippet}
``` You can then use the `MyAccordionContent` component alongside the other `Accordion` primitives throughout your application: ```svelte A ``` ## Examples The following examples demonstrate different ways to use the Accordion component. ### Horizontal Cards Use the Accordion component to create a horizontal card layout with collapsible sections. ```svelte {#each items as item (item.id)} (value = item.id)} > {item.title}
{item.title} {item.description}
{/each}
``` ### Checkout Steps Use the Accordion component to create a multi-step checkout process. ```svelte {#snippet MyAccordionHeader({ value, title }: { value: string; title: string })} {@const isCompleted = completedSteps.has(value)}
{isCompleted ? "" : value}
{title}
{/snippet} {#snippet InputField({ label, placeholder, type = "text" }: { label: string; placeholder: string; type?: string; })} {@const id = useId()}
{/snippet} {@render MyAccordionHeader({ title: "Shipping Information", value: "1" })}
{@render InputField({ label: "First Name", placeholder: "John" })} {@render InputField({ label: "Last Name", placeholder: "Doe" })}
{@render InputField({ label: "Address", placeholder: "1234 Elm Street" })}
{@render InputField({ label: "City", placeholder: "Tampa" })} {@render InputField({ label: "ZIP", placeholder: "123456" })}
{ completedSteps.add("1"); activeStep = "2"; }} > Continue to Payment
{@render MyAccordionHeader({ title: "Payment Method", value: "2" })}
{@render InputField({ label: "Card Number", placeholder: "4242 4242 4242 4242" })}
{@render InputField({ label: "Exp. Month", placeholder: "MM" })} {@render InputField({ label: "Exp. Year", placeholder: "YY" })} {@render InputField({ label: "CVC", placeholder: "123" })}
{ completedSteps.add("2"); activeStep = "3"; }} > Continue to Review
{@render MyAccordionHeader({ title: "Payment Method", value: "3" })}

Order Summary

Product 1 $29.99
Product 2 $49.99
Shipping $4.99
Total $84.97
{ completedSteps.add("3"); activeStep = ""; }} > Place Order
``` ## API Reference ### Accordion.Root The root accordion component used to set and manage the state of the accordion. | Property | Type | Description | | ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `type` required | `enum`- 'single' \| 'multiple' | 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`- string\[] \| string | 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`- string \| string\[] | 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` | | `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`- 'vertical' \| 'horizontal' | 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`- type SnippetProps = { props: Record\; }; | Use render delegation to render your own element. See [Child Snippet](/docs/child-snippet) docs for more information.`Default: undefined` | | Data Attribute | Value | Description | | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `data-orientation` | `enum`- 'vertical' \| 'horizontal' | 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`- type SnippetProps = { props: Record\; }; | Use render delegation to render your own element. See [Child Snippet](/docs/child-snippet) docs for more information.`Default: undefined` | | Data Attribute | Value | Description | | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `data-state` | `enum`- 'open' \| 'closed' | Whether the accordion item is open or closed. | | `data-disabled` | `''` | Present when the component is disabled. | | `data-orientation` | `enum`- 'vertical' \| 'horizontal' | 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`- 1 \| 2 \| 3 \| 4 \| 5 \| 6 | 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`- type SnippetProps = { props: Record\; }; | Use render delegation to render your own element. See [Child Snippet](/docs/child-snippet) docs for more information.`Default: undefined` | | Data Attribute | Value | Description | | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `data-orientation` | `enum`- 'vertical' \| 'horizontal' | The orientation of the component. | | `data-disabled` | `''` | Present when the component is disabled. | | `data-heading-level` | `enum`- '1' \| '2' \| '3' \| '4' \| '5' \| '6' | 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`- type SnippetProps = { props: Record\; }; | Use render delegation to render your own element. See [Child Snippet](/docs/child-snippet) docs for more information.`Default: undefined` | | Data Attribute | Value | Description | | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | `data-orientation` | `enum`- 'vertical' \| 'horizontal' | 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`- Snippet | The children content to render.`Default: undefined` | | `child` | `Snippet`- type SnippetProps = { props: Record\; }; | Use render delegation to render your own element. See [Child Snippet](/docs/child-snippet) docs for more information.`Default: undefined` | | Data Attribute | Value | Description | | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | `data-orientation` | `enum`- 'vertical' \| 'horizontal' | The orientation of the component. | | `data-disabled` | `''` | Present when the component is disabled. | | `data-accordion-content` | `''` | Present on the content element. | | CSS Variable | Description | | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--bits-accordion-content-height` | The height of the accordion content element. | | `--bits-accordion-content-width` | The width of the accordion content element. |