@carbon/react 1.68.0 → 1.69.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 (94) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +871 -871
  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/Checkbox/Checkbox.js +1 -1
  6. package/es/components/CheckboxGroup/CheckboxGroup.js +1 -2
  7. package/es/components/CheckboxGroup/index.d.ts +10 -0
  8. package/es/components/ComboBox/ComboBox.js +13 -18
  9. package/es/components/ComboButton/index.js +10 -3
  10. package/es/components/DataTable/TableCell.d.ts +1 -4
  11. package/es/components/DataTable/TableCell.js +3 -2
  12. package/es/components/Disclosure/index.d.ts +18 -0
  13. package/es/components/Dropdown/Dropdown.js +11 -9
  14. package/es/components/FileUploader/FileUploader.d.ts +8 -92
  15. package/es/components/FileUploader/FileUploader.js +116 -137
  16. package/es/components/Grid/CSSGrid.js +8 -1
  17. package/es/components/Grid/Grid.js +4 -0
  18. package/es/components/IdPrefix/index.d.ts +26 -0
  19. package/es/components/ListBox/next/ListBoxSelection.d.ts +9 -1
  20. package/es/components/ListBox/next/ListBoxSelection.js +12 -5
  21. package/es/components/Menu/MenuItem.js +1 -4
  22. package/es/components/MenuButton/index.d.ts +4 -0
  23. package/es/components/MenuButton/index.js +19 -5
  24. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +4 -0
  25. package/es/components/MultiSelect/FilterableMultiSelect.js +32 -6
  26. package/es/components/MultiSelect/MultiSelect.js +11 -9
  27. package/es/components/OverflowMenu/next/index.d.ts +4 -0
  28. package/es/components/OverflowMenu/next/index.js +19 -9
  29. package/es/components/PaginationNav/PaginationNav.js +1 -1
  30. package/es/components/Popover/index.js +18 -14
  31. package/es/components/Portal/index.d.ts +25 -0
  32. package/es/components/Slider/Slider.js +2 -2
  33. package/es/components/Tabs/Tabs.js +46 -20
  34. package/es/components/Tag/DismissibleTag.js +2 -2
  35. package/es/components/Tag/OperationalTag.d.ts +2 -10
  36. package/es/components/Tag/OperationalTag.js +2 -14
  37. package/es/components/Tag/SelectableTag.d.ts +18 -10
  38. package/es/components/Tag/SelectableTag.js +22 -28
  39. package/es/components/Toggle/Toggle.js +2 -0
  40. package/es/components/ToggleSmall/ToggleSmall.Skeleton.d.ts +49 -0
  41. package/es/components/ToggleSmall/index.d.ts +7 -0
  42. package/es/components/TreeView/TreeNode.js +4 -2
  43. package/es/components/TreeView/TreeView.js +4 -4
  44. package/es/components/UIShell/SideNavMenuItem.d.ts +4 -3
  45. package/es/components/UIShell/SideNavMenuItem.js +1 -4
  46. package/es/index.js +1 -1
  47. package/es/internal/useIdPrefix.d.ts +9 -0
  48. package/lib/components/Accordion/AccordionItem.js +0 -1
  49. package/lib/components/Button/Button.js +6 -0
  50. package/lib/components/Checkbox/Checkbox.js +1 -1
  51. package/lib/components/CheckboxGroup/CheckboxGroup.js +1 -2
  52. package/lib/components/CheckboxGroup/index.d.ts +10 -0
  53. package/lib/components/ComboBox/ComboBox.js +18 -23
  54. package/lib/components/ComboButton/index.js +12 -5
  55. package/lib/components/DataTable/TableCell.d.ts +1 -4
  56. package/lib/components/DataTable/TableCell.js +3 -2
  57. package/lib/components/Disclosure/index.d.ts +18 -0
  58. package/lib/components/Dropdown/Dropdown.js +18 -16
  59. package/lib/components/FileUploader/FileUploader.d.ts +8 -92
  60. package/lib/components/FileUploader/FileUploader.js +113 -134
  61. package/lib/components/Grid/CSSGrid.js +8 -1
  62. package/lib/components/Grid/Grid.js +4 -0
  63. package/lib/components/IdPrefix/index.d.ts +26 -0
  64. package/lib/components/ListBox/next/ListBoxSelection.d.ts +9 -1
  65. package/lib/components/ListBox/next/ListBoxSelection.js +12 -5
  66. package/lib/components/Menu/MenuItem.js +1 -4
  67. package/lib/components/MenuButton/index.d.ts +4 -0
  68. package/lib/components/MenuButton/index.js +19 -5
  69. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +4 -0
  70. package/lib/components/MultiSelect/FilterableMultiSelect.js +32 -6
  71. package/lib/components/MultiSelect/MultiSelect.js +18 -16
  72. package/lib/components/OverflowMenu/next/index.d.ts +4 -0
  73. package/lib/components/OverflowMenu/next/index.js +21 -11
  74. package/lib/components/PaginationNav/PaginationNav.js +1 -1
  75. package/lib/components/Popover/index.js +18 -14
  76. package/lib/components/Portal/index.d.ts +25 -0
  77. package/lib/components/Slider/Slider.js +2 -2
  78. package/lib/components/Tabs/Tabs.js +46 -20
  79. package/lib/components/Tag/DismissibleTag.js +2 -2
  80. package/lib/components/Tag/OperationalTag.d.ts +2 -10
  81. package/lib/components/Tag/OperationalTag.js +2 -14
  82. package/lib/components/Tag/SelectableTag.d.ts +18 -10
  83. package/lib/components/Tag/SelectableTag.js +22 -28
  84. package/lib/components/Toggle/Toggle.js +2 -0
  85. package/lib/components/ToggleSmall/ToggleSmall.Skeleton.d.ts +49 -0
  86. package/lib/components/ToggleSmall/index.d.ts +7 -0
  87. package/lib/components/TreeView/TreeNode.js +4 -2
  88. package/lib/components/TreeView/TreeView.js +4 -4
  89. package/lib/components/UIShell/SideNavMenuItem.d.ts +4 -3
  90. package/lib/components/UIShell/SideNavMenuItem.js +1 -4
  91. package/lib/index.js +2 -2
  92. package/lib/internal/useIdPrefix.d.ts +9 -0
  93. package/package.json +10 -9
  94. 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 };
@@ -14,6 +14,7 @@ import { useGridSettings, GridSettings } from './GridContext.js';
14
14
 
15
15
  function CSSGrid(_ref) {
16
16
  let {
17
+ align,
17
18
  as: BaseComponent = 'div',
18
19
  children,
19
20
  className: customClassName,
@@ -46,7 +47,9 @@ function CSSGrid(_ref) {
46
47
  [`${prefix}--css-grid`]: true,
47
48
  [`${prefix}--css-grid--condensed`]: mode === 'condensed',
48
49
  [`${prefix}--css-grid--narrow`]: mode === 'narrow',
49
- [`${prefix}--css-grid--full-width`]: fullWidth
50
+ [`${prefix}--css-grid--full-width`]: fullWidth,
51
+ [`${prefix}--css-grid--start`]: align === 'start',
52
+ [`${prefix}--css-grid--end`]: align === 'end'
50
53
  });
51
54
 
52
55
  // cast as any to let TypeScript allow passing in attributes to base component
@@ -59,6 +62,10 @@ function CSSGrid(_ref) {
59
62
  }, rest), children));
60
63
  }
61
64
  CSSGrid.propTypes = {
65
+ /**
66
+ * Specify grid aligment. Default is center
67
+ */
68
+ align: PropTypes.oneOf(['start', 'center', 'end']),
62
69
  /**
63
70
  * Provide a custom element to render instead of the default <div>
64
71
  */
@@ -19,6 +19,10 @@ function Grid(props) {
19
19
  return /*#__PURE__*/React__default.createElement(FlexGridComponent, props);
20
20
  }
21
21
  Grid.propTypes = {
22
+ /**
23
+ * Specify grid aligment. Default is center
24
+ */
25
+ align: PropTypes.oneOf(['start', 'center', 'end']),
22
26
  /**
23
27
  * Provide a custom element to render instead of the default <div>
24
28
  */
@@ -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 };
@@ -37,6 +37,10 @@ export interface ListBoxSelectionProps {
37
37
  * Specify whether or not the clear selection element should be disabled
38
38
  */
39
39
  disabled?: boolean;
40
+ /**
41
+ * Whether or not the listbox is readonly
42
+ */
43
+ readOnly?: boolean;
40
44
  /**
41
45
  * Specify an optional `onClearSelection` handler that is called when the underlying
42
46
  * element is cleared
@@ -58,7 +62,7 @@ export interface ListBoxSelectionProps {
58
62
  */
59
63
  onMouseUp?: React.MouseEventHandler<HTMLButtonElement>;
60
64
  }
61
- declare function ListBoxSelection({ clearSelection, selectionCount, translateWithId: t, disabled, onClearSelection, ...rest }: ListBoxSelectionProps): import("react/jsx-runtime").JSX.Element;
65
+ declare function ListBoxSelection({ clearSelection, selectionCount, translateWithId: t, disabled, readOnly, onClearSelection, ...rest }: ListBoxSelectionProps): import("react/jsx-runtime").JSX.Element;
62
66
  declare namespace ListBoxSelection {
63
67
  var propTypes: {
64
68
  /**
@@ -70,6 +74,10 @@ declare namespace ListBoxSelection {
70
74
  * Specify whether or not the clear selection element should be disabled
71
75
  */
72
76
  disabled: PropTypes.Requireable<boolean>;
77
+ /**
78
+ * Whether or not the listbox is readonly
79
+ */
80
+ readOnly: PropTypes.Requireable<boolean>;
73
81
  /**
74
82
  * Specify an optional `onClearSelection` handler that is called when the underlying
75
83
  * element is cleared
@@ -26,6 +26,7 @@ function ListBoxSelection(_ref) {
26
26
  selectionCount,
27
27
  translateWithId: t = defaultTranslateWithId,
28
28
  disabled,
29
+ readOnly,
29
30
  onClearSelection,
30
31
  ...rest
31
32
  } = _ref;
@@ -40,7 +41,7 @@ function ListBoxSelection(_ref) {
40
41
  });
41
42
  function onClick(event) {
42
43
  event.stopPropagation();
43
- if (disabled) {
44
+ if (disabled || readOnly) {
44
45
  return;
45
46
  }
46
47
  clearSelection(event);
@@ -57,21 +58,23 @@ function ListBoxSelection(_ref) {
57
58
  }, selectionCount), /*#__PURE__*/React__default.createElement("button", {
58
59
  "aria-label": description,
59
60
  className: `${prefix}--tag__close-icon`,
60
- disabled: disabled,
61
+ disabled: disabled || readOnly,
61
62
  onClick: onClick,
62
63
  tabIndex: -1,
63
64
  title: description,
64
- type: "button"
65
+ type: "button",
66
+ "aria-disabled": readOnly ? true : undefined
65
67
  }, _Close || (_Close = /*#__PURE__*/React__default.createElement(Close, null))));
66
68
  }
67
69
  return /*#__PURE__*/React__default.createElement("button", _extends({}, rest, {
68
70
  "aria-label": description,
69
71
  className: className,
70
- disabled: disabled,
72
+ disabled: disabled || readOnly,
71
73
  onClick: onClick,
72
74
  tabIndex: -1,
73
75
  title: description,
74
- type: "button"
76
+ type: "button",
77
+ "aria-disabled": readOnly ? true : undefined
75
78
  }), _Close2 || (_Close2 = /*#__PURE__*/React__default.createElement(Close, null)));
76
79
  }
77
80
  ListBoxSelection.propTypes = {
@@ -84,6 +87,10 @@ ListBoxSelection.propTypes = {
84
87
  * Specify whether or not the clear selection element should be disabled
85
88
  */
86
89
  disabled: PropTypes.bool,
90
+ /**
91
+ * Whether or not the listbox is readonly
92
+ */
93
+ readOnly: PropTypes.bool,
87
94
  /**
88
95
  * Specify an optional `onClearSelection` handler that is called when the underlying
89
96
  * element is cleared
@@ -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 };
@@ -143,6 +143,10 @@ export interface FilterableMultiSelectProps<ItemType> extends MultiSelectSorting
143
143
  * what this field is for
144
144
  */
145
145
  placeholder?: string;
146
+ /**
147
+ * Whether or not the filterable multiselect is readonly
148
+ */
149
+ readOnly?: boolean;
146
150
  /**
147
151
  * Specify feedback (mode) of the selection.
148
152
  * `top`: selected item jumps to top
@@ -90,6 +90,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
90
90
  onChange,
91
91
  onMenuChange,
92
92
  placeholder,
93
+ readOnly,
93
94
  titleText,
94
95
  type,
95
96
  selectionFeedback = 'top-after-reopen',
@@ -232,9 +233,11 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
232
233
  }
233
234
  };
234
235
  function handleMenuChange(forceIsOpen) {
235
- const nextIsOpen = forceIsOpen ?? !isOpen;
236
- setIsOpen(nextIsOpen);
237
- validateHighlightFocus();
236
+ if (!readOnly) {
237
+ const nextIsOpen = forceIsOpen ?? !isOpen;
238
+ setIsOpen(nextIsOpen);
239
+ validateHighlightFocus();
240
+ }
238
241
  }
239
242
  useEffect(() => {
240
243
  onMenuChange?.(isOpen);
@@ -423,7 +426,8 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
423
426
  [`${prefix}--multi-select--open`]: isOpen,
424
427
  [`${prefix}--multi-select--inline`]: inline,
425
428
  [`${prefix}--multi-select--selected`]: controlledSelectedItems?.length > 0,
426
- [`${prefix}--multi-select--filterable--input-focused`]: inputFocused
429
+ [`${prefix}--multi-select--filterable--input-focused`]: inputFocused,
430
+ [`${prefix}--multi-select--readonly`]: readOnly
427
431
  });
428
432
  const labelProps = getLabelProps();
429
433
  const buttonProps = getToggleButtonProps({
@@ -510,6 +514,24 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
510
514
  setIsFocused(evt?.type === 'focus' ? true : false);
511
515
  }
512
516
  };
517
+ const mergedRef = mergeRefs(textInput, inputProps.ref);
518
+ const readOnlyEventHandlers = readOnly ? {
519
+ onClick: evt => {
520
+ // NOTE: does not prevent click
521
+ evt.preventDefault();
522
+ // focus on the element as per readonly input behavior
523
+ if (mergedRef.current !== undefined) {
524
+ mergedRef.current.focus();
525
+ }
526
+ },
527
+ onKeyDown: evt => {
528
+ const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
529
+ // This prevents the select from opening for the above keys
530
+ if (selectAccessKeys.includes(evt.key)) {
531
+ evt.preventDefault();
532
+ }
533
+ }
534
+ } : {};
513
535
  const clearSelectionContent = controlledSelectedItems.length > 0 ? /*#__PURE__*/React__default.createElement("span", {
514
536
  className: `${prefix}--visually-hidden`
515
537
  }, clearSelectionDescription, " ", controlledSelectedItems.length, ",", clearSelectionText) : /*#__PURE__*/React__default.createElement("span", {
@@ -533,12 +555,13 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
533
555
  invalidText: invalidText,
534
556
  warn: warn,
535
557
  warnText: warnText,
536
- isOpen: isOpen,
558
+ isOpen: !readOnly && isOpen,
537
559
  size: size$1
538
560
  }, /*#__PURE__*/React__default.createElement("div", {
539
561
  className: `${prefix}--list-box__field`,
540
562
  ref: autoAlign ? refs.setReference : null
541
563
  }, controlledSelectedItems.length > 0 && /*#__PURE__*/React__default.createElement(ListBoxSelection, {
564
+ readOnly: readOnly,
542
565
  clearSelection: () => {
543
566
  clearSelection();
544
567
  if (textInput.current) {
@@ -551,7 +574,9 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
551
574
  }), /*#__PURE__*/React__default.createElement("input", _extends({
552
575
  className: inputClasses
553
576
  }, inputProps, {
554
- ref: mergeRefs(textInput, inputProps.ref)
577
+ ref: mergedRef
578
+ }, readOnlyEventHandlers, {
579
+ readOnly: readOnly
555
580
  })), invalid && /*#__PURE__*/React__default.createElement(WarningFilled, {
556
581
  className: `${prefix}--list-box__invalid-icon`
557
582
  }), showWarning && /*#__PURE__*/React__default.createElement(WarningAltFilled, {
@@ -560,6 +585,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
560
585
  clearSelection: clearInputValue,
561
586
  disabled: disabled,
562
587
  translateWithId: translateWithId,
588
+ readOnly: readOnly,
563
589
  onMouseUp: event => {
564
590
  // If we do not stop this event from propagating,
565
591
  // it seems like Downshift takes our event and