Collapsible

A single panel that expands and collapses. The trigger shows a chevron that turns when the panel opens, and the content lines up with the trigger's label.

  • collapsible-trigger.svelte
  • collapsible-content.svelte
  • manifest.ts
  • +page.svelte
<script lang="ts">
    import * as Collapsible from '@sivir-ui/svelte/components/collapsible';

    const files = [
        'collapsible-trigger.svelte',
        'collapsible-content.svelte',
        'manifest.ts',
        '+page.svelte'
    ];
</script>

<div class="w-full max-w-md">
    <Collapsible.Root open>
        <Collapsible.Trigger>{files.length} files changed</Collapsible.Trigger>
        <Collapsible.Content>
            <ul class="m-0 flex list-none flex-col gap-1.5 p-0">
                {#each files as file (file)}
                    <li class="truncate font-mono text-[0.875em] text-foreground">{file}</li>
                {/each}
            </ul>
        </Collapsible.Content>
    </Collapsible.Root>
</div>

Installation

Copy the command below and run it in your terminal.

bunx @sivir-ui/svelte add collapsible

Usage

Bind open to read or set the state. It starts as false. Set disabled on Root to disable the trigger.

Trigger renders its own chevron and fills the width of its container. Content is indented to the trigger label and styled as supporting text, so pass plain text or your own markup without adding padding. Root renders no element, so wrap it in a div when a list needs dividers or spacing between items.

import * as Collapsible from '@sivir-ui/svelte/components/collapsible';

let open = $state(false);

<Collapsible.Root bind:open>
  <Collapsible.Trigger>Order details</Collapsible.Trigger>
  <Collapsible.Content>3 items, shipped March 4.</Collapsible.Content>
</Collapsible.Root>

Examples

Settings

<script lang="ts">
    import * as Collapsible from '@sivir-ui/svelte/components/collapsible';

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

<div class="w-full max-w-md">
    <Collapsible.Root bind:open>
        <Collapsible.Trigger>
            {open ? 'Hide advanced settings' : 'Show advanced settings'}
        </Collapsible.Trigger>
        <Collapsible.Content>
            <dl class="m-0 grid grid-cols-[auto_minmax(0,1fr)] gap-x-6 gap-y-2">
                <dt>Request timeout</dt>
                <dd class="m-0 text-foreground tabular-nums">30 seconds</dd>
                <dt>Retries</dt>
                <dd class="m-0 text-foreground tabular-nums">3 attempts</dd>
                <dt>Backoff</dt>
                <dd class="m-0 text-foreground">Exponential</dd>
            </dl>
        </Collapsible.Content>
    </Collapsible.Root>
</div>

FAQ list

<script lang="ts">
    import * as Collapsible from '@sivir-ui/svelte/components/collapsible';

    const questions = [
        {
            question: 'What is your refund policy?',
            answer: 'Every purchase has a 30-day money-back guarantee. Email support@example.com to request a refund.'
        },
        {
            question: 'How long does shipping take?',
            answer: 'Standard shipping takes 5 to 7 business days. Express takes 2 to 3 and includes tracking.'
        },
        {
            question: 'Do you offer bulk discounts?',
            answer: 'Orders over 100 units get 15% off. Contact sales for a quote on larger orders.'
        }
    ];
</script>

<div class="w-full max-w-md divide-y divide-border">
    {#each questions as item (item.question)}
        <div class="py-1">
            <Collapsible.Root>
                <Collapsible.Trigger>{item.question}</Collapsible.Trigger>
                <Collapsible.Content>{item.answer}</Collapsible.Content>
            </Collapsible.Root>
        </div>
    {/each}
</div>

Disabled

<script lang="ts">
    import * as Collapsible from '@sivir-ui/svelte/components/collapsible';
</script>

<div class="flex w-full max-w-md flex-col">
    <Collapsible.Root disabled>
        <Collapsible.Trigger>v0.5.0 release notes (not yet published)</Collapsible.Trigger>
        <Collapsible.Content>Notes appear here when the release ships.</Collapsible.Content>
    </Collapsible.Root>
    <Collapsible.Root>
        <Collapsible.Trigger>v0.4.4 release notes</Collapsible.Trigger>
        <Collapsible.Content>
            Collapsible now ships with a chevron trigger, hover and disabled states, and content
            that lines up with the trigger label.
        </Collapsible.Content>
    </Collapsible.Root>
</div>

Anatomy

Collapsible.Root - Controls collapsible content state.

Collapsible.Trigger - Toggles the content.

Collapsible.Content - Contains collapsible content.