@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 +17 -0
- package/dist/cjs/compositional/popup.js +4 -1
- package/dist/cjs/popper-wrapper.js +7 -1
- package/dist/cjs/popup.js +13 -4
- package/dist/cjs/use-close-manager.js +31 -3
- package/dist/es2019/compositional/popup.js +4 -1
- package/dist/es2019/popper-wrapper.js +7 -1
- package/dist/es2019/popup.js +13 -4
- package/dist/es2019/use-close-manager.js +31 -4
- package/dist/esm/compositional/popup.js +4 -1
- package/dist/esm/popper-wrapper.js +7 -1
- package/dist/esm/popup.js +13 -4
- package/dist/esm/use-close-manager.js +31 -4
- package/dist/types/compositional/popup.d.ts +1 -1
- package/dist/types/popper-wrapper.d.ts +1 -1
- package/dist/types/popup.d.ts +1 -1
- package/dist/types/types.d.ts +22 -1
- package/dist/types/use-close-manager.d.ts +1 -1
- package/dist/types-ts4.5/compositional/popup.d.ts +1 -1
- package/dist/types-ts4.5/popper-wrapper.d.ts +1 -1
- package/dist/types-ts4.5/popup.d.ts +1 -1
- package/dist/types-ts4.5/types.d.ts +22 -1
- package/dist/types-ts4.5/use-close-manager.d.ts +1 -1
- package/package.json +13 -8
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
70
|
-
|
|
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') {
|
package/dist/es2019/popup.js
CHANGED
|
@@ -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
|
-
|
|
69
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
63
|
-
|
|
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;
|
package/dist/types/popup.d.ts
CHANGED
package/dist/types/types.d.ts
CHANGED
|
@@ -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
|
|
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;
|
|
@@ -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
|
|
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.
|
|
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.
|
|
47
|
-
"@atlaskit/portal": "^4.
|
|
48
|
-
"@atlaskit/theme": "^12.
|
|
49
|
-
"@atlaskit/tokens": "^1.
|
|
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.
|
|
65
|
-
"@atlaskit/icon": "^22.
|
|
65
|
+
"@atlaskit/button": "^17.15.0",
|
|
66
|
+
"@atlaskit/icon": "^22.3.0",
|
|
66
67
|
"@atlaskit/ssr": "*",
|
|
67
|
-
"@atlaskit/
|
|
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/",
|