@carbon/react 1.102.0 → 1.103.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 (153) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +1011 -1011
  2. package/es/components/Breadcrumb/BreadcrumbItem.js +1 -1
  3. package/es/components/Button/Button.Skeleton.js +2 -1
  4. package/es/components/Button/Button.d.ts +4 -4
  5. package/es/components/Button/Button.js +4 -4
  6. package/es/components/Button/index.js +1 -1
  7. package/es/components/ButtonSet/ButtonSet.js +1 -1
  8. package/es/components/Checkbox/index.js +1 -1
  9. package/es/components/ComboBox/ComboBox.js +2 -2
  10. package/es/components/ComposedModal/ComposedModal.js +0 -3
  11. package/es/components/ComposedModal/ComposedModalPresence.d.ts +9 -1
  12. package/es/components/ComposedModal/ComposedModalPresence.js +14 -1
  13. package/es/components/ComposedModal/index.d.ts +1 -1
  14. package/es/components/ContainedList/index.js +1 -1
  15. package/es/components/DataTable/TableHeader.js +1 -1
  16. package/es/components/DataTable/TableRow.js +1 -1
  17. package/es/components/DataTable/TableToolbarMenu.js +1 -1
  18. package/es/components/DatePicker/DatePicker.Skeleton.d.ts +8 -5
  19. package/es/components/DatePicker/DatePicker.Skeleton.js +2 -2
  20. package/es/components/DatePicker/DatePicker.d.ts +4 -2
  21. package/es/components/DatePicker/DatePicker.js +9 -6
  22. package/es/components/DatePicker/index.js +1 -1
  23. package/es/components/DatePicker/plugins/rangePlugin.d.ts +1 -1
  24. package/es/components/DatePicker/plugins/rangePlugin.js +2 -1
  25. package/es/components/{UIShell/_utils.d.ts → DatePicker/utils.d.ts} +2 -2
  26. package/es/components/{UIShell/_utils.js → DatePicker/utils.js} +2 -2
  27. package/es/components/DatePickerInput/DatePickerInput.js +1 -1
  28. package/es/components/Dialog/Dialog.js +1 -1
  29. package/es/components/Dropdown/index.js +1 -1
  30. package/es/components/ExpandableSearch/ExpandableSearch.js +1 -1
  31. package/es/components/FeatureFlags/index.d.ts +8 -18
  32. package/es/components/FeatureFlags/index.js +23 -103
  33. package/es/components/FileUploader/FileUploader.Skeleton.js +1 -1
  34. package/es/components/FileUploader/FileUploaderButton.d.ts +1 -1
  35. package/es/components/FileUploader/FileUploaderButton.js +3 -7
  36. package/es/components/Icon/Icon.Skeleton.js +1 -1
  37. package/es/components/IconIndicator/index.js +1 -1
  38. package/es/components/Menu/MenuItem.js +1 -1
  39. package/es/components/Modal/ModalPresence.d.ts +9 -1
  40. package/es/components/Modal/ModalPresence.js +14 -1
  41. package/es/components/Modal/index.d.ts +2 -2
  42. package/es/components/MultiSelect/MultiSelect.js +9 -10
  43. package/es/components/Notification/Notification.js +1 -1
  44. package/es/components/NumberInput/NumberInput.js +15 -13
  45. package/es/components/OverflowMenu/OverflowMenu.d.ts +1 -1
  46. package/es/components/OverflowMenu/OverflowMenu.js +3 -5
  47. package/es/components/OverflowMenuV2/index.js +1 -1
  48. package/es/components/PageHeader/PageHeader.js +2 -23
  49. package/es/components/Pagination/Pagination.Skeleton.js +1 -1
  50. package/es/components/Pagination/Pagination.d.ts +4 -0
  51. package/es/components/Pagination/Pagination.js +6 -1
  52. package/es/components/Pagination/experimental/Pagination.js +12 -1
  53. package/es/components/Popover/index.js +1 -1
  54. package/es/components/RadioButton/RadioButton.Skeleton.js +1 -1
  55. package/es/components/Search/index.js +1 -1
  56. package/es/components/Select/index.js +1 -1
  57. package/es/components/ShapeIndicator/index.js +1 -1
  58. package/es/components/Slider/Slider.js +230 -249
  59. package/es/components/Slider/SliderHandles.js +65 -53
  60. package/es/components/Switch/IconSwitch.js +1 -1
  61. package/es/components/Tabs/Tabs.js +10 -12
  62. package/es/components/Tag/Tag.Skeleton.js +1 -1
  63. package/es/components/TextArea/TextArea.js +1 -1
  64. package/es/components/TextArea/index.js +1 -1
  65. package/es/components/TextInput/index.js +1 -1
  66. package/es/components/Tile/Tile.d.ts +2 -2
  67. package/es/components/Tile/Tile.js +7 -2
  68. package/es/components/Toggle/Toggle.Skeleton.js +1 -1
  69. package/es/components/Toggletip/index.js +1 -1
  70. package/es/components/UIShell/HeaderMenu.js +1 -1
  71. package/es/components/UIShell/SideNav.d.ts +1 -4
  72. package/es/components/UIShell/SideNav.js +10 -25
  73. package/es/components/UIShell/SideNavContext.d.ts +17 -0
  74. package/es/components/UIShell/SideNavContext.js +24 -0
  75. package/es/components/UIShell/SideNavItems.d.ts +1 -1
  76. package/es/components/UIShell/SideNavItems.js +12 -16
  77. package/es/components/UIShell/SideNavLink.js +8 -4
  78. package/es/components/UIShell/SideNavMenu.js +7 -5
  79. package/es/index.js +30 -30
  80. package/es/internal/useNoInteractiveChildren.js +25 -30
  81. package/es/internal/usePresence.d.ts +1 -1
  82. package/es/internal/usePresence.js +14 -17
  83. package/lib/components/Button/Button.Skeleton.js +2 -1
  84. package/lib/components/Button/Button.d.ts +4 -4
  85. package/lib/components/Button/Button.js +4 -4
  86. package/lib/components/Button/index.js +1 -1
  87. package/lib/components/ButtonSet/ButtonSet.js +1 -1
  88. package/lib/components/Checkbox/index.js +1 -1
  89. package/lib/components/ComboBox/ComboBox.js +2 -2
  90. package/lib/components/ComposedModal/ComposedModal.js +0 -3
  91. package/lib/components/ComposedModal/ComposedModalPresence.d.ts +9 -1
  92. package/lib/components/ComposedModal/ComposedModalPresence.js +14 -0
  93. package/lib/components/ComposedModal/index.d.ts +1 -1
  94. package/lib/components/ContainedList/index.js +0 -3
  95. package/lib/components/DataTable/TableToolbarMenu.js +1 -1
  96. package/lib/components/DatePicker/DatePicker.Skeleton.d.ts +8 -5
  97. package/lib/components/DatePicker/DatePicker.Skeleton.js +2 -2
  98. package/lib/components/DatePicker/DatePicker.d.ts +4 -2
  99. package/lib/components/DatePicker/DatePicker.js +9 -6
  100. package/lib/components/DatePicker/index.js +1 -1
  101. package/lib/components/DatePicker/plugins/rangePlugin.d.ts +1 -1
  102. package/lib/components/DatePicker/plugins/rangePlugin.js +2 -1
  103. package/lib/components/{UIShell/_utils.d.ts → DatePicker/utils.d.ts} +2 -2
  104. package/lib/components/{UIShell/_utils.js → DatePicker/utils.js} +2 -2
  105. package/lib/components/Dropdown/index.js +1 -1
  106. package/lib/components/FeatureFlags/index.d.ts +8 -18
  107. package/lib/components/FeatureFlags/index.js +21 -102
  108. package/lib/components/FileUploader/FileUploader.Skeleton.js +1 -1
  109. package/lib/components/FileUploader/FileUploaderButton.d.ts +1 -1
  110. package/lib/components/FileUploader/FileUploaderButton.js +2 -6
  111. package/lib/components/Icon/Icon.Skeleton.js +0 -3
  112. package/lib/components/IconIndicator/index.js +0 -3
  113. package/lib/components/Modal/ModalPresence.d.ts +9 -1
  114. package/lib/components/Modal/ModalPresence.js +14 -0
  115. package/lib/components/Modal/index.d.ts +2 -2
  116. package/lib/components/MultiSelect/MultiSelect.js +8 -9
  117. package/lib/components/NumberInput/NumberInput.js +14 -12
  118. package/lib/components/OverflowMenu/OverflowMenu.d.ts +1 -1
  119. package/lib/components/OverflowMenu/OverflowMenu.js +2 -7
  120. package/lib/components/OverflowMenuV2/index.js +1 -1
  121. package/lib/components/PageHeader/PageHeader.js +2 -23
  122. package/lib/components/Pagination/Pagination.Skeleton.js +0 -3
  123. package/lib/components/Pagination/Pagination.d.ts +4 -0
  124. package/lib/components/Pagination/Pagination.js +6 -1
  125. package/lib/components/Pagination/experimental/Pagination.js +12 -1
  126. package/lib/components/RadioButton/RadioButton.Skeleton.js +0 -3
  127. package/lib/components/Search/index.js +1 -1
  128. package/lib/components/Select/index.js +1 -1
  129. package/lib/components/ShapeIndicator/index.js +0 -3
  130. package/lib/components/Slider/Slider.js +229 -248
  131. package/lib/components/Slider/SliderHandles.js +64 -52
  132. package/lib/components/Tabs/Tabs.js +9 -11
  133. package/lib/components/Tag/Tag.Skeleton.js +0 -3
  134. package/lib/components/TextArea/index.js +1 -1
  135. package/lib/components/TextInput/index.js +1 -1
  136. package/lib/components/Tile/Tile.d.ts +2 -2
  137. package/lib/components/Tile/Tile.js +6 -1
  138. package/lib/components/Toggle/Toggle.Skeleton.js +0 -3
  139. package/lib/components/Toggletip/index.js +0 -3
  140. package/lib/components/UIShell/SideNav.d.ts +1 -4
  141. package/lib/components/UIShell/SideNav.js +8 -24
  142. package/lib/components/UIShell/SideNavContext.d.ts +17 -0
  143. package/lib/components/UIShell/SideNavContext.js +27 -0
  144. package/lib/components/UIShell/SideNavItems.d.ts +1 -1
  145. package/lib/components/UIShell/SideNavItems.js +11 -15
  146. package/lib/components/UIShell/SideNavLink.js +7 -3
  147. package/lib/components/UIShell/SideNavMenu.js +8 -6
  148. package/lib/index.js +102 -100
  149. package/lib/internal/useNoInteractiveChildren.js +25 -30
  150. package/lib/internal/usePresence.d.ts +1 -1
  151. package/lib/internal/usePresence.js +13 -16
  152. package/package.json +5 -5
  153. package/telemetry.yml +2 -1
@@ -7,10 +7,9 @@
7
7
 
8
8
  import { FeatureFlags as FeatureFlags$1, createScope } from '@carbon/feature-flags';
9
9
  import PropTypes from 'prop-types';
10
- import React, { useContext, createContext, useState, useRef, useEffect } from 'react';
10
+ import React, { useContext, createContext, useMemo } from 'react';
11
11
  import { deprecate } from '../../prop-types/deprecate.js';
12
12
 
13
- // TODO: Can this variable be deleted now? It isn't used anywhere.
14
13
  /**
15
14
  * Our FeatureFlagContext is used alongside the FeatureFlags component to enable
16
15
  * or disable feature flags in a given React tree
@@ -22,7 +21,7 @@ const FeatureFlagContext = /*#__PURE__*/createContext(FeatureFlags$1);
22
21
  * along with the current `FeatureFlagContext` to provide consumers to check if
23
22
  * a feature flag is enabled or disabled in a given React tree
24
23
  */
25
- function FeatureFlags({
24
+ const FeatureFlags = ({
26
25
  children,
27
26
  flags = {},
28
27
  enableV12TileDefaultIcons = false,
@@ -35,46 +34,30 @@ function FeatureFlags({
35
34
  enableV12DynamicFloatingStyles = false,
36
35
  enableEnhancedFileUploader = false,
37
36
  enablePresence = false
38
- }) {
37
+ }) => {
39
38
  const parentScope = useContext(FeatureFlagContext);
40
- const [prevParentScope, setPrevParentScope] = useState(parentScope);
41
- const combinedFlags = {
42
- 'enable-v12-tile-default-icons': enableV12TileDefaultIcons,
43
- 'enable-v12-tile-radio-icons': enableV12TileRadioIcons,
44
- 'enable-v12-overflowmenu': enableV12Overflowmenu,
45
- 'enable-treeview-controllable': enableTreeviewControllable,
46
- 'enable-experimental-focus-wrap-without-sentinels': enableExperimentalFocusWrapWithoutSentinels,
47
- 'enable-focus-wrap-without-sentinels': enableFocusWrapWithoutSentinels,
48
- 'enable-dialog-element': enableDialogElement,
49
- 'enable-v12-dynamic-floating-styles': enableV12DynamicFloatingStyles,
50
- 'enable-enhanced-file-uploader': enableEnhancedFileUploader,
51
- 'enable-presence': enablePresence,
52
- ...flags
53
- };
54
- const [scope, updateScope] = useState(() => {
39
+ const scope = useMemo(() => {
40
+ const combinedFlags = {
41
+ 'enable-v12-tile-default-icons': enableV12TileDefaultIcons,
42
+ 'enable-v12-tile-radio-icons': enableV12TileRadioIcons,
43
+ 'enable-v12-overflowmenu': enableV12Overflowmenu,
44
+ 'enable-treeview-controllable': enableTreeviewControllable,
45
+ 'enable-experimental-focus-wrap-without-sentinels': enableExperimentalFocusWrapWithoutSentinels,
46
+ 'enable-focus-wrap-without-sentinels': enableFocusWrapWithoutSentinels,
47
+ 'enable-dialog-element': enableDialogElement,
48
+ 'enable-v12-dynamic-floating-styles': enableV12DynamicFloatingStyles,
49
+ 'enable-enhanced-file-uploader': enableEnhancedFileUploader,
50
+ 'enable-presence': enablePresence,
51
+ ...flags
52
+ };
55
53
  const scope = createScope(combinedFlags);
56
54
  scope.mergeWithScope(parentScope);
57
55
  return scope;
58
- });
59
- if (parentScope !== prevParentScope) {
60
- const scope = createScope(combinedFlags);
61
- scope.mergeWithScope(parentScope);
62
- updateScope(scope);
63
- setPrevParentScope(parentScope);
64
- }
65
-
66
- // We use a custom hook to detect if any of the keys or their values change
67
- // for flags that are passed in. If they have changed, then we re-create the
68
- // FeatureFlagScope using the new flags
69
- useChangedValue(combinedFlags, isEqual, changedFlags => {
70
- const scope = createScope(changedFlags);
71
- scope.mergeWithScope(parentScope);
72
- updateScope(scope);
73
- });
56
+ }, [enableV12TileDefaultIcons, enableV12TileRadioIcons, enableV12Overflowmenu, enableTreeviewControllable, enableExperimentalFocusWrapWithoutSentinels, enableFocusWrapWithoutSentinels, enableDialogElement, enableV12DynamicFloatingStyles, enableEnhancedFileUploader, enablePresence, flags, parentScope]);
74
57
  return /*#__PURE__*/React.createElement(FeatureFlagContext.Provider, {
75
58
  value: scope
76
59
  }, children);
77
- }
60
+ };
78
61
  FeatureFlags.propTypes = {
79
62
  children: PropTypes.node,
80
63
  /**
@@ -93,81 +76,18 @@ FeatureFlags.propTypes = {
93
76
  enablePresence: PropTypes.bool
94
77
  };
95
78
 
96
- /**
97
- * This hook will store previous versions of the given `value` and compare the
98
- * current value to the previous one using the `compare` function. If the
99
- * compare function returns true, then the given `callback` is invoked in an
100
- * effect.
101
- *
102
- * @param {any} value
103
- * @param {Function} compare
104
- * @param {Function} callback
105
- */
106
- function useChangedValue(value, compare, callback) {
107
- const initialRender = useRef(false);
108
- const savedCallback = useRef(callback);
109
- const [prevValue, setPrevValue] = useState(value);
110
- if (!compare(prevValue, value)) {
111
- setPrevValue(value);
112
- }
113
- useEffect(() => {
114
- savedCallback.current = callback;
115
- });
116
- useEffect(() => {
117
- // We only want the callback triggered after the first render
118
- if (initialRender.current) {
119
- savedCallback.current(prevValue);
120
- }
121
- }, [prevValue]);
122
- useEffect(() => {
123
- initialRender.current = true;
124
- }, []);
125
- }
126
-
127
79
  /**
128
80
  * Access whether a given flag is enabled or disabled in a given
129
81
  * FeatureFlagContext
130
- *
131
- * @returns {boolean}
132
82
  */
133
- function useFeatureFlag(flag) {
83
+ const useFeatureFlag = flag => {
134
84
  const scope = useContext(FeatureFlagContext);
135
85
  return scope.enabled(flag);
136
- }
86
+ };
137
87
 
138
88
  /**
139
89
  * Access all feature flag information for the given FeatureFlagContext
140
- *
141
- * @returns {FeatureFlagScope}
142
- */
143
- function useFeatureFlags() {
144
- return useContext(FeatureFlagContext);
145
- }
146
-
147
- /**
148
- * Compare two objects and determine if they are equal. This is a shallow
149
- * comparison since the objects we are comparing are objects with boolean flags
150
- * from the flags prop in the `FeatureFlags` component
151
- *
152
- * @param {object} a
153
- * @param {object} b
154
- * @returns {boolean}
155
90
  */
156
- function isEqual(a, b) {
157
- if (a === b) {
158
- return true;
159
- }
160
- for (const key of Object.keys(a)) {
161
- if (a[key] !== b[key]) {
162
- return false;
163
- }
164
- }
165
- for (const key of Object.keys(b)) {
166
- if (b[key] !== a[key]) {
167
- return false;
168
- }
169
- }
170
- return true;
171
- }
91
+ const useFeatureFlags = () => useContext(FeatureFlagContext);
172
92
 
173
- export { FeatureFlagContext, FeatureFlags, useFeatureFlag, useFeatureFlags };
93
+ export { FeatureFlags, useFeatureFlag, useFeatureFlags };
@@ -10,7 +10,7 @@ import PropTypes from 'prop-types';
10
10
  import React from 'react';
11
11
  import cx from 'classnames';
12
12
  import SkeletonText from '../SkeletonText/SkeletonText.js';
13
- import ButtonSkeleton from '../Button/Button.Skeleton.js';
13
+ import { ButtonSkeleton } from '../Button/Button.Skeleton.js';
14
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
15
 
16
16
  var _SkeletonText, _ButtonSkeleton;
@@ -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.
@@ -8,7 +8,7 @@
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import cx from 'classnames';
10
10
  import PropTypes from 'prop-types';
11
- import React, { useState, useRef } from 'react';
11
+ import React, { useState, useRef, useEffect } from 'react';
12
12
  import { Enter, Space } from '../../internal/keyboard/keys.js';
13
13
  import { matches } from '../../internal/keyboard/match.js';
14
14
  import { useId } from '../../internal/useId.js';
@@ -35,7 +35,6 @@ function FileUploaderButton({
35
35
  }) {
36
36
  const prefix = usePrefix();
37
37
  const [labelText, setLabelText] = useState(ownerLabelText);
38
- const [prevOwnerLabelText, setPrevOwnerLabelText] = useState(ownerLabelText);
39
38
  const generatedId = useId();
40
39
  const {
41
40
  current: inputId
@@ -49,12 +48,9 @@ function FileUploaderButton({
49
48
  [`${prefix}--btn--sm`]: size === 'small' || size === 'sm',
50
49
  [`${prefix}--layout--size-${size}`]: size
51
50
  });
52
-
53
- // Adjust label text state based on changes to the labelText prop
54
- if (ownerLabelText !== prevOwnerLabelText) {
51
+ useEffect(() => {
55
52
  setLabelText(ownerLabelText);
56
- setPrevOwnerLabelText(ownerLabelText);
57
- }
53
+ }, [ownerLabelText]);
58
54
  function onClick(event) {
59
55
  event.target.value = null;
60
56
  if (inputNode.current) {
@@ -27,4 +27,4 @@ IconSkeleton.propTypes = {
27
27
  className: PropTypes.string
28
28
  };
29
29
 
30
- export { IconSkeleton, IconSkeleton as default };
30
+ export { IconSkeleton };
@@ -70,4 +70,4 @@ IconIndicator.propTypes = {
70
70
  size: PropTypes.oneOf([16, 20])
71
71
  };
72
72
 
73
- export { IconIndicator, IconIndicatorKinds, IconIndicator as default };
73
+ export { IconIndicator, IconIndicatorKinds };
@@ -9,7 +9,7 @@ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js
9
9
  import cx from 'classnames';
10
10
  import PropTypes from 'prop-types';
11
11
  import React, { forwardRef, useState, useContext, useRef, useEffect } from 'react';
12
- import { useFloating, offset, autoUpdate, useInteractions, useHover, safePolygon, FloatingFocusManager } from '@floating-ui/react';
12
+ import { useFloating, autoUpdate, offset, useInteractions, useHover, safePolygon, FloatingFocusManager } from '@floating-ui/react';
13
13
  import { Checkmark, CaretLeft, CaretRight } from '@carbon/icons-react';
14
14
  import { ArrowRight, Enter, Space } from '../../internal/keyboard/keys.js';
15
15
  import { match } from '../../internal/keyboard/match.js';
@@ -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 PropsWithChildren } from 'react';
7
+ import React, { type ComponentType, type PropsWithChildren } from 'react';
8
8
  import { type PresenceContext } from '../../internal/usePresenceContext';
9
9
  export interface ModalPresenceProps {
10
10
  /**
@@ -29,4 +29,12 @@ export declare const ModalPresenceContext: React.Context<ModalPresenceContextPro
29
29
  * Handles occurrences where only a single modal must consume a context.
30
30
  */
31
31
  export declare const useExclusiveModalPresenceContext: (id: string) => ModalPresenceContextProps | undefined;
32
+ type WithModalPresenceProps = Pick<ModalPresenceProps, 'open'>;
33
+ /**
34
+ * Higher-order function that wraps a component with ModalPresence
35
+ */
36
+ export declare const withModalPresence: <TProps extends object>(Component: ComponentType<TProps>) => {
37
+ ({ open, ...componentProps }: TProps & WithModalPresenceProps): import("react/jsx-runtime").JSX.Element;
38
+ displayName: string;
39
+ };
32
40
  export {};
@@ -33,5 +33,18 @@ const useExclusiveModalPresenceContext = id => {
33
33
  const ctx = useContext(ModalPresenceContext);
34
34
  return ctx?.isPresenceExclusive(id) ? ctx : undefined;
35
35
  };
36
+ /**
37
+ * Higher-order function that wraps a component with ModalPresence
38
+ */
39
+ const withModalPresence = Component => {
40
+ const WithModalPresence = ({
41
+ open,
42
+ ...componentProps
43
+ }) => /*#__PURE__*/React.createElement(ModalPresence, {
44
+ open: open
45
+ }, /*#__PURE__*/React.createElement(Component, componentProps));
46
+ WithModalPresence.displayName = `withModalPresence(${Component.displayName || Component.name || 'Component'})`;
47
+ return WithModalPresence;
48
+ };
36
49
 
37
- export { ModalPresence, ModalPresenceContext, useExclusiveModalPresenceContext };
50
+ export { ModalPresence, ModalPresenceContext, useExclusiveModalPresenceContext, withModalPresence };
@@ -5,6 +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
+ import { ModalPresence, withModalPresence, type ModalPresenceProps } from './ModalPresence';
9
9
  export default Modal;
10
- export { Modal, ModalPresence, type ModalProps, type ModalPresenceProps };
10
+ export { Modal, ModalPresence, withModalPresence, type ModalProps, type ModalPresenceProps, };
@@ -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, useRef, isValidElement, useCallback, cloneElement } from 'react';
14
+ import React, { useMemo, useContext, useRef, useState, useEffect, 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';
@@ -110,11 +110,11 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
110
110
  isFluid
111
111
  } = useContext(FormContext);
112
112
  const multiSelectInstanceId = useId();
113
+ const prevOpenPropRef = useRef(open);
113
114
  // eslint-disable-next-line @typescript-eslint/no-unused-vars -- https://github.com/carbon-design-system/carbon/issues/20452
114
115
  const [isFocused, setIsFocused] = useState(false);
115
116
  const [inputFocused, setInputFocused] = useState(false);
116
117
  const [isOpen, setIsOpen] = useState(open || false);
117
- const [prevOpenProp, setPrevOpenProp] = useState(open);
118
118
  const [topItems, setTopItems] = useState([]);
119
119
  const [itemsCleared, setItemsCleared] = useState(false);
120
120
  const enableFloatingStyles = useFeatureFlag('enable-v12-dynamic-floating-styles') || autoAlign;
@@ -248,14 +248,13 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
248
248
  onMenuChange(open);
249
249
  }
250
250
  };
251
-
252
- /**
253
- * programmatically control this `open` prop
254
- */
255
- if (prevOpenProp !== open) {
256
- setIsOpenWrapper(open);
257
- setPrevOpenProp(open);
258
- }
251
+ useEffect(() => {
252
+ if (prevOpenPropRef.current !== open) {
253
+ setIsOpen(open);
254
+ onMenuChange?.(open);
255
+ prevOpenPropRef.current = open;
256
+ }
257
+ }, [open, onMenuChange]);
259
258
  const normalizedProps = useNormalizedInputProps({
260
259
  id,
261
260
  disabled,
@@ -16,7 +16,7 @@ import '../Text/TextDirection.js';
16
16
  import Button from '../Button/Button.js';
17
17
  import '../Button/Button.Skeleton.js';
18
18
  import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
19
- import { useNoInteractiveChildren, useInteractiveChildrenNeedDescription } from '../../internal/useNoInteractiveChildren.js';
19
+ import { useInteractiveChildrenNeedDescription, useNoInteractiveChildren } from '../../internal/useNoInteractiveChildren.js';
20
20
  import { Tab, Escape } from '../../internal/keyboard/keys.js';
21
21
  import { match, matches } from '../../internal/keyboard/match.js';
22
22
  import { usePrefix } from '../../internal/usePrefix.js';
@@ -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, cloneElement } from 'react';
12
+ import React, { useContext, useState, useMemo, useRef, useCallback, 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';
@@ -341,7 +341,7 @@ const NumberInput = /*#__PURE__*/React.forwardRef((props, forwardRef) => {
341
341
  * The number value that was previously "committed" to the input on blur
342
342
  * Only used when type="text"
343
343
  */
344
- const [previousNumberValue, setPreviousNumberValue] = useState(numberValue);
344
+ const previousNumberValue = useRef(numberValue);
345
345
  /**
346
346
  * The current text value of the input.
347
347
  * Only used when type=text
@@ -354,10 +354,12 @@ const NumberInput = /*#__PURE__*/React.forwardRef((props, forwardRef) => {
354
354
  numberingSystem
355
355
  }), [locale, formatOptions, numberingSystem]);
356
356
  const format = useCallback(value => isNaN(value) || value === null ? '' : numberFormatter.format(value), [numberFormatter]);
357
- if (isControlled && !(isNaN(previousNumberValue) && isNaN(numberValue)) && previousNumberValue !== numberValue) {
358
- setInputValue(format(numberValue));
359
- setPreviousNumberValue(numberValue);
360
- }
357
+ useEffect(() => {
358
+ if (isControlled && !(isNaN(previousNumberValue.current) && isNaN(numberValue)) && previousNumberValue.current !== numberValue) {
359
+ setInputValue(format(numberValue));
360
+ previousNumberValue.current = numberValue;
361
+ }
362
+ }, [isControlled, numberValue, format]);
361
363
  const inputRef = useRef(null);
362
364
  const ref = useMergedRefs([forwardRef, inputRef]);
363
365
  const numberInputClasses = cx({
@@ -504,7 +506,7 @@ const NumberInput = /*#__PURE__*/React.forwardRef((props, forwardRef) => {
504
506
  // numberValue in useControllableState.
505
507
  setNumberValue(parsedFormattedNewValue);
506
508
  setInputValue(formattedNewValue);
507
- setPreviousNumberValue(parsedFormattedNewValue);
509
+ previousNumberValue.current = parsedFormattedNewValue;
508
510
  }
509
511
  if (onChange) {
510
512
  onChange(event, state);
@@ -606,22 +608,22 @@ const NumberInput = /*#__PURE__*/React.forwardRef((props, forwardRef) => {
606
608
  if (onChange && isValid) {
607
609
  const state = {
608
610
  value: parsedFormattedNewValue,
609
- direction: previousNumberValue < parsedFormattedNewValue ? 'up' : 'down'
611
+ direction: previousNumberValue.current < parsedFormattedNewValue ? 'up' : 'down'
610
612
  };
611
613
 
612
614
  // If the old and new values are NaN, don't call onChange
613
- // to avoid an unecessary re-render and potential infinite
615
+ // to avoid an unnecessary re-render and potential infinite
614
616
  // loop when isControlled.
615
- if (!(isNaN(previousNumberValue) && isNaN(parsedFormattedNewValue))) {
617
+ if (!(isNaN(previousNumberValue.current) && isNaN(parsedFormattedNewValue))) {
616
618
  onChange(e, state);
617
619
  }
618
620
  }
619
621
 
620
622
  // If the old and new values are NaN, don't set state to avoid
621
- // an unecessary re-render and potential infinite loop when
623
+ // an unnecessary re-render and potential infinite loop when
622
624
  // isControlled.
623
- if (!(isNaN(previousNumberValue) && isNaN(numberValue))) {
624
- setPreviousNumberValue(numberValue);
625
+ if (!(isNaN(previousNumberValue.current) && isNaN(numberValue))) {
626
+ previousNumberValue.current = numberValue;
625
627
  }
626
628
  if (!(isNaN(numberValue) && isNaN(parsedFormattedNewValue))) {
627
629
  setNumberValue(parsedFormattedNewValue);
@@ -70,7 +70,7 @@ export interface OverflowMenuProps extends Omit<IconButtonProps, 'type' | 'aria-
70
70
  */
71
71
  menuOffset?: MenuOffset;
72
72
  /**
73
- * The adjustment in position applied to the floating menu.
73
+ * The adjustment in position applied to the floating menu when flipped.
74
74
  */
75
75
  menuOffsetFlip?: MenuOffset;
76
76
  /**
@@ -66,10 +66,8 @@ const getMenuOffset = (menuBody, direction, trigger, flip) => {
66
66
  if (process.env.NODE_ENV !== 'production') {
67
67
  !(triggerButtonPositionProp && triggerButtonPositionFactor) ? process.env.NODE_ENV !== "production" ? invariant(false, '[OverflowMenu] wrong floating menu direction: `%s`', direction) : invariant(false) : void 0;
68
68
  }
69
- // eslint-disable-next-line @typescript-eslint/no-unused-vars -- https://github.com/carbon-design-system/carbon/issues/20452
70
69
  const {
71
- offsetWidth: menuWidth,
72
- offsetHeight: menuHeight
70
+ offsetWidth: menuWidth
73
71
  } = menuBody;
74
72
  switch (triggerButtonPositionProp) {
75
73
  case 'top':
@@ -423,7 +421,7 @@ OverflowMenu.propTypes = {
423
421
  left: PropTypes.number.isRequired
424
422
  }), PropTypes.func]),
425
423
  /**
426
- * The adjustment in position applied to the floating menu.
424
+ * The adjustment in position applied to the floating menu when flipped.
427
425
  */
428
426
  menuOffsetFlip: PropTypes.oneOfType([PropTypes.shape({
429
427
  top: PropTypes.number.isRequired,
@@ -472,4 +470,4 @@ OverflowMenu.propTypes = {
472
470
  size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg'])
473
471
  };
474
472
 
475
- export { OverflowMenu, OverflowMenu as default, getMenuOffset };
473
+ export { OverflowMenu, getMenuOffset };
@@ -8,7 +8,7 @@
8
8
  import React from 'react';
9
9
  import { warning } from '../../internal/warning.js';
10
10
  import { FeatureFlags } from '../FeatureFlags/index.js';
11
- import OverflowMenu from '../OverflowMenu/index.js';
11
+ import { OverflowMenu } from '../OverflowMenu/index.js';
12
12
 
13
13
  let didWarnAboutDeprecation = false;
14
14
  function OverflowMenuV2(props) {
@@ -372,37 +372,19 @@ const PageHeaderTabBar = /*#__PURE__*/React.forwardRef(({
372
372
  const classNames = cx({
373
373
  [`${prefix}--page-header__tab-bar`]: true
374
374
  }, className);
375
- // Early return if no tags are provided
376
- if (!tags.length) {
377
- return /*#__PURE__*/React.createElement("div", _extends({
378
- className: classNames,
379
- ref: ref
380
- }, other), /*#__PURE__*/React.createElement(GridAsGridComponent, null, /*#__PURE__*/React.createElement(Column, {
381
- lg: 16,
382
- md: 8,
383
- sm: 4
384
- }, children)));
385
- }
386
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
387
375
  const [openPopover, setOpenPopover] = useState(false);
388
376
  const tagSize = tags[0]?.size || 'md';
389
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
390
377
  const instanceId = useId('PageHeaderTabBar');
391
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
392
378
  const tagsWithIds = useMemo(() => {
393
379
  return tags.map((tag, index) => ({
394
380
  ...tag,
395
381
  id: tag.id || `tag-${index}-${instanceId}`
396
382
  }));
397
- // eslint-disable-next-line react-hooks/exhaustive-deps -- https://github.com/carbon-design-system/carbon/issues/20452
398
- }, [tags]);
399
-
400
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
383
+ }, [instanceId, tags]);
401
384
  const tagsContainerRef = useRef(null);
402
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
403
385
  const offsetRef = useRef(null);
386
+
404
387
  // To close popover when window resizes
405
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
406
388
  useEffect(() => {
407
389
  const handleResize = () => {
408
390
  // Close the popover when window resizes to prevent unwanted opens
@@ -419,14 +401,11 @@ const PageHeaderTabBar = /*#__PURE__*/React.forwardRef(({
419
401
  visibleItems = [],
420
402
  hiddenItems = [],
421
403
  itemRefHandler = () => {}
422
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
423
404
  } = useOverflowItems(tagsWithIds, tagsContainerRef, offsetRef) || {
424
405
  visibleItems: [],
425
406
  hiddenItems: [],
426
407
  itemRefHandler: () => {}
427
408
  };
428
-
429
- // eslint-disable-next-line react-hooks/rules-of-hooks -- https://github.com/carbon-design-system/carbon/issues/20452
430
409
  const handleOverflowClick = useCallback(event => {
431
410
  event.stopPropagation();
432
411
  setOpenPopover(prev => !prev);
@@ -41,4 +41,4 @@ PaginationSkeleton.propTypes = {
41
41
  className: PropTypes.string
42
42
  };
43
43
 
44
- export { PaginationSkeleton, PaginationSkeleton as default };
44
+ export { PaginationSkeleton };
@@ -69,6 +69,10 @@ export interface PaginationProps extends Omit<React.HTMLAttributes<HTMLDivElemen
69
69
  * A function returning PII showing where the current page is.
70
70
  */
71
71
  pageRangeText?: (current: number, total: number) => string;
72
+ /**
73
+ * A function returning the label for the page select.
74
+ */
75
+ pageSelectLabelText?: (total: number) => string;
72
76
  /**
73
77
  * The number dictating how many items a page contains.
74
78
  */
@@ -65,6 +65,7 @@ const Pagination = /*#__PURE__*/React.forwardRef(({
65
65
  // eslint-disable-next-line @typescript-eslint/no-unused-vars -- https://github.com/carbon-design-system/carbon/issues/20452
66
66
  pageNumberText: _pageNumberText = 'Page Number',
67
67
  pageRangeText = (_current, total) => `of ${total} ${total === 1 ? 'page' : 'pages'}`,
68
+ pageSelectLabelText = total => `Page of ${total} ${total === 1 ? 'page' : 'pages'}`,
68
69
  page: controlledPage = 1,
69
70
  pageInputDisabled,
70
71
  pageSize: controlledPageSize,
@@ -245,7 +246,7 @@ const Pagination = /*#__PURE__*/React.forwardRef(({
245
246
  }, pageText(page)) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Select, {
246
247
  id: `${prefix}-pagination-select-${inputId}-right`,
247
248
  className: `${prefix}--select__page-number`,
248
- labelText: `Page of ${totalPages} pages`,
249
+ labelText: pageSelectLabelText(totalPages),
249
250
  inline: true,
250
251
  hideLabel: true,
251
252
  onChange: handlePageInputChange,
@@ -332,6 +333,10 @@ Pagination.propTypes = {
332
333
  * A function returning PII showing where the current page is.
333
334
  */
334
335
  pageRangeText: PropTypes.func,
336
+ /**
337
+ * A function returning the label for the page select.
338
+ */
339
+ pageSelectLabelText: PropTypes.func,
335
340
  /**
336
341
  * The number dictating how many items a page contains.
337
342
  */
@@ -78,7 +78,18 @@ function Pagination({
78
78
  hideLabel: true,
79
79
  noLabel: true,
80
80
  inline: true,
81
- onChange: event => setCurrentPageSize(Number(event.target.value)),
81
+ onChange: event => {
82
+ const pageSize = Number(event.target.value);
83
+ const page = 1;
84
+ setCurrentPage(page);
85
+ setCurrentPageSize(pageSize);
86
+ if (onChange) {
87
+ onChange({
88
+ page,
89
+ pageSize
90
+ });
91
+ }
92
+ },
82
93
  value: currentPageSize
83
94
  }, pageSizes.map(size => /*#__PURE__*/React.createElement(SelectItem, {
84
95
  key: size,
@@ -9,7 +9,7 @@ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js
9
9
  import cx from 'classnames';
10
10
  import PropTypes from 'prop-types';
11
11
  import { deprecateValuesWithin } from '../../prop-types/deprecateValuesWithin.js';
12
- import React, { forwardRef, useRef, useEffect, useMemo } from 'react';
12
+ import React, { useRef, useEffect, useMemo, forwardRef } from 'react';
13
13
  import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
14
14
  import { useMergedRefs } from '../../internal/useMergedRefs.js';
15
15
  import { usePrefix } from '../../internal/usePrefix.js';
@@ -32,4 +32,4 @@ RadioButtonSkeleton.propTypes = {
32
32
  className: PropTypes.string
33
33
  };
34
34
 
35
- export { RadioButtonSkeleton, RadioButtonSkeleton as default };
35
+ export { RadioButtonSkeleton };
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import Search from './Search.js';
9
- export { default as SearchSkeleton } from './Search.Skeleton.js';
9
+ export { SearchSkeleton } from './Search.Skeleton.js';
10
10
 
11
11
 
12
12
 
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import Select from './Select.js';
9
- export { default as SelectSkeleton } from './Select.Skeleton.js';
9
+ export { SelectSkeleton } from './Select.Skeleton.js';
10
10
 
11
11
 
12
12
 
@@ -90,4 +90,4 @@ ShapeIndicator.propTypes = {
90
90
  textSize: PropTypes.oneOf([12, 14])
91
91
  };
92
92
 
93
- export { ShapeIndicator, ShapeIndicatorKinds, ShapeIndicator as default };
93
+ export { ShapeIndicator, ShapeIndicatorKinds };