| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
- import * as React from "react";
- import { ChevronRight } from "lucide-react";
- interface CollapsibleProps {
- title: string;
- count?: number;
- defaultOpen?: boolean;
- icon?: React.ReactNode;
- badge?: React.ReactNode;
- children: React.ReactNode;
- }
- export function Collapsible({
- title,
- count,
- defaultOpen = true,
- icon,
- badge,
- children,
- }: CollapsibleProps) {
- const [open, setOpen] = React.useState(defaultOpen);
- return (
- <div className="rounded-lg border border-border bg-muted/10">
- <button
- type="button"
- className="flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-muted/20"
- onClick={() => setOpen((prev) => !prev)}
- >
- <ChevronRight
- className={`h-4 w-4 shrink-0 text-muted-foreground transition-transform ${
- open ? "rotate-90" : ""
- }`}
- />
- {icon && <span className="shrink-0 text-muted-foreground">{icon}</span>}
- <span className="text-sm font-semibold">{title}</span>
- {count !== undefined && (
- <span className="rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground">
- {count}
- </span>
- )}
- {badge && <span className="ml-auto">{badge}</span>}
- </button>
- {open && <div className="border-t border-border px-4 py-4">{children}</div>}
- </div>
- );
- }
|