haixunMaster/components/research-map-section.tsx

62 lines
1.7 KiB
TypeScript

"use client";
import { useState, type ReactNode } from "react";
import { ChevronDown } from "lucide-react";
import { cn } from "@/lib/utils";
interface ResearchMapSectionProps {
title: string;
count?: number;
defaultOpen?: boolean;
collapsible?: boolean;
children: ReactNode;
className?: string;
}
export function ResearchMapSection({
title,
count,
defaultOpen = false,
collapsible = true,
children,
className,
}: ResearchMapSectionProps) {
const [open, setOpen] = useState(defaultOpen || !collapsible);
const label = count !== undefined ? `${title} · ${count}` : title;
if (!collapsible) {
return (
<div className={cn("tool-section overflow-hidden", className)}>
<div className="tool-section-header">
<span>{label}</span>
</div>
<div className="border-t border-border px-3 py-2.5">{children}</div>
</div>
);
}
return (
<div className={cn("tool-section overflow-hidden", className)}>
<button
type="button"
onClick={() => setOpen((v) => !v)}
className="tool-section-header w-full text-left hover:bg-accent/50"
>
<span>{label}</span>
<ChevronDown
className={cn("h-3.5 w-3.5 shrink-0 transition-transform", open && "rotate-180")}
/>
</button>
{open && <div className="border-t border-border px-3 py-2.5">{children}</div>}
</div>
);
}
export function MapField({ label, children }: { label: string; children: ReactNode }) {
return (
<div className="rounded-md border border-border bg-muted/40 px-3 py-2.5">
<p className="tool-kv-label">{label}</p>
<div className="tool-kv-value">{children}</div>
</div>
);
}