import { createContext, useContext, useState } from "react"; import { cn } from "@/utils/ui"; import { HugeiconsIcon } from "@hugeicons/react"; import { ArrowDownIcon } from "@hugeicons/core-free-icons"; import { Label } from "@/components/ui/label"; const sectionExpandedCache = new Map(); interface SectionContext { isOpen: boolean; toggle: () => void; collapsible: boolean; } const SectionCtx = createContext(null); function useSectionContext() { return useContext(SectionCtx); } interface SectionProps { children: React.ReactNode; collapsible?: boolean; defaultOpen?: boolean; sectionKey?: string; className?: string; hasBorderTop?: boolean; hasBorderBottom?: boolean; } export function Section({ children, collapsible = false, defaultOpen = true, sectionKey, className, hasBorderTop = true, hasBorderBottom = true, }: SectionProps) { const cached = sectionKey ? sectionExpandedCache.get(sectionKey) : undefined; const [isOpen, setIsOpen] = useState(cached ?? defaultOpen); const toggle = () => { const next = !isOpen; setIsOpen(next); if (sectionKey) sectionExpandedCache.set(sectionKey, next); }; return (
{children}
); } interface SectionHeaderProps { title: string; children?: React.ReactNode; onClick?: () => void; className?: string; } export function SectionHeader({ title, children, onClick, className, }: SectionHeaderProps) { const ctx = useSectionContext(); const isCollapsible = ctx?.collapsible ?? false; const isOpen = ctx?.isOpen ?? true; const isInteractive = isCollapsible || !!onClick; const handleClick = isCollapsible ? ctx?.toggle : onClick; const content = ( <> {title}
{children} {isCollapsible && ( )}
); const baseClassName = cn( "flex w-full items-center justify-between h-11 px-3.5", className, ); if (isInteractive) { return ( ); } return
{content}
; } export function SectionFields({ children, className, }: { children: React.ReactNode; className?: string; }) { return (
{children}
); } export function SectionField({ label, beforeLabel, children, className, }: { label: string; beforeLabel?: React.ReactNode; children: React.ReactNode; className?: string; }) { return (
{beforeLabel}
{children}
); } export function SectionContent({ children, className, }: { children: React.ReactNode; className?: string; }) { const ctx = useSectionContext(); const isCollapsible = ctx?.collapsible ?? false; const isOpen = ctx?.isOpen ?? true; if (isCollapsible) { return (
{children}
); } return
{children}
; }