Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Multi-Level Accordion with Plus/Minus Trigger for Solid

Help topics with a plus on the right. Account starts open, and each article has its own chevron.

UI library: Ark UI

Account starts open in a bordered stack of help topics. A plus on the right turns into a minus, and the articles inside open with their own chevrons.

Use it when the two levels should look different. A tree with selection belongs in a Tree View. In Solid, Ark UI does not open an article when its topic opens.

Preview

Preview width

Installation

MCP · Pro
Make your AI a shadcn expert
Your agent installs components, builds pages and restyles your app from one prompt, in Claude Code, Cursor or VS Code.
Part of Pro

Anatomy

Accordion anatomy: root, item, item trigger, item content, item indicator

Usage

<Accordion class="w-full max-w-md -space-y-px" defaultValue={["account"]}>
    {topics.map(topic => <AccordionItem class="overflow-hidden border bg-background first:rounded-t-lg last:rounded-b-lg" value={topic.value}>
        <AccordionTrigger class="px-4 py-3 hover:no-underline **:data-[slot=accordion-trigger-icon]:hidden">
          <span class="flex w-full items-center justify-between gap-3">
            <span class="text-start">{topic.title}</span>
            <span class="relative size-4 shrink-0">
              <PlusIcon aria-hidden="true" class="absolute inset-0 size-4 text-muted-foreground transition-opacity duration-200 group-aria-expanded/accordion-trigger:opacity-0" />
              <MinusIcon aria-hidden="true" class="absolute inset-0 size-4 text-muted-foreground opacity-0 transition-opacity duration-200 group-aria-expanded/accordion-trigger:opacity-100" />
            </span>
          </span>
        </AccordionTrigger>
        <AccordionContent class="p-0">
          {topic.articles.map(article => <Collapsible class="border-t bg-accent px-4 py-3">
              <CollapsibleTrigger class="group flex gap-2 text-start font-medium">
                <ChevronDownIcon aria-hidden="true" class="mt-0.5 size-4 shrink-0 opacity-60 transition-transform duration-200 group-aria-expanded:rotate-180" />
                {article.title}
              </CollapsibleTrigger>
              <CollapsibleContent class="ps-6 pt-1 text-muted-foreground text-sm">
                {article.content}
              </CollapsibleContent>
            </Collapsible>)}
        </AccordionContent>
      </AccordionItem>)}
  </Accordion>

FAQ

How does the parent plus turn into a minus?

**:data-[slot=accordion-trigger-icon]:hidden on AccordionTrigger hides the built-in chevron. PlusIcon and MinusIcon share one relative size-4 box, and group-aria-expanded/accordion-trigger fades the plus out and the minus in over duration-200. Both icons are aria-hidden and text-muted-foreground.

What toggles an article?

Each article is a Collapsible inside AccordionContent. Its ChevronDownIcon sits on CollapsibleTrigger and uses group-aria-expanded:rotate-180 with duration-200.

How are the article rows styled?

AccordionContent is p-0. Each Collapsible has border-t and bg-accent, and CollapsibleContent uses ps-6 with text-sm text-muted-foreground.

Why does Account start open?

defaultValue={["account"]} opens Account on first render. The string matches that item's value.

Do the articles start open?

No. Each Collapsible renders closed until its trigger is pressed. Account starts open, so the article titles show.

How do I let several parent sections stay open at once?

One open item is the default. Add multiple to Accordion to let several stay open, and list every item that should start open in the defaultValue array.

API Reference

Accordion

Sets defaultValue={["account"]} and value={topic.value}. The rest is on the Accordion page.

Collapsible

No extra props in this demo. The rest is on the Collapsible page.