-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwith-selection.add-on.ts
More file actions
63 lines (51 loc) · 2.23 KB
/
with-selection.add-on.ts
File metadata and controls
63 lines (51 loc) · 2.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import { useCallback, useMemo, useState } from 'react';
import {
useRowSelect,
UseRowSelectInstanceProps,
UseRowSelectOptions,
UseRowSelectState,
} from 'react-table';
import { map, values, flatMap, reduce, assign, omit } from 'lodash-es';
import { IRelatableStateInstance, SelectSetter, TableAddOnReturn } from '../relatable.types';
import arrayHasItems from '../utils/array-has-items';
export interface IWithSelectionOptions<Data extends object = any> extends UseRowSelectOptions<Data> {
onSelectionChange?: SelectSetter<Data>;
// react-table state override https://react-table.js.org/api/useRowSelect
selectedRowIds?: {[id: string]: boolean};
}
export interface IWithSelectionState<Data extends object = any> extends UseRowSelectState<Data> {}
export interface IWithSelectionInstance<Data extends object = any> extends UseRowSelectInstanceProps<Data>, IRelatableStateInstance<Data, IWithSelectionState<Data>> {
onCustomSelectionChange: SelectSetter<Data>;
}
export default function withSelection<Data extends object = any>(options: IWithSelectionOptions<Data> = {}): TableAddOnReturn {
const { selectedRowIds: theirSelectedRowIds, onSelectionChange, ...tableParams } = options;
const [ourSelectedRowIds, setOurSelectedRowIds] = useState<{[id: string]: boolean}>({});
const selectedRowIds = theirSelectedRowIds || ourSelectedRowIds;
const stateParams = { selectedRowIds };
const onCustomSelectionChange: SelectSetter = useCallback((rows, select) => {
if (onSelectionChange) {
onSelectionChange(rows, select);
return;
}
const newIds = flatMap(rows, ({ id, subRows }) => arrayHasItems(subRows)
? map(subRows, (subRow) => subRow.id)
: [id],
);
if (select) {
setOurSelectedRowIds(reduce(newIds, (agg, id) => assign(agg, ({[id]: true})), {...selectedRowIds}));
return;
}
setOurSelectedRowIds(omit(selectedRowIds, newIds));
}, [onSelectionChange, selectedRowIds]);
return [
withSelection.name,
null,
() => true,
() => useMemo((): Partial<IWithSelectionInstance> => ({
...tableParams,
onCustomSelectionChange,
}), [onCustomSelectionChange, ...values(tableParams)]),
() => useMemo(() => stateParams, [selectedRowIds]),
useRowSelect,
];
}