mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-01 14:23:11 +00:00
50 lines
1.4 KiB
TypeScript
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>
|
|
);
|
|
}
|