@carbon/react 1.100.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 (118) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +966 -966
  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.js +18 -10
  8. package/es/components/ComboButton/index.d.ts +1 -1
  9. package/es/components/ComboButton/index.js +3 -2
  10. package/es/components/ComposedModal/ComposedModal.js +17 -22
  11. package/es/components/ComposedModal/ModalHeader.d.ts +2 -2
  12. package/es/components/ComposedModal/ModalHeader.js +1 -1
  13. package/es/components/Copy/Copy.d.ts +1 -1
  14. package/es/components/CopyButton/CopyButton.d.ts +1 -1
  15. package/es/components/DataTable/DataTable.d.ts +2 -0
  16. package/es/components/DataTable/DataTable.js +6 -5
  17. package/es/components/DataTable/Table.d.ts +1 -1
  18. package/es/components/DataTable/Table.js +10 -4
  19. package/es/components/DataTable/state/sorting.d.ts +4 -2
  20. package/es/components/FileUploader/FileUploaderItem.d.ts +1 -1
  21. package/es/components/FileUploader/FileUploaderItem.js +3 -2
  22. package/es/components/Menu/Menu.js +8 -4
  23. package/es/components/Menu/MenuItem.d.ts +5 -1
  24. package/es/components/Menu/MenuItem.js +11 -1
  25. package/es/components/MenuButton/index.d.ts +1 -1
  26. package/es/components/MenuButton/index.js +3 -2
  27. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  28. package/es/components/MultiSelect/FilterableMultiSelect.js +7 -5
  29. package/es/components/MultiSelect/MultiSelect.js +8 -4
  30. package/es/components/Notification/Notification.js +2 -1
  31. package/es/components/NumberInput/NumberInput.d.ts +1 -1
  32. package/es/components/NumberInput/NumberInput.js +5 -4
  33. package/es/components/OverflowMenu/OverflowMenu.d.ts +1 -0
  34. package/es/components/OverflowMenu/OverflowMenu.js +8 -4
  35. package/es/components/PageHeader/PageHeader.d.ts +1 -1
  36. package/es/components/PageHeader/PageHeader.js +5 -5
  37. package/es/components/RadioButtonGroup/RadioButtonGroup.js +4 -3
  38. package/es/components/Select/Select.js +2 -1
  39. package/es/components/StructuredList/StructuredList.d.ts +1 -1
  40. package/es/components/StructuredList/StructuredList.js +2 -4
  41. package/es/components/Tabs/Tabs.d.ts +2 -2
  42. package/es/components/Tabs/Tabs.js +20 -26
  43. package/es/components/Tag/DismissibleTag.js +3 -2
  44. package/es/components/Tag/OperationalTag.js +3 -2
  45. package/es/components/Tag/SelectableTag.js +3 -2
  46. package/es/components/Tag/Tag.js +3 -2
  47. package/es/components/TextArea/TextArea.d.ts +1 -1
  48. package/es/components/TextArea/TextArea.js +6 -5
  49. package/es/components/TextInput/ControlledPasswordInput.js +7 -6
  50. package/es/components/TextInput/PasswordInput.js +5 -6
  51. package/es/components/TextInput/TextInput.js +4 -4
  52. package/es/components/TimePicker/TimePicker.js +2 -2
  53. package/es/components/Tooltip/DefinitionTooltip.d.ts +1 -1
  54. package/es/components/Tooltip/DefinitionTooltip.js +3 -2
  55. package/es/internal/useId.js +3 -4
  56. package/es/internal/usePresence.js +3 -2
  57. package/es/internal/useResizeObserver.d.ts +1 -1
  58. package/es/internal/useResizeObserver.js +5 -7
  59. package/es/tools/events.d.ts +1 -1
  60. package/lib/components/AILabel/index.d.ts +1 -1
  61. package/lib/components/AILabel/index.js +1 -12
  62. package/lib/components/Checkbox/Checkbox.js +5 -3
  63. package/lib/components/CheckboxGroup/CheckboxGroup.js +4 -3
  64. package/lib/components/CodeSnippet/CodeSnippet.d.ts +1 -1
  65. package/lib/components/ComboBox/ComboBox.js +18 -10
  66. package/lib/components/ComboButton/index.d.ts +1 -1
  67. package/lib/components/ComboButton/index.js +2 -1
  68. package/lib/components/ComposedModal/ComposedModal.js +16 -21
  69. package/lib/components/ComposedModal/ModalHeader.d.ts +2 -2
  70. package/lib/components/ComposedModal/ModalHeader.js +1 -1
  71. package/lib/components/Copy/Copy.d.ts +1 -1
  72. package/lib/components/CopyButton/CopyButton.d.ts +1 -1
  73. package/lib/components/DataTable/DataTable.d.ts +2 -0
  74. package/lib/components/DataTable/DataTable.js +6 -5
  75. package/lib/components/DataTable/Table.d.ts +1 -1
  76. package/lib/components/DataTable/Table.js +10 -4
  77. package/lib/components/DataTable/state/sorting.d.ts +4 -2
  78. package/lib/components/FileUploader/FileUploaderItem.d.ts +1 -1
  79. package/lib/components/FileUploader/FileUploaderItem.js +2 -1
  80. package/lib/components/Menu/Menu.js +7 -3
  81. package/lib/components/Menu/MenuItem.d.ts +5 -1
  82. package/lib/components/Menu/MenuItem.js +11 -1
  83. package/lib/components/MenuButton/index.d.ts +1 -1
  84. package/lib/components/MenuButton/index.js +2 -1
  85. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  86. package/lib/components/MultiSelect/FilterableMultiSelect.js +6 -4
  87. package/lib/components/MultiSelect/MultiSelect.js +7 -3
  88. package/lib/components/Notification/Notification.js +2 -1
  89. package/lib/components/NumberInput/NumberInput.d.ts +1 -1
  90. package/lib/components/NumberInput/NumberInput.js +5 -4
  91. package/lib/components/OverflowMenu/OverflowMenu.d.ts +1 -0
  92. package/lib/components/OverflowMenu/OverflowMenu.js +7 -3
  93. package/lib/components/PageHeader/PageHeader.d.ts +1 -1
  94. package/lib/components/PageHeader/PageHeader.js +4 -4
  95. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +4 -3
  96. package/lib/components/Select/Select.js +2 -1
  97. package/lib/components/StructuredList/StructuredList.d.ts +1 -1
  98. package/lib/components/StructuredList/StructuredList.js +2 -4
  99. package/lib/components/Tabs/Tabs.d.ts +2 -2
  100. package/lib/components/Tabs/Tabs.js +15 -21
  101. package/lib/components/Tag/DismissibleTag.js +2 -1
  102. package/lib/components/Tag/OperationalTag.js +2 -1
  103. package/lib/components/Tag/SelectableTag.js +2 -1
  104. package/lib/components/Tag/Tag.js +2 -1
  105. package/lib/components/TextArea/TextArea.d.ts +1 -1
  106. package/lib/components/TextArea/TextArea.js +6 -5
  107. package/lib/components/TextInput/ControlledPasswordInput.js +7 -6
  108. package/lib/components/TextInput/PasswordInput.js +5 -6
  109. package/lib/components/TextInput/TextInput.js +4 -4
  110. package/lib/components/TimePicker/TimePicker.js +2 -2
  111. package/lib/components/Tooltip/DefinitionTooltip.d.ts +1 -1
  112. package/lib/components/Tooltip/DefinitionTooltip.js +3 -2
  113. package/lib/internal/useId.js +2 -3
  114. package/lib/internal/usePresence.js +2 -1
  115. package/lib/internal/useResizeObserver.d.ts +1 -1
  116. package/lib/internal/useResizeObserver.js +4 -6
  117. package/lib/tools/events.d.ts +1 -1
  118. package/package.json +8 -8
@@ -141,19 +141,19 @@ const TextInput = /*#__PURE__*/forwardRef(({
141
141
  as: "div",
142
142
  className: counterClasses
143
143
  }, `${textCount}/${maxCount}`) : null;
144
- const label = labelText ? /*#__PURE__*/React.createElement(Text, {
144
+ const label = typeof labelText !== 'undefined' && labelText !== null && /*#__PURE__*/React.createElement(Text, {
145
145
  as: "label",
146
146
  htmlFor: id,
147
147
  className: labelClasses
148
- }, labelText) : null;
148
+ }, labelText);
149
149
  const labelWrapper = /*#__PURE__*/React.createElement("div", {
150
150
  className: `${prefix}--text-input__label-wrapper`
151
151
  }, label, counter);
152
- const helper = helperText ? /*#__PURE__*/React.createElement(Text, {
152
+ const helper = typeof helperText !== 'undefined' && helperText !== null && /*#__PURE__*/React.createElement(Text, {
153
153
  as: "div",
154
154
  id: normalizedProps.helperId,
155
155
  className: helperTextClasses
156
- }, helperText) : null;
156
+ }, helperText);
157
157
  const input = /*#__PURE__*/React.createElement("input", getTextInputProps({
158
158
  sharedTextInputProps,
159
159
  invalid: normalizedProps.invalid,
@@ -98,10 +98,10 @@ const TimePicker = frFn((props, ref) => {
98
98
  [`${prefix}--visually-hidden`]: hideLabel,
99
99
  [`${prefix}--label--disabled`]: disabled
100
100
  });
101
- const label = labelText ? /*#__PURE__*/React.createElement("label", {
101
+ const label = typeof labelText !== 'undefined' && labelText !== null && /*#__PURE__*/React.createElement("label", {
102
102
  htmlFor: id,
103
103
  className: labelClasses
104
- }, labelText) : null;
104
+ }, labelText);
105
105
  function getInternalPickerSelects() {
106
106
  const readOnlyEventHandlers = {
107
107
  onMouseDown: evt => {
@@ -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.
@@ -48,8 +48,9 @@ const DefinitionTooltip = ({
48
48
  setOpen(false);
49
49
  },
50
50
  onMouseEnter: () => {
51
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- https://github.com/carbon-design-system/carbon/issues/20452
52
- openOnHover ? setOpen(true) : null;
51
+ if (openOnHover) {
52
+ setOpen(true);
53
+ }
53
54
  },
54
55
  onFocus: () => {
55
56
  setOpen(true);
@@ -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
@@ -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
  });
@@ -601,7 +609,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
601
609
  // The input should be described by the appropriate message text id
602
610
  // when both the message is supplied *and* when the component is in
603
611
  // the matching state (invalid, warn, etc).
604
- 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;
605
613
 
606
614
  // Memoize the value of getMenuProps to avoid an infinite loop
607
615
  const menuProps = React.useMemo(() => getMenuProps({
@@ -629,13 +637,13 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
629
637
  onBlur: handleFocus,
630
638
  className: className,
631
639
  disabled: disabled,
632
- invalid: invalid,
640
+ invalid: normalizedProps.invalid,
633
641
  invalidText: invalidText,
634
642
  invalidTextId: invalidTextId,
635
643
  isOpen: isOpen,
636
644
  light: light,
637
645
  size: size,
638
- warn: warn,
646
+ warn: normalizedProps.warn,
639
647
  ref: enableFloatingStyles ? refs.setReference : null,
640
648
  warnText: warnText,
641
649
  warnTextId: warnTextId
@@ -737,9 +745,9 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
737
745
  }), rest, readOnlyEventHandlers, {
738
746
  readOnly: readOnly,
739
747
  "aria-describedby": ariaDescribedBy
740
- })), invalid && /*#__PURE__*/React.createElement(iconsReact.WarningFilled, {
748
+ })), normalizedProps.invalid && /*#__PURE__*/React.createElement(iconsReact.WarningFilled, {
741
749
  className: `${prefix}--list-box__invalid-icon`
742
- }), showWarning && /*#__PURE__*/React.createElement(iconsReact.WarningAltFilled, {
750
+ }), normalizedProps.warn && /*#__PURE__*/React.createElement(iconsReact.WarningAltFilled, {
743
751
  className: `${prefix}--list-box__invalid-icon ${prefix}--list-box__invalid-icon--warning`
744
752
  }), inputValue && /*#__PURE__*/React.createElement(ListBoxSelection.default, {
745
753
  clearSelection: () => {
@@ -788,7 +796,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
788
796
  }, modifiedItemProps), itemToElement ? itemToElement(item) : itemToString(item), isEqual(currentSelectedItem, item) && /*#__PURE__*/React.createElement(iconsReact.Checkmark, {
789
797
  className: `${prefix}--list-box__menu-item__selected-icon`
790
798
  }));
791
- }) : null)), helperText && !invalid && !warn && !isFluid && /*#__PURE__*/React.createElement(Text.Text, {
799
+ }) : null)), helperText && !normalizedProps.invalid && !normalizedProps.warn && !isFluid && /*#__PURE__*/React.createElement(Text.Text, {
792
800
  as: "div",
793
801
  id: helperTextId,
794
802
  className: helperClasses
@@ -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. 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.
@@ -19,6 +19,7 @@ var match = require('../../internal/keyboard/match.js');
19
19
  var useId = require('../../internal/useId.js');
20
20
  var usePrefix = require('../../internal/usePrefix.js');
21
21
  var noopFn = require('../../internal/noopFn.js');
22
+ var useIsomorphicEffect = require('../../internal/useIsomorphicEffect.js');
22
23
  var Text = require('../Text/Text.js');
23
24
  require('../Text/TextDirection.js');
24
25
  require('../Tooltip/DefinitionTooltip.js');
@@ -62,7 +63,7 @@ function FileUploaderItem({
62
63
  setIsEllipsisApplied(isActive);
63
64
  return isActive;
64
65
  };
65
- React.useLayoutEffect(() => {
66
+ useIsomorphicEffect.default(() => {
66
67
  isEllipsisActive(textRef.current);
67
68
  }, [prefix, name]);
68
69
  return /*#__PURE__*/React.createElement("span", _rollupPluginBabelHelpers.extends({