@carbon/react 1.101.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 (152) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +998 -963
  2. package/es/components/Accordion/AccordionItem.js +8 -6
  3. package/es/components/ComboBox/ComboBox.js +3 -3
  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 +1 -0
  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/Loading/Loading.d.ts +1 -1
  30. package/es/components/Loading/Loading.js +3 -1
  31. package/es/components/Menu/Menu.d.ts +1 -1
  32. package/es/components/Menu/Menu.js +6 -2
  33. package/es/components/Menu/MenuItem.js +2 -2
  34. package/es/components/Modal/Modal.js +0 -1
  35. package/es/components/MultiSelect/FilterableMultiSelect.js +4 -3
  36. package/es/components/MultiSelect/MultiSelect.js +5 -8
  37. package/es/components/MultiSelect/MultiSelectPropTypes.d.ts +6 -8
  38. package/es/components/MultiSelect/tools/sorting.d.ts +16 -9
  39. package/es/components/MultiSelect/tools/sorting.js +10 -14
  40. package/es/components/OverflowMenu/OverflowMenu.js +1 -0
  41. package/es/components/OverflowMenuItem/OverflowMenuItem.d.ts +5 -1
  42. package/es/components/OverflowMenuItem/OverflowMenuItem.js +12 -2
  43. package/es/components/Popover/index.js +3 -3
  44. package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
  45. package/es/components/RadioButtonGroup/RadioButtonGroup.js +8 -11
  46. package/es/components/Search/Search.js +3 -2
  47. package/es/components/Search/utils.d.ts +7 -0
  48. package/es/components/Search/utils.js +10 -0
  49. package/es/components/Select/Select.d.ts +2 -2
  50. package/es/components/Select/Select.js +1 -1
  51. package/es/components/SelectItem/SelectItem.d.ts +3 -3
  52. package/es/components/StructuredList/StructuredList.js +2 -2
  53. package/es/components/Tabs/Tabs.js +9 -4
  54. package/es/components/Tag/DismissibleTag.d.ts +1 -1
  55. package/es/components/Tag/DismissibleTag.js +2 -2
  56. package/es/components/Tag/OperationalTag.d.ts +1 -1
  57. package/es/components/Tag/OperationalTag.js +2 -2
  58. package/es/components/Tag/SelectableTag.d.ts +1 -1
  59. package/es/components/Tag/SelectableTag.js +2 -2
  60. package/es/components/Tag/Tag.d.ts +1 -1
  61. package/es/components/Tag/Tag.js +2 -2
  62. package/es/components/TextArea/TextArea.d.ts +1 -2
  63. package/es/components/TextArea/TextArea.js +4 -5
  64. package/es/components/TextInput/ControlledPasswordInput.js +1 -1
  65. package/es/components/TimePickerSelect/TimePickerSelect.d.ts +4 -4
  66. package/es/components/Toggletip/index.js +1 -2
  67. package/es/components/TreeView/TreeNode.js +2 -2
  68. package/es/components/TreeView/TreeView.d.ts +1 -1
  69. package/es/components/UIShell/HeaderPanel.d.ts +1 -1
  70. package/es/components/UIShell/HeaderPanel.js +4 -2
  71. package/es/components/UIShell/SideNav.js +3 -3
  72. package/es/components/UIShell/Switcher.d.ts +1 -1
  73. package/es/components/UIShell/Switcher.js +1 -1
  74. package/es/feature-flags.js +2 -2
  75. package/es/internal/FloatingMenu.js +3 -3
  76. package/lib/components/Accordion/AccordionItem.js +7 -5
  77. package/lib/components/ComboBox/ComboBox.js +3 -3
  78. package/lib/components/ComposedModal/ComposedModal.js +0 -1
  79. package/lib/components/ContainedList/ContainedList.d.ts +1 -1
  80. package/lib/components/ContainedList/ContainedList.js +9 -34
  81. package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +3 -3
  82. package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -2
  83. package/lib/components/DataTable/DataTable.d.ts +6 -2
  84. package/lib/components/DataTable/DataTable.js +3 -1
  85. package/lib/components/DataTable/Table.js +1 -1
  86. package/lib/components/DataTable/TableToolbarSearch.d.ts +11 -2
  87. package/lib/components/DataTable/TableToolbarSearch.js +10 -3
  88. package/lib/components/DataTable/stories/examples/TableToolbarFilter.d.ts +3 -0
  89. package/lib/components/DataTableSkeleton/DataTableSkeleton.d.ts +2 -12
  90. package/lib/components/DataTableSkeleton/DataTableSkeleton.js +1 -8
  91. package/lib/components/DatePicker/DatePicker.js +4 -1
  92. package/lib/components/DatePickerInput/DatePickerInput.d.ts +2 -5
  93. package/lib/components/DatePickerInput/DatePickerInput.js +2 -13
  94. package/lib/components/Dropdown/Dropdown.js +1 -0
  95. package/lib/components/ExpandableSearch/ExpandableSearch.js +2 -1
  96. package/lib/components/ExpandableSearch/index.js +17 -0
  97. package/lib/components/FeatureFlags/index.js +5 -5
  98. package/lib/components/FluidSelect/FluidSelect.d.ts +3 -3
  99. package/lib/components/FluidTextArea/FluidTextArea.d.ts +2 -4
  100. package/lib/components/FluidTextArea/FluidTextArea.js +1 -2
  101. package/lib/components/FluidTimePickerSelect/FluidTimePickerSelect.d.ts +3 -3
  102. package/lib/components/Grid/Column.d.ts +1 -1
  103. package/lib/components/Grid/Column.js +2 -21
  104. package/lib/components/Loading/Loading.d.ts +1 -1
  105. package/lib/components/Loading/Loading.js +3 -1
  106. package/lib/components/Menu/Menu.d.ts +1 -1
  107. package/lib/components/Menu/Menu.js +6 -2
  108. package/lib/components/Menu/MenuItem.js +2 -2
  109. package/lib/components/Modal/Modal.js +0 -1
  110. package/lib/components/MultiSelect/FilterableMultiSelect.js +4 -3
  111. package/lib/components/MultiSelect/MultiSelect.js +5 -8
  112. package/lib/components/MultiSelect/MultiSelectPropTypes.d.ts +6 -8
  113. package/lib/components/MultiSelect/tools/sorting.d.ts +16 -9
  114. package/lib/components/MultiSelect/tools/sorting.js +10 -14
  115. package/lib/components/OverflowMenu/OverflowMenu.js +1 -0
  116. package/lib/components/OverflowMenuItem/OverflowMenuItem.d.ts +5 -1
  117. package/lib/components/OverflowMenuItem/OverflowMenuItem.js +12 -2
  118. package/lib/components/Popover/index.js +3 -3
  119. package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
  120. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +7 -10
  121. package/lib/components/Search/Search.js +3 -2
  122. package/lib/components/Search/utils.d.ts +7 -0
  123. package/lib/components/Search/utils.js +12 -0
  124. package/lib/components/Select/Select.d.ts +2 -2
  125. package/lib/components/Select/Select.js +1 -1
  126. package/lib/components/SelectItem/SelectItem.d.ts +3 -3
  127. package/lib/components/StructuredList/StructuredList.js +2 -2
  128. package/lib/components/Tabs/Tabs.js +9 -4
  129. package/lib/components/Tag/DismissibleTag.d.ts +1 -1
  130. package/lib/components/Tag/DismissibleTag.js +2 -2
  131. package/lib/components/Tag/OperationalTag.d.ts +1 -1
  132. package/lib/components/Tag/OperationalTag.js +2 -2
  133. package/lib/components/Tag/SelectableTag.d.ts +1 -1
  134. package/lib/components/Tag/SelectableTag.js +2 -2
  135. package/lib/components/Tag/Tag.d.ts +1 -1
  136. package/lib/components/Tag/Tag.js +2 -2
  137. package/lib/components/TextArea/TextArea.d.ts +1 -2
  138. package/lib/components/TextArea/TextArea.js +4 -5
  139. package/lib/components/TextInput/ControlledPasswordInput.js +1 -1
  140. package/lib/components/TimePickerSelect/TimePickerSelect.d.ts +4 -4
  141. package/lib/components/Toggletip/index.js +1 -2
  142. package/lib/components/TreeView/TreeNode.js +2 -2
  143. package/lib/components/TreeView/TreeView.d.ts +1 -1
  144. package/lib/components/UIShell/HeaderPanel.d.ts +1 -1
  145. package/lib/components/UIShell/HeaderPanel.js +4 -2
  146. package/lib/components/UIShell/SideNav.js +3 -3
  147. package/lib/components/UIShell/Switcher.d.ts +1 -1
  148. package/lib/components/UIShell/Switcher.js +1 -1
  149. package/lib/feature-flags.js +2 -21
  150. package/lib/internal/FloatingMenu.js +3 -22
  151. package/package.json +7 -7
  152. package/telemetry.yml +0 -1
@@ -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,10 +614,11 @@ 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);
@@ -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;
@@ -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
  */
@@ -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.
@@ -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) {
@@ -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 = Boolean(value || defaultValue);
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,
@@ -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();
@@ -848,8 +848,8 @@ const Tab = /*#__PURE__*/forwardRef(({
848
848
  if (tabRef.current && tabRef.current.parentElement) {
849
849
  // determine number of tabs, excluding disabled
850
850
  const tabCount = Array.from(tabRef.current.parentElement.childNodes).filter(node => {
851
- const element = node;
852
- return element.classList.contains(`${prefix}--tabs__nav-link`) && !element.classList.contains(`${prefix}--tabs__nav-item--disabled`);
851
+ if (!(node instanceof HTMLElement)) return false;
852
+ return node.classList.contains(`${prefix}--tabs__nav-link`) && !node.classList.contains(`${prefix}--tabs__nav-item--disabled`);
853
853
  }).length;
854
854
 
855
855
  // if not removing last tab focus on next tab
@@ -859,7 +859,10 @@ const Tab = /*#__PURE__*/forwardRef(({
859
859
  // if removing last tab focus on previous tab
860
860
  else {
861
861
  const prevTabIndex = (tabCount - 2) * 2;
862
- tabRef.current.parentElement.childNodes[prevTabIndex]?.focus();
862
+ const previousTab = tabRef.current.parentElement.childNodes[prevTabIndex];
863
+ if (previousTab instanceof HTMLElement) {
864
+ previousTab.focus();
865
+ }
863
866
  }
864
867
  }
865
868
  };
@@ -1160,7 +1163,9 @@ function TabPanels({
1160
1163
  // set max height to TabList
1161
1164
  const heights = refs.current.map(ref => ref?.offsetHeight || 0);
1162
1165
  const max = Math.max(...heights);
1163
- tabContainer.style.height = max + 'px';
1166
+ if (tabContainer instanceof HTMLElement) {
1167
+ tabContainer.style.height = max + 'px';
1168
+ }
1164
1169
 
1165
1170
  // re-hide hidden Tab Panels
1166
1171
  refs.current.forEach((ref, index) => {
@@ -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.
@@ -45,8 +45,8 @@ const DismissibleTag = /*#__PURE__*/forwardRef(({
45
45
  }, forwardRef) => {
46
46
  const prefix = usePrefix();
47
47
  const tagLabelRef = useRef(null);
48
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
49
- const tagId = id || `tag-${useId()}`;
48
+ const generatedTagId = useId();
49
+ const tagId = id ?? `tag-${generatedTagId}`;
50
50
  const tagClasses = cx(`${prefix}--tag--filter`, className);
51
51
  const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
52
52
  useIsomorphicEffect(() => {
@@ -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.
@@ -45,8 +45,8 @@ const OperationalTag = /*#__PURE__*/forwardRef(({
45
45
  }, forwardRef) => {
46
46
  const prefix = usePrefix();
47
47
  const tagRef = useRef(null);
48
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
49
- const tagId = id || `tag-${useId()}`;
48
+ const generatedTagId = useId();
49
+ const tagId = id ?? `tag-${generatedTagId}`;
50
50
  const tagClasses = cx(`${prefix}--tag--operational`, className);
51
51
  const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
52
52
  useIsomorphicEffect(() => {
@@ -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.
@@ -37,8 +37,8 @@ const SelectableTag = /*#__PURE__*/forwardRef(({
37
37
  }, forwardRef) => {
38
38
  const prefix = usePrefix();
39
39
  const tagRef = useRef(null);
40
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
41
- const tagId = id || `tag-${useId()}`;
40
+ const generatedTagId = useId();
41
+ const tagId = id ?? `tag-${generatedTagId}`;
42
42
  const [selectedTag, setSelectedTag] = useControllableState({
43
43
  value: selected,
44
44
  onChange: onChange,
@@ -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.
@@ -74,8 +74,8 @@ const TagBase = /*#__PURE__*/React.forwardRef(({
74
74
  console.warn('The `onClose` prop for Tag has been deprecated and will be removed in the next major version. Use DismissibleTag instead.');
75
75
  }
76
76
  const ref = useMergedRefs([forwardRef, tagRef]);
77
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
78
- const tagId = id || `tag-${useId()}`;
77
+ const generatedTagId = useId();
78
+ const tagId = id ?? `tag-${generatedTagId}`;
79
79
  const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
80
80
  useIsomorphicEffect(() => {
81
81
  const newElement = tagRef.current?.getElementsByClassName(`${prefix}--tag__label`)[0];
@@ -7,8 +7,7 @@
7
7
  import React, { type ReactNode } from 'react';
8
8
  export interface TextAreaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
9
9
  /**
10
- * Provide a custom className that is applied directly to the underlying
11
- * `<textarea>` node
10
+ * Provide a custom className that is applied to the wrapper node
12
11
  */
13
12
  className?: string;
14
13
  /**
@@ -38,7 +38,7 @@ const TextArea = frFn((props, forwardRef) => {
38
38
  onKeyDown = noopFn,
39
39
  invalid = false,
40
40
  invalidText = '',
41
- helperText = '',
41
+ helperText,
42
42
  light,
43
43
  placeholder = '',
44
44
  enableCounter = false,
@@ -239,7 +239,7 @@ const TextArea = frFn((props, forwardRef) => {
239
239
  ariaDescribedBy = warnId;
240
240
  } else {
241
241
  const ids = [];
242
- if (!isFluid && helperText && helperId) ids.push(helperId);
242
+ if (!isFluid && hasHelper && helperId) ids.push(helperId);
243
243
  if (counterDescriptionId) ids.push(counterDescriptionId);
244
244
  ariaDescribedBy = ids.length > 0 ? ids.join(' ') : undefined;
245
245
  }
@@ -278,7 +278,7 @@ const TextArea = frFn((props, forwardRef) => {
278
278
  }, [ariaAnnouncement, prevAnnouncement, counterMode]);
279
279
  const input = /*#__PURE__*/React.createElement("textarea", _extends({}, other, textareaProps, {
280
280
  placeholder: placeholder,
281
- "aria-readonly": Boolean(other.readOnly),
281
+ "aria-readonly": other.readOnly,
282
282
  className: textareaClasses,
283
283
  "aria-invalid": invalid,
284
284
  "aria-describedby": ariaDescribedBy,
@@ -324,8 +324,7 @@ const TextArea = frFn((props, forwardRef) => {
324
324
  TextArea.displayName = 'TextArea';
325
325
  TextArea.propTypes = {
326
326
  /**
327
- * Provide a custom className that is applied directly to the underlying
328
- * `<textarea>` node
327
+ * Provide a custom className that is applied to the wrapper node
329
328
  */
330
329
  className: PropTypes.string,
331
330
  /**
@@ -27,7 +27,7 @@ const ControlledPasswordInput = /*#__PURE__*/forwardRef(({
27
27
  hideLabel,
28
28
  invalid = false,
29
29
  invalidText = '',
30
- helperText = '',
30
+ helperText,
31
31
  light,
32
32
  type = 'password',
33
33
  togglePasswordVisibility,