Skip to content
42 linesCodeBlameRaw
1import { ChevronDown } from "lucide-react";
2import { Accordion as Primitive } from "radix-ui";
3import type { ComponentProps } from "react";
4
5import { cn } from "../../lib/cn";
6
7// shadcn/ui's accordion, styled with g1t's tokens: a stack of sections in
8// one panel, each opening under its heading, one at a time (`type="single"
9// collapsible`) or any number (`type="multiple"`). For questions and answers
10// and the like; a list of rows that each open on their own stays <details>.
11
12export const Accordion = Primitive.Root;
13
14export function AccordionItem({ className, ...props }: ComponentProps<typeof Primitive.Item>) {
15 return <Primitive.Item data-slot="accordion-item" className={cn("border-b border-line last:border-b-0", className)} {...props} />;
16}
17
18export function AccordionTrigger({ className, children, ...props }: ComponentProps<typeof Primitive.Trigger>) {
19 return (
20 <Primitive.Header className="flex">
21 <Primitive.Trigger
22 data-slot="accordion-trigger"
23 className={cn(
24 "flex flex-1 items-center justify-between gap-3 py-3 text-left text-sm font-medium outline-none transition-colors hover:text-fg focus-visible:ring-2 focus-visible:ring-accent disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
25 className,
26 )}
27 {...props}
28 >
29 {children}
30 <ChevronDown size={16} className="shrink-0 text-faint transition-transform" aria-hidden="true" />
31 </Primitive.Trigger>
32 </Primitive.Header>
33 );
34}
35
36export function AccordionContent({ className, children, ...props }: ComponentProps<typeof Primitive.Content>) {
37 return (
38 <Primitive.Content data-slot="accordion-content" className="overflow-hidden text-sm text-muted" {...props}>
39 <div className={cn("pb-3", className)}>{children}</div>
40 </Primitive.Content>
41 );
42}