ZaidanHomeDocsComponentsBlocksChartsTypesetCreate

Command Palette

Search for a command to run...

GitHub
New
Sections
  • Introduction
  • Components
  • Blocks
  • Installation
  • Customization
  • Dark Mode
  • Typeset
  • Zaidan Skills
  • FAQ
  • Roadmap
  • Changelog
Installation
  • Astro
  • Manual
  • Solid Start
  • TanStack Router
  • TanStack Start
  • Vite
Blocks
  • Data Grid
  • Event Calendar
  • Filters
  • Gantt
  • Image Crop
  • Kanban
  • Message Scroller
  • Questionnaire
  • Sortable
Components
  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Attachment
  • Avatar
  • Badge
  • Breadcrumb
  • Bubble
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Dialog
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Label
  • Marker
  • Menubar
  • Message
  • Native Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Radio Group
  • Resizable
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toast
  • Toggle
  • Toggle Group
  • Tooltip

Collapsible

An interactive component which expands/collapses a panel.

Kobalte
Kobalte

The Collapsible component is built on top of Kobalte Collapsible, which provides the accessible disclosure primitive and keyboard behavior.

Order #4189

StatusShipped
1
import { ChevronsUpDown } from "lucide-solid";
2
import { createSignal } from "solid-js";
3
import { Button } from "~/components/ui/button";
4
import {
5
Collapsible,
6
CollapsibleContent,
7
CollapsibleTrigger,
8
} from "~/components/ui/collapsible";
9
10
export default function CollapsibleDemo() {
11
const [open, setOpen] = createSignal(false);
12
13
return (
14
<Collapsible open={open()} onOpenChange={setOpen} class="flex w-[350px] flex-col gap-2">
15
<div class="flex items-center justify-between gap-4 px-4">
16
<h4 class="text-sm font-semibold">Order #4189</h4>
17
<CollapsibleTrigger
18
as={Button}
19
variant="ghost"
20
size="icon"
21
class="size-8"
22
aria-label="Toggle details"
23
>
24
<ChevronsUpDown />
25
</CollapsibleTrigger>
26
</div>
27
<div class="flex items-center justify-between rounded-md border px-4 py-2 text-sm">
28
<span class="text-muted-foreground">Status</span>
29
<span class="font-medium">Shipped</span>
30
</div>
31
<CollapsibleContent class="flex flex-col gap-2">
32
<div class="rounded-md border px-4 py-2 text-sm">
33
<p class="font-medium">Shipping address</p>
34
<p class="text-muted-foreground">100 Market St, San Francisco</p>
35
</div>
36
<div class="rounded-md border px-4 py-2 text-sm">
37
<p class="font-medium">Items</p>
38
<p class="text-muted-foreground">2x Studio Headphones</p>
39
</div>
40
</CollapsibleContent>
41
</Collapsible>
42
);
43
}

Installation

pnpm dlx shadcn@latest add @zaidan/collapsible
npx shadcn@latest add @zaidan/collapsible
yarn dlx shadcn@latest add @zaidan/collapsible
bunx --bun shadcn@latest add @zaidan/collapsible

Usage

1
import {
2
Collapsible,
3
CollapsibleContent,
4
CollapsibleTrigger,
5
} from "~/components/ui/collapsible";
1
<Collapsible>
2
<CollapsibleTrigger>Can I use this in my project?</CollapsibleTrigger>
3
<CollapsibleContent>
4
Yes. Free to use for personal and commercial projects. No attribution
5
required.
6
</CollapsibleContent>
7
</Collapsible>

Composition

Use the following composition to build a Collapsible:

Collapsible
├── CollapsibleTrigger
└── CollapsibleContent

Controlled State

Use the open and onOpenChange props to control the state.

1
import { createSignal } from "solid-js";
2
3
const [open, setOpen] = createSignal(false);
4
5
<Collapsible open={open()} onOpenChange={setOpen}>
6
<CollapsibleTrigger>Toggle</CollapsibleTrigger>
7
<CollapsibleContent>Content</CollapsibleContent>
8
</Collapsible>;

Basic

1
import { ChevronDownIcon } from "lucide-solid";
2
import { Button } from "~/components/ui/button";
3
import { Card, CardContent } from "~/components/ui/card";
4
import {
5
Collapsible,
6
CollapsibleContent,
7
CollapsibleTrigger,
8
} from "~/components/ui/collapsible";
9
10
export default function CollapsibleBasic() {
11
return (
12
<Card class="mx-auto w-full max-w-sm">
13
<CardContent>
14
<Collapsible class="rounded-md data-[expanded]:bg-muted">
15
<CollapsibleTrigger as={Button} variant="ghost" class="w-full">
16
Product details
17
<ChevronDownIcon class="ml-auto transition-transform group-data-[expanded]:rotate-180" />
18
</CollapsibleTrigger>
19
<CollapsibleContent class="flex flex-col items-start gap-2 p-2.5 pt-0 text-sm">
20
<div>This panel can be expanded or collapsed to reveal additional content.</div>
21
<Button size="xs">Learn More</Button>
22
</CollapsibleContent>
23
</Collapsible>
24
</CardContent>
25
</Card>
26
);
27
}

Settings Panel

Use a trigger button to reveal additional settings.

Radius
Set the corner radius of the element.
1
import { MaximizeIcon, MinimizeIcon } from "lucide-solid";
2
import { createSignal, Show } from "solid-js";
3
import { Button } from "~/components/ui/button";
4
import {
5
Card,
6
CardContent,
7
CardDescription,
8
CardHeader,
9
CardTitle,
10
} from "~/components/ui/card";
11
import {
12
Collapsible,
13
CollapsibleContent,
14
CollapsibleTrigger,
15
} from "~/components/ui/collapsible";
16
import { Field, FieldGroup, FieldLabel } from "~/components/ui/field";
17
import { Input } from "~/components/ui/input";
18
19
export default function CollapsibleSettings() {
20
const [open, setOpen] = createSignal(false);
21
22
return (
23
<Card class="mx-auto w-full max-w-xs" size="sm">
24
<CardHeader>
25
<CardTitle>Radius</CardTitle>
26
<CardDescription>Set the corner radius of the element.</CardDescription>
27
</CardHeader>
28
<CardContent>
29
<Collapsible open={open()} onOpenChange={setOpen} class="flex items-start gap-2">
30
<FieldGroup class="grid w-full grid-cols-2 gap-2">
31
<Field>
32
<FieldLabel for="collapsible-radius-x" class="sr-only">
33
Radius X
34
</FieldLabel>
35
<Input id="collapsible-radius-x" placeholder="0" value="0" />
36
</Field>
37
<Field>
38
<FieldLabel for="collapsible-radius-y" class="sr-only">
39
Radius Y
40
</FieldLabel>
41
<Input id="collapsible-radius-y" placeholder="0" value="0" />
42
</Field>
43
<CollapsibleContent class="col-span-full grid grid-cols-subgrid gap-2">
44
<Field>
45
<FieldLabel for="collapsible-radius-z" class="sr-only">
46
Radius Z
47
</FieldLabel>
48
<Input id="collapsible-radius-z" placeholder="0" value="0" />
49
</Field>
50
<Field>
51
<FieldLabel for="collapsible-radius-w" class="sr-only">
52
Radius W
53
</FieldLabel>
54
<Input id="collapsible-radius-w" placeholder="0" value="0" />
55
</Field>
56
</CollapsibleContent>
57
</FieldGroup>
58
<CollapsibleTrigger
59
as={Button}
60
variant="outline"
61
size="icon"
62
aria-label="Toggle radius settings"
63
>
64
<Show when={open()} fallback={<MaximizeIcon />}>
65
<MinimizeIcon />
66
</Show>
67
</CollapsibleTrigger>
68
</Collapsible>
69
</CardContent>
70
</Card>
71
);
72
}

File Tree

Use nested collapsibles to build a file tree.

1
import { ChevronRightIcon, FileIcon, FolderIcon } from "lucide-solid";
2
import { For, Show } from "solid-js";
3
import { Button } from "~/components/ui/button";
4
import { Card, CardContent, CardHeader } from "~/components/ui/card";
5
import {
6
Collapsible,
7
CollapsibleContent,
8
CollapsibleTrigger,
9
} from "~/components/ui/collapsible";
10
import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs";
11
12
type FileTreeItem = { name: string; items?: FileTreeItem[] };
13
14
const fileTree: FileTreeItem[] = [
15
{
16
name: "components",
17
items: [
18
{
19
name: "ui",
20
items: [
21
{ name: "button.tsx" },
22
{ name: "card.tsx" },
23
{ name: "dialog.tsx" },
24
{ name: "input.tsx" },
25
{ name: "select.tsx" },
26
{ name: "table.tsx" },
27
],
28
},
29
{ name: "login-form.tsx" },
30
{ name: "register-form.tsx" },
31
],
32
},
33
{
34
name: "lib",
35
items: [{ name: "utils.ts" }, { name: "cn.ts" }, { name: "api.ts" }],
36
},
37
{
38
name: "hooks",
39
items: [
40
{ name: "use-media-query.ts" },
41
{ name: "use-debounce.ts" },
42
{ name: "use-local-storage.ts" },
43
],
44
},
45
{
46
name: "types",
47
items: [{ name: "index.d.ts" }, { name: "api.d.ts" }],
48
},
49
{
50
name: "public",
51
items: [{ name: "favicon.ico" }, { name: "logo.svg" }, { name: "images" }],
52
},
53
{ name: "app.tsx" },
54
{ name: "layout.tsx" },
55
{ name: "globals.css" },
56
{ name: "package.json" },
57
{ name: "tsconfig.json" },
58
{ name: "README.md" },
59
{ name: ".gitignore" },
60
];
61
62
function FileTreeItem(props: { item: FileTreeItem }) {
63
return (
64
<Show
65
when={props.item.items}
66
fallback={
67
<Button variant="link" size="sm" class="w-full justify-start gap-2 text-foreground">
68
<FileIcon />
69
<span>{props.item.name}</span>
70
</Button>
71
}
72
>
73
{(items) => (
74
<Collapsible>
75
<CollapsibleTrigger
76
as={Button}
77
variant="ghost"
78
size="sm"
79
class="group w-full justify-start transition-none hover:bg-accent hover:text-accent-foreground"
80
>
81
<ChevronRightIcon class="transition-transform group-data-[expanded]:rotate-90" />
82
<FolderIcon />
83
{props.item.name}
84
</CollapsibleTrigger>
85
<CollapsibleContent class="mt-1 ml-5">
86
<div class="flex flex-col gap-1">
87
<For each={items()}>{(item) => <FileTreeItem item={item} />}</For>
88
</div>
89
</CollapsibleContent>
90
</Collapsible>
91
)}
92
</Show>
93
);
94
}
95
96
export default function CollapsibleFileTree() {
97
return (
98
<Card class="mx-auto w-full max-w-[16rem] gap-2" size="sm">
99
<CardHeader>
100
<Tabs defaultValue="explorer">
101
<TabsList class="w-full">
102
<TabsTrigger value="explorer">Explorer</TabsTrigger>
103
<TabsTrigger value="settings">Outline</TabsTrigger>
104
</TabsList>
105
</Tabs>
106
</CardHeader>
107
<CardContent>
108
<div class="flex flex-col gap-1">
109
<For each={fileTree}>{(item) => <FileTreeItem item={item} />}</For>
110
</div>
111
</CardContent>
112
</Card>
113
);
114
}

API Reference

For primitive props, keyboard behavior, and accessibility details, see the Kobalte Collapsible API reference.

On This Page

  • Installation
  • Usage
  • Composition
  • Controlled State
  • Basic
  • Settings Panel
  • File Tree
  • API Reference
Built by Kevin Abatan. The source code is available on GitHub.