Skip to content
edmi-ui

Collapsible

A single panel that expands and collapses.

StackBlitz ↗StackBlitz ↗StackBlitz ↗
3 tokens hidden
NVDAx · 32%
3 tokens hidden
NVDAx · 32%
3 tokens hidden
NVDAx · 32%
Terminal window
npx shadcn@latest add @edmi-ui/collapsible
Terminal window
pnpm dlx shadcn@latest add @edmi-ui/collapsible
Terminal window
yarn dlx shadcn@latest add @edmi-ui/collapsible
Terminal window
bunx shadcn@latest add @edmi-ui/collapsible

Pick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.

Terminal window
npx shadcn-vue@latest add @edmi-ui/collapsible
Terminal window
pnpm dlx shadcn-vue@latest add @edmi-ui/collapsible
Terminal window
yarn dlx shadcn-vue@latest add @edmi-ui/collapsible
Terminal window
bunx shadcn-vue@latest add @edmi-ui/collapsible

Pick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.

Terminal window
npx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/collapsible.json
Terminal window
pnpm dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/collapsible.json
Terminal window
yarn dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/collapsible.json
Terminal window
bunx --bun shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/collapsible.json

Pick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.

import { Button } from "@/components/ui/button";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
<Collapsible
className="w-[320px] rounded-xl border border-border bg-card p-3"
>
<div className="flex items-center justify-between">
<span className="px-1 text-sm font-medium">3 tokens hidden</span>
<CollapsibleTrigger
render={<Button variant="ghost" size="icon-xs" aria-label="Toggle" />}
>
<CaretUpDownIcon />
</CollapsibleTrigger>
</div>
<div className="mt-2 rounded-md border border-border bg-muted px-3 py-2 font-mono text-[13px]">
</div>
<CollapsibleContent className="mt-2 flex flex-col gap-2">
</CollapsibleContent>
</Collapsible>
<script setup lang="ts">
import { Button } from "@/components/ui/button";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
</script>
<template>
<Collapsible
class="w-[320px] rounded-xl border border-border bg-card p-3"
>
<div class="flex items-center justify-between">
<span class="px-1 text-sm font-medium">3 tokens hidden</span>
<CollapsibleTrigger as-child>
<Button variant="ghost" size="icon-xs" aria-label="Toggle">
<ChevronsUpDown />
</Button>
</CollapsibleTrigger>
</div>
<div class="mt-2 rounded-md border border-border bg-muted px-3 py-2 font-mono text-[13px]">
</div>
<CollapsibleContent class="mt-2 flex flex-col gap-2">
<div
:key="r"
class="rounded-md border border-border bg-muted px-3 py-2 font-mono text-[13px]"
>
{{ r }}
</div>
</CollapsibleContent>
</Collapsible>
</template>
<script lang="ts">
import * as Collapsible from "$lib/components/ui/collapsible";
import { Button } from "$lib/components/ui/button";
</script>
<Collapsible.Root
bind:open
class="w-[320px] rounded-xl border border-border bg-card p-3"
>
<div class="flex items-center justify-between">
<span class="px-1 text-sm font-medium">3 tokens hidden</span>
<Collapsible.Trigger>
{#snippet child({ props })}
<Button {...props} variant="ghost" size="icon-xs" aria-label="Toggle">
<CaretUpDownIcon />
</Button>
{/snippet}
</Collapsible.Trigger>
</div>
<div class="mt-2 rounded-md border border-border bg-muted px-3 py-2 font-mono text-[13px]">
</div>
<Collapsible.Content class="mt-2 flex flex-col gap-2">
{#each rows.slice(1) as r (r)}
<div class="rounded-md border border-border bg-muted px-3 py-2 font-mono text-[13px]">
{r}
</div>
{/each}
</Collapsible.Content>
</Collapsible.Root>
registry/ui/collapsible.tsx
import { Collapsible as CollapsiblePrimitive } from "@base-ui/react/collapsible";
function Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {
return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
}
function CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {
return (
<CollapsiblePrimitive.Trigger data-slot="collapsible-trigger" {...props} />
);
}
function CollapsibleContent({
className,
...props
}: CollapsiblePrimitive.Panel.Props) {
return (
<CollapsiblePrimitive.Panel
data-slot="collapsible-content"
className={className}
{...props}
/>
);
}
export { Collapsible, CollapsibleContent, CollapsibleTrigger };
registry/ui/collapsible/Collapsible.vue
<script setup lang="ts">
import type { CollapsibleRootEmits, CollapsibleRootProps } from 'reka-ui'
import { CollapsibleRoot, useForwardPropsEmits } from 'reka-ui'
const props = defineProps<CollapsibleRootProps>()
const emits = defineEmits<CollapsibleRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script>
<template>
<CollapsibleRoot
v-slot="slotProps"
data-slot="collapsible"
v-bind="forwarded"
>
<slot v-bind="slotProps" />
</CollapsibleRoot>
</template>
registry/ui/collapsible/CollapsibleContent.vue
<script setup lang="ts">
import type { CollapsibleContentProps } from 'reka-ui'
import { CollapsibleContent } from 'reka-ui'
const props = defineProps<CollapsibleContentProps>()
</script>
<template>
<CollapsibleContent
data-slot="collapsible-content"
v-bind="props"
>
<slot />
</CollapsibleContent>
</template>
registry/ui/collapsible/CollapsibleTrigger.vue
<script setup lang="ts">
import type { CollapsibleTriggerProps } from 'reka-ui'
import { CollapsibleTrigger } from 'reka-ui'
const props = defineProps<CollapsibleTriggerProps>()
</script>
<template>
<CollapsibleTrigger
data-slot="collapsible-trigger"
v-bind="props"
>
<slot />
</CollapsibleTrigger>
</template>
registry/ui/collapsible/index.ts
export { default as Collapsible } from "./Collapsible.vue";
export { default as CollapsibleContent } from "./CollapsibleContent.vue";
export { default as CollapsibleTrigger } from "./CollapsibleTrigger.vue";
src/lib/registry/ui/collapsible/collapsible.svelte
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from "bits-ui";
let {
ref = $bindable(null),
open = $bindable(false),
...restProps
}: CollapsiblePrimitive.RootProps = $props();
</script>
<CollapsiblePrimitive.Root bind:ref bind:open data-slot="collapsible" {...restProps} />
src/lib/registry/ui/collapsible/collapsible-content.svelte
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from "bits-ui";
let { ref = $bindable(null), ...restProps }: CollapsiblePrimitive.ContentProps = $props();
</script>
<CollapsiblePrimitive.Content bind:ref data-slot="collapsible-content" {...restProps} />
src/lib/registry/ui/collapsible/collapsible-trigger.svelte
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from "bits-ui";
let { ref = $bindable(null), ...restProps }: CollapsiblePrimitive.TriggerProps = $props();
</script>
<CollapsiblePrimitive.Trigger bind:ref data-slot="collapsible-trigger" {...restProps} />
src/lib/registry/ui/collapsible/index.ts
import Root from "./collapsible.svelte";
import Content from "./collapsible-content.svelte";
import Trigger from "./collapsible-trigger.svelte";
export {
Content,
Content as CollapsibleContent,
Root,
//
Root as Collapsible,
Trigger,
Trigger as CollapsibleTrigger,
};
Prop Type Default
open / defaultOpen boolean false
onOpenChange (open: boolean) => void —

Anatomy: Collapsible, CollapsibleTrigger, CollapsibleContent.

None — same API as the stock collapsible.