Kumo is Cloudflare's new design system.
<script lang="ts">
import { Text } from "kumo-svelte/components/text";
import * as Collapsible from "kumo-svelte/components/collapsible";
let open = $state(true);
</script>
<div class="w-full">
<Collapsible.Root bind:open>
<Collapsible.DefaultTrigger>What is Kumo?</Collapsible.DefaultTrigger>
<Collapsible.DefaultPanel>
<Text>Kumo is Cloudflare's new design system.</Text>
</Collapsible.DefaultPanel>
</Collapsible.Root>
</div>
Import
import * as Collapsible from "kumo-svelte/components/collapsible"; Usage
Collapsible uses named Svelte components for full composition control.
With Default Styling
Use Collapsible.DefaultTrigger and Collapsible.DefaultPanel for the classic Kumo style:
<script lang="ts">
import * as Collapsible from "kumo-svelte/components/collapsible";
let open = $state(false);
</script>
<Collapsible.Root bind:open>
<Collapsible.DefaultTrigger>Show details</Collapsible.DefaultTrigger>
<Collapsible.DefaultPanel>
Content with border-left accent styling.
</Collapsible.DefaultPanel>
</Collapsible.Root> Custom Trigger
Use Collapsible.Trigger and Collapsible.Panel for full control over trigger and panel styling:
<Collapsible.Root bind:open>
<Collapsible.Trigger class="rounded-md border px-3 py-1.5">
{open ? "Hide" : "Show"} details
</Collapsible.Trigger>
<Collapsible.Panel class="mt-2 rounded-lg bg-kumo-tint p-4">
Custom styled panel content.
</Collapsible.Panel>
</Collapsible.Root> Examples
Basic
Kumo is Cloudflare's new design system.
<script lang="ts">
import { Text } from "kumo-svelte/components/text";
import * as Collapsible from "kumo-svelte/components/collapsible";
let open = $state(false);
</script>
<div class="w-full">
<Collapsible.Root bind:open>
<Collapsible.DefaultTrigger>What is Kumo?</Collapsible.DefaultTrigger>
<Collapsible.DefaultPanel>
<Text>Kumo is Cloudflare's new design system.</Text>
</Collapsible.DefaultPanel>
</Collapsible.Root>
</div>
Multiple Items
Kumo is Cloudflare's new design system.
Install the components and import them into your project.
Check the repository for license information.
<script lang="ts">
import { Text } from "kumo-svelte/components/text";
import * as Collapsible from "kumo-svelte/components/collapsible";
let open1 = $state(false);
let open2 = $state(false);
let open3 = $state(false);
</script>
<div class="w-full space-y-2">
<Collapsible.Root bind:open={open1}>
<Collapsible.DefaultTrigger>What is Kumo?</Collapsible.DefaultTrigger>
<Collapsible.DefaultPanel>
<Text>Kumo is Cloudflare's new design system.</Text>
</Collapsible.DefaultPanel>
</Collapsible.Root>
<Collapsible.Root bind:open={open2}>
<Collapsible.DefaultTrigger>How do I use it?</Collapsible.DefaultTrigger>
<Collapsible.DefaultPanel>
<Text>Install the components and import them into your project.</Text>
</Collapsible.DefaultPanel>
</Collapsible.Root>
<Collapsible.Root bind:open={open3}>
<Collapsible.DefaultTrigger>Is it open source?</Collapsible.DefaultTrigger>
<Collapsible.DefaultPanel>
<Text>Check the repository for license information.</Text>
</Collapsible.DefaultPanel>
</Collapsible.Root>
</div>
Custom Trigger
Use Collapsible.Trigger with custom classes for full control.
This panel uses custom styling instead of the default border-left accent.
<script lang="ts">
import { Button } from "kumo-svelte/components/button";
import { Text } from "kumo-svelte/components/text";
import * as Collapsible from "kumo-svelte/components/collapsible";
let open = $state(false);
</script>
<div class="w-full">
<Collapsible.Root bind:open>
<Collapsible.Trigger>
{#snippet child({ props })}
<Button {...props} variant="secondary" size="sm">
{open ? "Hide details" : "Show details"}
</Button>
{/snippet}
</Collapsible.Trigger>
<Collapsible.Panel class="mt-3 rounded-lg bg-kumo-tint p-4">
<Text>This panel uses custom styling instead of the default border-left accent.</Text>
</Collapsible.Panel>
</Collapsible.Root>
</div>
Keep Mounted
Use forceMount on Collapsible.DefaultPanel or Collapsible.Panel to preserve internal state — such as form inputs — when the panel is collapsed.
Type something below, then collapse and re-open — your input is preserved because the panel stays mounted.
<script lang="ts">
import { Input } from "kumo-svelte/components/input";
import { Text } from "kumo-svelte/components/text";
import * as Collapsible from "kumo-svelte/components/collapsible";
let open = $state(true);
</script>
<div class="w-full space-y-4">
<Collapsible.Root bind:open>
<Collapsible.DefaultTrigger>Edit details</Collapsible.DefaultTrigger>
<Collapsible.DefaultPanel forceMount>
<Text>
Type something below, then collapse and re-open — your input is preserved because the
panel stays mounted.
</Text>
<Input label="Name" placeholder="Type here…" />
</Collapsible.DefaultPanel>
</Collapsible.Root>
</div>
Accordion Pattern
Control which item is open to create an accordion where only one item can be expanded at a time.
Kumo is Cloudflare's new design system built on accessibility primitives and Tailwind CSS.
Run `pnpm add kumo-svelte` and import the components you need.
Yes. Kumo builds on primitive components that provide keyboard and ARIA behavior.
<script lang="ts">
import { Text } from "kumo-svelte/components/text";
import * as Collapsible from "kumo-svelte/components/collapsible";
const items = [
{
title: "What is Kumo?",
content: "Kumo is Cloudflare's new design system built on accessibility primitives and Tailwind CSS.",
},
{
title: "How do I install it?",
content: "Run `pnpm add kumo-svelte` and import the components you need.",
},
{
title: "Is it accessible?",
content: "Yes. Kumo builds on primitive components that provide keyboard and ARIA behavior.",
},
];
let activeIndex = $state<number | null>(0);
</script>
<div class="w-full space-y-2">
{#each items as item, index}
<Collapsible.Root
open={activeIndex === index}
onOpenChange={(open) => {
activeIndex = open ? index : null;
}}
>
<Collapsible.DefaultTrigger>{item.title}</Collapsible.DefaultTrigger>
<Collapsible.DefaultPanel>
<Text>{item.content}</Text>
</Collapsible.DefaultPanel>
</Collapsible.Root>
{/each}
</div>
API Reference
Collapsible
| Prop | Type | Default |
|---|---|---|
| children* | Snippet | — |
| class | string | — |
| disabled | boolean | false |
| id | string | — |
| open | boolean | false |
| onOpenChange | (open: boolean) => void | — |
| onOpenChangeComplete | (open: boolean) => void | — |
Collapsible.DefaultPanel
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| class | string | — |
| forceMount | boolean | — |
| hiddenUntilFound | boolean | — |
| id | string | — |
Collapsible.DefaultTrigger
No component-specific props. This component accepts child content or standard forwarded attributes.
Collapsible.Panel
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| class | string | — |
| forceMount | boolean | — |
| hiddenUntilFound | boolean | — |
| id | string | — |
Collapsible.Trigger
No component-specific props. This component accepts child content or standard forwarded attributes.