@carbon/react 1.84.0-rc.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 (177) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +943 -943
  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 +34 -12
  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 +39 -11
  36. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  37. package/es/components/MultiSelect/FilterableMultiSelect.js +29 -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/OverflowMenu/OverflowMenu.js +4 -5
  43. package/es/components/PageHeader/PageHeader.d.ts +10 -9
  44. package/es/components/PageHeader/PageHeader.js +94 -34
  45. package/es/components/PageHeader/index.d.ts +2 -2
  46. package/es/components/PageHeader/index.js +1 -1
  47. package/es/components/Popover/index.js +2 -1
  48. package/es/components/RadioButton/RadioButton.d.ts +2 -2
  49. package/es/components/RadioButton/RadioButton.js +8 -8
  50. package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +2 -2
  51. package/es/components/RadioButtonGroup/RadioButtonGroup.js +9 -8
  52. package/es/components/RadioTile/RadioTile.d.ts +1 -1
  53. package/es/components/RadioTile/RadioTile.js +8 -7
  54. package/es/components/Search/Search.js +0 -1
  55. package/es/components/Select/Select.d.ts +2 -2
  56. package/es/components/Select/Select.js +8 -7
  57. package/es/components/Slider/Slider.js +6 -0
  58. package/es/components/Tag/DismissibleTag.d.ts +1 -1
  59. package/es/components/Tag/DismissibleTag.js +9 -8
  60. package/es/components/Tag/Tag.d.ts +1 -1
  61. package/es/components/Tag/Tag.js +9 -8
  62. package/es/components/TextArea/TextArea.js +12 -11
  63. package/es/components/TextInput/TextInput.d.ts +1 -1
  64. package/es/components/TextInput/TextInput.js +20 -9
  65. package/es/components/Tile/Tile.d.ts +2 -2
  66. package/es/components/Tile/Tile.js +30 -36
  67. package/es/components/TileGroup/TileGroup.d.ts +4 -4
  68. package/es/components/TileGroup/TileGroup.js +45 -53
  69. package/es/components/TileGroup/index.d.ts +3 -3
  70. package/es/components/Toggletip/index.js +2 -2
  71. package/es/components/Tooltip/DefinitionTooltip.js +1 -0
  72. package/es/components/TreeView/TreeNode.js +3 -3
  73. package/es/components/TreeView/TreeView.js +3 -3
  74. package/es/components/UIShell/Content.d.ts +5 -3
  75. package/es/components/UIShell/HeaderMenuItem.js +2 -1
  76. package/es/components/UIShell/HeaderPanel.d.ts +2 -2
  77. package/es/components/UIShell/HeaderPanel.js +9 -5
  78. package/es/index.js +1 -1
  79. package/es/internal/Selection.js +8 -3
  80. package/es/internal/environment.js +1 -12
  81. package/es/internal/{__mocks__/mockHTMLElement.d.ts → index.d.ts} +2 -4
  82. package/es/internal/useOverflowItems.d.ts +29 -0
  83. package/es/internal/useOverflowItems.js +122 -0
  84. package/es/internal/useResizeObserver.d.ts +1 -1
  85. package/es/internal/utils.d.ts +14 -0
  86. package/es/internal/utils.js +18 -0
  87. package/es/tools/uniqueId.d.ts +1 -6
  88. package/lib/components/AILabel/index.js +6 -1
  89. package/lib/components/Checkbox/Checkbox.d.ts +2 -2
  90. package/lib/components/Checkbox/Checkbox.js +7 -7
  91. package/lib/components/CheckboxGroup/CheckboxGroup.d.ts +2 -2
  92. package/lib/components/CheckboxGroup/CheckboxGroup.js +8 -7
  93. package/lib/components/CodeSnippet/CodeSnippet.js +2 -4
  94. package/lib/components/ComboBox/ComboBox.d.ts +1 -1
  95. package/lib/components/ComboBox/ComboBox.js +11 -10
  96. package/lib/components/ComposedModal/ComposedModal.d.ts +1 -1
  97. package/lib/components/ComposedModal/ComposedModal.js +35 -13
  98. package/lib/components/ContainedList/ContainedList.d.ts +1 -1
  99. package/lib/components/ContainedList/ContainedList.js +4 -2
  100. package/lib/components/ContentSwitcher/ContentSwitcher.js +5 -4
  101. package/lib/components/DataTable/DataTable.js +3 -0
  102. package/lib/components/DataTable/TableDecoratorRow.d.ts +2 -2
  103. package/lib/components/DataTable/TableDecoratorRow.js +8 -8
  104. package/lib/components/DataTable/TableExpandRow.d.ts +1 -1
  105. package/lib/components/DataTable/TableExpandRow.js +14 -5
  106. package/lib/components/DataTable/TableHeader.js +9 -9
  107. package/lib/components/DataTable/TableRow.js +11 -3
  108. package/lib/components/DataTable/tools/normalize.js +2 -1
  109. package/lib/components/DatePickerInput/DatePickerInput.js +7 -6
  110. package/lib/components/Dialog/index.d.ts +5 -1
  111. package/lib/components/Dialog/index.js +20 -0
  112. package/lib/components/Dropdown/Dropdown.d.ts +1 -1
  113. package/lib/components/Dropdown/Dropdown.js +12 -14
  114. package/lib/components/FileUploader/FileUploaderButton.js +2 -2
  115. package/lib/components/FileUploader/FileUploaderDropContainer.js +2 -2
  116. package/lib/components/FileUploader/FileUploaderItem.js +2 -2
  117. package/lib/components/Layer/index.d.ts +1 -3
  118. package/lib/components/Layer/index.js +9 -8
  119. package/lib/components/Menu/Menu.js +0 -6
  120. package/lib/components/Modal/Modal.d.ts +2 -2
  121. package/lib/components/Modal/Modal.js +47 -19
  122. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  123. package/lib/components/MultiSelect/FilterableMultiSelect.js +33 -11
  124. package/lib/components/MultiSelect/MultiSelect.d.ts +1 -1
  125. package/lib/components/MultiSelect/MultiSelect.js +13 -12
  126. package/lib/components/NumberInput/NumberInput.d.ts +1 -1
  127. package/lib/components/NumberInput/NumberInput.js +8 -7
  128. package/lib/components/OverflowMenu/OverflowMenu.js +4 -5
  129. package/lib/components/PageHeader/PageHeader.d.ts +10 -9
  130. package/lib/components/PageHeader/PageHeader.js +92 -34
  131. package/lib/components/PageHeader/index.d.ts +2 -2
  132. package/lib/components/PageHeader/index.js +0 -2
  133. package/lib/components/Popover/index.js +2 -1
  134. package/lib/components/RadioButton/RadioButton.d.ts +2 -2
  135. package/lib/components/RadioButton/RadioButton.js +7 -7
  136. package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +2 -2
  137. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +10 -9
  138. package/lib/components/RadioTile/RadioTile.d.ts +1 -1
  139. package/lib/components/RadioTile/RadioTile.js +7 -6
  140. package/lib/components/Search/Search.js +0 -1
  141. package/lib/components/Select/Select.d.ts +2 -2
  142. package/lib/components/Select/Select.js +7 -6
  143. package/lib/components/Slider/Slider.js +6 -0
  144. package/lib/components/Tag/DismissibleTag.d.ts +1 -1
  145. package/lib/components/Tag/DismissibleTag.js +8 -7
  146. package/lib/components/Tag/Tag.d.ts +1 -1
  147. package/lib/components/Tag/Tag.js +8 -7
  148. package/lib/components/TextArea/TextArea.js +11 -10
  149. package/lib/components/TextInput/TextInput.d.ts +1 -1
  150. package/lib/components/TextInput/TextInput.js +19 -8
  151. package/lib/components/Tile/Tile.d.ts +2 -2
  152. package/lib/components/Tile/Tile.js +29 -35
  153. package/lib/components/TileGroup/TileGroup.d.ts +4 -4
  154. package/lib/components/TileGroup/TileGroup.js +44 -52
  155. package/lib/components/TileGroup/index.d.ts +3 -3
  156. package/lib/components/Toggletip/index.js +2 -2
  157. package/lib/components/Tooltip/DefinitionTooltip.js +1 -0
  158. package/lib/components/TreeView/TreeNode.js +3 -3
  159. package/lib/components/TreeView/TreeView.js +3 -3
  160. package/lib/components/UIShell/Content.d.ts +5 -3
  161. package/lib/components/UIShell/HeaderMenuItem.js +2 -1
  162. package/lib/components/UIShell/HeaderPanel.d.ts +2 -2
  163. package/lib/components/UIShell/HeaderPanel.js +8 -4
  164. package/lib/index.js +1 -1
  165. package/lib/internal/Selection.js +8 -3
  166. package/lib/internal/environment.js +1 -12
  167. package/lib/internal/{__mocks__/mockHTMLElement.d.ts → index.d.ts} +2 -4
  168. package/lib/internal/useOverflowItems.d.ts +29 -0
  169. package/lib/internal/useOverflowItems.js +126 -0
  170. package/lib/internal/useResizeObserver.d.ts +1 -1
  171. package/lib/internal/utils.d.ts +14 -0
  172. package/lib/internal/utils.js +22 -0
  173. package/lib/tools/uniqueId.d.ts +1 -6
  174. package/package.json +14 -23
  175. package/telemetry.yml +3 -0
  176. package/es/tools/uniqueId.js +0 -14
  177. package/lib/tools/uniqueId.js +0 -18
@@ -17,7 +17,7 @@ var keys = require('../../internal/keyboard/keys.js');
17
17
  var match = require('../../internal/keyboard/match.js');
18
18
  var useControllableState = require('../../internal/useControllableState.js');
19
19
  var usePrefix = require('../../internal/usePrefix.js');
20
- var uniqueId = require('../../tools/uniqueId.js');
20
+ var useId = require('../../internal/useId.js');
21
21
  var index = require('../FeatureFlags/index.js');
22
22
  var TreeNode = require('./TreeNode.js');
23
23
 
@@ -43,7 +43,7 @@ const TreeView = ({
43
43
  const enableTreeviewControllable = index.useFeatureFlag('enable-treeview-controllable');
44
44
  const {
45
45
  current: treeId
46
- } = React.useRef(rest.id || uniqueId.uniqueId());
46
+ } = React.useRef(rest.id || useId.useId());
47
47
  const prefix = usePrefix.usePrefix();
48
48
  const treeClasses = cx__default["default"](className, `${prefix}--tree`, {
49
49
  // @ts-ignore - will always be false according to prop types
@@ -122,7 +122,7 @@ const TreeView = ({
122
122
  function enhanceTreeNodes(children) {
123
123
  return React__default["default"].Children.map(children, child => {
124
124
  if (! /*#__PURE__*/React__default["default"].isValidElement(child)) return child;
125
- const isTreeNode = child.type.displayName === 'TreeNode';
125
+ const isTreeNode = child.type === TreeNode["default"];
126
126
  if (isTreeNode) {
127
127
  const node = child;
128
128
  const sharedNodeProps = {
@@ -75,6 +75,8 @@ declare const Content: {
75
75
  inert?: boolean | undefined;
76
76
  inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined;
77
77
  is?: string | undefined;
78
+ exportparts?: string | undefined;
79
+ part?: string | undefined;
78
80
  "aria-activedescendant"?: string | undefined;
79
81
  "aria-atomic"?: (boolean | "true" | "false") | undefined;
80
82
  "aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined;
@@ -149,7 +151,7 @@ declare const Content: {
149
151
  onBlurCapture?: React.FocusEventHandler<HTMLElement> | undefined;
150
152
  onChange?: React.FormEventHandler<HTMLElement> | undefined;
151
153
  onChangeCapture?: React.FormEventHandler<HTMLElement> | undefined;
152
- onBeforeInput?: React.FormEventHandler<HTMLElement> | undefined;
154
+ onBeforeInput?: React.InputEventHandler<HTMLElement> | undefined;
153
155
  onBeforeInputCapture?: React.FormEventHandler<HTMLElement> | undefined;
154
156
  onInput?: React.FormEventHandler<HTMLElement> | undefined;
155
157
  onInputCapture?: React.FormEventHandler<HTMLElement> | undefined;
@@ -199,8 +201,6 @@ declare const Content: {
199
201
  onProgressCapture?: React.ReactEventHandler<HTMLElement> | undefined;
200
202
  onRateChange?: React.ReactEventHandler<HTMLElement> | undefined;
201
203
  onRateChangeCapture?: React.ReactEventHandler<HTMLElement> | undefined;
202
- onResize?: React.ReactEventHandler<HTMLElement> | undefined;
203
- onResizeCapture?: React.ReactEventHandler<HTMLElement> | undefined;
204
204
  onSeeked?: React.ReactEventHandler<HTMLElement> | undefined;
205
205
  onSeekedCapture?: React.ReactEventHandler<HTMLElement> | undefined;
206
206
  onSeeking?: React.ReactEventHandler<HTMLElement> | undefined;
@@ -281,6 +281,8 @@ declare const Content: {
281
281
  onLostPointerCaptureCapture?: React.PointerEventHandler<HTMLElement> | undefined;
282
282
  onScroll?: React.UIEventHandler<HTMLElement> | undefined;
283
283
  onScrollCapture?: React.UIEventHandler<HTMLElement> | undefined;
284
+ onScrollEnd?: React.UIEventHandler<HTMLElement> | undefined;
285
+ onScrollEndCapture?: React.UIEventHandler<HTMLElement> | undefined;
284
286
  onWheel?: React.WheelEventHandler<HTMLElement> | undefined;
285
287
  onWheelCapture?: React.WheelEventHandler<HTMLElement> | undefined;
286
288
  onAnimationStart?: React.AnimationEventHandler<HTMLElement> | undefined;
@@ -34,6 +34,7 @@ const HeaderMenuItem = /*#__PURE__*/React.forwardRef(function HeaderMenuItem({
34
34
  ...rest
35
35
  }, ref) {
36
36
  const prefix = usePrefix.usePrefix();
37
+ const resolvedTabIndex = tabIndex ?? 0;
37
38
  if (isCurrentPage) {
38
39
  isActive = isCurrentPage;
39
40
  }
@@ -52,7 +53,7 @@ const HeaderMenuItem = /*#__PURE__*/React.forwardRef(function HeaderMenuItem({
52
53
  "aria-current": hasCurrentClass ? true : ariaCurrent,
53
54
  className: linkClassName,
54
55
  ref: ref,
55
- tabIndex: tabIndex
56
+ tabIndex: resolvedTabIndex
56
57
  }), /*#__PURE__*/React__default["default"].createElement("span", {
57
58
  className: `${prefix}--text-truncate--end`
58
59
  }, children)));
@@ -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
  export interface HeaderPanelProps {
9
9
  /**
10
10
  * Specify whether focus and blur listeners are added. They are by default.
@@ -18,6 +18,7 @@ var keys = require('../../internal/keyboard/keys.js');
18
18
  var match = require('../../internal/keyboard/match.js');
19
19
  var useEvent = require('../../internal/useEvent.js');
20
20
  var useMergedRefs = require('../../internal/useMergedRefs.js');
21
+ var Switcher = require('./Switcher.js');
21
22
 
22
23
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
23
24
 
@@ -68,10 +69,13 @@ const HeaderPanel = /*#__PURE__*/React__default["default"].forwardRef(function H
68
69
  };
69
70
  }
70
71
  useEvent.useWindowEvent('click', () => {
71
- const focusedElement = document.activeElement;
72
- setLastClickedElement(focusedElement);
73
- const childJsxElement = children;
74
- if (childJsxElement?.type?.displayName === 'Switcher' && !focusedElement?.closest(`.${prefix}--header-panel--expanded`) && !focusedElement?.closest(`.${prefix}--header__action`) && !headerPanelReference?.current?.classList.contains(`${prefix}--switcher`) && expanded) {
72
+ const {
73
+ activeElement
74
+ } = document;
75
+ if (!(activeElement instanceof HTMLElement)) return;
76
+ setLastClickedElement(activeElement);
77
+ const isChildASwitcher = /*#__PURE__*/React.isValidElement(children) && typeof children.type !== 'string' && children.type === Switcher["default"];
78
+ if (isChildASwitcher && !activeElement.closest(`.${prefix}--header-panel--expanded`) && !activeElement.closest(`.${prefix}--header__action`) && !headerPanelReference?.current?.classList.contains(`${prefix}--switcher`) && expanded) {
75
79
  setExpandedState(false);
76
80
  onHeaderPanelFocus();
77
81
  }
package/lib/index.js CHANGED
@@ -424,7 +424,7 @@ exports.SelectableTile = Tile.SelectableTile;
424
424
  exports.Tile = Tile.Tile;
425
425
  exports.TileAboveTheFoldContent = Tile.TileAboveTheFoldContent;
426
426
  exports.TileBelowTheFoldContent = Tile.TileBelowTheFoldContent;
427
- exports.TileGroup = TileGroup["default"];
427
+ exports.TileGroup = TileGroup.TileGroup;
428
428
  exports.TimePicker = TimePicker["default"];
429
429
  exports.TimePickerSelect = TimePickerSelect["default"];
430
430
  exports.Toggle = Toggle.Toggle;
@@ -25,9 +25,14 @@ const callOnChangeHandler = ({
25
25
  }) => {
26
26
  if (isControlled) {
27
27
  if (isMounted && onChangeHandlerControlled) {
28
- onChangeHandlerControlled({
29
- selectedItems
30
- });
28
+ // Use setTimeout to defer the controlled onChange call,
29
+ // avoiding React’s warning: "Cannot update a component while rendering a different component".
30
+ // This ensures the parent state updates after rendering completes.
31
+ setTimeout(() => {
32
+ onChangeHandlerControlled({
33
+ selectedItems
34
+ });
35
+ }, 0);
31
36
  }
32
37
  } else {
33
38
  onChangeHandlerUncontrolled(selectedItems);
@@ -14,17 +14,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
14
14
  *
15
15
  * @see https://github.com/facebook/fbjs/blob/4d1751311d3f67af2dcce2e40df8512a23c7b9c6/packages/fbjs/src/core/ExecutionEnvironment.js#L12
16
16
  */
17
- const canUseDOM = !!(typeof window !== 'undefined' &&
18
- // TODO: `ssr-friendly` doesn't support ESLint v9.
19
- // https://github.com/kopiro/eslint-plugin-ssr-friendly/issues/30
20
- // https://github.com/carbon-design-system/carbon/issues/18991
21
- /*
22
- // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
23
- */
24
- window.document &&
25
- /*
26
- // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
27
- */
28
- window.document.createElement);
17
+ const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
29
18
 
30
19
  exports.canUseDOM = canUseDOM;
@@ -1,9 +1,7 @@
1
1
  /**
2
- * Copyright IBM Corp. 2025, 2025
2
+ * Copyright IBM Corp. 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
- export declare const mockHTMLElement: (options: HTMLElement) => {
8
- mockRestore: () => void;
9
- };
7
+ export * from './utils';
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Copyright IBM Corp. 2025, 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 { ReactNode, RefObject } from 'react';
8
+ type Item = {
9
+ id: string;
10
+ };
11
+ /**
12
+ * Manages overflow items in a container by automatically hiding items that don't fit.
13
+ * @param items - Array of items to manage for overflow, each must have an `id` property.
14
+ * @param containerRef - React ref to the container element that holds the items.
15
+ * @param offsetRef - Optional ref to an offset element (like a "more" button) whose width is reserved when calculating available space.
16
+ * @param maxItems - Optional maximum number of visible items. If undefined, only container space constrains visibility.
17
+ * @param onChange - Optional callback called when hidden items change. Receives array of currently hidden items.
18
+ * @returns Object with `visibleItems` (items to display), `hiddenItems` (items that don't fit), and `itemRefHandler` (function to attach refs to items for width measurement).
19
+ */
20
+ declare const useOverflowItems: <T extends Item>(items: T[] | ReactNode, containerRef: RefObject<HTMLDivElement>, offsetRef?: RefObject<HTMLDivElement>, maxItems?: number, onChange?: (hiddenItems: T[]) => void) => {
21
+ visibleItems: T[];
22
+ hiddenItems: T[];
23
+ itemRefHandler: () => void;
24
+ } | {
25
+ visibleItems: T[];
26
+ itemRefHandler: (id: string, node: HTMLDivElement | null) => () => void;
27
+ hiddenItems: T[];
28
+ };
29
+ export default useOverflowItems;
@@ -0,0 +1,126 @@
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
+ Object.defineProperty(exports, '__esModule', { value: true });
11
+
12
+ var React = require('react');
13
+ var useResizeObserver = require('./useResizeObserver.js');
14
+ var usePreviousValue = require('./usePreviousValue.js');
15
+
16
+ /**
17
+ * Manages overflow items in a container by automatically hiding items that don't fit.
18
+ * @param items - Array of items to manage for overflow, each must have an `id` property.
19
+ * @param containerRef - React ref to the container element that holds the items.
20
+ * @param offsetRef - Optional ref to an offset element (like a "more" button) whose width is reserved when calculating available space.
21
+ * @param maxItems - Optional maximum number of visible items. If undefined, only container space constrains visibility.
22
+ * @param onChange - Optional callback called when hidden items change. Receives array of currently hidden items.
23
+ * @returns Object with `visibleItems` (items to display), `hiddenItems` (items that don't fit), and `itemRefHandler` (function to attach refs to items for width measurement).
24
+ */
25
+
26
+ const useOverflowItems = (items, containerRef, offsetRef, maxItems, onChange) => {
27
+ const itemsRef = React.useRef(null);
28
+ const [maxWidth, setMaxWidth] = React.useState(0);
29
+ if (!items || !Array.isArray(items)) {
30
+ return {
31
+ visibleItems: [],
32
+ hiddenItems: [],
33
+ itemRefHandler: () => {}
34
+ };
35
+ }
36
+ const handleResize = () => {
37
+ if (containerRef.current) {
38
+ const offset = offsetRef?.current?.offsetWidth || 0;
39
+ const newMax = containerRef.current.offsetWidth - offset;
40
+ setMaxWidth(newMax);
41
+ }
42
+ };
43
+ useResizeObserver.useResizeObserver({
44
+ ref: containerRef,
45
+ onResize: handleResize
46
+ });
47
+ const getMap = () => {
48
+ if (!itemsRef.current) {
49
+ itemsRef.current = new Map();
50
+ }
51
+ return itemsRef.current;
52
+ };
53
+ const itemRefHandler = (id, node) => {
54
+ const map = getMap();
55
+ if (node) {
56
+ const style = getComputedStyle?.(node);
57
+ const totalWidth = node.offsetWidth + parseInt(style.marginLeft) + parseInt(style.marginRight);
58
+ map.set(id, totalWidth);
59
+ }
60
+ return () => {
61
+ map.delete(id);
62
+ };
63
+ };
64
+ const getVisibleItems = () => {
65
+ if (!items || Array.isArray(items) === false) {
66
+ return [];
67
+ }
68
+ if (!containerRef) {
69
+ return items;
70
+ }
71
+ const map = getMap();
72
+ let maxReached = false;
73
+ let accumulatedWidth = 0;
74
+ const visibleItems = items.slice(0, maxItems).reduce((prev, cur) => {
75
+ if (maxReached) {
76
+ return prev;
77
+ }
78
+ const itemWidth = map.get(cur.id) || 0;
79
+ const willFit = accumulatedWidth + itemWidth <= maxWidth;
80
+ if (willFit) {
81
+ accumulatedWidth += itemWidth;
82
+ prev.push(cur);
83
+ } else {
84
+ maxReached = true;
85
+ }
86
+ return prev;
87
+ }, []);
88
+ return visibleItems;
89
+ };
90
+
91
+ // Memoize visible items calculation to avoid recalculating on every render
92
+ const visibleItems = React.useMemo(() => {
93
+ if (!Array.isArray(items)) {
94
+ return [];
95
+ }
96
+ return getVisibleItems();
97
+ }, [items, maxWidth, maxItems]);
98
+
99
+ // Memoize hidden items calculation
100
+ const hiddenItems = React.useMemo(() => {
101
+ if (!Array.isArray(items)) {
102
+ return [];
103
+ }
104
+ return items.slice(visibleItems.length);
105
+ }, [items, visibleItems]);
106
+
107
+ // Use previous value to compare and only call onChange when needed
108
+ const previousHiddenItems = usePreviousValue.usePreviousValue(hiddenItems);
109
+
110
+ // Only call onChange if hidden items actually changed
111
+ React.useEffect(() => {
112
+ if (previousHiddenItems && onChange) {
113
+ const hasChanged = hiddenItems.length !== previousHiddenItems.length || hiddenItems.some((item, index) => item !== previousHiddenItems[index]);
114
+ if (hasChanged) {
115
+ onChange(hiddenItems);
116
+ }
117
+ }
118
+ }, [hiddenItems, previousHiddenItems, onChange]);
119
+ return {
120
+ visibleItems,
121
+ itemRefHandler,
122
+ hiddenItems
123
+ };
124
+ };
125
+
126
+ exports["default"] = useOverflowItems;
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { RefObject } from 'react';
8
8
  export declare const useResizeObserver: ({ ref, onResize, }: {
9
- ref: RefObject<HTMLElement>;
9
+ ref: RefObject<HTMLElement | null>;
10
10
  onResize?: (rect: DOMRectReadOnly) => void;
11
11
  }) => {
12
12
  width: number;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Copyright IBM Corp. 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 { type ComponentType, type ReactElement, type ReactNode } from 'react';
8
+ /**
9
+ * Checks if an element is a valid React element of a given component type.
10
+ *
11
+ * @param element - The element to test.
12
+ * @param component - The component to match.
13
+ */
14
+ export declare const isComponentElement: <P>(element: ReactNode, component: ComponentType<P>) => element is ReactElement<P>;
@@ -0,0 +1,22 @@
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
+ Object.defineProperty(exports, '__esModule', { value: true });
11
+
12
+ var React = require('react');
13
+
14
+ /**
15
+ * Checks if an element is a valid React element of a given component type.
16
+ *
17
+ * @param element - The element to test.
18
+ * @param component - The component to match.
19
+ */
20
+ const isComponentElement = (element, component) => /*#__PURE__*/React.isValidElement(element) && element.type === component;
21
+
22
+ exports.isComponentElement = isComponentElement;
@@ -1,7 +1,2 @@
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
- */
1
+ export declare const uniqueIdDeprecationMessage = "The `uniqueId()` helper function from @carbon/react was called. This function should no longer be used.\n\n@carbon/react components should use the internal/useId.js hook instead. Other projects can use React's `useId()` hook: https://react.dev/reference/react/useId";
7
2
  export declare const uniqueId: (prefix?: string) => string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@carbon/react",
3
3
  "description": "React components for the Carbon Design System",
4
- "version": "1.84.0-rc.0",
4
+ "version": "1.85.0-rc.0",
5
5
  "license": "Apache-2.0",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
@@ -52,11 +52,11 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@babel/runtime": "^7.27.3",
55
- "@carbon/feature-flags": "^0.27.0-rc.0",
56
- "@carbon/icons-react": "^11.61.0-rc.0",
57
- "@carbon/layout": "^11.35.0-rc.0",
58
- "@carbon/styles": "^1.83.0-rc.0",
59
- "@carbon/utilities": "^0.7.0-rc.0",
55
+ "@carbon/feature-flags": "^0.27.0",
56
+ "@carbon/icons-react": "^11.62.0-rc.0",
57
+ "@carbon/layout": "^11.36.0-rc.0",
58
+ "@carbon/styles": "^1.84.0-rc.0",
59
+ "@carbon/utilities": "^0.7.0",
60
60
  "@floating-ui/react": "^0.27.4",
61
61
  "@ibm/telemetry-js": "^1.5.0",
62
62
  "classnames": "2.5.1",
@@ -80,30 +80,23 @@
80
80
  "@babel/preset-react": "^7.27.1",
81
81
  "@babel/preset-typescript": "^7.27.1",
82
82
  "@carbon/test-utils": "^10.36.0",
83
- "@carbon/themes": "^11.54.0-rc.0",
83
+ "@carbon/themes": "^11.55.0-rc.0",
84
84
  "@figma/code-connect": "^1.3.2",
85
85
  "@rollup/plugin-babel": "^6.0.0",
86
86
  "@rollup/plugin-commonjs": "^28.0.0",
87
87
  "@rollup/plugin-node-resolve": "^15.0.0",
88
88
  "@rollup/plugin-typescript": "^11.0.0",
89
89
  "@stackblitz/sdk": "^1.11.0",
90
- "@storybook/addon-a11y": "^8.4.7",
91
- "@storybook/addon-actions": "^8.4.7",
92
- "@storybook/addon-docs": "^8.4.7",
93
- "@storybook/addon-essentials": "^8.4.7",
94
- "@storybook/addon-links": "^8.4.7",
95
- "@storybook/addon-webpack5-compiler-babel": "^3.0.3",
96
- "@storybook/blocks": "^8.4.7",
97
- "@storybook/manager-api": "^8.4.7",
98
- "@storybook/react": "^8.4.7",
99
- "@storybook/react-webpack5": "^8.4.7",
100
- "@storybook/theming": "^8.4.7",
90
+ "@storybook/addon-docs": "^9.0.5",
91
+ "@storybook/addon-links": "^9.0.5",
92
+ "@storybook/addon-webpack5-compiler-babel": "^3.0.6",
93
+ "@storybook/react-webpack5": "^9.0.5",
101
94
  "@types/react-is": "^19.0.0",
102
95
  "@types/use-sync-external-store": "^1",
103
96
  "autoprefixer": "^10.4.0",
104
97
  "babel-loader": "^9.0.0",
105
98
  "babel-plugin-dev-expression": "^0.2.3",
106
- "babel-preset-carbon": "^0.7.0-rc.0",
99
+ "babel-preset-carbon": "^0.7.0",
107
100
  "browserify-zlib": "^0.2.0",
108
101
  "browserslist-config-carbon": "^11.2.0",
109
102
  "clipboardy": "^2.1.0",
@@ -122,14 +115,12 @@
122
115
  "react-dom": "^19.0.0",
123
116
  "react-is": "^16.13.1 || ^17.0.2 || ^18.3.1 || ^19.0.0",
124
117
  "remark-gfm": "^4.0.0",
125
- "requestanimationframe": "^0.0.23",
126
118
  "rimraf": "^6.0.0",
127
119
  "rollup": "^2.79.1",
128
120
  "rollup-plugin-strip-banner": "^3.0.0",
129
121
  "sass": "^1.77.7",
130
122
  "sass-loader": "^16.0.0",
131
- "storybook": "^8.4.7",
132
- "storybook-addon-accessibility-checker": "^3.1.61-rc.3",
123
+ "storybook": "^9.0.5",
133
124
  "stream-browserify": "^3.0.0",
134
125
  "style-loader": "^4.0.0",
135
126
  "typescript-config-carbon": "^0.5.0",
@@ -148,5 +139,5 @@
148
139
  "**/*.scss",
149
140
  "**/*.css"
150
141
  ],
151
- "gitHead": "fcae2645f1b5a1a01b5629926df471ec1945d1e6"
142
+ "gitHead": "80ee492dc5079b90b8bca04f49497a90b60a366e"
152
143
  }
package/telemetry.yml CHANGED
@@ -326,6 +326,7 @@ collect:
326
326
  # Dialog
327
327
  - ariaDescribedBy
328
328
  - ariaLabelledBy
329
+ - focusAfterCloseRef
329
330
  - modal
330
331
  # DismissibleTag
331
332
  - dismissTooltipLabel
@@ -474,6 +475,8 @@ collect:
474
475
  # PageHeaderContentPageActions
475
476
  - actions
476
477
  - menuButtonLabel
478
+ # PageHeaderTabBar
479
+ - tags
477
480
  # PageSelector
478
481
  - currentPage
479
482
  - totalPages
@@ -1,14 +0,0 @@
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
- let lastId = 0;
9
- const uniqueId = (prefix = 'id') => {
10
- lastId++;
11
- return `${prefix}${lastId}`;
12
- };
13
-
14
- export { uniqueId };
@@ -1,18 +0,0 @@
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
- Object.defineProperty(exports, '__esModule', { value: true });
11
-
12
- let lastId = 0;
13
- const uniqueId = (prefix = 'id') => {
14
- lastId++;
15
- return `${prefix}${lastId}`;
16
- };
17
-
18
- exports.uniqueId = uniqueId;