@carbon/react 1.91.0-rc.0 → 1.92.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 (173) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +969 -934
  2. package/es/components/Accordion/AccordionItem.d.ts +12 -1
  3. package/es/components/Accordion/AccordionItem.js +9 -2
  4. package/es/components/Breadcrumb/Breadcrumb.Skeleton.d.ts +27 -2
  5. package/es/components/Breadcrumb/Breadcrumb.Skeleton.js +27 -4
  6. package/es/components/Breadcrumb/Breadcrumb.js +2 -1
  7. package/es/components/Breadcrumb/BreadcrumbItem.js +1 -1
  8. package/es/components/Checkbox/Checkbox.js +2 -2
  9. package/es/components/ComboBox/ComboBox.js +39 -23
  10. package/es/components/ComboButton/index.js +1 -1
  11. package/es/components/ComposedModal/ComposedModal.js +66 -17
  12. package/es/components/ComposedModal/ComposedModalPresence.d.ts +34 -0
  13. package/es/components/ComposedModal/ComposedModalPresence.js +42 -0
  14. package/es/components/ComposedModal/index.d.ts +1 -0
  15. package/es/components/ComposedModal/useComposedModalState.d.ts +7 -0
  16. package/es/components/ComposedModal/useComposedModalState.js +24 -0
  17. package/es/components/ContentSwitcher/ContentSwitcher.js +2 -2
  18. package/es/components/DataTable/TableBatchActions.js +2 -2
  19. package/es/components/DatePickerInput/DatePickerInput.js +2 -2
  20. package/es/components/Dialog/Dialog.js +2 -2
  21. package/es/components/Dropdown/Dropdown.js +5 -5
  22. package/es/components/ExpandableSearch/ExpandableSearch.d.ts +1 -1
  23. package/es/components/ExpandableSearch/ExpandableSearch.js +1 -1
  24. package/es/components/FeatureFlags/index.d.ts +2 -1
  25. package/es/components/FeatureFlags/index.js +3 -1
  26. package/es/components/FileUploader/FileUploader.js +2 -2
  27. package/es/components/FileUploader/FileUploaderItem.js +2 -2
  28. package/es/components/FluidTextInput/FluidPasswordInput.js +24 -5
  29. package/es/components/FluidTextInput/index.js +1 -1
  30. package/es/components/FormLabel/FormLabel.js +1 -1
  31. package/es/components/ListBox/ListBox.d.ts +1 -1
  32. package/es/components/ListBox/ListBox.js +1 -2
  33. package/es/components/ListItem/ListItem.js +1 -1
  34. package/es/components/Menu/MenuItem.js +2 -2
  35. package/es/components/MenuButton/index.d.ts +1 -1
  36. package/es/components/MenuButton/index.js +1 -1
  37. package/es/components/Modal/Modal.js +60 -10
  38. package/es/components/Modal/ModalPresence.d.ts +32 -0
  39. package/es/components/Modal/ModalPresence.js +37 -0
  40. package/es/components/Modal/index.d.ts +2 -1
  41. package/es/components/Modal/index.js +1 -0
  42. package/es/components/MultiSelect/FilterableMultiSelect.js +3 -3
  43. package/es/components/MultiSelect/MultiSelect.js +6 -5
  44. package/es/components/Notification/Notification.js +2 -2
  45. package/es/components/NumberInput/NumberInput.d.ts +21 -11
  46. package/es/components/NumberInput/NumberInput.js +40 -26
  47. package/es/components/OverflowMenu/OverflowMenu.js +2 -3
  48. package/es/components/OverflowMenu/next/index.js +1 -1
  49. package/es/components/OverflowMenuItem/OverflowMenuItem.js +1 -1
  50. package/es/components/PageHeader/PageHeader.js +2 -2
  51. package/es/components/PaginationNav/PaginationNav.d.ts +20 -0
  52. package/es/components/PaginationNav/PaginationNav.js +34 -5
  53. package/es/components/ProgressIndicator/ProgressIndicator.js +1 -1
  54. package/es/components/RadioButton/RadioButton.js +3 -3
  55. package/es/components/RadioButtonGroup/RadioButtonGroup.js +2 -2
  56. package/es/components/RadioTile/RadioTile.js +2 -2
  57. package/es/components/Select/Select.js +2 -2
  58. package/es/components/Slider/Slider.js +2 -2
  59. package/es/components/StructuredList/StructuredList.js +2 -2
  60. package/es/components/Tabs/Tabs.js +2 -2
  61. package/es/components/Tag/DismissibleTag.js +3 -3
  62. package/es/components/Tag/OperationalTag.js +3 -3
  63. package/es/components/Tag/SelectableTag.js +3 -3
  64. package/es/components/Tag/Tag.js +2 -2
  65. package/es/components/Text/Text.d.ts +1 -1
  66. package/es/components/Text/Text.js +0 -1
  67. package/es/components/Text/TextDirection.d.ts +1 -1
  68. package/es/components/Text/TextDirection.js +0 -1
  69. package/es/components/Text/createTextComponent.d.ts +2 -8
  70. package/es/components/Text/createTextComponent.js +2 -2
  71. package/es/components/Text/index.d.ts +0 -8
  72. package/es/components/TextArea/TextArea.js +2 -2
  73. package/es/components/TextInput/TextInput.js +2 -2
  74. package/es/components/Tile/Tile.js +2 -2
  75. package/es/components/Toggle/Toggle.js +2 -2
  76. package/es/components/UIShell/Switcher.js +0 -26
  77. package/es/index.d.ts +27 -23
  78. package/es/index.js +44 -41
  79. package/es/internal/useNormalizedInputProps.js +2 -2
  80. package/es/internal/usePresence.d.ts +17 -0
  81. package/es/internal/usePresence.js +66 -0
  82. package/es/internal/usePresenceContext.d.ts +25 -0
  83. package/es/internal/usePresenceContext.js +46 -0
  84. package/es/tools/mergeRefs.d.ts +5 -5
  85. package/es/tools/mergeRefs.js +16 -12
  86. package/lib/components/Accordion/AccordionItem.d.ts +12 -1
  87. package/lib/components/Accordion/AccordionItem.js +9 -2
  88. package/lib/components/Breadcrumb/Breadcrumb.Skeleton.d.ts +27 -2
  89. package/lib/components/Breadcrumb/Breadcrumb.Skeleton.js +27 -4
  90. package/lib/components/Breadcrumb/Breadcrumb.js +2 -1
  91. package/lib/components/Breadcrumb/BreadcrumbItem.js +1 -1
  92. package/lib/components/Checkbox/Checkbox.js +2 -2
  93. package/lib/components/ComboBox/ComboBox.js +39 -23
  94. package/lib/components/ComboButton/index.js +1 -1
  95. package/lib/components/ComposedModal/ComposedModal.js +65 -16
  96. package/lib/components/ComposedModal/ComposedModalPresence.d.ts +34 -0
  97. package/lib/components/ComposedModal/ComposedModalPresence.js +46 -0
  98. package/lib/components/ComposedModal/index.d.ts +1 -0
  99. package/lib/components/ComposedModal/useComposedModalState.d.ts +7 -0
  100. package/lib/components/ComposedModal/useComposedModalState.js +26 -0
  101. package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -1
  102. package/lib/components/DataTable/TableBatchActions.js +2 -2
  103. package/lib/components/DatePickerInput/DatePickerInput.js +2 -2
  104. package/lib/components/Dialog/Dialog.js +2 -2
  105. package/lib/components/Dropdown/Dropdown.js +3 -3
  106. package/lib/components/ExpandableSearch/ExpandableSearch.d.ts +1 -1
  107. package/lib/components/ExpandableSearch/ExpandableSearch.js +1 -1
  108. package/lib/components/FeatureFlags/index.d.ts +2 -1
  109. package/lib/components/FeatureFlags/index.js +3 -1
  110. package/lib/components/FileUploader/FileUploader.js +2 -2
  111. package/lib/components/FileUploader/FileUploaderItem.js +2 -2
  112. package/lib/components/FluidTextInput/FluidPasswordInput.js +26 -5
  113. package/lib/components/FluidTextInput/index.js +2 -1
  114. package/lib/components/FormLabel/FormLabel.js +1 -1
  115. package/lib/components/ListBox/ListBox.d.ts +1 -1
  116. package/lib/components/ListBox/ListBox.js +1 -2
  117. package/lib/components/ListItem/ListItem.js +1 -1
  118. package/lib/components/Menu/MenuItem.js +2 -2
  119. package/lib/components/MenuButton/index.d.ts +1 -1
  120. package/lib/components/MenuButton/index.js +1 -1
  121. package/lib/components/Modal/Modal.js +59 -9
  122. package/lib/components/Modal/ModalPresence.d.ts +32 -0
  123. package/lib/components/Modal/ModalPresence.js +41 -0
  124. package/lib/components/Modal/index.d.ts +2 -1
  125. package/lib/components/Modal/index.js +1 -0
  126. package/lib/components/MultiSelect/FilterableMultiSelect.js +3 -3
  127. package/lib/components/MultiSelect/MultiSelect.js +4 -3
  128. package/lib/components/Notification/Notification.js +2 -2
  129. package/lib/components/NumberInput/NumberInput.d.ts +21 -11
  130. package/lib/components/NumberInput/NumberInput.js +40 -26
  131. package/lib/components/OverflowMenu/OverflowMenu.js +2 -3
  132. package/lib/components/OverflowMenu/next/index.js +1 -1
  133. package/lib/components/OverflowMenuItem/OverflowMenuItem.js +1 -1
  134. package/lib/components/PageHeader/PageHeader.js +2 -2
  135. package/lib/components/PaginationNav/PaginationNav.d.ts +20 -0
  136. package/lib/components/PaginationNav/PaginationNav.js +34 -5
  137. package/lib/components/ProgressIndicator/ProgressIndicator.js +1 -1
  138. package/lib/components/RadioButton/RadioButton.js +3 -3
  139. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +3 -3
  140. package/lib/components/RadioTile/RadioTile.js +2 -2
  141. package/lib/components/Select/Select.js +2 -2
  142. package/lib/components/Slider/Slider.js +2 -2
  143. package/lib/components/StructuredList/StructuredList.js +2 -2
  144. package/lib/components/Tabs/Tabs.js +2 -2
  145. package/lib/components/Tag/DismissibleTag.js +3 -3
  146. package/lib/components/Tag/OperationalTag.js +3 -3
  147. package/lib/components/Tag/SelectableTag.js +3 -3
  148. package/lib/components/Tag/Tag.js +2 -2
  149. package/lib/components/Text/Text.d.ts +1 -1
  150. package/lib/components/Text/Text.js +0 -1
  151. package/lib/components/Text/TextDirection.d.ts +1 -1
  152. package/lib/components/Text/TextDirection.js +0 -1
  153. package/lib/components/Text/createTextComponent.d.ts +2 -8
  154. package/lib/components/Text/createTextComponent.js +2 -2
  155. package/lib/components/Text/index.d.ts +0 -8
  156. package/lib/components/TextArea/TextArea.js +2 -2
  157. package/lib/components/TextInput/TextInput.js +2 -2
  158. package/lib/components/Tile/Tile.js +2 -2
  159. package/lib/components/Toggle/Toggle.js +2 -2
  160. package/lib/components/UIShell/Switcher.js +0 -26
  161. package/lib/index.d.ts +27 -23
  162. package/lib/index.js +55 -6
  163. package/lib/internal/useNormalizedInputProps.js +2 -2
  164. package/lib/internal/usePresence.d.ts +17 -0
  165. package/lib/internal/usePresence.js +68 -0
  166. package/lib/internal/usePresenceContext.d.ts +25 -0
  167. package/lib/internal/usePresenceContext.js +48 -0
  168. package/lib/tools/mergeRefs.d.ts +5 -5
  169. package/lib/tools/mergeRefs.js +16 -14
  170. package/package.json +8 -8
  171. package/telemetry.yml +5 -2
  172. package/es/components/Text/index.js +0 -16
  173. package/lib/components/Text/index.js +0 -20
@@ -255,7 +255,8 @@ const Dropdown = /*#__PURE__*/React.forwardRef(({
255
255
  const handleFocus = evt => {
256
256
  setIsFocused(evt.type === 'focus' && !selectedItem ? true : false);
257
257
  };
258
- const mergedRef = mergeRefs.default(toggleButtonProps.ref, ref);
258
+ const buttonRef = React.useRef(null);
259
+ const mergedRef = mergeRefs.mergeRefs(toggleButtonProps.ref, ref, buttonRef);
259
260
  const [currTimer, setCurrTimer] = React.useState();
260
261
  const [isTyping, setIsTyping] = React.useState(false);
261
262
  const onKeyDownHandler = React.useCallback(evt => {
@@ -291,7 +292,7 @@ const Dropdown = /*#__PURE__*/React.forwardRef(({
291
292
  // NOTE: does not prevent click
292
293
  evt.preventDefault();
293
294
  // focus on the element as per readonly input behavior
294
- mergedRef?.current?.focus();
295
+ buttonRef.current?.focus();
295
296
  },
296
297
  onKeyDown: evt => {
297
298
  const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
@@ -306,7 +307,6 @@ const Dropdown = /*#__PURE__*/React.forwardRef(({
306
307
  onKeyDown: onKeyDownHandler
307
308
  };
308
309
  }
309
- // eslint-disable-next-line react-hooks/exhaustive-deps -- https://github.com/carbon-design-system/carbon/issues/20071
310
310
  }, [readOnly, onKeyDownHandler]);
311
311
  const menuProps = React.useMemo(() => getMenuProps({
312
312
  ref: enableFloatingStyles || autoAlign ? refs.setFloating : null
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2021
2
+ * Copyright IBM Corp. 2021, 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.
@@ -65,7 +65,7 @@ const ExpandableSearch = /*#__PURE__*/React.forwardRef(function ExpandableSearch
65
65
  return /*#__PURE__*/React.createElement(Search.default, _rollupPluginBabelHelpers.extends({}, props, {
66
66
  defaultValue: defaultValue,
67
67
  isExpanded: expanded,
68
- ref: mergeRefs.default(searchRef, forwardedRef),
68
+ ref: mergeRefs.mergeRefs(searchRef, forwardedRef),
69
69
  className: classes,
70
70
  onBlur: events.composeEventHandlers([onBlur, handleBlur]),
71
71
  onChange: events.composeEventHandlers([onChange, handleChange]),
@@ -17,6 +17,7 @@ export interface FeatureFlagsProps {
17
17
  enableDialogElement?: boolean;
18
18
  enableV12DynamicFloatingStyles?: boolean;
19
19
  enableEnhancedFileUploader?: boolean;
20
+ enablePresence?: boolean;
20
21
  }
21
22
  /**
22
23
  * Our FeatureFlagContext is used alongside the FeatureFlags component to enable
@@ -28,7 +29,7 @@ declare const FeatureFlagContext: React.Context<any>;
28
29
  * along with the current `FeatureFlagContext` to provide consumers to check if
29
30
  * a feature flag is enabled or disabled in a given React tree
30
31
  */
31
- declare function FeatureFlags({ children, flags, enableV12TileDefaultIcons, enableV12TileRadioIcons, enableV12Overflowmenu, enableTreeviewControllable, enableExperimentalFocusWrapWithoutSentinels, enableDialogElement, enableV12DynamicFloatingStyles, enableEnhancedFileUploader, }: FeatureFlagsProps): JSX.Element;
32
+ declare function FeatureFlags({ children, flags, enableV12TileDefaultIcons, enableV12TileRadioIcons, enableV12Overflowmenu, enableTreeviewControllable, enableExperimentalFocusWrapWithoutSentinels, enableDialogElement, enableV12DynamicFloatingStyles, enableEnhancedFileUploader, enablePresence, }: FeatureFlagsProps): JSX.Element;
32
33
  declare namespace FeatureFlags {
33
34
  var propTypes: {
34
35
  children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
@@ -34,7 +34,8 @@ function FeatureFlags({
34
34
  enableExperimentalFocusWrapWithoutSentinels = false,
35
35
  enableDialogElement = false,
36
36
  enableV12DynamicFloatingStyles = false,
37
- enableEnhancedFileUploader = false
37
+ enableEnhancedFileUploader = false,
38
+ enablePresence = false
38
39
  }) {
39
40
  const parentScope = React.useContext(FeatureFlagContext);
40
41
  const [prevParentScope, setPrevParentScope] = React.useState(parentScope);
@@ -47,6 +48,7 @@ function FeatureFlags({
47
48
  'enable-dialog-element': enableDialogElement,
48
49
  'enable-v12-dynamic-floating-styles': enableV12DynamicFloatingStyles,
49
50
  'enable-enhanced-file-uploader': enableEnhancedFileUploader,
51
+ 'enable-presence': enablePresence,
50
52
  ...flags
51
53
  };
52
54
  const [scope, updateScope] = React.useState(() => {
@@ -19,10 +19,10 @@ var Button = require('../Button/Button.js');
19
19
  var keys = require('../../internal/keyboard/keys.js');
20
20
  var match = require('../../internal/keyboard/match.js');
21
21
  var usePrefix = require('../../internal/usePrefix.js');
22
- require('../Text/index.js');
22
+ var Text = require('../Text/Text.js');
23
+ require('../Text/TextDirection.js');
23
24
  var useId = require('../../internal/useId.js');
24
25
  var index = require('../FeatureFlags/index.js');
25
- var Text = require('../Text/Text.js');
26
26
 
27
27
  // eslint-disable-next-line react/display-name -- https://github.com/carbon-design-system/carbon/issues/20071
28
28
  const FileUploader = /*#__PURE__*/React.forwardRef(({
@@ -19,10 +19,10 @@ 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
- require('../Text/index.js');
22
+ var Text = require('../Text/Text.js');
23
+ require('../Text/TextDirection.js');
23
24
  require('../Tooltip/DefinitionTooltip.js');
24
25
  var Tooltip = require('../Tooltip/Tooltip.js');
25
- var Text = require('../Text/Text.js');
26
26
 
27
27
  function FileUploaderItem({
28
28
  uuid,
@@ -7,13 +7,32 @@
7
7
 
8
8
  'use strict';
9
9
 
10
+ Object.defineProperty(exports, '__esModule', { value: true });
11
+
12
+ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
10
13
  var PropTypes = require('prop-types');
11
- require('react');
12
- require('classnames');
14
+ var React = require('react');
15
+ var cx = require('classnames');
13
16
  require('../TextInput/ControlledPasswordInput.js');
14
- require('../TextInput/PasswordInput.js');
17
+ var PasswordInput = require('../TextInput/PasswordInput.js');
18
+ var usePrefix = require('../../internal/usePrefix.js');
19
+ var FormContext = require('../FluidForm/FormContext.js');
15
20
 
16
- ({
21
+ const FluidPasswordInput = ({
22
+ className,
23
+ ...other
24
+ }) => {
25
+ const prefix = usePrefix.usePrefix();
26
+ const classNames = cx(className, `${prefix}--text-input--fluid`);
27
+ return /*#__PURE__*/React.createElement(FormContext.FormContext.Provider, {
28
+ value: {
29
+ isFluid: true
30
+ }
31
+ }, /*#__PURE__*/React.createElement(PasswordInput.default, _rollupPluginBabelHelpers.extends({
32
+ className: classNames
33
+ }, other)));
34
+ };
35
+ FluidPasswordInput.propTypes = {
17
36
  /**
18
37
  * Specify an optional className to be applied to the outer FluidForm wrapper
19
38
  */
@@ -90,4 +109,6 @@ require('../TextInput/PasswordInput.js');
90
109
  * Whether or not the component is readonly
91
110
  */
92
111
  readOnly: PropTypes.bool
93
- });
112
+ };
113
+
114
+ exports.default = FluidPasswordInput;
@@ -10,11 +10,12 @@
10
10
  Object.defineProperty(exports, '__esModule', { value: true });
11
11
 
12
12
  var FluidTextInput = require('./FluidTextInput.js');
13
- require('./FluidPasswordInput.js');
13
+ var FluidPasswordInput = require('./FluidPasswordInput.js');
14
14
  var FluidTextInput_Skeleton = require('./FluidTextInput.Skeleton.js');
15
15
 
16
16
 
17
17
 
18
18
  exports.FluidTextInput = FluidTextInput.default;
19
19
  exports.default = FluidTextInput.default;
20
+ exports.FluidPasswordInput = FluidPasswordInput.default;
20
21
  exports.FluidTextInputSkeleton = FluidTextInput_Skeleton.default;
@@ -14,8 +14,8 @@ var PropTypes = require('prop-types');
14
14
  var React = require('react');
15
15
  var cx = require('classnames');
16
16
  var usePrefix = require('../../internal/usePrefix.js');
17
- require('../Text/index.js');
18
17
  var Text = require('../Text/Text.js');
18
+ require('../Text/TextDirection.js');
19
19
 
20
20
  function FormLabel({
21
21
  className: customClassName,
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import React, { type HTMLAttributes } from 'react';
8
- import { type ListBoxSize, type ListBoxType } from '.';
8
+ import { type ListBoxSize, type ListBoxType } from './ListBoxPropTypes';
9
9
  type ExcludedAttributes = 'onKeyDown' | 'onKeyPress' | 'ref';
10
10
  export interface ListBoxProps extends Omit<HTMLAttributes<HTMLDivElement>, ExcludedAttributes> {
11
11
  /**
@@ -14,11 +14,10 @@ var cx = require('classnames');
14
14
  var React = require('react');
15
15
  var PropTypes = require('prop-types');
16
16
  var deprecate = require('../../prop-types/deprecate.js');
17
- require('./index.js');
17
+ var ListBoxPropTypes = require('./ListBoxPropTypes.js');
18
18
  var usePrefix = require('../../internal/usePrefix.js');
19
19
  require('../FluidForm/FluidForm.js');
20
20
  var FormContext = require('../FluidForm/FormContext.js');
21
- var ListBoxPropTypes = require('./ListBoxPropTypes.js');
22
21
 
23
22
  const handleOnKeyDown = event => {
24
23
  if (event.keyCode === 27) {
@@ -14,8 +14,8 @@ var PropTypes = require('prop-types');
14
14
  var React = require('react');
15
15
  var cx = require('classnames');
16
16
  var usePrefix = require('../../internal/usePrefix.js');
17
- require('../Text/index.js');
18
17
  var Text = require('../Text/Text.js');
18
+ require('../Text/TextDirection.js');
19
19
 
20
20
  function ListItem({
21
21
  className,
@@ -22,9 +22,9 @@ var Menu = require('./Menu.js');
22
22
  var MenuContext = require('./MenuContext.js');
23
23
  require('../LayoutDirection/LayoutDirection.js');
24
24
  var useLayoutDirection = require('../LayoutDirection/useLayoutDirection.js');
25
- require('../Text/index.js');
26
- var defaultItemToString = require('../../internal/defaultItemToString.js');
27
25
  var Text = require('../Text/Text.js');
26
+ require('../Text/TextDirection.js');
27
+ var defaultItemToString = require('../../internal/defaultItemToString.js');
28
28
 
29
29
  var _Checkmark, _CaretLeft, _CaretRight;
30
30
  const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem({
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2023
2
+ * Copyright IBM Corp. 2023, 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.
@@ -88,7 +88,7 @@ const MenuButton = /*#__PURE__*/React.forwardRef(({
88
88
  middleware: middlewares,
89
89
  whileElementsMounted: react.autoUpdate
90
90
  });
91
- const ref = mergeRefs.default(forwardRef, triggerRef);
91
+ const ref = mergeRefs.mergeRefs(forwardRef, triggerRef);
92
92
  const {
93
93
  open,
94
94
  handleClick: hookOnClick,
@@ -24,13 +24,15 @@ var requiredIfGivenPropIsTruthy = require('../../prop-types/requiredIfGivenPropI
24
24
  var wrapFocus = require('../../internal/wrapFocus.js');
25
25
  var useIsomorphicEffect = require('../../internal/useIsomorphicEffect.js');
26
26
  var useId = require('../../internal/useId.js');
27
+ var useMergedRefs = require('../../internal/useMergedRefs.js');
27
28
  var usePrefix = require('../../internal/usePrefix.js');
28
29
  var usePreviousValue = require('../../internal/usePreviousValue.js');
29
30
  var keys = require('../../internal/keyboard/keys.js');
30
31
  var match = require('../../internal/keyboard/match.js');
31
32
  var index$2 = require('../IconButton/index.js');
32
33
  var noopFn = require('../../internal/noopFn.js');
33
- require('../Text/index.js');
34
+ var Text = require('../Text/Text.js');
35
+ require('../Text/TextDirection.js');
34
36
  var index = require('../FeatureFlags/index.js');
35
37
  var events = require('../../tools/events.js');
36
38
  var deprecate = require('../../prop-types/deprecate.js');
@@ -38,12 +40,40 @@ var Dialog = require('../Dialog/Dialog.js');
38
40
  var index$1 = require('../AILabel/index.js');
39
41
  var utils = require('../../internal/utils.js');
40
42
  var warning = require('../../internal/warning.js');
43
+ var ModalPresence = require('./ModalPresence.js');
41
44
  var debounce = require('../../node_modules/es-toolkit/dist/compat/function/debounce.js');
42
- var Text = require('../Text/Text.js');
43
45
 
44
46
  const ModalSizes = ['xs', 'sm', 'md', 'lg'];
45
47
  const invalidOutsideClickMessage = '`<Modal>` prop `preventCloseOnClickOutside` should not be `false` when ' + '`passiveModal` is `false`. Transactional, non-passive Modals should ' + 'not be dissmissable by clicking outside. ' + 'See: https://carbondesignsystem.com/components/modal/usage/#transactional-modal';
46
48
  const Modal = /*#__PURE__*/React.forwardRef(function Modal({
49
+ open,
50
+ ...props
51
+ }, ref) {
52
+ const id = useId.useId();
53
+ const enablePresence = index.useFeatureFlag('enable-presence');
54
+ const hasPresenceContext = Boolean(React.useContext(ModalPresence.ModalPresenceContext));
55
+ const hasPresenceOptIn = enablePresence || hasPresenceContext;
56
+ const exclusivePresenceContext = ModalPresence.useExclusiveModalPresenceContext(id);
57
+
58
+ // if opt in and not exclusive to a presence context, wrap with presence
59
+ if (hasPresenceOptIn && !exclusivePresenceContext) {
60
+ return /*#__PURE__*/React.createElement(ModalPresence.ModalPresence, {
61
+ open: open ?? false,
62
+ _presenceId: id
63
+ // do not auto enable styles for opt-in by feature flag
64
+ ,
65
+ _autoEnablePresence: hasPresenceContext
66
+ }, /*#__PURE__*/React.createElement(ModalDialog, _rollupPluginBabelHelpers.extends({
67
+ open: true,
68
+ ref: ref
69
+ }, props)));
70
+ }
71
+ return /*#__PURE__*/React.createElement(ModalDialog, _rollupPluginBabelHelpers.extends({
72
+ ref: ref,
73
+ open: open
74
+ }, props));
75
+ });
76
+ const ModalDialog = /*#__PURE__*/React.forwardRef(function ModalDialog({
47
77
  'aria-label': ariaLabelProp,
48
78
  children,
49
79
  className,
@@ -54,7 +84,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
54
84
  passiveModal = false,
55
85
  secondaryButtonText,
56
86
  primaryButtonText,
57
- open,
87
+ open: externalOpen,
58
88
  onRequestClose = noopFn.noopFn,
59
89
  onRequestSubmit = noopFn.noopFn,
60
90
  onSecondarySubmit,
@@ -87,7 +117,6 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
87
117
  const endTrap = React.useRef(null);
88
118
  const wrapFocusTimeout = React.useRef(null);
89
119
  const [isScrollable, setIsScrollable] = React.useState(false);
90
- const prevOpen = usePreviousValue.usePreviousValue(open);
91
120
  const modalInstanceId = `modal-${useId.useId()}`;
92
121
  const modalLabelId = `${prefix}--modal-header__label--${modalInstanceId}`;
93
122
  const modalHeadingId = `${prefix}--modal-header__heading--${modalInstanceId}`;
@@ -97,6 +126,13 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
97
126
  [`${prefix}--btn--loading`]: loadingStatus !== 'inactive'
98
127
  });
99
128
  const loadingActive = loadingStatus !== 'inactive';
129
+ const presenceContext = React.useContext(ModalPresence.ModalPresenceContext);
130
+ const mergedRefs = useMergedRefs.useMergedRefs([ref, presenceContext?.presenceRef]);
131
+ const enablePresence = index.useFeatureFlag('enable-presence') || presenceContext?.autoEnablePresence;
132
+
133
+ // always mark as open when mounted with presence
134
+ const open = externalOpen || enablePresence;
135
+ const prevOpen = usePreviousValue.usePreviousValue(open);
100
136
  const focusTrapWithoutSentinels = index.useFeatureFlag('enable-experimental-focus-wrap-without-sentinels');
101
137
  const enableDialogElement = index.useFeatureFlag('enable-dialog-element');
102
138
  process.env.NODE_ENV !== "production" ? warning.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;
@@ -192,7 +228,8 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
192
228
  const onSecondaryButtonClick = onSecondarySubmit ? onSecondarySubmit : onRequestClose;
193
229
  const modalClasses = cx(`${prefix}--modal`, {
194
230
  [`${prefix}--modal-tall`]: !passiveModal,
195
- 'is-visible': open,
231
+ 'is-visible': enablePresence || open,
232
+ [`${prefix}--modal--enable-presence`]: presenceContext?.autoEnablePresence,
196
233
  [`${prefix}--modal--danger`]: danger,
197
234
  [`${prefix}--modal--slug`]: slug,
198
235
  [`${prefix}--modal--decorator`]: decorator
@@ -256,14 +293,25 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
256
293
  }
257
294
  }, [open, prefix, enableDialogElement]);
258
295
  React.useEffect(() => {
259
- if (!enableDialogElement && prevOpen && !open && launcherButtonRef) {
296
+ if (!enableDialogElement && !enablePresence && prevOpen && !open && launcherButtonRef) {
260
297
  setTimeout(() => {
261
298
  if ('current' in launcherButtonRef) {
262
299
  launcherButtonRef.current?.focus();
263
300
  }
264
301
  });
265
302
  }
266
- }, [open, prevOpen, launcherButtonRef, enableDialogElement]);
303
+ }, [open, prevOpen, launcherButtonRef, enableDialogElement, enablePresence]);
304
+ // Focus launcherButtonRef on unmount
305
+ React.useEffect(() => {
306
+ const launcherButton = launcherButtonRef?.current;
307
+ return () => {
308
+ if (enablePresence && launcherButton) {
309
+ setTimeout(() => {
310
+ launcherButton.focus();
311
+ });
312
+ }
313
+ };
314
+ }, [enablePresence, launcherButtonRef]);
267
315
  React.useEffect(() => {
268
316
  if (!enableDialogElement) {
269
317
  const initialFocus = focusContainerElement => {
@@ -335,7 +383,8 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
335
383
  role: isAlertDialog ? 'alertdialog' : '',
336
384
  "aria-describedby": isAlertDialog ? modalBodyId : '',
337
385
  className: containerClasses,
338
- "aria-label": ariaLabel
386
+ "aria-label": ariaLabel,
387
+ "data-exiting": presenceContext?.isExiting || undefined
339
388
  }, /*#__PURE__*/React.createElement("div", {
340
389
  className: `${prefix}--modal-header`
341
390
  }, modalLabel && /*#__PURE__*/React.createElement(Text.Text, {
@@ -462,7 +511,8 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
462
511
  onBlur: handleBlur,
463
512
  className: modalClasses,
464
513
  role: "presentation",
465
- ref: ref
514
+ ref: mergedRefs,
515
+ "data-exiting": presenceContext?.isExiting || undefined
466
516
  }), modalBody);
467
517
  });
468
518
  Modal.propTypes = {
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2025
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import React, { type PropsWithChildren } from 'react';
8
+ import { type PresenceContext } from '../../internal/usePresenceContext';
9
+ export interface ModalPresenceProps {
10
+ /**
11
+ * Specify whether the Modal is currently open
12
+ */
13
+ open: boolean;
14
+ /**
15
+ * Internal property for backwards compatibility. Specify whether the Modal should opt in to presence mode.
16
+ */
17
+ _autoEnablePresence?: boolean;
18
+ /**
19
+ * Internal property to predefine the presence context's id for exclusivity.
20
+ */
21
+ _presenceId?: string;
22
+ }
23
+ export declare const ModalPresence: ({ open, _presenceId: presenceId, _autoEnablePresence: autoEnablePresence, children, }: PropsWithChildren<ModalPresenceProps>) => import("react/jsx-runtime").JSX.Element | null;
24
+ interface ModalPresenceContextProps extends PresenceContext {
25
+ autoEnablePresence: boolean;
26
+ }
27
+ export declare const ModalPresenceContext: React.Context<ModalPresenceContextProps | undefined>;
28
+ /**
29
+ * Handles occurrences where only a single modal must consume a context.
30
+ */
31
+ export declare const useExclusiveModalPresenceContext: (id: string) => ModalPresenceContextProps | undefined;
32
+ export {};
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ var React = require('react');
11
+ var usePresenceContext = require('../../internal/usePresenceContext.js');
12
+
13
+ const ModalPresence = ({
14
+ open,
15
+ _presenceId: presenceId,
16
+ _autoEnablePresence: autoEnablePresence = true,
17
+ children
18
+ }) => {
19
+ const [isPresent, context] = usePresenceContext.usePresenceContext(open, presenceId);
20
+ const contextValue = React.useMemo(() => ({
21
+ autoEnablePresence,
22
+ ...context
23
+ }), [autoEnablePresence, context]);
24
+ if (!isPresent) return null;
25
+ return /*#__PURE__*/React.createElement(ModalPresenceContext.Provider, {
26
+ value: contextValue
27
+ }, children);
28
+ };
29
+ const ModalPresenceContext = /*#__PURE__*/React.createContext(undefined);
30
+
31
+ /**
32
+ * Handles occurrences where only a single modal must consume a context.
33
+ */
34
+ const useExclusiveModalPresenceContext = id => {
35
+ const ctx = React.useContext(ModalPresenceContext);
36
+ return ctx?.isPresenceExclusive(id) ? ctx : undefined;
37
+ };
38
+
39
+ exports.ModalPresence = ModalPresence;
40
+ exports.ModalPresenceContext = ModalPresenceContext;
41
+ exports.useExclusiveModalPresenceContext = useExclusiveModalPresenceContext;
@@ -5,5 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import Modal, { type ModalProps } from './Modal';
8
+ import { ModalPresence, type ModalPresenceProps } from './ModalPresence';
8
9
  export default Modal;
9
- export { Modal, type ModalProps };
10
+ export { Modal, ModalPresence, type ModalProps, type ModalPresenceProps };
@@ -10,6 +10,7 @@
10
10
  Object.defineProperty(exports, '__esModule', { value: true });
11
11
 
12
12
  var Modal = require('./Modal.js');
13
+ require('react');
13
14
 
14
15
 
15
16
 
@@ -625,14 +625,14 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
625
625
  setIsFocused(evt?.type === 'focus' ? true : false);
626
626
  }
627
627
  };
628
- const mergedRef = mergeRefs.default(textInput, inputProp.ref);
628
+ const mergedRef = mergeRefs.mergeRefs(textInput, inputProp.ref);
629
629
  const readOnlyEventHandlers = readOnly ? {
630
630
  onClick: evt => {
631
631
  // NOTE: does not prevent click
632
632
  evt.preventDefault();
633
633
  // focus on the element as per readonly input behavior
634
- if (mergedRef.current !== undefined) {
635
- mergedRef.current.focus();
634
+ if (textInput.current) {
635
+ textInput.current.focus();
636
636
  }
637
637
  },
638
638
  onKeyDown: evt => {
@@ -235,7 +235,8 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
235
235
  }
236
236
  }
237
237
  });
238
- const mergedRef = mergeRefs.default(toggleButtonProps.ref, ref);
238
+ const toggleButtonRef = React.useRef(null);
239
+ const mergedRef = mergeRefs.mergeRefs(toggleButtonProps.ref, ref, toggleButtonRef);
239
240
  const selectedItems = selectedItem;
240
241
 
241
242
  /**
@@ -390,8 +391,8 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
390
391
  // NOTE: does not prevent click
391
392
  evt.preventDefault();
392
393
  // focus on the element as per readonly input behavior
393
- if (mergedRef.current !== undefined) {
394
- mergedRef.current.focus();
394
+ if (toggleButtonRef.current) {
395
+ toggleButtonRef.current.focus();
395
396
  }
396
397
  },
397
398
  onKeyDown: evt => {
@@ -13,7 +13,8 @@ var React = require('react');
13
13
  var deprecate = require('../../prop-types/deprecate.js');
14
14
  var cx = require('classnames');
15
15
  var iconsReact = require('@carbon/icons-react');
16
- require('../Text/index.js');
16
+ var Text = require('../Text/Text.js');
17
+ require('../Text/TextDirection.js');
17
18
  var Button = require('../Button/Button.js');
18
19
  require('../Button/Button.Skeleton.js');
19
20
  var useIsomorphicEffect = require('../../internal/useIsomorphicEffect.js');
@@ -27,7 +28,6 @@ var wrapFocus = require('../../internal/wrapFocus.js');
27
28
  var index = require('../FeatureFlags/index.js');
28
29
  var warning = require('../../internal/warning.js');
29
30
  var deprecateValuesWithin = require('../../prop-types/deprecateValuesWithin.js');
30
- var Text = require('../Text/Text.js');
31
31
 
32
32
  /**
33
33
  * Conditionally call a callback when the escape key is pressed
@@ -17,6 +17,26 @@ export declare const translationIds: {
17
17
  type TranslationKey = keyof typeof translationIds;
18
18
  type ExcludedAttributes = 'defaultValue' | 'id' | 'min' | 'max' | 'onChange' | 'onClick' | 'size' | 'step' | 'value';
19
19
  export interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, ExcludedAttributes>, TranslateWithId<TranslationKey> {
20
+ /**
21
+ * Optional validation function that is called with the input value and locale.
22
+ * This is called before other validations, giving consumers the ability
23
+ * to short-circuit or extend validation without replacing built-in rules
24
+ * @example
25
+ * // Using the built-in separator validation
26
+ * <NumberInput validate={validateNumberSeparators} />
27
+ *
28
+ * // Combining with custom validation
29
+ * <NumberInput
30
+ * validate={(value, locale) => {
31
+ * return validateNumberSeparators(value, locale) && customValidation(value)
32
+ * }}
33
+ * />
34
+ * - Return `false` to immediately fail validation.
35
+ * - Return `true` to pass this validation, but still run other checks (min, max, required, etc.).
36
+ * - Return `undefined` to defer entirely to built-in validation logic.
37
+ *
38
+ */
39
+ validate?: (value: string, locale: string) => boolean | undefined;
20
40
  /**
21
41
  * `true` to allow empty string.
22
42
  */
@@ -186,16 +206,6 @@ export interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInp
186
206
  */
187
207
  warnText?: ReactNode;
188
208
  }
209
+ export declare const validateNumberSeparators: (input: string, locale: string) => boolean;
189
210
  declare const NumberInput: React.ForwardRefExoticComponent<NumberInputProps & React.RefAttributes<HTMLInputElement>>;
190
- export interface Label {
191
- disabled?: boolean;
192
- hideLabel?: boolean;
193
- id?: string;
194
- label?: ReactNode;
195
- }
196
- export interface HelperTextProps {
197
- id?: string;
198
- description?: ReactNode;
199
- disabled?: boolean;
200
- }
201
211
  export { NumberInput };