@atlaskit/modal-dialog 14.18.3 → 15.0.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/modal-dialog
2
2
 
3
+ ## 15.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [`babe23b40c154`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/babe23b40c154) -
8
+ Removes the `boolean` type for the `autoFocus` prop in the modal dialog. This improves the
9
+ accessibility of the modal dialog by ensuring focus always moves to the first interactive element,
10
+ as per the WCAG accessibility guidelines for modal dialogs.
11
+
12
+ You can run the included codemod to remove all boolean instances of `autoFocus`.
13
+
14
+ ### Patch Changes
15
+
16
+ - Updated dependencies
17
+
3
18
  ## 14.18.3
4
19
 
5
20
  ### Patch Changes
@@ -1,9 +1,9 @@
1
1
  import type { API, FileInfo, Options } from 'jscodeshift';
2
2
 
3
- import { removeAutoFocus } from './migrations/remove-props';
3
+ import { removeBooleanAutoFocus } from './migrations/remove-props';
4
4
  import { createTransformer } from './utils/create-transformer';
5
5
 
6
6
  const transformer: (fileInfo: FileInfo, { jscodeshift }: API, options: Options) => string =
7
- createTransformer('@atlaskit/modal-dialog', [removeAutoFocus]);
7
+ createTransformer('@atlaskit/modal-dialog', [removeBooleanAutoFocus]);
8
8
 
9
9
  export default transformer;
@@ -1,6 +1,6 @@
1
1
  jest.autoMockOff();
2
2
 
3
- import transformer from '../not-yet-boolean-autofocus-removal';
3
+ import transformer from '../15.0.0-boolean-autofocus-removal';
4
4
 
5
5
  const defineInlineTest = require('jscodeshift/dist/testUtils').defineInlineTest;
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { createRemoveFuncIfBooleanFor } from '../utils/create-remove-func-if-boolean-for';
2
2
 
3
- export const removeAutoFocus: (
3
+ export const removeBooleanAutoFocus: (
4
4
  j: import('jscodeshift/src/core').JSCodeshift,
5
5
  source: import('jscodeshift/src/Collection').Collection<Node>,
6
6
  ) => void = createRemoveFuncIfBooleanFor('@atlaskit/modal-dialog', 'ModalDialog', 'autoFocus');
@@ -65,7 +65,7 @@ var ModalDialog = function ModalDialog(props) {
65
65
  _props$shouldScrollIn = props.shouldScrollInViewport,
66
66
  shouldScrollInViewport = _props$shouldScrollIn === void 0 ? false : _props$shouldScrollIn,
67
67
  shouldCloseOnEscapePress = props.shouldCloseOnEscapePress,
68
- providedAutoFocus = props.autoFocus,
68
+ autoFocus = props.autoFocus,
69
69
  stackIndex = props.stackIndex,
70
70
  onClose = props.onClose,
71
71
  onCloseComplete = props.onCloseComplete,
@@ -82,10 +82,6 @@ var ModalDialog = function ModalDialog(props) {
82
82
  var id = (0, _useId.useId)();
83
83
  var titleId = "modal-dialog-title-".concat(id);
84
84
  var defaultTestId = testId || 'modal-dialog';
85
- // https://product-fabric.atlassian.net/browse/DSP-24307
86
- // If flag and falsy, use true instead.
87
- // When we remove boolean `autoFocus`, we won't have to worry about this
88
- var autoFocus = !providedAutoFocus ? true : providedAutoFocus;
89
85
  (0, _react.useEffect)(function () {
90
86
  // Modal dialogs can appear on top of iframe elements that are on another domain.
91
87
  // There is a Chrome bug where drag and drop in an element on top of a cross domain
@@ -97,7 +93,7 @@ var ModalDialog = function ModalDialog(props) {
97
93
 
98
94
  return (0, _combine.combine)((0, _element.disableDraggingToCrossOriginIFramesForElement)(), (0, _textSelection.disableDraggingToCrossOriginIFramesForTextSelection)(), (0, _external.disableDraggingToCrossOriginIFramesForExternal)());
99
95
  }, []);
100
- (0, _useAutoFocus.default)((0, _typeof2.default)(autoFocus) === 'object' ? autoFocus : undefined,
96
+ (0, _useAutoFocus.default)(autoFocus,
101
97
  // When a user supplies a ref to focus we enable this hook
102
98
  (0, _typeof2.default)(autoFocus) === 'object');
103
99
  var _useOnMotionFinish = (0, _useOnMotionFinish3.default)({
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
5
- var _typeof = require("@babel/runtime/helpers/typeof");
5
+ var _typeof3 = require("@babel/runtime/helpers/typeof");
6
6
  Object.defineProperty(exports, "__esModule", {
7
7
  value: true
8
8
  });
@@ -12,6 +12,7 @@ var _react = _interopRequireWildcard(require("react"));
12
12
  var React = _react;
13
13
  var _runtime = require("@compiled/react/runtime");
14
14
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
15
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
15
16
  var _reactFocusLock = _interopRequireDefault(require("react-focus-lock"));
16
17
  var _reactScrolllock = _interopRequireWildcard(require("react-scrolllock"));
17
18
  var _analyticsNext = require("@atlaskit/analytics-next");
@@ -27,7 +28,7 @@ var _constants = require("@atlaskit/theme/constants");
27
28
  var _useModalStack = _interopRequireDefault(require("../hooks/use-modal-stack"));
28
29
  var _usePreventProgrammaticScroll = _interopRequireDefault(require("../hooks/use-prevent-programmatic-scroll"));
29
30
  var _modalDialog = _interopRequireDefault(require("./modal-dialog"));
30
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
31
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
31
32
  var fillScreenStyles = null;
32
33
  var allowlistElements = function allowlistElements(element, callback) {
33
34
  // Allow focus to reach elements outside the modal:
@@ -53,8 +54,7 @@ var allowlistElements = function allowlistElements(element, callback) {
53
54
  * - [Usage](https://atlassian.design/components/modal-dialog/usage)
54
55
  */
55
56
  var InternalModalWrapper = function InternalModalWrapper(props) {
56
- var _props$autoFocus = props.autoFocus,
57
- autoFocus = _props$autoFocus === void 0 ? true : _props$autoFocus,
57
+ var autoFocus = props.autoFocus,
58
58
  focusLockAllowlist = props.focusLockAllowlist,
59
59
  _props$shouldCloseOnE = props.shouldCloseOnEscapePress,
60
60
  shouldCloseOnEscapePress = _props$shouldCloseOnE === void 0 ? true : _props$shouldCloseOnE,
@@ -85,16 +85,14 @@ var InternalModalWrapper = function InternalModalWrapper(props) {
85
85
  var stackIndex = stackIndexOverride || calculatedStackIndex;
86
86
  var isForeground = stackIndex === 0;
87
87
 
88
- // When a user supplies a ref to focus we skip auto focus via react-focus-lock
89
- // When flag is true and a ref is not supplied, autofocus is true. See https://product-fabric.atlassian.net/browse/DSP-24307
90
- // When we remove boolean `autoFocus`, we won't have to worry about this
91
- var autoFocusLock = typeof autoFocus === 'boolean';
88
+ // If no ref is provided, autofocus on first element
89
+ var autoFocusLock = !((0, _typeof2.default)(autoFocus) === 'object');
92
90
  var onCloseHandler = (0, _analyticsNext.usePlatformLeafEventHandler)({
93
91
  fn: providedOnClose || _noop.default,
94
92
  action: 'closed',
95
93
  componentName: 'modalDialog',
96
94
  packageName: "@atlaskit/modal-dialog",
97
- packageVersion: "0.0.0-development"
95
+ packageVersion: "14.18.3"
98
96
  });
99
97
  var onBlanketClicked = (0, _react.useCallback)(function (e) {
100
98
  if (shouldCloseOnOverlayClick) {
@@ -53,7 +53,7 @@ const ModalDialog = props => {
53
53
  width = 'medium',
54
54
  shouldScrollInViewport = false,
55
55
  shouldCloseOnEscapePress,
56
- autoFocus: providedAutoFocus,
56
+ autoFocus,
57
57
  stackIndex,
58
58
  onClose,
59
59
  onCloseComplete,
@@ -69,10 +69,6 @@ const ModalDialog = props => {
69
69
  const id = useId();
70
70
  const titleId = `modal-dialog-title-${id}`;
71
71
  const defaultTestId = testId || 'modal-dialog';
72
- // https://product-fabric.atlassian.net/browse/DSP-24307
73
- // If flag and falsy, use true instead.
74
- // When we remove boolean `autoFocus`, we won't have to worry about this
75
- const autoFocus = !providedAutoFocus ? true : providedAutoFocus;
76
72
  useEffect(() => {
77
73
  // Modal dialogs can appear on top of iframe elements that are on another domain.
78
74
  // There is a Chrome bug where drag and drop in an element on top of a cross domain
@@ -84,7 +80,7 @@ const ModalDialog = props => {
84
80
 
85
81
  return combine(disableDraggingToCrossOriginIFramesForElement(), disableDraggingToCrossOriginIFramesForTextSelection(), disableDraggingToCrossOriginIFramesForExternal());
86
82
  }, []);
87
- useAutoFocus(typeof autoFocus === 'object' ? autoFocus : undefined,
83
+ useAutoFocus(autoFocus,
88
84
  // When a user supplies a ref to focus we enable this hook
89
85
  typeof autoFocus === 'object');
90
86
  const [motionRef, onMotionFinish] = useOnMotionFinish({
@@ -45,7 +45,7 @@ const allowlistElements = (element, callback) => {
45
45
  */
46
46
  const InternalModalWrapper = props => {
47
47
  const {
48
- autoFocus = true,
48
+ autoFocus,
49
49
  focusLockAllowlist,
50
50
  shouldCloseOnEscapePress = true,
51
51
  shouldCloseOnOverlayClick = true,
@@ -71,16 +71,14 @@ const InternalModalWrapper = props => {
71
71
  const stackIndex = stackIndexOverride || calculatedStackIndex;
72
72
  const isForeground = stackIndex === 0;
73
73
 
74
- // When a user supplies a ref to focus we skip auto focus via react-focus-lock
75
- // When flag is true and a ref is not supplied, autofocus is true. See https://product-fabric.atlassian.net/browse/DSP-24307
76
- // When we remove boolean `autoFocus`, we won't have to worry about this
77
- const autoFocusLock = typeof autoFocus === 'boolean';
74
+ // If no ref is provided, autofocus on first element
75
+ const autoFocusLock = !(typeof autoFocus === 'object');
78
76
  const onCloseHandler = usePlatformLeafEventHandler({
79
77
  fn: providedOnClose || noop,
80
78
  action: 'closed',
81
79
  componentName: 'modalDialog',
82
80
  packageName: "@atlaskit/modal-dialog",
83
- packageVersion: "0.0.0-development"
81
+ packageVersion: "14.18.3"
84
82
  });
85
83
  const onBlanketClicked = useCallback(e => {
86
84
  if (shouldCloseOnOverlayClick) {
@@ -56,7 +56,7 @@ var ModalDialog = function ModalDialog(props) {
56
56
  _props$shouldScrollIn = props.shouldScrollInViewport,
57
57
  shouldScrollInViewport = _props$shouldScrollIn === void 0 ? false : _props$shouldScrollIn,
58
58
  shouldCloseOnEscapePress = props.shouldCloseOnEscapePress,
59
- providedAutoFocus = props.autoFocus,
59
+ autoFocus = props.autoFocus,
60
60
  stackIndex = props.stackIndex,
61
61
  onClose = props.onClose,
62
62
  onCloseComplete = props.onCloseComplete,
@@ -73,10 +73,6 @@ var ModalDialog = function ModalDialog(props) {
73
73
  var id = useId();
74
74
  var titleId = "modal-dialog-title-".concat(id);
75
75
  var defaultTestId = testId || 'modal-dialog';
76
- // https://product-fabric.atlassian.net/browse/DSP-24307
77
- // If flag and falsy, use true instead.
78
- // When we remove boolean `autoFocus`, we won't have to worry about this
79
- var autoFocus = !providedAutoFocus ? true : providedAutoFocus;
80
76
  useEffect(function () {
81
77
  // Modal dialogs can appear on top of iframe elements that are on another domain.
82
78
  // There is a Chrome bug where drag and drop in an element on top of a cross domain
@@ -88,7 +84,7 @@ var ModalDialog = function ModalDialog(props) {
88
84
 
89
85
  return combine(disableDraggingToCrossOriginIFramesForElement(), disableDraggingToCrossOriginIFramesForTextSelection(), disableDraggingToCrossOriginIFramesForExternal());
90
86
  }, []);
91
- useAutoFocus(_typeof(autoFocus) === 'object' ? autoFocus : undefined,
87
+ useAutoFocus(autoFocus,
92
88
  // When a user supplies a ref to focus we enable this hook
93
89
  _typeof(autoFocus) === 'object');
94
90
  var _useOnMotionFinish = useOnMotionFinish({
@@ -1,5 +1,6 @@
1
1
  /* modal-wrapper.tsx generated by @compiled/babel-plugin v0.39.1 */
2
2
  import _extends from "@babel/runtime/helpers/extends";
3
+ import _typeof from "@babel/runtime/helpers/typeof";
3
4
  import "./modal-wrapper.compiled.css";
4
5
  import * as React from 'react';
5
6
  import { ax, ix } from "@compiled/react/runtime";
@@ -44,8 +45,7 @@ var allowlistElements = function allowlistElements(element, callback) {
44
45
  * - [Usage](https://atlassian.design/components/modal-dialog/usage)
45
46
  */
46
47
  var InternalModalWrapper = function InternalModalWrapper(props) {
47
- var _props$autoFocus = props.autoFocus,
48
- autoFocus = _props$autoFocus === void 0 ? true : _props$autoFocus,
48
+ var autoFocus = props.autoFocus,
49
49
  focusLockAllowlist = props.focusLockAllowlist,
50
50
  _props$shouldCloseOnE = props.shouldCloseOnEscapePress,
51
51
  shouldCloseOnEscapePress = _props$shouldCloseOnE === void 0 ? true : _props$shouldCloseOnE,
@@ -76,16 +76,14 @@ var InternalModalWrapper = function InternalModalWrapper(props) {
76
76
  var stackIndex = stackIndexOverride || calculatedStackIndex;
77
77
  var isForeground = stackIndex === 0;
78
78
 
79
- // When a user supplies a ref to focus we skip auto focus via react-focus-lock
80
- // When flag is true and a ref is not supplied, autofocus is true. See https://product-fabric.atlassian.net/browse/DSP-24307
81
- // When we remove boolean `autoFocus`, we won't have to worry about this
82
- var autoFocusLock = typeof autoFocus === 'boolean';
79
+ // If no ref is provided, autofocus on first element
80
+ var autoFocusLock = !(_typeof(autoFocus) === 'object');
83
81
  var onCloseHandler = usePlatformLeafEventHandler({
84
82
  fn: providedOnClose || noop,
85
83
  action: 'closed',
86
84
  componentName: 'modalDialog',
87
85
  packageName: "@atlaskit/modal-dialog",
88
- packageVersion: "0.0.0-development"
86
+ packageVersion: "14.18.3"
89
87
  });
90
88
  var onBlanketClicked = useCallback(function (e) {
91
89
  if (shouldCloseOnOverlayClick) {
@@ -19,10 +19,8 @@ export interface ModalDialogProps {
19
19
  * accessibility regressions. Pass an element `ref` to focus on a specific element.
20
20
  *
21
21
  * Default value is `true`.
22
- *
23
- * @deprecated {@link https://hello.jira.atlassian.cloud/browse/ENGHEALTH-28588 Learn more about why `false` should not be used and will be removed.}
24
22
  */
25
- autoFocus?: boolean | RefObject<HTMLElement | null | undefined>;
23
+ autoFocus?: RefObject<HTMLElement | null | undefined>;
26
24
  /**
27
25
  * Contents of the modal dialog.
28
26
  */
@@ -19,10 +19,8 @@ export interface ModalDialogProps {
19
19
  * accessibility regressions. Pass an element `ref` to focus on a specific element.
20
20
  *
21
21
  * Default value is `true`.
22
- *
23
- * @deprecated {@link https://hello.jira.atlassian.cloud/browse/ENGHEALTH-28588 Learn more about why `false` should not be used and will be removed.}
24
22
  */
25
- autoFocus?: boolean | RefObject<HTMLElement | null | undefined>;
23
+ autoFocus?: RefObject<HTMLElement | null | undefined>;
26
24
  /**
27
25
  * Contents of the modal dialog.
28
26
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/modal-dialog",
3
- "version": "14.18.3",
3
+ "version": "15.0.0",
4
4
  "description": "A modal dialog displays content that requires user interaction, in a layer above the page.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -39,7 +39,7 @@
39
39
  "@atlaskit/button": "^23.11.0",
40
40
  "@atlaskit/css": "^0.19.0",
41
41
  "@atlaskit/ds-lib": "^7.0.0",
42
- "@atlaskit/icon": "^34.3.0",
42
+ "@atlaskit/icon": "^34.4.0",
43
43
  "@atlaskit/layering": "^3.7.0",
44
44
  "@atlaskit/motion": "^6.2.0",
45
45
  "@atlaskit/platform-feature-flags": "^1.1.0",
@@ -79,7 +79,7 @@
79
79
  "@atlaskit/radio": "^8.6.0",
80
80
  "@atlaskit/section-message": "^8.12.0",
81
81
  "@atlaskit/select": "^21.10.0",
82
- "@atlaskit/spotlight": "^0.13.0",
82
+ "@atlaskit/spotlight": "^0.14.0",
83
83
  "@atlaskit/textfield": "^8.3.0",
84
84
  "@atlaskit/tooltip": "^22.0.0",
85
85
  "@atlassian/feature-flags-test-utils": "^1.0.0",