Collapsible
Disclosure with a custom trigger; the panel animates its height and staggers its content.
Usage
svelte
<script lang="ts">
import { Collapsible } from "@milandekruijf/ui/svelte";
let open = $state(false);
</script>
<Collapsible bind:open>
{#snippet trigger()}
Toggle
{/snippet}
<p>Staggered panel content.</p>
</Collapsible>Examples
Custom trigger
The panel animates its height and staggers the content inside.
<script lang="ts">
import { css } from "@milandekruijf/pandacss/css";
import { Collapsible } from "@milandekruijf/ui/svelte";
import { ChevronDown } from "@lucide/svelte";
let expanded = $state(false);
const triggerClass = css({
display: "inline-flex",
alignItems: "center",
gap: 2,
h: 8,
px: 3,
fontSize: "lg",
fontWeight: "medium",
color: "slate.11",
bg: "slate.3",
borderWidth: 0,
cursor: "pointer",
transition: "color 0.2s ease-in-out, background-color 0.2s ease-in-out",
_hover: { bg: "slate.4" },
"&[data-state=open] svg": { transform: "rotate(180deg)" },
});
const chevronClass = css({
w: 4,
h: 4,
transition: "transform 0.2s ease-in-out",
});
const panelClass = css({
color: "slate.11",
maxW: "prose",
m: 0,
pt: 3,
});
</script>
<Collapsible bind:open={expanded} {triggerClass}>
{#snippet trigger()}
{expanded ? "Collapse" : "Expand"}
<ChevronDown class={chevronClass} />
{/snippet}
<p class={panelClass}>
The panel animates its height and staggers the content inside.
</p>
</Collapsible>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| open? | boolean | false | Bindable open state (`bind:open`). |
| trigger | Snippet | — | Trigger content, rendered inside the interactive trigger button. |
| children | Snippet | — | Panel content; sections and toggle items inside are staggered. |
| class? | string | — | Extra classes merged on the collapsible root. |
| triggerClass? | string | — | Extra classes merged on the trigger button. |
The root, trigger, and animated panel are all internal: style the trigger through `triggerClass`, and the panel animates its height while staggering its content.