@carbon/react 1.90.0 → 1.91.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 +986 -926
- package/es/components/Breadcrumb/Breadcrumb.Skeleton.d.ts +27 -2
- package/es/components/Breadcrumb/Breadcrumb.Skeleton.js +27 -4
- package/es/components/Breadcrumb/Breadcrumb.js +2 -1
- package/es/components/CodeSnippet/CodeSnippet.d.ts +1 -1
- package/es/components/CodeSnippet/CodeSnippet.js +1 -1
- package/es/components/ComboBox/ComboBox.js +1 -12
- package/es/components/ComboButton/index.js +1 -1
- package/es/components/ComposedModal/ComposedModal.js +1 -1
- package/es/components/ContentSwitcher/ContentSwitcher.js +2 -2
- package/es/components/Copy/Copy.d.ts +1 -1
- package/es/components/Copy/Copy.js +1 -1
- package/es/components/CopyButton/CopyButton.d.ts +1 -1
- package/es/components/CopyButton/CopyButton.js +1 -1
- package/es/components/DataTable/DataTable.d.ts +60 -15
- package/es/components/DataTable/DataTable.js +106 -179
- package/es/components/DataTable/Table.d.ts +2 -2
- package/es/components/DataTable/Table.js +1 -1
- package/es/components/DataTable/TableExpandHeader.d.ts +1 -1
- package/es/components/DataTable/TableExpandHeader.js +1 -1
- package/es/components/DatePicker/DatePicker.d.ts +0 -12
- package/es/components/DatePicker/DatePicker.js +3 -3
- package/es/components/DatePicker/plugins/rangePlugin.d.ts +19 -2
- package/es/components/DatePicker/plugins/rangePlugin.js +18 -14
- package/es/components/Dropdown/Dropdown.js +1 -12
- package/es/components/FeatureFlags/index.js +1 -0
- package/es/components/IconButton/index.js +1 -1
- package/es/components/Menu/MenuItem.d.ts +1 -1
- package/es/components/Menu/MenuItem.js +5 -5
- package/es/components/Modal/Modal.js +1 -1
- package/es/components/MultiSelect/FilterableMultiSelect.js +1 -1
- package/es/components/MultiSelect/MultiSelect.js +1 -12
- package/es/components/Notification/Notification.d.ts +6 -6
- package/es/components/Notification/Notification.js +6 -6
- package/es/components/OverflowMenu/OverflowMenu.js +1 -1
- package/es/components/OverflowMenu/next/index.js +1 -1
- package/es/components/PaginationNav/PaginationNav.d.ts +20 -0
- package/es/components/PaginationNav/PaginationNav.js +34 -5
- package/es/components/Popover/index.js +1 -1
- package/es/components/Search/Search.d.ts +4 -2
- package/es/components/Search/Search.js +5 -4
- package/es/components/Slider/Slider.d.ts +144 -188
- package/es/components/Slider/Slider.js +787 -710
- package/es/components/Slider/index.d.ts +2 -2
- package/es/components/Tabs/Tabs.d.ts +4 -0
- package/es/components/TextArea/TextArea.js +13 -6
- package/es/components/TextInput/ControlledPasswordInput.js +2 -2
- package/es/components/TextInput/PasswordInput.js +2 -2
- package/es/components/TextInput/TextInput.js +2 -2
- package/es/components/TextInput/util.d.ts +17 -5
- package/es/components/TextInput/util.js +2 -7
- package/es/components/UIShell/HeaderPanel.d.ts +1 -1
- package/es/index.d.ts +27 -24
- package/es/index.js +43 -41
- package/es/internal/defaultItemToString.d.ts +7 -0
- package/es/internal/defaultItemToString.js +17 -0
- package/es/internal/index.d.ts +1 -0
- package/es/prop-types/deprecateValuesWithin.d.ts +8 -1
- package/es/prop-types/deprecateValuesWithin.js +6 -6
- package/es/prop-types/requiredIfGivenPropIsTruthy.d.ts +8 -7
- package/es/prop-types/requiredIfGivenPropIsTruthy.js +10 -10
- package/lib/components/Breadcrumb/Breadcrumb.Skeleton.d.ts +27 -2
- package/lib/components/Breadcrumb/Breadcrumb.Skeleton.js +27 -4
- package/lib/components/Breadcrumb/Breadcrumb.js +2 -1
- package/lib/components/CodeSnippet/CodeSnippet.d.ts +1 -1
- package/lib/components/CodeSnippet/CodeSnippet.js +1 -1
- package/lib/components/ComboBox/ComboBox.js +3 -14
- package/lib/components/ComboButton/index.js +1 -1
- package/lib/components/ComposedModal/ComposedModal.js +1 -1
- package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -1
- package/lib/components/Copy/Copy.d.ts +1 -1
- package/lib/components/Copy/Copy.js +1 -1
- package/lib/components/CopyButton/CopyButton.d.ts +1 -1
- package/lib/components/CopyButton/CopyButton.js +1 -1
- package/lib/components/DataTable/DataTable.d.ts +60 -15
- package/lib/components/DataTable/DataTable.js +106 -179
- package/lib/components/DataTable/Table.d.ts +2 -2
- package/lib/components/DataTable/Table.js +1 -1
- package/lib/components/DataTable/TableExpandHeader.d.ts +1 -1
- package/lib/components/DataTable/TableExpandHeader.js +3 -3
- package/lib/components/DatePicker/DatePicker.d.ts +0 -12
- package/lib/components/DatePicker/DatePicker.js +2 -2
- package/lib/components/DatePicker/plugins/rangePlugin.d.ts +19 -2
- package/lib/components/DatePicker/plugins/rangePlugin.js +18 -16
- package/lib/components/Dropdown/Dropdown.js +3 -14
- package/lib/components/FeatureFlags/index.js +1 -0
- package/lib/components/IconButton/index.js +1 -1
- package/lib/components/Menu/MenuItem.d.ts +1 -1
- package/lib/components/Menu/MenuItem.js +6 -6
- package/lib/components/Modal/Modal.js +1 -1
- package/lib/components/MultiSelect/FilterableMultiSelect.js +8 -8
- package/lib/components/MultiSelect/MultiSelect.js +2 -13
- package/lib/components/Notification/Notification.d.ts +6 -6
- package/lib/components/Notification/Notification.js +6 -6
- package/lib/components/OverflowMenu/OverflowMenu.js +1 -1
- package/lib/components/OverflowMenu/next/index.js +1 -1
- package/lib/components/PaginationNav/PaginationNav.d.ts +20 -0
- package/lib/components/PaginationNav/PaginationNav.js +34 -5
- package/lib/components/Popover/index.js +1 -1
- package/lib/components/Search/Search.d.ts +4 -2
- package/lib/components/Search/Search.js +5 -4
- package/lib/components/Slider/Slider.d.ts +144 -188
- package/lib/components/Slider/Slider.js +784 -709
- package/lib/components/Slider/index.d.ts +2 -2
- package/lib/components/Tabs/Tabs.d.ts +4 -0
- package/lib/components/TextArea/TextArea.js +13 -6
- package/lib/components/TextInput/ControlledPasswordInput.js +1 -1
- package/lib/components/TextInput/PasswordInput.js +1 -1
- package/lib/components/TextInput/TextInput.js +1 -1
- package/lib/components/TextInput/util.d.ts +17 -5
- package/lib/components/TextInput/util.js +2 -7
- package/lib/components/UIShell/HeaderPanel.d.ts +1 -1
- package/lib/index.d.ts +27 -24
- package/lib/index.js +95 -28
- package/lib/internal/defaultItemToString.d.ts +7 -0
- package/lib/internal/defaultItemToString.js +19 -0
- package/lib/internal/index.d.ts +1 -0
- package/lib/prop-types/deprecateValuesWithin.d.ts +8 -1
- package/lib/prop-types/deprecateValuesWithin.js +6 -8
- package/lib/prop-types/requiredIfGivenPropIsTruthy.d.ts +8 -7
- package/lib/prop-types/requiredIfGivenPropIsTruthy.js +10 -12
- package/package.json +8 -7
- package/telemetry.yml +1 -2
- package/es/components/MultiSelect/tools/itemToString.d.ts +0 -1
- package/es/components/MultiSelect/tools/itemToString.js +0 -21
- package/es/components/Slider/index.js +0 -14
- package/es/internal/createClassWrapper.js +0 -23
- package/lib/components/MultiSelect/tools/itemToString.d.ts +0 -1
- package/lib/components/MultiSelect/tools/itemToString.js +0 -23
- package/lib/components/Slider/index.js +0 -20
- package/lib/internal/createClassWrapper.js +0 -25
|
@@ -37,6 +37,7 @@ import TableToolbarAction from './TableToolbarAction.js';
|
|
|
37
37
|
import TableToolbarContent from './TableToolbarContent.js';
|
|
38
38
|
import TableToolbarSearch from './TableToolbarSearch.js';
|
|
39
39
|
import TableToolbarMenu from './TableToolbarMenu.js';
|
|
40
|
+
import { deprecate } from '../../prop-types/deprecate.js';
|
|
40
41
|
|
|
41
42
|
const getInstanceId = setupGetInstanceId();
|
|
42
43
|
const translationKeys = {
|
|
@@ -50,11 +51,8 @@ const translationKeys = {
|
|
|
50
51
|
unselectRow: 'carbon.table.row.unselect'
|
|
51
52
|
};
|
|
52
53
|
|
|
53
|
-
// TODO: All code comments in this file should be revisited for accuracy and
|
|
54
|
-
// clarity.
|
|
55
|
-
|
|
56
54
|
/**
|
|
57
|
-
* Message
|
|
55
|
+
* Message IDs that will be passed to translateWithId().
|
|
58
56
|
*/
|
|
59
57
|
|
|
60
58
|
const defaultTranslations = {
|
|
@@ -80,14 +78,12 @@ const translateWithId = id => defaultTranslations[id];
|
|
|
80
78
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20071
|
|
81
79
|
|
|
82
80
|
/**
|
|
83
|
-
*
|
|
84
|
-
* subset of their fields in columns, or headers. We prioritize
|
|
85
|
-
* to the state of what we're rendering, so internally we
|
|
86
|
-
* given data and then
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* and updating the state of the single entity will cascade updates to the
|
|
90
|
-
* consumer.
|
|
81
|
+
* DataTable components are used to represent a collection of resources,
|
|
82
|
+
* displaying a subset of their fields in columns, or headers. We prioritize
|
|
83
|
+
* direct updates to the state of what we're rendering, so internally we
|
|
84
|
+
* normalize the given data and then denormalize it at render time. Each part of
|
|
85
|
+
* the DataTable is accessible through look-up by ID, and updating the state of
|
|
86
|
+
* a single entity cascades updates to the consumer.
|
|
91
87
|
*/
|
|
92
88
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20071
|
|
93
89
|
const DataTable = props => {
|
|
@@ -110,24 +106,18 @@ const DataTable = props => {
|
|
|
110
106
|
const instanceId = useMemo(() => getInstanceId(), []);
|
|
111
107
|
const [state, setState] = useState(() => ({
|
|
112
108
|
...getDerivedStateFromProps(props, {}),
|
|
113
|
-
|
|
109
|
+
// Initialize to collapsed. A value of `undefined` is treated as neutral.
|
|
110
|
+
isExpandedAll: false
|
|
114
111
|
}));
|
|
115
112
|
useEffect(() => {
|
|
116
113
|
const nextRowIds = rows.map(row => row.id);
|
|
117
114
|
const nextHeaders = headers.map(header => header.key);
|
|
118
115
|
const hasRowIdsChanged = !isEqual(nextRowIds, state.rowIds);
|
|
119
|
-
const currentHeaders = Object.keys(state.cellsById).
|
|
120
|
-
const headerKey = cellId.split(':')[1];
|
|
121
|
-
if (headerKey && !acc.includes(headerKey)) {
|
|
122
|
-
acc.push(headerKey);
|
|
123
|
-
}
|
|
124
|
-
return acc;
|
|
125
|
-
}, []);
|
|
116
|
+
const currentHeaders = Array.from(new Set(Object.keys(state.cellsById).map(id => id.split(':')[1])));
|
|
126
117
|
const hasHeadersChanged = !isEqual(nextHeaders, currentHeaders);
|
|
127
118
|
const currentRows = state.rowIds.map(id => {
|
|
128
119
|
const row = state.rowsById[id];
|
|
129
120
|
return {
|
|
130
|
-
// TODO: Investigate whether it be okay to just return `row`.
|
|
131
121
|
id: row.id,
|
|
132
122
|
disabled: row.disabled,
|
|
133
123
|
isExpanded: row.isExpanded,
|
|
@@ -140,11 +130,6 @@ const DataTable = props => {
|
|
|
140
130
|
}
|
|
141
131
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- https://github.com/carbon-design-system/carbon/issues/20071
|
|
142
132
|
}, [headers, rows]);
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Get the props associated with the given header. Mostly used for adding in
|
|
146
|
-
* sorting behavior.
|
|
147
|
-
*/
|
|
148
133
|
const getHeaderProps = ({
|
|
149
134
|
header,
|
|
150
135
|
onClick,
|
|
@@ -155,34 +140,36 @@ const DataTable = props => {
|
|
|
155
140
|
sortDirection,
|
|
156
141
|
sortHeaderKey
|
|
157
142
|
} = state;
|
|
143
|
+
const {
|
|
144
|
+
key,
|
|
145
|
+
slug,
|
|
146
|
+
decorator
|
|
147
|
+
} = header;
|
|
158
148
|
return {
|
|
159
149
|
...rest,
|
|
160
|
-
key
|
|
150
|
+
key,
|
|
161
151
|
sortDirection,
|
|
162
152
|
isSortable,
|
|
163
|
-
isSortHeader: sortHeaderKey ===
|
|
164
|
-
slug
|
|
165
|
-
decorator
|
|
153
|
+
isSortHeader: sortHeaderKey === key,
|
|
154
|
+
slug,
|
|
155
|
+
decorator,
|
|
166
156
|
onClick: event => {
|
|
167
157
|
const nextSortState = getNextSortState(props, state, {
|
|
168
|
-
key
|
|
158
|
+
key
|
|
169
159
|
});
|
|
170
160
|
setState(prev => ({
|
|
171
161
|
...prev,
|
|
172
162
|
...nextSortState
|
|
173
163
|
}));
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
164
|
+
if (onClick) {
|
|
165
|
+
handleOnHeaderClick(onClick, {
|
|
166
|
+
sortHeaderKey: key,
|
|
167
|
+
sortDirection: nextSortState.sortDirection
|
|
168
|
+
})(event);
|
|
169
|
+
}
|
|
179
170
|
}
|
|
180
171
|
};
|
|
181
172
|
};
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Get the props associated with the given expand header.
|
|
185
|
-
*/
|
|
186
173
|
const getExpandHeaderProps = ({
|
|
187
174
|
onClick,
|
|
188
175
|
onExpand,
|
|
@@ -195,39 +182,35 @@ const DataTable = props => {
|
|
|
195
182
|
} = state;
|
|
196
183
|
const isExpanded = isExpandedAll || rowIds.every(id => rowsById[id].isExpanded);
|
|
197
184
|
const translationKey = isExpanded ? translationKeys.collapseAll : translationKeys.expandAll;
|
|
185
|
+
const handlers = [handleOnExpandAll, onExpand];
|
|
186
|
+
if (onClick) {
|
|
187
|
+
handlers.push(handleOnExpandHeaderClick(onClick, {
|
|
188
|
+
isExpanded
|
|
189
|
+
}));
|
|
190
|
+
}
|
|
198
191
|
return {
|
|
199
192
|
...rest,
|
|
200
193
|
'aria-label': t(translationKey),
|
|
201
|
-
// Provide a string of all
|
|
194
|
+
// Provide a string of all expanded row IDs, separated by a space.
|
|
202
195
|
'aria-controls': rowIds.map(id => `expanded-row-${id}`).join(' '),
|
|
203
196
|
isExpanded,
|
|
204
|
-
|
|
205
|
-
// handler
|
|
206
|
-
onExpand: composeEventHandlers([handleOnExpandAll, onExpand,
|
|
207
|
-
// TODO: Avoid passing `false` to this function.
|
|
208
|
-
onClick && handleOnExpandHeaderClick(onClick, {
|
|
209
|
-
isExpanded
|
|
210
|
-
})])
|
|
197
|
+
onExpand: composeEventHandlers(handlers)
|
|
211
198
|
};
|
|
212
199
|
};
|
|
213
200
|
|
|
214
201
|
/**
|
|
215
|
-
*
|
|
202
|
+
* Wraps the consumer's `onClick` with sorting metadata.
|
|
216
203
|
*/
|
|
217
204
|
const handleOnHeaderClick = (onClick, sortParams) => {
|
|
218
205
|
return event => onClick(event, sortParams);
|
|
219
206
|
};
|
|
220
207
|
|
|
221
208
|
/**
|
|
222
|
-
*
|
|
209
|
+
* Wraps the consumer's `onClick` with sorting metadata.
|
|
223
210
|
*/
|
|
224
211
|
const handleOnExpandHeaderClick = (onClick, expandParams) => {
|
|
225
212
|
return event => onClick(event, expandParams);
|
|
226
213
|
};
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Get the props associated with the given row. Mostly used for expansion.
|
|
230
|
-
*/
|
|
231
214
|
const getRowProps = ({
|
|
232
215
|
row,
|
|
233
216
|
onClick,
|
|
@@ -248,10 +231,6 @@ const DataTable = props => {
|
|
|
248
231
|
disabled: row.disabled
|
|
249
232
|
};
|
|
250
233
|
};
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Get the props associated with an expanded row
|
|
254
|
-
*/
|
|
255
234
|
const getExpandedRowProps = ({
|
|
256
235
|
row,
|
|
257
236
|
...rest
|
|
@@ -263,9 +242,7 @@ const DataTable = props => {
|
|
|
263
242
|
};
|
|
264
243
|
|
|
265
244
|
/**
|
|
266
|
-
* Gets the props associated with selection for a header or a row
|
|
267
|
-
* applicable. Most often used to indicate selection status of the table or
|
|
268
|
-
* for a specific row.
|
|
245
|
+
* Gets the props associated with selection for a header or a row.
|
|
269
246
|
*/
|
|
270
247
|
const getSelectionProps = ({
|
|
271
248
|
onClick,
|
|
@@ -290,7 +267,7 @@ const DataTable = props => {
|
|
|
290
267
|
// Otherwise, we're working on `TableSelectAll` which handles toggling the
|
|
291
268
|
// selection state of all rows.
|
|
292
269
|
const rowCount = state.rowIds.length;
|
|
293
|
-
const selectedRowCount =
|
|
270
|
+
const selectedRowCount = selectedRows.length;
|
|
294
271
|
const checked = rowCount > 0 && selectedRowCount === rowCount;
|
|
295
272
|
const indeterminate = rowCount > 0 && selectedRowCount > 0 && selectedRowCount !== rowCount;
|
|
296
273
|
const translationKey = checked || indeterminate ? translationKeys.unselectAll : translationKeys.selectAll;
|
|
@@ -315,13 +292,13 @@ const DataTable = props => {
|
|
|
315
292
|
const {
|
|
316
293
|
shouldShowBatchActions
|
|
317
294
|
} = state;
|
|
318
|
-
const
|
|
295
|
+
const selectedRowCount = selectedRows.length;
|
|
319
296
|
return {
|
|
320
297
|
onSelectAll: undefined,
|
|
321
|
-
totalCount: state.rowIds.length
|
|
298
|
+
totalCount: state.rowIds.length,
|
|
322
299
|
...props,
|
|
323
|
-
shouldShowBatchActions: shouldShowBatchActions &&
|
|
324
|
-
totalSelected,
|
|
300
|
+
shouldShowBatchActions: shouldShowBatchActions && selectedRowCount > 0,
|
|
301
|
+
totalSelected: selectedRowCount,
|
|
325
302
|
onCancel: handleOnCancel
|
|
326
303
|
};
|
|
327
304
|
};
|
|
@@ -342,77 +319,49 @@ const DataTable = props => {
|
|
|
342
319
|
useStaticWidth
|
|
343
320
|
};
|
|
344
321
|
};
|
|
345
|
-
|
|
346
|
-
// TODO: `getHeaderProps` and `getRowProps` return `key` props. Would it be
|
|
347
|
-
// beneficial for this function to also return a `key` prop?
|
|
348
|
-
/**
|
|
349
|
-
* Get the props associated with the given table cell.
|
|
350
|
-
*/
|
|
351
322
|
const getCellProps = ({
|
|
352
323
|
cell: {
|
|
353
324
|
hasAILabelHeader,
|
|
354
|
-
|
|
325
|
+
id
|
|
355
326
|
},
|
|
356
327
|
...rest
|
|
357
328
|
}) => {
|
|
358
329
|
return {
|
|
359
330
|
...rest,
|
|
360
331
|
hasAILabelHeader,
|
|
361
|
-
|
|
332
|
+
key: id
|
|
362
333
|
};
|
|
363
334
|
};
|
|
364
335
|
|
|
365
336
|
/**
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
* @returns the array of rowIds that are currently selected
|
|
337
|
+
* Selected row IDs, excluding disabled rows.
|
|
369
338
|
*/
|
|
370
|
-
const
|
|
339
|
+
const selectedRows = state.rowIds.filter(id => {
|
|
371
340
|
const row = state.rowsById[id];
|
|
372
341
|
return row.isSelected && !row.disabled;
|
|
373
342
|
});
|
|
343
|
+
const filteredRowIds = typeof state.filterInputValue === 'string' ? filterRows({
|
|
344
|
+
cellsById: state.cellsById,
|
|
345
|
+
getCellId,
|
|
346
|
+
headers,
|
|
347
|
+
inputValue: state.filterInputValue,
|
|
348
|
+
rowIds: state.rowIds
|
|
349
|
+
}) : state.rowIds;
|
|
374
350
|
|
|
375
351
|
/**
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
* @returns the array of rowIds that are currently included through the filter
|
|
379
|
-
*/
|
|
380
|
-
const getFilteredRowIds = () => {
|
|
381
|
-
const filteredRowIds = typeof state.filterInputValue === 'string' ? filterRows({
|
|
382
|
-
rowIds: state.rowIds,
|
|
383
|
-
headers: headers,
|
|
384
|
-
cellsById: state.cellsById,
|
|
385
|
-
inputValue: state.filterInputValue,
|
|
386
|
-
getCellId
|
|
387
|
-
}) : state.rowIds;
|
|
388
|
-
// TODO: Use strict equality check.
|
|
389
|
-
if (filteredRowIds.length == 0) {
|
|
390
|
-
return [];
|
|
391
|
-
}
|
|
392
|
-
return filteredRowIds;
|
|
393
|
-
};
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Helper for getting the table prefix for elements that require an
|
|
397
|
-
* `id` attribute that is unique.
|
|
352
|
+
* Generates a prefix for table related IDs.
|
|
398
353
|
*/
|
|
399
354
|
const getTablePrefix = () => `data-table-${instanceId}`;
|
|
400
355
|
|
|
401
356
|
/**
|
|
402
|
-
*
|
|
403
|
-
* setState, so use it when setting state.
|
|
404
|
-
*
|
|
405
|
-
* @returns object to put into this.setState (use spread operator)
|
|
357
|
+
* Generates a new `rowsById` object with updated selection state.
|
|
406
358
|
*/
|
|
407
|
-
const
|
|
359
|
+
const getUpdatedSelectionState = (initialState, isSelected) => {
|
|
408
360
|
const {
|
|
409
361
|
rowIds
|
|
410
362
|
} = initialState;
|
|
411
|
-
|
|
412
|
-
const isFiltered = rowIds.length != filteredRowIds.length;
|
|
363
|
+
const isFiltered = rowIds.length !== filteredRowIds.length;
|
|
413
364
|
return {
|
|
414
|
-
// TODO: Should the `reduce` be typed with `<Record<string,
|
|
415
|
-
// DataTableRow<ColTypes>>>`?
|
|
416
365
|
rowsById: rowIds.reduce((acc, id) => {
|
|
417
366
|
const row = {
|
|
418
367
|
...initialState.rowsById[id]
|
|
@@ -420,62 +369,59 @@ const DataTable = props => {
|
|
|
420
369
|
if (!row.disabled && (!isFiltered || filteredRowIds.includes(id))) {
|
|
421
370
|
row.isSelected = isSelected;
|
|
422
371
|
}
|
|
423
|
-
|
|
372
|
+
|
|
373
|
+
// Local mutation for performance with large tables
|
|
374
|
+
acc[id] = row;
|
|
424
375
|
return acc;
|
|
425
376
|
}, {})
|
|
426
377
|
};
|
|
427
378
|
};
|
|
428
379
|
|
|
429
380
|
/**
|
|
430
|
-
* Handler for
|
|
431
|
-
*
|
|
381
|
+
* Handler for `onCancel` to hide the batch action toolbar and deselect all
|
|
382
|
+
* rows.
|
|
432
383
|
*/
|
|
433
384
|
const handleOnCancel = () => {
|
|
434
385
|
setState(prev => {
|
|
435
386
|
return {
|
|
436
387
|
...prev,
|
|
437
388
|
shouldShowBatchActions: false,
|
|
438
|
-
...
|
|
389
|
+
...getUpdatedSelectionState(prev, false)
|
|
439
390
|
};
|
|
440
391
|
});
|
|
441
392
|
};
|
|
442
393
|
|
|
443
394
|
/**
|
|
444
|
-
* Handler for toggling the selection state of all rows
|
|
395
|
+
* Handler for toggling the selection state of all rows.
|
|
445
396
|
*/
|
|
446
397
|
const handleSelectAll = () => {
|
|
447
398
|
setState(prev => {
|
|
448
|
-
const filteredRowIds = getFilteredRowIds();
|
|
449
399
|
const {
|
|
450
400
|
rowsById
|
|
451
401
|
} = prev;
|
|
452
|
-
const isSelected = !
|
|
402
|
+
const isSelected = !Object.values(rowsById).filter(row => row.isSelected && !row.disabled).length;
|
|
453
403
|
return {
|
|
454
404
|
...prev,
|
|
455
405
|
shouldShowBatchActions: isSelected,
|
|
456
|
-
...
|
|
406
|
+
...getUpdatedSelectionState(prev, isSelected)
|
|
457
407
|
};
|
|
458
408
|
});
|
|
459
409
|
};
|
|
460
410
|
|
|
461
411
|
/**
|
|
462
|
-
* Handler for toggling
|
|
412
|
+
* Handler for toggling selection state of a given row.
|
|
463
413
|
*/
|
|
464
414
|
const handleOnSelectRow = rowId => () => {
|
|
465
415
|
setState(prev => {
|
|
466
416
|
const row = prev.rowsById[rowId];
|
|
467
417
|
if (radio) {
|
|
468
|
-
//
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const [key, val] = c;
|
|
476
|
-
val.isSelected = false;
|
|
477
|
-
p[key] = val;
|
|
478
|
-
return p;
|
|
418
|
+
// Deselect all radio buttons, then toggle the target row
|
|
419
|
+
const rowsById = Object.entries(prev.rowsById).reduce((acc, [id, row]) => {
|
|
420
|
+
acc[id] = {
|
|
421
|
+
...row,
|
|
422
|
+
isSelected: false
|
|
423
|
+
};
|
|
424
|
+
return acc;
|
|
479
425
|
}, {});
|
|
480
426
|
return {
|
|
481
427
|
...prev,
|
|
@@ -483,8 +429,8 @@ const DataTable = props => {
|
|
|
483
429
|
rowsById: {
|
|
484
430
|
...rowsById,
|
|
485
431
|
[rowId]: {
|
|
486
|
-
...
|
|
487
|
-
isSelected: !
|
|
432
|
+
...rowsById[rowId],
|
|
433
|
+
isSelected: !rowsById[rowId].isSelected
|
|
488
434
|
}
|
|
489
435
|
}
|
|
490
436
|
};
|
|
@@ -494,10 +440,8 @@ const DataTable = props => {
|
|
|
494
440
|
const selectedRowsCount = !row.isSelected ? selectedRows + 1 : selectedRows - 1;
|
|
495
441
|
return {
|
|
496
442
|
...prev,
|
|
497
|
-
//
|
|
498
|
-
//
|
|
499
|
-
// have a non-zero number of selected rows that batch actions could
|
|
500
|
-
// still apply to
|
|
443
|
+
// Show batch action toolbar if selecting, or if there are other
|
|
444
|
+
// selected rows remaining.
|
|
501
445
|
shouldShowBatchActions: !row.isSelected || selectedRowsCount > 0,
|
|
502
446
|
rowsById: {
|
|
503
447
|
...prev.rowsById,
|
|
@@ -509,10 +453,6 @@ const DataTable = props => {
|
|
|
509
453
|
};
|
|
510
454
|
});
|
|
511
455
|
};
|
|
512
|
-
|
|
513
|
-
/**
|
|
514
|
-
* Handler for toggling the expansion state of a given row.
|
|
515
|
-
*/
|
|
516
456
|
const handleOnExpandRow = rowId => () => {
|
|
517
457
|
setState(prev => {
|
|
518
458
|
const row = prev.rowsById[rowId];
|
|
@@ -532,10 +472,6 @@ const DataTable = props => {
|
|
|
532
472
|
};
|
|
533
473
|
});
|
|
534
474
|
};
|
|
535
|
-
|
|
536
|
-
/**
|
|
537
|
-
* Handler for changing the expansion state of all rows.
|
|
538
|
-
*/
|
|
539
475
|
const handleOnExpandAll = () => {
|
|
540
476
|
setState(prev => {
|
|
541
477
|
const {
|
|
@@ -545,22 +481,19 @@ const DataTable = props => {
|
|
|
545
481
|
return {
|
|
546
482
|
...prev,
|
|
547
483
|
isExpandedAll: !isExpandedAll,
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
...acc,
|
|
551
|
-
[id]: {
|
|
484
|
+
rowsById: rowIds.reduce((acc, id) => {
|
|
485
|
+
acc[id] = {
|
|
552
486
|
...prev.rowsById[id],
|
|
553
487
|
isExpanded: !isExpandedAll
|
|
554
|
-
}
|
|
555
|
-
|
|
488
|
+
};
|
|
489
|
+
return acc;
|
|
490
|
+
}, {})
|
|
556
491
|
};
|
|
557
492
|
});
|
|
558
493
|
};
|
|
559
494
|
|
|
560
495
|
/**
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
* @param headerKey - The field for the header that we are sorting by.
|
|
496
|
+
* Transitions to the next sort state of the table.
|
|
564
497
|
*/
|
|
565
498
|
const handleSortBy = headerKey => () => {
|
|
566
499
|
setState(prev => {
|
|
@@ -576,37 +509,20 @@ const DataTable = props => {
|
|
|
576
509
|
};
|
|
577
510
|
|
|
578
511
|
/**
|
|
579
|
-
* Event handler for
|
|
580
|
-
* filter component.
|
|
512
|
+
* Event handler for table filter input changes.
|
|
581
513
|
*/
|
|
582
514
|
const handleOnInputValueChange = (event, defaultValue) => {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
}
|
|
589
|
-
if (defaultValue) {
|
|
590
|
-
setState(prev => ({
|
|
591
|
-
...prev,
|
|
592
|
-
filterInputValue: defaultValue
|
|
593
|
-
}));
|
|
594
|
-
}
|
|
515
|
+
const value = defaultValue || event.target?.value;
|
|
516
|
+
setState(prev => ({
|
|
517
|
+
...prev,
|
|
518
|
+
filterInputValue: value
|
|
519
|
+
}));
|
|
595
520
|
};
|
|
596
|
-
|
|
597
|
-
// TODO: Could getFilteredRowIds be used here?
|
|
598
|
-
const filteredRowIds = typeof state.filterInputValue === 'string' ? filterRows({
|
|
599
|
-
rowIds: state.rowIds,
|
|
600
|
-
headers,
|
|
601
|
-
cellsById: state.cellsById,
|
|
602
|
-
inputValue: state.filterInputValue,
|
|
603
|
-
getCellId
|
|
604
|
-
}) : state.rowIds;
|
|
605
521
|
const renderProps = {
|
|
606
522
|
// Data derived from state
|
|
607
523
|
rows: denormalize(filteredRowIds, state.rowsById, state.cellsById),
|
|
608
524
|
headers: headers,
|
|
609
|
-
selectedRows: denormalize(
|
|
525
|
+
selectedRows: denormalize(selectedRows, state.rowsById, state.cellsById),
|
|
610
526
|
// Prop accessors/getters
|
|
611
527
|
getHeaderProps,
|
|
612
528
|
getExpandHeaderProps,
|
|
@@ -660,6 +576,10 @@ DataTable.TableToolbarContent = TableToolbarContent;
|
|
|
660
576
|
DataTable.TableToolbarSearch = TableToolbarSearch;
|
|
661
577
|
DataTable.TableToolbarMenu = TableToolbarMenu;
|
|
662
578
|
DataTable.propTypes = {
|
|
579
|
+
/**
|
|
580
|
+
* Pass in the children that will be rendered within the Table
|
|
581
|
+
*/
|
|
582
|
+
children: PropTypes.node,
|
|
663
583
|
/**
|
|
664
584
|
* Experimental property. Allows table to align cell contents to the top if there is text wrapping in the content. Might have performance issues, intended for smaller tables
|
|
665
585
|
*/
|
|
@@ -695,6 +615,13 @@ DataTable.propTypes = {
|
|
|
695
615
|
* Specify whether the control should be a radio button or inline checkbox
|
|
696
616
|
*/
|
|
697
617
|
radio: PropTypes.bool,
|
|
618
|
+
/**
|
|
619
|
+
* @deprecated Use `children` instead. This prop will be removed in
|
|
620
|
+
* the next major version.
|
|
621
|
+
*
|
|
622
|
+
* https://www.patterns.dev/react/render-props-pattern/#children-as-a-function
|
|
623
|
+
*/
|
|
624
|
+
render: deprecate(PropTypes.func),
|
|
698
625
|
/**
|
|
699
626
|
* The `rows` prop is where you provide us with a list of all the rows that
|
|
700
627
|
* you want to render in the table. The only hard requirement is that this
|
|
@@ -721,13 +648,13 @@ DataTable.propTypes = {
|
|
|
721
648
|
*/
|
|
722
649
|
stickyHeader: PropTypes.bool,
|
|
723
650
|
/**
|
|
724
|
-
* Optional method that takes in a message
|
|
651
|
+
* Optional method that takes in a message ID and returns an
|
|
725
652
|
* internationalized string. See `DataTable.translationKeys` for all
|
|
726
|
-
* available message
|
|
653
|
+
* available message IDs.
|
|
727
654
|
*/
|
|
728
655
|
translateWithId: PropTypes.func,
|
|
729
656
|
/**
|
|
730
|
-
*
|
|
657
|
+
* If `true`, sets the table width to `auto` instead of `100%`.
|
|
731
658
|
*/
|
|
732
659
|
useStaticWidth: PropTypes.bool,
|
|
733
660
|
/**
|
|
@@ -26,7 +26,7 @@ export interface TableProps {
|
|
|
26
26
|
*/
|
|
27
27
|
stickyHeader?: boolean;
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* If `true`, sets the table width to `auto` instead of `100%`.
|
|
30
30
|
*/
|
|
31
31
|
useStaticWidth?: boolean;
|
|
32
32
|
/**
|
|
@@ -67,7 +67,7 @@ export declare const Table: {
|
|
|
67
67
|
*/
|
|
68
68
|
stickyHeader: PropTypes.Requireable<boolean>;
|
|
69
69
|
/**
|
|
70
|
-
*
|
|
70
|
+
* If `true`, sets the table width to `auto` instead of `100%`.
|
|
71
71
|
*/
|
|
72
72
|
useStaticWidth: PropTypes.Requireable<boolean>;
|
|
73
73
|
/**
|
|
@@ -166,7 +166,7 @@ Table.propTypes = {
|
|
|
166
166
|
*/
|
|
167
167
|
stickyHeader: PropTypes.bool,
|
|
168
168
|
/**
|
|
169
|
-
*
|
|
169
|
+
* If `true`, sets the table width to `auto` instead of `100%`.
|
|
170
170
|
*/
|
|
171
171
|
useStaticWidth: PropTypes.bool,
|
|
172
172
|
/**
|
|
@@ -98,7 +98,7 @@ declare const TableExpandHeader: {
|
|
|
98
98
|
* Specify whether this row is expanded or not. This helps coordinate data
|
|
99
99
|
* attributes so that `TableExpandRow` and `TableExpandedRow` work together
|
|
100
100
|
*/
|
|
101
|
-
isExpanded:
|
|
101
|
+
isExpanded: PropTypes.Validator<boolean | null | undefined>;
|
|
102
102
|
/**
|
|
103
103
|
* Hook for when a listener initiates a request to expand the given row
|
|
104
104
|
*/
|
|
@@ -12,7 +12,7 @@ import PropTypes from 'prop-types';
|
|
|
12
12
|
import React from 'react';
|
|
13
13
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
14
14
|
import { deprecate } from '../../prop-types/deprecate.js';
|
|
15
|
-
import requiredIfGivenPropIsTruthy from '../../prop-types/requiredIfGivenPropIsTruthy.js';
|
|
15
|
+
import { requiredIfGivenPropIsTruthy } from '../../prop-types/requiredIfGivenPropIsTruthy.js';
|
|
16
16
|
|
|
17
17
|
const TableExpandHeader = ({
|
|
18
18
|
['aria-controls']: ariaControls,
|
|
@@ -8,18 +8,6 @@ import React, { ReactNode } from 'react';
|
|
|
8
8
|
import flatpickr from 'flatpickr';
|
|
9
9
|
import { DateLimit, DateOption } from 'flatpickr/dist/types/options';
|
|
10
10
|
export type DatePickerTypes = 'simple' | 'single' | 'range';
|
|
11
|
-
export type CalRef = {
|
|
12
|
-
inline: boolean;
|
|
13
|
-
disableMobile: boolean;
|
|
14
|
-
defaultDate: Date;
|
|
15
|
-
closeOnSelect: (evt: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
16
|
-
mode: 'simple' | 'single' | 'range';
|
|
17
|
-
allowInput: boolean;
|
|
18
|
-
dateFormat: string;
|
|
19
|
-
locale: string;
|
|
20
|
-
plugins: [];
|
|
21
|
-
clickOpens: any;
|
|
22
|
-
};
|
|
23
11
|
export interface DatePickerProps {
|
|
24
12
|
/**
|
|
25
13
|
* Flatpickr prop passthrough enables direct date input, and when set to false,
|
|
@@ -14,7 +14,7 @@ import l10n from 'flatpickr/dist/l10n/index';
|
|
|
14
14
|
import DatePickerInput from '../DatePickerInput/DatePickerInput.js';
|
|
15
15
|
import { appendToPlugin } from './plugins/appendToPlugin.js';
|
|
16
16
|
import carbonFlatpickrFixEventsPlugin from './plugins/fixEventsPlugin.js';
|
|
17
|
-
import
|
|
17
|
+
import { rangePlugin } from './plugins/rangePlugin.js';
|
|
18
18
|
import { deprecate } from '../../prop-types/deprecate.js';
|
|
19
19
|
import { Escape, Tab, Enter } from '../../internal/keyboard/keys.js';
|
|
20
20
|
import { match } from '../../internal/keyboard/match.js';
|
|
@@ -354,8 +354,8 @@ const DatePicker = /*#__PURE__*/React.forwardRef(function DatePicker({
|
|
|
354
354
|
minDate: minDate,
|
|
355
355
|
maxDate: maxDate,
|
|
356
356
|
parseDate: parseDate,
|
|
357
|
-
plugins: [datePickerType === 'range' ?
|
|
358
|
-
input: endInputField.current
|
|
357
|
+
plugins: [datePickerType === 'range' ? rangePlugin({
|
|
358
|
+
input: endInputField.current ?? undefined
|
|
359
359
|
}) : () => {}, appendTo ? appendToPlugin({
|
|
360
360
|
appendTo
|
|
361
361
|
}) : () => {}, carbonFlatpickrMonthSelectPlugin({
|
|
@@ -1,2 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2019, 2025
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import { type Config } from 'flatpickr/dist/plugins/rangePlugin';
|
|
8
|
+
import { Instance } from 'flatpickr/dist/types/instance';
|
|
9
|
+
/**
|
|
10
|
+
* @param config Plugin configuration.
|
|
11
|
+
* @returns An extension of Flatpickr `rangePlugin` that does the following:
|
|
12
|
+
* * Better ensures the calendar dropdown is always aligned to the `<input>` for the starting date.
|
|
13
|
+
* Workaround for: https://github.com/flatpickr/flatpickr/issues/1944
|
|
14
|
+
* * A logic to ensure `fp.setDate()` call won't end up with "startDate to endDate" set to the first `<input>`
|
|
15
|
+
*/
|
|
16
|
+
export declare const rangePlugin: (config?: Config) => (fp: Instance) => Partial<import("flatpickr/dist/types/options").BaseOptions> & {
|
|
17
|
+
onReady: (import("flatpickr/dist/types/options").Hook | import("flatpickr/dist/types/options").Hook[] | undefined)[];
|
|
18
|
+
onPreCalendarPosition: () => void;
|
|
19
|
+
};
|