Collapsible
Conceals or reveals content sections, enhancing space utilization and organization.
@huntabyte starred 3 repositories
Overview
The Collapsible component enables you to create expandable and collapsible content sections. It provides an efficient way to manage space and organize information in user interfaces, enabling users to show or hide content as needed.
Key Features
- 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 subcomponents that work together to create a fully-featured collapsible.
Architecture
The Accordion component is composed of a few subcomponents, each with a specific role:
- Root: The parent container that manages the state and context for the collapsible functionality.
- Trigger: The interactive element (e.g., button) that toggles the expanded/collapsed state of the content.
- Content: The container for the content that will be shown or hidden based on the collapsible state.
Structure
Here's an overview of how the Collapsible component is structured in code:
Reusable Components
It's recommended to use the Collapsible
primitives to create your own custom collapsible component that can be used throughout your application.
You can then use the MyCollapsible
component in your application like so:
Managing Open State
Bits UI offers several approaches to manage and synchronize the Collapsible's open state, catering to different levels of control and integration needs.
1. Two-Way Binding
For seamless state synchronization, use Svelte's bind:open
directive. This method automatically keeps your local state in sync with the Collapsible's internal state.
Key Benefits
- Simplifies state management
- Automatically updates
isOpen
when the collapsible closes (e.g., via trigger press) - Allows external control (e.g., opening via a separate button)
2. Change Handler
For more granular control or to perform additional logic on state changes, use the onOpenChange
prop. This approach is useful when you need to execute custom logic alongside state updates.
Use Cases
- Implementing custom behaviors on open/close
- Integrating with external state management solutions
- Triggering side effects (e.g., logging, data fetching)
3. Fully Controlled
For complete control over the Collapsible's open state, use the controlledOpen
prop. This approach requires you to manually manage the open state, giving you full control over when and how the collapsible responds to open/close events.
To implement controlled state:
- Set the
controlledOpen
prop totrue
on theCollapsible.Root
component. - Provide an
open
prop toCollapsible.Root
, which should be a variable holding the current state. - Implement an
onOpenChange
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.
Svelte Transitions
The Collapsible 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 Collapsible 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 Collapsible.Content
.
In this example:
- The
forceMount
prop ensures the content is 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 directive (
transition:fade
) 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 MyCollapsibleContent
component alongside the other Collapsible
primitives throughout your application:
API Reference
The root collapsible container which manages the state of the collapsible.
Property | Type | Description |
---|---|---|
open $bindable | boolean | The open state of the collapsible. The content will be visible when this is true, and hidden when it's false. Default: false |
onOpenChange | function | A callback that is fired when the collapsible's open state changes. Default: undefined |
controlledOpen | boolean | Whether or not the open state is controlled or not. If Default: false |
disabled | boolean | Whether or not the collapsible is disabled. This prevents the user from interacting with it. 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. Default: undefined |
Data Attribute | Value | Description |
---|---|---|
data-state | enum | The collapsible's open state. |
data-disabled | '' | Present when the collapsible is disabled. |
data-collapsible-root | '' | Present on the root element. |
The button responsible for toggling the collapsible's open state.
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-state | enum | The collapsible's open state. |
data-disabled | '' | Present when the collapsible or this trigger is disabled. |
data-collapsible-trigger | '' | Present on the trigger element. |
The content displayed when the collapsible 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. Default: undefined |
Data Attribute | Value | Description |
---|---|---|
data-state | enum | The collapsible's open state. |
data-disabled | '' | Present when the collapsible is disabled. |
data-collapsible-content | '' | Present on the content element. |
CSS Variable | Description |
---|---|
--bits-collapsible-content-height | The height of the collapsible content element. |
--bits-collapsible-content-width | The width of the collapsible content element. |