Collapsible

An interactive component which expands and collapses a panel.

File Tree
Settings
Radius
Set the corner radius of the element.

Installation

Install the dependencies

pnpm add github:sveltery/base

Copy the component

Copy the following files into src/lib/components/ui/collapsible.

src/lib/components/ui/collapsible/Collapsible.svelte
<script lang="ts">
  import type { ComponentProps } from 'svelte';
  import { Collapsible as Primitive } from '@sveltery/base/collapsible';
  let { open = $bindable(), children, ...props }: ComponentProps<typeof Primitive.Root> = $props();
</script>
<Primitive.Root data-slot="collapsible" bind:open {children} {...props} />
src/lib/components/ui/collapsible/CollapsibleContent.svelte
<script lang="ts">
  import type { ComponentProps } from 'svelte';
  import { Collapsible as Primitive } from '@sveltery/base/collapsible';
  let { children, ...props }: ComponentProps<typeof Primitive.Panel> = $props();
</script>
<Primitive.Panel data-slot="collapsible-content" {children} {...props} />
src/lib/components/ui/collapsible/CollapsibleTrigger.svelte
<script lang="ts">
  import type { ComponentProps } from 'svelte';
  import { Collapsible as Primitive } from '@sveltery/base/collapsible';
  let { children, ...props }: ComponentProps<typeof Primitive.Trigger> = $props();
</script>
<Primitive.Trigger data-slot="collapsible-trigger" {children} {...props} />
src/lib/components/ui/collapsible/index.ts
export { default as Collapsible } from './Collapsible.svelte';
export { default as CollapsibleTrigger } from './CollapsibleTrigger.svelte';
export { default as CollapsibleContent } from './CollapsibleContent.svelte';

Update the import paths

Change the imports to match your project setup.

Usage

<script lang="ts">
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '$lib/components/ui/collapsible';
</script>
<Collapsible>
  <CollapsibleTrigger>Can I use this in my project?</CollapsibleTrigger>
  <CollapsibleContent>
    Yes. Free to use for personal and commercial projects. No attribution required.
  </CollapsibleContent>
</Collapsible>

Composition

Collapsible
├── CollapsibleTrigger
└── CollapsibleContent

Controlled state

Bind open to read and set the state.

<script lang="ts">
  let open = $state(false);
</script>

<Collapsible bind:open>
  <CollapsibleTrigger>Toggle</CollapsibleTrigger>
  <CollapsibleContent>Content</CollapsibleContent>
</Collapsible>

Custom trigger

Pass a render snippet to CollapsibleTrigger to render another element, such as a Button. Spread props onto it and render children.

{#snippet button(props, state, children)}
  <Button {...props} variant="outline" size="icon">{@render children?.()}</Button>
{/snippet}

<CollapsibleTrigger render={button}>…</CollapsibleTrigger>

API reference

Collapsible is styled on top of the Sveltery Base Collapsible primitive, which owns its behavior, open state and accessibility. See the Base UI Collapsible documentation for the behavior it ports.