@carbon/react 1.63.1 → 1.64.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 (114) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +1558 -1265
  2. package/es/components/{Slug → AILabel}/index.js +47 -35
  3. package/es/components/{AiSkeleton/AiSkeletonIcon.d.ts → AISkeleton/AISkeletonIcon.d.ts} +4 -4
  4. package/es/components/{AiSkeleton/AiSkeletonIcon.js → AISkeleton/AISkeletonIcon.js} +5 -5
  5. package/es/components/{AiSkeleton/AiSkeletonPlaceholder.d.ts → AISkeleton/AISkeletonPlaceholder.d.ts} +4 -4
  6. package/es/components/{AiSkeleton/AiSkeletonPlaceholder.js → AISkeleton/AISkeletonPlaceholder.js} +5 -5
  7. package/es/components/{AiSkeleton/AiSkeletonText.d.ts → AISkeleton/AISkeletonText.d.ts} +4 -4
  8. package/es/components/{AiSkeleton/AiSkeletonText.js → AISkeleton/AISkeletonText.js} +3 -3
  9. package/es/components/AISkeleton/index.d.ts +10 -0
  10. package/es/components/CheckboxGroup/CheckboxGroup.js +1 -1
  11. package/es/components/ComboBox/ComboBox.d.ts +21 -6
  12. package/es/components/ComboBox/ComboBox.js +52 -14
  13. package/es/components/ComposedModal/ComposedModal.js +1 -1
  14. package/es/components/DataTable/DataTable.js +1 -1
  15. package/es/components/DataTable/TableSelectRow.js +2 -1
  16. package/es/components/DataTable/TableToolbarSearch.js +2 -2
  17. package/es/components/DatePicker/DatePicker.js +65 -14
  18. package/es/components/DatePicker/plugins/fixEventsPlugin.js +11 -0
  19. package/es/components/DatePickerInput/DatePickerInput.js +1 -1
  20. package/es/components/Dropdown/Dropdown.d.ts +6 -4
  21. package/es/components/Dropdown/Dropdown.js +18 -10
  22. package/es/components/FluidMultiSelect/FluidMultiSelect.js +10 -6
  23. package/es/components/Menu/MenuItem.js +45 -63
  24. package/es/components/Modal/Modal.js +1 -1
  25. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +6 -4
  26. package/es/components/MultiSelect/FilterableMultiSelect.js +50 -27
  27. package/es/components/MultiSelect/MultiSelect.d.ts +6 -4
  28. package/es/components/MultiSelect/MultiSelect.js +12 -8
  29. package/es/components/NumberInput/NumberInput.js +2 -2
  30. package/es/components/OverflowMenu/OverflowMenu.js +2 -1
  31. package/es/components/OverflowMenu/next/index.js +2 -1
  32. package/es/components/RadioButtonGroup/RadioButtonGroup.js +1 -1
  33. package/es/components/RadioTile/RadioTile.js +1 -1
  34. package/es/components/Select/Select.js +1 -1
  35. package/es/components/Tabs/Tabs.js +3 -3
  36. package/es/components/Tag/DismissibleTag.js +1 -1
  37. package/es/components/Tag/OperationalTag.js +1 -1
  38. package/es/components/Tag/SelectableTag.js +3 -1
  39. package/es/components/Tag/Tag.js +1 -1
  40. package/es/components/TextArea/TextArea.js +1 -1
  41. package/es/components/TextInput/PasswordInput.js +5 -0
  42. package/es/components/TextInput/TextInput.js +1 -1
  43. package/es/components/Tile/Tile.js +2 -2
  44. package/es/components/TreeView/TreeNode.d.ts +150 -0
  45. package/es/components/TreeView/TreeNode.js +22 -15
  46. package/es/components/TreeView/TreeView.d.ts +59 -0
  47. package/es/components/TreeView/TreeView.js +37 -23
  48. package/es/components/TreeView/index.d.ts +11 -0
  49. package/es/components/UIShell/SwitcherItem.d.ts +4 -0
  50. package/es/components/UIShell/SwitcherItem.js +7 -1
  51. package/es/index.d.ts +4 -2
  52. package/es/index.js +6 -6
  53. package/es/node_modules/@floating-ui/core/dist/floating-ui.core.mjs.js +143 -0
  54. package/es/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs.js +39 -0
  55. package/lib/components/{Slug → AILabel}/index.js +49 -37
  56. package/lib/components/{AiSkeleton/AiSkeletonIcon.d.ts → AISkeleton/AISkeletonIcon.d.ts} +4 -4
  57. package/lib/components/{AiSkeleton/AiSkeletonIcon.js → AISkeleton/AISkeletonIcon.js} +5 -5
  58. package/lib/components/{AiSkeleton/AiSkeletonPlaceholder.d.ts → AISkeleton/AISkeletonPlaceholder.d.ts} +4 -4
  59. package/lib/components/{AiSkeleton/AiSkeletonPlaceholder.js → AISkeleton/AISkeletonPlaceholder.js} +5 -5
  60. package/lib/components/{AiSkeleton/AiSkeletonText.d.ts → AISkeleton/AISkeletonText.d.ts} +4 -4
  61. package/lib/components/{AiSkeleton/AiSkeletonText.js → AISkeleton/AISkeletonText.js} +3 -3
  62. package/lib/components/AISkeleton/index.d.ts +10 -0
  63. package/lib/components/CheckboxGroup/CheckboxGroup.js +1 -1
  64. package/lib/components/ComboBox/ComboBox.d.ts +21 -6
  65. package/lib/components/ComboBox/ComboBox.js +52 -14
  66. package/lib/components/ComposedModal/ComposedModal.js +1 -1
  67. package/lib/components/DataTable/DataTable.js +2 -2
  68. package/lib/components/DataTable/TableSelectRow.js +2 -1
  69. package/lib/components/DataTable/TableToolbarSearch.js +2 -2
  70. package/lib/components/DatePicker/DatePicker.js +65 -14
  71. package/lib/components/DatePicker/plugins/fixEventsPlugin.js +11 -0
  72. package/lib/components/DatePickerInput/DatePickerInput.js +1 -1
  73. package/lib/components/Dropdown/Dropdown.d.ts +6 -4
  74. package/lib/components/Dropdown/Dropdown.js +18 -10
  75. package/lib/components/FluidMultiSelect/FluidMultiSelect.js +10 -6
  76. package/lib/components/Menu/MenuItem.js +44 -62
  77. package/lib/components/Modal/Modal.js +1 -1
  78. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +6 -4
  79. package/lib/components/MultiSelect/FilterableMultiSelect.js +49 -26
  80. package/lib/components/MultiSelect/MultiSelect.d.ts +6 -4
  81. package/lib/components/MultiSelect/MultiSelect.js +12 -8
  82. package/lib/components/NumberInput/NumberInput.js +2 -2
  83. package/lib/components/OverflowMenu/OverflowMenu.js +2 -1
  84. package/lib/components/OverflowMenu/next/index.js +2 -1
  85. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +1 -1
  86. package/lib/components/RadioTile/RadioTile.js +1 -1
  87. package/lib/components/Select/Select.js +1 -1
  88. package/lib/components/Tabs/Tabs.js +2 -2
  89. package/lib/components/Tag/DismissibleTag.js +1 -1
  90. package/lib/components/Tag/OperationalTag.js +1 -1
  91. package/lib/components/Tag/SelectableTag.js +3 -1
  92. package/lib/components/Tag/Tag.js +1 -1
  93. package/lib/components/TextArea/TextArea.js +1 -1
  94. package/lib/components/TextInput/PasswordInput.js +5 -0
  95. package/lib/components/TextInput/TextInput.js +1 -1
  96. package/lib/components/Tile/Tile.js +2 -2
  97. package/lib/components/TreeView/TreeNode.d.ts +150 -0
  98. package/lib/components/TreeView/TreeNode.js +24 -17
  99. package/lib/components/TreeView/TreeView.d.ts +59 -0
  100. package/lib/components/TreeView/TreeView.js +39 -25
  101. package/lib/components/TreeView/index.d.ts +11 -0
  102. package/lib/components/UIShell/SwitcherItem.d.ts +4 -0
  103. package/lib/components/UIShell/SwitcherItem.js +7 -1
  104. package/lib/index.d.ts +4 -2
  105. package/lib/index.js +20 -14
  106. package/lib/node_modules/@floating-ui/core/dist/floating-ui.core.mjs.js +148 -0
  107. package/lib/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs.js +47 -0
  108. package/package.json +4 -4
  109. package/scss/components/ai-label/_ai-label.scss +9 -0
  110. package/scss/components/ai-label/_index.scss +9 -0
  111. package/es/components/AiSkeleton/index.d.ts +0 -10
  112. package/es/components/DataTable/tools/instanceId.js +0 -20
  113. package/lib/components/AiSkeleton/index.d.ts +0 -10
  114. package/lib/components/DataTable/tools/instanceId.js +0 -24
@@ -23,6 +23,7 @@ require('../FluidForm/FluidForm.js');
23
23
  var FormContext = require('../FluidForm/FormContext.js');
24
24
  var useId = require('../../internal/useId.js');
25
25
  var react = require('@floating-ui/react');
26
+ var floatingUi_core = require('../../node_modules/@floating-ui/core/dist/floating-ui.core.mjs.js');
26
27
  var ListBoxPropTypes = require('../ListBox/ListBoxPropTypes.js');
27
28
 
28
29
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -82,7 +83,8 @@ const Dropdown = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
82
83
  } = _ref;
83
84
  const {
84
85
  refs,
85
- floatingStyles
86
+ floatingStyles,
87
+ middlewareData
86
88
  } = react.useFloating(autoAlign ? {
87
89
  placement: direction,
88
90
  // The floating element is positioned relative to its nearest
@@ -101,15 +103,19 @@ const Dropdown = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
101
103
  width: `${rects.reference.width}px`
102
104
  });
103
105
  }
104
- }), react.flip()],
106
+ }), react.flip(), floatingUi_core.hide()],
105
107
  whileElementsMounted: react.autoUpdate
106
108
  } : {} // When autoAlign is turned off, floating-ui will not be used
107
109
  );
108
110
  React.useEffect(() => {
109
111
  if (autoAlign) {
110
- Object.keys(floatingStyles).forEach(style => {
112
+ const updatedFloatingStyles = {
113
+ ...floatingStyles,
114
+ visibility: middlewareData.hide?.referenceHidden ? 'hidden' : 'visible'
115
+ };
116
+ Object.keys(updatedFloatingStyles).forEach(style => {
111
117
  if (refs.floating.current) {
112
- refs.floating.current.style[style] = floatingStyles[style];
118
+ refs.floating.current.style[style] = updatedFloatingStyles[style];
113
119
  }
114
120
  });
115
121
  }
@@ -270,11 +276,11 @@ const Dropdown = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
270
276
  };
271
277
  const menuProps = React.useMemo(() => getMenuProps({
272
278
  ref: autoAlign ? refs.setFloating : null
273
- }), [autoAlign]);
279
+ }), [autoAlign, getMenuProps, refs.setFloating]);
274
280
 
275
281
  // Slug is always size `mini`
276
282
  let normalizedSlug;
277
- if (slug && slug['type']?.displayName === 'Slug') {
283
+ if (slug && slug['type']?.displayName === 'AILabel') {
278
284
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
279
285
  size: 'mini'
280
286
  });
@@ -370,10 +376,12 @@ Dropdown.propTypes = {
370
376
  */
371
377
  disabled: PropTypes__default["default"].bool,
372
378
  /**
373
- * Additional props passed to Downshift. Use with caution: anything you define
374
- * here overrides the components' internal handling of that prop. Downshift
375
- * internals are subject to change, and in some cases they can not be shimmed
376
- * to shield you from potentially breaking changes.
379
+ * Additional props passed to Downshift.
380
+ *
381
+ * **Use with caution:** anything you define here overrides the components'
382
+ * internal handling of that prop. Downshift APIs and internals are subject to
383
+ * change, and in some cases they can not be shimmed by Carbon to shield you
384
+ * from potentially breaking changes.
377
385
  */
378
386
  downshiftProps: PropTypes__default["default"].object,
379
387
  /**
@@ -63,7 +63,8 @@ FluidMultiSelect.propTypes = {
63
63
  clearSelectionText: PropTypes__default["default"].string,
64
64
  /**
65
65
  * Provide a compare function that is used to determine the ordering of
66
- * options. See 'sortItems' for more control.
66
+ * options. See 'sortItems' for more control. Consider declaring function
67
+ * with `useCallback` to prevent unnecessary re-renders.
67
68
  */
68
69
  compareItems: PropTypes__default["default"].func,
69
70
  /**
@@ -75,10 +76,12 @@ FluidMultiSelect.propTypes = {
75
76
  */
76
77
  disabled: PropTypes__default["default"].bool,
77
78
  /**
78
- * Additional props passed to Downshift. Use with caution: anything you define
79
- * here overrides the components' internal handling of that prop. Downshift
80
- * internals are subject to change, and in some cases they can not be shimmed
81
- * to shield you from potentially breaking changes.
79
+ * Additional props passed to Downshift.
80
+ *
81
+ * **Use with caution:** anything you define here overrides the components'
82
+ * internal handling of that prop. Downshift APIs and internals are subject to
83
+ * change, and in some cases they can not be shimmed by Carbon to shield you
84
+ * from potentially breaking changes.
82
85
  */
83
86
  downshiftProps: PropTypes__default["default"].object,
84
87
  /**
@@ -114,7 +117,8 @@ FluidMultiSelect.propTypes = {
114
117
  /**
115
118
  * Helper function passed to downshift that allows the library to render a
116
119
  * given item to a string label. By default, it extracts the `label` field
117
- * from a given item to serve as the item label in the list.
120
+ * from a given item to serve as the item label in the list. Consider
121
+ * declaring function with `useCallback` to prevent unnecessary re-renders.
118
122
  */
119
123
  itemToString: PropTypes__default["default"].func,
120
124
  /**
@@ -13,6 +13,7 @@ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelper
13
13
  var cx = require('classnames');
14
14
  var PropTypes = require('prop-types');
15
15
  var React = require('react');
16
+ var react = require('@floating-ui/react');
16
17
  var iconsReact = require('@carbon/icons-react');
17
18
  var useControllableState = require('../../internal/useControllableState.js');
18
19
  var useMergedRefs = require('../../internal/useMergedRefs.js');
@@ -33,9 +34,6 @@ var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
33
34
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
34
35
 
35
36
  var _CaretLeft, _CaretRight;
36
- const hoverIntentDelay = 150; // in ms
37
- const leaveIntentDelay = 300; // in ms
38
-
39
37
  const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(_ref, forwardRef) {
40
38
  let {
41
39
  children,
@@ -48,19 +46,37 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(_ref, forwardRe
48
46
  shortcut,
49
47
  ...rest
50
48
  } = _ref;
49
+ const [submenuOpen, setSubmenuOpen] = React.useState(false);
50
+ const [rtl, setRtl] = React.useState(false);
51
+ const {
52
+ refs,
53
+ floatingStyles,
54
+ context: floatingContext
55
+ } = react.useFloating({
56
+ open: submenuOpen,
57
+ onOpenChange: setSubmenuOpen,
58
+ placement: rtl ? 'left-start' : 'right-start',
59
+ whileElementsMounted: react.autoUpdate,
60
+ middleware: [react.offset({
61
+ mainAxis: -6,
62
+ crossAxis: -6
63
+ })]
64
+ });
65
+ const {
66
+ getReferenceProps,
67
+ getFloatingProps
68
+ } = react.useInteractions([react.useHover(floatingContext, {
69
+ delay: 100,
70
+ enabled: true,
71
+ handleClose: react.safePolygon({
72
+ requireIntent: false
73
+ })
74
+ })]);
51
75
  const prefix = usePrefix.usePrefix();
52
76
  const context = React.useContext(MenuContext.MenuContext);
53
77
  const menuItem = React.useRef(null);
54
- const ref = useMergedRefs.useMergedRefs([forwardRef, menuItem]);
55
- const [boundaries, setBoundaries] = React.useState({
56
- x: -1,
57
- y: -1
58
- });
59
- const [rtl, setRtl] = React.useState(false);
78
+ const ref = useMergedRefs.useMergedRefs([forwardRef, menuItem, refs.setReference]);
60
79
  const hasChildren = Boolean(children);
61
- const [submenuOpen, setSubmenuOpen] = React.useState(false);
62
- const hoverIntentTimeout = React.useRef(null);
63
- const leaveIntentTimeout = React.useRef(null);
64
80
  const isDisabled = disabled && !hasChildren;
65
81
  const isDanger = kind === 'danger' && !hasChildren;
66
82
  function registerItem() {
@@ -76,31 +92,10 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(_ref, forwardRe
76
92
  if (!menuItem.current) {
77
93
  return;
78
94
  }
79
- const {
80
- x,
81
- y,
82
- width,
83
- height
84
- } = menuItem.current.getBoundingClientRect();
85
- if (rtl) {
86
- setBoundaries({
87
- x: [-x, x - width],
88
- y: [y, y + height]
89
- });
90
- } else {
91
- setBoundaries({
92
- x: [x, x + width],
93
- y: [y, y + height]
94
- });
95
- }
96
95
  setSubmenuOpen(true);
97
96
  }
98
97
  function closeSubmenu() {
99
98
  setSubmenuOpen(false);
100
- setBoundaries({
101
- x: -1,
102
- y: -1
103
- });
104
99
  }
105
100
  function handleClick(e) {
106
101
  if (!isDisabled) {
@@ -114,27 +109,6 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(_ref, forwardRe
114
109
  }
115
110
  }
116
111
  }
117
- function handleMouseEnter() {
118
- if (leaveIntentTimeout.current) {
119
- // When mouse reenters before closing keep sub menu open
120
- clearTimeout(leaveIntentTimeout.current);
121
- leaveIntentTimeout.current = null;
122
- }
123
- hoverIntentTimeout.current = setTimeout(() => {
124
- openSubmenu();
125
- }, hoverIntentDelay);
126
- }
127
- function handleMouseLeave() {
128
- if (hoverIntentTimeout.current) {
129
- clearTimeout(hoverIntentTimeout.current);
130
- // Avoid closing the sub menu as soon as mouse leaves
131
- // prevents accidental closure due to scroll bar
132
- leaveIntentTimeout.current = setTimeout(() => {
133
- closeSubmenu();
134
- menuItem.current?.focus();
135
- }, leaveIntentDelay);
136
- }
137
- }
138
112
  function handleKeyDown(e) {
139
113
  if (hasChildren && match.match(e, keys.ArrowRight)) {
140
114
  openSubmenu();
@@ -179,7 +153,18 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(_ref, forwardRe
179
153
  });
180
154
  }
181
155
  }, [iconsAllowed, IconElement, context.state.hasIcons, context]);
182
- return /*#__PURE__*/React__default["default"].createElement("li", _rollupPluginBabelHelpers["extends"]({
156
+ React.useEffect(() => {
157
+ Object.keys(floatingStyles).forEach(style => {
158
+ if (refs.floating.current && style !== 'position') {
159
+ refs.floating.current.style[style] = floatingStyles[style];
160
+ }
161
+ });
162
+ }, [floatingStyles, refs.floating]);
163
+ return /*#__PURE__*/React__default["default"].createElement(react.FloatingFocusManager, {
164
+ context: floatingContext,
165
+ order: ['reference', 'floating'],
166
+ modal: false
167
+ }, /*#__PURE__*/React__default["default"].createElement("li", _rollupPluginBabelHelpers["extends"]({
183
168
  role: "menuitem"
184
169
  }, rest, {
185
170
  ref: ref,
@@ -189,10 +174,8 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(_ref, forwardRe
189
174
  "aria-haspopup": hasChildren ?? undefined,
190
175
  "aria-expanded": hasChildren ? submenuOpen : undefined,
191
176
  onClick: handleClick,
192
- onMouseEnter: hasChildren ? handleMouseEnter : undefined,
193
- onMouseLeave: hasChildren ? handleMouseLeave : undefined,
194
177
  onKeyDown: handleKeyDown
195
- }), /*#__PURE__*/React__default["default"].createElement("div", {
178
+ }, getReferenceProps()), /*#__PURE__*/React__default["default"].createElement("div", {
196
179
  className: `${prefix}--menu-item__icon`
197
180
  }, iconsAllowed && IconElement && /*#__PURE__*/React__default["default"].createElement(IconElement, null)), /*#__PURE__*/React__default["default"].createElement(Text.Text, {
198
181
  as: "div",
@@ -202,16 +185,15 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(_ref, forwardRe
202
185
  className: `${prefix}--menu-item__shortcut`
203
186
  }, shortcut), hasChildren && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("div", {
204
187
  className: `${prefix}--menu-item__shortcut`
205
- }, rtl ? _CaretLeft || (_CaretLeft = /*#__PURE__*/React__default["default"].createElement(iconsReact.CaretLeft, null)) : _CaretRight || (_CaretRight = /*#__PURE__*/React__default["default"].createElement(iconsReact.CaretRight, null))), /*#__PURE__*/React__default["default"].createElement(Menu.Menu, {
188
+ }, rtl ? _CaretLeft || (_CaretLeft = /*#__PURE__*/React__default["default"].createElement(iconsReact.CaretLeft, null)) : _CaretRight || (_CaretRight = /*#__PURE__*/React__default["default"].createElement(iconsReact.CaretRight, null))), /*#__PURE__*/React__default["default"].createElement(Menu.Menu, _rollupPluginBabelHelpers["extends"]({
206
189
  label: label,
207
190
  open: submenuOpen,
208
191
  onClose: () => {
209
192
  closeSubmenu();
210
193
  menuItem.current?.focus();
211
194
  },
212
- x: boundaries.x,
213
- y: boundaries.y
214
- }, children)));
195
+ ref: refs.setFloating
196
+ }, getFloatingProps()), children))));
215
197
  });
216
198
  MenuItem.propTypes = {
217
199
  /**
@@ -240,7 +240,7 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
240
240
 
241
241
  // Slug is always size `sm`
242
242
  let normalizedSlug;
243
- if (slug && slug['type']?.displayName === 'Slug') {
243
+ if (slug && slug['type']?.displayName === 'AILabel') {
244
244
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
245
245
  size: 'sm'
246
246
  });
@@ -48,10 +48,12 @@ export interface FilterableMultiSelectProps<ItemType> extends MultiSelectSorting
48
48
  */
49
49
  disabled?: boolean;
50
50
  /**
51
- * Additional props passed to Downshift. Use with caution: anything you define
52
- * here overrides the components' internal handling of that prop. Downshift
53
- * internals are subject to change, and in some cases they can not be shimmed
54
- * to shield you from potentially breaking changes.
51
+ * Additional props passed to Downshift.
52
+ *
53
+ * **Use with caution:** anything you define here overrides the components'
54
+ * internal handling of that prop. Downshift APIs and internals are subject to
55
+ * change, and in some cases they can not be shimmed by Carbon to shield you
56
+ * from potentially breaking changes.
55
57
  */
56
58
  downshiftProps?: UseMultipleSelectionProps<ItemType>;
57
59
  /**
@@ -176,20 +176,23 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
176
176
  setPrevOpen(open);
177
177
  }
178
178
 
179
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
180
- const sortedItems = sortItems(filterItems(items, {
181
- itemToString: itemToString$1,
182
- inputValue
183
- }), {
184
- selectedItems: {
185
- top: controlledSelectedItems,
186
- fixed: [],
187
- 'top-after-reopen': topItems
188
- }[selectionFeedback],
189
- itemToString: itemToString$1,
190
- compareItems,
191
- locale
192
- });
179
+ // memoize sorted items to reduce unnecessary expensive sort on rerender
180
+ const sortedItems = React.useMemo(() => {
181
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
182
+ return sortItems(filterItems(items, {
183
+ itemToString: itemToString$1,
184
+ inputValue
185
+ }), {
186
+ selectedItems: {
187
+ top: controlledSelectedItems,
188
+ fixed: [],
189
+ 'top-after-reopen': topItems
190
+ }[selectionFeedback],
191
+ itemToString: itemToString$1,
192
+ compareItems,
193
+ locale
194
+ });
195
+ }, [items, inputValue, controlledSelectedItems, topItems, selectionFeedback, itemToString$1, compareItems, locale]);
193
196
  const inline = type === 'inline';
194
197
  const showWarning = !invalid && warn;
195
198
  const wrapperClasses = cx__default["default"](`${prefix}--multi-select__wrapper`, `${prefix}--multi-select--filterable__wrapper`, `${prefix}--list-box__wrapper`, containerClassName, {
@@ -229,9 +232,15 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
229
232
  setTopItems(controlledSelectedItems);
230
233
  }
231
234
  }, [controlledSelectedItems, isOpen, setTopItems]);
235
+ const validateHighlightFocus = () => {
236
+ if (controlledSelectedItems.length > 0) {
237
+ setHighlightedIndex(0);
238
+ }
239
+ };
232
240
  function handleMenuChange(forceIsOpen) {
233
241
  const nextIsOpen = forceIsOpen ?? !isOpen;
234
242
  setIsOpen(nextIsOpen);
243
+ validateHighlightFocus();
235
244
  if (onMenuChange) {
236
245
  onMenuChange(nextIsOpen);
237
246
  }
@@ -249,9 +258,8 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
249
258
  } = Downshift.useCombobox({
250
259
  isOpen,
251
260
  items: sortedItems,
261
+ // defaultHighlightedIndex: 0, // after selection, highlight the first item.
252
262
  itemToString: itemToString$1,
253
- defaultHighlightedIndex: 0,
254
- // after selection, highlight the first item.
255
263
  id,
256
264
  labelId,
257
265
  menuId,
@@ -296,24 +304,37 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
296
304
  return changes;
297
305
  case FunctionToggleMenu:
298
306
  case ToggleButtonClick:
307
+ validateHighlightFocus();
299
308
  if (changes.isOpen && !changes.selectedItem) {
300
309
  return {
301
- ...changes,
302
- highlightedIndex: 0
310
+ ...changes
303
311
  };
304
312
  }
305
- return changes;
313
+ return {
314
+ ...changes,
315
+ highlightedIndex: null
316
+ };
306
317
  case InputChange:
307
318
  if (onInputValueChange) {
308
319
  onInputValueChange(changes.inputValue);
309
320
  }
310
321
  setInputValue(changes.inputValue ?? '');
311
322
  setIsOpen(true);
312
- return changes;
323
+ return {
324
+ ...changes,
325
+ highlightedIndex: 0
326
+ };
313
327
  case InputClick:
328
+ validateHighlightFocus();
329
+ if (changes.isOpen && !changes.selectedItem) {
330
+ return {
331
+ ...changes
332
+ };
333
+ }
314
334
  return {
315
335
  ...changes,
316
- isOpen: false
336
+ isOpen: false,
337
+ highlightedIndex: null
317
338
  };
318
339
  case MenuMouseLeave:
319
340
  return {
@@ -397,7 +418,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
397
418
 
398
419
  // Slug is always size `mini`
399
420
  let normalizedSlug;
400
- if (slug && slug['type']?.displayName === 'Slug') {
421
+ if (slug && slug['type']?.displayName === 'AILabel') {
401
422
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
402
423
  size: 'mini'
403
424
  });
@@ -634,10 +655,12 @@ FilterableMultiSelect.propTypes = {
634
655
  */
635
656
  disabled: PropTypes__default["default"].bool,
636
657
  /**
637
- * Additional props passed to Downshift. Use with caution: anything you define
638
- * here overrides the components' internal handling of that prop. Downshift
639
- * internals are subject to change, and in some cases they can not be shimmed
640
- * to shield you from potentially breaking changes.
658
+ * Additional props passed to Downshift.
659
+ *
660
+ * **Use with caution:** anything you define here overrides the components'
661
+ * internal handling of that prop. Downshift APIs and internals are subject to
662
+ * change, and in some cases they can not be shimmed by Carbon to shield you
663
+ * from potentially breaking changes.
641
664
  */
642
665
  // @ts-ignore
643
666
  downshiftProps: PropTypes__default["default"].shape(Downshift__default["default"].propTypes),
@@ -42,10 +42,12 @@ export interface MultiSelectProps<ItemType> extends MultiSelectSortingProps<Item
42
42
  */
43
43
  disabled?: ListBoxProps['disabled'];
44
44
  /**
45
- * Additional props passed to Downshift. Use with caution: anything you define
46
- * here overrides the components' internal handling of that prop. Downshift
47
- * internals are subject to change, and in some cases they can not be shimmed
48
- * to shield you from potentially breaking changes.
45
+ * Additional props passed to Downshift.
46
+ *
47
+ * **Use with caution:** anything you define here overrides the components'
48
+ * internal handling of that prop. Downshift APIs and internals are subject to
49
+ * change, and in some cases they can not be shimmed by Carbon to shield you
50
+ * from potentially breaking changes.
49
51
  */
50
52
  downshiftProps?: Partial<UseSelectProps<ItemType>>;
51
53
  /**
@@ -322,7 +322,7 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
322
322
  setIsOpenWrapper(changes.isOpen || false);
323
323
  return {
324
324
  ...changes,
325
- highlightedIndex: 0
325
+ highlightedIndex: controlledSelectedItems.length > 0 ? 0 : undefined
326
326
  };
327
327
  case ItemClick:
328
328
  setHighlightedIndex(changes.selectedItem);
@@ -397,7 +397,7 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
397
397
 
398
398
  // Slug is always size `mini`
399
399
  let normalizedSlug;
400
- if (slug && slug['type']?.displayName === 'Slug') {
400
+ if (slug && slug['type']?.displayName === 'AILabel') {
401
401
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
402
402
  size: 'mini'
403
403
  });
@@ -517,7 +517,8 @@ MultiSelect.propTypes = {
517
517
  clearSelectionText: PropTypes__default["default"].string,
518
518
  /**
519
519
  * Provide a compare function that is used to determine the ordering of
520
- * options. See 'sortItems' for more control.
520
+ * options. See 'sortItems' for more control. Consider
521
+ * declaring function with `useCallback` to prevent unnecessary re-renders.
521
522
  */
522
523
  compareItems: PropTypes__default["default"].func,
523
524
  /**
@@ -529,10 +530,12 @@ MultiSelect.propTypes = {
529
530
  */
530
531
  disabled: PropTypes__default["default"].bool,
531
532
  /**
532
- * Additional props passed to Downshift. Use with caution: anything you define
533
- * here overrides the components' internal handling of that prop. Downshift
534
- * internals are subject to change, and in some cases they can not be shimmed
535
- * to shield you from potentially breaking changes.
533
+ * Additional props passed to Downshift.
534
+ *
535
+ * **Use with caution:** anything you define here overrides the components'
536
+ * internal handling of that prop. Downshift APIs and internals are subject to
537
+ * change, and in some cases they can not be shimmed by Carbon to shield you
538
+ * from potentially breaking changes.
536
539
  */
537
540
  downshiftProps: PropTypes__default["default"].object,
538
541
  /**
@@ -569,7 +572,8 @@ MultiSelect.propTypes = {
569
572
  /**
570
573
  * Helper function passed to downshift that allows the library to render a
571
574
  * given item to a string label. By default, it extracts the `label` field
572
- * from a given item to serve as the item label in the list.
575
+ * from a given item to serve as the item label in the list. Consider
576
+ * declaring function with `useCallback` to prevent unnecessary re-renders.
573
577
  */
574
578
  itemToString: PropTypes__default["default"].func,
575
579
  /**
@@ -190,7 +190,7 @@ const NumberInput = /*#__PURE__*/React__default["default"].forwardRef(function N
190
190
 
191
191
  // Slug is always size `mini`
192
192
  let normalizedSlug;
193
- if (slug && slug['type']?.displayName === 'Slug') {
193
+ if (slug && slug['type']?.displayName === 'AILabel') {
194
194
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
195
195
  size: 'mini'
196
196
  });
@@ -198,7 +198,7 @@ const NumberInput = /*#__PURE__*/React__default["default"].forwardRef(function N
198
198
 
199
199
  // Need to update the internal value when the revert button is clicked
200
200
  let isRevertActive;
201
- if (slug && slug['type']?.displayName === 'Slug') {
201
+ if (slug && slug['type']?.displayName === 'AILabel') {
202
202
  isRevertActive = normalizedSlug.props.revertActive;
203
203
  }
204
204
  React.useEffect(() => {
@@ -416,7 +416,8 @@ class OverflowMenu extends React__default["default"].Component {
416
416
  id: id,
417
417
  ref: mergeRefs["default"](this._triggerRef, ref),
418
418
  size: size,
419
- label: iconDescription
419
+ label: iconDescription,
420
+ kind: "ghost"
420
421
  }), /*#__PURE__*/React__default["default"].createElement(IconElement, iconProps)), open && this.state.hasMountedTrigger && wrappedMenuBody));
421
422
  }
422
423
  }
@@ -106,7 +106,8 @@ const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function
106
106
  onMouseDown: handleMousedown,
107
107
  ref: floatingRef,
108
108
  label: label,
109
- align: tooltipAlignment
109
+ align: tooltipAlignment,
110
+ kind: "ghost"
110
111
  }, /*#__PURE__*/React__default["default"].createElement(IconElement, {
111
112
  className: `${prefix}--overflow-menu__icon`
112
113
  })), /*#__PURE__*/React__default["default"].createElement(Menu.Menu, {
@@ -111,7 +111,7 @@ const RadioButtonGroup = /*#__PURE__*/React__default["default"].forwardRef((prop
111
111
 
112
112
  // Slug is always size `mini`
113
113
  let normalizedSlug;
114
- if (slug && slug['type']?.displayName === 'Slug') {
114
+ if (slug && slug['type']?.displayName === 'AILabel') {
115
115
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
116
116
  size: 'mini',
117
117
  kind: 'default'
@@ -81,7 +81,7 @@ const RadioTile = /*#__PURE__*/React__default["default"].forwardRef(function Rad
81
81
 
82
82
  // Slug is always size `xs`
83
83
  let normalizedSlug;
84
- if (slug && slug['type']?.displayName === 'Slug') {
84
+ if (slug && slug['type']?.displayName === 'AILabel') {
85
85
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
86
86
  size: 'xs'
87
87
  });
@@ -135,7 +135,7 @@ const Select = /*#__PURE__*/React__default["default"].forwardRef(function Select
135
135
 
136
136
  // Slug is always size `mini`
137
137
  let normalizedSlug;
138
- if (slug && slug['type']?.displayName === 'Slug') {
138
+ if (slug && slug['type']?.displayName === 'AILabel') {
139
139
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
140
140
  size: 'mini'
141
141
  });
@@ -798,7 +798,7 @@ const Tab = /*#__PURE__*/React.forwardRef(function Tab(_ref8, forwardRef) {
798
798
  };
799
799
  useEvent.useEvent(dismissIconRef, 'mouseover', onDismissIconMouseEnter);
800
800
  useEvent.useEvent(dismissIconRef, 'mouseleave', onDismissIconMouseLeave);
801
- React.useLayoutEffect(() => {
801
+ useIsomorphicEffect["default"](() => {
802
802
  function handler() {
803
803
  const elementTabId = document.getElementById(`${id}`) || tabRef.current;
804
804
  if (elementTabId?.closest(`.${prefix}--tabs--vertical`)) {
@@ -1139,7 +1139,7 @@ function TabPanels(_ref11) {
1139
1139
  const prefix = usePrefix.usePrefix();
1140
1140
  const refs = React.useRef([]);
1141
1141
  const hiddenStates = React.useRef([]);
1142
- React.useLayoutEffect(() => {
1142
+ useIsomorphicEffect["default"](() => {
1143
1143
  const tabContainer = refs.current[0]?.previousElementSibling;
1144
1144
  const isVertical = tabContainer?.classList.contains(`${prefix}--tabs--vertical`);
1145
1145
  const parentHasHeight = tabContainer?.parentElement?.style.height;
@@ -60,7 +60,7 @@ const DismissibleTag = _ref => {
60
60
  }
61
61
  };
62
62
  let normalizedSlug;
63
- if (slug && slug['type']?.displayName === 'Slug') {
63
+ if (slug && slug['type']?.displayName === 'AILabel') {
64
64
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
65
65
  size: 'sm',
66
66
  kind: 'inline'
@@ -62,7 +62,7 @@ const OperationalTag = _ref => {
62
62
  setIsEllipsisApplied(isEllipsisActive.isEllipsisActive(newElement));
63
63
  }, [prefix, tagRef]);
64
64
  let normalizedSlug;
65
- if (slug && slug['type']?.displayName === 'Slug') {
65
+ if (slug && slug['type']?.displayName === 'AILabel') {
66
66
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
67
67
  size: 'sm',
68
68
  kind: 'inline'
@@ -53,7 +53,7 @@ const SelectableTag = _ref => {
53
53
  setIsEllipsisApplied(isEllipsisActive.isEllipsisActive(newElement));
54
54
  }, [prefix, tagRef]);
55
55
  let normalizedSlug;
56
- if (slug && slug['type']?.displayName === 'Slug') {
56
+ if (slug && slug['type']?.displayName === 'AILabel') {
57
57
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
58
58
  size: 'sm',
59
59
  kind: 'inline'
@@ -75,6 +75,7 @@ const SelectableTag = _ref => {
75
75
  leaveDelayMs: 0,
76
76
  onMouseEnter: () => false
77
77
  }, /*#__PURE__*/React__default["default"].createElement(Tag["default"], _rollupPluginBabelHelpers["extends"]({
78
+ "aria-pressed": selectedTag,
78
79
  ref: tagRef,
79
80
  slug: slug,
80
81
  size: size,
@@ -89,6 +90,7 @@ const SelectableTag = _ref => {
89
90
  }, text), normalizedSlug));
90
91
  }
91
92
  return /*#__PURE__*/React__default["default"].createElement(Tag["default"], _rollupPluginBabelHelpers["extends"]({
93
+ "aria-pressed": selectedTag,
92
94
  ref: tagRef,
93
95
  slug: slug,
94
96
  size: size,