@carbon/react 1.101.0-rc.0 → 1.102.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +1009 -974
  2. package/es/components/Accordion/AccordionItem.js +8 -6
  3. package/es/components/ComboBox/ComboBox.js +10 -5
  4. package/es/components/ComposedModal/ComposedModal.js +0 -1
  5. package/es/components/ContainedList/ContainedList.d.ts +1 -1
  6. package/es/components/ContainedList/ContainedList.js +9 -34
  7. package/es/components/ContentSwitcher/ContentSwitcher.d.ts +3 -3
  8. package/es/components/ContentSwitcher/ContentSwitcher.js +1 -2
  9. package/es/components/DataTable/DataTable.d.ts +6 -2
  10. package/es/components/DataTable/DataTable.js +3 -1
  11. package/es/components/DataTable/Table.js +1 -1
  12. package/es/components/DataTable/TableToolbarSearch.d.ts +11 -2
  13. package/es/components/DataTable/TableToolbarSearch.js +10 -3
  14. package/es/components/DataTable/stories/examples/TableToolbarFilter.d.ts +3 -0
  15. package/es/components/DataTableSkeleton/DataTableSkeleton.d.ts +2 -12
  16. package/es/components/DataTableSkeleton/DataTableSkeleton.js +1 -8
  17. package/es/components/DatePicker/DatePicker.js +4 -1
  18. package/es/components/DatePickerInput/DatePickerInput.d.ts +2 -5
  19. package/es/components/DatePickerInput/DatePickerInput.js +2 -13
  20. package/es/components/Dropdown/Dropdown.js +5 -4
  21. package/es/components/ExpandableSearch/ExpandableSearch.js +2 -1
  22. package/es/components/ExpandableSearch/index.js +12 -0
  23. package/es/components/FluidSelect/FluidSelect.d.ts +3 -3
  24. package/es/components/FluidTextArea/FluidTextArea.d.ts +2 -4
  25. package/es/components/FluidTextArea/FluidTextArea.js +1 -2
  26. package/es/components/FluidTimePickerSelect/FluidTimePickerSelect.d.ts +3 -3
  27. package/es/components/Grid/Column.d.ts +1 -1
  28. package/es/components/Grid/Column.js +2 -2
  29. package/es/components/ListBox/test-helpers.d.ts +71 -0
  30. package/es/components/Loading/Loading.d.ts +1 -1
  31. package/es/components/Loading/Loading.js +3 -1
  32. package/es/components/Menu/Menu.d.ts +1 -1
  33. package/es/components/Menu/Menu.js +6 -2
  34. package/es/components/Menu/MenuItem.js +2 -2
  35. package/es/components/Modal/Modal.js +0 -1
  36. package/es/components/MultiSelect/FilterableMultiSelect.js +5 -4
  37. package/es/components/MultiSelect/MultiSelect.js +6 -9
  38. package/es/components/MultiSelect/MultiSelectPropTypes.d.ts +6 -8
  39. package/es/components/MultiSelect/tools/sorting.d.ts +16 -9
  40. package/es/components/MultiSelect/tools/sorting.js +10 -14
  41. package/es/components/NumberInput/NumberInput.js +1 -1
  42. package/es/components/OverflowMenu/OverflowMenu.js +1 -0
  43. package/es/components/OverflowMenuItem/OverflowMenuItem.d.ts +5 -1
  44. package/es/components/OverflowMenuItem/OverflowMenuItem.js +12 -2
  45. package/es/components/Popover/index.js +4 -4
  46. package/es/components/ProgressIndicator/ProgressIndicator.d.ts +1 -1
  47. package/es/components/ProgressIndicator/ProgressIndicator.js +1 -1
  48. package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
  49. package/es/components/RadioButtonGroup/RadioButtonGroup.js +8 -11
  50. package/es/components/Search/Search.d.ts +1 -1
  51. package/es/components/Search/Search.js +3 -2
  52. package/es/components/Search/utils.d.ts +7 -0
  53. package/es/components/Search/utils.js +10 -0
  54. package/es/components/Select/Select.d.ts +2 -2
  55. package/es/components/Select/Select.js +2 -2
  56. package/es/components/SelectItem/SelectItem.d.ts +3 -3
  57. package/es/components/StructuredList/StructuredList.js +2 -2
  58. package/es/components/Tabs/Tabs.js +9 -4
  59. package/es/components/Tag/DismissibleTag.d.ts +1 -1
  60. package/es/components/Tag/DismissibleTag.js +2 -2
  61. package/es/components/Tag/OperationalTag.d.ts +1 -1
  62. package/es/components/Tag/OperationalTag.js +2 -2
  63. package/es/components/Tag/SelectableTag.d.ts +1 -1
  64. package/es/components/Tag/SelectableTag.js +2 -2
  65. package/es/components/Tag/Tag.d.ts +1 -1
  66. package/es/components/Tag/Tag.js +2 -2
  67. package/es/components/TextArea/TextArea.d.ts +2 -3
  68. package/es/components/TextArea/TextArea.js +4 -5
  69. package/es/components/TextInput/ControlledPasswordInput.js +1 -1
  70. package/es/components/TimePickerSelect/TimePickerSelect.d.ts +4 -4
  71. package/es/components/Toggletip/index.js +1 -2
  72. package/es/components/TreeView/TreeNode.js +2 -2
  73. package/es/components/TreeView/TreeView.d.ts +1 -1
  74. package/es/components/UIShell/HeaderPanel.d.ts +1 -1
  75. package/es/components/UIShell/HeaderPanel.js +4 -2
  76. package/es/components/UIShell/SideNav.js +3 -3
  77. package/es/components/UIShell/Switcher.d.ts +1 -1
  78. package/es/components/UIShell/Switcher.js +1 -1
  79. package/es/feature-flags.js +2 -2
  80. package/es/internal/FloatingMenu.js +3 -3
  81. package/lib/components/Accordion/AccordionItem.js +7 -5
  82. package/lib/components/ComboBox/ComboBox.js +10 -5
  83. package/lib/components/ComposedModal/ComposedModal.js +0 -1
  84. package/lib/components/ContainedList/ContainedList.d.ts +1 -1
  85. package/lib/components/ContainedList/ContainedList.js +9 -34
  86. package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +3 -3
  87. package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -2
  88. package/lib/components/DataTable/DataTable.d.ts +6 -2
  89. package/lib/components/DataTable/DataTable.js +3 -1
  90. package/lib/components/DataTable/Table.js +1 -1
  91. package/lib/components/DataTable/TableToolbarSearch.d.ts +11 -2
  92. package/lib/components/DataTable/TableToolbarSearch.js +10 -3
  93. package/lib/components/DataTable/stories/examples/TableToolbarFilter.d.ts +3 -0
  94. package/lib/components/DataTableSkeleton/DataTableSkeleton.d.ts +2 -12
  95. package/lib/components/DataTableSkeleton/DataTableSkeleton.js +1 -8
  96. package/lib/components/DatePicker/DatePicker.js +4 -1
  97. package/lib/components/DatePickerInput/DatePickerInput.d.ts +2 -5
  98. package/lib/components/DatePickerInput/DatePickerInput.js +2 -13
  99. package/lib/components/Dropdown/Dropdown.js +5 -4
  100. package/lib/components/ExpandableSearch/ExpandableSearch.js +2 -1
  101. package/lib/components/ExpandableSearch/index.js +17 -0
  102. package/lib/components/FeatureFlags/index.js +5 -5
  103. package/lib/components/FluidSelect/FluidSelect.d.ts +3 -3
  104. package/lib/components/FluidTextArea/FluidTextArea.d.ts +2 -4
  105. package/lib/components/FluidTextArea/FluidTextArea.js +1 -2
  106. package/lib/components/FluidTimePickerSelect/FluidTimePickerSelect.d.ts +3 -3
  107. package/lib/components/Grid/Column.d.ts +1 -1
  108. package/lib/components/Grid/Column.js +2 -21
  109. package/lib/components/ListBox/test-helpers.d.ts +71 -0
  110. package/lib/components/Loading/Loading.d.ts +1 -1
  111. package/lib/components/Loading/Loading.js +3 -1
  112. package/lib/components/Menu/Menu.d.ts +1 -1
  113. package/lib/components/Menu/Menu.js +6 -2
  114. package/lib/components/Menu/MenuItem.js +2 -2
  115. package/lib/components/Modal/Modal.js +0 -1
  116. package/lib/components/MultiSelect/FilterableMultiSelect.js +5 -4
  117. package/lib/components/MultiSelect/MultiSelect.js +6 -9
  118. package/lib/components/MultiSelect/MultiSelectPropTypes.d.ts +6 -8
  119. package/lib/components/MultiSelect/tools/sorting.d.ts +16 -9
  120. package/lib/components/MultiSelect/tools/sorting.js +10 -14
  121. package/lib/components/NumberInput/NumberInput.js +1 -1
  122. package/lib/components/OverflowMenu/OverflowMenu.js +1 -0
  123. package/lib/components/OverflowMenuItem/OverflowMenuItem.d.ts +5 -1
  124. package/lib/components/OverflowMenuItem/OverflowMenuItem.js +12 -2
  125. package/lib/components/Popover/index.js +4 -4
  126. package/lib/components/ProgressIndicator/ProgressIndicator.d.ts +1 -1
  127. package/lib/components/ProgressIndicator/ProgressIndicator.js +1 -1
  128. package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
  129. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +7 -10
  130. package/lib/components/Search/Search.d.ts +1 -1
  131. package/lib/components/Search/Search.js +3 -2
  132. package/lib/components/Search/utils.d.ts +7 -0
  133. package/lib/components/Search/utils.js +12 -0
  134. package/lib/components/Select/Select.d.ts +2 -2
  135. package/lib/components/Select/Select.js +2 -2
  136. package/lib/components/SelectItem/SelectItem.d.ts +3 -3
  137. package/lib/components/StructuredList/StructuredList.js +2 -2
  138. package/lib/components/Tabs/Tabs.js +9 -4
  139. package/lib/components/Tag/DismissibleTag.d.ts +1 -1
  140. package/lib/components/Tag/DismissibleTag.js +2 -2
  141. package/lib/components/Tag/OperationalTag.d.ts +1 -1
  142. package/lib/components/Tag/OperationalTag.js +2 -2
  143. package/lib/components/Tag/SelectableTag.d.ts +1 -1
  144. package/lib/components/Tag/SelectableTag.js +2 -2
  145. package/lib/components/Tag/Tag.d.ts +1 -1
  146. package/lib/components/Tag/Tag.js +2 -2
  147. package/lib/components/TextArea/TextArea.d.ts +2 -3
  148. package/lib/components/TextArea/TextArea.js +4 -5
  149. package/lib/components/TextInput/ControlledPasswordInput.js +1 -1
  150. package/lib/components/TimePickerSelect/TimePickerSelect.d.ts +4 -4
  151. package/lib/components/Toggletip/index.js +1 -2
  152. package/lib/components/TreeView/TreeNode.js +2 -2
  153. package/lib/components/TreeView/TreeView.d.ts +1 -1
  154. package/lib/components/UIShell/HeaderPanel.d.ts +1 -1
  155. package/lib/components/UIShell/HeaderPanel.js +4 -2
  156. package/lib/components/UIShell/SideNav.js +3 -3
  157. package/lib/components/UIShell/Switcher.d.ts +1 -1
  158. package/lib/components/UIShell/Switcher.js +1 -1
  159. package/lib/feature-flags.js +2 -21
  160. package/lib/internal/FloatingMenu.js +3 -22
  161. package/package.json +10 -10
  162. package/telemetry.yml +0 -1
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2026
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 '@testing-library/jest-dom/jest-globals';
8
+ export declare const findListBoxNode: () => Element | null;
9
+ export declare const findMenuNode: () => Element | null;
10
+ export declare const findMenuItemNode: (index: number) => Element;
11
+ export declare const findMenuIconNode: () => Element | null;
12
+ export declare const findFieldNode: () => Element | null;
13
+ export declare const findComboboxNode: () => Element | null;
14
+ export declare const findPopupNode: () => Element | null;
15
+ export declare const openMenu: () => Promise<void>;
16
+ export declare const assertMenuOpen: (mockProps: {
17
+ items: unknown[];
18
+ }) => void;
19
+ export declare const assertMenuClosed: () => void;
20
+ /**
21
+ * 'GenericItem' corresponds to an item in a collection that is passed to
22
+ * `MultiSelect` that is in a predictable shape and works with the default
23
+ * `itemToString` function.
24
+ */
25
+ export declare const generateGenericItem: (index: number) => {
26
+ id: string;
27
+ label: string;
28
+ value: number;
29
+ };
30
+ /**
31
+ * 'CustomItem' corresponds to a potentially different item structure that might
32
+ * be passed into `MultiSelect` that we would need to supply a custom
33
+ * `itemToString` method for.
34
+ */
35
+ export declare const generateCustomItem: (index: number) => {
36
+ field: string;
37
+ value: string;
38
+ };
39
+ /**
40
+ * Generates an array of values generated by the `generator` function.
41
+ */
42
+ export declare const generateItems: <T>(amount: number, generator: (index: number) => T) => T[];
43
+ export declare const customItemToString: ({ field, }: {
44
+ field: string;
45
+ value: string;
46
+ }) => string;
47
+ /**
48
+ * This object contains two sets of three items that share the same root
49
+ * word in different portions of the string (beginning, middle, end):
50
+ *
51
+ * - 'struct'
52
+ * - 'port'
53
+ *
54
+ * Separated by a disabled item, these derivative words are helpful when
55
+ * testing fuzzy search functions and components that do substring filtering.
56
+ */
57
+ export declare const cognateItems: ({
58
+ id: string;
59
+ text: string;
60
+ disabled?: undefined;
61
+ } | {
62
+ id: string;
63
+ text: string;
64
+ disabled: boolean;
65
+ })[];
66
+ /**
67
+ * Flushes microtasks to ensure element position state is settled
68
+ * From https://floating-ui.com/docs/react#testing
69
+ * More context here: https://github.com/floating-ui/react-popper/issues/368#issuecomment-1340413010
70
+ */
71
+ export declare const waitForPosition: () => Promise<void>;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2025
2
+ * Copyright IBM Corp. 2016, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -36,7 +36,9 @@ function Loading({
36
36
  className: loadingClassName
37
37
  }), /*#__PURE__*/React.createElement("svg", {
38
38
  className: `${prefix}--loading__svg`,
39
- viewBox: "0 0 100 100"
39
+ viewBox: "0 0 100 100",
40
+ role: "img",
41
+ "aria-label": description
40
42
  }, /*#__PURE__*/React.createElement("title", null, description), small ? /*#__PURE__*/React.createElement("circle", {
41
43
  className: `${prefix}--loading__background`,
42
44
  cx: "50%",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2023, 2025
2
+ * Copyright IBM Corp. 2023, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -84,10 +84,14 @@ const Menu = /*#__PURE__*/forwardRef(function Menu({
84
84
  }
85
85
  function handleOpen() {
86
86
  if (menu.current) {
87
- focusReturn.current = document.activeElement;
87
+ const {
88
+ activeElement,
89
+ dir
90
+ } = document;
91
+ focusReturn.current = activeElement instanceof HTMLElement ? activeElement : null;
88
92
  if (legacyAutoalign) {
89
93
  const pos = calculatePosition();
90
- if ((document?.dir === 'rtl' || direction === 'rtl') && !rest?.id?.includes('MenuButton')) {
94
+ if ((dir === 'rtl' || direction === 'rtl') && !rest?.id?.includes('MenuButton')) {
91
95
  menu.current.style.insetInlineStart = `initial`;
92
96
  menu.current.style.insetInlineEnd = `${pos[0]}px`;
93
97
  } else {
@@ -69,7 +69,7 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem({
69
69
  const context = useContext(MenuContext);
70
70
  const menuItem = useRef(null);
71
71
  const ref = useMergedRefs([forwardRef, menuItem, refs.setReference]);
72
- const hasChildren = Boolean(children);
72
+ const hasChildren = React.Children.toArray(children).length > 0;
73
73
  const isDisabled = disabled && !hasChildren;
74
74
  const isDanger = kind === 'danger' && !hasChildren;
75
75
  function registerItem() {
@@ -77,7 +77,7 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem({
77
77
  type: 'registerItem',
78
78
  payload: {
79
79
  ref: menuItem,
80
- disabled: Boolean(disabled)
80
+ disabled: disabled ?? false
81
81
  }
82
82
  });
83
83
  }
@@ -158,7 +158,6 @@ const ModalDialog = /*#__PURE__*/React.forwardRef(function ModalDialog({
158
158
  const {
159
159
  target
160
160
  } = evt;
161
- evt.stopPropagation();
162
161
  const shouldCloseOnOutsideClick =
163
162
  // Passive modals can close on clicks outside the modal when
164
163
  // preventCloseOnClickOutside is undefined or explicitly set to false.
@@ -220,7 +220,6 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
220
220
  item => !item.disabled);
221
221
 
222
222
  // Sort only non-select-all items, select-all item must stay at the top
223
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- https://github.com/carbon-design-system/carbon/issues/20452
224
223
  const sortedReal = sortItems(nonSelectAllItems, {
225
224
  selectedItems: {
226
225
  top: controlledSelectedItems,
@@ -313,6 +312,7 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
313
312
  useEffect(() => {
314
313
  const handleClickOutside = event => {
315
314
  const target = event.target;
315
+ if (!(target instanceof Node)) return;
316
316
  const wrapper = document.getElementById(id)?.closest(`.${prefix}--multi-select__wrapper`);
317
317
 
318
318
  // If click is outside our component and menu is open or input is focused
@@ -614,15 +614,16 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
614
614
 
615
615
  // Memoize the value of getMenuProps to avoid an infinite loop
616
616
  const menuProps = useMemo(() => getMenuProps({
617
- ref: autoAlign ? refs.setFloating : null
617
+ ref: autoAlign ? refs.setFloating : null,
618
+ hidden: !isOpen
618
619
  }, {
619
620
  suppressRefError: true
620
- }), [autoAlign, getMenuProps, refs.setFloating]);
621
+ }), [autoAlign, getMenuProps, isOpen, refs.setFloating]);
621
622
  const handleFocus = evt => {
622
623
  if (evt?.target.classList.contains(`${prefix}--tag__close-icon`) || evt?.target.classList.contains(`${prefix}--list-box__selection`)) {
623
624
  setIsFocused(false);
624
625
  } else {
625
- setIsFocused(evt?.type === 'focus' ? true : false);
626
+ setIsFocused(evt?.type === 'focus');
626
627
  }
627
628
  };
628
629
  const mergedRef = mergeRefs(textInput, inputProp.ref);
@@ -390,7 +390,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
390
390
  if (evt.target.classList.contains(`${prefix}--tag__close-icon`)) {
391
391
  setIsFocused(false);
392
392
  } else {
393
- setIsFocused(evt.type === 'focus' ? true : false);
393
+ setIsFocused(evt.type === 'focus');
394
394
  }
395
395
  };
396
396
  const readOnlyEventHandlers = readOnly ? {
@@ -424,8 +424,9 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
424
424
 
425
425
  // Memoize the value of getMenuProps to avoid an infinite loop
426
426
  const menuProps = useMemo(() => getMenuProps({
427
- ref: enableFloatingStyles ? refs.setFloating : null
428
- }), [enableFloatingStyles, getMenuProps, refs.setFloating]);
427
+ ref: enableFloatingStyles ? refs.setFloating : null,
428
+ hidden: !isOpen
429
+ }), [enableFloatingStyles, getMenuProps, isOpen, refs.setFloating]);
429
430
  const allLabelProps = getLabelProps();
430
431
  const labelProps = /*#__PURE__*/isValidElement(titleText) ? {
431
432
  id: allLabelProps.id
@@ -472,9 +473,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
472
473
  }, selectedItems.length > 0 && /*#__PURE__*/React.createElement(ListBox.Selection, {
473
474
  readOnly: readOnly,
474
475
  clearSelection: !disabled && !readOnly ? clearSelection : noopFn,
475
- selectionCount: selectedItemsLength
476
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
477
- ,
476
+ selectionCount: selectedItemsLength,
478
477
  translateWithId: translateWithId,
479
478
  disabled: disabled
480
479
  }), /*#__PURE__*/React.createElement("button", _extends({
@@ -493,9 +492,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
493
492
  translateWithId: translateWithId
494
493
  })), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React.createElement("div", {
495
494
  className: `${prefix}--list-box__inner-wrapper--decorator`
496
- }, normalizedDecorator) : ''), /*#__PURE__*/React.createElement(ListBox.Menu, menuProps, isOpen &&
497
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- https://github.com/carbon-design-system/carbon/issues/20452
498
- sortItems(filteredItems, sortOptions).map((item, index) => {
495
+ }, normalizedDecorator) : ''), /*#__PURE__*/React.createElement(ListBox.Menu, menuProps, isOpen && sortItems(filteredItems, sortOptions).map((item, index) => {
499
496
  const {
500
497
  hasIndividualSelections,
501
498
  nonSelectAllSelectedCount,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2023
2
+ * Copyright IBM Corp. 2016, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -34,17 +34,15 @@ export declare const sortingPropTypes: {
34
34
  */
35
35
  sortItems: PropTypes.Requireable<(...args: any[]) => any>;
36
36
  };
37
- interface DownshiftTypedProps<ItemType> {
38
- itemToString?(item: ItemType): string;
39
- }
40
37
  interface SharedOptions {
41
38
  locale: string;
42
39
  }
43
- interface CompareItems {
44
- (itemA: string, itemB: string, options: SharedOptions): number;
45
- }
46
- export interface SortItemsOptions<ItemType> extends SharedOptions, DownshiftTypedProps<ItemType> {
40
+ export type CompareItems = (itemA: string, itemB: string, options: {
41
+ locale: string;
42
+ }) => number;
43
+ export interface SortItemsOptions<ItemType> extends SharedOptions {
47
44
  compareItems: CompareItems;
45
+ itemToString: (item: ItemType) => string;
48
46
  selectedItems: ItemType[];
49
47
  }
50
48
  export interface MultiSelectSortingProps<ItemType> {
@@ -1,9 +1,16 @@
1
- export function defaultCompareItems(itemA: string, itemB: string, { locale }: {
2
- locale: string;
3
- }): number;
4
- export function defaultSortItems(items: any, { selectedItems, itemToString, compareItems, locale }: {
5
- selectedItems?: never[] | undefined;
6
- itemToString: any;
7
- compareItems: any;
8
- locale?: string | undefined;
9
- }): any;
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2026
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 { CompareItems, SortItemsOptions } from '../MultiSelectPropTypes';
8
+ /**
9
+ * Use `localeCompare` with the `numeric` option enabled to sort two
10
+ * alphanumeric strings.
11
+ */
12
+ export declare const defaultCompareItems: CompareItems;
13
+ /**
14
+ * Default sorting function for options in a selection control.
15
+ */
16
+ export declare const defaultSortItems: <T>(items: T[], { selectedItems, itemToString, compareItems, locale }: SortItemsOptions<T>) => T[];
@@ -5,16 +5,11 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
+ const isSelectAllItem = item => typeof item === 'object' && item !== null && 'isSelectAll' in item;
9
+
8
10
  /**
9
- * Use the locale `localeCompare` with the `numeric` option to sort two
10
- * alpha-numeric strings.
11
- *
12
- * @param {string} itemA - The first string to compare.
13
- * @param {string} itemB - The second string to compare.
14
- * @param {object} options - Options for comparing.
15
- * @param {string} options.locale - The locale to use for comparison.
16
- * @returns {number} A negative number if itemA comes before itemB, a positive
17
- * number if itemA comes after itemB, or 0 if they are equal.
11
+ * Use `localeCompare` with the `numeric` option enabled to sort two
12
+ * alphanumeric strings.
18
13
  */
19
14
  const defaultCompareItems = (itemA, itemB, {
20
15
  locale
@@ -23,18 +18,19 @@ const defaultCompareItems = (itemA, itemB, {
23
18
  });
24
19
 
25
20
  /**
26
- * Default sorting algorithm for options in a selection control
21
+ * Default sorting function for options in a selection control.
27
22
  */
28
23
  const defaultSortItems = (items, {
29
- selectedItems = [],
24
+ selectedItems,
30
25
  itemToString,
31
26
  compareItems,
32
- locale = 'en'
27
+ locale
33
28
  }) => {
29
+ // TODO: Should this util mutate items or should that be avoided?
34
30
  return items.sort((itemA, itemB) => {
35
31
  // Always place "select all" option at the beginning
36
- if (itemA.isSelectAll) return -1;
37
- if (itemB.isSelectAll) return 1;
32
+ if (isSelectAllItem(itemA) && itemA.isSelectAll) return -1;
33
+ if (isSelectAllItem(itemB) && itemB.isSelectAll) return 1;
38
34
  const hasItemA = selectedItems.includes(itemA);
39
35
  const hasItemB = selectedItems.includes(itemB);
40
36
  if (hasItemA && !hasItemB) return -1;
@@ -445,7 +445,7 @@ const NumberInput = /*#__PURE__*/React.forwardRef((props, forwardRef) => {
445
445
  if ('type' in evt.target && evt.target.type === 'button') {
446
446
  setIsFocused(false);
447
447
  } else {
448
- setIsFocused(evt.type === 'focus' ? true : false);
448
+ setIsFocused(evt.type === 'focus');
449
449
  }
450
450
  };
451
451
  const outerElementClasses = cx(`${prefix}--form-item`, {
@@ -255,6 +255,7 @@ const OverflowMenu = /*#__PURE__*/forwardRef(({
255
255
  const focusinEventName = hasFocusin ? 'focusin' : 'focus';
256
256
  hFocusIn.current = on(menuBody.ownerDocument, focusinEventName, event => {
257
257
  const target = event.target;
258
+ if (!(target instanceof Element)) return;
258
259
  const triggerEl = triggerRef.current;
259
260
  if (typeof target.matches === 'function') {
260
261
  if (!menuBody.contains(target) && triggerEl && !target.matches(`.${prefix}--overflow-menu:first-child, .${prefix}--overflow-menu-options:first-child`)) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2025
2
+ * Copyright IBM Corp. 2016, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -14,6 +14,10 @@ export interface OverflowMenuItemProps extends React.HTMLAttributes<HTMLElement>
14
14
  * A callback to tell the parent menu component that the menu should be closed.
15
15
  */
16
16
  closeMenu?: () => void;
17
+ /**
18
+ * Specify the message read by screen readers for the danger overflow menu item variant
19
+ */
20
+ dangerDescription?: string;
17
21
  /**
18
22
  * `true` to make this menu item disabled.
19
23
  */
@@ -15,12 +15,14 @@ import { usePrefix } from '../../internal/usePrefix.js';
15
15
  import { warning } from '../../internal/warning.js';
16
16
  import { Text } from '../Text/Text.js';
17
17
  import '../Text/TextDirection.js';
18
+ import { useId } from '../../internal/useId.js';
18
19
 
19
20
  const frFn = forwardRef;
20
21
  const OverflowMenuItem = frFn((props, ref) => {
21
22
  const {
22
23
  className,
23
24
  closeMenu,
25
+ dangerDescription = 'danger',
24
26
  disabled = false,
25
27
  handleOverflowMenuItemFocus,
26
28
  hasDivider = false,
@@ -64,13 +66,17 @@ const OverflowMenuItem = frFn((props, ref) => {
64
66
  [`${prefix}--overflow-menu-options__option--disabled`]: disabled
65
67
  }, wrapperClassName);
66
68
  const TagToUse = href ? 'a' : 'button';
69
+ const assistiveId = useId('danger-description');
67
70
  const OverflowMenuItemContent = (() => {
68
71
  if (typeof itemText !== 'string') {
69
72
  return itemText;
70
73
  }
71
- return /*#__PURE__*/React.createElement("div", {
74
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
72
75
  className: `${prefix}--overflow-menu-options__option-content`
73
- }, itemText);
76
+ }, itemText), isDelete && /*#__PURE__*/React.createElement("span", {
77
+ id: assistiveId,
78
+ className: `${prefix}--visually-hidden`
79
+ }, dangerDescription));
74
80
  })();
75
81
  return /*#__PURE__*/React.createElement(Text, {
76
82
  as: "li",
@@ -110,6 +116,10 @@ OverflowMenuItem.propTypes = {
110
116
  * A callback to tell the parent menu component that the menu should be closed.
111
117
  */
112
118
  closeMenu: PropTypes.func,
119
+ /**
120
+ * Specify the message read by screen readers for the danger overflow menu item variant
121
+ */
122
+ dangerDescription: PropTypes.string,
113
123
  /**
114
124
  * `true` to make this menu item disabled.
115
125
  */
@@ -40,7 +40,7 @@ const Popover = /*#__PURE__*/React.forwardRef(function PopoverRenderFunction({
40
40
  autoAlign = false,
41
41
  autoAlignBoundary,
42
42
  backgroundToken = 'layer',
43
- caret = isTabTip ? false : true,
43
+ caret = !isTabTip,
44
44
  className: customClassName,
45
45
  children,
46
46
  border = false,
@@ -160,7 +160,8 @@ forwardRef) {
160
160
  // Middleware order matters, arrow should be last
161
161
  middleware: [offset(!isTabTip ? {
162
162
  alignmentAxis: alignmentAxisOffset,
163
- mainAxis: popoverDimensions?.current?.offset
163
+ // Use 4px spacing when no caret, otherwise use the caret offset
164
+ mainAxis: caret ? popoverDimensions?.current?.offset : 4
164
165
  } : 0), autoAlign && flip({
165
166
  fallbackPlacements: isTabTip ? align.includes('bottom') ? ['bottom-start', 'bottom-end', 'top-start', 'top-end'] : ['top-start', 'top-end', 'bottom-start', 'bottom-end'] : align.includes('bottom') ? ['bottom', 'bottom-start', 'bottom-end', 'right', 'right-start', 'right-end', 'left', 'left-start', 'left-end', 'top', 'top-start', 'top-end'] : ['top', 'top-start', 'top-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end', 'bottom', 'bottom-start', 'bottom-end'],
166
167
  fallbackStrategy: 'initialPlacement',
@@ -297,10 +298,9 @@ forwardRef) {
297
298
  return item;
298
299
  }
299
300
  });
300
- const BaseComponentAsAny = BaseComponent;
301
301
  return /*#__PURE__*/React.createElement(PopoverContext.Provider, {
302
302
  value: value
303
- }, /*#__PURE__*/React.createElement(BaseComponentAsAny, _extends({}, rest, {
303
+ }, /*#__PURE__*/React.createElement(BaseComponent, _extends({}, rest, {
304
304
  className: className,
305
305
  ref: ref
306
306
  }), enableFloatingStyles || isTabTip ? mappedChildren : children));
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2025
2
+ * Copyright IBM Corp. 2016, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -65,7 +65,7 @@ function ProgressIndicator({
65
65
  if (index === currentIndex) {
66
66
  return /*#__PURE__*/React.cloneElement(child, {
67
67
  complete: child.props.complete,
68
- current: child.props.complete ? false : true,
68
+ current: !child.props.complete,
69
69
  index,
70
70
  onClick
71
71
  });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2025
2
+ * Copyright IBM Corp. 2016, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
- import React, { useState, useRef, cloneElement } from 'react';
10
+ import React, { useState, useRef, useEffect, cloneElement } from 'react';
11
11
  import cx from 'classnames';
12
12
  import { Legend } from '../Text/createTextComponent.js';
13
13
  import { usePrefix } from '../../internal/usePrefix.js';
@@ -43,17 +43,14 @@ const RadioButtonGroup = /*#__PURE__*/React.forwardRef((props, ref) => {
43
43
  } = props;
44
44
  const prefix = usePrefix();
45
45
  const [selected, setSelected] = useState(valueSelected ?? defaultSelected);
46
- const [prevValueSelected, setPrevValueSelected] = useState(valueSelected);
46
+ const prevValueSelected = useRef(valueSelected);
47
47
  const radioButtonGroupInstanceId = useId();
48
-
49
- /**
50
- * prop + state alignment - getDerivedStateFromProps
51
- * only update if selected prop changes
52
- */
53
- if (valueSelected !== prevValueSelected) {
54
- setSelected(valueSelected);
55
- setPrevValueSelected(valueSelected);
56
- }
48
+ useEffect(() => {
49
+ if (valueSelected !== prevValueSelected.current) {
50
+ setSelected(valueSelected);
51
+ prevValueSelected.current = valueSelected;
52
+ }
53
+ }, [valueSelected]);
57
54
  function getRadioButtons() {
58
55
  const mappedChildren = React.Children.map(children, radioButton => {
59
56
  if (!radioButton) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2025
2
+ * Copyright IBM Corp. 2016, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -22,6 +22,7 @@ import { FormContext } from '../FluidForm/FormContext.js';
22
22
  import { noopFn } from '../../internal/noopFn.js';
23
23
  import '../Tooltip/DefinitionTooltip.js';
24
24
  import { Tooltip } from '../Tooltip/Tooltip.js';
25
+ import { isSearchValuePresent } from './utils.js';
25
26
 
26
27
  var _Close;
27
28
  const Search = /*#__PURE__*/React.forwardRef(({
@@ -47,7 +48,7 @@ const Search = /*#__PURE__*/React.forwardRef(({
47
48
  value,
48
49
  ...rest
49
50
  }, forwardRef) => {
50
- const hasPropValue = value || defaultValue ? true : false;
51
+ const hasPropValue = isSearchValuePresent(value) || isSearchValuePresent(defaultValue);
51
52
  const prefix = usePrefix();
52
53
  const {
53
54
  isFluid
@@ -74,7 +75,7 @@ const Search = /*#__PURE__*/React.forwardRef(({
74
75
  [`${prefix}--search-close--hidden`]: !hasContent || !isExpanded
75
76
  });
76
77
  if (value !== prevValue) {
77
- setHasContent(!!value);
78
+ setHasContent(isSearchValuePresent(value));
78
79
  setPrevValue(value);
79
80
  }
80
81
  function clearInput() {
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright IBM Corp. 2026
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
+ export declare const isSearchValuePresent: (value: string | number | undefined) => boolean;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
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
+
8
+ const isSearchValuePresent = value => value !== '' && typeof value !== 'undefined';
9
+
10
+ export { isSearchValuePresent };
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import React, { type ChangeEventHandler, type ComponentPropsWithRef, type ReactNode } from 'react';
7
+ import React, { type ChangeEventHandler, type ComponentPropsWithRef, type ReactNode, type SelectHTMLAttributes } from 'react';
8
8
  type ExcludedAttributes = 'size';
9
9
  export interface SelectProps extends Omit<ComponentPropsWithRef<'select'>, ExcludedAttributes> {
10
10
  /**
@@ -22,7 +22,7 @@ export interface SelectProps extends Omit<ComponentPropsWithRef<'select'>, Exclu
22
22
  /**
23
23
  * Optionally provide the default value of the `<select>`
24
24
  */
25
- defaultValue?: any;
25
+ defaultValue?: SelectHTMLAttributes<HTMLSelectElement>['defaultValue'];
26
26
  /**
27
27
  * Specify whether the control is disabled
28
28
  */
@@ -34,7 +34,7 @@ const Select = /*#__PURE__*/forwardRef(({
34
34
  hideLabel = false,
35
35
  invalid = false,
36
36
  invalidText = '',
37
- helperText = '',
37
+ helperText,
38
38
  light = false,
39
39
  readOnly,
40
40
  size,
@@ -107,7 +107,7 @@ const Select = /*#__PURE__*/forwardRef(({
107
107
  ariaProps['aria-describedby'] = helper ? normalizedProps.helperId : undefined;
108
108
  }
109
109
  const handleFocus = evt => {
110
- setIsFocused(evt.type === 'focus' ? true : false);
110
+ setIsFocused(evt.type === 'focus');
111
111
  };
112
112
  const handleChange = evt => {
113
113
  const selectedOption = evt?.target?.options[evt.target.selectedIndex];
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2023
2
+ * Copyright IBM Corp. 2016, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import PropTypes from 'prop-types';
8
- import { HTMLAttributes } from 'react';
8
+ import { type HTMLAttributes, type OptionHTMLAttributes } from 'react';
9
9
  export interface SelectItemProps extends HTMLAttributes<HTMLOptionElement> {
10
10
  /**
11
11
  * Specify an optional className to be applied to the node
@@ -26,7 +26,7 @@ export interface SelectItemProps extends HTMLAttributes<HTMLOptionElement> {
26
26
  /**
27
27
  * Specify the value of the <SelectItem>
28
28
  */
29
- value: any;
29
+ value: OptionHTMLAttributes<HTMLOptionElement>['value'];
30
30
  }
31
31
  declare const SelectItem: {
32
32
  ({ className, value, disabled, hidden, text, ...other }: SelectItemProps): import("react/jsx-runtime").JSX.Element;
@@ -150,8 +150,8 @@ function StructuredListRow(props) {
150
150
  ...other
151
151
  } = props;
152
152
  const [hasFocusWithin, setHasFocusWithin] = useState(false);
153
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
154
- const rowId = id ?? useId('grid-input');
153
+ const generatedRowId = useId('grid-input');
154
+ const rowId = id ?? generatedRowId;
155
155
  const selectedRow = React.useContext(GridSelectedRowStateContext);
156
156
  const setSelectedRow = React.useContext(GridSelectedRowDispatchContext);
157
157
  const prefix = usePrefix();