@carbon/react 1.84.0 → 1.85.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 (151) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +784 -784
  2. package/es/components/AILabel/index.js +6 -1
  3. package/es/components/Checkbox/Checkbox.d.ts +2 -2
  4. package/es/components/Checkbox/Checkbox.js +8 -8
  5. package/es/components/CheckboxGroup/CheckboxGroup.d.ts +2 -2
  6. package/es/components/CheckboxGroup/CheckboxGroup.js +9 -8
  7. package/es/components/CodeSnippet/CodeSnippet.js +2 -4
  8. package/es/components/ComboBox/ComboBox.d.ts +1 -1
  9. package/es/components/ComboBox/ComboBox.js +8 -7
  10. package/es/components/ComposedModal/ComposedModal.d.ts +1 -1
  11. package/es/components/ComposedModal/ComposedModal.js +15 -10
  12. package/es/components/ContainedList/ContainedList.d.ts +1 -1
  13. package/es/components/ContainedList/ContainedList.js +4 -2
  14. package/es/components/ContentSwitcher/ContentSwitcher.js +6 -5
  15. package/es/components/DataTable/DataTable.js +3 -0
  16. package/es/components/DataTable/TableDecoratorRow.d.ts +2 -2
  17. package/es/components/DataTable/TableDecoratorRow.js +8 -8
  18. package/es/components/DataTable/TableExpandRow.d.ts +1 -1
  19. package/es/components/DataTable/TableExpandRow.js +15 -6
  20. package/es/components/DataTable/TableHeader.js +10 -10
  21. package/es/components/DataTable/TableRow.js +12 -4
  22. package/es/components/DataTable/tools/normalize.js +2 -1
  23. package/es/components/DatePickerInput/DatePickerInput.js +8 -7
  24. package/es/components/Dialog/index.d.ts +5 -1
  25. package/es/components/Dialog/index.js +20 -0
  26. package/es/components/Dropdown/Dropdown.d.ts +1 -1
  27. package/es/components/Dropdown/Dropdown.js +8 -10
  28. package/es/components/FileUploader/FileUploaderButton.js +2 -2
  29. package/es/components/FileUploader/FileUploaderDropContainer.js +2 -2
  30. package/es/components/FileUploader/FileUploaderItem.js +2 -2
  31. package/es/components/Layer/index.d.ts +1 -3
  32. package/es/components/Layer/index.js +9 -8
  33. package/es/components/Menu/Menu.js +0 -6
  34. package/es/components/Modal/Modal.d.ts +2 -2
  35. package/es/components/Modal/Modal.js +20 -9
  36. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  37. package/es/components/MultiSelect/FilterableMultiSelect.js +8 -7
  38. package/es/components/MultiSelect/MultiSelect.d.ts +1 -1
  39. package/es/components/MultiSelect/MultiSelect.js +8 -7
  40. package/es/components/NumberInput/NumberInput.d.ts +1 -1
  41. package/es/components/NumberInput/NumberInput.js +9 -8
  42. package/es/components/PageHeader/PageHeader.js +2 -2
  43. package/es/components/Popover/index.js +2 -1
  44. package/es/components/RadioButton/RadioButton.d.ts +2 -2
  45. package/es/components/RadioButton/RadioButton.js +8 -8
  46. package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +2 -2
  47. package/es/components/RadioButtonGroup/RadioButtonGroup.js +9 -8
  48. package/es/components/RadioTile/RadioTile.d.ts +1 -1
  49. package/es/components/RadioTile/RadioTile.js +8 -7
  50. package/es/components/Select/Select.d.ts +2 -2
  51. package/es/components/Select/Select.js +8 -7
  52. package/es/components/Tag/DismissibleTag.d.ts +1 -1
  53. package/es/components/Tag/DismissibleTag.js +9 -8
  54. package/es/components/Tag/Tag.d.ts +1 -1
  55. package/es/components/Tag/Tag.js +9 -8
  56. package/es/components/TextArea/TextArea.js +8 -7
  57. package/es/components/TextInput/TextInput.d.ts +1 -1
  58. package/es/components/TextInput/TextInput.js +20 -9
  59. package/es/components/Tile/Tile.d.ts +2 -2
  60. package/es/components/Tile/Tile.js +30 -36
  61. package/es/components/Toggletip/index.js +2 -2
  62. package/es/components/Tooltip/DefinitionTooltip.js +1 -0
  63. package/es/components/TreeView/TreeNode.js +3 -3
  64. package/es/components/TreeView/TreeView.js +3 -3
  65. package/es/components/UIShell/Content.d.ts +5 -3
  66. package/es/components/UIShell/HeaderPanel.d.ts +2 -2
  67. package/es/components/UIShell/HeaderPanel.js +9 -5
  68. package/es/internal/Selection.js +8 -3
  69. package/es/internal/environment.js +1 -12
  70. package/es/internal/{__mocks__/mockHTMLElement.d.ts → index.d.ts} +2 -4
  71. package/es/internal/useResizeObserver.d.ts +1 -1
  72. package/es/internal/utils.d.ts +14 -0
  73. package/es/internal/utils.js +18 -0
  74. package/es/tools/uniqueId.d.ts +1 -6
  75. package/lib/components/AILabel/index.js +6 -1
  76. package/lib/components/Checkbox/Checkbox.d.ts +2 -2
  77. package/lib/components/Checkbox/Checkbox.js +7 -7
  78. package/lib/components/CheckboxGroup/CheckboxGroup.d.ts +2 -2
  79. package/lib/components/CheckboxGroup/CheckboxGroup.js +8 -7
  80. package/lib/components/CodeSnippet/CodeSnippet.js +2 -4
  81. package/lib/components/ComboBox/ComboBox.d.ts +1 -1
  82. package/lib/components/ComboBox/ComboBox.js +11 -10
  83. package/lib/components/ComposedModal/ComposedModal.d.ts +1 -1
  84. package/lib/components/ComposedModal/ComposedModal.js +16 -11
  85. package/lib/components/ContainedList/ContainedList.d.ts +1 -1
  86. package/lib/components/ContainedList/ContainedList.js +4 -2
  87. package/lib/components/ContentSwitcher/ContentSwitcher.js +5 -4
  88. package/lib/components/DataTable/DataTable.js +3 -0
  89. package/lib/components/DataTable/TableDecoratorRow.d.ts +2 -2
  90. package/lib/components/DataTable/TableDecoratorRow.js +8 -8
  91. package/lib/components/DataTable/TableExpandRow.d.ts +1 -1
  92. package/lib/components/DataTable/TableExpandRow.js +14 -5
  93. package/lib/components/DataTable/TableHeader.js +9 -9
  94. package/lib/components/DataTable/TableRow.js +11 -3
  95. package/lib/components/DataTable/tools/normalize.js +2 -1
  96. package/lib/components/DatePickerInput/DatePickerInput.js +7 -6
  97. package/lib/components/Dialog/index.d.ts +5 -1
  98. package/lib/components/Dialog/index.js +20 -0
  99. package/lib/components/Dropdown/Dropdown.d.ts +1 -1
  100. package/lib/components/Dropdown/Dropdown.js +12 -14
  101. package/lib/components/FileUploader/FileUploaderButton.js +2 -2
  102. package/lib/components/FileUploader/FileUploaderDropContainer.js +2 -2
  103. package/lib/components/FileUploader/FileUploaderItem.js +2 -2
  104. package/lib/components/Layer/index.d.ts +1 -3
  105. package/lib/components/Layer/index.js +9 -8
  106. package/lib/components/Menu/Menu.js +0 -6
  107. package/lib/components/Modal/Modal.d.ts +2 -2
  108. package/lib/components/Modal/Modal.js +28 -17
  109. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  110. package/lib/components/MultiSelect/FilterableMultiSelect.js +12 -11
  111. package/lib/components/MultiSelect/MultiSelect.d.ts +1 -1
  112. package/lib/components/MultiSelect/MultiSelect.js +13 -12
  113. package/lib/components/NumberInput/NumberInput.d.ts +1 -1
  114. package/lib/components/NumberInput/NumberInput.js +8 -7
  115. package/lib/components/PageHeader/PageHeader.js +2 -2
  116. package/lib/components/Popover/index.js +2 -1
  117. package/lib/components/RadioButton/RadioButton.d.ts +2 -2
  118. package/lib/components/RadioButton/RadioButton.js +7 -7
  119. package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +2 -2
  120. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +10 -9
  121. package/lib/components/RadioTile/RadioTile.d.ts +1 -1
  122. package/lib/components/RadioTile/RadioTile.js +7 -6
  123. package/lib/components/Select/Select.d.ts +2 -2
  124. package/lib/components/Select/Select.js +7 -6
  125. package/lib/components/Tag/DismissibleTag.d.ts +1 -1
  126. package/lib/components/Tag/DismissibleTag.js +8 -7
  127. package/lib/components/Tag/Tag.d.ts +1 -1
  128. package/lib/components/Tag/Tag.js +8 -7
  129. package/lib/components/TextArea/TextArea.js +7 -6
  130. package/lib/components/TextInput/TextInput.d.ts +1 -1
  131. package/lib/components/TextInput/TextInput.js +19 -8
  132. package/lib/components/Tile/Tile.d.ts +2 -2
  133. package/lib/components/Tile/Tile.js +29 -35
  134. package/lib/components/Toggletip/index.js +2 -2
  135. package/lib/components/Tooltip/DefinitionTooltip.js +1 -0
  136. package/lib/components/TreeView/TreeNode.js +3 -3
  137. package/lib/components/TreeView/TreeView.js +3 -3
  138. package/lib/components/UIShell/Content.d.ts +5 -3
  139. package/lib/components/UIShell/HeaderPanel.d.ts +2 -2
  140. package/lib/components/UIShell/HeaderPanel.js +8 -4
  141. package/lib/internal/Selection.js +8 -3
  142. package/lib/internal/environment.js +1 -12
  143. package/lib/internal/{__mocks__/mockHTMLElement.d.ts → index.d.ts} +2 -4
  144. package/lib/internal/useResizeObserver.d.ts +1 -1
  145. package/lib/internal/utils.d.ts +14 -0
  146. package/lib/internal/utils.js +22 -0
  147. package/lib/tools/uniqueId.d.ts +1 -6
  148. package/package.json +11 -20
  149. package/telemetry.yml +1 -0
  150. package/es/tools/uniqueId.js +0 -14
  151. package/lib/tools/uniqueId.js +0 -18
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import React, { Ref, type HTMLAttributes, type ReactNode } from 'react';
7
+ import React, { type HTMLAttributes, type ReactNode, type Ref } from 'react';
8
8
  import { UseSelectProps } from 'downshift';
9
9
  import { type ListBoxMenuIconTranslationKey, type ListBoxSize, type ListBoxType } from '../ListBox';
10
10
  import { TranslateWithId } from '../../types/common';
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React, { useEffect, useContext, useCallback, useMemo, useState, isValidElement } from 'react';
9
+ import React, { useEffect, useContext, useCallback, useMemo, useState, isValidElement, cloneElement } from 'react';
10
10
  import { useSelect } from 'downshift';
11
11
  import cx from 'classnames';
12
12
  import PropTypes from 'prop-types';
@@ -20,6 +20,8 @@ import { FormContext } from '../FluidForm/FormContext.js';
20
20
  import { useId } from '../../internal/useId.js';
21
21
  import { useFloating, size, flip, hide, autoUpdate } from '@floating-ui/react';
22
22
  import { useFeatureFlag } from '../FeatureFlags/index.js';
23
+ import { AILabel } from '../AILabel/index.js';
24
+ import { isComponentElement } from '../../internal/utils.js';
23
25
  import { ListBoxSizePropType, ListBoxTypePropType } from '../ListBox/ListBoxPropTypes.js';
24
26
 
25
27
  const {
@@ -308,15 +310,11 @@ const Dropdown = /*#__PURE__*/React.forwardRef(({
308
310
  }), [autoAlign, getMenuProps, refs.setFloating, enableFloatingStyles]);
309
311
 
310
312
  // AILabel is always size `mini`
311
- const normalizedDecorator = useMemo(() => {
312
- let element = slug ?? decorator;
313
- if (element && element['type']?.displayName === 'AILabel') {
314
- return /*#__PURE__*/React.cloneElement(element, {
315
- size: 'mini'
316
- });
317
- }
318
- return /*#__PURE__*/React.isValidElement(element) ? element : null;
319
- }, [slug, decorator]);
313
+ const candidate = slug ?? decorator;
314
+ const candidateIsAILabel = isComponentElement(candidate, AILabel);
315
+ const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
316
+ size: 'mini'
317
+ }) : null;
320
318
  const allLabelProps = getLabelProps();
321
319
  const labelProps = /*#__PURE__*/isValidElement(titleText) ? {
322
320
  id: allLabelProps.id
@@ -11,7 +11,7 @@ import PropTypes from 'prop-types';
11
11
  import React, { useState, useRef } from 'react';
12
12
  import { Enter, Space } from '../../internal/keyboard/keys.js';
13
13
  import { matches } from '../../internal/keyboard/match.js';
14
- import { uniqueId } from '../../tools/uniqueId.js';
14
+ import { useId } from '../../internal/useId.js';
15
15
  import { usePrefix } from '../../internal/usePrefix.js';
16
16
  import deprecate from '../../prop-types/deprecate.js';
17
17
  import { noopFn } from '../../internal/noopFn.js';
@@ -39,7 +39,7 @@ function FileUploaderButton({
39
39
  const [prevOwnerLabelText, setPrevOwnerLabelText] = useState(ownerLabelText);
40
40
  const {
41
41
  current: inputId
42
- } = useRef(id || uniqueId());
42
+ } = useRef(id || useId());
43
43
  const inputNode = useRef(null);
44
44
  const classes = cx(`${prefix}--btn`, className, {
45
45
  [`${prefix}--btn--${buttonKind}`]: buttonKind,
@@ -11,7 +11,7 @@ import PropTypes from 'prop-types';
11
11
  import cx from 'classnames';
12
12
  import { Enter, Space } from '../../internal/keyboard/keys.js';
13
13
  import { matches } from '../../internal/keyboard/match.js';
14
- import { uniqueId } from '../../tools/uniqueId.js';
14
+ import { useId } from '../../internal/useId.js';
15
15
  import { usePrefix } from '../../internal/usePrefix.js';
16
16
  import { composeEventHandlers } from '../../tools/events.js';
17
17
  import deprecate from '../../prop-types/deprecate.js';
@@ -36,7 +36,7 @@ function FileUploaderDropContainer({
36
36
  const inputRef = useRef(null);
37
37
  const {
38
38
  current: uid
39
- } = useRef(id || uniqueId());
39
+ } = useRef(id || useId());
40
40
  const [isActive, setActive] = useState(false);
41
41
  const dropareaClasses = cx(`${prefix}--file__drop-container`, `${prefix}--file-browse-btn`, {
42
42
  [`${prefix}--file__drop-container--drag-over`]: isActive,
@@ -12,7 +12,7 @@ import React, { useRef, useState, useLayoutEffect } from 'react';
12
12
  import Filename from './Filename.js';
13
13
  import { Enter, Space } from '../../internal/keyboard/keys.js';
14
14
  import { matches } from '../../internal/keyboard/match.js';
15
- import { uniqueId } from '../../tools/uniqueId.js';
15
+ import { useId } from '../../internal/useId.js';
16
16
  import { usePrefix } from '../../internal/usePrefix.js';
17
17
  import { noopFn } from '../../internal/noopFn.js';
18
18
  import '../Text/index.js';
@@ -38,7 +38,7 @@ function FileUploaderItem({
38
38
  const prefix = usePrefix();
39
39
  const {
40
40
  current: id
41
- } = useRef(uuid || uniqueId());
41
+ } = useRef(uuid || useId());
42
42
  const classes = cx(`${prefix}--file__selected-file`, className, {
43
43
  [`${prefix}--file__selected-file--invalid`]: invalid,
44
44
  [`${prefix}--file__selected-file--md`]: size === 'md',
@@ -35,7 +35,5 @@ export interface LayerBaseProps {
35
35
  withBackground?: boolean;
36
36
  }
37
37
  export type LayerProps<T extends React.ElementType> = PolymorphicComponentPropWithRef<T, LayerBaseProps>;
38
- declare const Layer: React.ForwardRefExoticComponent<LayerBaseProps & {
39
- as?: React.ElementType;
40
- } & React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<any>>;
38
+ declare const Layer: React.ForwardRefExoticComponent<Omit<LayerProps<React.ElementType<any, keyof React.JSX.IntrinsicElements>>, "ref"> & React.RefAttributes<unknown>>;
41
39
  export { Layer };
@@ -25,14 +25,15 @@ function useLayer() {
25
25
  level
26
26
  };
27
27
  }
28
- const Layer = /*#__PURE__*/React.forwardRef(({
29
- as,
30
- className: customClassName,
31
- children,
32
- level: overrideLevel,
33
- withBackground = false,
34
- ...rest
35
- }, ref) => {
28
+ const Layer = /*#__PURE__*/React.forwardRef((props, ref) => {
29
+ const {
30
+ as,
31
+ className: customClassName,
32
+ children,
33
+ level: overrideLevel,
34
+ withBackground = false,
35
+ ...rest
36
+ } = props;
36
37
  const contextLevel = React.useContext(LayerContext);
37
38
  const level = overrideLevel ?? contextLevel;
38
39
  const prefix = usePrefix();
@@ -34,12 +34,6 @@ const Menu = /*#__PURE__*/forwardRef(function Menu({
34
34
  open,
35
35
  size = 'sm',
36
36
  legacyAutoalign = 'true',
37
- // TODO: `ssr-friendly` doesn't support ESLint v9.
38
- // https://github.com/kopiro/eslint-plugin-ssr-friendly/issues/30
39
- // https://github.com/carbon-design-system/carbon/issues/18991
40
- /*
41
- // eslint-disable-next-line ssr-friendly/no-dom-globals-in-react-fc
42
- */
43
37
  target = canUseDOM && document.body,
44
38
  x = 0,
45
39
  y = 0,
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import React, { type HTMLAttributes, type ReactNode, type Ref } from 'react';
7
+ import React, { type HTMLAttributes, type ReactNode, type RefObject } from 'react';
8
8
  import { InlineLoadingStatus } from '../InlineLoading/InlineLoading';
9
9
  export declare const ModalSizes: readonly ["xs", "sm", "md", "lg"];
10
10
  export type ModalSize = (typeof ModalSizes)[number];
@@ -57,7 +57,7 @@ export interface ModalProps extends HTMLAttributes<HTMLDivElement> {
57
57
  /**
58
58
  * Provide a ref to return focus to once the modal is closed.
59
59
  */
60
- launcherButtonRef?: Ref<HTMLButtonElement>;
60
+ launcherButtonRef?: RefObject<HTMLButtonElement | null>;
61
61
  /**
62
62
  * Specify the description for the loading text
63
63
  */
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
- import React, { useRef, useState, useEffect } from 'react';
10
+ import React, { useRef, useState, useEffect, cloneElement } from 'react';
11
11
  import cx from 'classnames';
12
12
  import { Close } from '@carbon/icons-react';
13
13
  import { toggleClass } from '../../tools/toggleClass.js';
@@ -31,11 +31,14 @@ import { useFeatureFlag } from '../FeatureFlags/index.js';
31
31
  import { composeEventHandlers } from '../../tools/events.js';
32
32
  import deprecate from '../../prop-types/deprecate.js';
33
33
  import { unstable__Dialog } from '../Dialog/index.js';
34
+ import { AILabel } from '../AILabel/index.js';
35
+ import { isComponentElement } from '../../internal/utils.js';
34
36
  import { warning } from '../../internal/warning.js';
35
37
  import { debounce } from '../../node_modules/es-toolkit/dist/compat/function/debounce.mjs.js';
36
38
  import { Text } from '../Text/Text.js';
37
39
 
38
40
  const ModalSizes = ['xs', 'sm', 'md', 'lg'];
41
+ const invalidOutsideClickMessage = '`Modal`: `preventCloseOnClickOutside` should not be `false` when `passiveModal` is `false`. Non-passive `Modal`s should not be dismissible by clicking outside.';
39
42
  const Modal = /*#__PURE__*/React.forwardRef(function Modal({
40
43
  'aria-label': ariaLabelProp,
41
44
  children,
@@ -61,7 +64,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
61
64
  size,
62
65
  hasScrollingContent = false,
63
66
  closeButtonLabel = 'Close',
64
- preventCloseOnClickOutside = false,
67
+ preventCloseOnClickOutside = !passiveModal,
65
68
  isFullWidth,
66
69
  launcherButtonRef,
67
70
  loadingStatus = 'inactive',
@@ -92,6 +95,9 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
92
95
  const focusTrapWithoutSentinels = useFeatureFlag('enable-experimental-focus-wrap-without-sentinels');
93
96
  const enableDialogElement = useFeatureFlag('enable-dialog-element');
94
97
  process.env.NODE_ENV !== "production" ? warning(!(focusTrapWithoutSentinels && enableDialogElement), '`<Modal>` detected both `focusTrapWithoutSentinels` and ' + '`enableDialogElement` feature flags are enabled. The native dialog ' + 'element handles focus, so `enableDialogElement` must be off for ' + '`focusTrapWithoutSentinels` to have any effect.') : void 0;
98
+ if (!passiveModal && preventCloseOnClickOutside === false) {
99
+ console.error(invalidOutsideClickMessage);
100
+ }
95
101
  function isCloseButton(element) {
96
102
  return !onSecondarySubmit && element === secondaryButton.current || element.classList.contains(modalCloseButtonClass);
97
103
  }
@@ -265,12 +271,11 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
265
271
  }, []);
266
272
 
267
273
  // AILabel always size `sm`
268
- let normalizedDecorator = /*#__PURE__*/React.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
269
- if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
270
- normalizedDecorator = /*#__PURE__*/React.cloneElement(normalizedDecorator, {
271
- size: 'sm'
272
- });
273
- }
274
+ const candidate = slug ?? decorator;
275
+ const candidateIsAILabel = isComponentElement(candidate, AILabel);
276
+ const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
277
+ size: 'sm'
278
+ }) : null;
274
279
  const modalButton = /*#__PURE__*/React.createElement("div", {
275
280
  className: `${prefix}--modal-close-button`
276
281
  }, /*#__PURE__*/React.createElement(IconButton, {
@@ -292,6 +297,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
292
297
  const isAlertDialog = alert && !passiveModal;
293
298
  const modalBody = enableDialogElement ? /*#__PURE__*/React.createElement(unstable__Dialog, {
294
299
  open: open,
300
+ focusAfterCloseRef: launcherButtonRef,
295
301
  modal: true,
296
302
  ref: innerModal,
297
303
  role: isAlertDialog ? 'alertdialog' : '',
@@ -538,7 +544,12 @@ Modal.propTypes = {
538
544
  /**
539
545
  * Prevent closing on click outside of modal
540
546
  */
541
- preventCloseOnClickOutside: PropTypes.bool,
547
+ preventCloseOnClickOutside: (props, propName) => {
548
+ if (!props.passiveModal && props[propName] === false) {
549
+ return new Error(invalidOutsideClickMessage);
550
+ }
551
+ return null;
552
+ },
542
553
  /**
543
554
  * Specify whether the Button should be disabled, or not
544
555
  */
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { type UseComboboxProps, type UseMultipleSelectionProps } from 'downshift';
8
- import React, { ReactNode, FunctionComponent, ReactElement } from 'react';
8
+ import React, { type FunctionComponent, type ReactElement, type ReactNode } from 'react';
9
9
  import { type MultiSelectSortingProps } from './MultiSelectPropTypes';
10
10
  import { type ListBoxSize, type ListBoxType } from '../ListBox';
11
11
  import { TranslateWithId } from '../../types/common';
@@ -11,7 +11,7 @@ import cx from 'classnames';
11
11
  import Downshift, { useCombobox, useMultipleSelection } from 'downshift';
12
12
  import isEqual from 'react-fast-compare';
13
13
  import PropTypes from 'prop-types';
14
- import React, { forwardRef, useContext, useRef, useState, useLayoutEffect, useMemo, useEffect } from 'react';
14
+ import React, { forwardRef, useContext, useRef, useState, useLayoutEffect, useMemo, useEffect, cloneElement } from 'react';
15
15
  import { defaultFilterItems } from '../ComboBox/tools/filter.js';
16
16
  import { sortingPropTypes } from './MultiSelectPropTypes.js';
17
17
  import ListBox from '../ListBox/index.js';
@@ -29,6 +29,8 @@ import '../FluidForm/FluidForm.js';
29
29
  import { FormContext } from '../FluidForm/FormContext.js';
30
30
  import { useSelection } from '../../internal/Selection.js';
31
31
  import { useFloating, flip, size, hide, autoUpdate } from '@floating-ui/react';
32
+ import { AILabel } from '../AILabel/index.js';
33
+ import { isComponentElement } from '../../internal/utils.js';
32
34
  import { ListBoxSizePropType, ListBoxTypePropType } from '../ListBox/ListBoxPropTypes.js';
33
35
 
34
36
  const {
@@ -444,12 +446,11 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
444
446
  }
445
447
 
446
448
  // AILabel always size `mini`
447
- let normalizedDecorator = /*#__PURE__*/React.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
448
- if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
449
- normalizedDecorator = /*#__PURE__*/React.cloneElement(normalizedDecorator, {
450
- size: 'mini'
451
- });
452
- }
449
+ const candidate = slug ?? decorator;
450
+ const candidateIsAILabel = isComponentElement(candidate, AILabel);
451
+ const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
452
+ size: 'mini'
453
+ }) : null;
453
454
  const className = cx(`${prefix}--multi-select`, `${prefix}--combo-box`, `${prefix}--multi-select--filterable`, {
454
455
  [`${prefix}--multi-select--invalid`]: invalid,
455
456
  [`${prefix}--multi-select--invalid--focused`]: invalid && inputFocused,
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { UseSelectProps } from 'downshift';
8
- import React, { ReactNode } from 'react';
8
+ import React, { type ReactNode } from 'react';
9
9
  import { type ListBoxSize, type ListBoxType } from '../ListBox';
10
10
  import { MultiSelectSortingProps } from './MultiSelectPropTypes';
11
11
  import { ListBoxProps } from '../ListBox/ListBox';
@@ -11,7 +11,7 @@ import cx from 'classnames';
11
11
  import { useSelect } from 'downshift';
12
12
  import isEqual from 'react-fast-compare';
13
13
  import PropTypes from 'prop-types';
14
- import React, { useMemo, useContext, useState, useLayoutEffect, isValidElement, useCallback } from 'react';
14
+ import React, { useMemo, useContext, useState, useLayoutEffect, isValidElement, useCallback, cloneElement } from 'react';
15
15
  import ListBox from '../ListBox/index.js';
16
16
  import { sortingPropTypes } from './MultiSelectPropTypes.js';
17
17
  import { defaultSortItems, defaultCompareItems } from './tools/sorting.js';
@@ -29,6 +29,8 @@ import '../Checkbox/Checkbox.Skeleton.js';
29
29
  import { noopFn } from '../../internal/noopFn.js';
30
30
  import { useFloating, flip, size, hide, autoUpdate } from '@floating-ui/react';
31
31
  import { useFeatureFlag } from '../FeatureFlags/index.js';
32
+ import { AILabel } from '../AILabel/index.js';
33
+ import { isComponentElement } from '../../internal/utils.js';
32
34
  import { ListBoxSizePropType, ListBoxTypePropType } from '../ListBox/ListBoxPropTypes.js';
33
35
 
34
36
  const {
@@ -409,12 +411,11 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
409
411
  } : {};
410
412
 
411
413
  // AILabel always size `mini`
412
- let normalizedDecorator = /*#__PURE__*/React.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
413
- if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
414
- normalizedDecorator = /*#__PURE__*/React.cloneElement(normalizedDecorator, {
415
- size: 'mini'
416
- });
417
- }
414
+ const candidate = slug ?? decorator;
415
+ const candidateIsAILabel = isComponentElement(candidate, AILabel);
416
+ const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
417
+ size: 'mini'
418
+ }) : null;
418
419
  const itemsSelectedText = selectedItems.length > 0 && selectedItems.map(item => item?.text);
419
420
  const selectedItemsLength = selectAll ? selectedItems.filter(item => !item.isSelectAll).length : selectedItems.length;
420
421
 
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import React, { ReactNode } from 'react';
7
+ import React, { type ReactNode } from 'react';
8
8
  import { TranslateWithId } from '../../types/common';
9
9
  import { type NumberFormatOptions } from '@carbon/utilities';
10
10
  export declare const translationIds: {
@@ -9,7 +9,7 @@ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js
9
9
  import { Subtract, Add } from '@carbon/icons-react';
10
10
  import cx from 'classnames';
11
11
  import PropTypes from 'prop-types';
12
- import React, { useContext, useState, useMemo, useCallback, useRef, useEffect } from 'react';
12
+ import React, { useContext, useState, useMemo, useCallback, useRef, useEffect, cloneElement } from 'react';
13
13
  import { useMergedRefs } from '../../internal/useMergedRefs.js';
14
14
  import { useNormalizedInputProps } from '../../internal/useNormalizedInputProps.js';
15
15
  import { usePrefix } from '../../internal/usePrefix.js';
@@ -23,6 +23,8 @@ import { NumberParser, NumberFormatter } from '@carbon/utilities';
23
23
  import { ArrowUp, ArrowDown } from '../../internal/keyboard/keys.js';
24
24
  import { match } from '../../internal/keyboard/match.js';
25
25
  import { NumberFormatOptionsPropType } from './NumberFormatPropTypes.js';
26
+ import { AILabel } from '../AILabel/index.js';
27
+ import { isComponentElement } from '../../internal/utils.js';
26
28
  import { Text } from '../Text/Text.js';
27
29
 
28
30
  var _Subtract, _Add;
@@ -262,16 +264,15 @@ const NumberInput = /*#__PURE__*/React.forwardRef(function NumberInput(props, fo
262
264
  };
263
265
 
264
266
  // AILabel always size `mini`
265
- let normalizedDecorator = /*#__PURE__*/React.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
266
- if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
267
- normalizedDecorator = /*#__PURE__*/React.cloneElement(normalizedDecorator, {
268
- size: 'mini'
269
- });
270
- }
267
+ const candidate = slug ?? decorator;
268
+ const candidateIsAILabel = isComponentElement(candidate, AILabel);
269
+ const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
270
+ size: 'mini'
271
+ }) : null;
271
272
 
272
273
  // Need to update the internal value when the revert button is clicked
273
274
  let isRevertActive;
274
- if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
275
+ if (normalizedDecorator?.type === AILabel) {
275
276
  isRevertActive = normalizedDecorator.props.revertActive;
276
277
  }
277
278
  useEffect(() => {
@@ -470,9 +470,9 @@ BreadcrumbBar.displayName = 'PageHeaderBreadcrumbBar';
470
470
  const Content = PageHeaderContent;
471
471
  Content.displayName = 'PageHeaderContent';
472
472
  const ContentPageActions = PageHeaderContentPageActions;
473
- Content.displayName = 'PageHeaderContentPageActions';
473
+ ContentPageActions.displayName = 'PageHeaderContentPageActions';
474
474
  const ContentText = PageHeaderContentText;
475
- Content.displayName = 'PageHeaderContentText';
475
+ ContentText.displayName = 'PageHeaderContentText';
476
476
  const HeroImage = PageHeaderHeroImage;
477
477
  HeroImage.displayName = 'PageHeaderHeroImage';
478
478
  const TabBar = PageHeaderTabBar;
@@ -17,6 +17,7 @@ import { useWindowEvent } from '../../internal/useEvent.js';
17
17
  import { mapPopoverAlign } from '../../tools/mapPopoverAlign.js';
18
18
  import { useFloating, offset, flip, arrow, hide, autoUpdate } from '@floating-ui/react';
19
19
  import { useFeatureFlag } from '../FeatureFlags/index.js';
20
+ import { ToggletipButton } from '../Toggletip/index.js';
20
21
 
21
22
  const PopoverContext = /*#__PURE__*/React.createContext({
22
23
  setFloating: {
@@ -226,7 +227,7 @@ forwardRef) {
226
227
  // For a toggletip there is a specific trigger component, ToggletipButton.
227
228
  // In either of these cases we want to set this as the reference node for floating-ui autoAlign
228
229
  // positioning.
229
- if (enableFloatingStyles && item?.type?.displayName !== 'PopoverContent' || enableFloatingStyles && item?.type?.displayName === 'ToggletipButton') {
230
+ if (enableFloatingStyles && item?.type !== PopoverContent || enableFloatingStyles && item?.type === ToggletipButton) {
230
231
  // Set the reference element for floating-ui
231
232
  refs.setReference(node);
232
233
  }
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2023
2
+ * Copyright IBM Corp. 2016, 2025
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, { ReactNode } from 'react';
7
+ import React, { type ReactNode } from 'react';
8
8
  type ExcludedAttributes = 'onChange';
9
9
  export interface RadioButtonProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, ExcludedAttributes> {
10
10
  /**
@@ -7,13 +7,15 @@
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
- import React, { useRef } from 'react';
10
+ import React, { useRef, cloneElement } from 'react';
11
11
  import cx from 'classnames';
12
12
  import '../Text/index.js';
13
13
  import deprecate from '../../prop-types/deprecate.js';
14
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
15
  import { useId } from '../../internal/useId.js';
16
16
  import mergeRefs from '../../tools/mergeRefs.js';
17
+ import { AILabel } from '../AILabel/index.js';
18
+ import { isComponentElement } from '../../internal/utils.js';
17
19
  import { Text } from '../Text/Text.js';
18
20
 
19
21
  const RadioButton = /*#__PURE__*/React.forwardRef((props, ref) => {
@@ -47,13 +49,11 @@ const RadioButton = /*#__PURE__*/React.forwardRef((props, ref) => {
47
49
  [`${prefix}--radio-button-wrapper--decorator`]: decorator
48
50
  });
49
51
  const inputRef = useRef(null);
50
- let normalizedDecorator = /*#__PURE__*/React.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
51
- if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
52
- const size = normalizedDecorator.props?.['kind'] === 'inline' ? 'md' : 'mini';
53
- normalizedDecorator = /*#__PURE__*/React.cloneElement(normalizedDecorator, {
54
- size
55
- });
56
- }
52
+ const candidate = slug ?? decorator;
53
+ const candidateIsAILabel = isComponentElement(candidate, AILabel);
54
+ const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
55
+ size: candidate.props?.['kind'] === 'inline' ? 'md' : 'mini'
56
+ }) : null;
57
57
  return /*#__PURE__*/React.createElement("div", {
58
58
  className: wrapperClasses
59
59
  }, /*#__PURE__*/React.createElement("input", _extends({}, rest, {
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2023
2
+ * Copyright IBM Corp. 2016, 2025
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, { ReactNode } from 'react';
7
+ import React, { type ReactNode } from 'react';
8
8
  import type { RadioButtonProps } from '../RadioButton';
9
9
  export declare const RadioButtonGroupContext: React.Context<null>;
10
10
  type ExcludedAttributes = 'onChange';
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
- import React, { useState, useRef } from 'react';
10
+ import React, { useState, useRef, cloneElement } from 'react';
11
11
  import cx from 'classnames';
12
12
  import { Legend } from '../Text/index.js';
13
13
  import { usePrefix } from '../../internal/usePrefix.js';
@@ -15,6 +15,8 @@ import { WarningFilled, WarningAltFilled } from '@carbon/icons-react';
15
15
  import deprecate from '../../prop-types/deprecate.js';
16
16
  import mergeRefs from '../../tools/mergeRefs.js';
17
17
  import { useId } from '../../internal/useId.js';
18
+ import { AILabel } from '../AILabel/index.js';
19
+ import { isComponentElement } from '../../internal/utils.js';
18
20
 
19
21
  const RadioButtonGroup = /*#__PURE__*/React.forwardRef((props, ref) => {
20
22
  const {
@@ -103,13 +105,12 @@ const RadioButtonGroup = /*#__PURE__*/React.forwardRef((props, ref) => {
103
105
  const divRef = useRef(null);
104
106
 
105
107
  // AILabel is always size `mini`
106
- let normalizedDecorator = /*#__PURE__*/React.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
107
- if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
108
- normalizedDecorator = /*#__PURE__*/React.cloneElement(normalizedDecorator, {
109
- size: 'mini',
110
- kind: 'default'
111
- });
112
- }
108
+ const candidate = slug ?? decorator;
109
+ const candidateIsAILabel = isComponentElement(candidate, AILabel);
110
+ const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
111
+ size: 'mini',
112
+ kind: 'default'
113
+ }) : null;
113
114
  return /*#__PURE__*/React.createElement("div", {
114
115
  className: wrapperClasses,
115
116
  ref: mergeRefs(divRef, ref)
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2023
2
+ * Copyright IBM Corp. 2016, 2025
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.
@@ -9,7 +9,7 @@ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js
9
9
  import { RadioButtonChecked, RadioButton, CheckmarkFilled } from '@carbon/icons-react';
10
10
  import cx from 'classnames';
11
11
  import PropTypes from 'prop-types';
12
- import React from 'react';
12
+ import React, { cloneElement } from 'react';
13
13
  import { Enter, Space } from '../../internal/keyboard/keys.js';
14
14
  import { matches } from '../../internal/keyboard/match.js';
15
15
  import { useFallbackId } from '../../internal/useId.js';
@@ -18,6 +18,8 @@ import deprecate from '../../prop-types/deprecate.js';
18
18
  import { noopFn } from '../../internal/noopFn.js';
19
19
  import '../Text/index.js';
20
20
  import { useFeatureFlag } from '../FeatureFlags/index.js';
21
+ import { AILabel } from '../AILabel/index.js';
22
+ import { isComponentElement } from '../../internal/utils.js';
21
23
  import { Text } from '../Text/Text.js';
22
24
 
23
25
  var _RadioButtonChecked, _RadioButton, _CheckmarkFilled;
@@ -72,12 +74,11 @@ const RadioTile = /*#__PURE__*/React.forwardRef(function RadioTile({
72
74
  }
73
75
 
74
76
  // AILabel is always size `xs`
75
- let normalizedDecorator = /*#__PURE__*/React.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
76
- if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
77
- normalizedDecorator = /*#__PURE__*/React.cloneElement(normalizedDecorator, {
78
- size: 'xs'
79
- });
80
- }
77
+ const candidate = slug ?? decorator;
78
+ const candidateIsAILabel = isComponentElement(candidate, AILabel);
79
+ const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
80
+ size: 'xs'
81
+ }) : null;
81
82
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", {
82
83
  checked: checked,
83
84
  className: `${prefix}--tile-input`,
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2023
2
+ * Copyright IBM Corp. 2016, 2025
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, { ChangeEventHandler, ComponentPropsWithRef, ReactNode } from 'react';
7
+ import React, { type ChangeEventHandler, type ComponentPropsWithRef, type ReactNode } from 'react';
8
8
  type ExcludedAttributes = 'size';
9
9
  export interface SelectProps extends Omit<ComponentPropsWithRef<'select'>, ExcludedAttributes> {
10
10
  /**
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
- import React, { useContext, useState } from 'react';
10
+ import React, { useContext, useState, cloneElement } from 'react';
11
11
  import cx from 'classnames';
12
12
  import { ChevronDown, WarningFilled, WarningAltFilled } from '@carbon/icons-react';
13
13
  import deprecate from '../../prop-types/deprecate.js';
@@ -17,6 +17,8 @@ import { FormContext } from '../FluidForm/FormContext.js';
17
17
  import { useId } from '../../internal/useId.js';
18
18
  import { composeEventHandlers } from '../../tools/events.js';
19
19
  import '../Text/index.js';
20
+ import { AILabel } from '../AILabel/index.js';
21
+ import { isComponentElement } from '../../internal/utils.js';
20
22
  import { Text } from '../Text/Text.js';
21
23
 
22
24
  const Select = /*#__PURE__*/React.forwardRef(function Select({
@@ -134,12 +136,11 @@ const Select = /*#__PURE__*/React.forwardRef(function Select({
134
136
  };
135
137
 
136
138
  // AILabel always size `mini`
137
- let normalizedDecorator = /*#__PURE__*/React.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
138
- if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
139
- normalizedDecorator = /*#__PURE__*/React.cloneElement(normalizedDecorator, {
140
- size: 'mini'
141
- });
142
- }
139
+ const candidate = slug ?? decorator;
140
+ const candidateIsAILabel = isComponentElement(candidate, AILabel);
141
+ const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
142
+ size: 'mini'
143
+ }) : null;
143
144
  const input = (() => {
144
145
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("select", _extends({}, other, ariaProps, {
145
146
  id: id,