@carbon/react 1.87.1 → 1.88.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 (89) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +851 -851
  2. package/es/components/AILabel/index.d.ts +4 -3
  3. package/es/components/AILabel/index.js +3 -1
  4. package/es/components/Button/Button.js +3 -1
  5. package/es/components/CodeSnippet/CodeSnippet.d.ts +9 -5
  6. package/es/components/CodeSnippet/CodeSnippet.js +3 -1
  7. package/es/components/ComboBox/ComboBox.d.ts +2 -1
  8. package/es/components/ComboBox/ComboBox.js +2 -1
  9. package/es/components/ContentSwitcher/ContentSwitcher.d.ts +1 -6
  10. package/es/components/Copy/Copy.d.ts +9 -5
  11. package/es/components/Copy/Copy.js +3 -1
  12. package/es/components/CopyButton/CopyButton.d.ts +9 -5
  13. package/es/components/CopyButton/CopyButton.js +3 -1
  14. package/es/components/Dropdown/Dropdown.d.ts +4 -1
  15. package/es/components/Dropdown/Dropdown.js +4 -1
  16. package/es/components/FileUploader/FileUploaderButton.js +6 -3
  17. package/es/components/IconButton/index.d.ts +6 -4
  18. package/es/components/IconButton/index.js +3 -4
  19. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +5 -2
  20. package/es/components/MultiSelect/FilterableMultiSelect.js +101 -22
  21. package/es/components/MultiSelect/MultiSelect.d.ts +2 -1
  22. package/es/components/MultiSelect/MultiSelect.js +2 -1
  23. package/es/components/Notification/Notification.d.ts +9 -1
  24. package/es/components/Notification/Notification.js +9 -1
  25. package/es/components/NumberInput/NumberInput.d.ts +4 -0
  26. package/es/components/NumberInput/NumberInput.js +12 -7
  27. package/es/components/OverflowMenu/next/index.d.ts +6 -2
  28. package/es/components/OverflowMenu/next/index.js +4 -1
  29. package/es/components/Popover/index.d.ts +4 -1
  30. package/es/components/Popover/index.js +12 -2
  31. package/es/components/Switch/IconSwitch.d.ts +44 -2
  32. package/es/components/Switch/IconSwitch.js +34 -27
  33. package/es/components/Switch/Switch.js +1 -0
  34. package/es/components/Toggletip/index.d.ts +4 -1
  35. package/es/components/Toggletip/index.js +4 -1
  36. package/es/components/Tooltip/DefinitionTooltip.d.ts +4 -2
  37. package/es/components/Tooltip/DefinitionTooltip.js +3 -1
  38. package/es/components/Tooltip/Tooltip.d.ts +0 -3
  39. package/es/components/Tooltip/Tooltip.js +2 -10
  40. package/es/components/TreeView/TreeNode.d.ts +4 -2
  41. package/es/components/TreeView/TreeNode.js +2 -1
  42. package/es/components/UIShell/HeaderPanel.js +1 -1
  43. package/es/internal/Selection.d.ts +1 -0
  44. package/es/internal/Selection.js +10 -0
  45. package/lib/components/AILabel/index.d.ts +4 -3
  46. package/lib/components/AILabel/index.js +3 -1
  47. package/lib/components/Button/Button.js +3 -1
  48. package/lib/components/CodeSnippet/CodeSnippet.d.ts +9 -5
  49. package/lib/components/CodeSnippet/CodeSnippet.js +3 -1
  50. package/lib/components/ComboBox/ComboBox.d.ts +2 -1
  51. package/lib/components/ComboBox/ComboBox.js +2 -1
  52. package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +1 -6
  53. package/lib/components/Copy/Copy.d.ts +9 -5
  54. package/lib/components/Copy/Copy.js +3 -1
  55. package/lib/components/CopyButton/CopyButton.d.ts +9 -5
  56. package/lib/components/CopyButton/CopyButton.js +3 -1
  57. package/lib/components/Dropdown/Dropdown.d.ts +4 -1
  58. package/lib/components/Dropdown/Dropdown.js +4 -1
  59. package/lib/components/FileUploader/FileUploaderButton.js +6 -3
  60. package/lib/components/IconButton/index.d.ts +6 -4
  61. package/lib/components/IconButton/index.js +3 -4
  62. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +5 -2
  63. package/lib/components/MultiSelect/FilterableMultiSelect.js +100 -21
  64. package/lib/components/MultiSelect/MultiSelect.d.ts +2 -1
  65. package/lib/components/MultiSelect/MultiSelect.js +2 -1
  66. package/lib/components/Notification/Notification.d.ts +9 -1
  67. package/lib/components/Notification/Notification.js +9 -1
  68. package/lib/components/NumberInput/NumberInput.d.ts +4 -0
  69. package/lib/components/NumberInput/NumberInput.js +12 -7
  70. package/lib/components/OverflowMenu/next/index.d.ts +6 -2
  71. package/lib/components/OverflowMenu/next/index.js +4 -1
  72. package/lib/components/Popover/index.d.ts +4 -1
  73. package/lib/components/Popover/index.js +12 -2
  74. package/lib/components/Switch/IconSwitch.d.ts +44 -2
  75. package/lib/components/Switch/IconSwitch.js +35 -28
  76. package/lib/components/Switch/Switch.js +1 -0
  77. package/lib/components/Toggletip/index.d.ts +4 -1
  78. package/lib/components/Toggletip/index.js +4 -1
  79. package/lib/components/Tooltip/DefinitionTooltip.d.ts +4 -2
  80. package/lib/components/Tooltip/DefinitionTooltip.js +3 -1
  81. package/lib/components/Tooltip/Tooltip.d.ts +0 -3
  82. package/lib/components/Tooltip/Tooltip.js +2 -10
  83. package/lib/components/TreeView/TreeNode.d.ts +4 -2
  84. package/lib/components/TreeView/TreeNode.js +2 -1
  85. package/lib/components/UIShell/HeaderPanel.js +2 -2
  86. package/lib/internal/Selection.d.ts +1 -0
  87. package/lib/internal/Selection.js +10 -0
  88. package/package.json +7 -7
  89. package/telemetry.yml +2 -9
@@ -6,12 +6,7 @@
6
6
  */
7
7
  import PropTypes from 'prop-types';
8
8
  import { type HTMLAttributes, type ReactElement } from 'react';
9
- export interface SwitchEventHandlersParams {
10
- index?: number;
11
- name?: string | number;
12
- text?: string;
13
- key?: string | number;
14
- }
9
+ import type { SwitchEventHandlersParams } from '../Switch/Switch';
15
10
  export interface ContentSwitcherProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {
16
11
  /**
17
12
  * Pass in Switch components to be rendered in the ContentSwitcher
@@ -6,16 +6,18 @@
6
6
  */
7
7
  import PropTypes from 'prop-types';
8
8
  import React, { AnimationEventHandler, MouseEventHandler, PropsWithChildren } from 'react';
9
- export type DeprecatedCopyAlignment = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'left-bottom' | 'left-top' | 'right-bottom' | 'right-top';
10
- export type NewCopyAlignment = 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-end' | 'left-start' | 'right-end' | 'right-start';
11
- export type CopyAlignment = DeprecatedCopyAlignment | NewCopyAlignment;
9
+ import type { DeprecatedPopoverAlignment, NewPopoverAlignment, PopoverAlignment } from '../Popover';
10
+ export type DeprecatedCopyAlignment = DeprecatedPopoverAlignment;
11
+ export type NewCopyAlignment = NewPopoverAlignment;
12
+ export type CopyAlignment = PopoverAlignment;
12
13
  export interface CopyProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
13
14
  /**
14
15
  * Specify how the trigger should align with the tooltip
15
16
  */
16
17
  align?: CopyAlignment;
17
18
  /**
18
- * **Experimental**: Will attempt to automatically align the tooltip
19
+ * **Experimental**: Will attempt to automatically align the tooltip. Requires React v17+
20
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
19
21
  */
20
22
  autoAlign?: boolean;
21
23
  /**
@@ -50,7 +52,9 @@ declare namespace Copy {
50
52
  */
51
53
  align: (props: any, propName: any, componentName: any, ...rest: any[]) => any;
52
54
  /**
53
- * **Experimental**: Will attempt to automatically align the tooltip
55
+ * **Experimental**: Will attempt to automatically align the tooltip. Requires
56
+ * React v17+
57
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
54
58
  */
55
59
  autoAlign: PropTypes.Requireable<boolean>;
56
60
  /**
@@ -94,7 +94,9 @@ Copy.propTypes = {
94
94
  // new values to match floating-ui
95
95
  'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']), ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'], mapPopoverAlign.mapPopoverAlign),
96
96
  /**
97
- * **Experimental**: Will attempt to automatically align the tooltip
97
+ * **Experimental**: Will attempt to automatically align the tooltip. Requires
98
+ * React v17+
99
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
98
100
  */
99
101
  autoAlign: PropTypes.bool,
100
102
  /**
@@ -7,16 +7,18 @@
7
7
  import PropTypes from 'prop-types';
8
8
  import { MouseEventHandler } from 'react';
9
9
  import { ButtonProps } from '../Button';
10
- export type DeprecatedCopyButtonAlignment = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'left-bottom' | 'left-top' | 'right-bottom' | 'right-top';
11
- export type NewCopyButtonAlignment = 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-end' | 'left-start' | 'right-end' | 'right-start';
12
- export type CopyButtonAlignment = DeprecatedCopyButtonAlignment | NewCopyButtonAlignment;
10
+ import type { DeprecatedPopoverAlignment, NewPopoverAlignment, PopoverAlignment } from '../Popover';
11
+ export type DeprecatedCopyButtonAlignment = DeprecatedPopoverAlignment;
12
+ export type NewCopyButtonAlignment = NewPopoverAlignment;
13
+ export type CopyButtonAlignment = PopoverAlignment;
13
14
  export interface CopyButtonProps extends ButtonProps<'button'> {
14
15
  /**
15
16
  * Specify how the trigger should align with the tooltip
16
17
  */
17
18
  align?: CopyButtonAlignment;
18
19
  /**
19
- * **Experimental**: Will attempt to automatically align the tooltip
20
+ * **Experimental**: Will attempt to automatically align the tooltip. Requires React v17+
21
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
20
22
  */
21
23
  autoAlign?: boolean;
22
24
  /**
@@ -51,7 +53,9 @@ declare namespace CopyButton {
51
53
  */
52
54
  align: (props: any, propName: any, componentName: any, ...rest: any[]) => any;
53
55
  /**
54
- * **Experimental**: Will attempt to automatically align the tooltip
56
+ * **Experimental**: Will attempt to automatically align the tooltip. Requires
57
+ * React v17+
58
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
55
59
  */
56
60
  autoAlign: PropTypes.Requireable<boolean>;
57
61
  /**
@@ -76,7 +76,9 @@ CopyButton.propTypes = {
76
76
  // new values to match floating-ui
77
77
  'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']), ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'], mapPopoverAlign.mapPopoverAlign),
78
78
  /**
79
- * **Experimental**: Will attempt to automatically align the tooltip
79
+ * **Experimental**: Will attempt to automatically align the tooltip. Requires
80
+ * React v17+
81
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
80
82
  */
81
83
  autoAlign: PropTypes.bool,
82
84
  /**
@@ -24,7 +24,10 @@ export interface DropdownProps<ItemType> extends Omit<HTMLAttributes<HTMLDivElem
24
24
  */
25
25
  ariaLabel?: string;
26
26
  /**
27
- * **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
27
+ * **Experimental**: Will attempt to automatically align the floating element
28
+ * to avoid collisions with the viewport and being clipped by ancestor
29
+ * elements. Requires React v17+
30
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
28
31
  */
29
32
  autoAlign?: boolean;
30
33
  /**
@@ -400,7 +400,10 @@ Dropdown.propTypes = {
400
400
  */
401
401
  ariaLabel: deprecate.deprecate(PropTypes.string, 'This prop syntax has been deprecated. Please use the new `aria-label`.'),
402
402
  /**
403
- * **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
403
+ * **Experimental**: Will attempt to automatically align the floating element
404
+ * to avoid collisions with the viewport and being clipped by ancestor
405
+ * elements. Requires React v17+
406
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
404
407
  */
405
408
  autoAlign: PropTypes.bool,
406
409
  /**
@@ -67,9 +67,12 @@ function FileUploaderButton({
67
67
  }
68
68
  }
69
69
  function onKeyDown(event) {
70
- if (match.matches(event, [keys.Enter, keys.Space]) && inputNode.current) {
71
- inputNode.current.value = '';
72
- inputNode.current.click();
70
+ if (match.matches(event, [keys.Enter, keys.Space])) {
71
+ event.preventDefault();
72
+ if (inputNode.current) {
73
+ inputNode.current.value = '';
74
+ inputNode.current.click();
75
+ }
73
76
  }
74
77
  }
75
78
  function handleOnChange(event) {
@@ -6,18 +6,20 @@
6
6
  */
7
7
  import React, { ReactNode } from 'react';
8
8
  import { ButtonSize } from '../Button';
9
+ import type { DeprecatedPopoverAlignment, NewPopoverAlignment, PopoverAlignment } from '../Popover';
9
10
  export declare const IconButtonKinds: readonly ["primary", "secondary", "ghost", "tertiary"];
10
11
  export type IconButtonKind = (typeof IconButtonKinds)[number];
11
- export type DeprecatedIconButtonAlignment = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'left-bottom' | 'left-top' | 'right-bottom' | 'right-top';
12
- export type NewIconButtonAlignment = 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-end' | 'left-start' | 'right-end' | 'right-start';
13
- export type IconButtonAlignment = DeprecatedIconButtonAlignment | NewIconButtonAlignment;
12
+ export type DeprecatedIconButtonAlignment = DeprecatedPopoverAlignment;
13
+ export type NewIconButtonAlignment = NewPopoverAlignment;
14
+ export type IconButtonAlignment = PopoverAlignment;
14
15
  export interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
15
16
  /**
16
17
  * Specify how the trigger should align with the tooltip
17
18
  */
18
19
  align?: IconButtonAlignment;
19
20
  /**
20
- * **Experimental**: Will attempt to automatically align the tooltip
21
+ * **Experimental**: Will attempt to automatically align the tooltip. Requires React v17+
22
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
21
23
  */
22
24
  autoAlign?: boolean;
23
25
  /**
@@ -101,7 +101,9 @@ IconButton.propTypes = {
101
101
  // new values to match floating-ui
102
102
  'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']), ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'], mapPopoverAlign.mapPopoverAlign),
103
103
  /**
104
- * **Experimental**: Will attempt to automatically align the tooltip
104
+ * **Experimental**: Will attempt to automatically align the tooltip. Requires
105
+ * React v17+
106
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
105
107
  */
106
108
  autoAlign: PropTypes.bool,
107
109
  /**
@@ -156,9 +158,6 @@ IconButton.propTypes = {
156
158
  /**
157
159
  * Provide the label to be rendered inside of the Tooltip. The label will use
158
160
  * `aria-labelledby` and will fully describe the child node that is provided.
159
- * If the child node already has an `aria-label`, the tooltip will not apply
160
- * `aria-labelledby`. If the child node has `aria-labelledby`, that value will
161
- * be used instead. Otherwise, the tooltip will use its own ID as the label.
162
161
  * This means that if you have text in the child node it will not be
163
162
  * announced to the screen reader.
164
163
  * If using `badgeCount={0}`, make sure the label explains that there is a
@@ -28,7 +28,8 @@ export interface FilterableMultiSelectProps<ItemType> extends MultiSelectSorting
28
28
  /**
29
29
  * **Experimental**: Will attempt to automatically align the floating
30
30
  * element to avoid collisions with the viewport and being clipped by
31
- * ancestor elements.
31
+ * ancestor elements. Requires React v17+
32
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
32
33
  */
33
34
  autoAlign?: boolean;
34
35
  className?: string;
@@ -62,7 +63,9 @@ export interface FilterableMultiSelectProps<ItemType> extends MultiSelectSorting
62
63
  */
63
64
  downshiftProps?: UseMultipleSelectionProps<ItemType>;
64
65
  /**
65
- * Default sorter is assigned if not provided.
66
+ * Provide a method that filters the dropdown options based on the current input. Overriding this
67
+ * prop means that you have to handle the filtering logic when the user types in the text input.
68
+ * Otherwise, a default built-in filtering function will be used.
66
69
  */
67
70
  filterItems?(items: readonly ItemType[], extra: {
68
71
  inputValue: string | null;
@@ -17,6 +17,8 @@ var React = require('react');
17
17
  var filter = require('./filter.js');
18
18
  var MultiSelectPropTypes = require('./MultiSelectPropTypes.js');
19
19
  var index$1 = require('../ListBox/index.js');
20
+ var Checkbox = require('../Checkbox/Checkbox.js');
21
+ require('../Checkbox/Checkbox.Skeleton.js');
20
22
  var ListBoxSelection = require('../ListBox/next/ListBoxSelection.js');
21
23
  var ListBoxTrigger = require('../ListBox/next/ListBoxTrigger.js');
22
24
  var keys = require('../../internal/keyboard/keys.js');
@@ -117,16 +119,56 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
117
119
  const [inputValue, setInputValue] = React.useState('');
118
120
  const [topItems, setTopItems] = React.useState(initialSelectedItems ?? []);
119
121
  const [inputFocused, setInputFocused] = React.useState(false);
122
+ const filteredItems = React.useMemo(() => filterItems(items, {
123
+ itemToString: itemToString$1,
124
+ inputValue
125
+ }), [items, inputValue, itemToString$1, filterItems]);
126
+ const nonSelectAllItems = React.useMemo(() => filteredItems.filter(item => !item.isSelectAll), [filteredItems]);
127
+ let selectAll = filteredItems.some(item => item.isSelectAll);
128
+ if ((selected ?? []).length > 0 && selectAll) {
129
+ console.warn('Warning: `selectAll` should not be used when `selectedItems` is provided. Please pass either `selectAll` or `selectedItems`, not both.');
130
+ selectAll = false;
131
+ }
120
132
  const {
121
133
  selectedItems: controlledSelectedItems,
122
134
  onItemChange,
123
- clearSelection
135
+ clearSelection,
136
+ toggleAll
124
137
  } = Selection.useSelection({
125
138
  disabled,
126
139
  initialSelectedItems,
127
140
  onChange,
128
- selectedItems: selected
141
+ selectedItems: selected,
142
+ selectAll,
143
+ filteredItems
129
144
  });
145
+ const selectAllStatus = React.useMemo(() => {
146
+ const selectable = nonSelectAllItems.filter(item => !item.disabled);
147
+ const nonSelectedCount = selectable.filter(item => !controlledSelectedItems.some(sel => isEqual(sel, item))).length;
148
+ const totalCount = selectable.length;
149
+ return {
150
+ checked: totalCount > 0 && nonSelectedCount === 0,
151
+ indeterminate: nonSelectedCount > 0 && nonSelectedCount < totalCount
152
+ };
153
+ }, [controlledSelectedItems, nonSelectAllItems]);
154
+ const handleSelectAllClick = React.useCallback(() => {
155
+ const selectable = nonSelectAllItems.filter(i => !i.disabled);
156
+ const {
157
+ checked,
158
+ indeterminate
159
+ } = selectAllStatus;
160
+
161
+ // clear all options if select-all state is checked or indeterminate
162
+ if (checked || indeterminate) {
163
+ const remainingSelectedItems = controlledSelectedItems.filter(sel => !filteredItems.some(e => isEqual(e, sel)));
164
+ toggleAll(remainingSelectedItems);
165
+
166
+ // select all options if select-all state is empty
167
+ } else {
168
+ const toSelect = selectable.filter(e => !controlledSelectedItems.some(sel => isEqual(sel, e)));
169
+ toggleAll([...controlledSelectedItems, ...toSelect]);
170
+ }
171
+ }, [nonSelectAllItems, selectAllStatus, controlledSelectedItems, toggleAll]);
130
172
  const {
131
173
  refs,
132
174
  floatingStyles,
@@ -177,10 +219,11 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
177
219
  // memoize sorted items to reduce unnecessary expensive sort on rerender
178
220
  const sortedItems = React.useMemo(() => {
179
221
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
180
- return sortItems(filterItems(items, {
181
- itemToString: itemToString$1,
182
- inputValue
183
- }), {
222
+ const selectAllItem = items.find(item => item.isSelectAll);
223
+ const selectableRealItems = nonSelectAllItems.filter(item => !item.disabled);
224
+
225
+ // Sort only non-select-all items, select-all item must stay at the top
226
+ const sortedReal = sortItems(nonSelectAllItems, {
184
227
  selectedItems: {
185
228
  top: controlledSelectedItems,
186
229
  fixed: [],
@@ -190,7 +233,13 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
190
233
  compareItems,
191
234
  locale
192
235
  });
193
- }, [items, inputValue, controlledSelectedItems, topItems, selectionFeedback, itemToString$1, compareItems, locale]);
236
+
237
+ // Only show select-all-item if there exist non-disabled filtered items to select
238
+ if (selectAllItem && selectableRealItems.length > 0) {
239
+ return [selectAllItem, ...sortedReal];
240
+ }
241
+ return sortedReal;
242
+ }, [items, inputValue, controlledSelectedItems, topItems, selectionFeedback, itemToString$1, compareItems, locale, sortItems, nonSelectAllItems]);
194
243
  const inline = type === 'inline';
195
244
  const showWarning = !invalid && warn;
196
245
  const wrapperClasses = cx(`${prefix}--multi-select__wrapper`, `${prefix}--multi-select--filterable__wrapper`, `${prefix}--list-box__wrapper`, containerClassName, {
@@ -313,8 +362,15 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
313
362
  }
314
363
  switch (type) {
315
364
  case InputKeyDownEnter:
365
+ if (sortedItems.length === 0) {
366
+ return changes;
367
+ }
316
368
  if (changes.selectedItem && changes.selectedItem.disabled !== true) {
317
- onItemChange(changes.selectedItem);
369
+ if (changes.selectedItem.isSelectAll) {
370
+ handleSelectAllClick();
371
+ } else {
372
+ onItemChange(changes.selectedItem);
373
+ }
318
374
  }
319
375
  setHighlightedIndex(changes.selectedItem);
320
376
  return {
@@ -322,7 +378,9 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
322
378
  highlightedIndex: state.highlightedIndex
323
379
  };
324
380
  case ItemClick:
325
- if (changes.selectedItem) {
381
+ if (changes.selectedItem.isSelectAll) {
382
+ handleSelectAllClick();
383
+ } else {
326
384
  onItemChange(changes.selectedItem);
327
385
  }
328
386
  setHighlightedIndex(changes.selectedItem);
@@ -455,6 +513,9 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
455
513
  const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/React.cloneElement(candidate, {
456
514
  size: 'mini'
457
515
  }) : null;
516
+
517
+ // exclude the select-all item from the count
518
+ const selectedItemsLength = controlledSelectedItems.filter(item => !item.isSelectAll).length;
458
519
  const className = cx(`${prefix}--multi-select`, `${prefix}--combo-box`, `${prefix}--multi-select--filterable`, {
459
520
  [`${prefix}--multi-select--invalid`]: invalid,
460
521
  [`${prefix}--multi-select--invalid--focused`]: invalid && inputFocused,
@@ -462,7 +523,8 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
462
523
  [`${prefix}--multi-select--inline`]: inline,
463
524
  [`${prefix}--multi-select--selected`]: controlledSelectedItems?.length > 0,
464
525
  [`${prefix}--multi-select--filterable--input-focused`]: inputFocused,
465
- [`${prefix}--multi-select--readonly`]: readOnly
526
+ [`${prefix}--multi-select--readonly`]: readOnly,
527
+ [`${prefix}--multi-select--selectall`]: selectAll
466
528
  });
467
529
  const labelProps = getLabelProps();
468
530
  const buttonProps = getToggleButtonProps({
@@ -600,7 +662,7 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
600
662
  textInput.current.focus();
601
663
  }
602
664
  },
603
- selectionCount: controlledSelectedItems.length,
665
+ selectionCount: selectedItemsLength,
604
666
  translateWithId: translateWithId,
605
667
  disabled: disabled
606
668
  }), /*#__PURE__*/React.createElement("input", _rollupPluginBabelHelpers.extends({
@@ -632,7 +694,14 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
632
694
  }))), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React.createElement("div", {
633
695
  className: `${prefix}--list-box__inner-wrapper--decorator`
634
696
  }, normalizedDecorator) : '', /*#__PURE__*/React.createElement(index$1.default.Menu, menuProps, isOpen ? sortedItems.map((item, index) => {
635
- const isChecked = controlledSelectedItems.filter(selected => isEqual(selected, item)).length > 0;
697
+ let isChecked;
698
+ let isIndeterminate = false;
699
+ if (item.isSelectAll) {
700
+ isChecked = selectAllStatus.checked;
701
+ isIndeterminate = selectAllStatus.indeterminate;
702
+ } else {
703
+ isChecked = controlledSelectedItems.filter(selected => isEqual(selected, item)).length > 0;
704
+ }
636
705
  const itemProps = getItemProps({
637
706
  item,
638
707
  ['aria-selected']: isChecked
@@ -652,20 +721,23 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
652
721
  return /*#__PURE__*/React.createElement(index$1.default.MenuItem, _rollupPluginBabelHelpers.extends({
653
722
  key: itemProps.id,
654
723
  "aria-label": itemText,
655
- isActive: isChecked,
724
+ isActive: isChecked && !item['isSelectAll'],
656
725
  isHighlighted: highlightedIndex === index,
657
726
  title: itemText,
658
727
  disabled: disabled
659
728
  }, modifiedItemProps), /*#__PURE__*/React.createElement("div", {
660
729
  className: `${prefix}--checkbox-wrapper`
661
- }, /*#__PURE__*/React.createElement("span", {
730
+ }, /*#__PURE__*/React.createElement(Checkbox.default, {
731
+ id: `${itemProps.id}-item`,
732
+ labelText: ItemToElement ? /*#__PURE__*/React.createElement(ItemToElement, _rollupPluginBabelHelpers.extends({
733
+ key: itemProps.id
734
+ }, item)) : itemText,
735
+ checked: isChecked,
662
736
  title: useTitleInItem ? itemText : undefined,
663
- className: `${prefix}--checkbox-label`,
664
- "data-contained-checkbox-state": isChecked,
665
- id: `${itemProps.id}-item`
666
- }, ItemToElement ? /*#__PURE__*/React.createElement(ItemToElement, _rollupPluginBabelHelpers.extends({
667
- key: itemProps.id
668
- }, item)) : itemText)));
737
+ indeterminate: isIndeterminate,
738
+ disabled: disabled,
739
+ tabIndex: -1
740
+ })));
669
741
  }) : null)), !inline && !invalid && !warn ? helper : null);
670
742
  });
671
743
  FilterableMultiSelect.displayName = 'FilterableMultiSelect';
@@ -683,7 +755,8 @@ FilterableMultiSelect.propTypes = {
683
755
  /**
684
756
  * **Experimental**: Will attempt to automatically align the floating
685
757
  * element to avoid collisions with the viewport and being clipped by
686
- * ancestor elements.
758
+ * ancestor elements. Requires React v17+
759
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
687
760
  */
688
761
  autoAlign: PropTypes.bool,
689
762
  /**
@@ -698,6 +771,12 @@ FilterableMultiSelect.propTypes = {
698
771
  * **Experimental**: Provide a decorator component to be rendered inside the `FilterableMultiSelect` component
699
772
  */
700
773
  decorator: PropTypes.node,
774
+ /**
775
+ * Provide a method that filters the dropdown options based on the current input. Overriding this
776
+ * prop means that you have to handle the filtering logic when the user types in the text input.
777
+ * Otherwise, a default built-in filtering function will be used.
778
+ */
779
+ filterItems: PropTypes.func,
701
780
  /**
702
781
  * Specify the direction of the multiselect dropdown. Can be either top or bottom.
703
782
  */
@@ -17,7 +17,8 @@ export interface MultiSelectProps<ItemType> extends MultiSelectSortingProps<Item
17
17
  /**
18
18
  * **Experimental**: Will attempt to automatically align the floating
19
19
  * element to avoid collisions with the viewport and being clipped by
20
- * ancestor elements.
20
+ * ancestor elements. Requires React v17+
21
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
21
22
  */
22
23
  autoAlign?: boolean;
23
24
  className?: string;
@@ -538,7 +538,8 @@ MultiSelect.propTypes = {
538
538
  /**
539
539
  * **Experimental**: Will attempt to automatically align the floating
540
540
  * element to avoid collisions with the viewport and being clipped by
541
- * ancestor elements.
541
+ * ancestor elements. Requires React v17+
542
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
542
543
  */
543
544
  autoAlign: PropTypes.bool,
544
545
  /**
@@ -367,6 +367,10 @@ export interface ActionableNotificationProps extends HTMLAttributes<HTMLDivEleme
367
367
  * Provide a description for "close" icon button that can be read by screen readers
368
368
  */
369
369
  'aria-label'?: string;
370
+ /**
371
+ * Specify the caption
372
+ */
373
+ caption?: string;
370
374
  /**
371
375
  * Specify the content
372
376
  */
@@ -430,7 +434,7 @@ export interface ActionableNotificationProps extends HTMLAttributes<HTMLDivEleme
430
434
  */
431
435
  title?: string;
432
436
  }
433
- export declare function ActionableNotification({ actionButtonLabel, ['aria-label']: ariaLabel, ariaLabel: deprecatedAriaLabel, children, role, onActionButtonClick, onClose, onCloseButtonClick, statusIconDescription, className, inline, kind, lowContrast, hideCloseButton, hasFocus, closeOnEscape, title, subtitle, ...rest }: ActionableNotificationProps): import("react/jsx-runtime").JSX.Element | null;
437
+ export declare function ActionableNotification({ actionButtonLabel, ['aria-label']: ariaLabel, ariaLabel: deprecatedAriaLabel, caption, children, role, onActionButtonClick, onClose, onCloseButtonClick, statusIconDescription, className, inline, kind, lowContrast, hideCloseButton, hasFocus, closeOnEscape, title, subtitle, ...rest }: ActionableNotificationProps): import("react/jsx-runtime").JSX.Element | null;
434
438
  export declare namespace ActionableNotification {
435
439
  var propTypes: {
436
440
  /**
@@ -446,6 +450,10 @@ export declare namespace ActionableNotification {
446
450
  * Provide a description for "close" icon button that can be read by screen readers
447
451
  */
448
452
  ariaLabel: (props: Record<string, any>, propName: string, componentName: string, ...rest: any[]) => any;
453
+ /**
454
+ * Specify the caption
455
+ */
456
+ caption: PropTypes.Requireable<string>;
449
457
  /**
450
458
  * Specify the content
451
459
  */
@@ -474,6 +474,7 @@ function ActionableNotification({
474
474
  ['aria-label']: ariaLabel,
475
475
  // @ts-expect-error: deprecated prop
476
476
  ariaLabel: deprecatedAriaLabel,
477
+ caption,
477
478
  children,
478
479
  role = 'alertdialog',
479
480
  onActionButtonClick,
@@ -588,7 +589,10 @@ function ActionableNotification({
588
589
  as: "div",
589
590
  className: `${prefix}--actionable-notification__subtitle`,
590
591
  id: subtitleId
591
- }, subtitle), children))), /*#__PURE__*/React.createElement("div", {
592
+ }, subtitle), caption && /*#__PURE__*/React.createElement(Text.Text, {
593
+ as: "div",
594
+ className: `${prefix}--actionable-notification__caption`
595
+ }, caption), children))), /*#__PURE__*/React.createElement("div", {
592
596
  className: `${prefix}--actionable-notification__button-wrapper`,
593
597
  ref: innerModal
594
598
  }, actionButtonLabel && /*#__PURE__*/React.createElement(NotificationActionButton, {
@@ -619,6 +623,10 @@ ActionableNotification.propTypes = {
619
623
  * Provide a description for "close" icon button that can be read by screen readers
620
624
  */
621
625
  ariaLabel: deprecate.deprecate(PropTypes.string, 'This prop syntax has been deprecated. Please use the new `aria-label`.'),
626
+ /**
627
+ * Specify the caption
628
+ */
629
+ caption: PropTypes.string,
622
630
  /**
623
631
  * Specify the content
624
632
  */
@@ -51,6 +51,10 @@ export interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInp
51
51
  * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options
52
52
  */
53
53
  formatOptions?: NumberFormatOptions;
54
+ /**
55
+ * Provide the value stepping should begin at when the input is empty
56
+ */
57
+ stepStartValue?: number;
54
58
  /**
55
59
  * Provide text that is used alongside the control label for additional help
56
60
  */
@@ -78,6 +78,7 @@ const NumberInput = /*#__PURE__*/React.forwardRef(function NumberInput(props, fo
78
78
  defaultValue = type === 'number' ? 0 : NaN,
79
79
  warn = false,
80
80
  warnText = '',
81
+ stepStartValue = 0,
81
82
  value: controlledValue,
82
83
  ...rest
83
84
  } = props;
@@ -238,14 +239,14 @@ const NumberInput = /*#__PURE__*/React.forwardRef(function NumberInput(props, fo
238
239
  if (inputRef.current) {
239
240
  const currentValue = type === 'number' ? Number(inputRef.current.value) : numberValue;
240
241
  let rawValue;
241
- if (Number.isNaN(currentValue)) {
242
- // When the field is empty (NaN), incrementing begins at min,
243
- // decrementing begins at max.
244
- // When there's no min or max to use, it begins at 0.
245
- if (direction === `up` && min) {
242
+ if (Number.isNaN(currentValue) || !currentValue) {
243
+ if (typeof stepStartValue === 'number' && stepStartValue) {
244
+ rawValue = stepStartValue;
245
+ } else if (min && min < 0 && max && max > 0 || !max && !min || max) {
246
+ if (direction === `up`) rawValue = 1;
247
+ if (direction === `down`) rawValue = -1;
248
+ } else if (min && min > 0 && max && max > 0 || min) {
246
249
  rawValue = min;
247
- } else if (direction === `down` && max) {
248
- rawValue = max;
249
250
  } else {
250
251
  rawValue = 0;
251
252
  }
@@ -534,6 +535,10 @@ NumberInput.propTypes = {
534
535
  * The minimum value.
535
536
  */
536
537
  min: PropTypes.number,
538
+ /**
539
+ * Provide the value stepping should begin at when the input is empty
540
+ */
541
+ stepStartValue: PropTypes.number,
537
542
  /**
538
543
  * Provide an optional handler that is called when the input or stepper
539
544
  * buttons are blurred.
@@ -5,9 +5,13 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import React, { type ElementType } from 'react';
8
+ import type { PopoverAlignment } from '../../Popover';
8
9
  interface OverflowMenuProps {
9
10
  /**
10
- * **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
11
+ * **Experimental**: Will attempt to automatically align the floating element
12
+ * to avoid collisions with the viewport and being clipped by ancestor
13
+ * elements. Requires React v17+
14
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
11
15
  */
12
16
  autoAlign?: boolean;
13
17
  /**
@@ -37,7 +41,7 @@ interface OverflowMenuProps {
37
41
  /**
38
42
  * Specify how the trigger tooltip should be aligned.
39
43
  */
40
- tooltipAlignment?: 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'right';
44
+ tooltipAlignment?: PopoverAlignment;
41
45
  /**
42
46
  * Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
43
47
  */
@@ -134,7 +134,10 @@ const OverflowMenu = /*#__PURE__*/React.forwardRef(function OverflowMenu({
134
134
  });
135
135
  OverflowMenu.propTypes = {
136
136
  /**
137
- * **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
137
+ * **Experimental**: Will attempt to automatically align the floating element
138
+ * to avoid collisions with the viewport and being clipped by ancestor
139
+ * elements. Requires React v17+
140
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
138
141
  */
139
142
  autoAlign: PropTypes.bool,
140
143
  /**
@@ -26,7 +26,10 @@ export interface PopoverBaseProps {
26
26
  */
27
27
  align?: PopoverAlignment;
28
28
  /**
29
- * Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes.
29
+ * Will auto-align the popover on first render if it is not visible. This prop
30
+ * is currently experimental and is subject to future changes. Requires
31
+ * React v17+
32
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
30
33
  */
31
34
  autoAlign?: boolean;
32
35
  /**