/** * FormSection Component * * A reusable form section component that: * - Groups related form fields * - Provides consistent section headers * - Handles section styling and spacing * - Supports collapsible sections * * This component improves form organization and readability. */ import React, { useState } from 'react'; import { Card } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { ChevronDown, ChevronRight } from 'lucide-react'; import { cn } from '@/lib/utils'; // ============================================================================= // TYPES // ============================================================================= export interface FormSectionProps { // Section configuration title?: string; description?: string; collapsible?: boolean; defaultExpanded?: boolean; // Styling className?: string; headerClassName?: string; contentClassName?: string; titleClassName?: string; descriptionClassName?: string; // Layout variant?: 'default' | 'bordered' | 'minimal'; spacing?: 'sm' | 'md' | 'lg'; // Actions actions?: React.ReactNode; // Children children: React.ReactNode; } // ============================================================================= // COMPONENT // ============================================================================= export function FormSection({ title, description, collapsible = false, defaultExpanded = true, className = '', headerClassName = '', contentClassName = '', titleClassName = '', descriptionClassName = '', variant = 'default', spacing = 'md', actions, children, }: FormSectionProps) { // ============================================================================= // STATE // ============================================================================= const [isExpanded, setIsExpanded] = useState(defaultExpanded); // ============================================================================= // HELPER FUNCTIONS // ============================================================================= const getSpacing = (spacing: 'sm' | 'md' | 'lg') => { switch (spacing) { case 'sm': return 'space-y-3'; case 'lg': return 'space-y-6'; default: return 'space-y-4'; } }; const getVariantStyles = (variant: 'default' | 'bordered' | 'minimal') => { switch (variant) { case 'bordered': return 'border border-border rounded-lg p-4'; case 'minimal': return ''; default: return 'bg-card rounded-lg p-4 shadow-sm'; } }; // ============================================================================= // RENDER FUNCTIONS // ============================================================================= const renderHeader = () => { if (!title && !description && !actions) return null; return (
{title && (
{collapsible && ( )}

{title}

)} {description && (

{description}

)}
{actions && (
{actions}
)}
); }; const renderContent = () => { if (collapsible && !isExpanded) return null; return (
{children}
); }; // ============================================================================= // MAIN RENDER // ============================================================================= const sectionContent = (
{renderHeader()} {renderContent()}
); // Wrap in Card for default variant if (variant === 'default') { return {sectionContent}; } return sectionContent; } export default FormSection;