import { useCallback, useMemo, useState } from 'react'; import { SortingRule, useSortBy, UseSortByInstanceProps, UseSortByOptions, UseSortByState } from 'react-table'; import { filter, values } from 'lodash-es'; import { IRelatableStateInstance, SORT_ACTIONS, SortSetter, TableAddOnReturn } from '../relatable.types'; export interface IWithSortingOptions extends UseSortByOptions { onSortChange?: SortSetter; // react-table state override https://react-table.js.org/api/useSortBy sortBy?: SortingRule[]; } export interface IWithSortingState extends UseSortByState { onCustomSortChange: SortSetter; } export interface IWithSortingInstance extends UseSortByInstanceProps, IRelatableStateInstance> { onCustomSortChange: SortSetter; } export default function withSorting(options: IWithSortingOptions = {}): TableAddOnReturn { const { sortBy: theirSortBy, onSortChange, ...tableParams } = options; const [ourSortBy, setOurSortBy] = useState[]>([]); const sortBy = theirSortBy || ourSortBy; const stateParams = { sortBy }; const onCustomSortChange: SortSetter = useCallback((column, action) => { if (onSortChange) { onSortChange(column, action); return; } const withoutColumn = filter(ourSortBy, ({ id }) => id !== column.id); if (action === SORT_ACTIONS.SORT_CLEAR) { setOurSortBy(withoutColumn); return; } setOurSortBy([...withoutColumn, { id: column.id, desc: action === SORT_ACTIONS.SORT_DESC }]); }, [onSortChange, ourSortBy, setOurSortBy]); return [ withSorting.name, withSorting.name, ({ canSort }) => canSort, () => useMemo((): Partial => ({ ...tableParams, onCustomSortChange, }), [onCustomSortChange, ...values(tableParams)]), () => useMemo(() => stateParams, [sortBy]), useSortBy, ]; }