import React, { useState, type ReactNode, useEffect } from 'react'; import { ChevronDown, ChevronUp } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Card, CardHeader, CardContent } from '@/components/ui/card'; interface CollapsibleSectionProps { title: ReactNode; children: ReactNode; initiallyOpen?: boolean; storageKey?: string; // New prop for localStorage key className?: string; headerClassName?: string; headerContent?: ReactNode; titleClassName?: string; buttonClassName?: string; contentClassName?: string; asCard?: boolean; // New prop to decide if it should render as a Card onStateChange?: (isOpen: boolean) => void; // New prop for state change callback id?: string; minimal?: boolean; // New prop for minimal styling renderHeader?: ( toggle: () => void, isOpen: boolean ) => React.ReactNode; } const CollapsibleSection: React.FC = ({ title, children, initiallyOpen = true, storageKey, className = '', headerClassName, headerContent, titleClassName, buttonClassName = '', // Made button smaller contentClassName, asCard = false, // Default to not rendering as a card onStateChange, // Destructure new prop id, minimal = false, renderHeader }) => { const [isOpen, setIsOpen] = useState(() => { if (storageKey) { try { const storedState = localStorage.getItem(storageKey); if (storedState !== null) { return JSON.parse(storedState) as boolean; } } catch (error) { console.error(`Error reading CollapsibleSection state from localStorage for key "${storageKey}":`, error); } } return initiallyOpen; }); useEffect(() => { if (storageKey) { try { localStorage.setItem(storageKey, JSON.stringify(isOpen)); if (onStateChange) { // Call onStateChange when state is synced from localStorage onStateChange(isOpen); } } catch (error) { console.error(`Error writing CollapsibleSection state to localStorage for key "${storageKey}":`, error); } } }, [isOpen, storageKey, onStateChange]); const toggleOpen = () => { const newState = !isOpen; setIsOpen(newState); if (onStateChange) { // Call onStateChange when toggling onStateChange(newState); } }; // Apply minimal styling if enabled const finalHeaderClassName = headerClassName || (minimal ? 'flex justify-between items-center p-1 cursor-pointer border-b border-border' : 'flex justify-between items-center p-3 md:p-4 cursor-pointer border-b border-border' ); const finalTitleClassName = titleClassName || (minimal ? 'text-sm font-semibold' : 'text-md md:text-lg font-semibold' ); const finalContentClassName = contentClassName || (minimal ? 'p-0' : 'p-3 md:p-4' ); const finalContainerClassName = minimal ? `bg-card ${className}` : `rounded-lg shadow-none md:shadow-md border border-border bg-card ${className}`; const header = renderHeader ? ( renderHeader(toggleOpen, isOpen) ) : (
{title}
{headerContent}
); if (asCard) { const cardClassName = minimal ? `${className}` : `shadow-none md:shadow-md ${className}`; return (
{title}
{headerContent}
{isOpen && {children}}
); } return (
{header} {isOpen &&
{children}
}
); }; export default CollapsibleSection;