Primitives
Accordion
Index-numbered disclosure rows.
● LIVE
"use client";import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "@/registry/okibi/ui/accordion";export default function AccordionDemo() { return ( <Accordion type="single" collapsible className="w-80 max-w-full"> <AccordionItem value="grid"> <AccordionTrigger index="01">Sec Grid</AccordionTrigger> <AccordionContent> Perimeter secure. All four nodes reporting in. </AccordionContent> </AccordionItem> <AccordionItem value="ice"> <AccordionTrigger index="02">ICE Layer</AccordionTrigger> <AccordionContent> Black ICE armed across the subnet. No intrusion detected. </AccordionContent> </AccordionItem> <AccordionItem value="uplink"> <AccordionTrigger index="03">Net Uplink</AccordionTrigger> <AccordionContent> Uplink locked to grid reference. Handshake verified. </AccordionContent> </AccordionItem> </Accordion> );}npx shadcn@latest add https://okibi.cndr.dev/r/accordion.jsonInstallation
Install the theme first, then add the component:
npx shadcn@latest add https://okibi.cndr.dev/r/accordion.jsonInstall the required dependencies:
npm install @radix-ui/react-accordion lucide-reactCopy the source from the Code tab above into components/ui/accordion.tsx. It uses the cn helper and the okibi theme tokens — install the theme first if you haven't.
Usage
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
<Accordion type="single" collapsible>
<AccordionItem value="item-1">
<AccordionTrigger>Section one</AccordionTrigger>
<AccordionContent>Disclosure body…</AccordionContent>
</AccordionItem>
</Accordion>Anatomy
<Accordion type="single" collapsible>
<AccordionItem value="item-1"> {/* unique value per row */}
<AccordionTrigger index="01" /> {/* mono index is a Trigger prop, not Item */}
<AccordionContent />
</AccordionItem>
</Accordion>API Reference
Accordion
| Prop | Type | Default | Description |
|---|---|---|---|
type | "single" | "multiple" | – | One open row at a time, or many. |
collapsible | boolean | false | Allow closing the open row (single only). |
AccordionItem
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | – | Unique id for the row. |
AccordionTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
index | string | – | Optional mono index annotation rendered before the trigger label. |
Accessibility
- Wraps Radix
Accordion, which renders each trigger inside anAccordionPrimitive.Headerand wires thebutton/region disclosure semantics anddata-state. - Full keyboard model from the primitive:
Enter/Spacetoggle a row, arrow keys move between triggers,Home/Endjump to the first/last. - Triggers carry the standard square signal focus ring (
ring-2 ring-ringwith offset);disableditems are skipped and dimmed toopacity-60. - The chevron reticle is decorative (
aria-hidden) and rotates viadata-state=open, so its motion conveys nothing assistive tech needs. type='single'allows one open row (addcollapsibleto close it);type='multiple'lets several stay open — the toggle state is announced by Radix.
Guidelines
Do
- Put the mono
indexonAccordionTrigger, where it renders ahead of the label. - Add
collapsibleto atype='single'accordion when the open row should be closable back to all-collapsed. - Give each
AccordionItema uniquevalueso open state tracks correctly.
Don't
- Do not pass
indextoAccordionItem— it is anAccordionTriggerprop and is ignored on the item. - Do not bury primary actions inside a collapsed row; the content is hidden until the user opens it.
- Do not re-add JS motion — the height keyframes are CSS-only and already reduced-motion gated.