carbon-react 119.7.0 → 119.7.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 (32) hide show
  1. package/esm/__internal__/checkable-input/checkable-input.component.d.ts +2 -0
  2. package/esm/__internal__/checkable-input/checkable-input.component.js +3 -0
  3. package/esm/__internal__/form-field/form-field.component.d.ts +3 -1
  4. package/esm/__internal__/form-field/form-field.component.js +2 -1
  5. package/esm/components/checkbox/checkbox.component.js +1 -0
  6. package/esm/components/dialog/dialog.component.js +4 -6
  7. package/esm/components/dialog-full-screen/dialog-full-screen.component.js +4 -6
  8. package/esm/components/radio-button/radio-button.component.js +1 -0
  9. package/esm/components/sidebar/sidebar.component.js +4 -6
  10. package/esm/components/switch/switch.component.js +2 -0
  11. package/esm/components/toast/toast.component.js +5 -2
  12. package/esm/hooks/__internal__/useModalAria/index.d.ts +1 -0
  13. package/esm/hooks/__internal__/useModalAria/index.js +1 -0
  14. package/esm/hooks/__internal__/useModalAria/useModalAria.d.ts +2 -0
  15. package/esm/hooks/__internal__/useModalAria/useModalAria.js +45 -0
  16. package/lib/__internal__/checkable-input/checkable-input.component.d.ts +2 -0
  17. package/lib/__internal__/checkable-input/checkable-input.component.js +3 -0
  18. package/lib/__internal__/form-field/form-field.component.d.ts +3 -1
  19. package/lib/__internal__/form-field/form-field.component.js +2 -1
  20. package/lib/components/checkbox/checkbox.component.js +1 -0
  21. package/lib/components/dialog/dialog.component.js +3 -5
  22. package/lib/components/dialog-full-screen/dialog-full-screen.component.js +3 -5
  23. package/lib/components/radio-button/radio-button.component.js +1 -0
  24. package/lib/components/sidebar/sidebar.component.js +3 -5
  25. package/lib/components/switch/switch.component.js +2 -0
  26. package/lib/components/toast/toast.component.js +5 -2
  27. package/lib/hooks/__internal__/useModalAria/index.d.ts +1 -0
  28. package/lib/hooks/__internal__/useModalAria/index.js +13 -0
  29. package/lib/hooks/__internal__/useModalAria/package.json +6 -0
  30. package/lib/hooks/__internal__/useModalAria/useModalAria.d.ts +2 -0
  31. package/lib/hooks/__internal__/useModalAria/useModalAria.js +52 -0
  32. package/package.json +1 -1
@@ -4,6 +4,8 @@ import { ValidationProps } from "../validations";
4
4
  export interface CommonCheckableInputProps extends ValidationProps, CommonHiddenCheckableInputProps {
5
5
  /** If true, the component will be disabled */
6
6
  disabled?: boolean;
7
+ /** @private @ignore */
8
+ loading?: boolean;
7
9
  /** Help content to be displayed under an input */
8
10
  fieldHelp?: React.ReactNode;
9
11
  /**
@@ -14,6 +14,7 @@ const CheckableInput = /*#__PURE__*/React.forwardRef((_ref, ref) => {
14
14
  checked,
15
15
  children,
16
16
  disabled,
17
+ loading,
17
18
  error,
18
19
  fieldHelp,
19
20
  fieldHelpInline,
@@ -57,6 +58,7 @@ const CheckableInput = /*#__PURE__*/React.forwardRef((_ref, ref) => {
57
58
  const isRadio = type === "radio";
58
59
  const formFieldProps = {
59
60
  disabled,
61
+ loading,
60
62
  error,
61
63
  fieldHelp,
62
64
  fieldHelpInline,
@@ -217,6 +219,7 @@ CheckableInput.propTypes = {
217
219
  "labelWidth": PropTypes.number,
218
220
  "lang": PropTypes.string,
219
221
  "list": PropTypes.string,
222
+ "loading": PropTypes.bool,
220
223
  "max": PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
221
224
  "maxLength": PropTypes.number,
222
225
  "min": PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
@@ -7,6 +7,8 @@ import { IconType } from "../../components/icon";
7
7
  interface CommonFormFieldProps extends MarginProps, ValidationProps {
8
8
  /** If true, the component will be disabled */
9
9
  disabled?: boolean;
10
+ /** @private @ignore */
11
+ loading?: boolean;
10
12
  /** Help content to be displayed under an input */
11
13
  fieldHelp?: React.ReactNode;
12
14
  /** The unique id of the Help component tooltip, used for accessibility */
@@ -59,7 +61,7 @@ export interface FormFieldProps extends CommonFormFieldProps, TagProps {
59
61
  useValidationIcon?: boolean;
60
62
  }
61
63
  declare const FormField: {
62
- ({ children, "data-component": dataComponent, disabled, fieldHelp: fieldHelpContent, fieldHelpInline, error, warning, info, tooltipId, fieldHelpId, label, labelId, labelAlign, labelHelp, labelHelpIcon, labelInline, labelSpacing, labelWidth, labelAs, id, reverse, isOptional, useValidationIcon, adaptiveLabelBreakpoint, isRequired, validationIconId, validationRedesignOptIn, ...rest }: FormFieldProps): React.JSX.Element;
64
+ ({ children, "data-component": dataComponent, disabled, loading, fieldHelp: fieldHelpContent, fieldHelpInline, error, warning, info, tooltipId, fieldHelpId, label, labelId, labelAlign, labelHelp, labelHelpIcon, labelInline, labelSpacing, labelWidth, labelAs, id, reverse, isOptional, useValidationIcon, adaptiveLabelBreakpoint, isRequired, validationIconId, validationRedesignOptIn, ...rest }: FormFieldProps): React.JSX.Element;
63
65
  displayName: string;
64
66
  };
65
67
  export default FormField;
@@ -14,6 +14,7 @@ const FormField = _ref => {
14
14
  children,
15
15
  "data-component": dataComponent,
16
16
  disabled,
17
+ loading,
17
18
  fieldHelp: fieldHelpContent,
18
19
  fieldHelpInline,
19
20
  error,
@@ -46,7 +47,7 @@ const FormField = _ref => {
46
47
  warning: !!warning,
47
48
  info: !!info
48
49
  };
49
- if (!disabled) return undefined;
50
+ if (!(disabled && !loading)) return undefined;
50
51
  return Object.keys(validationProps).find(propName => validationProps[propName]);
51
52
  }, [error, warning, info, disabled]);
52
53
  !(invalidValidationProp === undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, `Prop \`${invalidValidationProp}\` cannot be used in conjunction with \`disabled\`. ` + "Use `readOnly` if you require users to see validations with a non-interactive field") : invariant(false) : void 0;
@@ -235,6 +235,7 @@ Checkbox.propTypes = {
235
235
  "labelWidth": PropTypes.number,
236
236
  "lang": PropTypes.string,
237
237
  "list": PropTypes.string,
238
+ "loading": PropTypes.bool,
238
239
  "m": PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.number, PropTypes.shape({
239
240
  "__@toStringTag": PropTypes.string.isRequired,
240
241
  "description": PropTypes.string,
@@ -1,5 +1,5 @@
1
1
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
- import React, { useRef, useEffect, useLayoutEffect, useCallback, useContext } from "react";
2
+ import React, { useRef, useEffect, useLayoutEffect, useCallback } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import createGuid from "../../__internal__/utils/helpers/guid";
5
5
  import Modal from "../modal";
@@ -12,7 +12,7 @@ import IconButton from "../icon-button";
12
12
  import Icon from "../icon";
13
13
  import useLocale from "../../hooks/__internal__/useLocale";
14
14
  import useIsStickyFooterForm from "../../hooks/__internal__/useIsStickyFooterForm";
15
- import TopModalContext from "../carbon-provider/top-modal-context";
15
+ import useModalAria from "../../hooks/__internal__/useModalAria/useModalAria";
16
16
  const PADDING_VALUES = [0, 1, 2, 3, 4, 5, 6, 7, 8];
17
17
  export const Dialog = _ref => {
18
18
  let {
@@ -49,9 +49,7 @@ export const Dialog = _ref => {
49
49
  current: subtitleId
50
50
  } = useRef(createGuid());
51
51
  const hasStickyFooter = useIsStickyFooterForm(children);
52
- const {
53
- topModal
54
- } = useContext(TopModalContext);
52
+ const isTopModal = useModalAria(dialogRef);
55
53
  const centerDialog = useCallback(() => {
56
54
  /* istanbul ignore if */
57
55
  if (!dialogRef.current) {
@@ -162,7 +160,7 @@ export const Dialog = _ref => {
162
160
  isOpen: open,
163
161
  additionalWrapperRefs: focusableContainers
164
162
  }, /*#__PURE__*/React.createElement(StyledDialog, _extends({
165
- "aria-modal": topModal?.contains(dialogRef.current) ? true : undefined,
163
+ "aria-modal": isTopModal ? true : undefined,
166
164
  ref: dialogRef,
167
165
  topMargin: TOP_MARGIN
168
166
  }, dialogProps, {
@@ -1,5 +1,5 @@
1
1
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
- import React, { useRef, useContext } from "react";
2
+ import React, { useRef } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import createGuid from "../../__internal__/utils/helpers/guid";
5
5
  import Modal from "../modal";
@@ -12,7 +12,7 @@ import IconButton from "../icon-button";
12
12
  import Icon from "../icon";
13
13
  import useLocale from "../../hooks/__internal__/useLocale";
14
14
  import useIsStickyFooterForm from "../../hooks/__internal__/useIsStickyFooterForm";
15
- import TopModalContext from "../carbon-provider/top-modal-context";
15
+ import useModalAria from "../../hooks/__internal__/useModalAria/useModalAria";
16
16
  export const DialogFullScreen = _ref => {
17
17
  let {
18
18
  "aria-describedby": ariaDescribedBy,
@@ -48,9 +48,7 @@ export const DialogFullScreen = _ref => {
48
48
  current: subtitleId
49
49
  } = useRef(createGuid());
50
50
  const hasStickyFooter = useIsStickyFooterForm(children);
51
- const {
52
- topModal
53
- } = useContext(TopModalContext);
51
+ const isTopModal = useModalAria(dialogRef);
54
52
  const closeIcon = () => {
55
53
  if (!showCloseIcon || !onCancel) return null;
56
54
  return /*#__PURE__*/React.createElement(IconButton, {
@@ -96,7 +94,7 @@ export const DialogFullScreen = _ref => {
96
94
  additionalWrapperRefs: focusableContainers,
97
95
  focusableSelectors: focusableSelectors
98
96
  }, /*#__PURE__*/React.createElement(StyledDialogFullScreen, _extends({
99
- "aria-modal": role === "dialog" && topModal?.contains(dialogRef.current) ? true : undefined
97
+ "aria-modal": role === "dialog" && isTopModal ? true : undefined
100
98
  }, ariaProps, {
101
99
  ref: dialogRef,
102
100
  "data-element": "dialog-full-screen",
@@ -240,6 +240,7 @@ RadioButton.propTypes = {
240
240
  "labelWidth": PropTypes.number,
241
241
  "lang": PropTypes.string,
242
242
  "list": PropTypes.string,
243
+ "loading": PropTypes.bool,
243
244
  "m": PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.number, PropTypes.shape({
244
245
  "__@toStringTag": PropTypes.string.isRequired,
245
246
  "description": PropTypes.string,
@@ -1,5 +1,5 @@
1
1
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
- import React, { useCallback, useContext, useRef } from "react";
2
+ import React, { useCallback, useRef } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import Modal from "../modal";
5
5
  import StyledSidebar from "./sidebar.style";
@@ -12,7 +12,7 @@ import createGuid from "../../__internal__/utils/helpers/guid";
12
12
  import useLocale from "../../hooks/__internal__/useLocale";
13
13
  import { filterStyledSystemPaddingProps } from "../../style/utils";
14
14
  import useIsStickyFooterForm from "../../hooks/__internal__/useIsStickyFooterForm";
15
- import TopModalContext from "../carbon-provider/top-modal-context";
15
+ import useModalAria from "../../hooks/__internal__/useModalAria/useModalAria";
16
16
 
17
17
  // TODO FE-5408 will investigate why React.RefObject<T> produces a failed prop type when current = null
18
18
 
@@ -52,9 +52,7 @@ const Sidebar = /*#__PURE__*/React.forwardRef((_ref, ref) => {
52
52
  if (typeof ref === "object") ref.current = reference;
53
53
  if (typeof ref === "function") ref(reference);
54
54
  }, [ref]);
55
- const {
56
- topModal
57
- } = useContext(TopModalContext);
55
+ const isTopModal = useModalAria(sidebarRef);
58
56
  const closeIcon = () => {
59
57
  if (!onCancel) return null;
60
58
  return /*#__PURE__*/React.createElement(IconButton, {
@@ -71,7 +69,7 @@ const Sidebar = /*#__PURE__*/React.forwardRef((_ref, ref) => {
71
69
  "data-role": rest["data-role"]
72
70
  };
73
71
  const sidebar = /*#__PURE__*/React.createElement(StyledSidebar, _extends({
74
- "aria-modal": !enableBackgroundUI && topModal?.contains(sidebarRef.current),
72
+ "aria-modal": !enableBackgroundUI && isTopModal,
75
73
  "aria-describedby": ariaDescribedBy,
76
74
  "aria-label": ariaLabel,
77
75
  "aria-labelledby": !ariaLabelledBy && !ariaLabel ? headerId : ariaLabelledBy,
@@ -99,6 +99,7 @@ const Switch = /*#__PURE__*/React.forwardRef((_ref, ref) => {
99
99
  warning,
100
100
  info,
101
101
  disabled: disabled || loading,
102
+ loading,
102
103
  checked: isControlled ? checked : checkedInternal,
103
104
  label,
104
105
  labelHelp,
@@ -143,6 +144,7 @@ const Switch = /*#__PURE__*/React.forwardRef((_ref, ref) => {
143
144
  error,
144
145
  warning,
145
146
  disabled: disabled || loading,
147
+ loading,
146
148
  checked: isControlled ? checked : checkedInternal,
147
149
  onBlur,
148
150
  onFocus,
@@ -58,8 +58,11 @@ const Toast = /*#__PURE__*/React.forwardRef((_ref, ref) => {
58
58
  useEffect(() => {
59
59
  if (!disableAutoFocus) {
60
60
  if (open) {
61
- focusedElementBeforeOpening.current = document.activeElement;
62
- toastContentNodeRef.current?.focus();
61
+ // setTimeout needed as otherwise this runs before the ref is populated
62
+ setTimeout(() => {
63
+ focusedElementBeforeOpening.current = document.activeElement;
64
+ toastContentNodeRef.current?.focus();
65
+ }, 0);
63
66
  } else if (focusedElementBeforeOpening.current) {
64
67
  focusedElementBeforeOpening.current.focus();
65
68
  focusedElementBeforeOpening.current = null;
@@ -0,0 +1 @@
1
+ export { default } from "./useModalAria";
@@ -0,0 +1 @@
1
+ export { default } from "./useModalAria";
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export default function useModalAria(containerRef: React.RefObject<HTMLDivElement>): boolean | undefined;
@@ -0,0 +1,45 @@
1
+ import { useContext, useEffect } from "react";
2
+ import TopModalContext from "../../../components/carbon-provider/top-modal-context";
3
+ export default function useModalAria(containerRef) {
4
+ const {
5
+ topModal
6
+ } = useContext(TopModalContext);
7
+ const isTopModal = topModal?.contains(containerRef.current);
8
+ useEffect(() => {
9
+ const originalValues = [];
10
+ const hideNonTopModalElements = rootElement => {
11
+ if (!rootElement.contains(topModal)) {
12
+ originalValues.push({
13
+ element: rootElement,
14
+ "aria-hidden": rootElement.getAttribute("aria-hidden"),
15
+ inert: rootElement.getAttribute("inert")
16
+ });
17
+ rootElement.setAttribute("aria-hidden", "true");
18
+ rootElement.setAttribute("inert", "");
19
+ } else if (rootElement !== topModal) {
20
+ Array.from(rootElement.children).forEach(hideNonTopModalElements);
21
+ }
22
+ };
23
+ if (isTopModal) {
24
+ hideNonTopModalElements(document.body);
25
+ }
26
+ return () => originalValues.forEach(_ref => {
27
+ let {
28
+ element,
29
+ "aria-hidden": ariaHidden,
30
+ inert
31
+ } = _ref;
32
+ if (ariaHidden === null) {
33
+ element.removeAttribute("aria-hidden");
34
+ } else {
35
+ element.setAttribute("aria-hidden", ariaHidden);
36
+ }
37
+ if (inert === null) {
38
+ element.removeAttribute("inert");
39
+ } else {
40
+ element.setAttribute("inert", inert);
41
+ }
42
+ });
43
+ }, [topModal, isTopModal]);
44
+ return isTopModal;
45
+ }
@@ -4,6 +4,8 @@ import { ValidationProps } from "../validations";
4
4
  export interface CommonCheckableInputProps extends ValidationProps, CommonHiddenCheckableInputProps {
5
5
  /** If true, the component will be disabled */
6
6
  disabled?: boolean;
7
+ /** @private @ignore */
8
+ loading?: boolean;
7
9
  /** Help content to be displayed under an input */
8
10
  fieldHelp?: React.ReactNode;
9
11
  /**
@@ -23,6 +23,7 @@ const CheckableInput = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
23
23
  checked,
24
24
  children,
25
25
  disabled,
26
+ loading,
26
27
  error,
27
28
  fieldHelp,
28
29
  fieldHelpInline,
@@ -66,6 +67,7 @@ const CheckableInput = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
66
67
  const isRadio = type === "radio";
67
68
  const formFieldProps = {
68
69
  disabled,
70
+ loading,
69
71
  error,
70
72
  fieldHelp,
71
73
  fieldHelpInline,
@@ -226,6 +228,7 @@ CheckableInput.propTypes = {
226
228
  "labelWidth": _propTypes.default.number,
227
229
  "lang": _propTypes.default.string,
228
230
  "list": _propTypes.default.string,
231
+ "loading": _propTypes.default.bool,
229
232
  "max": _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
230
233
  "maxLength": _propTypes.default.number,
231
234
  "min": _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
@@ -7,6 +7,8 @@ import { IconType } from "../../components/icon";
7
7
  interface CommonFormFieldProps extends MarginProps, ValidationProps {
8
8
  /** If true, the component will be disabled */
9
9
  disabled?: boolean;
10
+ /** @private @ignore */
11
+ loading?: boolean;
10
12
  /** Help content to be displayed under an input */
11
13
  fieldHelp?: React.ReactNode;
12
14
  /** The unique id of the Help component tooltip, used for accessibility */
@@ -59,7 +61,7 @@ export interface FormFieldProps extends CommonFormFieldProps, TagProps {
59
61
  useValidationIcon?: boolean;
60
62
  }
61
63
  declare const FormField: {
62
- ({ children, "data-component": dataComponent, disabled, fieldHelp: fieldHelpContent, fieldHelpInline, error, warning, info, tooltipId, fieldHelpId, label, labelId, labelAlign, labelHelp, labelHelpIcon, labelInline, labelSpacing, labelWidth, labelAs, id, reverse, isOptional, useValidationIcon, adaptiveLabelBreakpoint, isRequired, validationIconId, validationRedesignOptIn, ...rest }: FormFieldProps): React.JSX.Element;
64
+ ({ children, "data-component": dataComponent, disabled, loading, fieldHelp: fieldHelpContent, fieldHelpInline, error, warning, info, tooltipId, fieldHelpId, label, labelId, labelAlign, labelHelp, labelHelpIcon, labelInline, labelSpacing, labelWidth, labelAs, id, reverse, isOptional, useValidationIcon, adaptiveLabelBreakpoint, isRequired, validationIconId, validationRedesignOptIn, ...rest }: FormFieldProps): React.JSX.Element;
63
65
  displayName: string;
64
66
  };
65
67
  export default FormField;
@@ -23,6 +23,7 @@ const FormField = _ref => {
23
23
  children,
24
24
  "data-component": dataComponent,
25
25
  disabled,
26
+ loading,
26
27
  fieldHelp: fieldHelpContent,
27
28
  fieldHelpInline,
28
29
  error,
@@ -55,7 +56,7 @@ const FormField = _ref => {
55
56
  warning: !!warning,
56
57
  info: !!info
57
58
  };
58
- if (!disabled) return undefined;
59
+ if (!(disabled && !loading)) return undefined;
59
60
  return Object.keys(validationProps).find(propName => validationProps[propName]);
60
61
  }, [error, warning, info, disabled]);
61
62
  !(invalidValidationProp === undefined) ? process.env.NODE_ENV !== "production" ? (0, _invariant.default)(false, `Prop \`${invalidValidationProp}\` cannot be used in conjunction with \`disabled\`. ` + "Use `readOnly` if you require users to see validations with a non-interactive field") : (0, _invariant.default)(false) : void 0;
@@ -245,6 +245,7 @@ Checkbox.propTypes = {
245
245
  "labelWidth": _propTypes.default.number,
246
246
  "lang": _propTypes.default.string,
247
247
  "list": _propTypes.default.string,
248
+ "loading": _propTypes.default.bool,
248
249
  "m": _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.oneOf([null]), _propTypes.default.number, _propTypes.default.shape({
249
250
  "__@toStringTag": _propTypes.default.string.isRequired,
250
251
  "description": _propTypes.default.string,
@@ -17,7 +17,7 @@ var _iconButton = _interopRequireDefault(require("../icon-button"));
17
17
  var _icon = _interopRequireDefault(require("../icon"));
18
18
  var _useLocale = _interopRequireDefault(require("../../hooks/__internal__/useLocale"));
19
19
  var _useIsStickyFooterForm = _interopRequireDefault(require("../../hooks/__internal__/useIsStickyFooterForm"));
20
- var _topModalContext = _interopRequireDefault(require("../carbon-provider/top-modal-context"));
20
+ var _useModalAria = _interopRequireDefault(require("../../hooks/__internal__/useModalAria/useModalAria"));
21
21
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
22
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
23
23
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -58,9 +58,7 @@ const Dialog = _ref => {
58
58
  current: subtitleId
59
59
  } = (0, _react.useRef)((0, _guid.default)());
60
60
  const hasStickyFooter = (0, _useIsStickyFooterForm.default)(children);
61
- const {
62
- topModal
63
- } = (0, _react.useContext)(_topModalContext.default);
61
+ const isTopModal = (0, _useModalAria.default)(dialogRef);
64
62
  const centerDialog = (0, _react.useCallback)(() => {
65
63
  /* istanbul ignore if */
66
64
  if (!dialogRef.current) {
@@ -171,7 +169,7 @@ const Dialog = _ref => {
171
169
  isOpen: open,
172
170
  additionalWrapperRefs: focusableContainers
173
171
  }, /*#__PURE__*/_react.default.createElement(_dialog.StyledDialog, _extends({
174
- "aria-modal": topModal?.contains(dialogRef.current) ? true : undefined,
172
+ "aria-modal": isTopModal ? true : undefined,
175
173
  ref: dialogRef,
176
174
  topMargin: _dialog2.TOP_MARGIN
177
175
  }, dialogProps, {
@@ -17,7 +17,7 @@ var _iconButton = _interopRequireDefault(require("../icon-button"));
17
17
  var _icon = _interopRequireDefault(require("../icon"));
18
18
  var _useLocale = _interopRequireDefault(require("../../hooks/__internal__/useLocale"));
19
19
  var _useIsStickyFooterForm = _interopRequireDefault(require("../../hooks/__internal__/useIsStickyFooterForm"));
20
- var _topModalContext = _interopRequireDefault(require("../carbon-provider/top-modal-context"));
20
+ var _useModalAria = _interopRequireDefault(require("../../hooks/__internal__/useModalAria/useModalAria"));
21
21
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
22
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
23
23
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -57,9 +57,7 @@ const DialogFullScreen = _ref => {
57
57
  current: subtitleId
58
58
  } = (0, _react.useRef)((0, _guid.default)());
59
59
  const hasStickyFooter = (0, _useIsStickyFooterForm.default)(children);
60
- const {
61
- topModal
62
- } = (0, _react.useContext)(_topModalContext.default);
60
+ const isTopModal = (0, _useModalAria.default)(dialogRef);
63
61
  const closeIcon = () => {
64
62
  if (!showCloseIcon || !onCancel) return null;
65
63
  return /*#__PURE__*/_react.default.createElement(_iconButton.default, {
@@ -105,7 +103,7 @@ const DialogFullScreen = _ref => {
105
103
  additionalWrapperRefs: focusableContainers,
106
104
  focusableSelectors: focusableSelectors
107
105
  }, /*#__PURE__*/_react.default.createElement(_dialogFullScreen.default, _extends({
108
- "aria-modal": role === "dialog" && topModal?.contains(dialogRef.current) ? true : undefined
106
+ "aria-modal": role === "dialog" && isTopModal ? true : undefined
109
107
  }, ariaProps, {
110
108
  ref: dialogRef,
111
109
  "data-element": "dialog-full-screen",
@@ -250,6 +250,7 @@ RadioButton.propTypes = {
250
250
  "labelWidth": _propTypes.default.number,
251
251
  "lang": _propTypes.default.string,
252
252
  "list": _propTypes.default.string,
253
+ "loading": _propTypes.default.bool,
253
254
  "m": _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.oneOf([null]), _propTypes.default.number, _propTypes.default.shape({
254
255
  "__@toStringTag": _propTypes.default.string.isRequired,
255
256
  "description": _propTypes.default.string,
@@ -17,7 +17,7 @@ var _guid = _interopRequireDefault(require("../../__internal__/utils/helpers/gui
17
17
  var _useLocale = _interopRequireDefault(require("../../hooks/__internal__/useLocale"));
18
18
  var _utils = require("../../style/utils");
19
19
  var _useIsStickyFooterForm = _interopRequireDefault(require("../../hooks/__internal__/useIsStickyFooterForm"));
20
- var _topModalContext = _interopRequireDefault(require("../carbon-provider/top-modal-context"));
20
+ var _useModalAria = _interopRequireDefault(require("../../hooks/__internal__/useModalAria/useModalAria"));
21
21
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
22
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
23
23
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -61,9 +61,7 @@ const Sidebar = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
61
61
  if (typeof ref === "object") ref.current = reference;
62
62
  if (typeof ref === "function") ref(reference);
63
63
  }, [ref]);
64
- const {
65
- topModal
66
- } = (0, _react.useContext)(_topModalContext.default);
64
+ const isTopModal = (0, _useModalAria.default)(sidebarRef);
67
65
  const closeIcon = () => {
68
66
  if (!onCancel) return null;
69
67
  return /*#__PURE__*/_react.default.createElement(_iconButton.default, {
@@ -80,7 +78,7 @@ const Sidebar = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
80
78
  "data-role": rest["data-role"]
81
79
  };
82
80
  const sidebar = /*#__PURE__*/_react.default.createElement(_sidebar.default, _extends({
83
- "aria-modal": !enableBackgroundUI && topModal?.contains(sidebarRef.current),
81
+ "aria-modal": !enableBackgroundUI && isTopModal,
84
82
  "aria-describedby": ariaDescribedBy,
85
83
  "aria-label": ariaLabel,
86
84
  "aria-labelledby": !ariaLabelledBy && !ariaLabel ? headerId : ariaLabelledBy,
@@ -108,6 +108,7 @@ const Switch = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
108
108
  warning,
109
109
  info,
110
110
  disabled: disabled || loading,
111
+ loading,
111
112
  checked: isControlled ? checked : checkedInternal,
112
113
  label,
113
114
  labelHelp,
@@ -152,6 +153,7 @@ const Switch = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
152
153
  error,
153
154
  warning,
154
155
  disabled: disabled || loading,
156
+ loading,
155
157
  checked: isControlled ? checked : checkedInternal,
156
158
  onBlur,
157
159
  onFocus,
@@ -67,8 +67,11 @@ const Toast = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
67
67
  (0, _react.useEffect)(() => {
68
68
  if (!disableAutoFocus) {
69
69
  if (open) {
70
- focusedElementBeforeOpening.current = document.activeElement;
71
- toastContentNodeRef.current?.focus();
70
+ // setTimeout needed as otherwise this runs before the ref is populated
71
+ setTimeout(() => {
72
+ focusedElementBeforeOpening.current = document.activeElement;
73
+ toastContentNodeRef.current?.focus();
74
+ }, 0);
72
75
  } else if (focusedElementBeforeOpening.current) {
73
76
  focusedElementBeforeOpening.current.focus();
74
77
  focusedElementBeforeOpening.current = null;
@@ -0,0 +1 @@
1
+ export { default } from "./useModalAria";
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _useModalAria.default;
10
+ }
11
+ });
12
+ var _useModalAria = _interopRequireDefault(require("./useModalAria"));
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,6 @@
1
+ {
2
+ "sideEffects": false,
3
+ "module": "../../../../esm/hooks/__internal__/useModalAria/index.js",
4
+ "main": "./index.js",
5
+ "types": "./index.d.ts"
6
+ }
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export default function useModalAria(containerRef: React.RefObject<HTMLDivElement>): boolean | undefined;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = useModalAria;
7
+ var _react = require("react");
8
+ var _topModalContext = _interopRequireDefault(require("../../../components/carbon-provider/top-modal-context"));
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+ function useModalAria(containerRef) {
11
+ const {
12
+ topModal
13
+ } = (0, _react.useContext)(_topModalContext.default);
14
+ const isTopModal = topModal?.contains(containerRef.current);
15
+ (0, _react.useEffect)(() => {
16
+ const originalValues = [];
17
+ const hideNonTopModalElements = rootElement => {
18
+ if (!rootElement.contains(topModal)) {
19
+ originalValues.push({
20
+ element: rootElement,
21
+ "aria-hidden": rootElement.getAttribute("aria-hidden"),
22
+ inert: rootElement.getAttribute("inert")
23
+ });
24
+ rootElement.setAttribute("aria-hidden", "true");
25
+ rootElement.setAttribute("inert", "");
26
+ } else if (rootElement !== topModal) {
27
+ Array.from(rootElement.children).forEach(hideNonTopModalElements);
28
+ }
29
+ };
30
+ if (isTopModal) {
31
+ hideNonTopModalElements(document.body);
32
+ }
33
+ return () => originalValues.forEach(_ref => {
34
+ let {
35
+ element,
36
+ "aria-hidden": ariaHidden,
37
+ inert
38
+ } = _ref;
39
+ if (ariaHidden === null) {
40
+ element.removeAttribute("aria-hidden");
41
+ } else {
42
+ element.setAttribute("aria-hidden", ariaHidden);
43
+ }
44
+ if (inert === null) {
45
+ element.removeAttribute("inert");
46
+ } else {
47
+ element.setAttribute("inert", inert);
48
+ }
49
+ });
50
+ }, [topModal, isTopModal]);
51
+ return isTopModal;
52
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carbon-react",
3
- "version": "119.7.0",
3
+ "version": "119.7.2",
4
4
  "description": "A library of reusable React components for easily building user interfaces.",
5
5
  "files": [
6
6
  "lib",