40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
'use client';
|
|||
|
|
import { useMarketOutlookSections, type SectionId } from '@/stores/market-outlook-sections-store';
|
||
|
|
|
||
|
|
interface SectionCollapseProps {
|
||
|
|
id: SectionId;
|
||
|
|
title: string;
|
||
|
|
children: React.ReactNode;
|
||
|
|
info?: React.ReactNode;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function SectionCollapse({ id, title, children, info }: SectionCollapseProps) {
|
||
|
|
const open = useMarketOutlookSections((s) => s.open[id]);
|
||
|
|
const toggle = useMarketOutlookSections((s) => s.toggle);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div>
|
||
|
|
<div
|
||
|
|
role="button"
|
||
|
|
tabIndex={0}
|
||
|
|
onClick={() => toggle(id)}
|
||
|
|
onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggle(id); } }}
|
||
|
|
className="flex items-center gap-2 w-full text-left group cursor-pointer"
|
||
|
|
>
|
||
|
|
<span className={`text-xs text-fg-muted transition-transform duration-200 ${open ? 'rotate-90' : ''}`}>
|
||
|
|
▸
|
||
|
|
</span>
|
||
|
|
<h3 className="text-base font-semibold text-fg group-hover:text-accent transition-colors">
|
||
|
|
{title}
|
||
|
|
</h3>
|
||
|
|
{info && (
|
||
|
|
<span onClick={(e) => e.stopPropagation()} className="inline-flex">
|
||
|
|
{info}
|
||
|
|
</span>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
{open && <div className="animate-in fade-in duration-200 mt-4">{children}</div>}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|