shoc-frontend-new/src/components/ui/collapsible-section.tsx
2026-07-24 11:32:58 -03:00

50 lines
1.4 KiB
TypeScript

import { useState, type ElementType, type ReactNode } from "react";
import { ChevronDown, ChevronUp } from "lucide-react";
import { CountBadge } from "@/components/ui/count-badge";
import { cn } from "@/lib/utils";
export type CollapsibleSectionProps = {
icon?: ElementType;
label: string;
count?: number;
defaultOpen?: boolean;
children: ReactNode;
className?: string;
};
export function CollapsibleSection({
icon: Icon,
label,
count = 0,
defaultOpen = false,
children,
className,
}: CollapsibleSectionProps) {
const [open, setOpen] = useState(defaultOpen);
return (
<div className={cn("border-b border-border", open && "pb-3", className)}>
<button
type="button"
onClick={() => setOpen((current) => !current)}
className="flex w-full cursor-pointer items-center justify-between py-3 text-left"
aria-expanded={open}
>
<div className="flex items-center gap-2">
{Icon != null && <Icon size={16} className="text-primary" />}
<span className="text-sm font-semibold text-foreground">{label}</span>
</div>
<div className="flex items-center gap-2">
<CountBadge count={count} />
{open ? (
<ChevronUp size={16} className="text-muted-foreground" />
) : (
<ChevronDown size={16} className="text-muted-foreground" />
)}
</div>
</button>
{open && children}
</div>
);
}