@atlaskit/popup 1.16.0 → 1.17.1

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,22 @@
1
1
  # @atlaskit/popup
2
2
 
3
+ ## 1.17.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#97895](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/97895)
8
+ [`4f26610d9fbc`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/4f26610d9fbc) -
9
+ Adds auto-generated ID to popup and popup triggers for better coverage of assistive technologies
10
+ and `aria-controls`..
11
+
12
+ ## 1.17.0
13
+
14
+ ### Minor Changes
15
+
16
+ - [#91673](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/91673)
17
+ [`e757c83a22ee`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e757c83a22ee) -
18
+ Add new props for improving accessibility: `role`, `label` and `titleId`.
19
+
3
20
  ## 1.16.0
4
21
 
5
22
  ### Minor Changes
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.PopupTrigger = exports.PopupContent = exports.Popup = void 0;
9
9
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
10
  var _react = _interopRequireWildcard(require("react"));
11
+ var _reactUid = require("react-uid");
11
12
  var _tinyInvariant = _interopRequireDefault(require("tiny-invariant"));
12
13
  var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
13
14
  var _layering = require("@atlaskit/layering");
@@ -51,13 +52,15 @@ var useEnsureIsInsidePopup = function useEnsureIsInsidePopup() {
51
52
  */
52
53
  var Popup = exports.Popup = function Popup(_ref) {
53
54
  var children = _ref.children,
54
- id = _ref.id,
55
+ providedId = _ref.id,
55
56
  _ref$isOpen = _ref.isOpen,
56
57
  isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen;
57
58
  var _useState = (0, _react.useState)(null),
58
59
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
59
60
  triggerRef = _useState2[0],
60
61
  setTriggerRef = _useState2[1];
62
+ var generatedId = (0, _reactUid.useUID)();
63
+ var id = providedId || generatedId;
61
64
  return /*#__PURE__*/_react.default.createElement(EnsureIsInsidePopupContext.Provider, {
62
65
  value: true
63
66
  }, /*#__PURE__*/_react.default.createElement(IdContext.Provider, {
@@ -77,7 +77,10 @@ function PopperWrapper(_ref) {
77
77
  shouldUseCaptureOnOutsideClick = _ref.shouldUseCaptureOnOutsideClick,
78
78
  shouldRenderToParent = _ref.shouldRenderToParent,
79
79
  shouldDisableFocusLock = _ref.shouldDisableFocusLock,
80
- strategy = _ref.strategy;
80
+ strategy = _ref.strategy,
81
+ role = _ref.role,
82
+ label = _ref.label,
83
+ titleId = _ref.titleId;
81
84
  var _useState = (0, _react.useState)(null),
82
85
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
83
86
  popupRef = _useState2[0],
@@ -131,6 +134,9 @@ function PopperWrapper(_ref) {
131
134
  "data-ds--level": currentLevel,
132
135
  "data-placement": placement,
133
136
  "data-testid": testId,
137
+ role: role,
138
+ "aria-label": label,
139
+ "aria-labelledby": titleId,
134
140
  ref: function ref(node) {
135
141
  if (node) {
136
142
  if (typeof _ref3 === 'function') {
package/dist/cjs/popup.js CHANGED
@@ -8,6 +8,7 @@ exports.default = exports.Popup = void 0;
8
8
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
9
  var _react = require("react");
10
10
  var _react2 = require("@emotion/react");
11
+ var _reactUid = require("react-uid");
11
12
  var _layering = require("@atlaskit/layering");
12
13
  var _popper = require("@atlaskit/popper");
13
14
  var _portal = _interopRequireDefault(require("@atlaskit/portal"));
@@ -20,7 +21,7 @@ var _useGetMemoizedMergedTriggerRef = require("./use-get-memoized-merged-trigger
20
21
  var defaultLayer = _constants.layers.layer();
21
22
  var Popup = exports.Popup = /*#__PURE__*/(0, _react.memo)(function (_ref) {
22
23
  var isOpen = _ref.isOpen,
23
- id = _ref.id,
24
+ providedId = _ref.id,
24
25
  offset = _ref.offset,
25
26
  testId = _ref.testId,
26
27
  trigger = _ref.trigger,
@@ -45,12 +46,17 @@ var Popup = exports.Popup = /*#__PURE__*/(0, _react.memo)(function (_ref) {
45
46
  shouldRenderToParent = _ref$shouldRenderToPa === void 0 ? false : _ref$shouldRenderToPa,
46
47
  _ref$shouldDisableFoc = _ref.shouldDisableFocusLock,
47
48
  shouldDisableFocusLock = _ref$shouldDisableFoc === void 0 ? false : _ref$shouldDisableFoc,
48
- strategy = _ref.strategy;
49
+ strategy = _ref.strategy,
50
+ role = _ref.role,
51
+ label = _ref.label,
52
+ titleId = _ref.titleId;
49
53
  var _useState = (0, _react.useState)(null),
50
54
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
51
55
  triggerRef = _useState2[0],
52
56
  setTriggerRef = _useState2[1];
53
57
  var getMergedTriggerRef = (0, _useGetMemoizedMergedTriggerRef.useGetMemoizedMergedTriggerRef)();
58
+ var generatedId = (0, _reactUid.useUID)();
59
+ var id = providedId || generatedId;
54
60
  var renderPopperWrapper = (0, _react2.jsx)(_layering.UNSAFE_LAYERING, {
55
61
  isDisabled: false
56
62
  }, (0, _react2.jsx)(_popperWrapper.default, {
@@ -71,13 +77,16 @@ var Popup = exports.Popup = /*#__PURE__*/(0, _react.memo)(function (_ref) {
71
77
  shouldRenderToParent: shouldRenderToParent,
72
78
  shouldDisableFocusLock: shouldDisableFocusLock,
73
79
  triggerRef: triggerRef,
74
- strategy: strategy
80
+ strategy: strategy,
81
+ role: role,
82
+ label: label,
83
+ titleId: titleId
75
84
  }));
76
85
  return (0, _react2.jsx)(_popper.Manager, null, (0, _react2.jsx)(_popper.Reference, null, function (_ref2) {
77
86
  var ref = _ref2.ref;
78
87
  return trigger({
79
88
  ref: getMergedTriggerRef(ref, setTriggerRef, isOpen),
80
- 'aria-controls': id,
89
+ 'aria-controls': isOpen ? id : undefined,
81
90
  'aria-expanded': isOpen,
82
91
  'aria-haspopup': true
83
92
  });
@@ -9,6 +9,9 @@ var _react = require("react");
9
9
  var _bindEventListener = require("bind-event-listener");
10
10
  var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
11
11
  var _layering = require("@atlaskit/layering");
12
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports
14
+
12
15
  var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
13
16
  var isOpen = _ref.isOpen,
14
17
  onClose = _ref.onClose,
@@ -17,7 +20,8 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
17
20
  capture = _ref.shouldUseCaptureOnOutsideClick,
18
21
  shouldCloseOnTab = _ref.shouldCloseOnTab;
19
22
  var _UNSAFE_useLayering = (0, _layering.UNSAFE_useLayering)(),
20
- isLayerDisabled = _UNSAFE_useLayering.isLayerDisabled;
23
+ isLayerDisabled = _UNSAFE_useLayering.isLayerDisabled,
24
+ currentLevel = _UNSAFE_useLayering.currentLevel;
21
25
  (0, _react.useEffect)(function () {
22
26
  if (!isOpen || !popupRef) {
23
27
  return _noop.default;
@@ -41,6 +45,10 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
41
45
  if (!doesDomNodeExist) {
42
46
  return;
43
47
  }
48
+ if (isLayerDisabled() && (0, _platformFeatureFlags.getBooleanFF)('platform.design-system-team.iframe-layering_p3eb8')) {
49
+ //if it is a disabled layer, we need to disable its click listener.
50
+ return;
51
+ }
44
52
  var isClickOnPopup = popupRef && popupRef.contains(target);
45
53
  var isClickOnTrigger = triggerRef && triggerRef.contains(target);
46
54
  if (!isClickOnPopup && !isClickOnTrigger) {
@@ -66,6 +74,26 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
66
74
  type: 'keydown',
67
75
  listener: onKeyDown
68
76
  }]);
69
- return unbind;
70
- }, [isOpen, onClose, popupRef, triggerRef, capture, isLayerDisabled, shouldCloseOnTab]);
77
+
78
+ // bind onBlur event listener to fix popup not close when clicking on iframe outside
79
+ var unbindBlur = _noop.default;
80
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.design-system-team.iframe-layering_p3eb8')) {
81
+ unbindBlur = (0, _bindEventListener.bind)(window, {
82
+ type: 'blur',
83
+ listener: function onBlur(e) {
84
+ if (isLayerDisabled() || !(document.activeElement instanceof HTMLIFrameElement)) {
85
+ return;
86
+ }
87
+ var wrapper = document.activeElement.closest('[data-ds--level]');
88
+ if (!wrapper || currentLevel > Number(wrapper.getAttribute('data-ds--level'))) {
89
+ closePopup(e);
90
+ }
91
+ }
92
+ });
93
+ }
94
+ return function () {
95
+ unbind();
96
+ unbindBlur();
97
+ };
98
+ }, [isOpen, onClose, popupRef, triggerRef, capture, isLayerDisabled, shouldCloseOnTab, currentLevel]);
71
99
  };
@@ -1,4 +1,5 @@
1
1
  import React, { createContext, useContext, useState } from 'react';
2
+ import { useUID } from 'react-uid';
2
3
  import invariant from 'tiny-invariant';
3
4
  import noop from '@atlaskit/ds-lib/noop';
4
5
  import { UNSAFE_LAYERING } from '@atlaskit/layering';
@@ -40,10 +41,12 @@ const useEnsureIsInsidePopup = () => {
40
41
  */
41
42
  export const Popup = ({
42
43
  children,
43
- id,
44
+ id: providedId,
44
45
  isOpen = false
45
46
  }) => {
46
47
  const [triggerRef, setTriggerRef] = useState(null);
48
+ const generatedId = useUID();
49
+ const id = providedId || generatedId;
47
50
  return /*#__PURE__*/React.createElement(EnsureIsInsidePopupContext.Provider, {
48
51
  value: true
49
52
  }, /*#__PURE__*/React.createElement(IdContext.Provider, {
@@ -66,7 +66,10 @@ function PopperWrapper({
66
66
  shouldUseCaptureOnOutsideClick,
67
67
  shouldRenderToParent,
68
68
  shouldDisableFocusLock,
69
- strategy
69
+ strategy,
70
+ role,
71
+ label,
72
+ titleId
70
73
  }) {
71
74
  const [popupRef, setPopupRef] = useState(null);
72
75
  const [initialFocusRef, setInitialFocusRef] = useState(null);
@@ -115,6 +118,9 @@ function PopperWrapper({
115
118
  "data-ds--level": currentLevel,
116
119
  "data-placement": placement,
117
120
  "data-testid": testId,
121
+ role: role,
122
+ "aria-label": label,
123
+ "aria-labelledby": titleId,
118
124
  ref: node => {
119
125
  if (node) {
120
126
  if (typeof ref === 'function') {
@@ -2,6 +2,7 @@
2
2
  /** @jsx jsx */
3
3
  import { memo, useState } from 'react';
4
4
  import { jsx } from '@emotion/react';
5
+ import { useUID } from 'react-uid';
5
6
  import { UNSAFE_LAYERING } from '@atlaskit/layering';
6
7
  import { Manager, Reference } from '@atlaskit/popper';
7
8
  import Portal from '@atlaskit/portal';
@@ -11,7 +12,7 @@ import { useGetMemoizedMergedTriggerRef } from './use-get-memoized-merged-trigge
11
12
  const defaultLayer = layers.layer();
12
13
  export const Popup = /*#__PURE__*/memo(({
13
14
  isOpen,
14
- id,
15
+ id: providedId,
15
16
  offset,
16
17
  testId,
17
18
  trigger,
@@ -28,10 +29,15 @@ export const Popup = /*#__PURE__*/memo(({
28
29
  shouldUseCaptureOnOutsideClick = false,
29
30
  shouldRenderToParent = false,
30
31
  shouldDisableFocusLock = false,
31
- strategy
32
+ strategy,
33
+ role,
34
+ label,
35
+ titleId
32
36
  }) => {
33
37
  const [triggerRef, setTriggerRef] = useState(null);
34
38
  const getMergedTriggerRef = useGetMemoizedMergedTriggerRef();
39
+ const generatedId = useUID();
40
+ const id = providedId || generatedId;
35
41
  const renderPopperWrapper = jsx(UNSAFE_LAYERING, {
36
42
  isDisabled: false
37
43
  }, jsx(PopperWrapper, {
@@ -52,14 +58,17 @@ export const Popup = /*#__PURE__*/memo(({
52
58
  shouldRenderToParent: shouldRenderToParent,
53
59
  shouldDisableFocusLock: shouldDisableFocusLock,
54
60
  triggerRef: triggerRef,
55
- strategy: strategy
61
+ strategy: strategy,
62
+ role: role,
63
+ label: label,
64
+ titleId: titleId
56
65
  }));
57
66
  return jsx(Manager, null, jsx(Reference, null, ({
58
67
  ref
59
68
  }) => {
60
69
  return trigger({
61
70
  ref: getMergedTriggerRef(ref, setTriggerRef, isOpen),
62
- 'aria-controls': id,
71
+ 'aria-controls': isOpen ? id : undefined,
63
72
  'aria-expanded': isOpen,
64
73
  'aria-haspopup': true
65
74
  });
@@ -1,7 +1,9 @@
1
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports
1
2
  import { useEffect } from 'react';
2
- import { bindAll } from 'bind-event-listener';
3
+ import { bind, bindAll } from 'bind-event-listener';
3
4
  import noop from '@atlaskit/ds-lib/noop';
4
5
  import { UNSAFE_useLayering } from '@atlaskit/layering';
6
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
5
7
  export const useCloseManager = ({
6
8
  isOpen,
7
9
  onClose,
@@ -11,7 +13,8 @@ export const useCloseManager = ({
11
13
  shouldCloseOnTab
12
14
  }) => {
13
15
  const {
14
- isLayerDisabled
16
+ isLayerDisabled,
17
+ currentLevel
15
18
  } = UNSAFE_useLayering();
16
19
  useEffect(() => {
17
20
  if (!isOpen || !popupRef) {
@@ -38,6 +41,10 @@ export const useCloseManager = ({
38
41
  if (!doesDomNodeExist) {
39
42
  return;
40
43
  }
44
+ if (isLayerDisabled() && getBooleanFF('platform.design-system-team.iframe-layering_p3eb8')) {
45
+ //if it is a disabled layer, we need to disable its click listener.
46
+ return;
47
+ }
41
48
  const isClickOnPopup = popupRef && popupRef.contains(target);
42
49
  const isClickOnTrigger = triggerRef && triggerRef.contains(target);
43
50
  if (!isClickOnPopup && !isClickOnTrigger) {
@@ -65,6 +72,26 @@ export const useCloseManager = ({
65
72
  type: 'keydown',
66
73
  listener: onKeyDown
67
74
  }]);
68
- return unbind;
69
- }, [isOpen, onClose, popupRef, triggerRef, capture, isLayerDisabled, shouldCloseOnTab]);
75
+
76
+ // bind onBlur event listener to fix popup not close when clicking on iframe outside
77
+ let unbindBlur = noop;
78
+ if (getBooleanFF('platform.design-system-team.iframe-layering_p3eb8')) {
79
+ unbindBlur = bind(window, {
80
+ type: 'blur',
81
+ listener: function onBlur(e) {
82
+ if (isLayerDisabled() || !(document.activeElement instanceof HTMLIFrameElement)) {
83
+ return;
84
+ }
85
+ const wrapper = document.activeElement.closest('[data-ds--level]');
86
+ if (!wrapper || currentLevel > Number(wrapper.getAttribute('data-ds--level'))) {
87
+ closePopup(e);
88
+ }
89
+ }
90
+ });
91
+ }
92
+ return () => {
93
+ unbind();
94
+ unbindBlur();
95
+ };
96
+ }, [isOpen, onClose, popupRef, triggerRef, capture, isLayerDisabled, shouldCloseOnTab, currentLevel]);
70
97
  };
@@ -1,5 +1,6 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  import React, { createContext, useContext, useState } from 'react';
3
+ import { useUID } from 'react-uid';
3
4
  import invariant from 'tiny-invariant';
4
5
  import noop from '@atlaskit/ds-lib/noop';
5
6
  import { UNSAFE_LAYERING } from '@atlaskit/layering';
@@ -41,13 +42,15 @@ var useEnsureIsInsidePopup = function useEnsureIsInsidePopup() {
41
42
  */
42
43
  export var Popup = function Popup(_ref) {
43
44
  var children = _ref.children,
44
- id = _ref.id,
45
+ providedId = _ref.id,
45
46
  _ref$isOpen = _ref.isOpen,
46
47
  isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen;
47
48
  var _useState = useState(null),
48
49
  _useState2 = _slicedToArray(_useState, 2),
49
50
  triggerRef = _useState2[0],
50
51
  setTriggerRef = _useState2[1];
52
+ var generatedId = useUID();
53
+ var id = providedId || generatedId;
51
54
  return /*#__PURE__*/React.createElement(EnsureIsInsidePopupContext.Provider, {
52
55
  value: true
53
56
  }, /*#__PURE__*/React.createElement(IdContext.Provider, {
@@ -70,7 +70,10 @@ function PopperWrapper(_ref) {
70
70
  shouldUseCaptureOnOutsideClick = _ref.shouldUseCaptureOnOutsideClick,
71
71
  shouldRenderToParent = _ref.shouldRenderToParent,
72
72
  shouldDisableFocusLock = _ref.shouldDisableFocusLock,
73
- strategy = _ref.strategy;
73
+ strategy = _ref.strategy,
74
+ role = _ref.role,
75
+ label = _ref.label,
76
+ titleId = _ref.titleId;
74
77
  var _useState = useState(null),
75
78
  _useState2 = _slicedToArray(_useState, 2),
76
79
  popupRef = _useState2[0],
@@ -124,6 +127,9 @@ function PopperWrapper(_ref) {
124
127
  "data-ds--level": currentLevel,
125
128
  "data-placement": placement,
126
129
  "data-testid": testId,
130
+ role: role,
131
+ "aria-label": label,
132
+ "aria-labelledby": titleId,
127
133
  ref: function ref(node) {
128
134
  if (node) {
129
135
  if (typeof _ref3 === 'function') {
package/dist/esm/popup.js CHANGED
@@ -3,6 +3,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  /** @jsx jsx */
4
4
  import { memo, useState } from 'react';
5
5
  import { jsx } from '@emotion/react';
6
+ import { useUID } from 'react-uid';
6
7
  import { UNSAFE_LAYERING } from '@atlaskit/layering';
7
8
  import { Manager, Reference } from '@atlaskit/popper';
8
9
  import Portal from '@atlaskit/portal';
@@ -12,7 +13,7 @@ import { useGetMemoizedMergedTriggerRef } from './use-get-memoized-merged-trigge
12
13
  var defaultLayer = layers.layer();
13
14
  export var Popup = /*#__PURE__*/memo(function (_ref) {
14
15
  var isOpen = _ref.isOpen,
15
- id = _ref.id,
16
+ providedId = _ref.id,
16
17
  offset = _ref.offset,
17
18
  testId = _ref.testId,
18
19
  trigger = _ref.trigger,
@@ -37,12 +38,17 @@ export var Popup = /*#__PURE__*/memo(function (_ref) {
37
38
  shouldRenderToParent = _ref$shouldRenderToPa === void 0 ? false : _ref$shouldRenderToPa,
38
39
  _ref$shouldDisableFoc = _ref.shouldDisableFocusLock,
39
40
  shouldDisableFocusLock = _ref$shouldDisableFoc === void 0 ? false : _ref$shouldDisableFoc,
40
- strategy = _ref.strategy;
41
+ strategy = _ref.strategy,
42
+ role = _ref.role,
43
+ label = _ref.label,
44
+ titleId = _ref.titleId;
41
45
  var _useState = useState(null),
42
46
  _useState2 = _slicedToArray(_useState, 2),
43
47
  triggerRef = _useState2[0],
44
48
  setTriggerRef = _useState2[1];
45
49
  var getMergedTriggerRef = useGetMemoizedMergedTriggerRef();
50
+ var generatedId = useUID();
51
+ var id = providedId || generatedId;
46
52
  var renderPopperWrapper = jsx(UNSAFE_LAYERING, {
47
53
  isDisabled: false
48
54
  }, jsx(PopperWrapper, {
@@ -63,13 +69,16 @@ export var Popup = /*#__PURE__*/memo(function (_ref) {
63
69
  shouldRenderToParent: shouldRenderToParent,
64
70
  shouldDisableFocusLock: shouldDisableFocusLock,
65
71
  triggerRef: triggerRef,
66
- strategy: strategy
72
+ strategy: strategy,
73
+ role: role,
74
+ label: label,
75
+ titleId: titleId
67
76
  }));
68
77
  return jsx(Manager, null, jsx(Reference, null, function (_ref2) {
69
78
  var ref = _ref2.ref;
70
79
  return trigger({
71
80
  ref: getMergedTriggerRef(ref, setTriggerRef, isOpen),
72
- 'aria-controls': id,
81
+ 'aria-controls': isOpen ? id : undefined,
73
82
  'aria-expanded': isOpen,
74
83
  'aria-haspopup': true
75
84
  });
@@ -1,7 +1,9 @@
1
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports
1
2
  import { useEffect } from 'react';
2
- import { bindAll } from 'bind-event-listener';
3
+ import { bind, bindAll } from 'bind-event-listener';
3
4
  import noop from '@atlaskit/ds-lib/noop';
4
5
  import { UNSAFE_useLayering } from '@atlaskit/layering';
6
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
5
7
  export var useCloseManager = function useCloseManager(_ref) {
6
8
  var isOpen = _ref.isOpen,
7
9
  onClose = _ref.onClose,
@@ -10,7 +12,8 @@ export var useCloseManager = function useCloseManager(_ref) {
10
12
  capture = _ref.shouldUseCaptureOnOutsideClick,
11
13
  shouldCloseOnTab = _ref.shouldCloseOnTab;
12
14
  var _UNSAFE_useLayering = UNSAFE_useLayering(),
13
- isLayerDisabled = _UNSAFE_useLayering.isLayerDisabled;
15
+ isLayerDisabled = _UNSAFE_useLayering.isLayerDisabled,
16
+ currentLevel = _UNSAFE_useLayering.currentLevel;
14
17
  useEffect(function () {
15
18
  if (!isOpen || !popupRef) {
16
19
  return noop;
@@ -34,6 +37,10 @@ export var useCloseManager = function useCloseManager(_ref) {
34
37
  if (!doesDomNodeExist) {
35
38
  return;
36
39
  }
40
+ if (isLayerDisabled() && getBooleanFF('platform.design-system-team.iframe-layering_p3eb8')) {
41
+ //if it is a disabled layer, we need to disable its click listener.
42
+ return;
43
+ }
37
44
  var isClickOnPopup = popupRef && popupRef.contains(target);
38
45
  var isClickOnTrigger = triggerRef && triggerRef.contains(target);
39
46
  if (!isClickOnPopup && !isClickOnTrigger) {
@@ -59,6 +66,26 @@ export var useCloseManager = function useCloseManager(_ref) {
59
66
  type: 'keydown',
60
67
  listener: onKeyDown
61
68
  }]);
62
- return unbind;
63
- }, [isOpen, onClose, popupRef, triggerRef, capture, isLayerDisabled, shouldCloseOnTab]);
69
+
70
+ // bind onBlur event listener to fix popup not close when clicking on iframe outside
71
+ var unbindBlur = noop;
72
+ if (getBooleanFF('platform.design-system-team.iframe-layering_p3eb8')) {
73
+ unbindBlur = bind(window, {
74
+ type: 'blur',
75
+ listener: function onBlur(e) {
76
+ if (isLayerDisabled() || !(document.activeElement instanceof HTMLIFrameElement)) {
77
+ return;
78
+ }
79
+ var wrapper = document.activeElement.closest('[data-ds--level]');
80
+ if (!wrapper || currentLevel > Number(wrapper.getAttribute('data-ds--level'))) {
81
+ closePopup(e);
82
+ }
83
+ }
84
+ });
85
+ }
86
+ return function () {
87
+ unbind();
88
+ unbindBlur();
89
+ };
90
+ }, [isOpen, onClose, popupRef, triggerRef, capture, isLayerDisabled, shouldCloseOnTab, currentLevel]);
64
91
  };
@@ -24,7 +24,7 @@ export type PopupProps = {
24
24
  * </Popup>
25
25
  * ```
26
26
  */
27
- export declare const Popup: ({ children, id, isOpen }: PopupProps) => JSX.Element;
27
+ export declare const Popup: ({ children, id: providedId, isOpen, }: PopupProps) => JSX.Element;
28
28
  export type PopupTriggerProps = {
29
29
  children: (props: TriggerProps) => React.ReactNode;
30
30
  };
@@ -1,4 +1,4 @@
1
1
  import { jsx } from '@emotion/react';
2
2
  import { PopperWrapperProps } from './types';
3
- declare function PopperWrapper({ isOpen, id, offset, testId, content, fallbackPlacements, onClose, boundary, rootBoundary, shouldFlip, placement, popupComponent: PopupContainer, autoFocus, triggerRef, shouldUseCaptureOnOutsideClick, shouldRenderToParent, shouldDisableFocusLock, strategy, }: PopperWrapperProps): jsx.JSX.Element;
3
+ declare function PopperWrapper({ isOpen, id, offset, testId, content, fallbackPlacements, onClose, boundary, rootBoundary, shouldFlip, placement, popupComponent: PopupContainer, autoFocus, triggerRef, shouldUseCaptureOnOutsideClick, shouldRenderToParent, shouldDisableFocusLock, strategy, role, label, titleId, }: PopperWrapperProps): jsx.JSX.Element;
4
4
  export default PopperWrapper;
@@ -1,5 +1,5 @@
1
1
  /** @jsx jsx */
2
2
  import { type FC } from 'react';
3
- import { PopupProps } from './types';
3
+ import { type PopupProps } from './types';
4
4
  export declare const Popup: FC<PopupProps>;
5
5
  export default Popup;
@@ -61,6 +61,11 @@ export interface PopupComponentProps {
61
61
  * The default is `false`.
62
62
  */
63
63
  shouldRenderToParent?: boolean;
64
+ /**
65
+ * Use this to set the accessibility role for the popup.
66
+ * We strongly recommend using only `menu` or `dialog`.
67
+ */
68
+ role?: string;
64
69
  }
65
70
  interface BaseProps {
66
71
  /**
@@ -145,7 +150,7 @@ interface BaseProps {
145
150
  */
146
151
  shouldRenderToParent?: boolean;
147
152
  /**
148
- * This allows the Popup disable focus lock. It will only work when `shouldRenderToParent` is `true`.
153
+ * This allows the popup disable focus lock. It will only work when `shouldRenderToParent` is `true`.
149
154
  * The default is `false`.
150
155
  */
151
156
  shouldDisableFocusLock?: boolean;
@@ -154,6 +159,22 @@ interface BaseProps {
154
159
  * The default is `fixed`.
155
160
  */
156
161
  strategy?: 'absolute' | 'fixed';
162
+ /**
163
+ * Use this to set the accessibility role for the popup.
164
+ * We strongly recommend using only `menu` or `dialog`.
165
+ * Must be used along with `label` or `titleId`.
166
+ */
167
+ role?: string;
168
+ /**
169
+ * Refers to an `aria-label` attribute. Sets an accessible name for the popup to announce it to users of assistive technology.
170
+ * Usage of either this, or the `titleId` attribute is strongly recommended.
171
+ */
172
+ label?: string;
173
+ /**
174
+ * Id referenced by the popup `aria-labelledby` attribute.
175
+ * Usage of either this, or the `label` attribute is strongly recommended.
176
+ */
177
+ titleId?: string;
157
178
  }
158
179
  export interface PopupProps extends BaseProps {
159
180
  /**
@@ -1,2 +1,2 @@
1
- import { CloseManagerHook } from './types';
1
+ import { type CloseManagerHook } from './types';
2
2
  export declare const useCloseManager: ({ isOpen, onClose, popupRef, triggerRef, shouldUseCaptureOnOutsideClick: capture, shouldCloseOnTab, }: CloseManagerHook) => void;
@@ -24,7 +24,7 @@ export type PopupProps = {
24
24
  * </Popup>
25
25
  * ```
26
26
  */
27
- export declare const Popup: ({ children, id, isOpen }: PopupProps) => JSX.Element;
27
+ export declare const Popup: ({ children, id: providedId, isOpen, }: PopupProps) => JSX.Element;
28
28
  export type PopupTriggerProps = {
29
29
  children: (props: TriggerProps) => React.ReactNode;
30
30
  };
@@ -1,4 +1,4 @@
1
1
  import { jsx } from '@emotion/react';
2
2
  import { PopperWrapperProps } from './types';
3
- declare function PopperWrapper({ isOpen, id, offset, testId, content, fallbackPlacements, onClose, boundary, rootBoundary, shouldFlip, placement, popupComponent: PopupContainer, autoFocus, triggerRef, shouldUseCaptureOnOutsideClick, shouldRenderToParent, shouldDisableFocusLock, strategy, }: PopperWrapperProps): jsx.JSX.Element;
3
+ declare function PopperWrapper({ isOpen, id, offset, testId, content, fallbackPlacements, onClose, boundary, rootBoundary, shouldFlip, placement, popupComponent: PopupContainer, autoFocus, triggerRef, shouldUseCaptureOnOutsideClick, shouldRenderToParent, shouldDisableFocusLock, strategy, role, label, titleId, }: PopperWrapperProps): jsx.JSX.Element;
4
4
  export default PopperWrapper;
@@ -1,5 +1,5 @@
1
1
  /** @jsx jsx */
2
2
  import { type FC } from 'react';
3
- import { PopupProps } from './types';
3
+ import { type PopupProps } from './types';
4
4
  export declare const Popup: FC<PopupProps>;
5
5
  export default Popup;
@@ -61,6 +61,11 @@ export interface PopupComponentProps {
61
61
  * The default is `false`.
62
62
  */
63
63
  shouldRenderToParent?: boolean;
64
+ /**
65
+ * Use this to set the accessibility role for the popup.
66
+ * We strongly recommend using only `menu` or `dialog`.
67
+ */
68
+ role?: string;
64
69
  }
65
70
  interface BaseProps {
66
71
  /**
@@ -148,7 +153,7 @@ interface BaseProps {
148
153
  */
149
154
  shouldRenderToParent?: boolean;
150
155
  /**
151
- * This allows the Popup disable focus lock. It will only work when `shouldRenderToParent` is `true`.
156
+ * This allows the popup disable focus lock. It will only work when `shouldRenderToParent` is `true`.
152
157
  * The default is `false`.
153
158
  */
154
159
  shouldDisableFocusLock?: boolean;
@@ -157,6 +162,22 @@ interface BaseProps {
157
162
  * The default is `fixed`.
158
163
  */
159
164
  strategy?: 'absolute' | 'fixed';
165
+ /**
166
+ * Use this to set the accessibility role for the popup.
167
+ * We strongly recommend using only `menu` or `dialog`.
168
+ * Must be used along with `label` or `titleId`.
169
+ */
170
+ role?: string;
171
+ /**
172
+ * Refers to an `aria-label` attribute. Sets an accessible name for the popup to announce it to users of assistive technology.
173
+ * Usage of either this, or the `titleId` attribute is strongly recommended.
174
+ */
175
+ label?: string;
176
+ /**
177
+ * Id referenced by the popup `aria-labelledby` attribute.
178
+ * Usage of either this, or the `label` attribute is strongly recommended.
179
+ */
180
+ titleId?: string;
160
181
  }
161
182
  export interface PopupProps extends BaseProps {
162
183
  /**
@@ -1,2 +1,2 @@
1
- import { CloseManagerHook } from './types';
1
+ import { type CloseManagerHook } from './types';
2
2
  export declare const useCloseManager: ({ isOpen, onClose, popupRef, triggerRef, shouldUseCaptureOnOutsideClick: capture, shouldCloseOnTab, }: CloseManagerHook) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/popup",
3
- "version": "1.16.0",
3
+ "version": "1.17.1",
4
4
  "description": "A popup displays brief content in an overlay.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -43,15 +43,16 @@
43
43
  "@atlaskit/ds-lib": "^2.3.0",
44
44
  "@atlaskit/layering": "^0.3.0",
45
45
  "@atlaskit/platform-feature-flags": "^0.2.0",
46
- "@atlaskit/popper": "^5.5.0",
47
- "@atlaskit/portal": "^4.4.0",
48
- "@atlaskit/theme": "^12.7.0",
49
- "@atlaskit/tokens": "^1.45.0",
46
+ "@atlaskit/popper": "^5.6.0",
47
+ "@atlaskit/portal": "^4.5.0",
48
+ "@atlaskit/theme": "^12.8.0",
49
+ "@atlaskit/tokens": "^1.49.0",
50
50
  "@babel/runtime": "^7.0.0",
51
51
  "@emotion/react": "^11.7.1",
52
52
  "bind-event-listener": "^3.0.0",
53
53
  "focus-trap": "^2.4.5",
54
54
  "memoize-one": "^6.0.0",
55
+ "react-uid": "^2.2.0",
55
56
  "tiny-invariant": "^1.2.0"
56
57
  },
57
58
  "peerDependencies": {
@@ -61,10 +62,11 @@
61
62
  "devDependencies": {
62
63
  "@af/accessibility-testing": "*",
63
64
  "@af/visual-regression": "*",
64
- "@atlaskit/button": "^17.14.0",
65
- "@atlaskit/icon": "^22.1.0",
65
+ "@atlaskit/button": "^17.15.0",
66
+ "@atlaskit/icon": "^22.3.0",
66
67
  "@atlaskit/ssr": "*",
67
- "@atlaskit/toggle": "^13.0.0",
68
+ "@atlaskit/textfield": "^6.3.0",
69
+ "@atlaskit/toggle": "^13.1.0",
68
70
  "@atlaskit/visual-regression": "*",
69
71
  "@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1",
70
72
  "@atlassian/feature-flags-test-utils": "*",
@@ -107,6 +109,9 @@
107
109
  "platform-feature-flags": {
108
110
  "platform.design-system-team.iframe_gojiv": {
109
111
  "type": "boolean"
112
+ },
113
+ "platform.design-system-team.iframe-layering_p3eb8": {
114
+ "type": "boolean"
110
115
  }
111
116
  },
112
117
  "homepage": "https://atlassian.design/components/popup/",