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