UNPKG

@kadconsulting/dry

Version:
101 lines 5.78 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { createElement as _createElement } from "react"; // TableHeader.tsx import { useMemo, useCallback, useState, useEffect } from 'react'; // TODO-DRY: icon needs to be easer to use import Icon from '../../Icons/Icon/Icon'; import { ArrowNarrowUp, ArrowNarrowDown, ChevronSelectorVertical, } from '../../Icons/paths'; import { IconSizes } from '../../Icons/Icon/IconTypes'; import { FilterType } from '../DataTableTypes'; import './TableHeader.scss'; const TableHeader = ({ headerGroups, onSortChange, columnOrder, columnWidths, onColumnOrderChange, onColumnResize, sortedColumn, hasResize, isDraggable, }) => { // State for tracking drag source const [draggedColumnIndex, setDraggedColumnIndex] = useState(null); // State for tracking initial position and size for resizing const [startX, setStartX] = useState(null); const [startWidth, setStartWidth] = useState(null); // Create a memoized version of headerGroups const memoizedHeaderGroups = useMemo(() => headerGroups, [headerGroups]); // Handle column sorting const handleSort = useCallback((column) => { // This is broken up so if in the future we want to make this logic better we can start here switch (column.filterType) { case FilterType.Text: let textNewSortBy = [ { id: column.id, desc: sortedColumn?.direction === 'asc' }, ]; onSortChange(textNewSortBy); case FilterType.Number: const numberNewSortBy = [ { id: column.id, desc: sortedColumn?.direction === 'asc' }, ]; onSortChange(numberNewSortBy); case FilterType.DateRange: const dateNewSortBy = [ { id: column.id, desc: sortedColumn?.direction === 'asc' }, ]; onSortChange(dateNewSortBy); default: return true; } }, [onSortChange, sortedColumn]); // Handle column reordering const handleColumnReorder = useCallback((sourceIndex, destinationIndex) => { const newOrder = [...columnOrder]; const [removed] = newOrder.splice(sourceIndex, 1); newOrder.splice(destinationIndex, 0, removed); onColumnOrderChange(newOrder); }, [columnOrder, onColumnOrderChange]); // Handle drag start const handleDragStart = useCallback((e, columnIndex) => { e.dataTransfer.effectAllowed = 'move'; setDraggedColumnIndex(columnIndex); }, []); // Handle drag over const handleDragOver = useCallback((e) => { e.preventDefault(); }, []); // Handle drop const handleDrop = useCallback((e, columnIndex) => { e.preventDefault(); if (draggedColumnIndex !== null && draggedColumnIndex !== columnIndex) { handleColumnReorder(draggedColumnIndex, columnIndex); } setDraggedColumnIndex(null); }, [draggedColumnIndex, handleColumnReorder]); // Handle mouse down for resizing const handleMouseDown = useCallback((e, colIndex) => { setStartX(e.pageX); setStartWidth(columnWidths[headerGroups[0].headers[colIndex].id]); }, [columnWidths, headerGroups]); // Handle mouse move for resizing const handleMouseMove = useCallback((e) => { if (startX === null || startWidth === null) return; const newWidth = startWidth + (e.pageX - startX); const columnId = headerGroups[0].headers[draggedColumnIndex] .id; onColumnResize({ [columnId]: newWidth }); }, [startX, startWidth, draggedColumnIndex, headerGroups, onColumnResize]); // Handle mouse up for resizing const handleMouseUp = useCallback(() => { document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); setStartX(null); setStartWidth(null); }, [handleMouseMove]); useEffect(() => { if (startX !== null) { document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); } return () => { document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); }; }, [startX, handleMouseMove, handleMouseUp]); return (_jsx("thead", { children: memoizedHeaderGroups.map((headerGroup, index) => (_createElement("tr", { ...headerGroup.getHeaderGroupProps(), key: index }, headerGroup.headers.map((column, colIndex) => (_createElement("th", { ...column.getHeaderProps(), key: colIndex, style: { width: `${columnWidths[column.id]}px` } }, _jsxs("div", { className: 'header-container', children: [_jsxs("div", { className: 'header-content', onClick: () => handleSort(column), children: [column.render('Header'), _jsx("span", { className: 'sort-indicator', children: sortedColumn?.id === column.id ? (sortedColumn?.direction === 'asc' ? (_jsx(Icon, { color: 'black', Path: ArrowNarrowUp, size: IconSizes.SMALL })) : (_jsx(Icon, { color: 'black', Path: ArrowNarrowDown, size: IconSizes.SMALL }))) : (_jsx(Icon, { color: 'black', Path: ChevronSelectorVertical, size: IconSizes.SMALL })) })] }), isDraggable && (_jsx("div", { className: 'drag-handle', draggable: true, onDragStart: (e) => handleDragStart(e, colIndex), onDragOver: handleDragOver, onDrop: (e) => handleDrop(e, colIndex), children: "\u2630" })), hasResize && (_jsx("div", { className: 'resize-handle', onMouseDown: (e) => handleMouseDown(e, colIndex), children: "\u2500" }))] }))))))) })); }; export default TableHeader; //# sourceMappingURL=TableHeader.js.map