@carbon/react 1.85.0 → 1.86.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +797 -797
- package/es/components/AILabel/index.js +1 -1
- package/es/components/Accordion/AccordionItem.d.ts +1 -1
- package/es/components/Accordion/AccordionItem.js +1 -1
- package/es/components/Checkbox/Checkbox.js +1 -1
- package/es/components/CheckboxGroup/CheckboxGroup.js +1 -1
- package/es/components/CodeSnippet/CodeSnippet.d.ts +2 -2
- package/es/components/CodeSnippet/CodeSnippet.js +1 -1
- package/es/components/ComboBox/ComboBox.js +1 -1
- package/es/components/ComposedModal/ComposedModal.js +1 -1
- package/es/components/ContentSwitcher/ContentSwitcher.d.ts +1 -1
- package/es/components/ContentSwitcher/ContentSwitcher.js +1 -1
- package/es/components/DataTable/DataTable.d.ts +230 -170
- package/es/components/DataTable/DataTable.js +508 -519
- package/es/components/DataTable/TableContainer.d.ts +9 -1
- package/es/components/DataTable/TableContainer.js +7 -1
- package/es/components/DataTable/TableExpandHeader.d.ts +1 -1
- package/es/components/DataTable/TableExpandHeader.js +1 -1
- package/es/components/DataTable/TableSelectAll.d.ts +2 -2
- package/es/components/DataTable/TableSelectAll.js +1 -1
- package/es/components/DataTable/TableSelectRow.d.ts +2 -2
- package/es/components/DataTable/TableSelectRow.js +1 -1
- package/es/components/DataTable/TableToolbar.d.ts +1 -1
- package/es/components/DataTable/TableToolbar.js +1 -1
- package/es/components/DataTable/TableToolbarMenu.d.ts +2 -18
- package/es/components/DataTable/TableToolbarMenu.js +0 -1
- package/es/components/DataTable/index.d.ts +1 -1
- package/es/components/DataTable/state/getDerivedStateFromProps.js +5 -1
- package/es/components/DatePicker/DatePicker.js +1 -1
- package/es/components/DatePickerInput/DatePickerInput.js +1 -1
- package/es/components/Dropdown/Dropdown.js +1 -1
- package/es/components/FeatureFlags/index.d.ts +2 -2
- package/es/components/FeatureFlags/index.js +1 -1
- package/es/components/FileUploader/FileUploaderButton.d.ts +1 -1
- package/es/components/FileUploader/FileUploaderButton.js +1 -1
- package/es/components/FileUploader/FileUploaderDropContainer.d.ts +2 -2
- package/es/components/FileUploader/FileUploaderDropContainer.js +1 -1
- package/es/components/FluidTextArea/FluidTextArea.d.ts +1 -1
- package/es/components/FluidTextArea/FluidTextArea.js +1 -1
- package/es/components/InlineCheckbox/InlineCheckbox.js +1 -1
- package/es/components/ListBox/ListBox.js +1 -1
- package/es/components/Loading/Loading.d.ts +1 -1
- package/es/components/Loading/Loading.js +1 -1
- package/es/components/Menu/Menu.js +1 -1
- package/es/components/Modal/Modal.js +1 -1
- package/es/components/MultiSelect/FilterableMultiSelect.js +1 -1
- package/es/components/MultiSelect/MultiSelect.js +1 -1
- package/es/components/Notification/Notification.d.ts +4 -4
- package/es/components/Notification/Notification.js +1 -1
- package/es/components/NumberInput/NumberInput.d.ts +7 -0
- package/es/components/NumberInput/NumberInput.js +80 -25
- package/es/components/OverflowMenu/OverflowMenu.d.ts +2 -6
- package/es/components/OverflowMenu/OverflowMenu.js +1 -1
- package/es/components/Pagination/Pagination.js +22 -5
- package/es/components/RadioButton/RadioButton.js +1 -1
- package/es/components/RadioButtonGroup/RadioButtonGroup.js +1 -1
- package/es/components/RadioTile/RadioTile.js +1 -1
- package/es/components/Search/Search.js +1 -1
- package/es/components/Select/Select.js +1 -1
- package/es/components/Slider/Slider.js +1 -1
- package/es/components/StructuredList/StructuredList.d.ts +5 -5
- package/es/components/StructuredList/StructuredList.js +1 -1
- package/es/components/Tabs/Tabs.d.ts +1 -1
- package/es/components/Tabs/Tabs.js +1 -1
- package/es/components/Tag/DismissibleTag.js +1 -1
- package/es/components/Tag/Tag.js +1 -1
- package/es/components/TextArea/TextArea.js +1 -1
- package/es/components/TextInput/ControlledPasswordInput.js +1 -1
- package/es/components/TextInput/PasswordInput.js +1 -1
- package/es/components/TextInput/TextInput.js +1 -1
- package/es/components/Tile/Tile.js +1 -1
- package/es/components/TileGroup/TileGroup.d.ts +5 -5
- package/es/components/TimePicker/TimePicker.d.ts +8 -0
- package/es/components/TimePicker/TimePicker.js +6 -4
- package/es/components/Tooltip/DefinitionTooltip.d.ts +1 -1
- package/es/components/Tooltip/DefinitionTooltip.js +1 -1
- package/es/components/TreeView/TreeContext.d.ts +19 -0
- package/es/components/TreeView/TreeContext.js +13 -0
- package/es/components/TreeView/TreeNode.d.ts +4 -4
- package/es/components/TreeView/TreeNode.js +56 -108
- package/es/components/TreeView/TreeView.js +42 -79
- package/es/components/UIShell/HeaderMenu.js +1 -1
- package/es/components/UIShell/HeaderMenuItem.d.ts +1 -1
- package/es/components/UIShell/HeaderMenuItem.js +1 -1
- package/es/components/UIShell/HeaderName.d.ts +1 -1
- package/es/components/UIShell/HeaderPanel.js +5 -7
- package/es/components/UIShell/Link.d.ts +2 -2
- package/es/components/UIShell/Link.js +1 -1
- package/es/components/UIShell/Switcher.d.ts +1 -1
- package/es/components/UIShell/Switcher.js +39 -12
- package/es/index.js +1 -1
- package/es/internal/useNoInteractiveChildren.d.ts +25 -0
- package/es/internal/useNoInteractiveChildren.js +39 -32
- package/es/prop-types/deprecate.d.ts +17 -0
- package/es/prop-types/deprecate.js +22 -12
- package/lib/components/AILabel/index.js +2 -2
- package/lib/components/Accordion/AccordionItem.d.ts +1 -1
- package/lib/components/Accordion/AccordionItem.js +1 -1
- package/lib/components/Checkbox/Checkbox.js +1 -1
- package/lib/components/CheckboxGroup/CheckboxGroup.js +1 -1
- package/lib/components/CodeSnippet/CodeSnippet.d.ts +2 -2
- package/lib/components/CodeSnippet/CodeSnippet.js +2 -2
- package/lib/components/ComboBox/ComboBox.js +3 -3
- package/lib/components/ComposedModal/ComposedModal.js +1 -1
- package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +1 -1
- package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -1
- package/lib/components/DataTable/DataTable.d.ts +230 -170
- package/lib/components/DataTable/DataTable.js +507 -518
- package/lib/components/DataTable/TableContainer.d.ts +9 -1
- package/lib/components/DataTable/TableContainer.js +7 -1
- package/lib/components/DataTable/TableExpandHeader.d.ts +1 -1
- package/lib/components/DataTable/TableExpandHeader.js +1 -1
- package/lib/components/DataTable/TableSelectAll.d.ts +2 -2
- package/lib/components/DataTable/TableSelectAll.js +1 -1
- package/lib/components/DataTable/TableSelectRow.d.ts +2 -2
- package/lib/components/DataTable/TableSelectRow.js +1 -1
- package/lib/components/DataTable/TableToolbar.d.ts +1 -1
- package/lib/components/DataTable/TableToolbar.js +1 -1
- package/lib/components/DataTable/TableToolbarMenu.d.ts +2 -18
- package/lib/components/DataTable/TableToolbarMenu.js +0 -1
- package/lib/components/DataTable/index.d.ts +1 -1
- package/lib/components/DataTable/state/getDerivedStateFromProps.js +5 -1
- package/lib/components/DatePicker/DatePicker.js +1 -1
- package/lib/components/DatePickerInput/DatePickerInput.js +1 -1
- package/lib/components/Dropdown/Dropdown.js +3 -3
- package/lib/components/FeatureFlags/index.d.ts +2 -2
- package/lib/components/FeatureFlags/index.js +1 -1
- package/lib/components/FileUploader/FileUploaderButton.d.ts +1 -1
- package/lib/components/FileUploader/FileUploaderButton.js +1 -1
- package/lib/components/FileUploader/FileUploaderDropContainer.d.ts +2 -2
- package/lib/components/FileUploader/FileUploaderDropContainer.js +2 -2
- package/lib/components/FluidTextArea/FluidTextArea.d.ts +1 -1
- package/lib/components/FluidTextArea/FluidTextArea.js +1 -1
- package/lib/components/InlineCheckbox/InlineCheckbox.js +1 -1
- package/lib/components/ListBox/ListBox.js +1 -1
- package/lib/components/Loading/Loading.d.ts +1 -1
- package/lib/components/Loading/Loading.js +1 -1
- package/lib/components/Menu/Menu.js +1 -1
- package/lib/components/Modal/Modal.js +1 -1
- package/lib/components/MultiSelect/FilterableMultiSelect.js +4 -4
- package/lib/components/MultiSelect/MultiSelect.js +2 -2
- package/lib/components/Notification/Notification.d.ts +4 -4
- package/lib/components/Notification/Notification.js +4 -4
- package/lib/components/NumberInput/NumberInput.d.ts +7 -0
- package/lib/components/NumberInput/NumberInput.js +81 -26
- package/lib/components/OverflowMenu/OverflowMenu.d.ts +2 -6
- package/lib/components/OverflowMenu/OverflowMenu.js +2 -2
- package/lib/components/Pagination/Pagination.js +21 -4
- package/lib/components/RadioButton/RadioButton.js +1 -1
- package/lib/components/RadioButtonGroup/RadioButtonGroup.js +1 -1
- package/lib/components/RadioTile/RadioTile.js +2 -2
- package/lib/components/Search/Search.js +1 -1
- package/lib/components/Select/Select.js +2 -2
- package/lib/components/Slider/Slider.js +1 -1
- package/lib/components/StructuredList/StructuredList.d.ts +5 -5
- package/lib/components/StructuredList/StructuredList.js +4 -4
- package/lib/components/Tabs/Tabs.d.ts +1 -1
- package/lib/components/Tabs/Tabs.js +1 -1
- package/lib/components/Tag/DismissibleTag.js +1 -1
- package/lib/components/Tag/Tag.js +4 -4
- package/lib/components/TextArea/TextArea.js +2 -2
- package/lib/components/TextInput/ControlledPasswordInput.js +1 -1
- package/lib/components/TextInput/PasswordInput.js +1 -1
- package/lib/components/TextInput/TextInput.js +2 -2
- package/lib/components/Tile/Tile.js +9 -9
- package/lib/components/TileGroup/TileGroup.d.ts +5 -5
- package/lib/components/TimePicker/TimePicker.d.ts +8 -0
- package/lib/components/TimePicker/TimePicker.js +6 -4
- package/lib/components/Tooltip/DefinitionTooltip.d.ts +1 -1
- package/lib/components/Tooltip/DefinitionTooltip.js +1 -1
- package/lib/components/TreeView/TreeContext.d.ts +19 -0
- package/lib/components/TreeView/TreeContext.js +18 -0
- package/lib/components/TreeView/TreeNode.d.ts +4 -4
- package/lib/components/TreeView/TreeNode.js +55 -107
- package/lib/components/TreeView/TreeView.js +41 -78
- package/lib/components/UIShell/HeaderMenu.js +1 -1
- package/lib/components/UIShell/HeaderMenuItem.d.ts +1 -1
- package/lib/components/UIShell/HeaderMenuItem.js +1 -1
- package/lib/components/UIShell/HeaderName.d.ts +1 -1
- package/lib/components/UIShell/HeaderPanel.js +5 -7
- package/lib/components/UIShell/Link.d.ts +2 -2
- package/lib/components/UIShell/Link.js +1 -1
- package/lib/components/UIShell/Switcher.d.ts +1 -1
- package/lib/components/UIShell/Switcher.js +38 -11
- package/lib/index.js +1 -1
- package/lib/internal/useNoInteractiveChildren.d.ts +25 -0
- package/lib/internal/useNoInteractiveChildren.js +39 -32
- package/lib/prop-types/deprecate.d.ts +17 -0
- package/lib/prop-types/deprecate.js +22 -12
- package/package.json +3 -3
- package/telemetry.yml +15 -14
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { defineProperty as _defineProperty } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
8
|
import PropTypes from 'prop-types';
|
|
10
|
-
import {
|
|
9
|
+
import { useMemo, useState, useEffect } from 'react';
|
|
11
10
|
import isEqual from 'react-fast-compare';
|
|
12
11
|
import getDerivedStateFromProps from './state/getDerivedStateFromProps.js';
|
|
13
12
|
import { getNextSortState } from './state/sorting.js';
|
|
@@ -51,6 +50,9 @@ const translationKeys = {
|
|
|
51
50
|
unselectRow: 'carbon.table.row.unselect'
|
|
52
51
|
};
|
|
53
52
|
|
|
53
|
+
// TODO: All code comments in this file should be revisited for accuracy and
|
|
54
|
+
// clarity.
|
|
55
|
+
|
|
54
56
|
/**
|
|
55
57
|
* Message ids that will be passed to translateWithId().
|
|
56
58
|
*/
|
|
@@ -76,557 +78,544 @@ const translateWithId = id => defaultTranslations[id];
|
|
|
76
78
|
* and updating the state of the single entity will cascade updates to the
|
|
77
79
|
* consumer.
|
|
78
80
|
*/
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
sortDirection: nextSortState.sortDirection
|
|
116
|
-
})(event);
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
});
|
|
121
|
-
/**
|
|
122
|
-
* Get the props associated with the given expand header.
|
|
123
|
-
*/
|
|
124
|
-
_defineProperty(this, "getExpandHeaderProps", ({
|
|
125
|
-
onClick,
|
|
126
|
-
onExpand,
|
|
127
|
-
...rest
|
|
128
|
-
} = {}) => {
|
|
129
|
-
const {
|
|
130
|
-
translateWithId: t = translateWithId
|
|
131
|
-
} = this.props;
|
|
132
|
-
const {
|
|
133
|
-
isExpandedAll,
|
|
134
|
-
rowIds,
|
|
135
|
-
rowsById
|
|
136
|
-
} = this.state;
|
|
137
|
-
const isExpanded = isExpandedAll || rowIds.every(id => rowsById[id].isExpanded);
|
|
138
|
-
const translationKey = isExpanded ? translationKeys.collapseAll : translationKeys.expandAll;
|
|
139
|
-
return {
|
|
140
|
-
...rest,
|
|
141
|
-
'aria-label': t(translationKey),
|
|
142
|
-
// Provide a string of all the expanded row id's, separated by a space.
|
|
143
|
-
'aria-controls': rowIds.map(id => `expanded-row-${id}`).join(' '),
|
|
144
|
-
isExpanded,
|
|
145
|
-
// Compose the event handlers so we don't overwrite a consumer's `onClick`
|
|
146
|
-
// handler
|
|
147
|
-
onExpand: composeEventHandlers([this.handleOnExpandAll, onExpand, onClick && this.handleOnExpandHeaderClick(onClick, {
|
|
148
|
-
isExpanded
|
|
149
|
-
})])
|
|
150
|
-
};
|
|
151
|
-
});
|
|
152
|
-
/**
|
|
153
|
-
* Decorate consumer's `onClick` event handler with sort parameters
|
|
154
|
-
*/
|
|
155
|
-
_defineProperty(this, "handleOnHeaderClick", (onClick, sortParams) => {
|
|
156
|
-
return event => onClick(event, sortParams);
|
|
157
|
-
});
|
|
158
|
-
/**
|
|
159
|
-
* Decorate consumer's `onClick` event handler with expand parameters
|
|
160
|
-
*/
|
|
161
|
-
_defineProperty(this, "handleOnExpandHeaderClick", (onClick, expandParams) => {
|
|
162
|
-
return event => onClick(event, expandParams);
|
|
163
|
-
});
|
|
164
|
-
/**
|
|
165
|
-
* Get the props associated with the given row. Mostly used for expansion.
|
|
166
|
-
*/
|
|
167
|
-
_defineProperty(this, "getRowProps", ({
|
|
168
|
-
row,
|
|
169
|
-
onClick,
|
|
170
|
-
...rest
|
|
171
|
-
}) => {
|
|
172
|
-
const {
|
|
173
|
-
translateWithId: t = translateWithId
|
|
174
|
-
} = this.props;
|
|
175
|
-
const translationKey = row.isExpanded ? translationKeys.collapseRow : translationKeys.expandRow;
|
|
81
|
+
const DataTable = props => {
|
|
82
|
+
const {
|
|
83
|
+
children,
|
|
84
|
+
filterRows = defaultFilterRows,
|
|
85
|
+
headers,
|
|
86
|
+
render,
|
|
87
|
+
translateWithId: t = translateWithId,
|
|
88
|
+
size,
|
|
89
|
+
isSortable: isSortableProp,
|
|
90
|
+
useZebraStyles,
|
|
91
|
+
useStaticWidth,
|
|
92
|
+
stickyHeader,
|
|
93
|
+
overflowMenuOnHover,
|
|
94
|
+
experimentalAutoAlign,
|
|
95
|
+
radio,
|
|
96
|
+
rows
|
|
97
|
+
} = props;
|
|
98
|
+
const instanceId = useMemo(() => getInstanceId(), []);
|
|
99
|
+
const [state, setState] = useState(() => ({
|
|
100
|
+
...getDerivedStateFromProps(props, {}),
|
|
101
|
+
isExpandedAll: false // Start with collapsed state, treat `undefined` as neutral state
|
|
102
|
+
}));
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
const nextRowIds = rows.map(row => row.id);
|
|
105
|
+
const nextHeaders = headers.map(header => header.key);
|
|
106
|
+
const hasRowIdsChanged = !isEqual(nextRowIds, state.rowIds);
|
|
107
|
+
const currentHeaders = Object.keys(state.cellsById).reduce((acc, cellId) => {
|
|
108
|
+
const headerKey = cellId.split(':')[1];
|
|
109
|
+
if (headerKey && !acc.includes(headerKey)) {
|
|
110
|
+
acc.push(headerKey);
|
|
111
|
+
}
|
|
112
|
+
return acc;
|
|
113
|
+
}, []);
|
|
114
|
+
const hasHeadersChanged = !isEqual(nextHeaders, currentHeaders);
|
|
115
|
+
const currentRows = state.rowIds.map(id => {
|
|
116
|
+
const row = state.rowsById[id];
|
|
176
117
|
return {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
// Compose the event handlers so we don't overwrite a consumer's `onClick`
|
|
181
|
-
// handler
|
|
182
|
-
onExpand: composeEventHandlers([this.handleOnExpandRow(row.id), onClick]),
|
|
118
|
+
// TODO: Investigate whether it be okay to just return `row`.
|
|
119
|
+
id: row.id,
|
|
120
|
+
disabled: row.disabled,
|
|
183
121
|
isExpanded: row.isExpanded,
|
|
184
|
-
|
|
185
|
-
'aria-controls': `expanded-row-${row.id}`,
|
|
186
|
-
isSelected: row.isSelected,
|
|
187
|
-
disabled: row.disabled
|
|
122
|
+
isSelected: row.isSelected
|
|
188
123
|
};
|
|
189
124
|
});
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
...rest
|
|
196
|
-
}) => {
|
|
197
|
-
return {
|
|
198
|
-
...rest,
|
|
199
|
-
id: `expanded-row-${row.id}`
|
|
200
|
-
};
|
|
201
|
-
});
|
|
202
|
-
/**
|
|
203
|
-
* Gets the props associated with selection for a header or a row, where
|
|
204
|
-
* applicable. Most often used to indicate selection status of the table or
|
|
205
|
-
* for a specific row.
|
|
206
|
-
*/
|
|
207
|
-
_defineProperty(this, "getSelectionProps", ({
|
|
208
|
-
onClick,
|
|
209
|
-
row,
|
|
210
|
-
...rest
|
|
211
|
-
} = {}) => {
|
|
212
|
-
const {
|
|
213
|
-
translateWithId: t = translateWithId
|
|
214
|
-
} = this.props;
|
|
125
|
+
const hasRowsChanged = !isEqual(rows, currentRows);
|
|
126
|
+
if (hasRowIdsChanged || hasHeadersChanged || hasRowsChanged) {
|
|
127
|
+
setState(prev => getDerivedStateFromProps(props, prev));
|
|
128
|
+
}
|
|
129
|
+
}, [headers, rows]);
|
|
215
130
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
131
|
+
/**
|
|
132
|
+
* Get the props associated with the given header. Mostly used for adding in
|
|
133
|
+
* sorting behavior.
|
|
134
|
+
*/
|
|
135
|
+
const getHeaderProps = ({
|
|
136
|
+
header,
|
|
137
|
+
onClick,
|
|
138
|
+
isSortable = isSortableProp,
|
|
139
|
+
...rest
|
|
140
|
+
}) => {
|
|
141
|
+
const {
|
|
142
|
+
sortDirection,
|
|
143
|
+
sortHeaderKey
|
|
144
|
+
} = state;
|
|
145
|
+
return {
|
|
146
|
+
...rest,
|
|
147
|
+
key: header.key,
|
|
148
|
+
sortDirection,
|
|
149
|
+
isSortable,
|
|
150
|
+
isSortHeader: sortHeaderKey === header.key,
|
|
151
|
+
slug: header.slug,
|
|
152
|
+
decorator: header.decorator,
|
|
153
|
+
onClick: event => {
|
|
154
|
+
const nextSortState = getNextSortState(props, state, {
|
|
155
|
+
key: header.key
|
|
156
|
+
});
|
|
157
|
+
setState(prev => ({
|
|
158
|
+
...prev,
|
|
159
|
+
...nextSortState
|
|
160
|
+
}));
|
|
161
|
+
onClick && handleOnHeaderClick(onClick, {
|
|
162
|
+
sortHeaderKey: header.key,
|
|
163
|
+
sortDirection: nextSortState.sortDirection
|
|
164
|
+
})(event);
|
|
229
165
|
}
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get the props associated with the given expand header.
|
|
171
|
+
*/
|
|
172
|
+
const getExpandHeaderProps = ({
|
|
173
|
+
onClick,
|
|
174
|
+
onExpand,
|
|
175
|
+
...rest
|
|
176
|
+
} = {}) => {
|
|
177
|
+
const {
|
|
178
|
+
isExpandedAll,
|
|
179
|
+
rowIds,
|
|
180
|
+
rowsById
|
|
181
|
+
} = state;
|
|
182
|
+
const isExpanded = isExpandedAll || rowIds.every(id => rowsById[id].isExpanded);
|
|
183
|
+
const translationKey = isExpanded ? translationKeys.collapseAll : translationKeys.expandAll;
|
|
184
|
+
return {
|
|
185
|
+
...rest,
|
|
186
|
+
'aria-label': t(translationKey),
|
|
187
|
+
// Provide a string of all the expanded row id's, separated by a space.
|
|
188
|
+
'aria-controls': rowIds.map(id => `expanded-row-${id}`).join(' '),
|
|
189
|
+
isExpanded,
|
|
190
|
+
// Compose the event handlers so we don't overwrite a consumer's `onClick`
|
|
191
|
+
// handler
|
|
192
|
+
onExpand: composeEventHandlers([handleOnExpandAll, onExpand,
|
|
193
|
+
// TODO: Avoid passing `false` to this function.
|
|
194
|
+
onClick && handleOnExpandHeaderClick(onClick, {
|
|
195
|
+
isExpanded
|
|
196
|
+
})])
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Decorate consumer's `onClick` event handler with sort parameters
|
|
202
|
+
*/
|
|
203
|
+
const handleOnHeaderClick = (onClick, sortParams) => {
|
|
204
|
+
return event => onClick(event, sortParams);
|
|
205
|
+
};
|
|
230
206
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
207
|
+
/**
|
|
208
|
+
* Decorate consumer's `onClick` event handler with expand parameters
|
|
209
|
+
*/
|
|
210
|
+
const handleOnExpandHeaderClick = (onClick, expandParams) => {
|
|
211
|
+
return event => onClick(event, expandParams);
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Get the props associated with the given row. Mostly used for expansion.
|
|
216
|
+
*/
|
|
217
|
+
const getRowProps = ({
|
|
218
|
+
row,
|
|
219
|
+
onClick,
|
|
220
|
+
...rest
|
|
221
|
+
}) => {
|
|
222
|
+
const translationKey = row.isExpanded ? translationKeys.collapseRow : translationKeys.expandRow;
|
|
223
|
+
return {
|
|
224
|
+
...rest,
|
|
225
|
+
key: row.id,
|
|
226
|
+
onClick,
|
|
227
|
+
// Compose the event handlers so we don't overwrite a consumer's `onClick`
|
|
228
|
+
// handler
|
|
229
|
+
onExpand: composeEventHandlers([handleOnExpandRow(row.id), onClick]),
|
|
230
|
+
isExpanded: row.isExpanded,
|
|
231
|
+
'aria-label': t(translationKey),
|
|
232
|
+
'aria-controls': `expanded-row-${row.id}`,
|
|
233
|
+
isSelected: row.isSelected,
|
|
234
|
+
disabled: row.disabled
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Get the props associated with an expanded row
|
|
240
|
+
*/
|
|
241
|
+
const getExpandedRowProps = ({
|
|
242
|
+
row,
|
|
243
|
+
...rest
|
|
244
|
+
}) => {
|
|
245
|
+
return {
|
|
246
|
+
...rest,
|
|
247
|
+
id: `expanded-row-${row.id}`
|
|
248
|
+
};
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Gets the props associated with selection for a header or a row, where
|
|
253
|
+
* applicable. Most often used to indicate selection status of the table or
|
|
254
|
+
* for a specific row.
|
|
255
|
+
*/
|
|
256
|
+
const getSelectionProps = ({
|
|
257
|
+
onClick,
|
|
258
|
+
row,
|
|
259
|
+
...rest
|
|
260
|
+
} = {}) => {
|
|
261
|
+
// If we're given a row, return the selection state values for that row
|
|
262
|
+
if (row) {
|
|
263
|
+
const translationKey = row.isSelected ? translationKeys.unselectRow : translationKeys.selectRow;
|
|
238
264
|
return {
|
|
239
265
|
...rest,
|
|
266
|
+
checked: row.isSelected,
|
|
267
|
+
onSelect: composeEventHandlers([handleOnSelectRow(row.id), onClick]),
|
|
268
|
+
id: `${getTablePrefix()}__select-row-${row.id}`,
|
|
269
|
+
name: `select-row-${instanceId}`,
|
|
240
270
|
'aria-label': t(translationKey),
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
indeterminate,
|
|
244
|
-
name: `select-all-${this.instanceId}`,
|
|
245
|
-
onSelect: composeEventHandlers([this.handleSelectAll, onClick])
|
|
246
|
-
};
|
|
247
|
-
});
|
|
248
|
-
_defineProperty(this, "getToolbarProps", props => {
|
|
249
|
-
const {
|
|
250
|
-
size
|
|
251
|
-
} = this.props;
|
|
252
|
-
const isSmall = size === 'xs' || size === 'sm';
|
|
253
|
-
return {
|
|
254
|
-
...props,
|
|
255
|
-
size: isSmall ? 'sm' : undefined
|
|
256
|
-
};
|
|
257
|
-
});
|
|
258
|
-
_defineProperty(this, "getBatchActionProps", props => {
|
|
259
|
-
const {
|
|
260
|
-
shouldShowBatchActions
|
|
261
|
-
} = this.state;
|
|
262
|
-
const totalSelected = this.getSelectedRows().length;
|
|
263
|
-
return {
|
|
264
|
-
onSelectAll: undefined,
|
|
265
|
-
totalCount: this.state.rowIds.length || 0,
|
|
266
|
-
...props,
|
|
267
|
-
shouldShowBatchActions: shouldShowBatchActions && totalSelected > 0,
|
|
268
|
-
totalSelected,
|
|
269
|
-
onCancel: this.handleOnCancel
|
|
270
|
-
};
|
|
271
|
-
});
|
|
272
|
-
_defineProperty(this, "getTableProps", () => {
|
|
273
|
-
const {
|
|
274
|
-
useZebraStyles,
|
|
275
|
-
size = 'lg',
|
|
276
|
-
isSortable,
|
|
277
|
-
useStaticWidth,
|
|
278
|
-
stickyHeader,
|
|
279
|
-
overflowMenuOnHover = false,
|
|
280
|
-
experimentalAutoAlign
|
|
281
|
-
} = this.props;
|
|
282
|
-
return {
|
|
283
|
-
useZebraStyles,
|
|
284
|
-
size,
|
|
285
|
-
isSortable,
|
|
286
|
-
useStaticWidth,
|
|
287
|
-
stickyHeader,
|
|
288
|
-
overflowMenuOnHover,
|
|
289
|
-
experimentalAutoAlign
|
|
290
|
-
};
|
|
291
|
-
});
|
|
292
|
-
_defineProperty(this, "getTableContainerProps", () => {
|
|
293
|
-
const {
|
|
294
|
-
stickyHeader,
|
|
295
|
-
useStaticWidth
|
|
296
|
-
} = this.props;
|
|
297
|
-
return {
|
|
298
|
-
stickyHeader,
|
|
299
|
-
useStaticWidth
|
|
271
|
+
disabled: row.disabled,
|
|
272
|
+
radio
|
|
300
273
|
};
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
//
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Otherwise, we're working on `TableSelectAll` which handles toggling the
|
|
277
|
+
// selection state of all rows.
|
|
278
|
+
const rowCount = state.rowIds.length;
|
|
279
|
+
const selectedRowCount = getSelectedRows().length;
|
|
280
|
+
const checked = rowCount > 0 && selectedRowCount === rowCount;
|
|
281
|
+
const indeterminate = rowCount > 0 && selectedRowCount > 0 && selectedRowCount !== rowCount;
|
|
282
|
+
const translationKey = checked || indeterminate ? translationKeys.unselectAll : translationKeys.selectAll;
|
|
283
|
+
return {
|
|
284
|
+
...rest,
|
|
285
|
+
'aria-label': t(translationKey),
|
|
286
|
+
checked,
|
|
287
|
+
id: `${getTablePrefix()}__select-all`,
|
|
288
|
+
indeterminate,
|
|
289
|
+
name: `select-all-${instanceId}`,
|
|
290
|
+
onSelect: composeEventHandlers([handleSelectAll, onClick])
|
|
291
|
+
};
|
|
292
|
+
};
|
|
293
|
+
const getToolbarProps = props => {
|
|
294
|
+
const isSmall = size === 'xs' || size === 'sm';
|
|
295
|
+
return {
|
|
296
|
+
...props,
|
|
297
|
+
size: isSmall ? 'sm' : undefined
|
|
298
|
+
};
|
|
299
|
+
};
|
|
300
|
+
const getBatchActionProps = props => {
|
|
301
|
+
const {
|
|
302
|
+
shouldShowBatchActions
|
|
303
|
+
} = state;
|
|
304
|
+
const totalSelected = getSelectedRows().length;
|
|
305
|
+
return {
|
|
306
|
+
onSelectAll: undefined,
|
|
307
|
+
totalCount: state.rowIds.length || 0,
|
|
308
|
+
...props,
|
|
309
|
+
shouldShowBatchActions: shouldShowBatchActions && totalSelected > 0,
|
|
310
|
+
totalSelected,
|
|
311
|
+
onCancel: handleOnCancel
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
const getTableProps = () => {
|
|
315
|
+
return {
|
|
316
|
+
useZebraStyles,
|
|
317
|
+
size: size ?? 'lg',
|
|
318
|
+
isSortable: isSortableProp,
|
|
319
|
+
useStaticWidth,
|
|
320
|
+
stickyHeader,
|
|
321
|
+
overflowMenuOnHover: overflowMenuOnHover ?? false,
|
|
322
|
+
experimentalAutoAlign
|
|
323
|
+
};
|
|
324
|
+
};
|
|
325
|
+
const getTableContainerProps = () => {
|
|
326
|
+
return {
|
|
327
|
+
stickyHeader,
|
|
328
|
+
useStaticWidth
|
|
329
|
+
};
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
// TODO: `getHeaderProps` and `getRowProps` return `key` props. Would it be
|
|
333
|
+
// beneficial for this function to also return a `key` prop?
|
|
334
|
+
/**
|
|
335
|
+
* Get the props associated with the given table cell.
|
|
336
|
+
*/
|
|
337
|
+
const getCellProps = ({
|
|
338
|
+
cell: {
|
|
339
|
+
hasAILabelHeader,
|
|
340
|
+
hasDecoratorHeader
|
|
341
|
+
},
|
|
342
|
+
...rest
|
|
343
|
+
}) => {
|
|
344
|
+
return {
|
|
345
|
+
...rest,
|
|
346
|
+
hasAILabelHeader,
|
|
347
|
+
hasDecoratorHeader
|
|
348
|
+
};
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Helper utility to get all the currently selected rows
|
|
353
|
+
*
|
|
354
|
+
* @returns the array of rowIds that are currently selected
|
|
355
|
+
*/
|
|
356
|
+
const getSelectedRows = () => state.rowIds.filter(id => {
|
|
357
|
+
const row = state.rowsById[id];
|
|
358
|
+
return row.isSelected && !row.disabled;
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Helper utility to get all of the available rows after applying the filter
|
|
363
|
+
*
|
|
364
|
+
* @returns the array of rowIds that are currently included through the filter
|
|
365
|
+
*/
|
|
366
|
+
const getFilteredRowIds = () => {
|
|
367
|
+
const filteredRowIds = typeof state.filterInputValue === 'string' ? filterRows({
|
|
368
|
+
rowIds: state.rowIds,
|
|
369
|
+
headers: headers,
|
|
370
|
+
cellsById: state.cellsById,
|
|
371
|
+
inputValue: state.filterInputValue,
|
|
372
|
+
getCellId
|
|
373
|
+
}) : state.rowIds;
|
|
374
|
+
// TODO: Use strict equality check.
|
|
375
|
+
if (filteredRowIds.length == 0) {
|
|
376
|
+
return [];
|
|
377
|
+
}
|
|
378
|
+
return filteredRowIds;
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Helper for getting the table prefix for elements that require an
|
|
383
|
+
* `id` attribute that is unique.
|
|
384
|
+
*/
|
|
385
|
+
const getTablePrefix = () => `data-table-${instanceId}`;
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Helper for toggling all selected items in a state. Does not call
|
|
389
|
+
* setState, so use it when setting state.
|
|
390
|
+
*
|
|
391
|
+
* @returns object to put into this.setState (use spread operator)
|
|
392
|
+
*/
|
|
393
|
+
const setAllSelectedState = (initialState, isSelected, filteredRowIds) => {
|
|
394
|
+
const {
|
|
395
|
+
rowIds
|
|
396
|
+
} = initialState;
|
|
397
|
+
// TODO: Use strict inequality check.
|
|
398
|
+
const isFiltered = rowIds.length != filteredRowIds.length;
|
|
399
|
+
return {
|
|
400
|
+
// TODO: Should the `reduce` be typed with `<Record<string,
|
|
401
|
+
// DataTableRow<ColTypes>>>`?
|
|
402
|
+
rowsById: rowIds.reduce((acc, id) => {
|
|
403
|
+
const row = {
|
|
404
|
+
...initialState.rowsById[id]
|
|
405
|
+
};
|
|
406
|
+
if (!row.disabled && (!isFiltered || filteredRowIds.includes(id))) {
|
|
407
|
+
row.isSelected = isSelected;
|
|
408
|
+
}
|
|
409
|
+
acc[id] = row; // Local mutation for performance with large tables
|
|
410
|
+
return acc;
|
|
411
|
+
}, {})
|
|
412
|
+
};
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Handler for the `onCancel` event to hide the batch action bar and
|
|
417
|
+
* deselect all selected rows
|
|
418
|
+
*/
|
|
419
|
+
const handleOnCancel = () => {
|
|
420
|
+
setState(prev => {
|
|
314
421
|
return {
|
|
315
|
-
...
|
|
316
|
-
|
|
317
|
-
|
|
422
|
+
...prev,
|
|
423
|
+
shouldShowBatchActions: false,
|
|
424
|
+
...setAllSelectedState(prev, false, getFilteredRowIds())
|
|
318
425
|
};
|
|
319
426
|
});
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}));
|
|
329
|
-
/**
|
|
330
|
-
* Helper utility to get all of the available rows after applying the filter
|
|
331
|
-
*
|
|
332
|
-
* @returns the array of rowIds that are currently included through the filter
|
|
333
|
-
*/
|
|
334
|
-
_defineProperty(this, "getFilteredRowIds", () => {
|
|
335
|
-
const {
|
|
336
|
-
filterRows = defaultFilterRows
|
|
337
|
-
} = this.props;
|
|
338
|
-
const filteredRowIds = typeof this.state.filterInputValue === 'string' ? filterRows({
|
|
339
|
-
rowIds: this.state.rowIds,
|
|
340
|
-
headers: this.props.headers,
|
|
341
|
-
cellsById: this.state.cellsById,
|
|
342
|
-
inputValue: this.state.filterInputValue,
|
|
343
|
-
getCellId
|
|
344
|
-
}) : this.state.rowIds;
|
|
345
|
-
if (filteredRowIds.length == 0) {
|
|
346
|
-
return [];
|
|
347
|
-
}
|
|
348
|
-
return filteredRowIds;
|
|
349
|
-
});
|
|
350
|
-
/**
|
|
351
|
-
* Helper for getting the table prefix for elements that require an
|
|
352
|
-
* `id` attribute that is unique.
|
|
353
|
-
*/
|
|
354
|
-
_defineProperty(this, "getTablePrefix", () => `data-table-${this.instanceId}`);
|
|
355
|
-
/**
|
|
356
|
-
* Helper for toggling all selected items in a state. Does not call
|
|
357
|
-
* setState, so use it when setting state.
|
|
358
|
-
*
|
|
359
|
-
* @returns object to put into this.setState (use spread operator)
|
|
360
|
-
*/
|
|
361
|
-
_defineProperty(this, "setAllSelectedState", (initialState, isSelected, filteredRowIds) => {
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Handler for toggling the selection state of all rows in the database
|
|
431
|
+
*/
|
|
432
|
+
const handleSelectAll = () => {
|
|
433
|
+
setState(prev => {
|
|
434
|
+
const filteredRowIds = getFilteredRowIds();
|
|
362
435
|
const {
|
|
363
|
-
|
|
364
|
-
} =
|
|
365
|
-
const
|
|
436
|
+
rowsById
|
|
437
|
+
} = prev;
|
|
438
|
+
const isSelected = !(Object.values(rowsById).filter(row => row.isSelected && !row.disabled).length > 0);
|
|
366
439
|
return {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
};
|
|
371
|
-
if (!row.disabled && (!isFiltered || filteredRowIds.includes(id))) {
|
|
372
|
-
row.isSelected = isSelected;
|
|
373
|
-
}
|
|
374
|
-
acc[id] = row; // Local mutation for performance with large tables
|
|
375
|
-
return acc;
|
|
376
|
-
}, {})
|
|
440
|
+
...prev,
|
|
441
|
+
shouldShowBatchActions: isSelected,
|
|
442
|
+
...setAllSelectedState(prev, isSelected, filteredRowIds)
|
|
377
443
|
};
|
|
378
444
|
});
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Handler for toggling the selection state of a given row.
|
|
449
|
+
*/
|
|
450
|
+
const handleOnSelectRow = rowId => () => {
|
|
451
|
+
setState(prev => {
|
|
452
|
+
const row = prev.rowsById[rowId];
|
|
453
|
+
if (radio) {
|
|
454
|
+
// TODO:
|
|
455
|
+
// 1. Should the `reduce` be typed with `<Record<string,
|
|
456
|
+
// DataTableRow<ColTypes>>>`?
|
|
457
|
+
// 2. Add better parameter names. Use `acc` and `row`.
|
|
458
|
+
//
|
|
459
|
+
// deselect all radio buttons
|
|
460
|
+
const rowsById = Object.entries(prev.rowsById).reduce((p, c) => {
|
|
461
|
+
const [key, val] = c;
|
|
462
|
+
val.isSelected = false;
|
|
463
|
+
p[key] = val;
|
|
464
|
+
return p;
|
|
465
|
+
}, {});
|
|
385
466
|
return {
|
|
467
|
+
...prev,
|
|
386
468
|
shouldShowBatchActions: false,
|
|
387
|
-
...this.setAllSelectedState(state, false, this.getFilteredRowIds())
|
|
388
|
-
};
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
/**
|
|
392
|
-
* Handler for toggling the selection state of all rows in the database
|
|
393
|
-
*/
|
|
394
|
-
_defineProperty(this, "handleSelectAll", () => {
|
|
395
|
-
this.setState(state => {
|
|
396
|
-
const filteredRowIds = this.getFilteredRowIds();
|
|
397
|
-
const {
|
|
398
|
-
rowsById
|
|
399
|
-
} = state;
|
|
400
|
-
const isSelected = !(Object.values(rowsById).filter(row => row.isSelected && !row.disabled).length > 0);
|
|
401
|
-
return {
|
|
402
|
-
shouldShowBatchActions: isSelected,
|
|
403
|
-
...this.setAllSelectedState(state, isSelected, filteredRowIds)
|
|
404
|
-
};
|
|
405
|
-
});
|
|
406
|
-
});
|
|
407
|
-
/**
|
|
408
|
-
* Handler for toggling the selection state of a given row.
|
|
409
|
-
*/
|
|
410
|
-
_defineProperty(this, "handleOnSelectRow", rowId => () => {
|
|
411
|
-
this.setState(state => {
|
|
412
|
-
const row = state.rowsById[rowId];
|
|
413
|
-
if (this.props.radio) {
|
|
414
|
-
// deselect all radio buttons
|
|
415
|
-
const rowsById = Object.entries(state.rowsById).reduce((p, c) => {
|
|
416
|
-
const [key, val] = c;
|
|
417
|
-
val.isSelected = false;
|
|
418
|
-
p[key] = val;
|
|
419
|
-
return p;
|
|
420
|
-
}, {});
|
|
421
|
-
return {
|
|
422
|
-
shouldShowBatchActions: false,
|
|
423
|
-
rowsById: {
|
|
424
|
-
...rowsById,
|
|
425
|
-
[rowId]: {
|
|
426
|
-
...row,
|
|
427
|
-
isSelected: !row.isSelected
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
const selectedRows = state.rowIds.filter(id => state.rowsById[id].isSelected).length;
|
|
433
|
-
// Predict the length of the selected rows after this change occurs
|
|
434
|
-
const selectedRowsCount = !row.isSelected ? selectedRows + 1 : selectedRows - 1;
|
|
435
|
-
return {
|
|
436
|
-
// Basic assumption here is that we want to show the batch action bar if
|
|
437
|
-
// the row is being selected. If it's being unselected, then see if we
|
|
438
|
-
// have a non-zero number of selected rows that batch actions could
|
|
439
|
-
// still apply to
|
|
440
|
-
shouldShowBatchActions: !row.isSelected || selectedRowsCount > 0,
|
|
441
469
|
rowsById: {
|
|
442
|
-
...
|
|
470
|
+
...rowsById,
|
|
443
471
|
[rowId]: {
|
|
444
472
|
...row,
|
|
445
473
|
isSelected: !row.isSelected
|
|
446
474
|
}
|
|
447
475
|
}
|
|
448
476
|
};
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
...
|
|
464
|
-
|
|
465
|
-
...row,
|
|
466
|
-
isExpanded: !row.isExpanded
|
|
467
|
-
}
|
|
477
|
+
}
|
|
478
|
+
const selectedRows = prev.rowIds.filter(id => prev.rowsById[id].isSelected).length;
|
|
479
|
+
// Predict the length of the selected rows after this change occurs
|
|
480
|
+
const selectedRowsCount = !row.isSelected ? selectedRows + 1 : selectedRows - 1;
|
|
481
|
+
return {
|
|
482
|
+
...prev,
|
|
483
|
+
// Basic assumption here is that we want to show the batch action bar if
|
|
484
|
+
// the row is being selected. If it's being unselected, then see if we
|
|
485
|
+
// have a non-zero number of selected rows that batch actions could
|
|
486
|
+
// still apply to
|
|
487
|
+
shouldShowBatchActions: !row.isSelected || selectedRowsCount > 0,
|
|
488
|
+
rowsById: {
|
|
489
|
+
...prev.rowsById,
|
|
490
|
+
[rowId]: {
|
|
491
|
+
...row,
|
|
492
|
+
isSelected: !row.isSelected
|
|
468
493
|
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
});
|
|
472
|
-
/**
|
|
473
|
-
* Handler for changing the expansion state of all rows.
|
|
474
|
-
*/
|
|
475
|
-
_defineProperty(this, "handleOnExpandAll", () => {
|
|
476
|
-
this.setState(state => {
|
|
477
|
-
const {
|
|
478
|
-
rowIds,
|
|
479
|
-
isExpandedAll
|
|
480
|
-
} = state;
|
|
481
|
-
return {
|
|
482
|
-
isExpandedAll: !isExpandedAll,
|
|
483
|
-
rowsById: rowIds.reduce((acc, id) => ({
|
|
484
|
-
...acc,
|
|
485
|
-
[id]: {
|
|
486
|
-
...state.rowsById[id],
|
|
487
|
-
isExpanded: !isExpandedAll
|
|
488
|
-
}
|
|
489
|
-
}), {})
|
|
490
|
-
};
|
|
491
|
-
});
|
|
494
|
+
}
|
|
495
|
+
};
|
|
492
496
|
});
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Handler for toggling the expansion state of a given row.
|
|
501
|
+
*/
|
|
502
|
+
const handleOnExpandRow = rowId => () => {
|
|
503
|
+
setState(prev => {
|
|
504
|
+
const row = prev.rowsById[rowId];
|
|
505
|
+
const {
|
|
506
|
+
isExpandedAll
|
|
507
|
+
} = prev;
|
|
508
|
+
return {
|
|
509
|
+
...prev,
|
|
510
|
+
isExpandedAll: row.isExpanded ? false : isExpandedAll,
|
|
511
|
+
rowsById: {
|
|
512
|
+
...prev.rowsById,
|
|
513
|
+
[rowId]: {
|
|
514
|
+
...row,
|
|
515
|
+
isExpanded: !row.isExpanded
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
};
|
|
502
519
|
});
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Handler for changing the expansion state of all rows.
|
|
524
|
+
*/
|
|
525
|
+
const handleOnExpandAll = () => {
|
|
526
|
+
setState(prev => {
|
|
527
|
+
const {
|
|
528
|
+
rowIds,
|
|
529
|
+
isExpandedAll
|
|
530
|
+
} = prev;
|
|
531
|
+
return {
|
|
532
|
+
...prev,
|
|
533
|
+
isExpandedAll: !isExpandedAll,
|
|
534
|
+
// TODO: Add generic to `reduce`.
|
|
535
|
+
rowsById: rowIds.reduce((acc, id) => ({
|
|
536
|
+
...acc,
|
|
537
|
+
[id]: {
|
|
538
|
+
...prev.rowsById[id],
|
|
539
|
+
isExpanded: !isExpandedAll
|
|
540
|
+
}
|
|
541
|
+
}), {})
|
|
542
|
+
};
|
|
518
543
|
});
|
|
519
|
-
|
|
520
|
-
...getDerivedStateFromProps(_props, {}),
|
|
521
|
-
isExpandedAll: false // Start with collapsed state, treat `undefined` as neutral state
|
|
522
|
-
};
|
|
523
|
-
this.instanceId = getInstanceId();
|
|
524
|
-
}
|
|
544
|
+
};
|
|
525
545
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
}
|
|
548
|
-
render() {
|
|
549
|
-
const {
|
|
550
|
-
children,
|
|
551
|
-
filterRows = defaultFilterRows,
|
|
552
|
-
headers,
|
|
553
|
-
render
|
|
554
|
-
} = this.props;
|
|
555
|
-
const {
|
|
556
|
-
filterInputValue,
|
|
557
|
-
rowIds,
|
|
558
|
-
rowsById,
|
|
559
|
-
cellsById
|
|
560
|
-
} = this.state;
|
|
561
|
-
const filteredRowIds = typeof filterInputValue === 'string' ? filterRows({
|
|
562
|
-
rowIds,
|
|
563
|
-
headers,
|
|
564
|
-
cellsById,
|
|
565
|
-
inputValue: filterInputValue,
|
|
566
|
-
getCellId
|
|
567
|
-
}) : rowIds;
|
|
568
|
-
const renderProps = {
|
|
569
|
-
// Data derived from state
|
|
570
|
-
rows: denormalize(filteredRowIds, rowsById, cellsById),
|
|
571
|
-
headers: this.props.headers,
|
|
572
|
-
selectedRows: denormalize(this.getSelectedRows(), rowsById, cellsById),
|
|
573
|
-
// Prop accessors/getters
|
|
574
|
-
getHeaderProps: this.getHeaderProps,
|
|
575
|
-
getExpandHeaderProps: this.getExpandHeaderProps,
|
|
576
|
-
getRowProps: this.getRowProps,
|
|
577
|
-
getExpandedRowProps: this.getExpandedRowProps,
|
|
578
|
-
getSelectionProps: this.getSelectionProps,
|
|
579
|
-
getToolbarProps: this.getToolbarProps,
|
|
580
|
-
getBatchActionProps: this.getBatchActionProps,
|
|
581
|
-
getTableProps: this.getTableProps,
|
|
582
|
-
getTableContainerProps: this.getTableContainerProps,
|
|
583
|
-
getCellProps: this.getCellProps,
|
|
584
|
-
// Custom event handlers
|
|
585
|
-
onInputChange: this.handleOnInputValueChange,
|
|
586
|
-
// Expose internal state change actions
|
|
587
|
-
sortBy: headerKey => this.handleSortBy(headerKey)(),
|
|
588
|
-
selectAll: this.handleSelectAll,
|
|
589
|
-
selectRow: rowId => this.handleOnSelectRow(rowId)(),
|
|
590
|
-
expandRow: rowId => this.handleOnExpandRow(rowId)(),
|
|
591
|
-
expandAll: this.handleOnExpandAll,
|
|
592
|
-
radio: this.props.radio
|
|
593
|
-
};
|
|
594
|
-
if (typeof render !== 'undefined') {
|
|
595
|
-
return render(renderProps);
|
|
546
|
+
/**
|
|
547
|
+
* Handler for transitioning to the next sort state of the table
|
|
548
|
+
*
|
|
549
|
+
* @param headerKey - The field for the header that we are sorting by.
|
|
550
|
+
*/
|
|
551
|
+
const handleSortBy = headerKey => () => {
|
|
552
|
+
setState(prev => getNextSortState(props, prev, {
|
|
553
|
+
key: headerKey
|
|
554
|
+
}));
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Event handler for transitioning input value state changes for the table
|
|
559
|
+
* filter component.
|
|
560
|
+
*/
|
|
561
|
+
const handleOnInputValueChange = (event, defaultValue) => {
|
|
562
|
+
if (event.target) {
|
|
563
|
+
setState(prev => ({
|
|
564
|
+
...prev,
|
|
565
|
+
filterInputValue: event.target.value
|
|
566
|
+
}));
|
|
596
567
|
}
|
|
597
|
-
if (
|
|
598
|
-
|
|
568
|
+
if (defaultValue) {
|
|
569
|
+
setState(prev => ({
|
|
570
|
+
...prev,
|
|
571
|
+
filterInputValue: defaultValue
|
|
572
|
+
}));
|
|
599
573
|
}
|
|
600
|
-
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
// TODO: Could getFilteredRowIds be used here?
|
|
577
|
+
const filteredRowIds = typeof state.filterInputValue === 'string' ? filterRows({
|
|
578
|
+
rowIds: state.rowIds,
|
|
579
|
+
headers,
|
|
580
|
+
cellsById: state.cellsById,
|
|
581
|
+
inputValue: state.filterInputValue,
|
|
582
|
+
getCellId
|
|
583
|
+
}) : state.rowIds;
|
|
584
|
+
const renderProps = {
|
|
585
|
+
// Data derived from state
|
|
586
|
+
rows: denormalize(filteredRowIds, state.rowsById, state.cellsById),
|
|
587
|
+
headers: headers,
|
|
588
|
+
selectedRows: denormalize(getSelectedRows(), state.rowsById, state.cellsById),
|
|
589
|
+
// Prop accessors/getters
|
|
590
|
+
getHeaderProps,
|
|
591
|
+
getExpandHeaderProps,
|
|
592
|
+
getRowProps,
|
|
593
|
+
getExpandedRowProps,
|
|
594
|
+
getSelectionProps,
|
|
595
|
+
getToolbarProps,
|
|
596
|
+
getBatchActionProps,
|
|
597
|
+
getTableProps,
|
|
598
|
+
getTableContainerProps,
|
|
599
|
+
getCellProps,
|
|
600
|
+
// Custom event handlers
|
|
601
|
+
onInputChange: handleOnInputValueChange,
|
|
602
|
+
// Expose internal state change actions
|
|
603
|
+
sortBy: headerKey => handleSortBy(headerKey)(),
|
|
604
|
+
selectAll: handleSelectAll,
|
|
605
|
+
selectRow: rowId => handleOnSelectRow(rowId)(),
|
|
606
|
+
expandRow: rowId => handleOnExpandRow(rowId)(),
|
|
607
|
+
expandAll: handleOnExpandAll,
|
|
608
|
+
radio: radio
|
|
609
|
+
};
|
|
610
|
+
if (typeof render !== 'undefined') {
|
|
611
|
+
return render(renderProps);
|
|
612
|
+
}
|
|
613
|
+
if (typeof children !== 'undefined') {
|
|
614
|
+
return children(renderProps);
|
|
601
615
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
// functional component.
|
|
606
|
-
//
|
|
607
|
-
// Static properties for sub-components
|
|
608
|
-
_defineProperty(DataTable, "Table", void 0);
|
|
609
|
-
_defineProperty(DataTable, "TableActionList", void 0);
|
|
610
|
-
_defineProperty(DataTable, "TableBatchAction", void 0);
|
|
611
|
-
_defineProperty(DataTable, "TableBatchActions", void 0);
|
|
612
|
-
_defineProperty(DataTable, "TableBody", void 0);
|
|
613
|
-
_defineProperty(DataTable, "TableCell", void 0);
|
|
614
|
-
_defineProperty(DataTable, "TableContainer", void 0);
|
|
615
|
-
_defineProperty(DataTable, "TableDecoratorRow", void 0);
|
|
616
|
-
_defineProperty(DataTable, "TableExpandHeader", void 0);
|
|
617
|
-
_defineProperty(DataTable, "TableExpandRow", void 0);
|
|
618
|
-
_defineProperty(DataTable, "TableExpandedRow", void 0);
|
|
619
|
-
_defineProperty(DataTable, "TableHead", void 0);
|
|
620
|
-
_defineProperty(DataTable, "TableHeader", void 0);
|
|
621
|
-
_defineProperty(DataTable, "TableRow", void 0);
|
|
622
|
-
_defineProperty(DataTable, "TableSelectAll", void 0);
|
|
623
|
-
_defineProperty(DataTable, "TableSelectRow", void 0);
|
|
624
|
-
_defineProperty(DataTable, "TableSlugRow", void 0);
|
|
625
|
-
_defineProperty(DataTable, "TableToolbar", void 0);
|
|
626
|
-
_defineProperty(DataTable, "TableToolbarAction", void 0);
|
|
627
|
-
_defineProperty(DataTable, "TableToolbarContent", void 0);
|
|
628
|
-
_defineProperty(DataTable, "TableToolbarSearch", void 0);
|
|
629
|
-
_defineProperty(DataTable, "TableToolbarMenu", void 0);
|
|
616
|
+
return null;
|
|
617
|
+
};
|
|
618
|
+
DataTable.translationKeys = Object.values(translationKeys);
|
|
630
619
|
DataTable.Table = Table;
|
|
631
620
|
DataTable.TableActionList = TableActionList;
|
|
632
621
|
DataTable.TableBatchAction = TableBatchAction;
|
|
@@ -726,4 +715,4 @@ DataTable.propTypes = {
|
|
|
726
715
|
useZebraStyles: PropTypes.bool
|
|
727
716
|
};
|
|
728
717
|
|
|
729
|
-
export { DataTable
|
|
718
|
+
export { DataTable };
|