UNPKG

mod-arch-shared

Version:

Shared UI components and utilities for modular architecture micro-frontend projects

147 lines 6.5 kB
import * as React from 'react'; export const getTableColumnSort = ({ columns, subColumns = [], sortField, setSortField, ...sortProps }) => { const allColumns = [...columns, ...subColumns]; const resolvedSortIndex = sortField === undefined ? undefined : allColumns.findIndex((c) => c.field === sortField); return getTableColumnSortByIndex({ columns, subColumns, sortIndex: resolvedSortIndex !== undefined && resolvedSortIndex >= 0 ? resolvedSortIndex : undefined, setSortIndex: (index) => { const column = allColumns[index]; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- defensive coding if (!column || column.field == null) { return; } setSortField(column.field); }, ...sortProps, }); }; const getTableColumnSortByIndex = ({ columns, subColumns, sortIndex, sortDirection, setSortIndex, setSortDirection, }) => (columnIndex) => (columnIndex < columns.length ? columns[columnIndex] : subColumns?.[columnIndex - columns.length])?.sortable ? { sortBy: { index: sortIndex, direction: sortDirection, defaultDirection: 'asc', }, onSort: (_event, index, direction) => { setSortIndex(index); setSortDirection(direction); }, columnIndex, } : undefined; /** * Using PF Composable Tables, this utility will help with handling sort logic. * * Use `transformData` on your data before you render rows. * Use `getColumnSort` on your Th.sort as you render it (using the index of your column) * * @see https://www.patternfly.org/v4/components/table */ const useTableColumnSort = (columns, subColumns, defaultSortColIndex, controlledSortProps) => { const [internalSortIndex, setInternalSortIndex] = React.useState(defaultSortColIndex); const [internalSortDirection, setInternalSortDirection] = React.useState('asc'); const allColumns = React.useMemo(() => [...columns, ...subColumns], [columns, subColumns]); // Resolve sort index: from sortIndex, or from sortField via columns const resolvedSortIndex = React.useMemo(() => { const normalizeSortIndex = (index) => typeof index === 'number' && Number.isInteger(index) && index >= 0 && index < allColumns.length ? index : undefined; if (controlledSortProps?.sortIndex !== undefined) { return normalizeSortIndex(controlledSortProps.sortIndex); } if (controlledSortProps?.sortField !== undefined) { const idx = allColumns.findIndex((c) => c.field === controlledSortProps.sortField); return idx >= 0 ? idx : undefined; } return normalizeSortIndex(internalSortIndex); }, [ controlledSortProps?.sortIndex, controlledSortProps?.sortField, allColumns, internalSortIndex, ]); const activeSortIndex = resolvedSortIndex; const activeSortDirection = controlledSortProps?.sortDirection !== undefined ? controlledSortProps.sortDirection : internalSortDirection; const isSortIndexControlled = controlledSortProps?.sortIndex !== undefined || controlledSortProps?.sortField !== undefined; const isSortDirectionControlled = controlledSortProps?.sortDirection !== undefined; const handleSortIndexChange = (index) => { const onFieldChange = controlledSortProps && 'onSortFieldChange' in controlledSortProps ? controlledSortProps.onSortFieldChange : undefined; if (onFieldChange) { const column = allColumns[index]; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- defensive coding if (!column || column.field == null) { return; } onFieldChange(column.field); } else { const onIndexChange = controlledSortProps && 'onSortIndexChange' in controlledSortProps ? controlledSortProps.onSortIndexChange : undefined; onIndexChange?.(index); } if (!isSortIndexControlled) { setInternalSortIndex(index); } }; const handleSortDirectionChange = (direction) => { controlledSortProps?.onSortDirectionChange?.(direction); if (!isSortDirectionControlled) { setInternalSortDirection(direction); } }; return { transformData: (data) => { if (activeSortIndex === undefined) { return data; } return data.toSorted((a, b) => { const columnField = activeSortIndex < columns.length ? columns[activeSortIndex] : subColumns[activeSortIndex - columns.length]; const compute = () => { if (typeof columnField.sortable === 'function') { return columnField.sortable(a, b, columnField.field); } if (!columnField.field) { // If you lack the field, no auto sorting can be done return 0; } // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const dataValueA = a[columnField.field]; // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const dataValueB = b[columnField.field]; if (typeof dataValueA === 'string' && typeof dataValueB === 'string') { return dataValueA.localeCompare(dataValueB); } if (typeof dataValueA === 'number' && typeof dataValueB === 'number') { return dataValueA - dataValueB; } return 0; }; return compute() * (activeSortDirection === 'desc' ? -1 : 1); }); }, getColumnSort: getTableColumnSortByIndex({ columns, subColumns, sortDirection: activeSortDirection, setSortDirection: handleSortDirectionChange, sortIndex: activeSortIndex, setSortIndex: handleSortIndexChange, }), }; }; export default useTableColumnSort; //# sourceMappingURL=useTableColumnSort.js.map