@carbon/react 1.78.1 → 1.78.2

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 (217) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +764 -764
  2. package/es/components/Accordion/AccordionItem.js +2 -2
  3. package/es/components/Button/Button.d.ts +3 -2
  4. package/es/components/Button/Button.js +2 -1
  5. package/es/components/Button/ButtonBase.js +1 -1
  6. package/es/components/ChatButton/ChatButton.d.ts +3 -2
  7. package/es/components/ChatButton/ChatButton.js +2 -1
  8. package/es/components/ComboBox/ComboBox.js +24 -34
  9. package/es/components/ComposedModal/ComposedModal.js +51 -65
  10. package/es/components/ContainedList/ContainedListItem/ContainedListItem.d.ts +2 -2
  11. package/es/components/ContainedList/ContainedListItem/ContainedListItem.js +1 -1
  12. package/es/components/ContentSwitcher/ContentSwitcher.js +3 -3
  13. package/es/components/DataTable/TableBatchAction.d.ts +3 -3
  14. package/es/components/DataTable/TableBatchAction.js +1 -1
  15. package/es/components/DataTable/TableContainer.d.ts +1 -1
  16. package/es/components/DataTable/TableContainer.js +3 -3
  17. package/es/components/DataTable/TableExpandHeader.d.ts +5 -6
  18. package/es/components/DataTable/TableToolbarMenu.d.ts +2 -2
  19. package/es/components/DataTable/TableToolbarMenu.js +1 -1
  20. package/es/components/DatePicker/DatePicker.js +2 -2
  21. package/es/components/DatePicker/plugins/fixEventsPlugin.js +1 -1
  22. package/es/components/Dialog/index.d.ts +4 -42
  23. package/es/components/ExpandableSearch/ExpandableSearch.js +2 -2
  24. package/es/components/FeatureFlags/index.d.ts +1 -3
  25. package/es/components/FeatureFlags/index.js +0 -3
  26. package/es/components/FileUploader/FileUploader.d.ts +1 -1
  27. package/es/components/FileUploader/FileUploader.js +2 -2
  28. package/es/components/FileUploader/FileUploaderButton.js +2 -2
  29. package/es/components/FileUploader/FileUploaderDropContainer.d.ts +1 -1
  30. package/es/components/FileUploader/FileUploaderDropContainer.js +4 -6
  31. package/es/components/FileUploader/FileUploaderItem.d.ts +1 -1
  32. package/es/components/FileUploader/FileUploaderItem.js +2 -2
  33. package/es/components/Grid/CSSGrid.js +14 -18
  34. package/es/components/Grid/FlexGrid.js +6 -7
  35. package/es/components/Grid/GridTypes.d.ts +3 -5
  36. package/es/components/IconButton/index.js +3 -3
  37. package/es/components/Layer/index.d.ts +6 -4
  38. package/es/components/Layer/index.js +6 -5
  39. package/es/components/Link/Link.d.ts +3 -2
  40. package/es/components/Link/Link.js +2 -1
  41. package/es/components/ListBox/ListBoxMenuItem.d.ts +3 -3
  42. package/es/components/ListBox/ListBoxMenuItem.js +15 -37
  43. package/es/components/Menu/Menu.js +2 -2
  44. package/es/components/Menu/MenuItem.d.ts +2 -2
  45. package/es/components/Menu/MenuItem.js +3 -3
  46. package/es/components/Modal/Modal.js +49 -121
  47. package/es/components/Modal/next/index.d.ts +171 -0
  48. package/es/components/ModalWrapper/ModalWrapper.js +1 -1
  49. package/es/components/MultiSelect/FilterableMultiSelect.js +3 -3
  50. package/es/components/MultiSelect/MultiSelect.js +2 -2
  51. package/es/components/Notification/Notification.d.ts +13 -5
  52. package/es/components/Notification/Notification.js +4 -3
  53. package/es/components/OverflowMenu/OverflowMenu.d.ts +8 -4
  54. package/es/components/OverflowMenu/OverflowMenu.js +3 -3
  55. package/es/components/OverflowMenu/next/index.d.ts +2 -2
  56. package/es/components/OverflowMenu/next/index.js +1 -1
  57. package/es/components/OverflowMenuItem/OverflowMenuItem.js +2 -2
  58. package/es/components/ProgressIndicator/ProgressIndicator.js +2 -2
  59. package/es/components/RadioTile/RadioTile.js +2 -2
  60. package/es/components/Search/Search.d.ts +3 -2
  61. package/es/components/Search/Search.js +6 -4
  62. package/es/components/Slider/Slider.d.ts +15 -16
  63. package/es/components/Slider/Slider.js +22 -22
  64. package/es/components/Tabs/Tabs.d.ts +6 -3
  65. package/es/components/Tabs/Tabs.js +9 -8
  66. package/es/components/Tag/DismissibleTag.d.ts +5 -3
  67. package/es/components/Tag/DismissibleTag.js +2 -1
  68. package/es/components/Tag/OperationalTag.d.ts +3 -2
  69. package/es/components/Tag/OperationalTag.js +2 -1
  70. package/es/components/Tag/SelectableTag.d.ts +5 -3
  71. package/es/components/Tag/SelectableTag.js +2 -1
  72. package/es/components/Tag/Tag.d.ts +3 -2
  73. package/es/components/Tag/Tag.js +2 -1
  74. package/es/components/Tile/Tile.d.ts +5 -3
  75. package/es/components/Tile/Tile.js +6 -8
  76. package/es/components/Toggletip/index.js +2 -2
  77. package/es/components/Tooltip/DefinitionTooltip.js +2 -2
  78. package/es/components/Tooltip/Tooltip.d.ts +1 -1
  79. package/es/components/Tooltip/Tooltip.js +2 -2
  80. package/es/components/TreeView/TreeNode.d.ts +5 -3
  81. package/es/components/TreeView/TreeNode.js +4 -3
  82. package/es/components/TreeView/TreeView.js +2 -2
  83. package/es/components/UIShell/HeaderContainer.js +2 -2
  84. package/es/components/UIShell/HeaderMenu.js +2 -2
  85. package/es/components/UIShell/HeaderPanel.js +2 -2
  86. package/es/components/UIShell/SideNav.d.ts +1 -1
  87. package/es/components/UIShell/SideNav.js +2 -2
  88. package/es/components/UIShell/SideNavHeader.d.ts +3 -2
  89. package/es/components/UIShell/SideNavHeader.js +2 -1
  90. package/es/components/UIShell/SideNavLink.d.ts +2 -2
  91. package/es/components/UIShell/SideNavLink.js +1 -1
  92. package/es/components/UIShell/SideNavMenu.d.ts +2 -2
  93. package/es/components/UIShell/SideNavMenu.js +3 -3
  94. package/es/components/UIShell/SwitcherItem.js +2 -2
  95. package/es/internal/FloatingMenu.js +4 -4
  96. package/es/internal/OptimizedResize.js +24 -21
  97. package/es/internal/focus/index.js +15 -0
  98. package/es/internal/keyboard/keys.js +2 -2
  99. package/es/internal/keyboard/match.js +41 -17
  100. package/es/internal/keyboard/navigation.js +27 -15
  101. package/es/internal/useMergedRefs.js +0 -3
  102. package/lib/components/Accordion/AccordionItem.js +2 -2
  103. package/lib/components/Button/Button.d.ts +3 -2
  104. package/lib/components/Button/Button.js +2 -1
  105. package/lib/components/Button/ButtonBase.js +1 -1
  106. package/lib/components/ChatButton/ChatButton.d.ts +3 -2
  107. package/lib/components/ChatButton/ChatButton.js +2 -1
  108. package/lib/components/ComboBox/ComboBox.js +24 -34
  109. package/lib/components/ComposedModal/ComposedModal.js +50 -64
  110. package/lib/components/ContainedList/ContainedListItem/ContainedListItem.d.ts +2 -2
  111. package/lib/components/ContainedList/ContainedListItem/ContainedListItem.js +1 -1
  112. package/lib/components/ContentSwitcher/ContentSwitcher.js +3 -3
  113. package/lib/components/DataTable/TableBatchAction.d.ts +3 -3
  114. package/lib/components/DataTable/TableBatchAction.js +1 -1
  115. package/lib/components/DataTable/TableContainer.d.ts +1 -1
  116. package/lib/components/DataTable/TableContainer.js +3 -3
  117. package/lib/components/DataTable/TableExpandHeader.d.ts +5 -6
  118. package/lib/components/DataTable/TableToolbarMenu.d.ts +2 -2
  119. package/lib/components/DataTable/TableToolbarMenu.js +1 -1
  120. package/lib/components/DatePicker/DatePicker.js +2 -2
  121. package/lib/components/DatePicker/plugins/fixEventsPlugin.js +1 -1
  122. package/lib/components/Dialog/index.d.ts +4 -42
  123. package/lib/components/ExpandableSearch/ExpandableSearch.js +2 -2
  124. package/lib/components/FeatureFlags/index.d.ts +1 -3
  125. package/lib/components/FeatureFlags/index.js +0 -3
  126. package/lib/components/FileUploader/FileUploader.d.ts +1 -1
  127. package/lib/components/FileUploader/FileUploader.js +2 -2
  128. package/lib/components/FileUploader/FileUploaderButton.js +2 -2
  129. package/lib/components/FileUploader/FileUploaderDropContainer.d.ts +1 -1
  130. package/lib/components/FileUploader/FileUploaderDropContainer.js +4 -6
  131. package/lib/components/FileUploader/FileUploaderItem.d.ts +1 -1
  132. package/lib/components/FileUploader/FileUploaderItem.js +2 -2
  133. package/lib/components/Grid/CSSGrid.js +14 -18
  134. package/lib/components/Grid/FlexGrid.js +6 -7
  135. package/lib/components/Grid/GridTypes.d.ts +3 -5
  136. package/lib/components/IconButton/index.js +3 -3
  137. package/lib/components/Layer/index.d.ts +6 -4
  138. package/lib/components/Layer/index.js +6 -5
  139. package/lib/components/Link/Link.d.ts +3 -2
  140. package/lib/components/Link/Link.js +2 -1
  141. package/lib/components/ListBox/ListBoxMenuItem.d.ts +3 -3
  142. package/lib/components/ListBox/ListBoxMenuItem.js +14 -36
  143. package/lib/components/Menu/Menu.js +2 -2
  144. package/lib/components/Menu/MenuItem.d.ts +2 -2
  145. package/lib/components/Menu/MenuItem.js +3 -3
  146. package/lib/components/Modal/Modal.js +51 -123
  147. package/lib/components/Modal/next/index.d.ts +171 -0
  148. package/lib/components/ModalWrapper/ModalWrapper.js +1 -1
  149. package/lib/components/MultiSelect/FilterableMultiSelect.js +3 -3
  150. package/lib/components/MultiSelect/MultiSelect.js +2 -2
  151. package/lib/components/Notification/Notification.d.ts +13 -5
  152. package/lib/components/Notification/Notification.js +4 -3
  153. package/lib/components/OverflowMenu/OverflowMenu.d.ts +8 -4
  154. package/lib/components/OverflowMenu/OverflowMenu.js +3 -3
  155. package/lib/components/OverflowMenu/next/index.d.ts +2 -2
  156. package/lib/components/OverflowMenu/next/index.js +1 -1
  157. package/lib/components/OverflowMenuItem/OverflowMenuItem.js +2 -2
  158. package/lib/components/ProgressIndicator/ProgressIndicator.js +2 -2
  159. package/lib/components/RadioTile/RadioTile.js +2 -2
  160. package/lib/components/Search/Search.d.ts +3 -2
  161. package/lib/components/Search/Search.js +6 -4
  162. package/lib/components/Slider/Slider.d.ts +15 -16
  163. package/lib/components/Slider/Slider.js +22 -22
  164. package/lib/components/Tabs/Tabs.d.ts +6 -3
  165. package/lib/components/Tabs/Tabs.js +9 -8
  166. package/lib/components/Tag/DismissibleTag.d.ts +5 -3
  167. package/lib/components/Tag/DismissibleTag.js +2 -1
  168. package/lib/components/Tag/OperationalTag.d.ts +3 -2
  169. package/lib/components/Tag/OperationalTag.js +2 -1
  170. package/lib/components/Tag/SelectableTag.d.ts +5 -3
  171. package/lib/components/Tag/SelectableTag.js +2 -1
  172. package/lib/components/Tag/Tag.d.ts +3 -2
  173. package/lib/components/Tag/Tag.js +2 -1
  174. package/lib/components/Tile/Tile.d.ts +5 -3
  175. package/lib/components/Tile/Tile.js +6 -8
  176. package/lib/components/Toggletip/index.js +2 -2
  177. package/lib/components/Tooltip/DefinitionTooltip.js +2 -2
  178. package/lib/components/Tooltip/Tooltip.d.ts +1 -1
  179. package/lib/components/Tooltip/Tooltip.js +2 -2
  180. package/lib/components/TreeView/TreeNode.d.ts +5 -3
  181. package/lib/components/TreeView/TreeNode.js +4 -3
  182. package/lib/components/TreeView/TreeView.js +2 -2
  183. package/lib/components/UIShell/HeaderContainer.js +2 -2
  184. package/lib/components/UIShell/HeaderMenu.js +2 -2
  185. package/lib/components/UIShell/HeaderPanel.js +2 -2
  186. package/lib/components/UIShell/SideNav.d.ts +1 -1
  187. package/lib/components/UIShell/SideNav.js +2 -2
  188. package/lib/components/UIShell/SideNavHeader.d.ts +3 -2
  189. package/lib/components/UIShell/SideNavHeader.js +2 -1
  190. package/lib/components/UIShell/SideNavLink.d.ts +2 -2
  191. package/lib/components/UIShell/SideNavLink.js +1 -1
  192. package/lib/components/UIShell/SideNavMenu.d.ts +2 -2
  193. package/lib/components/UIShell/SideNavMenu.js +3 -3
  194. package/lib/components/UIShell/SwitcherItem.js +2 -2
  195. package/lib/internal/FloatingMenu.js +5 -5
  196. package/lib/internal/OptimizedResize.js +24 -21
  197. package/lib/internal/focus/index.js +19 -0
  198. package/lib/internal/keyboard/keys.js +2 -2
  199. package/lib/internal/keyboard/match.js +41 -17
  200. package/lib/internal/keyboard/navigation.js +27 -15
  201. package/lib/internal/useMergedRefs.js +0 -3
  202. package/package.json +6 -6
  203. package/telemetry.yml +0 -1
  204. package/es/components/Dialog/index.js +0 -177
  205. package/es/internal/OptimizedResize.d.ts +0 -18
  206. package/es/internal/keyboard/index.d.ts +0 -9
  207. package/es/internal/keyboard/keys.d.ts +0 -23
  208. package/es/internal/keyboard/match.d.ts +0 -26
  209. package/es/internal/keyboard/navigation.d.ts +0 -37
  210. package/lib/components/Dialog/index.js +0 -190
  211. package/lib/internal/OptimizedResize.d.ts +0 -18
  212. package/lib/internal/keyboard/index.d.ts +0 -9
  213. package/lib/internal/keyboard/keys.d.ts +0 -23
  214. package/lib/internal/keyboard/match.d.ts +0 -26
  215. package/lib/internal/keyboard/navigation.d.ts +0 -37
  216. package/scss/components/dialog/_dialog.scss +0 -9
  217. package/scss/components/dialog/_index.scss +0 -9
@@ -17,21 +17,20 @@ import ButtonSet from '../ButtonSet/ButtonSet.js';
17
17
  import InlineLoading from '../InlineLoading/InlineLoading.js';
18
18
  import { Layer } from '../Layer/index.js';
19
19
  import requiredIfGivenPropIsTruthy from '../../prop-types/requiredIfGivenPropIsTruthy.js';
20
- import wrapFocus, { elementOrParentIsFloatingMenu } from '../../internal/wrapFocus.js';
20
+ import wrapFocus, { wrapFocusWithoutSentinels, elementOrParentIsFloatingMenu } from '../../internal/wrapFocus.js';
21
21
  import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
22
22
  import { useId } from '../../internal/useId.js';
23
23
  import { usePrefix } from '../../internal/usePrefix.js';
24
- import { Escape, Enter } from '../../internal/keyboard/keys.js';
25
- import { match } from '../../internal/keyboard/match.js';
26
24
  import { IconButton } from '../IconButton/index.js';
27
25
  import { noopFn } from '../../internal/noopFn.js';
28
26
  import '../Text/index.js';
29
27
  import { useFeatureFlag } from '../FeatureFlags/index.js';
30
28
  import { composeEventHandlers } from '../../tools/events.js';
31
29
  import deprecate from '../../prop-types/deprecate.js';
32
- import { unstable__Dialog } from '../Dialog/index.js';
33
30
  import { debounce } from '../../node_modules/es-toolkit/dist/compat/function/debounce.mjs.js';
31
+ import { match } from '../../internal/keyboard/match.js';
34
32
  import { Text } from '../Text/Text.js';
33
+ import { Escape, Enter, Tab } from '../../internal/keyboard/keys.js';
35
34
 
36
35
  const ModalSizes = ['xs', 'sm', 'md', 'lg'];
37
36
  const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
@@ -87,7 +86,7 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
87
86
  [`${prefix}--btn--loading`]: loadingStatus !== 'inactive'
88
87
  });
89
88
  const loadingActive = loadingStatus !== 'inactive';
90
- const enableDialogElement = useFeatureFlag('enable-experimental-focus-wrap-without-sentinels') || useFeatureFlag('enable-dialog-element');
89
+ const focusTrapWithoutSentinels = useFeatureFlag('enable-experimental-focus-wrap-without-sentinels');
91
90
  function isCloseButton(element) {
92
91
  return !onSecondarySubmit && element === secondaryButton.current || element.classList.contains(modalCloseButtonClass);
93
92
  }
@@ -100,6 +99,13 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
100
99
  if (match(evt, Enter) && shouldSubmitOnEnter && !isCloseButton(evt.target)) {
101
100
  onRequestSubmit(evt);
102
101
  }
102
+ if (focusTrapWithoutSentinels && match(evt, Tab) && innerModal.current) {
103
+ wrapFocusWithoutSentinels({
104
+ containerNode: innerModal.current,
105
+ currentActiveNode: evt.target,
106
+ event: evt
107
+ });
108
+ }
103
109
  }
104
110
  }
105
111
  function handleOnClick(evt) {
@@ -175,46 +181,40 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
175
181
  }
176
182
  useEffect(() => {
177
183
  return () => {
178
- if (!enableDialogElement) {
179
- toggleClass(document.body, `${prefix}--body--with-modal-open`, false);
180
- }
184
+ toggleClass(document.body, `${prefix}--body--with-modal-open`, false);
181
185
  };
182
- }, [prefix, enableDialogElement]);
186
+ }, [prefix]);
183
187
  useEffect(() => {
184
- if (!enableDialogElement) {
185
- toggleClass(document.body, `${prefix}--body--with-modal-open`, open ?? false);
186
- }
187
- }, [open, prefix, enableDialogElement]);
188
+ toggleClass(document.body, `${prefix}--body--with-modal-open`, open ?? false);
189
+ }, [open, prefix]);
188
190
  useEffect(() => {
189
- if (!enableDialogElement && !open && launcherButtonRef) {
191
+ if (!open && launcherButtonRef) {
190
192
  setTimeout(() => {
191
193
  if ('current' in launcherButtonRef) {
192
194
  launcherButtonRef.current?.focus();
193
195
  }
194
196
  });
195
197
  }
196
- }, [open, launcherButtonRef, enableDialogElement]);
198
+ }, [open, launcherButtonRef]);
197
199
  useEffect(() => {
198
- if (!enableDialogElement) {
199
- const initialFocus = focusContainerElement => {
200
- const containerElement = focusContainerElement || innerModal.current;
201
- const primaryFocusElement = containerElement ? containerElement.querySelector(danger ? `.${prefix}--btn--secondary` : selectorPrimaryFocus) : null;
202
- if (primaryFocusElement) {
203
- return primaryFocusElement;
204
- }
205
- return button && button.current;
206
- };
207
- const focusButton = focusContainerElement => {
208
- const target = initialFocus(focusContainerElement);
209
- if (target !== null) {
210
- target.focus();
211
- }
212
- };
213
- if (open) {
214
- focusButton(innerModal.current);
200
+ const initialFocus = focusContainerElement => {
201
+ const containerElement = focusContainerElement || innerModal.current;
202
+ const primaryFocusElement = containerElement ? containerElement.querySelector(danger ? `.${prefix}--btn--secondary` : selectorPrimaryFocus) : null;
203
+ if (primaryFocusElement) {
204
+ return primaryFocusElement;
215
205
  }
206
+ return button && button.current;
207
+ };
208
+ const focusButton = focusContainerElement => {
209
+ const target = initialFocus(focusContainerElement);
210
+ if (target !== null) {
211
+ target.focus();
212
+ }
213
+ };
214
+ if (open) {
215
+ focusButton(innerModal.current);
216
216
  }
217
- }, [open, selectorPrimaryFocus, danger, prefix, enableDialogElement]);
217
+ }, [open, selectorPrimaryFocus, danger, prefix]);
218
218
  useIsomorphicEffect(() => {
219
219
  if (contentRef.current) {
220
220
  setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
@@ -254,84 +254,7 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
254
254
  tabIndex: "-1",
255
255
  className: `${modalCloseButtonClass}__icon`
256
256
  })));
257
-
258
- // alertdialog is the only permitted aria role for a native dialog element
259
- // https://www.w3.org/TR/html-aria/#docconformance:~:text=Role%3A-,alertdialog,-.%20(dialog%20is
260
- const isAlertDialog = alert && !passiveModal;
261
- const modalBody = enableDialogElement ? /*#__PURE__*/React__default.createElement(unstable__Dialog, {
262
- open: open,
263
- modal: true,
264
- ref: innerModal,
265
- role: isAlertDialog ? 'alertdialog' : '',
266
- "aria-describedby": isAlertDialog ? modalBodyId : '',
267
- className: containerClasses,
268
- "aria-label": ariaLabel
269
- }, /*#__PURE__*/React__default.createElement("div", {
270
- className: `${prefix}--modal-header`
271
- }, modalLabel && /*#__PURE__*/React__default.createElement(Text, {
272
- as: "h2",
273
- id: modalLabelId,
274
- className: `${prefix}--modal-header__label`
275
- }, modalLabel), /*#__PURE__*/React__default.createElement(Text, {
276
- as: "h2",
277
- id: modalHeadingId,
278
- className: `${prefix}--modal-header__heading`
279
- }, modalHeading), decorator ? /*#__PURE__*/React__default.createElement("div", {
280
- className: `${prefix}--modal--inner__decorator`
281
- }, normalizedDecorator) : '', /*#__PURE__*/React__default.createElement("div", {
282
- className: `${prefix}--modal-close-button`
283
- }, /*#__PURE__*/React__default.createElement(IconButton, {
284
- className: modalCloseButtonClass,
285
- label: closeButtonLabel,
286
- onClick: onRequestClose,
287
- "aria-label": closeButtonLabel,
288
- align: "left",
289
- ref: button
290
- }, /*#__PURE__*/React__default.createElement(Close, {
291
- size: 20,
292
- "aria-hidden": "true",
293
- tabIndex: "-1",
294
- className: `${modalCloseButtonClass}__icon`
295
- })))), /*#__PURE__*/React__default.createElement(Layer, _extends({
296
- ref: contentRef,
297
- id: modalBodyId,
298
- className: contentClasses
299
- }, hasScrollingContentProps), children), !passiveModal && /*#__PURE__*/React__default.createElement(ButtonSet, {
300
- className: footerClasses,
301
- "aria-busy": loadingActive
302
- }, Array.isArray(secondaryButtons) && secondaryButtons.length <= 2 ? secondaryButtons.map((_ref3, i) => {
303
- let {
304
- buttonText,
305
- onClick: onButtonClick
306
- } = _ref3;
307
- return /*#__PURE__*/React__default.createElement(Button, {
308
- key: `${buttonText}-${i}`,
309
- kind: "secondary",
310
- onClick: onButtonClick
311
- }, buttonText);
312
- }) : secondaryButtonText && /*#__PURE__*/React__default.createElement(Button, {
313
- disabled: loadingActive,
314
- kind: "secondary",
315
- onClick: onSecondaryButtonClick,
316
- ref: secondaryButton
317
- }, secondaryButtonText), /*#__PURE__*/React__default.createElement(Button, {
318
- className: primaryButtonClass,
319
- kind: danger ? 'danger' : 'primary',
320
- disabled: loadingActive || primaryButtonDisabled,
321
- onClick: onRequestSubmit,
322
- ref: button
323
- }, loadingStatus === 'inactive' ? primaryButtonText : /*#__PURE__*/React__default.createElement(InlineLoading, {
324
- status: loadingStatus,
325
- description: loadingDescription,
326
- iconDescription: loadingIconDescription,
327
- className: `${prefix}--inline-loading--btn`,
328
- onSuccess: onLoadingSuccess
329
- })))) : /*#__PURE__*/React__default.createElement(React__default.Fragment, null, !enableDialogElement && /*#__PURE__*/React__default.createElement("span", {
330
- ref: startTrap,
331
- tabIndex: 0,
332
- role: "link",
333
- className: `${prefix}--visually-hidden`
334
- }, "Focus sentinel"), /*#__PURE__*/React__default.createElement("div", _extends({
257
+ const modalBody = /*#__PURE__*/React__default.createElement("div", _extends({
335
258
  ref: innerModal,
336
259
  role: "dialog"
337
260
  }, alertDialogProps, {
@@ -358,11 +281,11 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
358
281
  }, hasScrollingContentProps), children), !passiveModal && /*#__PURE__*/React__default.createElement(ButtonSet, {
359
282
  className: footerClasses,
360
283
  "aria-busy": loadingActive
361
- }, Array.isArray(secondaryButtons) && secondaryButtons.length <= 2 ? secondaryButtons.map((_ref4, i) => {
284
+ }, Array.isArray(secondaryButtons) && secondaryButtons.length <= 2 ? secondaryButtons.map((_ref3, i) => {
362
285
  let {
363
286
  buttonText,
364
287
  onClick: onButtonClick
365
- } = _ref4;
288
+ } = _ref3;
366
289
  return /*#__PURE__*/React__default.createElement(Button, {
367
290
  key: `${buttonText}-${i}`,
368
291
  kind: "secondary",
@@ -385,21 +308,26 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
385
308
  iconDescription: loadingIconDescription,
386
309
  className: `${prefix}--inline-loading--btn`,
387
310
  onSuccess: onLoadingSuccess
388
- })))), !enableDialogElement && /*#__PURE__*/React__default.createElement("span", {
389
- ref: endTrap,
390
- tabIndex: 0,
391
- role: "link",
392
- className: `${prefix}--visually-hidden`
393
- }, "Focus sentinel"));
311
+ }))));
394
312
  return /*#__PURE__*/React__default.createElement(Layer, _extends({}, rest, {
395
313
  level: 0,
396
314
  onKeyDown: handleKeyDown,
397
315
  onClick: composeEventHandlers([rest?.onClick, handleOnClick]),
398
- onBlur: !enableDialogElement ? handleBlur : () => {},
316
+ onBlur: !focusTrapWithoutSentinels ? handleBlur : () => {},
399
317
  className: modalClasses,
400
318
  role: "presentation",
401
319
  ref: ref
402
- }), modalBody);
320
+ }), !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("span", {
321
+ ref: startTrap,
322
+ tabIndex: 0,
323
+ role: "link",
324
+ className: `${prefix}--visually-hidden`
325
+ }, "Focus sentinel"), modalBody, !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("span", {
326
+ ref: endTrap,
327
+ tabIndex: 0,
328
+ role: "link",
329
+ className: `${prefix}--visually-hidden`
330
+ }, "Focus sentinel"));
403
331
  });
404
332
  Modal.propTypes = {
405
333
  /**
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2025
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import React, { ReactNode } from 'react';
8
+ import { ReactAttr } from '../../../types/common';
9
+ import { InlineLoadingStatus } from '../../InlineLoading/InlineLoading';
10
+ export declare const ModalSizes: readonly ["xs", "sm", "md", "lg"];
11
+ export type ModalSize = (typeof ModalSizes)[number];
12
+ export interface ModalSecondaryButton {
13
+ buttonText?: string | ReactNode;
14
+ onClick?: React.MouseEventHandler<HTMLButtonElement>;
15
+ }
16
+ export interface BaseModalProps extends ReactAttr<HTMLDivElement> {
17
+ /**
18
+ * Required props for the accessibility label of the header
19
+ */
20
+ 'aria-label'?: string;
21
+ /**
22
+ * Provide the contents of your Modal
23
+ */
24
+ children?: ReactNode;
25
+ /**
26
+ * Specify an optional className to be applied to the modal root node
27
+ */
28
+ className?: string;
29
+ /**
30
+ * Specify an label for the close button of the modal; defaults to close
31
+ */
32
+ closeButtonLabel?: string;
33
+ /**
34
+ * Specify whether the Modal is for dangerous actions
35
+ */
36
+ danger?: boolean;
37
+ /**
38
+ * **Experimental**: Provide a decorator component to be rendered inside the `Modal` component
39
+ */
40
+ decorator?: ReactNode;
41
+ /**
42
+ * Specify whether the modal contains scrolling content
43
+ */
44
+ hasScrollingContent?: boolean;
45
+ /**
46
+ * Specify the DOM element ID of the top-level node.
47
+ */
48
+ id?: string;
49
+ /**
50
+ * Specify whether or not the Modal content should have any inner padding.
51
+ */
52
+ isFullWidth?: boolean;
53
+ /**
54
+ * Specify the description for the loading text
55
+ */
56
+ loadingDescription?: string;
57
+ /**
58
+ * Specify the description for the loading text
59
+ */
60
+ loadingIconDescription?: string;
61
+ /**
62
+ * Specify loading status
63
+ */
64
+ loadingStatus?: InlineLoadingStatus;
65
+ /**
66
+ * Specify a label to be read by screen readers on the modal root node
67
+ */
68
+ modalAriaLabel?: string;
69
+ /**
70
+ * Specify the content of the modal header title.
71
+ */
72
+ modalHeading?: ReactNode;
73
+ /**
74
+ * Specify the content of the modal header label.
75
+ */
76
+ modalLabel?: ReactNode;
77
+ /**
78
+ * Specify a handler for keypresses.
79
+ * @deprecated this property is unused
80
+ */
81
+ onKeyDown?: React.KeyboardEventHandler<HTMLElement>;
82
+ /**
83
+ * Specify an optional handler to be invoked when loading is
84
+ * successful
85
+ */
86
+ onLoadingSuccess?: () => void;
87
+ /**
88
+ * Specify a handler for closing modal.
89
+ * The handler should care of closing modal, e.g. changing `open` prop.
90
+ */
91
+ onRequestClose?: React.ReactEventHandler<HTMLElement>;
92
+ /**
93
+ * Specify a handler for "submitting" modal.
94
+ * The handler should care of closing modal, e.g. changing `open` prop, if necessary.
95
+ */
96
+ onRequestSubmit?: React.ReactEventHandler<HTMLElement>;
97
+ /**
98
+ * Specify a handler for the secondary button.
99
+ * Useful if separate handler from `onRequestClose` is desirable
100
+ */
101
+ onSecondarySubmit?: React.ReactEventHandler<HTMLElement>;
102
+ /**
103
+ * Specify whether the Modal is currently open
104
+ */
105
+ open?: boolean;
106
+ /**
107
+ * Prevent closing on click outside of modal
108
+ */
109
+ preventCloseOnClickOutside?: boolean;
110
+ /**
111
+ * Specify whether the Button should be disabled, or not
112
+ */
113
+ primaryButtonDisabled?: boolean;
114
+ /**
115
+ * Specify the text for the primary button
116
+ */
117
+ primaryButtonText?: ReactNode;
118
+ /**
119
+ * Specify the text for the secondary button
120
+ */
121
+ secondaryButtonText?: ReactNode;
122
+ /**
123
+ * Specify an array of config objects for secondary buttons
124
+ */
125
+ secondaryButtons?: ModalSecondaryButton[];
126
+ /**
127
+ * Specify a CSS selector that matches the DOM element that should
128
+ * be focused when the Modal opens
129
+ */
130
+ selectorPrimaryFocus?: string;
131
+ /**
132
+ * Specify CSS selectors that match DOM elements working as floating menus.
133
+ * Focusing on those elements won't trigger "focus-wrap" behavior
134
+ */
135
+ selectorsFloatingMenus?: string[];
136
+ /**
137
+ * Specify if Enter key should be used as "submit" action
138
+ */
139
+ shouldSubmitOnEnter?: boolean;
140
+ /**
141
+ * Specify the size variant.
142
+ */
143
+ size?: ModalSize;
144
+ }
145
+ interface PassiveModal extends BaseModalProps {
146
+ /**
147
+ * Specify whether the modal should be button-less
148
+ */
149
+ passiveModal?: true;
150
+ /**
151
+ * Specify whether the Modal is displaying an alert, error or warning. Should
152
+ * go hand in hand with the `danger` prop. This changes the `role` to
153
+ * `alertdialog` and cannot be used with passive modals.
154
+ */
155
+ alert?: never;
156
+ }
157
+ interface NonPassiveModal extends BaseModalProps {
158
+ /**
159
+ * Specify whether the modal should be button-less
160
+ */
161
+ passiveModal?: false;
162
+ /**
163
+ * Specify whether the Modal is displaying an alert, error or warning. Should
164
+ * go hand in hand with the `danger` prop. This changes the `role` to
165
+ * `alertdialog` and cannot be used with passive modals.
166
+ */
167
+ alert?: boolean;
168
+ }
169
+ export type ModalProps = PassiveModal | NonPassiveModal;
170
+ declare const Modal: React.ForwardRefExoticComponent<ModalProps & React.RefAttributes<HTMLDivElement>>;
171
+ export default Modal;
@@ -13,8 +13,8 @@ import Button, { ButtonKinds } from '../Button/Button.js';
13
13
  import '../Button/Button.Skeleton.js';
14
14
  import { warning } from '../../internal/warning.js';
15
15
  import { noopFn } from '../../internal/noopFn.js';
16
- import { Escape } from '../../internal/keyboard/keys.js';
17
16
  import { match } from '../../internal/keyboard/match.js';
17
+ import { Escape } from '../../internal/keyboard/keys.js';
18
18
 
19
19
  let didWarnAboutDeprecation = false;
20
20
  class ModalWrapper extends React__default.Component {
@@ -17,8 +17,6 @@ import { sortingPropTypes } from './MultiSelectPropTypes.js';
17
17
  import ListBox from '../ListBox/index.js';
18
18
  import ListBoxSelection from '../ListBox/next/ListBoxSelection.js';
19
19
  import ListBoxTrigger from '../ListBox/next/ListBoxTrigger.js';
20
- import { Escape, Space, Enter, Delete, Tab, Home, End } from '../../internal/keyboard/keys.js';
21
- import { match } from '../../internal/keyboard/match.js';
22
20
  import { defaultItemToString } from './tools/itemToString.js';
23
21
  import mergeRefs from '../../tools/mergeRefs.js';
24
22
  import deprecate from '../../prop-types/deprecate.js';
@@ -29,7 +27,9 @@ import '../FluidForm/FluidForm.js';
29
27
  import { FormContext } from '../FluidForm/FormContext.js';
30
28
  import { useSelection } from '../../internal/Selection.js';
31
29
  import { useFloating, flip, size, hide, autoUpdate } from '@floating-ui/react';
30
+ import { match } from '../../internal/keyboard/match.js';
32
31
  import { ListBoxSize } from '../ListBox/ListBoxPropTypes.js';
32
+ import { Escape, Space, Enter, Delete, Tab, Home, End } from '../../internal/keyboard/keys.js';
33
33
 
34
34
  const {
35
35
  InputBlur,
@@ -414,7 +414,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
414
414
  });
415
415
  function clearInputValue(event) {
416
416
  const value = textInput.current?.value;
417
- if (value?.length === 1 || event && 'key' in event && match(event, Escape)) {
417
+ if (value?.length === 1 || event && match(event, Escape)) {
418
418
  setInputValue('');
419
419
  } else {
420
420
  setInputValue(value ?? '');
@@ -19,8 +19,6 @@ import { useSelection } from '../../internal/Selection.js';
19
19
  import { useId } from '../../internal/useId.js';
20
20
  import mergeRefs from '../../tools/mergeRefs.js';
21
21
  import deprecate from '../../prop-types/deprecate.js';
22
- import { Delete, Escape, Space, ArrowDown, Enter } from '../../internal/keyboard/keys.js';
23
- import { match } from '../../internal/keyboard/match.js';
24
22
  import { usePrefix } from '../../internal/usePrefix.js';
25
23
  import '../FluidForm/FluidForm.js';
26
24
  import { FormContext } from '../FluidForm/FormContext.js';
@@ -29,7 +27,9 @@ import '../Checkbox/Checkbox.Skeleton.js';
29
27
  import { noopFn } from '../../internal/noopFn.js';
30
28
  import { useFloating, flip, size, hide, autoUpdate } from '@floating-ui/react';
31
29
  import { useFeatureFlag } from '../FeatureFlags/index.js';
30
+ import { match } from '../../internal/keyboard/match.js';
32
31
  import { ListBoxSize } from '../ListBox/ListBoxPropTypes.js';
32
+ import { Delete, Escape, Space, ArrowDown, Enter } from '../../internal/keyboard/keys.js';
33
33
 
34
34
  const {
35
35
  ItemClick,
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2025
2
+ * Copyright IBM Corp. 2016, 2023
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import PropTypes from 'prop-types';
8
- import React, { type ReactNode, type MouseEvent, type ButtonHTMLAttributes, type HTMLAttributes } from 'react';
8
+ import React, { type ReactNode, type MouseEvent, type ComponentType, type FunctionComponent, type ButtonHTMLAttributes, type HTMLAttributes } from 'react';
9
9
  import { type ButtonProps } from '../Button';
10
10
  export interface NotificationActionButtonProps extends ButtonProps<'button'> {
11
11
  /**
@@ -71,9 +71,16 @@ export interface NotificationButtonProps extends ButtonHTMLAttributes<HTMLButton
71
71
  */
72
72
  notificationType?: 'toast' | 'inline' | 'actionable';
73
73
  /**
74
- * A component used to render an icon.
74
+ * Optional prop to allow overriding the icon rendering.
75
+ * Can be a React component class
75
76
  */
76
- renderIcon?: React.ElementType;
77
+ renderIcon?: ComponentType<{
78
+ className?: string;
79
+ name?: string;
80
+ }> | FunctionComponent<{
81
+ className?: string;
82
+ name?: string;
83
+ }>;
77
84
  }
78
85
  export declare function NotificationButton({ 'aria-label': ariaLabel, ariaLabel: deprecatedAriaLabel, className, type, renderIcon: IconTag, name, notificationType, ...rest }: NotificationButtonProps): import("react/jsx-runtime").JSX.Element;
79
86
  export declare namespace NotificationButton {
@@ -101,7 +108,8 @@ export declare namespace NotificationButton {
101
108
  */
102
109
  notificationType: PropTypes.Requireable<string>;
103
110
  /**
104
- * A component used to render an icon.
111
+ * Optional prop to allow overriding the icon rendering.
112
+ * Can be a React component class
105
113
  */
106
114
  renderIcon: PropTypes.Requireable<object>;
107
115
  /**
@@ -16,8 +16,6 @@ import Button from '../Button/Button.js';
16
16
  import '../Button/Button.Skeleton.js';
17
17
  import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
18
18
  import { useNoInteractiveChildren, useInteractiveChildrenNeedDescription } from '../../internal/useNoInteractiveChildren.js';
19
- import { Tab, Escape } from '../../internal/keyboard/keys.js';
20
- import { match, matches } from '../../internal/keyboard/match.js';
21
19
  import { usePrefix } from '../../internal/usePrefix.js';
22
20
  import { useId } from '../../internal/useId.js';
23
21
  import { noopFn } from '../../internal/noopFn.js';
@@ -25,7 +23,9 @@ import wrapFocus, { wrapFocusWithoutSentinels } from '../../internal/wrapFocus.j
25
23
  import { useFeatureFlag } from '../FeatureFlags/index.js';
26
24
  import { warning } from '../../internal/warning.js';
27
25
  import deprecateValuesWithin from '../../prop-types/deprecateValuesWithin.js';
26
+ import { match, matches } from '../../internal/keyboard/match.js';
28
27
  import { Text } from '../Text/Text.js';
28
+ import { Tab, Escape } from '../../internal/keyboard/keys.js';
29
29
 
30
30
  /**
31
31
  * Conditionally call a callback when the escape key is pressed
@@ -145,7 +145,8 @@ NotificationButton.propTypes = {
145
145
  */
146
146
  notificationType: PropTypes.oneOf(['toast', 'inline', 'actionable']),
147
147
  /**
148
- * A component used to render an icon.
148
+ * Optional prop to allow overriding the icon rendering.
149
+ * Can be a React component class
149
150
  */
150
151
  renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
151
152
  /**
@@ -5,9 +5,13 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { type MenuDirection, type MenuOffset } from '../../internal/FloatingMenu';
8
- import React from 'react';
8
+ import React, { ComponentType } from 'react';
9
9
  import PropTypes from 'prop-types';
10
10
  export declare const getMenuOffset: MenuOffset;
11
+ type IconProps = {
12
+ className?: string;
13
+ 'aria-label'?: string;
14
+ };
11
15
  export interface OverflowMenuProps {
12
16
  /**
13
17
  * Specify a label to be read by screen readers on the container node
@@ -85,9 +89,9 @@ export interface OverflowMenuProps {
85
89
  */
86
90
  open?: boolean;
87
91
  /**
88
- * A component used to render an icon.
92
+ * Function called to override icon rendering.
89
93
  */
90
- renderIcon?: React.ElementType;
94
+ renderIcon?: ComponentType<IconProps>;
91
95
  /**
92
96
  * Specify a CSS selector that matches the DOM element that should
93
97
  * be focused when the OverflowMenu opens
@@ -204,7 +208,7 @@ declare class OverflowMenu extends React.Component<OverflowMenuProps, OverflowMe
204
208
  */
205
209
  open: PropTypes.Requireable<boolean>;
206
210
  /**
207
- * A component used to render an icon.
211
+ * Function called to override icon rendering.
208
212
  */
209
213
  renderIcon: PropTypes.Requireable<object>;
210
214
  /**
@@ -8,8 +8,6 @@
8
8
  import { defineProperty as _defineProperty, extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import { FloatingMenu, DIRECTION_TOP, DIRECTION_BOTTOM } from '../../internal/FloatingMenu.js';
10
10
  import React__default from 'react';
11
- import { ArrowUp, ArrowRight, ArrowDown, ArrowLeft, Escape } from '../../internal/keyboard/keys.js';
12
- import { matches } from '../../internal/keyboard/match.js';
13
11
  import ClickListener from '../../internal/ClickListener.js';
14
12
  import { IconButton } from '../IconButton/index.js';
15
13
  import { OverflowMenuVertical } from '@carbon/icons-react';
@@ -21,6 +19,8 @@ import invariant from 'invariant';
21
19
  import mergeRefs from '../../tools/mergeRefs.js';
22
20
  import { noopFn } from '../../internal/noopFn.js';
23
21
  import setupGetInstanceId from '../../tools/setupGetInstanceId.js';
22
+ import { matches } from '../../internal/keyboard/match.js';
23
+ import { ArrowUp, ArrowRight, ArrowDown, ArrowLeft, Escape } from '../../internal/keyboard/keys.js';
24
24
 
25
25
  const getInstanceId = setupGetInstanceId();
26
26
  const on = function (element) {
@@ -488,7 +488,7 @@ _defineProperty(OverflowMenu, "propTypes", {
488
488
  */
489
489
  open: PropTypes.bool,
490
490
  /**
491
- * A component used to render an icon.
491
+ * Function called to override icon rendering.
492
492
  */
493
493
  renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
494
494
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2020, 2025
2
+ * Copyright IBM Corp. 2020, 2023
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.
@@ -27,7 +27,7 @@ interface OverflowMenuProps {
27
27
  */
28
28
  menuAlignment?: 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end';
29
29
  /**
30
- * A component used to render an icon.
30
+ * Optionally provide a custom icon to be rendered on the trigger button.
31
31
  */
32
32
  renderIcon?: ComponentType | FunctionComponent;
33
33
  /**
@@ -165,7 +165,7 @@ OverflowMenu.propTypes = {
165
165
  */
166
166
  menuAlignment: PropTypes.oneOf(['top-start', 'top-end', 'bottom-start', 'bottom-end']),
167
167
  /**
168
- * A component used to render an icon.
168
+ * Optionally provide a custom icon to be rendered on the trigger button.
169
169
  */
170
170
  // @ts-expect-error: PropTypes are not expressive enough to cover this case
171
171
  renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
@@ -9,12 +9,12 @@ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js
9
9
  import cx from 'classnames';
10
10
  import PropTypes from 'prop-types';
11
11
  import React__default from 'react';
12
- import { ArrowDown, ArrowUp } from '../../internal/keyboard/keys.js';
13
- import { match } from '../../internal/keyboard/match.js';
14
12
  import { usePrefix } from '../../internal/usePrefix.js';
15
13
  import { warning } from '../../internal/warning.js';
16
14
  import '../Text/index.js';
15
+ import { match } from '../../internal/keyboard/match.js';
17
16
  import { Text } from '../Text/Text.js';
17
+ import { ArrowDown, ArrowUp } from '../../internal/keyboard/keys.js';
18
18
 
19
19
  const OverflowMenuItem = /*#__PURE__*/React__default.forwardRef(function OverflowMenuItem(_ref, ref) {
20
20
  let {