roiui
itemaccordion-tailwindsource: ok · hit
Accordion (Tailwind)
A collapsible content component.
npx shadcn add "https://roiui.com/r/accordion-tailwind.json"free
Interaction
accordion
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Files1 · source cached 10/8/2026, 9:00:11 PM
registry/brook/tailwind/ui/accordion.tsx
"use client";
import { Accordion } from "@base-ui/react/accordion";
import { cn } from "../../../lib/utils";
function AccordionRoot({ className, ...props }: Accordion.Root.Props) {
return (
<Accordion.Root
className={cn("flex w-[32rem] max-w-[calc(100vw-8rem)] flex-col max-sm:w-full max-sm:max-w-full", className)}
data-slot="accordion-root"
{...props}
/>
);
}
function AccordionItem({ className, ...props }: Accordion.Item.Props) {
return (
<Accordion.Item
className={cn(
"overflow-hidden border-border border-b-[0.5px] bg-[var(--mix-card-75-bg)] p-4",
"transition-[margin,border-radius,border-color] duration-200 ease-[var(--ease-in-out-quad)]",
// Default state - first item has top rounded, last item has bottom rounded
"first:rounded-t-3xl",
"last:rounded-b-3xl last:border-b-transparent",
"first:last:rounded-3xl",
// Expanded item gets full rounded corners and unsticks with margins
"data-[open]:my-2 data-[open]:rounded-3xl data-[open]:border-b-transparent",
"data-[open]:last:mb-0 data-[open]:first:mt-0",
// Item before an expanded item gets rounded bottom only
"[&:has(+*[data-open]):not([data-open])]:rounded-t-none [&:has(+*[data-open]):not([data-open])]:rounded-b-3xl [&:has(+*[data-open]):not([data-open])]:border-b-transparent",
"[&:has(+*[data-open]):not([data-open]):first-child]:rounded-3xl",
// Item after an expanded item gets rounded top only
"[*[data-open]+&:not([data-open])]:rounded-t-3xl [*[data-open]+&:not([data-open])]:rounded-b-none",
"[*[data-open]+&:not([data-open]):last-child]:rounded-3xl",
// Item sandwiched between two expanded items gets full rounded corners
"[*[data-open]+&:not([data-open]):has(+*[data-open])]:rounded-3xl [*[data-open]+&:not([data-open]):has(+*[data-open])]:border-b-transparent",
className
)}
data-slot="accordion-item"
{...props}
/>
);
}
function AccordionHeader({ className, ...props }: Accordion.Header.Props) {
return <Accordion.Header className={cn("m-0", className)} data-slot="accordion-header" {...props} />;
}
function AccordionTrigger({ className, children, ...props }: Accordion.Trigger.Props) {
return (
<Accordion.Trigger
className={cn(
"group flex w-full cursor-pointer items-center gap-4 border-none bg-transparent text-left max-sm:gap-3",
"font-[350] text-base text-secondary-foreground tracking-[-0.02em]",
className
)}
data-slot="accordion-trigger"
{...props}
>
<div
className={cn(
"flex h-8 w-8 items-center justify-center text-muted-foreground max-sm:h-7 max-sm:w-7 max-sm:flex-shrink-0",
"transition-[color,rotate] duration-[200ms,150ms] ease-[ease,var(--ease-in-out-quad)]",
"rotate-0",
"[[data-panel-open]_&]:rotate-90",
"group-hover:text-foreground"
)}
>
<svg
aria-label="Accordion toggle icon"
className="max-sm:h-4 max-sm:w-4"
fill="none"
height="18"
role="img"
viewBox="0 0 20 20"
width="18"
>
<title>Toggle accordion</title>
<path
className={cn(
"origin-center transition-[opacity,scale] duration-150 ease-[var(--ease-in-out-quad)]",
"[[data-panel-open]_&]:scale-0 [[data-panel-open]_&]:opacity-0"
)}
d="M4 10L16 10"
stroke="currentColor"
strokeLinecap="round"
strokeWidth="2"
/>
<path d="M10 4L10 16" stroke="currentColor" strokeLinecap="round" strokeWidth="2" />
</svg>
</div>
<div>{children}</div>
</Accordion.Trigger>
);
}
function AccordionPanel({ className, children, ...props }: Accordion.Panel.Props) {
return (
<Accordion.Panel
className={cn(
"h-[var(--accordion-panel-height)] overflow-hidden",
"transition-[height] duration-150 ease-[var(--ease-in-out-quad)]",
"data-[ending-style]:h-0 data-[starting-style]:h-0",
className
)}
data-slot="accordion-panel"
{...props}
>
<div className="w-full overflow-hidden">
<div className="ml-12 pr-12 text-foreground/75 text-sm leading-[1.6] max-sm:ml-10 max-sm:pr-0 max-sm:text-[0.9375rem] max-sm:leading-[1.5]">
{children}
</div>
</div>
</Accordion.Panel>
);
}
export { AccordionRoot as Accordion, AccordionHeader, AccordionItem, AccordionPanel, AccordionRoot, AccordionTrigger };