@carbon/react 1.100.0-rc.0 → 1.101.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 (148) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +933 -933
  2. package/es/components/AILabel/index.d.ts +1 -1
  3. package/es/components/AILabel/index.js +1 -12
  4. package/es/components/Checkbox/Checkbox.js +5 -3
  5. package/es/components/CheckboxGroup/CheckboxGroup.js +4 -3
  6. package/es/components/CodeSnippet/CodeSnippet.d.ts +1 -1
  7. package/es/components/ComboBox/ComboBox.d.ts +3 -4
  8. package/es/components/ComboBox/ComboBox.js +20 -18
  9. package/es/components/ComboButton/index.d.ts +1 -1
  10. package/es/components/ComboButton/index.js +3 -2
  11. package/es/components/ComposedModal/ComposedModal.js +17 -22
  12. package/es/components/ComposedModal/ModalHeader.d.ts +2 -2
  13. package/es/components/ComposedModal/ModalHeader.js +1 -1
  14. package/es/components/Copy/Copy.d.ts +1 -1
  15. package/es/components/CopyButton/CopyButton.d.ts +1 -1
  16. package/es/components/DataTable/DataTable.d.ts +2 -0
  17. package/es/components/DataTable/DataTable.js +6 -5
  18. package/es/components/DataTable/Table.d.ts +1 -1
  19. package/es/components/DataTable/Table.js +10 -4
  20. package/es/components/DataTable/state/sorting.d.ts +4 -2
  21. package/es/components/Dropdown/Dropdown.d.ts +3 -4
  22. package/es/components/Dropdown/Dropdown.js +16 -13
  23. package/es/components/FileUploader/FileUploaderItem.d.ts +1 -1
  24. package/es/components/FileUploader/FileUploaderItem.js +3 -2
  25. package/es/components/FluidComboBox/FluidComboBox.d.ts +2 -7
  26. package/es/components/FluidComboBox/FluidComboBox.js +1 -2
  27. package/es/components/FluidDropdown/FluidDropdown.d.ts +1 -6
  28. package/es/components/FluidDropdown/FluidDropdown.js +1 -2
  29. package/es/components/FluidMultiSelect/FluidMultiSelect.d.ts +1 -6
  30. package/es/components/FluidMultiSelect/FluidMultiSelect.js +1 -2
  31. package/es/components/InlineLoading/InlineLoading.js +5 -11
  32. package/es/components/Menu/Menu.js +8 -4
  33. package/es/components/Menu/MenuItem.d.ts +5 -1
  34. package/es/components/Menu/MenuItem.js +11 -1
  35. package/es/components/MenuButton/index.d.ts +1 -1
  36. package/es/components/MenuButton/index.js +3 -2
  37. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  38. package/es/components/MultiSelect/FilterableMultiSelect.js +7 -5
  39. package/es/components/MultiSelect/MultiSelect.d.ts +3 -4
  40. package/es/components/MultiSelect/MultiSelect.js +10 -13
  41. package/es/components/Notification/Notification.js +5 -3
  42. package/es/components/NumberInput/NumberInput.d.ts +1 -1
  43. package/es/components/NumberInput/NumberInput.js +5 -4
  44. package/es/components/OverflowMenu/OverflowMenu.d.ts +1 -0
  45. package/es/components/OverflowMenu/OverflowMenu.js +8 -4
  46. package/es/components/PageHeader/PageHeader.d.ts +1 -1
  47. package/es/components/PageHeader/PageHeader.js +5 -5
  48. package/es/components/RadioButtonGroup/RadioButtonGroup.js +4 -3
  49. package/es/components/Select/Select.js +2 -1
  50. package/es/components/StructuredList/StructuredList.d.ts +1 -1
  51. package/es/components/StructuredList/StructuredList.js +2 -4
  52. package/es/components/Tabs/Tabs.d.ts +2 -2
  53. package/es/components/Tabs/Tabs.js +20 -26
  54. package/es/components/Tag/DismissibleTag.js +3 -2
  55. package/es/components/Tag/OperationalTag.js +3 -2
  56. package/es/components/Tag/SelectableTag.js +3 -2
  57. package/es/components/Tag/Tag.js +3 -2
  58. package/es/components/TextArea/TextArea.d.ts +1 -1
  59. package/es/components/TextArea/TextArea.js +7 -8
  60. package/es/components/TextInput/ControlledPasswordInput.js +7 -6
  61. package/es/components/TextInput/PasswordInput.js +5 -6
  62. package/es/components/TextInput/TextInput.js +4 -4
  63. package/es/components/Tile/Tile.d.ts +1 -1
  64. package/es/components/Tile/Tile.js +37 -69
  65. package/es/components/TimePicker/TimePicker.js +2 -2
  66. package/es/components/Tooltip/DefinitionTooltip.d.ts +1 -1
  67. package/es/components/Tooltip/DefinitionTooltip.js +3 -2
  68. package/es/components/UIShell/SideNav.d.ts +0 -1
  69. package/es/components/UIShell/SideNav.js +12 -3
  70. package/es/internal/useId.js +3 -4
  71. package/es/internal/usePresence.js +3 -2
  72. package/es/internal/useResizeObserver.d.ts +1 -1
  73. package/es/internal/useResizeObserver.js +5 -7
  74. package/es/tools/events.d.ts +1 -1
  75. package/lib/components/AILabel/index.d.ts +1 -1
  76. package/lib/components/AILabel/index.js +1 -12
  77. package/lib/components/Checkbox/Checkbox.js +5 -3
  78. package/lib/components/CheckboxGroup/CheckboxGroup.js +4 -3
  79. package/lib/components/CodeSnippet/CodeSnippet.d.ts +1 -1
  80. package/lib/components/ComboBox/ComboBox.d.ts +3 -4
  81. package/lib/components/ComboBox/ComboBox.js +20 -18
  82. package/lib/components/ComboButton/index.d.ts +1 -1
  83. package/lib/components/ComboButton/index.js +2 -1
  84. package/lib/components/ComposedModal/ComposedModal.js +16 -21
  85. package/lib/components/ComposedModal/ModalHeader.d.ts +2 -2
  86. package/lib/components/ComposedModal/ModalHeader.js +1 -1
  87. package/lib/components/Copy/Copy.d.ts +1 -1
  88. package/lib/components/CopyButton/CopyButton.d.ts +1 -1
  89. package/lib/components/DataTable/DataTable.d.ts +2 -0
  90. package/lib/components/DataTable/DataTable.js +6 -5
  91. package/lib/components/DataTable/Table.d.ts +1 -1
  92. package/lib/components/DataTable/Table.js +10 -4
  93. package/lib/components/DataTable/state/sorting.d.ts +4 -2
  94. package/lib/components/Dropdown/Dropdown.d.ts +3 -4
  95. package/lib/components/Dropdown/Dropdown.js +16 -13
  96. package/lib/components/FileUploader/FileUploaderItem.d.ts +1 -1
  97. package/lib/components/FileUploader/FileUploaderItem.js +2 -1
  98. package/lib/components/FluidComboBox/FluidComboBox.d.ts +2 -7
  99. package/lib/components/FluidComboBox/FluidComboBox.js +1 -2
  100. package/lib/components/FluidDropdown/FluidDropdown.d.ts +1 -6
  101. package/lib/components/FluidDropdown/FluidDropdown.js +1 -2
  102. package/lib/components/FluidMultiSelect/FluidMultiSelect.d.ts +1 -6
  103. package/lib/components/FluidMultiSelect/FluidMultiSelect.js +1 -2
  104. package/lib/components/InlineLoading/InlineLoading.js +5 -11
  105. package/lib/components/Menu/Menu.js +7 -3
  106. package/lib/components/Menu/MenuItem.d.ts +5 -1
  107. package/lib/components/Menu/MenuItem.js +11 -1
  108. package/lib/components/MenuButton/index.d.ts +1 -1
  109. package/lib/components/MenuButton/index.js +2 -1
  110. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  111. package/lib/components/MultiSelect/FilterableMultiSelect.js +6 -4
  112. package/lib/components/MultiSelect/MultiSelect.d.ts +3 -4
  113. package/lib/components/MultiSelect/MultiSelect.js +9 -12
  114. package/lib/components/Notification/Notification.js +5 -3
  115. package/lib/components/NumberInput/NumberInput.d.ts +1 -1
  116. package/lib/components/NumberInput/NumberInput.js +5 -4
  117. package/lib/components/OverflowMenu/OverflowMenu.d.ts +1 -0
  118. package/lib/components/OverflowMenu/OverflowMenu.js +7 -3
  119. package/lib/components/PageHeader/PageHeader.d.ts +1 -1
  120. package/lib/components/PageHeader/PageHeader.js +4 -4
  121. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +4 -3
  122. package/lib/components/Select/Select.js +2 -1
  123. package/lib/components/StructuredList/StructuredList.d.ts +1 -1
  124. package/lib/components/StructuredList/StructuredList.js +2 -4
  125. package/lib/components/Tabs/Tabs.d.ts +2 -2
  126. package/lib/components/Tabs/Tabs.js +15 -21
  127. package/lib/components/Tag/DismissibleTag.js +2 -1
  128. package/lib/components/Tag/OperationalTag.js +2 -1
  129. package/lib/components/Tag/SelectableTag.js +2 -1
  130. package/lib/components/Tag/Tag.js +2 -1
  131. package/lib/components/TextArea/TextArea.d.ts +1 -1
  132. package/lib/components/TextArea/TextArea.js +7 -8
  133. package/lib/components/TextInput/ControlledPasswordInput.js +7 -6
  134. package/lib/components/TextInput/PasswordInput.js +5 -6
  135. package/lib/components/TextInput/TextInput.js +4 -4
  136. package/lib/components/Tile/Tile.d.ts +1 -1
  137. package/lib/components/Tile/Tile.js +35 -67
  138. package/lib/components/TimePicker/TimePicker.js +2 -2
  139. package/lib/components/Tooltip/DefinitionTooltip.d.ts +1 -1
  140. package/lib/components/Tooltip/DefinitionTooltip.js +3 -2
  141. package/lib/components/UIShell/SideNav.d.ts +0 -1
  142. package/lib/components/UIShell/SideNav.js +11 -2
  143. package/lib/internal/useId.js +2 -3
  144. package/lib/internal/usePresence.js +2 -1
  145. package/lib/internal/useResizeObserver.d.ts +1 -1
  146. package/lib/internal/useResizeObserver.js +4 -6
  147. package/lib/tools/events.d.ts +1 -1
  148. package/package.json +8 -8
@@ -5,9 +5,9 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import React, { useState, useLayoutEffect, useEffect } from 'react';
8
+ import React, { useState, useEffect } from 'react';
9
9
  import { setupGetInstanceId } from '../tools/setupGetInstanceId.js';
10
- import { canUseDOM } from './environment.js';
10
+ import useIsomorphicEffect from './useIsomorphicEffect.js';
11
11
  import { useIdPrefix } from './useIdPrefix.js';
12
12
 
13
13
  // This file was heavily inspired by:
@@ -46,7 +46,6 @@ const _React = {
46
46
  ...React
47
47
  };
48
48
  const instanceId = setupGetInstanceId();
49
- const useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect;
50
49
  let serverHandoffCompleted = false;
51
50
  const defaultId = 'id';
52
51
 
@@ -64,7 +63,7 @@ function useCompatibleId(prefix = defaultId) {
64
63
  }
65
64
  return null;
66
65
  });
67
- useIsomorphicLayoutEffect(() => {
66
+ useIsomorphicEffect(() => {
68
67
  if (id === null) {
69
68
  setId(`${contextPrefix ? `${contextPrefix}-` : ``}${prefix}-${instanceId()}`);
70
69
  }
@@ -5,8 +5,9 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import { useState, useCallback, useLayoutEffect } from 'react';
8
+ import { useState, useCallback } from 'react';
9
9
  import { usePrefix } from './usePrefix.js';
10
+ import useIsomorphicEffect from './useIsomorphicEffect.js';
10
11
 
11
12
  const usePresence = (ref, isOpen) => {
12
13
  const prefix = usePrefix();
@@ -25,7 +26,7 @@ const usePresence = (ref, isOpen) => {
25
26
  const handleAnimationEnd = useCallback(() => {
26
27
  setExitState('finished');
27
28
  }, []);
28
- useLayoutEffect(() => {
29
+ useIsomorphicEffect(() => {
29
30
  if (!ref.current || !isExiting) return;
30
31
 
31
32
  // resolve for JSDOM
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2025, 2025
2
+ * Copyright IBM Corp. 2025, 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.
@@ -5,7 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import { useState, useRef, useEffect, useLayoutEffect } from 'react';
8
+ import { useState, useRef, useEffect } from 'react';
9
+ import useIsomorphicEffect from './useIsomorphicEffect.js';
9
10
 
10
11
  const useResizeObserver = ({
11
12
  ref,
@@ -16,7 +17,7 @@ const useResizeObserver = ({
16
17
  const entriesToHandle = useRef(null);
17
18
  const cb = useRef(onResize);
18
19
  useEffect(() => {
19
- // ref for onResize removes it as dependency from useLayoutEffect
20
+ // ref for onResize removes it as dependency from useIsomorphicEffect
20
21
  // This significantly reduces repeated calls if a function is redefined on every
21
22
  // render
22
23
  cb.current = onResize;
@@ -37,7 +38,7 @@ const useResizeObserver = ({
37
38
  getInitialSize();
38
39
  // eslint-disable-next-line react-hooks/exhaustive-deps -- https://github.com/carbon-design-system/carbon/issues/20452
39
40
  }, [width, height]);
40
- useLayoutEffect(() => {
41
+ useIsomorphicEffect(() => {
41
42
  if (!ref?.current) {
42
43
  return;
43
44
  }
@@ -48,9 +49,7 @@ const useResizeObserver = ({
48
49
  const entry = entriesToHandle.current[0];
49
50
  setWidth(entry.contentRect.width);
50
51
  setHeight(entry.contentRect.height);
51
-
52
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- https://github.com/carbon-design-system/carbon/issues/20452
53
- cb.current && cb.current(entry.contentRect);
52
+ cb.current?.(entry.contentRect);
54
53
  };
55
54
  const observer = new ResizeObserver(entries => {
56
55
  // always update entriesToHandle
@@ -66,7 +65,6 @@ const useResizeObserver = ({
66
65
  return () => {
67
66
  observer.disconnect();
68
67
  };
69
- // eslint-disable-next-line react-hooks/exhaustive-deps -- https://github.com/carbon-design-system/carbon/issues/20452
70
68
  }, []);
71
69
  return {
72
70
  width,
@@ -14,4 +14,4 @@ import type { SyntheticEvent } from 'react';
14
14
  * @param handlers - An array of event handler functions.
15
15
  * @returns A composite event handler.
16
16
  */
17
- export declare const composeEventHandlers: <E extends SyntheticEvent = SyntheticEvent<Element, Event>>(handlers: (((event: E, ...args: any[]) => void) | undefined)[]) => (event: E, ...args: any[]) => void;
17
+ export declare const composeEventHandlers: <E extends SyntheticEvent = SyntheticEvent>(handlers: (((event: E, ...args: any[]) => void) | undefined)[]) => (event: E, ...args: any[]) => 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.
@@ -25,20 +25,9 @@ const AILabelContent = /*#__PURE__*/React.forwardRef(function AILabelContent({
25
25
  }, ref // eslint-disable-line @typescript-eslint/no-unused-vars -- https://github.com/carbon-design-system/carbon/issues/20452
26
26
  ) {
27
27
  const prefix = usePrefix.usePrefix();
28
- const hasAILabelActions = React.Children.toArray(children).some(child => {
29
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20452
30
- const item = child;
31
- // TODO: Is there supposed to be a `return` here? If so, this issue would
32
- // have been caught by ESLint. It's concerning that this code is 7 months
33
- // old and no one has noticed any issues with it. It also makes me question
34
- // whether the code is necessary.
35
- // https://github.com/carbon-design-system/carbon/issues/18991
36
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- https://github.com/carbon-design-system/carbon/issues/20452
37
- item.type === AILabelActions;
38
- });
39
28
  const aiLabelContentClasses = cx(className, {
40
29
  [`${prefix}--ai-label-content`]: true,
41
- [`${prefix}--ai-label-content--with-actions`]: hasAILabelActions
30
+ [`${prefix}--ai-label-content--with-actions`]: false
42
31
  });
43
32
  return /*#__PURE__*/React.createElement(index.ToggletipContent, {
44
33
  className: aiLabelContentClasses
@@ -46,11 +46,12 @@ const Checkbox = /*#__PURE__*/React.forwardRef(({
46
46
  const showWarning = !readOnly && !invalid && warn;
47
47
  const showHelper = !invalid && !warn;
48
48
  const checkboxGroupInstanceId = useId.useId();
49
- const helperId = !helperText ? undefined : `checkbox-helper-text-${checkboxGroupInstanceId}`;
50
- const helper = helperText ? /*#__PURE__*/React.createElement("div", {
49
+ const hasHelper = typeof helperText !== 'undefined' && helperText !== null;
50
+ const helperId = !hasHelper ? undefined : `checkbox-helper-text-${checkboxGroupInstanceId}`;
51
+ const helper = hasHelper && /*#__PURE__*/React.createElement("div", {
51
52
  id: helperId,
52
53
  className: `${prefix}--form__helper-text`
53
- }, helperText) : null;
54
+ }, helperText);
54
55
  const wrapperClasses = cx(`${prefix}--form-item`, `${prefix}--checkbox-wrapper`, className, {
55
56
  [`${prefix}--checkbox-wrapper--readonly`]: readOnly,
56
57
  [`${prefix}--checkbox-wrapper--invalid`]: !readOnly && invalid,
@@ -110,6 +111,7 @@ const Checkbox = /*#__PURE__*/React.forwardRef(({
110
111
  className: `${prefix}--checkbox-label`,
111
112
  title: title
112
113
  }, /*#__PURE__*/React.createElement(Text.Text, {
114
+ as: "div",
113
115
  className: innerLabelClasses
114
116
  }, labelText, slug ? normalizedDecorator : decorator ? /*#__PURE__*/React.createElement("div", {
115
117
  className: `${prefix}--checkbox-wrapper-inner--decorator`
@@ -42,11 +42,12 @@ const CheckboxGroup = ({
42
42
  const showWarning = !readOnly && !invalid && warn;
43
43
  const showHelper = !invalid && !warn;
44
44
  const checkboxGroupInstanceId = useId.useId();
45
- const helperId = !helperText ? undefined : `checkbox-group-helper-text-${checkboxGroupInstanceId}`;
46
- const helper = helperText ? /*#__PURE__*/React.createElement("div", {
45
+ const hasHelper = typeof helperText !== 'undefined' && helperText !== null;
46
+ const helperId = !hasHelper ? undefined : `checkbox-group-helper-text-${checkboxGroupInstanceId}`;
47
+ const helper = hasHelper && /*#__PURE__*/React.createElement("div", {
47
48
  id: helperId,
48
49
  className: `${prefix}--form__helper-text`
49
- }, helperText) : null;
50
+ }, helperText);
50
51
  const fieldsetClasses = cx(`${prefix}--checkbox-group`, className, {
51
52
  [`${prefix}--checkbox-group--${orientation}`]: orientation === 'horizontal',
52
53
  [`${prefix}--checkbox-group--readonly`]: readOnly,
@@ -111,7 +111,7 @@ declare namespace CodeSnippet {
111
111
  /**
112
112
  * Specify how the trigger should align with the tooltip
113
113
  */
114
- align: PropTypes.Requireable<string> | PropTypes.Validator<string>;
114
+ align: PropTypes.Requireable<import("@floating-ui/utils").Placement | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "left-bottom" | "left-top" | "right-bottom" | "right-top"> | PropTypes.Validator<import("@floating-ui/utils").Placement | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "left-bottom" | "left-top" | "right-bottom" | "right-top">;
115
115
  /**
116
116
  * Specify a label to be read by screen readers on the containing textbox
117
117
  * node
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { UseComboboxProps, UseComboboxActions } from 'downshift';
8
- import { type ComponentType, type InputHTMLAttributes, type MouseEvent, type PropsWithChildren, type ReactElement, type ReactNode, type RefAttributes, type RefObject } from 'react';
8
+ import { type InputHTMLAttributes, type MouseEvent, type PropsWithChildren, type ReactElement, type ReactNode, type RefAttributes, type RefObject } from 'react';
9
9
  import { type ListBoxMenuIconTranslationKey, type ListBoxSelectionTranslationKey, type ListBoxSize } from '../ListBox';
10
10
  import type { TranslateWithId } from '../../types/common';
11
11
  type ExcludedAttributes = 'id' | 'onChange' | 'onClick' | 'type' | 'size';
@@ -98,10 +98,9 @@ export interface ComboBoxProps<ItemType> extends Omit<InputHTMLAttributes<HTMLIn
98
98
  */
99
99
  invalidText?: ReactNode;
100
100
  /**
101
- * Optional function to render items as custom components instead of strings.
102
- * Defaults to null and is overridden by a getter
101
+ * Renders an item as a custom React node instead of a string.
103
102
  */
104
- itemToElement?: ComponentType<ItemType> | null;
103
+ itemToElement?: ((item: ItemType) => ReactNode) | null;
105
104
  /**
106
105
  * Helper function passed to downshift that allows the library to render a
107
106
  * given item to a string label. By default, it extracts the `label` field
@@ -27,6 +27,7 @@ var useId = require('../../internal/useId.js');
27
27
  var mergeRefs = require('../../tools/mergeRefs.js');
28
28
  var deprecate = require('../../prop-types/deprecate.js');
29
29
  var usePrefix = require('../../internal/usePrefix.js');
30
+ var useNormalizedInputProps = require('../../internal/useNormalizedInputProps.js');
30
31
  require('../FluidForm/FluidForm.js');
31
32
  var FormContext = require('../FluidForm/FormContext.js');
32
33
  var react = require('@floating-ui/react');
@@ -251,8 +252,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
251
252
  React.useEffect(() => {
252
253
  if (prevInputValue.current !== inputValue) {
253
254
  prevInputValue.current = inputValue;
254
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- https://github.com/carbon-design-system/carbon/issues/20452
255
- onInputChange && onInputChange(inputValue);
255
+ onInputChange?.(inputValue);
256
256
  }
257
257
  // eslint-disable-next-line react-hooks/exhaustive-deps -- https://github.com/carbon-design-system/carbon/issues/20452
258
258
  }, [inputValue]);
@@ -427,11 +427,19 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
427
427
  event?.persist?.();
428
428
  }
429
429
  };
430
- const showWarning = !invalid && warn;
430
+ const normalizedProps = useNormalizedInputProps.useNormalizedInputProps({
431
+ id,
432
+ readOnly,
433
+ disabled: disabled || false,
434
+ invalid: invalid || false,
435
+ invalidText,
436
+ warn: warn || false,
437
+ warnText
438
+ });
431
439
  const className = cx(`${prefix}--combo-box`, {
432
440
  [`${prefix}--combo-box--invalid--focused`]: invalid && isFocused,
433
441
  [`${prefix}--list-box--up`]: direction === 'top',
434
- [`${prefix}--combo-box--warning`]: showWarning,
442
+ [`${prefix}--combo-box--warning`]: normalizedProps.warn,
435
443
  [`${prefix}--combo-box--readonly`]: readOnly,
436
444
  [`${prefix}--autoalign`]: enableFloatingStyles
437
445
  });
@@ -454,9 +462,6 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
454
462
  [`${prefix}--combo-box--input--focus`]: isFocused
455
463
  });
456
464
 
457
- // needs to be Capitalized for react to render it correctly
458
- const ItemToElement = itemToElement;
459
-
460
465
  // AILabel always size `mini`
461
466
  const candidate = slug ?? decorator;
462
467
  const candidateIsAILabel = utils.isComponentElement(candidate, index$1.AILabel);
@@ -604,7 +609,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
604
609
  // The input should be described by the appropriate message text id
605
610
  // when both the message is supplied *and* when the component is in
606
611
  // the matching state (invalid, warn, etc).
607
- const ariaDescribedBy = invalid && invalidText && invalidTextId || warn && warnText && warnTextId || helperText && !isFluid && helperTextId || undefined;
612
+ const ariaDescribedBy = normalizedProps.invalid && invalidText && invalidTextId || normalizedProps.warn && warnText && warnTextId || helperText && !isFluid && helperTextId || undefined;
608
613
 
609
614
  // Memoize the value of getMenuProps to avoid an infinite loop
610
615
  const menuProps = React.useMemo(() => getMenuProps({
@@ -632,13 +637,13 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
632
637
  onBlur: handleFocus,
633
638
  className: className,
634
639
  disabled: disabled,
635
- invalid: invalid,
640
+ invalid: normalizedProps.invalid,
636
641
  invalidText: invalidText,
637
642
  invalidTextId: invalidTextId,
638
643
  isOpen: isOpen,
639
644
  light: light,
640
645
  size: size,
641
- warn: warn,
646
+ warn: normalizedProps.warn,
642
647
  ref: enableFloatingStyles ? refs.setReference : null,
643
648
  warnText: warnText,
644
649
  warnTextId: warnTextId
@@ -740,9 +745,9 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
740
745
  }), rest, readOnlyEventHandlers, {
741
746
  readOnly: readOnly,
742
747
  "aria-describedby": ariaDescribedBy
743
- })), invalid && /*#__PURE__*/React.createElement(iconsReact.WarningFilled, {
748
+ })), normalizedProps.invalid && /*#__PURE__*/React.createElement(iconsReact.WarningFilled, {
744
749
  className: `${prefix}--list-box__invalid-icon`
745
- }), showWarning && /*#__PURE__*/React.createElement(iconsReact.WarningAltFilled, {
750
+ }), normalizedProps.warn && /*#__PURE__*/React.createElement(iconsReact.WarningAltFilled, {
746
751
  className: `${prefix}--list-box__invalid-icon ${prefix}--list-box__invalid-icon--warning`
747
752
  }), inputValue && /*#__PURE__*/React.createElement(ListBoxSelection.default, {
748
753
  clearSelection: () => {
@@ -788,12 +793,10 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
788
793
  isHighlighted: highlightedIndex === index,
789
794
  title: title,
790
795
  disabled: disabled
791
- }, modifiedItemProps), ItemToElement ? /*#__PURE__*/React.createElement(ItemToElement, _rollupPluginBabelHelpers.extends({
792
- key: itemProps.id
793
- }, item)) : itemToString(item), isEqual(currentSelectedItem, item) && /*#__PURE__*/React.createElement(iconsReact.Checkmark, {
796
+ }, modifiedItemProps), itemToElement ? itemToElement(item) : itemToString(item), isEqual(currentSelectedItem, item) && /*#__PURE__*/React.createElement(iconsReact.Checkmark, {
794
797
  className: `${prefix}--list-box__menu-item__selected-icon`
795
798
  }));
796
- }) : null)), helperText && !invalid && !warn && !isFluid && /*#__PURE__*/React.createElement(Text.Text, {
799
+ }) : null)), helperText && !normalizedProps.invalid && !normalizedProps.warn && !isFluid && /*#__PURE__*/React.createElement(Text.Text, {
797
800
  as: "div",
798
801
  id: helperTextId,
799
802
  className: helperClasses
@@ -886,8 +889,7 @@ ComboBox.propTypes = {
886
889
  */
887
890
  invalidText: PropTypes.node,
888
891
  /**
889
- * Optional function to render items as custom components instead of strings.
890
- * Defaults to null and is overridden by a getter
892
+ * Renders an item as a custom React node instead of a string.
891
893
  */
892
894
  itemToElement: PropTypes.func,
893
895
  /**
@@ -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.
@@ -20,6 +20,7 @@ require('../Menu/MenuItem.js');
20
20
  var useAttachedMenu = require('../../internal/useAttachedMenu.js');
21
21
  var useId = require('../../internal/useId.js');
22
22
  var usePrefix = require('../../internal/usePrefix.js');
23
+ var useIsomorphicEffect = require('../../internal/useIsomorphicEffect.js');
23
24
  var react = require('@floating-ui/react');
24
25
  var index = require('../FeatureFlags/index.js');
25
26
  var mergeRefs = require('../../tools/mergeRefs.js');
@@ -96,7 +97,7 @@ const ComboButton = /*#__PURE__*/React.forwardRef(function ComboButton({
96
97
  handleMousedown: handleTriggerMousedown,
97
98
  handleClose
98
99
  } = useAttachedMenu.useAttachedMenu(containerRef);
99
- React.useLayoutEffect(() => {
100
+ useIsomorphicEffect.default(() => {
100
101
  const updatedFloatingStyles = {
101
102
  ...floatingStyles,
102
103
  visibility: middlewareData.hide?.referenceHidden ? 'hidden' : 'visible'
@@ -12,7 +12,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
12
12
  var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
13
13
  var React = require('react');
14
14
  var useResizeObserver = require('../../internal/useResizeObserver.js');
15
- var reactIs = require('react-is');
16
15
  var PropTypes = require('prop-types');
17
16
  var index = require('../Layer/index.js');
18
17
  var ModalHeader = require('./ModalHeader.js');
@@ -263,29 +262,25 @@ const ComposedModalDialog = /*#__PURE__*/React.forwardRef(function ComposedModal
263
262
  const containerClass = cx(`${prefix}--modal-container`, size && `${prefix}--modal-container--${size}`, isFullWidth && `${prefix}--modal-container--full-width`, containerClassName);
264
263
 
265
264
  // Generate aria-label based on Modal Header label if one is not provided (L253)
265
+ //
266
+ // TODO: Confirm whether `ModalHeader` `label` should allow `ReactNode`. If
267
+ // so, define how to derive a string for `aria-label`.
266
268
  let generatedAriaLabel;
267
269
  const childrenWithProps = React.Children.toArray(children).map(child => {
268
- switch (true) {
269
- case reactIs.isElement(child) && child.type === /*#__PURE__*/React.createElement(ModalHeader.ModalHeader).type:
270
- {
271
- const el = child;
272
- generatedAriaLabel = el.props.label;
273
- return /*#__PURE__*/React.cloneElement(el, {
274
- closeModal
275
- });
276
- }
277
- case reactIs.isElement(child) && child.type === /*#__PURE__*/React.createElement(ModalFooter.ModalFooter).type:
278
- {
279
- const el = child;
280
- return /*#__PURE__*/React.cloneElement(el, {
281
- closeModal,
282
- inputref: button,
283
- danger
284
- });
285
- }
286
- default:
287
- return child;
270
+ if (utils.isComponentElement(child, ModalHeader.ModalHeader)) {
271
+ generatedAriaLabel = child.props.label;
272
+ return /*#__PURE__*/React.cloneElement(child, {
273
+ closeModal
274
+ });
275
+ }
276
+ if (utils.isComponentElement(child, ModalFooter.ModalFooter)) {
277
+ return /*#__PURE__*/React.cloneElement(child, {
278
+ closeModal,
279
+ inputref: button,
280
+ danger
281
+ });
288
282
  }
283
+ return child;
289
284
  });
290
285
 
291
286
  // Modals without a footer are considered passive and carry limitations as
@@ -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.
@@ -40,7 +40,7 @@ export interface ModalHeaderProps extends DivProps {
40
40
  /**
41
41
  * Specify an optional label to be displayed
42
42
  */
43
- label?: ReactNode;
43
+ label?: string;
44
44
  /**
45
45
  * Specify an optional className to be applied to the modal header label
46
46
  */
@@ -96,7 +96,7 @@ ModalHeader.propTypes = {
96
96
  /**
97
97
  * Specify an optional label to be displayed
98
98
  */
99
- label: PropTypes.node,
99
+ label: PropTypes.string,
100
100
  /**
101
101
  * Specify an optional className to be applied to the modal header label
102
102
  */
@@ -50,7 +50,7 @@ declare namespace Copy {
50
50
  /**
51
51
  * Specify how the trigger should align with the tooltip
52
52
  */
53
- align: PropTypes.Requireable<string> | PropTypes.Validator<string>;
53
+ align: PropTypes.Requireable<import("@floating-ui/utils").Placement | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "left-bottom" | "left-top" | "right-bottom" | "right-top"> | PropTypes.Validator<import("@floating-ui/utils").Placement | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "left-bottom" | "left-top" | "right-bottom" | "right-top">;
54
54
  /**
55
55
  * **Experimental**: Will attempt to automatically align the tooltip. Requires
56
56
  * React v17+
@@ -51,7 +51,7 @@ declare namespace CopyButton {
51
51
  /**
52
52
  * Specify how the trigger should align with the tooltip
53
53
  */
54
- align: PropTypes.Requireable<string> | PropTypes.Validator<string>;
54
+ align: PropTypes.Requireable<import("@floating-ui/utils").Placement | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "left-bottom" | "left-top" | "right-bottom" | "right-top"> | PropTypes.Validator<import("@floating-ui/utils").Placement | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "left-bottom" | "left-top" | "right-bottom" | "right-top">;
55
55
  /**
56
56
  * **Experimental**: Will attempt to automatically align the tooltip. Requires
57
57
  * React v17+
@@ -51,6 +51,7 @@ export interface DataTableHeader {
51
51
  header: ReactNode;
52
52
  slug?: ReactElement;
53
53
  decorator?: ReactElement;
54
+ isSortable?: boolean;
54
55
  }
55
56
  export interface DataTableRenderProps<RowType, ColTypes extends any[]> {
56
57
  /**
@@ -435,6 +436,7 @@ export declare const DataTable: {
435
436
  headers: PropTypes.Validator<(PropTypes.InferProps<{
436
437
  key: PropTypes.Validator<string>;
437
438
  header: PropTypes.Validator<NonNullable<PropTypes.ReactNodeLike>>;
439
+ isSortable: PropTypes.Requireable<boolean>;
438
440
  }> | null | undefined)[]>;
439
441
  /**
440
442
  * Specify whether the table should be able to be sorted by its headers
@@ -98,7 +98,7 @@ const DataTable = props => {
98
98
  render,
99
99
  translateWithId: t = defaultTranslateWithId,
100
100
  size,
101
- isSortable: isSortableProp,
101
+ isSortable,
102
102
  useZebraStyles,
103
103
  useStaticWidth,
104
104
  stickyHeader,
@@ -137,7 +137,7 @@ const DataTable = props => {
137
137
  const getHeaderProps = ({
138
138
  header,
139
139
  onClick,
140
- isSortable = isSortableProp,
140
+ isSortable: headerIsSortable,
141
141
  ...rest
142
142
  }) => {
143
143
  const {
@@ -153,7 +153,7 @@ const DataTable = props => {
153
153
  ...rest,
154
154
  key,
155
155
  sortDirection,
156
- isSortable,
156
+ isSortable: headerIsSortable ?? header.isSortable ?? isSortable,
157
157
  isSortHeader: sortHeaderKey === key,
158
158
  slug,
159
159
  decorator,
@@ -312,7 +312,7 @@ const DataTable = props => {
312
312
  return {
313
313
  useZebraStyles,
314
314
  size: size ?? 'lg',
315
- isSortable: isSortableProp,
315
+ isSortable,
316
316
  useStaticWidth,
317
317
  stickyHeader,
318
318
  overflowMenuOnHover: overflowMenuOnHover ?? false,
@@ -602,7 +602,8 @@ DataTable.propTypes = {
602
602
  */
603
603
  headers: PropTypes.arrayOf(PropTypes.shape({
604
604
  key: PropTypes.string.isRequired,
605
- header: PropTypes.node.isRequired
605
+ header: PropTypes.node.isRequired,
606
+ isSortable: PropTypes.bool
606
607
  })).isRequired,
607
608
  /**
608
609
  * Specify whether the table should be able to be sorted by its headers
@@ -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,12 +74,18 @@ const Table = ({
74
74
  [`${prefix}--data-table--visible-overflow-menu`]: !overflowMenuOnHover
75
75
  });
76
76
  const toggleTableBodyAlignmentClass = React.useCallback((alignTop = false) => {
77
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- https://github.com/carbon-design-system/carbon/issues/20452
78
- alignTop ? tableRef.current?.classList.add(`${prefix}--data-table--top-aligned-body`) : tableRef.current?.classList.remove(`${prefix}--data-table--top-aligned-body`);
77
+ if (alignTop) {
78
+ tableRef.current?.classList.add(`${prefix}--data-table--top-aligned-body`);
79
+ } else {
80
+ tableRef.current?.classList.remove(`${prefix}--data-table--top-aligned-body`);
81
+ }
79
82
  }, [prefix]);
80
83
  const toggleTableHeaderAlignmentClass = React.useCallback((alignTop = false) => {
81
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- https://github.com/carbon-design-system/carbon/issues/20452
82
- alignTop ? tableRef.current?.classList.add(`${prefix}--data-table--top-aligned-header`) : tableRef.current?.classList.remove(`${prefix}--data-table--top-aligned-header`);
84
+ if (alignTop) {
85
+ tableRef.current?.classList.add(`${prefix}--data-table--top-aligned-header`);
86
+ } else {
87
+ tableRef.current?.classList.remove(`${prefix}--data-table--top-aligned-header`);
88
+ }
83
89
  }, [prefix]);
84
90
  const setTableAlignment = React.useCallback(() => {
85
91
  if (experimentalAutoAlign) {
@@ -43,7 +43,8 @@ export declare const getNextSortDirection: (prevHeader: string, currentHeader: s
43
43
  * @param state - Current table state.
44
44
  * @param key - Header key to sort by.
45
45
  */
46
- export declare const getNextSortState: <ColTypes extends any[]>(props: Props, state: State<ColTypes>, { key }: {
46
+ export declare const getNextSortState: <ColTypes extends any[]>(// eslint-disable-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20452
47
+ props: Props, state: State<ColTypes>, { key }: {
47
48
  key: string;
48
49
  }) => Pick<State<ColTypes>, "sortHeaderKey" | "sortDirection" | "rowIds">;
49
50
  /**
@@ -54,5 +55,6 @@ export declare const getNextSortState: <ColTypes extends any[]>(props: Props, st
54
55
  * @param key - Header key to sort by.
55
56
  * @param sortDirection - Sort direction to apply.
56
57
  */
57
- export declare const getSortedState: <ColTypes extends any[]>({ locale, sortRow }: Props, { rowIds, cellsById, initialRowOrder }: State<ColTypes>, key: string, sortDirection: DataTableSortState) => Pick<State<ColTypes>, "rowIds" | "sortDirection" | "sortHeaderKey">;
58
+ export declare const getSortedState: <ColTypes extends any[]>(// eslint-disable-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20452
59
+ { locale, sortRow }: Props, { rowIds, cellsById, initialRowOrder }: State<ColTypes>, key: string, sortDirection: DataTableSortState) => Pick<State<ColTypes>, "rowIds" | "sortDirection" | "sortHeaderKey">;
58
60
  export {};
@@ -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.
@@ -78,10 +78,9 @@ export interface DropdownProps<ItemType> extends Omit<HTMLAttributes<HTMLDivElem
78
78
  */
79
79
  invalidText?: ReactNode;
80
80
  /**
81
- * Function to render items as custom components instead of strings.
82
- * Defaults to null and is overridden by a getter
81
+ * Renders an item as a custom React node instead of a string.
83
82
  */
84
- itemToElement?: React.JSXElementConstructor<ItemType> | null;
83
+ itemToElement?: ((item: ItemType) => NonNullable<ReactNode>) | null;
85
84
  /**
86
85
  * Helper function passed to downshift that allows the library to render a
87
86
  * given item to a string label. By default, it extracts the `label` field