import { useCallback, useMemo } from 'react'; import { IdType, useExpanded, UseExpandedInstanceProps, UseExpandedOptions, UseExpandedState } from 'react-table'; import { forEach, values } from 'lodash-es'; import { ExpandSetter, IRelatableStateInstance, TableAddOnReturn } from '../relatable.types'; import { ExpandedRow, IRowProps } from '../components/renderers'; import arrayHasItems from '../utils/array-has-items'; export interface IWithExpandedOptions extends UseExpandedOptions { onExpandedChange?: ExpandSetter; expandedRowComponent?: React.FC; // react-table state override https://react-table.js.org/api/useExpanded expanded?: IdType[]; } export interface IWithExpandedState extends UseExpandedState { expandSubRows: false; CustomExpandedRowComponent: React.FC; onCustomExpandedChange: ExpandSetter; } export interface IWithExpandedInstance extends UseExpandedInstanceProps, IRelatableStateInstance> { expandSubRows: false; CustomExpandedRowComponent: React.FC; onCustomExpandedChange: ExpandSetter; } export default function withExpanded(options: IWithExpandedOptions = {}): TableAddOnReturn { const { expanded, expandedRowComponent = ExpandedRow, onExpandedChange, ...tableParams } = options; const stateParams = expanded ? { expanded } : {}; const onCustomExpandedChange: ExpandSetter = useCallback((rows, expand) => { if (onExpandedChange) { onExpandedChange(rows, expand); return; } forEach(rows, (row) => row.toggleRowExpanded(expand)); }, [onExpandedChange]); return [ withExpanded.name, null, ({ subRows }) => arrayHasItems(subRows), () => useMemo((): Partial => ({ ...tableParams, expandSubRows: false, CustomExpandedRowComponent: expandedRowComponent, onCustomExpandedChange, }), [expandedRowComponent, onCustomExpandedChange, ...values(tableParams)]), () => useMemo(() => stateParams, [expanded]), useExpanded, ]; }