@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
@@ -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];
@@ -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,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": other.readOnly ? true : false,
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,
@@ -1,10 +1,10 @@
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.
6
6
  */
7
- import React from 'react';
7
+ import React, { type SelectHTMLAttributes } from 'react';
8
8
  export type TimePickerSelectProps = {
9
9
  /**
10
10
  * Provide the contents of your TimePickerSelect
@@ -17,7 +17,7 @@ export type TimePickerSelectProps = {
17
17
  /**
18
18
  * Optionally provide the default value of the `<select>`
19
19
  */
20
- defaultValue?: any;
20
+ defaultValue?: SelectHTMLAttributes<HTMLSelectElement>['defaultValue'];
21
21
  /**
22
22
  * Specify whether the control is disabled
23
23
  */
@@ -39,7 +39,7 @@ declare const TimePickerSelect: React.ForwardRefExoticComponent<{
39
39
  /**
40
40
  * Optionally provide the default value of the `<select>`
41
41
  */
42
- defaultValue?: any;
42
+ defaultValue?: SelectHTMLAttributes<HTMLSelectElement>["defaultValue"];
43
43
  /**
44
44
  * Specify whether the control is disabled
45
45
  */
@@ -134,8 +134,7 @@ function Toggletip({
134
134
  const eventType = 'PointerEvent' in window ? 'pointerdown' : 'mousedown';
135
135
  const handleOutsideClick = event => {
136
136
  const node = event.target;
137
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- https://github.com/carbon-design-system/carbon/issues/20452
138
- if (open && node && !ref.current.contains(node)) {
137
+ if (open && node && !ref.current?.contains(node)) {
139
138
  setOpen(false);
140
139
  }
141
140
  };
@@ -241,7 +241,7 @@ const TreeNode = /*#__PURE__*/React.forwardRef(({
241
241
  return node;
242
242
  }
243
243
  if (node.classList.contains(`${prefix}--tree-node-link-parent`)) {
244
- return node.firstChild;
244
+ return node.firstElementChild;
245
245
  }
246
246
  if (node.classList.contains(`${prefix}--tree`)) {
247
247
  return null;
@@ -263,7 +263,7 @@ const TreeNode = /*#__PURE__*/React.forwardRef(({
263
263
  * When focus is on a leaf node or a closed parent node, move focus to
264
264
  * its parent node (unless its depth is level 1)
265
265
  */
266
- const parentNode = findParentTreeNode(href ? currentNode.current?.parentElement?.parentElement : currentNode.current?.parentElement);
266
+ const parentNode = findParentTreeNode((href ? currentNode.current?.parentElement?.parentElement : currentNode.current?.parentElement) ?? null);
267
267
  if (parentNode instanceof HTMLElement) {
268
268
  parentNode.focus();
269
269
  }
@@ -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.
@@ -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.
@@ -59,8 +59,10 @@ const HeaderPanel = /*#__PURE__*/React.forwardRef(({
59
59
  };
60
60
  }
61
61
  useWindowEvent('click', event => {
62
- const target = event.target;
63
- if (!(target instanceof HTMLElement)) return;
62
+ const {
63
+ target
64
+ } = event;
65
+ if (!(target instanceof Element)) return;
64
66
  setLastClickedElement(target);
65
67
  const isChildASwitcher = /*#__PURE__*/isValidElement(children) && typeof children.type !== 'string' && children.type === Switcher;
66
68
  if (isChildASwitcher && !target.closest(`.${prefix}--header-panel--expanded`) && !target.closest(`.${prefix}--header__action`) && !headerPanelReference?.current?.classList.contains(`${prefix}--switcher`) && expanded) {
@@ -20,7 +20,7 @@ import { useDelayedState } from '../../internal/useDelayedState.js';
20
20
  import { breakpoints } from '@carbon/layout';
21
21
  import { useMatchMedia } from '../../internal/useMatchMedia.js';
22
22
 
23
- // TO-DO: comment back in when footer is added for rails
23
+ // TODO: comment back in when footer is added for rails
24
24
  // import SideNavFooter from './SideNavFooter';
25
25
 
26
26
  const SideNavContext = /*#__PURE__*/createContext({});
@@ -35,7 +35,7 @@ const SideNav = frFn((props, ref) => {
35
35
  children,
36
36
  onToggle,
37
37
  className: customClassName,
38
- // TO-DO: comment back in when footer is added for rails
38
+ // TODO: comment back in when footer is added for rails
39
39
  // translateById: t = (id) => translations[id],
40
40
  href,
41
41
  isFixedNav = false,
@@ -73,7 +73,7 @@ const SideNav = frFn((props, ref) => {
73
73
  'aria-labelledby': ariaLabelledBy
74
74
  };
75
75
 
76
- // TO-DO: comment back in when footer is added for rails
76
+ // TODO: comment back in when footer is added for rails
77
77
  // const assistiveText = expanded
78
78
  // ? t('carbon.sidenav.state.open')
79
79
  // : t('carbon.sidenav.state.closed');
@@ -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.
@@ -61,7 +61,7 @@ const Switcher = /*#__PURE__*/forwardRef((props, forwardRef) => {
61
61
  }
62
62
  })();
63
63
  const switcherItem = switcherRef.current?.children[nextValidIndex]?.children[0];
64
- if (switcherItem) {
64
+ if (switcherItem instanceof HTMLElement) {
65
65
  switcherItem.focus();
66
66
  }
67
67
  };
@@ -5,9 +5,9 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import * as FeatureFlags from '@carbon/feature-flags';
8
+ import { merge } from '@carbon/feature-flags';
9
9
 
10
- FeatureFlags.merge({
10
+ merge({
11
11
  'enable-css-custom-properties': true,
12
12
  'enable-css-grid': true,
13
13
  'enable-v11-release': true,
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import React, { useContext, useState, useRef, useCallback, useEffect, cloneElement } from 'react';
9
- import * as FeatureFlags from '@carbon/feature-flags';
9
+ import { enabled } from '@carbon/feature-flags';
10
10
  import ReactDOM from 'react-dom';
11
11
  import { Tab } from './keyboard/keys.js';
12
12
  import { match } from './keyboard/match.js';
@@ -274,8 +274,8 @@ const FloatingMenu = ({
274
274
  });
275
275
  }
276
276
  };
277
- const deprecatedFlag = FeatureFlags.enabled('enable-experimental-focus-wrap-without-sentinels');
278
- const focusTrapWithoutSentinelsFlag = FeatureFlags.enabled('enable-focus-wrap-without-sentinels');
277
+ const deprecatedFlag = enabled('enable-experimental-focus-wrap-without-sentinels');
278
+ const focusTrapWithoutSentinelsFlag = enabled('enable-focus-wrap-without-sentinels');
279
279
  const focusTrapWithoutSentinels = deprecatedFlag || focusTrapWithoutSentinelsFlag;
280
280
  if (typeof document !== 'undefined') {
281
281
  const portalTarget = target ? target() : document.body;
@@ -41,7 +41,7 @@ function AccordionItem({
41
41
  ...rest
42
42
  }) {
43
43
  const [isOpen, setIsOpen] = React.useState(open);
44
- const [prevIsOpen, setPrevIsOpen] = React.useState(open);
44
+ const prevOpenRef = React.useRef(open);
45
45
  const accordionState = React.useContext(AccordionProvider.AccordionContext);
46
46
  const disabledIsControlled = typeof controlledDisabled === 'boolean';
47
47
  const disabled = disabledIsControlled ? controlledDisabled : accordionState.disabled;
@@ -64,10 +64,12 @@ function AccordionItem({
64
64
  node.style.maxBlockSize = '';
65
65
  }
66
66
  }, [isOpen]);
67
- if (open !== prevIsOpen) {
68
- setIsOpen(open);
69
- setPrevIsOpen(open);
70
- }
67
+ React.useEffect(() => {
68
+ if (open !== prevOpenRef.current) {
69
+ setIsOpen(open);
70
+ prevOpenRef.current = open;
71
+ }
72
+ }, [open]);
71
73
 
72
74
  // When the AccordionItem heading is clicked, toggle the open state of the
73
75
  // panel
@@ -149,7 +149,8 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
149
149
  middleware: autoAlign ? [react.flip(), react.hide()] : undefined,
150
150
  whileElementsMounted: react.autoUpdate
151
151
  } : {});
152
- const parentWidth = refs?.reference?.current?.clientWidth;
152
+ const referenceElement = refs?.reference?.current;
153
+ const parentWidth = referenceElement instanceof HTMLElement ? referenceElement.clientWidth : undefined;
153
154
  React.useEffect(() => {
154
155
  if (enableFloatingStyles) {
155
156
  const updatedFloatingStyles = {
@@ -503,10 +504,9 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
503
504
  onHighlightedIndexChange: ({
504
505
  highlightedIndex
505
506
  }) => {
506
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion , valid-typeof , no-constant-binary-expression -- https://github.com/carbon-design-system/carbon/issues/20452
507
+ // eslint-disable-next-line valid-typeof , no-constant-binary-expression -- https://github.com/carbon-design-system/carbon/issues/20452
507
508
  if (highlightedIndex > -1 && typeof window !== undefined) {
508
509
  const itemArray = document.querySelectorAll(`li.${prefix}--list-box__menu-item[role="option"]`);
509
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- https://github.com/carbon-design-system/carbon/issues/20452
510
510
  const highlightedItem = itemArray[highlightedIndex];
511
511
  if (highlightedItem) {
512
512
  highlightedItem.scrollIntoView({
@@ -785,15 +785,20 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
785
785
  const {
786
786
  'aria-disabled': unusedAriaDisabled,
787
787
  // eslint-disable-line @typescript-eslint/no-unused-vars
788
+ 'aria-selected': unusedAriaSelected,
789
+ // eslint-disable-line @typescript-eslint/no-unused-vars
788
790
  ...modifiedItemProps
789
791
  } = itemProps;
792
+ const isSelected = isEqual(currentSelectedItem, item);
790
793
  return /*#__PURE__*/React.createElement(index$2.default.MenuItem, _rollupPluginBabelHelpers.extends({
791
794
  key: itemProps.id,
792
- isActive: isEqual(currentSelectedItem, item),
795
+ isActive: isSelected,
793
796
  isHighlighted: highlightedIndex === index,
794
797
  title: title,
795
798
  disabled: disabled
796
- }, modifiedItemProps), itemToElement ? itemToElement(item) : itemToString(item), isEqual(currentSelectedItem, item) && /*#__PURE__*/React.createElement(iconsReact.Checkmark, {
799
+ }, modifiedItemProps, {
800
+ "aria-selected": isSelected
801
+ }), itemToElement ? itemToElement(item) : itemToString(item), isSelected && /*#__PURE__*/React.createElement(iconsReact.Checkmark, {
797
802
  className: `${prefix}--list-box__menu-item__selected-icon`
798
803
  }));
799
804
  }) : null)), helperText && !normalizedProps.invalid && !normalizedProps.warn && !isFluid && /*#__PURE__*/React.createElement(Text.Text, {
@@ -200,7 +200,6 @@ const ComposedModalDialog = /*#__PURE__*/React.forwardRef(function ComposedModal
200
200
  target
201
201
  } = evt;
202
202
  const mouseDownTarget = onMouseDownTarget.current;
203
- evt.stopPropagation();
204
203
  const shouldCloseOnOutsideClick =
205
204
  // Passive modals can close on clicks outside the modal when
206
205
  // preventCloseOnClickOutside is undefined or explicitly set to false.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2022, 2025
2
+ * Copyright IBM Corp. 2022, 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,36 +14,25 @@ var React = require('react');
14
14
  var PropTypes = require('prop-types');
15
15
  var cx = require('classnames');
16
16
  var index = require('../Layout/index.js');
17
+ var utils = require('../../internal/utils.js');
17
18
  var useId = require('../../internal/useId.js');
18
19
  var usePrefix = require('../../internal/usePrefix.js');
19
20
  var ContainedListItem = require('./ContainedListItem/ContainedListItem.js');
21
+ var ExpandableSearch = require('../ExpandableSearch/ExpandableSearch.js');
20
22
  var Search = require('../Search/Search.js');
21
23
  require('../Search/Search.Skeleton.js');
22
24
 
23
25
  const variants = ['on-page', 'disclosed'];
24
- function filterChildren(children) {
26
+ const isSearchComponent = node => utils.isComponentElement(node, Search.default) || utils.isComponentElement(node, ExpandableSearch.default);
27
+ const filterChildren = children => {
25
28
  if (Array.isArray(children)) {
26
- return children?.filter(child => !['Search', 'ExpandableSearch'].includes(child?.type?.displayName));
29
+ return children.filter(child => !isSearchComponent(child));
27
30
  }
28
- if (children && !['Search', 'ExpandableSearch'].includes(children?.type?.displayName)) {
31
+ if (children && !isSearchComponent(children)) {
29
32
  return children;
30
33
  }
31
34
  return null;
32
- }
33
- function renderChildren(children) {
34
- if (Array.isArray(children)) {
35
- children.map((child, index) => {
36
- if (index === 0 && child.type === Search.default) {
37
- return child;
38
- }
39
- return child;
40
- });
41
- }
42
- if (children && children.type === Search.default) {
43
- return children;
44
- }
45
- return children;
46
- }
35
+ };
47
36
  const ContainedList = ({
48
37
  action,
49
38
  children,
@@ -63,21 +52,7 @@ const ContainedList = ({
63
52
  [`${prefix}--layout--size-${size}`]: size
64
53
  }, `${prefix}--contained-list--${kind}`, className);
65
54
  const filteredChildren = filterChildren(children);
66
- function isSearchAction(action) {
67
- if (! /*#__PURE__*/React.isValidElement(action)) {
68
- return false;
69
- }
70
- const actionTypes = ['Search', 'ExpandableSearch'];
71
- let actionType = '';
72
- if (typeof action.type === 'string') {
73
- actionType = action.type;
74
- } else {
75
- actionType = action.type.displayName || '';
76
- }
77
- return actionTypes.includes(actionType);
78
- }
79
- const isActionSearch = isSearchAction(action);
80
- const renderedChildren = renderChildren(children);
55
+ const isActionSearch = isSearchComponent(action);
81
56
  return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
82
57
  className: classes
83
58
  }, rest), label && /*#__PURE__*/React.createElement("div", {
@@ -104,7 +79,7 @@ const ContainedList = ({
104
79
  React.createElement("ul", {
105
80
  role: "list",
106
81
  "aria-labelledby": label ? labelId : undefined
107
- }, isActionSearch ? filteredChildren : renderedChildren));
82
+ }, isActionSearch ? filteredChildren : children));
108
83
  };
109
84
  ContainedList.propTypes = {
110
85
  /**
@@ -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.
@@ -35,7 +35,7 @@ export interface ContentSwitcherProps extends Omit<HTMLAttributes<HTMLElement>,
35
35
  /**
36
36
  * Specify a selected index for the initially selected content
37
37
  */
38
- selectedIndex: number;
38
+ selectedIndex?: number;
39
39
  /**
40
40
  * Choose whether or not to automatically change selection on focus when left/right arrow pressed. Defaults to 'automatic'
41
41
  */
@@ -43,7 +43,7 @@ export interface ContentSwitcherProps extends Omit<HTMLAttributes<HTMLElement>,
43
43
  /**
44
44
  * Specify the size of the Content Switcher. Currently supports either `sm`, `md` (default) or `lg` as an option.
45
45
  */
46
- size: 'sm' | 'md' | 'lg';
46
+ size?: 'sm' | 'md' | 'lg';
47
47
  }
48
48
  export declare const ContentSwitcher: {
49
49
  ({ children, className, light, lowContrast, selectedIndex: selectedIndexProp, selectionMode, size, onChange, ...other }: ContentSwitcherProps): import("react/jsx-runtime").JSX.Element;
@@ -18,7 +18,6 @@ var keys = require('../../internal/keyboard/keys.js');
18
18
  var match = require('../../internal/keyboard/match.js');
19
19
  var navigation = require('../../internal/keyboard/navigation.js');
20
20
  var usePrefix = require('../../internal/usePrefix.js');
21
- var noopFn = require('../../internal/noopFn.js');
22
21
  require('../Switch/Switch.js');
23
22
  var IconSwitch = require('../Switch/IconSwitch.js');
24
23
 
@@ -30,7 +29,7 @@ const ContentSwitcher = ({
30
29
  selectedIndex: selectedIndexProp = 0,
31
30
  selectionMode = 'automatic',
32
31
  size,
33
- onChange = noopFn.noopFn,
32
+ onChange,
34
33
  ...other
35
34
  }) => {
36
35
  const prefix = React.useContext(usePrefix.PrefixContext);
@@ -5,9 +5,10 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import PropTypes from 'prop-types';
8
- import React, { type ChangeEvent, type MouseEvent, type ReactElement, type ReactNode } from 'react';
8
+ import React, { type MouseEvent, type ReactElement, type ReactNode } from 'react';
9
9
  import { type SortRowFn } from './state/sorting';
10
10
  import type { DataTableSortState } from './state/sortStates';
11
+ import { type TableToolbarSearchOnChangeEvent } from './TableToolbarSearch';
11
12
  import type { TranslateWithId } from '../../types/common';
12
13
  declare const translationIds: {
13
14
  readonly 'carbon.table.row.expand': "carbon.table.row.expand";
@@ -169,8 +170,11 @@ export interface DataTableRenderProps<RowType, ColTypes extends any[]> {
169
170
  };
170
171
  /**
171
172
  * Handles input value changes.
173
+ *
174
+ * Note: the `''` event sentinel is supported for compatibility with
175
+ * `TableToolbarSearch` and should be removed in the next major release.
172
176
  */
173
- onInputChange: (event: ChangeEvent<HTMLInputElement>, defaultValue?: string) => void;
177
+ onInputChange: (event: TableToolbarSearchOnChangeEvent, defaultValue?: string) => void;
174
178
  /**
175
179
  * Sorts the table by a specific header.
176
180
  */
@@ -518,7 +518,9 @@ const DataTable = props => {
518
518
  * Event handler for table filter input changes.
519
519
  */
520
520
  const handleOnInputValueChange = (event, defaultValue) => {
521
- const value = defaultValue || event.target?.value;
521
+ // TODO: Remove `''` sentinel support once `TableToolbarSearch` no
522
+ // longer emits it on mount.
523
+ const value = defaultValue ?? (event === '' ? event : event.target.value);
522
524
  setState(prev => ({
523
525
  ...prev,
524
526
  filterInputValue: value
@@ -95,7 +95,7 @@ const Table = ({
95
95
  const isBodyMultiline = Array.from(tableRef.current.querySelectorAll('td')).some(td => isElementWrappingContent(td, context));
96
96
  const isHeaderMultiline = Array.from(tableRef.current.querySelectorAll('th')).some(th => {
97
97
  const label = th.querySelector(`.${prefix}--table-header-label`);
98
- return label && isElementWrappingContent(label, context);
98
+ return label instanceof HTMLElement && isElementWrappingContent(label, context);
99
99
  });
100
100
  toggleTableBodyAlignmentClass(isBodyMultiline);
101
101
  toggleTableHeaderAlignmentClass(isHeaderMultiline);
@@ -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.
@@ -15,6 +15,12 @@ declare const translationIds: {
15
15
  type TranslationKey = keyof typeof translationIds;
16
16
  type ExcludedInheritedProps = 'defaultValue' | 'labelText' | 'onBlur' | 'onChange' | 'onExpand' | 'onFocus' | 'tabIndex';
17
17
  export type TableToolbarSearchHandleExpand = (event: FocusEvent<HTMLInputElement>, newValue?: boolean) => void;
18
+ /**
19
+ * @deprecated Passing `''` as the event sentinel is legacy compatibility
20
+ * behavior for `DataTable` filtering. In the next major release, this type
21
+ * should become an optional `ChangeEvent<HTMLInputElement>` instead.
22
+ */
23
+ export type TableToolbarSearchOnChangeEvent = '' | ChangeEvent<HTMLInputElement>;
18
24
  export interface TableToolbarSearchProps extends Omit<SearchProps, ExcludedInheritedProps>, TranslateWithId<TranslationKey> {
19
25
  /**
20
26
  * Specifies if the search should initially render in an expanded state
@@ -40,8 +46,11 @@ export interface TableToolbarSearchProps extends Omit<SearchProps, ExcludedInher
40
46
  onBlur?(event: FocusEvent<HTMLInputElement>, handleExpand: TableToolbarSearchHandleExpand): void;
41
47
  /**
42
48
  * Provide an optional hook that is called each time the input is updated
49
+ *
50
+ * Note: the `''` event sentinel is legacy compatibility behavior and will be
51
+ * removed in the next major release.
43
52
  */
44
- onChange?: (event: '' | ChangeEvent<HTMLInputElement>, value?: string) => void;
53
+ onChange?: (event: TableToolbarSearchOnChangeEvent, value?: string) => void;
45
54
  /**
46
55
  * Provide an optional hook that is called each time the input is expanded
47
56
  */