UNPKG

@coveord/plasma-mantine

Version:

A Plasma flavoured Mantine theme

80 lines (69 loc) 3.02 kB
import {useCallback, useMemo} from 'react'; import {getStorageItem, setStorageItem} from '../../utils/local-storage.js'; import type {TableState} from './use-table.js'; type ColumnVisibility = TableState['columnVisibility']; const storagePath = (tableId: string) => ['table', tableId, 'columnVisibility'] as const; const capVisibleColumns = (visibility: ColumnVisibility, max: number): ColumnVisibility => { let visibleCount = 0; const result: ColumnVisibility = {}; for (const [key, isVisible] of Object.entries(visibility)) { const shouldShow = isVisible && visibleCount < max; result[key] = shouldShow; if (shouldShow) { visibleCount++; } } return result; }; const sanitizeFromStorage = (raw: unknown, validColumnIds: Set<string>): ColumnVisibility => { const result: ColumnVisibility = {}; if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) { return result; } for (const [key, value] of Object.entries(raw as Record<string, unknown>)) { if (validColumnIds.has(key) && typeof value === 'boolean') { result[key] = value; } } return result; }; /** * Hook that persists column visibility preferences to localStorage. * * @param defaultVisibleColumns - The default visibility map. Its keys define the set of valid column IDs. * Must be a stable reference (e.g. via `useRef`) to avoid re-reading localStorage on every render. * @param maxSelectableColumns - Maximum number of columns that can be visible at the same time. * @param tableId - Unique identifier for the table. When omitted, no persistence occurs. */ export const usePersistedColumnVisibility = ( defaultVisibleColumns: ColumnVisibility, maxSelectableColumns: number, tableId?: string, ) => { const path = tableId ? storagePath(tableId) : null; const validIds = useMemo(() => new Set(Object.keys(defaultVisibleColumns)), [defaultVisibleColumns]); const hasValidIds = validIds.size > 0; const initialColumnVisibility = useMemo((): ColumnVisibility => { if (!path || !hasValidIds) { return defaultVisibleColumns; } const stored = getStorageItem<unknown>([...path]); if (stored !== null) { const sanitized = sanitizeFromStorage(stored, validIds); if (Object.keys(sanitized).length > 0) { return capVisibleColumns({...defaultVisibleColumns, ...sanitized}, maxSelectableColumns); } } return capVisibleColumns(defaultVisibleColumns, maxSelectableColumns); }, [path, validIds, defaultVisibleColumns, maxSelectableColumns]); const persistColumnVisibility = useCallback( (visibility: ColumnVisibility) => { if (!path || !hasValidIds) { return; } setStorageItem([...path], visibility); }, [path, hasValidIds], ); return {initialColumnVisibility, persistColumnVisibility}; };