forked from bvaughn/react-virtualized
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcreateMultiSort.js
109 lines (94 loc) · 2.74 KB
/
createMultiSort.js
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/** @flow */
type SortDirection = 'ASC' | 'DESC';
type SortParams = {
defaultSortDirection: SortDirection,
event: MouseEvent,
sortBy: string,
};
type SortDirectionMap = {[string]: SortDirection};
type MultiSortOptions = {
defaultSortBy: ?Array<string>,
defaultSortDirection: ?SortDirectionMap,
};
type MultiSortReturn = {
/**
* Sort property to be passed to the `Table` component.
* This function updates `sortBy` and `sortDirection` values.
*/
sort: (params: SortParams) => void,
/**
* Specifies the fields currently responsible for sorting data,
* In order of importance.
*/
sortBy: Array<string>,
/**
* Specifies the direction a specific field is being sorted in.
*/
sortDirection: SortDirectionMap,
};
export default function createMultiSort(
sortCallback: Function,
{defaultSortBy, defaultSortDirection = {}}: MultiSortOptions = {},
): MultiSortReturn {
if (!sortCallback) {
throw Error(`Required parameter "sortCallback" not specified`);
}
const sortBy = defaultSortBy || [];
const sortDirection = {};
sortBy.forEach(dataKey => {
sortDirection[dataKey] =
defaultSortDirection[dataKey] !== undefined
? defaultSortDirection[dataKey]
: 'ASC';
});
function sort({
defaultSortDirection,
event,
sortBy: dataKey,
}: SortParams): void {
if (event.shiftKey) {
// Shift + click appends a column to existing criteria
if (sortDirection[dataKey] !== undefined) {
sortDirection[dataKey] =
sortDirection[dataKey] === 'ASC' ? 'DESC' : 'ASC';
} else {
sortDirection[dataKey] = defaultSortDirection;
sortBy.push(dataKey);
}
} else if (event.ctrlKey || event.metaKey) {
// Control + click removes column from sort (if pressent)
const index = sortBy.indexOf(dataKey);
if (index >= 0) {
sortBy.splice(index, 1);
delete sortDirection[dataKey];
}
} else {
// Clear sortBy array of all non-selected keys
sortBy.length = 0;
sortBy.push(dataKey);
// Clear sortDirection object of all non-selected keys
const sortDirectionKeys = Object.keys(sortDirection);
sortDirectionKeys.forEach(key => {
if (key !== dataKey) delete sortDirection[key];
});
// If key is already selected, reverse sort direction.
// Else, set sort direction to default direction.
if (sortDirection[dataKey] !== undefined) {
sortDirection[dataKey] =
sortDirection[dataKey] === 'ASC' ? 'DESC' : 'ASC';
} else {
sortDirection[dataKey] = defaultSortDirection;
}
}
// Notify application code
sortCallback({
sortBy,
sortDirection,
});
}
return {
sort,
sortBy,
sortDirection,
};
}