import React, { useState, useRef, useEffect, useMemo, memo } from 'react'; import { cn } from '../../utils/cn'; import { TableSettings as TableSettingsType } from '../../hooks/useTableSettings'; interface TableSettingsProps { settings?: TableSettingsType; onUpdateSetting: (key: K, value: TableSettingsType[K]) => void; onResetSettings: () => void; /** * Callback when user saves new tableIdentifier */ onSaveTableIdentifier?: (identifier: string) => void; /** * Current table identifier */ currentTableIdentifier?: string; /** * Callback when user saves all settings */ onSaveAllSettings?: (identifier: string) => void; /** * List of saved configurations for this page */ savedConfigurations?: { id: string; name?: string }[]; } // Settings icon component with memo to prevent re-renders const SettingsIcon = memo(({ size = 16 }: { size?: number }) => { return ( ); }); SettingsIcon.displayName = 'SettingsIcon'; // RadioOption component const RadioOption = memo(({ id, name, label, value, checked, onChange }: { id: string; name: string; label: string; value: string; checked: boolean; onChange: (value: string) => void; }) => ( )); RadioOption.displayName = 'RadioOption'; // CheckboxOption component const CheckboxOption = memo(({ id, label, checked, onChange }: { id: string; label: string; checked: boolean; onChange: (checked: boolean) => void; }) => ( )); CheckboxOption.displayName = 'CheckboxOption'; // Configurations Panel component const ConfigurationsPanel = memo(({ configurations, currentIdentifier, onLoadConfig, onClose }: { configurations: { id: string; name?: string }[]; currentIdentifier: string; onLoadConfig: (id: string) => void; onClose: () => void; }) => (

Saved Configurations

{configurations.length === 0 ? (

No saved configurations found

) : ( configurations.map(config => ( )) )}
)); ConfigurationsPanel.displayName = 'ConfigurationsPanel'; /** * TableSettings component - UI for customizing table appearance and settings */ export function TableSettings({ settings = {}, onUpdateSetting, onResetSettings, onSaveTableIdentifier, currentTableIdentifier = '', onSaveAllSettings, savedConfigurations = [] }: TableSettingsProps) { // Component state const [isOpen, setIsOpen] = useState(false); const [tableIdentifier, setTableIdentifier] = useState(currentTableIdentifier); const [showConfigurations, setShowConfigurations] = useState(false); const [identifierError, setIdentifierError] = useState(''); const [isClient, setIsClient] = useState(false); // Refs for DOM elements const dropdownRef = useRef(null); const configurationsPanelRef = useRef(null); const buttonRef = useRef(null); // Mark when we're on client side useEffect(() => { setIsClient(true); setTableIdentifier(currentTableIdentifier); }, [currentTableIdentifier]); // Close dropdown when clicking outside useEffect(() => { if (typeof window === 'undefined' || !isOpen) return; function handleClickOutside(event: MouseEvent) { if ( dropdownRef.current && buttonRef.current && !dropdownRef.current.contains(event.target as Node) && !buttonRef.current.contains(event.target as Node) ) { setIsOpen(false); setShowConfigurations(false); } if ( showConfigurations && configurationsPanelRef.current && !configurationsPanelRef.current.contains(event.target as Node) && !dropdownRef.current?.contains(event.target as Node) ) { setShowConfigurations(false); } } document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen, showConfigurations]); // Close on ESC key useEffect(() => { if (typeof window === 'undefined' || !isOpen) return; const handleEsc = (event: KeyboardEvent) => { if (event.key === 'Escape') { setIsOpen(false); setShowConfigurations(false); } }; document.addEventListener('keydown', handleEsc); return () => { document.removeEventListener('keydown', handleEsc); }; }, [isOpen]); // Toggle dropdown const toggleDropdown = () => { setIsOpen(prev => { if (!prev) { setTableIdentifier(currentTableIdentifier); setIdentifierError(''); } return !prev; }); }; // Validate table identifier const validateIdentifier = (identifier: string): boolean => { if (!identifier.trim()) { setIdentifierError('Identifier cannot be empty'); return false; } if (!/^[a-zA-Z0-9_-]+$/.test(identifier)) { setIdentifierError('Identifier can only contain letters, numbers, hyphens and underscores'); return false; } setIdentifierError(''); return true; }; // Save table settings const handleSaveSettings = () => { if (validateIdentifier(tableIdentifier) && onSaveAllSettings) { onSaveAllSettings(tableIdentifier); setIsOpen(false); } }; // Load a saved configuration const handleLoadConfiguration = (configId: string) => { if (onSaveTableIdentifier) { onSaveTableIdentifier(configId); setIsOpen(false); setTableIdentifier(configId); } }; // Don't render anything if not on client side if (!isClient) { return (
); } return (
{isOpen && (

Table Settings

{/* Table Identifier Section */}
Table Identifier
{ setTableIdentifier(e.target.value); if (identifierError) validateIdentifier(e.target.value); }} placeholder="Enter table identifier" />
{identifierError ? (

{identifierError}

) : (

Enter a unique identifier for this table to save its settings.

)} {/* Load Saved Configurations */}
{showConfigurations && ( setShowConfigurations(false)} /> )}
{/* Table Size Section */}
Size
onUpdateSetting('size', val as any)} /> onUpdateSetting('size', val as any)} /> onUpdateSetting('size', val as any)} />
{/* Theme Section */}
Theme
onUpdateSetting('theme', val as any)} /> onUpdateSetting('theme', val as any)} /> onUpdateSetting('theme', val as any)} />
{/* Table Style Section */}
Table Style
onUpdateSetting('variant', val as any)} /> onUpdateSetting('variant', val as any)} /> onUpdateSetting('variant', val as any)} /> onUpdateSetting('variant', val as any)} />
{/* Color Scheme Section */}
Color Scheme
onUpdateSetting('colorScheme', val as any)} /> onUpdateSetting('colorScheme', val as any)} /> onUpdateSetting('colorScheme', val as any)} />
{/* Border Radius Section */}
Border Radius
onUpdateSetting('borderRadius', val as any)} /> onUpdateSetting('borderRadius', val as any)} /> onUpdateSetting('borderRadius', val as any)} /> onUpdateSetting('borderRadius', val as any)} /> onUpdateSetting('borderRadius', val as any)} />
{/* Table Features Section */}
Table Features
onUpdateSetting('striped', val)} /> onUpdateSetting('hover', val)} /> onUpdateSetting('bordered', val)} /> onUpdateSetting('sticky', val)} />
{/* Save Settings Section */}

Save settings with the current identifier

)}
); } export default TableSettings;