@carbon/react 1.89.0-rc.0 → 1.89.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 (63) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +1113 -851
  2. package/es/components/AILabel/index.d.ts +2 -5
  3. package/es/components/AILabel/index.js +2 -42
  4. package/es/components/ComposedModal/ComposedModal.js +2 -2
  5. package/es/components/Copy/Copy.js +1 -0
  6. package/es/components/DataTable/DataTable.js +10 -3
  7. package/es/components/Dialog/Dialog.d.ts +245 -0
  8. package/es/components/Dialog/Dialog.js +593 -0
  9. package/es/components/Dialog/index.d.ts +3 -251
  10. package/es/components/Dialog/index.js +1 -609
  11. package/es/components/FeatureFlags/index.d.ts +3 -1
  12. package/es/components/FeatureFlags/index.js +5 -2
  13. package/es/components/FileUploader/FileUploader.d.ts +28 -6
  14. package/es/components/FileUploader/FileUploader.js +152 -38
  15. package/es/components/Link/Link.js +15 -1
  16. package/es/components/Menu/MenuContext.d.ts +1 -1
  17. package/es/components/Menu/MenuContext.js +11 -4
  18. package/es/components/Menu/MenuItem.js +4 -10
  19. package/es/components/Modal/Modal.js +17 -9
  20. package/es/components/MultiSelect/FilterableMultiSelect.js +1 -5
  21. package/es/components/MultiSelect/MultiSelect.js +3 -7
  22. package/es/components/Popover/index.d.ts +4 -0
  23. package/es/components/Popover/index.js +8 -2
  24. package/es/components/StructuredList/StructuredList.d.ts +16 -0
  25. package/es/components/StructuredList/StructuredList.js +23 -11
  26. package/es/components/Toggletip/index.d.ts +13 -36
  27. package/es/components/Toggletip/index.js +12 -51
  28. package/es/index.d.ts +2 -1
  29. package/es/index.js +2 -0
  30. package/es/internal/Selection.js +1 -1
  31. package/es/internal/useMergedRefs.js +4 -3
  32. package/lib/components/AILabel/index.d.ts +2 -5
  33. package/lib/components/AILabel/index.js +1 -41
  34. package/lib/components/ComposedModal/ComposedModal.js +2 -2
  35. package/lib/components/Copy/Copy.js +1 -0
  36. package/lib/components/DataTable/DataTable.js +10 -3
  37. package/lib/components/Dialog/Dialog.d.ts +245 -0
  38. package/lib/components/Dialog/Dialog.js +602 -0
  39. package/lib/components/Dialog/index.d.ts +3 -251
  40. package/lib/components/Dialog/index.js +9 -614
  41. package/lib/components/FeatureFlags/index.d.ts +3 -1
  42. package/lib/components/FeatureFlags/index.js +5 -2
  43. package/lib/components/FileUploader/FileUploader.d.ts +28 -6
  44. package/lib/components/FileUploader/FileUploader.js +151 -37
  45. package/lib/components/Link/Link.js +15 -1
  46. package/lib/components/Menu/MenuContext.d.ts +1 -1
  47. package/lib/components/Menu/MenuContext.js +11 -4
  48. package/lib/components/Menu/MenuItem.js +4 -10
  49. package/lib/components/Modal/Modal.js +24 -16
  50. package/lib/components/MultiSelect/FilterableMultiSelect.js +1 -5
  51. package/lib/components/MultiSelect/MultiSelect.js +3 -7
  52. package/lib/components/Popover/index.d.ts +4 -0
  53. package/lib/components/Popover/index.js +8 -2
  54. package/lib/components/StructuredList/StructuredList.d.ts +16 -0
  55. package/lib/components/StructuredList/StructuredList.js +23 -11
  56. package/lib/components/Toggletip/index.d.ts +13 -36
  57. package/lib/components/Toggletip/index.js +11 -50
  58. package/lib/index.d.ts +2 -1
  59. package/lib/index.js +60 -58
  60. package/lib/internal/Selection.js +1 -1
  61. package/lib/internal/useMergedRefs.js +3 -2
  62. package/package.json +15 -16
  63. package/telemetry.yml +5 -2
@@ -5,6 +5,21 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import React, { type HTMLAttributes } from 'react';
8
+ interface FileItem {
9
+ name: string;
10
+ uuid: string;
11
+ file: File;
12
+ }
13
+ export interface FileChangeData {
14
+ addedFiles: FileItem[];
15
+ removedFiles: FileItem[];
16
+ currentFiles: FileItem[];
17
+ action: 'add' | 'remove' | 'clear';
18
+ }
19
+ export interface FileDeleteData {
20
+ deletedFile: FileItem;
21
+ remainingFiles: FileItem[];
22
+ }
8
23
  export interface FileUploaderProps extends HTMLAttributes<HTMLSpanElement> {
9
24
  /**
10
25
  * Specify the types of files that this input should be able to receive
@@ -52,20 +67,23 @@ export interface FileUploaderProps extends HTMLAttributes<HTMLSpanElement> {
52
67
  */
53
68
  name?: string;
54
69
  /**
55
- * Provide an optional `onChange` hook that is called each time the input is
56
- * changed
70
+ * Provide an optional `onChange` hook that is called each time the input is changed.
71
+ * When 'enable-enhanced-file-uploader' feature flag is enabled:
72
+ * - Also fires for file deletions and clearFiles operations
73
+ * - Event includes enhanced file information in event.target
57
74
  */
58
- onChange?: (event: any) => void;
75
+ onChange?: (event: any, data?: FileChangeData) => void;
59
76
  /**
60
77
  * Provide an optional `onClick` hook that is called each time the
61
78
  * FileUploader is clicked
62
79
  */
63
80
  onClick?: (event: any) => void;
64
81
  /**
65
- * Provide an optional `onDelete` hook that is called when an uploaded item
66
- * is removed
82
+ * Provide an optional `onDelete` hook that is called when an uploaded item is removed.
83
+ * When 'enable-enhanced-file-uploader' feature flag is enabled:
84
+ * - Event includes deleted file information in event.target
67
85
  */
68
- onDelete?: (event: any) => void;
86
+ onDelete?: (event: any, data?: FileDeleteData) => void;
69
87
  /**
70
88
  * Specify the size of the FileUploaderButton, from a list of available
71
89
  * sizes.
@@ -77,6 +95,10 @@ export interface FileUploaderHandle {
77
95
  * Clear internal state
78
96
  */
79
97
  clearFiles: () => void;
98
+ /**
99
+ * Get current files (only available when 'enable-enhanced-file-uploader' feature flag is enabled)
100
+ */
101
+ getCurrentFiles?: () => FileItem[];
80
102
  }
81
103
  declare const FileUploader: {
82
104
  <ItemType>(props: FileUploaderProps): React.ReactElement<any>;
@@ -21,6 +21,7 @@ var match = require('../../internal/keyboard/match.js');
21
21
  var usePrefix = require('../../internal/usePrefix.js');
22
22
  require('../Text/index.js');
23
23
  var useId = require('../../internal/useId.js');
24
+ var index = require('../FeatureFlags/index.js');
24
25
  var Text = require('../Text/Text.js');
25
26
 
26
27
  const FileUploader = /*#__PURE__*/React.forwardRef(({
@@ -42,45 +43,149 @@ const FileUploader = /*#__PURE__*/React.forwardRef(({
42
43
  ...other
43
44
  }, ref) => {
44
45
  const fileUploaderInstanceId = useId.useId('file-uploader');
45
- const [state, updateState] = React.useState({
46
- fileNames: []
47
- });
48
- const nodes = [];
49
46
  const prefix = usePrefix.usePrefix();
50
- const handleChange = evt => {
47
+ const enhancedFileUploaderEnabled = index.useFeatureFlag('enable-enhanced-file-uploader');
48
+ const [fileItems, setFileItems] = React.useState([]);
49
+ const [legacyFileNames, setLegacyFileNames] = React.useState([]);
50
+ const [fileObjects, setFileObjects] = React.useState(new Map());
51
+ const nodes = [];
52
+ const createFileItem = file => ({
53
+ name: file.name,
54
+ uuid: `${fileUploaderInstanceId}-${Date.now()}-${Array.from(crypto.getRandomValues(new Uint8Array(8))).map(b => b.toString(36)).join('')}`,
55
+ file
56
+ });
57
+ const handleChange = React.useCallback(evt => {
51
58
  evt.stopPropagation();
52
- const filenames = Array.prototype.map.call(evt.target.files, file => file.name);
53
- updateState(prevState => ({
54
- fileNames: multiple ? [...new Set([...prevState.fileNames, ...filenames])] : filenames
55
- }));
56
- if (onChange) {
57
- onChange(evt);
59
+ const newFiles = Array.from(evt.target.files);
60
+ if (enhancedFileUploaderEnabled) {
61
+ const newFileItems = newFiles.map(createFileItem);
62
+ let updatedFileItems;
63
+ if (multiple) {
64
+ const existingNames = new Set(fileItems.map(item => item.name));
65
+ const uniqueNewItems = newFileItems.filter(item => !existingNames.has(item.name));
66
+ updatedFileItems = [...fileItems, ...uniqueNewItems];
67
+ } else {
68
+ updatedFileItems = newFileItems;
69
+ }
70
+ setFileItems(updatedFileItems);
71
+ if (onChange) {
72
+ const allFiles = updatedFileItems.map(item => item.file);
73
+ const enhancedEvent = {
74
+ ...evt,
75
+ target: {
76
+ ...evt.target,
77
+ files: Object.assign(allFiles, {
78
+ item: index => allFiles[index] || null
79
+ }),
80
+ addedFiles: newFileItems,
81
+ currentFiles: updatedFileItems,
82
+ action: 'add'
83
+ }
84
+ };
85
+ onChange(enhancedEvent);
86
+ }
87
+ } else {
88
+ const filenames = newFiles.map(file => file.name);
89
+ const updatedFileNames = multiple ? [...new Set([...legacyFileNames, ...filenames])] : filenames;
90
+ setLegacyFileNames(updatedFileNames);
91
+ setFileObjects(prevMap => {
92
+ const newMap = multiple ? new Map(prevMap) : new Map();
93
+ newFiles.forEach(file => {
94
+ newMap.set(file.name, file);
95
+ });
96
+ return newMap;
97
+ });
98
+ if (onChange) {
99
+ onChange(evt);
100
+ }
58
101
  }
59
- };
60
- const handleClick = (evt, {
102
+ }, [enhancedFileUploaderEnabled, fileItems, legacyFileNames, multiple, onChange]);
103
+ const handleClick = React.useCallback((evt, {
61
104
  index,
62
105
  filenameStatus
63
106
  }) => {
64
107
  if (filenameStatus === 'edit') {
65
108
  evt.stopPropagation();
66
- const filteredArray = state.fileNames.filter(filename => filename !== nodes[index]?.innerText?.trim());
67
- updateState({
68
- fileNames: filteredArray
69
- });
70
- if (onDelete) {
71
- onDelete(evt);
72
- uploaderButton.current?.focus?.();
109
+ if (enhancedFileUploaderEnabled) {
110
+ const deletedItem = fileItems[index];
111
+ if (!deletedItem) return;
112
+ const remainingItems = fileItems.filter((_, i) => i !== index);
113
+ setFileItems(remainingItems);
114
+ const remainingFiles = remainingItems.map(item => item.file);
115
+ const enhancedEvent = {
116
+ ...evt,
117
+ target: {
118
+ ...evt.target,
119
+ files: Object.assign(remainingFiles, {
120
+ item: index => remainingFiles[index] || null
121
+ }),
122
+ deletedFile: deletedItem,
123
+ deletedFileName: deletedItem.name,
124
+ remainingFiles: remainingItems,
125
+ currentFiles: remainingItems,
126
+ action: 'remove'
127
+ }
128
+ };
129
+ if (onDelete) {
130
+ onDelete(enhancedEvent);
131
+ }
132
+ if (onChange) {
133
+ onChange(enhancedEvent);
134
+ }
135
+ } else {
136
+ const deletedFileName = legacyFileNames[index];
137
+ const filteredArray = legacyFileNames.filter(filename => filename !== deletedFileName);
138
+ setLegacyFileNames(filteredArray);
139
+
140
+ // Update File objects
141
+ setFileObjects(prevMap => {
142
+ const newMap = new Map(prevMap);
143
+ if (deletedFileName) {
144
+ newMap.delete(deletedFileName);
145
+ }
146
+ return newMap;
147
+ });
148
+ if (onDelete) {
149
+ onDelete(evt);
150
+ }
151
+ }
152
+ if (onClick) {
153
+ onClick(evt);
73
154
  }
74
- onClick?.(evt);
155
+ uploaderButton.current?.focus?.();
75
156
  }
76
- };
157
+ }, [enhancedFileUploaderEnabled, fileItems, legacyFileNames, onDelete, onChange, onClick]);
77
158
  React.useImperativeHandle(ref, () => ({
78
159
  clearFiles() {
79
- updateState({
80
- fileNames: []
81
- });
82
- }
83
- }));
160
+ if (enhancedFileUploaderEnabled) {
161
+ const previousItems = [...fileItems];
162
+ setFileItems([]);
163
+ if (onChange && previousItems.length > 0) {
164
+ const enhancedEvent = {
165
+ target: {
166
+ files: Object.assign([], {
167
+ item: () => null
168
+ }),
169
+ clearedFiles: previousItems,
170
+ currentFiles: [],
171
+ action: 'clear'
172
+ },
173
+ preventDefault: () => {},
174
+ stopPropagation: () => {}
175
+ };
176
+ onChange(enhancedEvent);
177
+ }
178
+ } else {
179
+ setLegacyFileNames([]);
180
+ setFileObjects(new Map());
181
+ }
182
+ },
183
+ ...(enhancedFileUploaderEnabled && {
184
+ getCurrentFiles() {
185
+ return [...fileItems];
186
+ }
187
+ })
188
+ }), [enhancedFileUploaderEnabled, fileItems, onChange]);
84
189
  const uploaderButton = /*#__PURE__*/React.createRef();
85
190
  const classes = cx({
86
191
  [`${prefix}--form-item`]: true,
@@ -93,6 +198,15 @@ const FileUploader = /*#__PURE__*/React.forwardRef(({
93
198
  [`${prefix}--file__selected-file--md`]: size === 'field' || size === 'md',
94
199
  [`${prefix}--file__selected-file--sm`]: size === 'small' || size === 'sm'
95
200
  });
201
+ const displayFiles = enhancedFileUploaderEnabled ? fileItems.map((item, index) => ({
202
+ name: item.name,
203
+ key: item.uuid,
204
+ index
205
+ })) : legacyFileNames.map((name, index) => ({
206
+ name,
207
+ key: index,
208
+ index
209
+ }));
96
210
  return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
97
211
  className: classes
98
212
  }, other), !labelTitle ? null : /*#__PURE__*/React.createElement(Text.Text, {
@@ -116,32 +230,32 @@ const FileUploader = /*#__PURE__*/React.forwardRef(({
116
230
  "aria-describedby": fileUploaderInstanceId
117
231
  }), /*#__PURE__*/React.createElement("div", {
118
232
  className: `${prefix}--file-container`
119
- }, state.fileNames.length === 0 ? null : state.fileNames.map((name, index) => /*#__PURE__*/React.createElement("span", _rollupPluginBabelHelpers.extends({
120
- key: index,
233
+ }, displayFiles.length === 0 ? null : displayFiles.map(file => /*#__PURE__*/React.createElement("span", _rollupPluginBabelHelpers.extends({
234
+ key: file.key,
121
235
  className: selectedFileClasses,
122
236
  ref: node => {
123
- nodes[index] = node;
124
- } // eslint-disable-line
237
+ nodes[file.index] = node;
238
+ }
125
239
  }, other), /*#__PURE__*/React.createElement(Text.Text, {
126
240
  as: "p",
127
241
  className: `${prefix}--file-filename`,
128
- id: name
129
- }, name), /*#__PURE__*/React.createElement("span", {
242
+ id: enhancedFileUploaderEnabled ? `${fileUploaderInstanceId}-file-${fileItems[file.index]?.uuid || file.index}` : `${fileUploaderInstanceId}-file-${file.index}`
243
+ }, file.name), /*#__PURE__*/React.createElement("span", {
130
244
  className: `${prefix}--file__state-container`
131
245
  }, /*#__PURE__*/React.createElement(Filename.default, {
132
- name: name,
246
+ name: file.name,
133
247
  iconDescription: iconDescription,
134
248
  status: filenameStatus,
135
249
  onKeyDown: evt => {
136
250
  if (match.matches(evt, [keys.Enter, keys.Space])) {
137
251
  handleClick(evt, {
138
- index,
252
+ index: file.index,
139
253
  filenameStatus
140
254
  });
141
255
  }
142
256
  },
143
257
  onClick: evt => handleClick(evt, {
144
- index,
258
+ index: file.index,
145
259
  filenameStatus
146
260
  })
147
261
  }))))));
@@ -211,7 +325,7 @@ FileUploader.propTypes = {
211
325
  * Specify the size of the FileUploaderButton, from a list of available
212
326
  * sizes.
213
327
  */
214
- size: PropTypes.oneOf(['sm', 'md', 'lg'])
328
+ size: PropTypes.oneOf(['sm', 'small', 'md', 'field', 'lg'])
215
329
  };
216
330
 
217
331
  exports.default = FileUploader;
@@ -52,9 +52,23 @@ const LinkBase = /*#__PURE__*/React.forwardRef(({
52
52
  linkProps['aria-disabled'] = true;
53
53
  }
54
54
  const BaseComponentAsAny = BaseComponent ?? 'a';
55
+ const handleOnClick = event => {
56
+ if (disabled) {
57
+ event.preventDefault();
58
+ event.stopPropagation();
59
+ } else {
60
+ // If the link is not disabled, we allow the onClick event to propagate
61
+ // so that any parent handlers can also respond to the click.
62
+ if (rest.onClick) {
63
+ rest.onClick(event);
64
+ }
65
+ }
66
+ };
55
67
  return /*#__PURE__*/React.createElement(BaseComponentAsAny, _rollupPluginBabelHelpers.extends({
56
68
  ref: ref
57
- }, linkProps, rest), children, !inline && Icon && /*#__PURE__*/React.createElement("div", {
69
+ }, linkProps, rest, {
70
+ onClick: handleOnClick
71
+ }), children, !inline && Icon && /*#__PURE__*/React.createElement("div", {
58
72
  className: `${prefix}--link__icon`
59
73
  }, /*#__PURE__*/React.createElement(Icon, null)));
60
74
  });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2023
2
+ * Copyright IBM Corp. 2023, 2025
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -30,10 +30,17 @@ function menuReducer(state, action) {
30
30
  hasSelectableItems: true
31
31
  };
32
32
  case 'registerItem':
33
- return {
34
- ...state,
35
- items: [...state.items, action.payload].filter(item => item.ref.current !== null)
36
- };
33
+ {
34
+ const newItem = action.payload;
35
+ const items = state.items.filter(item => item.ref.current);
36
+ const next = newItem.ref.current?.nextElementSibling;
37
+ const idx = items.findIndex(item => item.ref.current === next);
38
+ items.splice(idx < 0 ? items.length : idx, 0, newItem);
39
+ return {
40
+ ...state,
41
+ items
42
+ };
43
+ }
37
44
  }
38
45
  }
39
46
  const MenuContext = /*#__PURE__*/React.createContext({
@@ -51,7 +51,8 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem({
51
51
  middleware: [react.offset({
52
52
  mainAxis: -6,
53
53
  crossAxis: -6
54
- })]
54
+ })],
55
+ strategy: 'fixed'
55
56
  });
56
57
  const {
57
58
  getReferenceProps,
@@ -130,18 +131,11 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem({
130
131
  [`${prefix}--menu-item--disabled`]: isDisabled,
131
132
  [`${prefix}--menu-item--danger`]: isDanger
132
133
  });
133
- const [isFocusable, setIsFocusable] = React.useState(false);
134
+
134
135
  // on first render, register this menuitem in the context's state
135
136
  // (used for keyboard navigation)
136
137
  React.useEffect(() => {
137
138
  registerItem();
138
-
139
- // Detects if this is the first focusable item
140
- const currentItems = context.state.items;
141
- if (!disabled && menuItem.current && currentItems.length === 0) {
142
- setIsFocusable(true);
143
- }
144
-
145
139
  // eslint-disable-next-line react-hooks/exhaustive-deps
146
140
  }, []);
147
141
 
@@ -180,7 +174,7 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem({
180
174
  }, rest, {
181
175
  ref: ref,
182
176
  className: classNames,
183
- tabIndex: isFocusable ? 0 : -1,
177
+ tabIndex: !disabled ? 0 : -1,
184
178
  "aria-disabled": isDisabled ?? undefined,
185
179
  "aria-haspopup": hasChildren ?? undefined,
186
180
  "aria-expanded": hasChildren ? submenuOpen : undefined,
@@ -19,7 +19,7 @@ var Button = require('../Button/Button.js');
19
19
  require('../Button/Button.Skeleton.js');
20
20
  var ButtonSet = require('../ButtonSet/ButtonSet.js');
21
21
  var InlineLoading = require('../InlineLoading/InlineLoading.js');
22
- var index$4 = require('../Layer/index.js');
22
+ var index$3 = require('../Layer/index.js');
23
23
  var requiredIfGivenPropIsTruthy = require('../../prop-types/requiredIfGivenPropIsTruthy.js');
24
24
  var wrapFocus = require('../../internal/wrapFocus.js');
25
25
  var useIsomorphicEffect = require('../../internal/useIsomorphicEffect.js');
@@ -28,13 +28,13 @@ var usePrefix = require('../../internal/usePrefix.js');
28
28
  var usePreviousValue = require('../../internal/usePreviousValue.js');
29
29
  var keys = require('../../internal/keyboard/keys.js');
30
30
  var match = require('../../internal/keyboard/match.js');
31
- var index$3 = require('../IconButton/index.js');
31
+ var index$2 = require('../IconButton/index.js');
32
32
  var noopFn = require('../../internal/noopFn.js');
33
33
  require('../Text/index.js');
34
34
  var index = require('../FeatureFlags/index.js');
35
35
  var events = require('../../tools/events.js');
36
36
  var deprecate = require('../../prop-types/deprecate.js');
37
- var index$2 = require('../Dialog/index.js');
37
+ var Dialog = require('../Dialog/Dialog.js');
38
38
  var index$1 = require('../AILabel/index.js');
39
39
  var utils = require('../../internal/utils.js');
40
40
  var warning = require('../../internal/warning.js');
@@ -85,6 +85,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
85
85
  const innerModal = React.useRef(null);
86
86
  const startTrap = React.useRef(null);
87
87
  const endTrap = React.useRef(null);
88
+ const wrapFocusTimeout = React.useRef(null);
88
89
  const [isScrollable, setIsScrollable] = React.useState(false);
89
90
  const prevOpen = usePreviousValue.usePreviousValue(open);
90
91
  const modalInstanceId = `modal-${useId.useId()}`;
@@ -146,13 +147,20 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
146
147
  const {
147
148
  current: endTrapNode
148
149
  } = endTrap;
149
- wrapFocus.wrapFocus({
150
- bodyNode,
151
- startTrapNode,
152
- endTrapNode,
153
- currentActiveNode,
154
- oldActiveNode,
155
- selectorsFloatingMenus
150
+ // use setTimeout to ensure focus is set after all browser default focus behavior. Fixes issue of
151
+ // focus not wrapping in Firefox
152
+ wrapFocusTimeout.current = setTimeout(() => {
153
+ wrapFocus.wrapFocus({
154
+ bodyNode,
155
+ startTrapNode,
156
+ endTrapNode,
157
+ currentActiveNode,
158
+ oldActiveNode,
159
+ selectorsFloatingMenus
160
+ });
161
+ if (wrapFocusTimeout.current) {
162
+ clearTimeout(wrapFocusTimeout.current);
163
+ }
156
164
  });
157
165
  }
158
166
 
@@ -293,7 +301,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
293
301
  }) : null;
294
302
  const modalButton = /*#__PURE__*/React.createElement("div", {
295
303
  className: `${prefix}--modal-close-button`
296
- }, /*#__PURE__*/React.createElement(index$3.IconButton, {
304
+ }, /*#__PURE__*/React.createElement(index$2.IconButton, {
297
305
  className: modalCloseButtonClass,
298
306
  label: closeButtonLabel,
299
307
  onClick: onRequestClose,
@@ -310,7 +318,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
310
318
  // alertdialog is the only permitted aria role for a native dialog element
311
319
  // https://www.w3.org/TR/html-aria/#docconformance:~:text=Role%3A-,alertdialog,-.%20(dialog%20is
312
320
  const isAlertDialog = alert && !passiveModal;
313
- const modalBody = enableDialogElement ? /*#__PURE__*/React.createElement(index$2.unstable__Dialog, {
321
+ const modalBody = enableDialogElement ? /*#__PURE__*/React.createElement(Dialog.Dialog, {
314
322
  open: open,
315
323
  focusAfterCloseRef: launcherButtonRef,
316
324
  modal: true,
@@ -333,7 +341,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
333
341
  className: `${prefix}--modal--inner__decorator`
334
342
  }, normalizedDecorator) : '', /*#__PURE__*/React.createElement("div", {
335
343
  className: `${prefix}--modal-close-button`
336
- }, /*#__PURE__*/React.createElement(index$3.IconButton, {
344
+ }, /*#__PURE__*/React.createElement(index$2.IconButton, {
337
345
  className: modalCloseButtonClass,
338
346
  label: closeButtonLabel,
339
347
  onClick: onRequestClose,
@@ -345,7 +353,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
345
353
  "aria-hidden": "true",
346
354
  tabIndex: "-1",
347
355
  className: `${modalCloseButtonClass}__icon`
348
- })))), /*#__PURE__*/React.createElement(index$4.Layer, _rollupPluginBabelHelpers.extends({
356
+ })))), /*#__PURE__*/React.createElement(index$3.Layer, _rollupPluginBabelHelpers.extends({
349
357
  ref: contentRef,
350
358
  id: modalBodyId,
351
359
  className: contentClasses
@@ -401,7 +409,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
401
409
  className: `${prefix}--modal-header__heading`
402
410
  }, modalHeading), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React.createElement("div", {
403
411
  className: `${prefix}--modal--inner__decorator`
404
- }, normalizedDecorator) : '', !passiveModal && modalButton), /*#__PURE__*/React.createElement(index$4.Layer, _rollupPluginBabelHelpers.extends({
412
+ }, normalizedDecorator) : '', !passiveModal && modalButton), /*#__PURE__*/React.createElement(index$3.Layer, _rollupPluginBabelHelpers.extends({
405
413
  ref: contentRef,
406
414
  id: modalBodyId,
407
415
  className: contentClasses
@@ -438,7 +446,7 @@ const Modal = /*#__PURE__*/React.forwardRef(function Modal({
438
446
  role: "link",
439
447
  className: `${prefix}--visually-hidden`
440
448
  }, "Focus sentinel"));
441
- return /*#__PURE__*/React.createElement(index$4.Layer, _rollupPluginBabelHelpers.extends({}, rest, {
449
+ return /*#__PURE__*/React.createElement(index$3.Layer, _rollupPluginBabelHelpers.extends({}, rest, {
442
450
  level: 0,
443
451
  onKeyDown: handleKeyDown,
444
452
  onClick: events.composeEventHandlers([rest?.onClick, handleOnClick]),
@@ -124,11 +124,7 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
124
124
  inputValue
125
125
  }), [items, inputValue, itemToString$1, filterItems]);
126
126
  const nonSelectAllItems = React.useMemo(() => filteredItems.filter(item => !item.isSelectAll), [filteredItems]);
127
- let selectAll = filteredItems.some(item => item.isSelectAll);
128
- if ((selected ?? []).length > 0 && selectAll) {
129
- console.warn('Warning: `selectAll` should not be used when `selectedItems` is provided. Please pass either `selectAll` or `selectedItems`, not both.');
130
- selectAll = false;
131
- }
127
+ const selectAll = filteredItems.some(item => item.isSelectAll);
132
128
  const {
133
129
  selectedItems: controlledSelectedItems,
134
130
  onItemChange,
@@ -113,11 +113,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
113
113
  return true; // Return true if item is not an object with undefined values
114
114
  });
115
115
  }, [items]);
116
- let selectAll = filteredItems.some(item => item.isSelectAll);
117
- if ((selected ?? []).length > 0 && selectAll) {
118
- console.warn('Warning: `selectAll` should not be used when `selectedItems` is provided. Please pass either `selectAll` or `selectedItems`, not both.');
119
- selectAll = false;
120
- }
116
+ const selectAll = filteredItems.some(item => item.isSelectAll);
121
117
  const prefix = usePrefix.usePrefix();
122
118
  const {
123
119
  isFluid
@@ -491,13 +487,13 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
491
487
  })), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React.createElement("div", {
492
488
  className: `${prefix}--list-box__inner-wrapper--decorator`
493
489
  }, normalizedDecorator) : ''), /*#__PURE__*/React.createElement(index$2.default.Menu, menuProps, isOpen && sortItems(filteredItems, sortOptions).map((item, index) => {
494
- const isChecked = selectedItems.filter(selected => isEqual(selected, item)).length > 0;
495
490
  const {
496
491
  hasIndividualSelections,
497
492
  nonSelectAllSelectedCount,
498
493
  totalSelectableCount
499
494
  } = getSelectionStats(selectedItems, filteredItems);
500
- const isIndeterminate = item['isSelectAll'] && hasIndividualSelections && nonSelectAllSelectedCount < totalSelectableCount;
495
+ const isChecked = item.isSelectAll ? nonSelectAllSelectedCount === totalSelectableCount && totalSelectableCount > 0 : selectedItems.some(selected => isEqual(selected, item));
496
+ const isIndeterminate = item.isSelectAll && hasIndividualSelections && nonSelectAllSelectedCount < totalSelectableCount;
501
497
  const itemProps = getItemProps({
502
498
  item,
503
499
  // we don't want Downshift to set aria-selected for us
@@ -25,6 +25,10 @@ export interface PopoverBaseProps {
25
25
  * Specify how the popover should align with the trigger element.
26
26
  */
27
27
  align?: PopoverAlignment;
28
+ /**
29
+ * **Experimental:** Provide an offset value for alignment axis. Only takes effect when `autoalign` is enabled.
30
+ */
31
+ alignmentAxisOffset?: number;
28
32
  /**
29
33
  * Will auto-align the popover on first render if it is not visible. This prop
30
34
  * is currently experimental and is subject to future changes. Requires
@@ -19,7 +19,6 @@ var useEvent = require('../../internal/useEvent.js');
19
19
  var mapPopoverAlign = require('../../tools/mapPopoverAlign.js');
20
20
  var react = require('@floating-ui/react');
21
21
  var index = require('../FeatureFlags/index.js');
22
- var index$1 = require('../Toggletip/index.js');
23
22
 
24
23
  const PopoverContext = /*#__PURE__*/React.createContext({
25
24
  setFloating: {
@@ -64,7 +63,10 @@ forwardRef) {
64
63
  // The `Popover` should close whenever it and its children loses focus
65
64
  useEvent.useEvent(popover, 'focusout', event => {
66
65
  const relatedTarget = event.relatedTarget;
66
+
67
+ // No relatedTarget, focus moved to nowhere, so close the popover
67
68
  if (!relatedTarget) {
69
+ onRequestClose?.();
68
70
  return;
69
71
  }
70
72
  const isOutsideMainContainer = !popover.current?.contains(relatedTarget);
@@ -237,7 +239,7 @@ forwardRef) {
237
239
  // For a toggletip there is a specific trigger component, ToggletipButton.
238
240
  // In either of these cases we want to set this as the reference node for floating-ui autoAlign
239
241
  // positioning.
240
- if (enableFloatingStyles && item?.type !== PopoverContent || enableFloatingStyles && item?.type === index$1.ToggletipButton) {
242
+ if (enableFloatingStyles && item?.type !== PopoverContent || enableFloatingStyles && item?.type['displayName'] === 'ToggletipButton') {
241
243
  // Set the reference element for floating-ui
242
244
  refs.setReference(node);
243
245
  }
@@ -294,6 +296,10 @@ Popover.propTypes = {
294
296
 
295
297
  // new values to match floating-ui
296
298
  'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']), ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'], mapPopoverAlign.mapPopoverAlign),
299
+ /**
300
+ * **Experimental:** Provide an offset value for alignment axis. Only takes effect when `autoalign` is enabled.
301
+ */
302
+ alignmentAxisOffset: PropTypes.number,
297
303
  /**
298
304
  * Provide a custom element or component to render the top-level node for the
299
305
  * component.
@@ -32,6 +32,10 @@ export interface StructuredListWrapperProps extends DivAttrs {
32
32
  * Specify whether your StructuredListWrapper should have selections
33
33
  */
34
34
  selection?: boolean;
35
+ /**
36
+ * Specify which row will be selected initially
37
+ */
38
+ selectedInitialRow?: string;
35
39
  }
36
40
  export declare function StructuredListWrapper(props: StructuredListWrapperProps): import("react/jsx-runtime").JSX.Element;
37
41
  export declare namespace StructuredListWrapper {
@@ -65,6 +69,10 @@ export declare namespace StructuredListWrapper {
65
69
  * Specify whether your StructuredListWrapper should have selections
66
70
  */
67
71
  selection: PropTypes.Requireable<boolean>;
72
+ /**
73
+ * Specify which row will be selected initially
74
+ */
75
+ selectedInitialRow: PropTypes.Requireable<string>;
68
76
  };
69
77
  }
70
78
  export interface StructuredListHeadProps extends DivAttrs {
@@ -148,6 +156,10 @@ export interface StructuredListRowProps extends DivAttrs {
148
156
  * Mark if this row should be selectable
149
157
  */
150
158
  selection?: boolean;
159
+ /**
160
+ * Specify row id so that it can be used for initial selection
161
+ */
162
+ id?: string;
151
163
  }
152
164
  export declare function StructuredListRow(props: StructuredListRowProps): import("react/jsx-runtime").JSX.Element;
153
165
  export declare namespace StructuredListRow {
@@ -180,6 +192,10 @@ export declare namespace StructuredListRow {
180
192
  * Mark if this row should be selectable
181
193
  */
182
194
  selection: PropTypes.Requireable<boolean>;
195
+ /**
196
+ * Specify row id so that it can be used for initial selection
197
+ */
198
+ id: PropTypes.Requireable<string>;
183
199
  };
184
200
  }
185
201
  export interface StructuredListInputProps extends DivAttrs {