Collapsible
A single panel that expands and collapses.
import { Button } from "@/components/ui/button";import { Collapsible, CollapsibleContent, CollapsibleTrigger,} from "@/components/ui/collapsible";import { useState } from "react";import { IconPlaceholder } from "@/edmi/icon-placeholder";
const rows = ["NVDAx · 32%", "MSFTx · 28%", "AAPLx · 24%", "ANTHRP-pre · 16%"];
export default function Demo() { const [open, setOpen] = useState(false); return ( <Collapsible open={open} onOpenChange={setOpen} 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" />} > <IconPlaceholder lucide="ChevronsUpDownIcon" tabler="IconSelector" hugeicons="UnfoldMoreIcon" phosphor="CaretUpDownIcon" remixicon="RiArrowUpDownLine" /> </CollapsibleTrigger> </div> <div className="mt-2 rounded-md border border-border bg-muted px-3 py-2 font-mono text-[13px]"> {rows[0]} </div> <CollapsibleContent className="mt-2 flex flex-col gap-2"> {rows.slice(1).map((r) => ( <div key={r} className="rounded-md border border-border bg-muted px-3 py-2 font-mono text-[13px]" > {r} </div> ))} </CollapsibleContent> </Collapsible> );}<script setup lang="ts">import { ChevronsUpDown } from "@lucide/vue";import { ref } from "vue";import { Button } from "@/components/ui/button";import { Collapsible, CollapsibleContent, CollapsibleTrigger,} from "@/components/ui/collapsible";
const open = ref(false);const rows = ["NVDAx · 32%", "MSFTx · 28%", "AAPLx · 24%", "ANTHRP-pre · 16%"];</script>
<template> <Collapsible v-model:open="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> <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]"> {{ rows[0] }} </div> <CollapsibleContent class="mt-2 flex flex-col gap-2"> <div v-for="r in rows.slice(1)" :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 { Button } from "$lib/components/ui/button"; import * as Collapsible from "$lib/components/ui/collapsible"; import IconPlaceholder from "$lib/components/icon-placeholder/icon-placeholder.svelte";
let open = $state(false); const rows = ["NVDAx · 32%", "MSFTx · 28%", "AAPLx · 24%", "ANTHRP-pre · 16%"];</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"> <IconPlaceholder lucide="ChevronsUpDownIcon" tabler="IconSelector" hugeicons="UnfoldMoreIcon" phosphor="CaretUpDownIcon" remixicon="RiArrowUpDownLine" /> </Button> {/snippet} </Collapsible.Trigger> </div> <div class="mt-2 rounded-md border border-border bg-muted px-3 py-2 font-mono text-[13px]"> {rows[0]} </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>Installation
Section titled “Installation”npx shadcn@latest add @edmi-ui/collapsiblepnpm dlx shadcn@latest add @edmi-ui/collapsibleyarn dlx shadcn@latest add @edmi-ui/collapsiblebunx shadcn@latest add @edmi-ui/collapsiblePick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.
Install the dependencies:
Terminal window npm install @base-ui/reactTerminal window pnpm add @base-ui/reactTerminal window yarn add @base-ui/reactTerminal window bun add @base-ui/reactCopy the code from Component source into your project and update the import paths to match your aliases.
npx shadcn-vue@latest add @edmi-ui/collapsiblepnpm dlx shadcn-vue@latest add @edmi-ui/collapsibleyarn dlx shadcn-vue@latest add @edmi-ui/collapsiblebunx shadcn-vue@latest add @edmi-ui/collapsiblePick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.
Install the dependencies:
Terminal window npm install reka-uiTerminal window pnpm add reka-uiTerminal window yarn add reka-uiTerminal window bun add reka-uiCopy the code from Component source into your project and update the import paths to match your aliases.
npx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/collapsible.jsonpnpm dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/collapsible.jsonyarn dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/collapsible.jsonbunx --bun shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/collapsible.jsonPick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.
Copy the code from Component source into your project and update the import paths to match your aliases.
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>Component source
Section titled “Component source”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 };<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><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><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>export { default as Collapsible } from "./Collapsible.vue";export { default as CollapsibleContent } from "./CollapsibleContent.vue";export { default as CollapsibleTrigger } from "./CollapsibleTrigger.vue";<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} /><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} /><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} />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.
✦ Edmi additions
Section titled “✦ Edmi additions”None — same API as the stock collapsible.