@carbon/react 1.68.0 → 1.69.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 (78) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +786 -786
  2. package/README.md +3 -3
  3. package/es/components/Accordion/AccordionItem.js +0 -1
  4. package/es/components/Button/Button.js +6 -0
  5. package/es/components/CheckboxGroup/CheckboxGroup.js +1 -2
  6. package/es/components/CheckboxGroup/index.d.ts +10 -0
  7. package/es/components/ComboBox/ComboBox.js +13 -18
  8. package/es/components/ComboButton/index.js +10 -3
  9. package/es/components/DataTable/TableCell.d.ts +1 -4
  10. package/es/components/DataTable/TableCell.js +3 -2
  11. package/es/components/Disclosure/index.d.ts +18 -0
  12. package/es/components/Dropdown/Dropdown.js +11 -9
  13. package/es/components/FileUploader/FileUploader.d.ts +8 -92
  14. package/es/components/FileUploader/FileUploader.js +116 -137
  15. package/es/components/IdPrefix/index.d.ts +26 -0
  16. package/es/components/Menu/MenuItem.js +1 -4
  17. package/es/components/MenuButton/index.d.ts +4 -0
  18. package/es/components/MenuButton/index.js +19 -5
  19. package/es/components/MultiSelect/MultiSelect.js +11 -9
  20. package/es/components/OverflowMenu/next/index.d.ts +4 -0
  21. package/es/components/OverflowMenu/next/index.js +19 -9
  22. package/es/components/PaginationNav/PaginationNav.js +1 -1
  23. package/es/components/Popover/index.js +18 -14
  24. package/es/components/Portal/index.d.ts +25 -0
  25. package/es/components/Slider/Slider.js +2 -2
  26. package/es/components/Tag/DismissibleTag.js +2 -2
  27. package/es/components/Tag/OperationalTag.d.ts +2 -10
  28. package/es/components/Tag/OperationalTag.js +2 -14
  29. package/es/components/Tag/SelectableTag.d.ts +2 -10
  30. package/es/components/Tag/SelectableTag.js +2 -16
  31. package/es/components/Toggle/Toggle.js +2 -0
  32. package/es/components/ToggleSmall/ToggleSmall.Skeleton.d.ts +49 -0
  33. package/es/components/ToggleSmall/index.d.ts +7 -0
  34. package/es/components/TreeView/TreeNode.js +4 -2
  35. package/es/components/TreeView/TreeView.js +4 -4
  36. package/es/components/UIShell/SideNavMenuItem.d.ts +4 -3
  37. package/es/components/UIShell/SideNavMenuItem.js +1 -4
  38. package/es/index.js +1 -1
  39. package/es/internal/useIdPrefix.d.ts +9 -0
  40. package/lib/components/Accordion/AccordionItem.js +0 -1
  41. package/lib/components/Button/Button.js +6 -0
  42. package/lib/components/CheckboxGroup/CheckboxGroup.js +1 -2
  43. package/lib/components/CheckboxGroup/index.d.ts +10 -0
  44. package/lib/components/ComboBox/ComboBox.js +18 -23
  45. package/lib/components/ComboButton/index.js +12 -5
  46. package/lib/components/DataTable/TableCell.d.ts +1 -4
  47. package/lib/components/DataTable/TableCell.js +3 -2
  48. package/lib/components/Disclosure/index.d.ts +18 -0
  49. package/lib/components/Dropdown/Dropdown.js +18 -16
  50. package/lib/components/FileUploader/FileUploader.d.ts +8 -92
  51. package/lib/components/FileUploader/FileUploader.js +113 -134
  52. package/lib/components/IdPrefix/index.d.ts +26 -0
  53. package/lib/components/Menu/MenuItem.js +1 -4
  54. package/lib/components/MenuButton/index.d.ts +4 -0
  55. package/lib/components/MenuButton/index.js +19 -5
  56. package/lib/components/MultiSelect/MultiSelect.js +18 -16
  57. package/lib/components/OverflowMenu/next/index.d.ts +4 -0
  58. package/lib/components/OverflowMenu/next/index.js +21 -11
  59. package/lib/components/PaginationNav/PaginationNav.js +1 -1
  60. package/lib/components/Popover/index.js +18 -14
  61. package/lib/components/Portal/index.d.ts +25 -0
  62. package/lib/components/Slider/Slider.js +2 -2
  63. package/lib/components/Tag/DismissibleTag.js +2 -2
  64. package/lib/components/Tag/OperationalTag.d.ts +2 -10
  65. package/lib/components/Tag/OperationalTag.js +2 -14
  66. package/lib/components/Tag/SelectableTag.d.ts +2 -10
  67. package/lib/components/Tag/SelectableTag.js +2 -16
  68. package/lib/components/Toggle/Toggle.js +2 -0
  69. package/lib/components/ToggleSmall/ToggleSmall.Skeleton.d.ts +49 -0
  70. package/lib/components/ToggleSmall/index.d.ts +7 -0
  71. package/lib/components/TreeView/TreeNode.js +4 -2
  72. package/lib/components/TreeView/TreeView.js +4 -4
  73. package/lib/components/UIShell/SideNavMenuItem.d.ts +4 -3
  74. package/lib/components/UIShell/SideNavMenuItem.js +1 -4
  75. package/lib/index.js +2 -2
  76. package/lib/internal/useIdPrefix.d.ts +9 -0
  77. package/package.json +7 -7
  78. package/telemetry.yml +809 -809
@@ -5,157 +5,137 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import { defineProperty as _defineProperty, extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
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__default from 'react';
11
+ import React__default, { useState } from 'react';
12
12
  import Filename from './Filename.js';
13
13
  import FileUploaderButton from './FileUploaderButton.js';
14
14
  import { ButtonKinds } from '../../prop-types/types.js';
15
- import { PrefixContext } from '../../internal/usePrefix.js';
15
+ import { usePrefix } from '../../internal/usePrefix.js';
16
16
  import '../Text/index.js';
17
+ import { useId } from '../../internal/useId.js';
17
18
  import { Text } from '../Text/Text.js';
18
19
  import { matches } from '../../internal/keyboard/match.js';
19
20
  import { Enter, Space } from '../../internal/keyboard/keys.js';
20
21
 
21
- class FileUploader extends React__default.Component {
22
- constructor() {
23
- super(...arguments);
24
- _defineProperty(this, "state", {
25
- filenames: []
26
- });
27
- _defineProperty(this, "nodes", []);
28
- _defineProperty(this, "uploaderButton", /*#__PURE__*/React__default.createRef());
29
- _defineProperty(this, "handleChange", evt => {
22
+ const FileUploader = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
23
+ let {
24
+ accept,
25
+ buttonKind,
26
+ buttonLabel,
27
+ className,
28
+ disabled,
29
+ filenameStatus,
30
+ iconDescription,
31
+ labelDescription,
32
+ labelTitle,
33
+ multiple,
34
+ name,
35
+ onChange,
36
+ onClick,
37
+ onDelete,
38
+ size,
39
+ ...other
40
+ } = _ref;
41
+ const fileUploaderInstanceId = useId('file-uploader');
42
+ const [state, updateState] = useState({
43
+ fileNames: []
44
+ });
45
+ const nodes = [];
46
+ const prefix = usePrefix();
47
+ const handleChange = evt => {
48
+ evt.stopPropagation();
49
+ const filenames = Array.prototype.map.call(evt.target.files, file => file.name);
50
+ updateState(prevState => ({
51
+ fileNames: multiple ? [...new Set([...prevState.fileNames, ...filenames])] : filenames
52
+ }));
53
+ if (onChange) {
54
+ onChange(evt);
55
+ }
56
+ };
57
+ const handleClick = (evt, _ref2) => {
58
+ let {
59
+ index,
60
+ filenameStatus
61
+ } = _ref2;
62
+ if (filenameStatus === 'edit') {
30
63
  evt.stopPropagation();
31
- const filenames = Array.prototype.map.call(evt.target.files, file => file.name);
32
- this.setState({
33
- filenames: this.props.multiple ? [...new Set([...this.state.filenames, ...filenames])] : filenames
64
+ const filteredArray = state.fileNames.filter(filename => filename !== nodes[index]?.innerText?.trim());
65
+ updateState({
66
+ fileNames: filteredArray
34
67
  });
35
- if (this.props.onChange) {
36
- this.props.onChange(evt);
68
+ if (onDelete) {
69
+ onDelete(evt);
70
+ uploaderButton.current?.focus?.();
37
71
  }
38
- });
39
- _defineProperty(this, "handleClick", (evt, _ref) => {
40
- let {
41
- index,
42
- filenameStatus
43
- } = _ref;
44
- if (filenameStatus === 'edit') {
45
- evt.stopPropagation();
46
- const filteredArray = this.state.filenames.filter(filename => filename !== this.nodes[index].innerText.trim());
47
- this.setState({
48
- filenames: filteredArray
72
+ onClick?.(evt);
73
+ }
74
+ };
75
+ const uploaderButton = /*#__PURE__*/React__default.createRef();
76
+ const classes = cx({
77
+ [`${prefix}--form-item`]: true,
78
+ [className]: className
79
+ });
80
+ const getHelperLabelClasses = baseClass => cx(baseClass, {
81
+ [`${prefix}--label-description--disabled`]: disabled
82
+ });
83
+ const selectedFileClasses = cx(`${prefix}--file__selected-file`, {
84
+ [`${prefix}--file__selected-file--md`]: size === 'field' || size === 'md',
85
+ [`${prefix}--file__selected-file--sm`]: size === 'small' || size === 'sm'
86
+ });
87
+ return /*#__PURE__*/React__default.createElement("div", _extends({
88
+ className: classes
89
+ }, other), !labelTitle ? null : /*#__PURE__*/React__default.createElement(Text, {
90
+ as: "h3",
91
+ className: getHelperLabelClasses(`${prefix}--file--label`)
92
+ }, labelTitle), /*#__PURE__*/React__default.createElement(Text, {
93
+ as: "p",
94
+ className: getHelperLabelClasses(`${prefix}--label-description`),
95
+ id: fileUploaderInstanceId
96
+ }, labelDescription), /*#__PURE__*/React__default.createElement(FileUploaderButton, {
97
+ innerRef: uploaderButton,
98
+ disabled: disabled,
99
+ labelText: buttonLabel,
100
+ multiple: multiple,
101
+ buttonKind: buttonKind,
102
+ onChange: handleChange,
103
+ disableLabelChanges: true,
104
+ accept: accept,
105
+ name: name,
106
+ size: size,
107
+ "aria-describedby": fileUploaderInstanceId
108
+ }), /*#__PURE__*/React__default.createElement("div", {
109
+ className: `${prefix}--file-container`
110
+ }, state.fileNames.length === 0 ? null : state.fileNames.map((name, index) => /*#__PURE__*/React__default.createElement("span", _extends({
111
+ key: index,
112
+ className: selectedFileClasses,
113
+ ref: node => nodes[index] = node // eslint-disable-line
114
+ }, other), /*#__PURE__*/React__default.createElement(Text, {
115
+ as: "p",
116
+ className: `${prefix}--file-filename`,
117
+ id: name
118
+ }, name), /*#__PURE__*/React__default.createElement("span", {
119
+ className: `${prefix}--file__state-container`
120
+ }, /*#__PURE__*/React__default.createElement(Filename, {
121
+ name: name,
122
+ iconDescription: iconDescription,
123
+ status: filenameStatus,
124
+ onKeyDown: evt => {
125
+ if (matches(evt, [Enter, Space])) {
126
+ handleClick(evt, {
127
+ index,
128
+ filenameStatus
49
129
  });
50
- if (this.props.onDelete) {
51
- this.props.onDelete(evt);
52
- this.uploaderButton.current?.focus?.();
53
- }
54
- this.props.onClick?.(evt);
55
130
  }
56
- });
57
- _defineProperty(this, "clearFiles", () => {
58
- // A clearFiles function that resets filenames and can be referenced using a ref by the parent.
59
- this.setState({
60
- filenames: []
61
- });
62
- });
63
- }
64
- static getDerivedStateFromProps(_ref2, state) {
65
- let {
131
+ },
132
+ onClick: evt => handleClick(evt, {
133
+ index,
66
134
  filenameStatus
67
- } = _ref2;
68
- const {
69
- prevFilenameStatus
70
- } = state;
71
- return prevFilenameStatus === filenameStatus ? null : {
72
- filenameStatus,
73
- prevFilenameStatus: filenameStatus
74
- };
75
- }
76
- render() {
77
- const {
78
- iconDescription,
79
- buttonLabel = '',
80
- buttonKind = 'primary',
81
- disabled = false,
82
- filenameStatus = 'uploading',
83
- labelDescription,
84
- labelTitle,
85
- className,
86
- multiple = false,
87
- accept = [],
88
- name,
89
- size = 'md',
90
- onDelete,
91
- // eslint-disable-line
92
- ...other
93
- } = this.props;
94
- const prefix = this.context;
95
- const classes = cx({
96
- [`${prefix}--form-item`]: true,
97
- [className]: className
98
- });
99
- const getHelperLabelClasses = baseClass => cx(baseClass, {
100
- [`${prefix}--label-description--disabled`]: disabled
101
- });
102
- const selectedFileClasses = cx(`${prefix}--file__selected-file`, {
103
- [`${prefix}--file__selected-file--md`]: size === 'field' || size === 'md',
104
- [`${prefix}--file__selected-file--sm`]: size === 'small' || size === 'sm'
105
- });
106
- return /*#__PURE__*/React__default.createElement("div", _extends({
107
- className: classes
108
- }, other), !labelTitle ? null : /*#__PURE__*/React__default.createElement(Text, {
109
- as: "h3",
110
- className: getHelperLabelClasses(`${prefix}--file--label`)
111
- }, labelTitle), /*#__PURE__*/React__default.createElement(Text, {
112
- as: "p",
113
- className: getHelperLabelClasses(`${prefix}--label-description`),
114
- id: "description"
115
- }, labelDescription), /*#__PURE__*/React__default.createElement(FileUploaderButton, {
116
- innerRef: this.uploaderButton,
117
- disabled: disabled,
118
- labelText: buttonLabel,
119
- multiple: multiple,
120
- buttonKind: buttonKind,
121
- onChange: this.handleChange,
122
- disableLabelChanges: true,
123
- accept: accept,
124
- name: name,
125
- size: size,
126
- "aria-describedby": "description"
127
- }), /*#__PURE__*/React__default.createElement("div", {
128
- className: `${prefix}--file-container`
129
- }, this.state.filenames.length === 0 ? null : this.state.filenames.map((name, index) => /*#__PURE__*/React__default.createElement("span", _extends({
130
- key: index,
131
- className: selectedFileClasses,
132
- ref: node => this.nodes[index] = node // eslint-disable-line
133
- }, other), /*#__PURE__*/React__default.createElement(Text, {
134
- as: "p",
135
- className: `${prefix}--file-filename`,
136
- id: name
137
- }, name), /*#__PURE__*/React__default.createElement("span", {
138
- className: `${prefix}--file__state-container`
139
- }, /*#__PURE__*/React__default.createElement(Filename, {
140
- name: name,
141
- iconDescription: iconDescription,
142
- status: filenameStatus,
143
- onKeyDown: evt => {
144
- if (matches(evt, [Enter, Space])) {
145
- this.handleClick(evt, {
146
- index,
147
- filenameStatus
148
- });
149
- }
150
- },
151
- onClick: evt => this.handleClick(evt, {
152
- index,
153
- filenameStatus
154
- })
155
- }))))));
156
- }
157
- }
158
- _defineProperty(FileUploader, "propTypes", {
135
+ })
136
+ }))))));
137
+ });
138
+ FileUploader.propTypes = {
159
139
  /**
160
140
  * Specify the types of files that this input should be able to receive
161
141
  */
@@ -221,7 +201,6 @@ _defineProperty(FileUploader, "propTypes", {
221
201
  * sizes.
222
202
  */
223
203
  size: PropTypes.oneOf(['sm', 'md', 'lg'])
224
- });
225
- _defineProperty(FileUploader, "contextType", PrefixContext);
204
+ };
226
205
 
227
206
  export { FileUploader as default };
@@ -0,0 +1,26 @@
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
+ import PropTypes from 'prop-types';
8
+ import { PropsWithChildren, ReactNode } from 'react';
9
+ type IdPrefixProps = {
10
+ children?: ReactNode;
11
+ /**
12
+ * The value used to prefix the auto-generated id placed on some DOM elements
13
+ */
14
+ prefix?: string;
15
+ };
16
+ declare function IdPrefix({ children, prefix }: PropsWithChildren<IdPrefixProps>): import("react/jsx-runtime").JSX.Element;
17
+ declare namespace IdPrefix {
18
+ var propTypes: {
19
+ children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
20
+ /**
21
+ * The value used to prefix the auto-generated id placed on some DOM elements
22
+ */
23
+ prefix: PropTypes.Requireable<string>;
24
+ };
25
+ }
26
+ export { IdPrefix };
@@ -347,9 +347,6 @@ const MenuItemRadioGroup = /*#__PURE__*/forwardRef(function MenuItemRadioGroup(_
347
347
  });
348
348
  function handleClick(item, e) {
349
349
  setSelection(item);
350
- if (onChange) {
351
- onChange(e);
352
- }
353
350
  }
354
351
  useEffect(() => {
355
352
  if (!context.state.hasIcons) {
@@ -374,7 +371,7 @@ const MenuItemRadioGroup = /*#__PURE__*/forwardRef(function MenuItemRadioGroup(_
374
371
  "aria-checked": item === selection,
375
372
  renderIcon: item === selection ? Checkmark : undefined,
376
373
  onClick: e => {
377
- handleClick(item, e);
374
+ handleClick(item);
378
375
  }
379
376
  }))));
380
377
  });
@@ -39,6 +39,10 @@ export interface MenuButtonProps extends ComponentProps<'div'> {
39
39
  * Specify the tabIndex of the button.
40
40
  */
41
41
  tabIndex?: number;
42
+ /**
43
+ * Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
44
+ */
45
+ menuTarget?: Element;
42
46
  }
43
47
  declare const MenuButton: React.ForwardRefExoticComponent<Omit<MenuButtonProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
44
48
  export { MenuButton };
@@ -18,6 +18,7 @@ import { useAttachedMenu } from '../../internal/useAttachedMenu.js';
18
18
  import { useId } from '../../internal/useId.js';
19
19
  import { usePrefix } from '../../internal/usePrefix.js';
20
20
  import { flip, size, useFloating, autoUpdate } from '@floating-ui/react';
21
+ import { useFeatureFlag } from '../FeatureFlags/index.js';
21
22
  import mergeRefs from '../../tools/mergeRefs.js';
22
23
 
23
24
  const validButtonKinds = ['primary', 'tertiary', 'ghost'];
@@ -32,14 +33,21 @@ const MenuButton = /*#__PURE__*/forwardRef(function MenuButton(_ref, forwardRef)
32
33
  size: size$1 = 'lg',
33
34
  menuAlignment = 'bottom',
34
35
  tabIndex = 0,
36
+ menuTarget,
35
37
  ...rest
36
38
  } = _ref;
39
+ // feature flag utilized to separate out only the dynamic styles from @floating-ui
40
+ // flag is turned on when collision detection (ie. flip, hide) logic is not desired
41
+ const enableOnlyFloatingStyles = useFeatureFlag('enable-v12-dynamic-floating-styles');
37
42
  const id = useId('MenuButton');
38
43
  const prefix = usePrefix();
39
44
  const triggerRef = useRef(null);
40
- const middlewares = [flip({
41
- crossAxis: false
42
- })];
45
+ let middlewares = [];
46
+ if (!enableOnlyFloatingStyles) {
47
+ middlewares = [flip({
48
+ crossAxis: false
49
+ })];
50
+ }
43
51
  if (menuAlignment === 'bottom' || menuAlignment === 'top') {
44
52
  middlewares.push(size({
45
53
  apply(_ref2) {
@@ -121,7 +129,8 @@ const MenuButton = /*#__PURE__*/forwardRef(function MenuButton(_ref, forwardRef)
121
129
  mode: "basic",
122
130
  size: size$1,
123
131
  open: open,
124
- onClose: handleClose
132
+ onClose: handleClose,
133
+ target: menuTarget
125
134
  }, children));
126
135
  });
127
136
  MenuButton.propTypes = {
@@ -160,7 +169,12 @@ MenuButton.propTypes = {
160
169
  * Specify the tabIndex of the button.
161
170
  */
162
171
  // @ts-ignore-next-line -- avoid spurious (?) TS2322 error
163
- tabIndex: PropTypes.number
172
+ tabIndex: PropTypes.number,
173
+ /**
174
+ * Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
175
+ */
176
+
177
+ menuTarget: PropTypes.instanceOf(typeof Element !== 'undefined' ? Element : Object)
164
178
  };
165
179
 
166
180
  export { MenuButton };
@@ -27,6 +27,7 @@ import '../Checkbox/Checkbox.Skeleton.js';
27
27
  import { noopFn } from '../../internal/noopFn.js';
28
28
  import { useFloating, flip, size, autoUpdate } from '@floating-ui/react';
29
29
  import { hide } from '../../node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs.js';
30
+ import { useFeatureFlag } from '../FeatureFlags/index.js';
30
31
  import { match } from '../../internal/keyboard/match.js';
31
32
  import { ListBoxSize } from '../ListBox/ListBoxPropTypes.js';
32
33
  import { Delete, Escape, Space, ArrowDown, Enter } from '../../internal/keyboard/keys.js';
@@ -125,11 +126,12 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
125
126
  const [prevOpenProp, setPrevOpenProp] = useState(open);
126
127
  const [topItems, setTopItems] = useState([]);
127
128
  const [itemsCleared, setItemsCleared] = useState(false);
129
+ const enableFloatingStyles = useFeatureFlag('enable-v12-dynamic-floating-styles') || autoAlign;
128
130
  const {
129
131
  refs,
130
132
  floatingStyles,
131
133
  middlewareData
132
- } = useFloating(autoAlign ? {
134
+ } = useFloating(enableFloatingStyles ? {
133
135
  placement: direction,
134
136
  // The floating element is positioned relative to its nearest
135
137
  // containing block (usually the viewport). It will in many cases also
@@ -137,7 +139,7 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
137
139
  // https://floating-ui.com/docs/misc#clipping
138
140
  strategy: 'fixed',
139
141
  // Middleware order matters, arrow should be last
140
- middleware: [flip({
142
+ middleware: [autoAlign && flip({
141
143
  crossAxis: false
142
144
  }), size({
143
145
  apply(_ref2) {
@@ -149,11 +151,11 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
149
151
  width: `${rects.reference.width}px`
150
152
  });
151
153
  }
152
- }), hide()],
154
+ }), autoAlign && hide()],
153
155
  whileElementsMounted: autoUpdate
154
156
  } : {});
155
157
  useLayoutEffect(() => {
156
- if (autoAlign) {
158
+ if (enableFloatingStyles) {
157
159
  const updatedFloatingStyles = {
158
160
  ...floatingStyles,
159
161
  visibility: middlewareData.hide?.referenceHidden ? 'hidden' : 'visible'
@@ -164,7 +166,7 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
164
166
  }
165
167
  });
166
168
  }
167
- }, [autoAlign, floatingStyles, refs.floating, middlewareData, open]);
169
+ }, [enableFloatingStyles, floatingStyles, refs.floating, middlewareData, open]);
168
170
  const {
169
171
  selectedItems: controlledSelectedItems,
170
172
  onItemChange,
@@ -279,7 +281,7 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
279
281
  [`${prefix}--multi-select--selected`]: selectedItems && selectedItems.length > 0,
280
282
  [`${prefix}--list-box--up`]: direction === 'top',
281
283
  [`${prefix}--multi-select--readonly`]: readOnly,
282
- [`${prefix}--autoalign`]: autoAlign,
284
+ [`${prefix}--autoalign`]: enableFloatingStyles,
283
285
  [`${prefix}--multi-select--selectall`]: selectAll
284
286
  });
285
287
 
@@ -410,8 +412,8 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
410
412
 
411
413
  // Memoize the value of getMenuProps to avoid an infinite loop
412
414
  const menuProps = useMemo(() => getMenuProps({
413
- ref: autoAlign ? refs.setFloating : null
414
- }), [autoAlign, getMenuProps, refs.setFloating]);
415
+ ref: enableFloatingStyles ? refs.setFloating : null
416
+ }), [enableFloatingStyles, getMenuProps, refs.setFloating]);
415
417
  return /*#__PURE__*/React__default.createElement("div", {
416
418
  className: wrapperClasses
417
419
  }, /*#__PURE__*/React__default.createElement("label", _extends({
@@ -438,7 +440,7 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
438
440
  className: `${prefix}--list-box__invalid-icon ${prefix}--list-box__invalid-icon--warning`
439
441
  }), /*#__PURE__*/React__default.createElement("div", {
440
442
  className: multiSelectFieldWrapperClasses,
441
- ref: autoAlign ? refs.setReference : null
443
+ ref: enableFloatingStyles ? refs.setReference : null
442
444
  }, selectedItems.length > 0 && /*#__PURE__*/React__default.createElement(ListBox.Selection, {
443
445
  readOnly: readOnly,
444
446
  clearSelection: !disabled && !readOnly ? clearSelection : noopFn,
@@ -38,6 +38,10 @@ interface OverflowMenuProps {
38
38
  * Specify how the trigger tooltip should be aligned.
39
39
  */
40
40
  tooltipAlignment?: 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'right';
41
+ /**
42
+ * Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
43
+ */
44
+ menuTarget?: Element;
41
45
  }
42
46
  declare const OverflowMenu: React.ForwardRefExoticComponent<OverflowMenuProps & React.RefAttributes<HTMLDivElement>>;
43
47
  export { OverflowMenu };
@@ -11,6 +11,7 @@ import PropTypes from 'prop-types';
11
11
  import cx from 'classnames';
12
12
  import { OverflowMenuVertical } from '@carbon/icons-react';
13
13
  import { useFloating, flip, autoUpdate } from '@floating-ui/react';
14
+ import { useFeatureFlag } from '../../FeatureFlags/index.js';
14
15
  import { IconButton } from '../../IconButton/index.js';
15
16
  import { Menu } from '../../Menu/Menu.js';
16
17
  import '../../Menu/MenuItem.js';
@@ -30,14 +31,16 @@ const OverflowMenu = /*#__PURE__*/React__default.forwardRef(function OverflowMen
30
31
  size = defaultSize,
31
32
  menuAlignment = 'bottom-start',
32
33
  tooltipAlignment,
34
+ menuTarget,
33
35
  ...rest
34
36
  } = _ref;
37
+ const enableFloatingStyles = useFeatureFlag('enable-v12-dynamic-floating-styles') || autoAlign;
35
38
  const {
36
39
  refs,
37
40
  floatingStyles,
38
41
  placement,
39
42
  middlewareData
40
- } = useFloating(autoAlign ? {
43
+ } = useFloating(enableFloatingStyles ? {
41
44
  // Computing the position starts with initial positioning
42
45
  // via `placement`.
43
46
  placement: menuAlignment,
@@ -49,14 +52,16 @@ const OverflowMenu = /*#__PURE__*/React__default.forwardRef(function OverflowMen
49
52
  // Middleware are executed as an in-between “middle” step of the
50
53
  // initial `placement` computation and eventual return of data for
51
54
  // rendering. Each middleware is executed in order.
52
- middleware: [flip({
55
+ middleware: [autoAlign && flip({
53
56
  // An explicit array of placements to try if the initial
54
57
  // `placement` doesn’t fit on the axes in which overflow
55
58
  // is checked.
56
59
  fallbackPlacements: menuAlignment.includes('bottom') ? ['bottom-start', 'bottom-end', 'top-start', 'top-end'] : ['top-start', 'top-end', 'bottom-start', 'bottom-end']
57
60
  })],
58
61
  whileElementsMounted: autoUpdate
59
- } : {} // When autoAlign is turned off, floating-ui will not be used
62
+ } : {}
63
+ // When autoAlign is turned off & the `enable-v12-dynamic-floating-styles` feature flag is not
64
+ // enabled, floating-ui will not be used
60
65
  );
61
66
  const id = useId('overflowmenu');
62
67
  const prefix = usePrefix();
@@ -70,21 +75,21 @@ const OverflowMenu = /*#__PURE__*/React__default.forwardRef(function OverflowMen
70
75
  handleClose
71
76
  } = useAttachedMenu(triggerRef);
72
77
  useEffect(() => {
73
- if (autoAlign) {
78
+ if (enableFloatingStyles) {
74
79
  Object.keys(floatingStyles).forEach(style => {
75
80
  if (refs.floating.current) {
76
81
  refs.floating.current.style[style] = floatingStyles[style];
77
82
  }
78
83
  });
79
84
  }
80
- }, [floatingStyles, autoAlign, refs.floating, open, placement, middlewareData]);
85
+ }, [floatingStyles, enableFloatingStyles, refs.floating, open, placement, middlewareData]);
81
86
  function handleTriggerClick() {
82
87
  if (triggerRef.current) {
83
88
  hookOnClick();
84
89
  }
85
90
  }
86
91
  const containerClasses = cx(className, `${prefix}--overflow-menu__container`, {
87
- [`${prefix}--autoalign`]: autoAlign
92
+ [`${prefix}--autoalign`]: enableFloatingStyles
88
93
  });
89
94
  const menuClasses = cx(`${prefix}--overflow-menu__${menuAlignment}`);
90
95
  const triggerClasses = cx(`${prefix}--overflow-menu`, {
@@ -115,12 +120,13 @@ const OverflowMenu = /*#__PURE__*/React__default.forwardRef(function OverflowMen
115
120
  className: menuClasses,
116
121
  id: id,
117
122
  size: size,
118
- legacyAutoalign: !autoAlign,
123
+ legacyAutoalign: !enableFloatingStyles,
119
124
  open: open,
120
125
  onClose: handleClose,
121
126
  x: x,
122
127
  y: y,
123
- label: label
128
+ label: label,
129
+ target: menuTarget
124
130
  }, children));
125
131
  });
126
132
  OverflowMenu.propTypes = {
@@ -156,7 +162,11 @@ OverflowMenu.propTypes = {
156
162
  /**
157
163
  * Specify how the trigger tooltip should be aligned.
158
164
  */
159
- tooltipAlignment: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right'])
165
+ tooltipAlignment: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right']),
166
+ /**
167
+ * Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
168
+ */
169
+ menuTarget: PropTypes.instanceOf(typeof Element !== 'undefined' ? Element : Object)
160
170
  };
161
171
 
162
172
  export { OverflowMenu };
@@ -213,7 +213,7 @@ const PaginationNav = /*#__PURE__*/React__default.forwardRef(function Pagination
213
213
  }
214
214
  function pageWouldBeHidden(page) {
215
215
  const startOffset = itemsDisplayedOnPage <= 4 && page > 1 ? 0 : 1;
216
- const wouldBeHiddenInFront = page >= startOffset && page <= cuts.front;
216
+ const wouldBeHiddenInFront = page >= startOffset && page <= cuts.front || page === 0;
217
217
  const wouldBeHiddenInBack = page >= totalItems - cuts.back - 1 && page <= totalItems - 2;
218
218
  return wouldBeHiddenInFront || wouldBeHiddenInBack;
219
219
  }