@atlaskit/popup 1.23.1 → 1.24.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 +16 -0
- package/dist/cjs/popup.js +3 -1
- package/dist/cjs/use-close-manager.js +5 -13
- package/dist/cjs/use-get-memoized-merged-trigger-ref-new.js +34 -0
- package/dist/es2019/popup.js +3 -1
- package/dist/es2019/use-close-manager.js +5 -13
- package/dist/es2019/use-get-memoized-merged-trigger-ref-new.js +23 -0
- package/dist/esm/popup.js +3 -1
- package/dist/esm/use-close-manager.js +5 -13
- package/dist/esm/use-get-memoized-merged-trigger-ref-new.js +28 -0
- package/dist/types/use-get-memoized-merged-trigger-ref-new.d.ts +7 -0
- package/dist/types-ts4.5/use-get-memoized-merged-trigger-ref-new.d.ts +7 -0
- package/package.json +5 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/popup
|
|
2
2
|
|
|
3
|
+
## 1.24.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#124840](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/124840)
|
|
8
|
+
[`2e4f70b9a71fa`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2e4f70b9a71fa) -
|
|
9
|
+
Fix to set ref for trigger in React 18 Strict mode behind feature flag
|
|
10
|
+
|
|
11
|
+
## 1.23.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [#134766](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/134766)
|
|
16
|
+
[`56e1c0d98f0c2`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/56e1c0d98f0c2) -
|
|
17
|
+
Fixed unnecessary closing of modal dialogs that opened from a popup.
|
|
18
|
+
|
|
3
19
|
## 1.23.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/cjs/popup.js
CHANGED
|
@@ -17,6 +17,7 @@ var _primitives = require("@atlaskit/primitives");
|
|
|
17
17
|
var _constants = require("@atlaskit/theme/constants");
|
|
18
18
|
var _popperWrapper = _interopRequireDefault(require("./popper-wrapper"));
|
|
19
19
|
var _useGetMemoizedMergedTriggerRef = require("./use-get-memoized-merged-trigger-ref");
|
|
20
|
+
var _useGetMemoizedMergedTriggerRefNew = require("./use-get-memoized-merged-trigger-ref-new");
|
|
20
21
|
/* eslint-disable @repo/internal/react/require-jsdoc */
|
|
21
22
|
/**
|
|
22
23
|
* @jsxRuntime classic
|
|
@@ -70,6 +71,7 @@ var Popup = exports.Popup = /*#__PURE__*/(0, _react.memo)(function (_ref) {
|
|
|
70
71
|
triggerRef = _useState2[0],
|
|
71
72
|
setTriggerRef = _useState2[1];
|
|
72
73
|
var getMergedTriggerRef = (0, _useGetMemoizedMergedTriggerRef.useGetMemoizedMergedTriggerRef)();
|
|
74
|
+
var getMergedTriggerRefNew = (0, _useGetMemoizedMergedTriggerRefNew.useGetMemoizedMergedTriggerRefNew)();
|
|
73
75
|
var generatedId = (0, _reactUid.useUID)();
|
|
74
76
|
var id = providedId || generatedId;
|
|
75
77
|
var renderPopperWrapper = (0, _react2.jsx)(_layering.UNSAFE_LAYERING, {
|
|
@@ -103,7 +105,7 @@ var Popup = exports.Popup = /*#__PURE__*/(0, _react.memo)(function (_ref) {
|
|
|
103
105
|
var popupContent = (0, _react2.jsx)(_popper.Manager, null, (0, _react2.jsx)(_popper.Reference, null, function (_ref2) {
|
|
104
106
|
var ref = _ref2.ref;
|
|
105
107
|
return trigger({
|
|
106
|
-
ref: getMergedTriggerRef(ref, setTriggerRef, isOpen),
|
|
108
|
+
ref: !(0, _platformFeatureFlags.fg)('platform-design-system-dsp-20476-dropdown-menu') ? getMergedTriggerRef(ref, setTriggerRef, isOpen) : getMergedTriggerRefNew(ref, setTriggerRef),
|
|
107
109
|
'aria-controls': isOpen ? id : undefined,
|
|
108
110
|
'aria-expanded': isOpen,
|
|
109
111
|
'aria-haspopup': role === 'dialog' && (0, _platformFeatureFlags.fg)('platform_dst_popup-disable-focuslock') ? 'dialog' : true
|
|
@@ -60,17 +60,9 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
|
|
|
60
60
|
if (!doesDomNodeExist) {
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
|
-
if ((
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
//if it is a disabled layer, we need to disable its click listener.
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
} else {
|
|
70
|
-
if (isLayerDisabled()) {
|
|
71
|
-
//if it is a disabled layer, we need to disable its click listener.
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
63
|
+
if (isLayerDisabled()) {
|
|
64
|
+
//if it is a disabled layer, we need to disable its click listener.
|
|
65
|
+
return;
|
|
74
66
|
}
|
|
75
67
|
var isClickOnPopup = popupRef && popupRef.contains(target);
|
|
76
68
|
var isClickOnTrigger = triggerRef && triggerRef.contains(target);
|
|
@@ -103,7 +95,7 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
|
|
|
103
95
|
return;
|
|
104
96
|
}
|
|
105
97
|
if (key === 'Tab') {
|
|
106
|
-
var _document$
|
|
98
|
+
var _document$activeEleme;
|
|
107
99
|
// We have cases where we need to close the Popup on Tab press.
|
|
108
100
|
// Example: DropdownMenu
|
|
109
101
|
if (shouldCloseOnTab) {
|
|
@@ -113,7 +105,7 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
|
|
|
113
105
|
closePopup(event);
|
|
114
106
|
return;
|
|
115
107
|
}
|
|
116
|
-
if (isLayerDisabled() && (_document$
|
|
108
|
+
if (isLayerDisabled() && (_document$activeEleme = document.activeElement) !== null && _document$activeEleme !== void 0 && _document$activeEleme.closest('[aria-modal]')) {
|
|
117
109
|
return;
|
|
118
110
|
}
|
|
119
111
|
if (shouldDisableFocusTrap) {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.useGetMemoizedMergedTriggerRefNew = void 0;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _react = require("react");
|
|
10
|
+
var _memoizeOne = _interopRequireDefault(require("memoize-one"));
|
|
11
|
+
/**
|
|
12
|
+
* Here setting ref is not dependent on isOpen flag which is failing in React 18 strict mode
|
|
13
|
+
* Implemented behind ff `platform-design-system-dsp-20476-dropdown-menu`
|
|
14
|
+
* @returns Function to set trigger ref
|
|
15
|
+
*/
|
|
16
|
+
var useGetMemoizedMergedTriggerRefNew = exports.useGetMemoizedMergedTriggerRefNew = function useGetMemoizedMergedTriggerRefNew() {
|
|
17
|
+
var _useState = (0, _react.useState)(function () {
|
|
18
|
+
return (0, _memoizeOne.default)(function (ref, setTriggerRef) {
|
|
19
|
+
return function (node) {
|
|
20
|
+
if (node) {
|
|
21
|
+
if (typeof ref === 'function') {
|
|
22
|
+
ref(node);
|
|
23
|
+
} else if (ref) {
|
|
24
|
+
ref.current = node;
|
|
25
|
+
}
|
|
26
|
+
setTriggerRef(node);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}),
|
|
31
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 1),
|
|
32
|
+
getMemoizedMergedTriggerRefNew = _useState2[0];
|
|
33
|
+
return getMemoizedMergedTriggerRefNew;
|
|
34
|
+
};
|
package/dist/es2019/popup.js
CHANGED
|
@@ -16,6 +16,7 @@ import { Box, xcss } from '@atlaskit/primitives';
|
|
|
16
16
|
import { layers } from '@atlaskit/theme/constants';
|
|
17
17
|
import PopperWrapper from './popper-wrapper';
|
|
18
18
|
import { useGetMemoizedMergedTriggerRef } from './use-get-memoized-merged-trigger-ref';
|
|
19
|
+
import { useGetMemoizedMergedTriggerRefNew } from './use-get-memoized-merged-trigger-ref-new';
|
|
19
20
|
const defaultLayer = layers.layer();
|
|
20
21
|
const wrapperStyles = xcss({
|
|
21
22
|
position: 'relative'
|
|
@@ -49,6 +50,7 @@ export const Popup = /*#__PURE__*/memo(({
|
|
|
49
50
|
}) => {
|
|
50
51
|
const [triggerRef, setTriggerRef] = useState(null);
|
|
51
52
|
const getMergedTriggerRef = useGetMemoizedMergedTriggerRef();
|
|
53
|
+
const getMergedTriggerRefNew = useGetMemoizedMergedTriggerRefNew();
|
|
52
54
|
const generatedId = useUID();
|
|
53
55
|
const id = providedId || generatedId;
|
|
54
56
|
const renderPopperWrapper = jsx(UNSAFE_LAYERING, {
|
|
@@ -83,7 +85,7 @@ export const Popup = /*#__PURE__*/memo(({
|
|
|
83
85
|
ref
|
|
84
86
|
}) => {
|
|
85
87
|
return trigger({
|
|
86
|
-
ref: getMergedTriggerRef(ref, setTriggerRef, isOpen),
|
|
88
|
+
ref: !fg('platform-design-system-dsp-20476-dropdown-menu') ? getMergedTriggerRef(ref, setTriggerRef, isOpen) : getMergedTriggerRefNew(ref, setTriggerRef),
|
|
87
89
|
'aria-controls': isOpen ? id : undefined,
|
|
88
90
|
'aria-expanded': isOpen,
|
|
89
91
|
'aria-haspopup': role === 'dialog' && fg('platform_dst_popup-disable-focuslock') ? 'dialog' : true
|
|
@@ -57,17 +57,9 @@ export const useCloseManager = ({
|
|
|
57
57
|
if (!doesDomNodeExist) {
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//if it is a disabled layer, we need to disable its click listener.
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
} else {
|
|
67
|
-
if (isLayerDisabled()) {
|
|
68
|
-
//if it is a disabled layer, we need to disable its click listener.
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
60
|
+
if (isLayerDisabled()) {
|
|
61
|
+
//if it is a disabled layer, we need to disable its click listener.
|
|
62
|
+
return;
|
|
71
63
|
}
|
|
72
64
|
const isClickOnPopup = popupRef && popupRef.contains(target);
|
|
73
65
|
const isClickOnTrigger = triggerRef && triggerRef.contains(target);
|
|
@@ -102,7 +94,7 @@ export const useCloseManager = ({
|
|
|
102
94
|
return;
|
|
103
95
|
}
|
|
104
96
|
if (key === 'Tab') {
|
|
105
|
-
var _document$
|
|
97
|
+
var _document$activeEleme;
|
|
106
98
|
// We have cases where we need to close the Popup on Tab press.
|
|
107
99
|
// Example: DropdownMenu
|
|
108
100
|
if (shouldCloseOnTab) {
|
|
@@ -112,7 +104,7 @@ export const useCloseManager = ({
|
|
|
112
104
|
closePopup(event);
|
|
113
105
|
return;
|
|
114
106
|
}
|
|
115
|
-
if (isLayerDisabled() && (_document$
|
|
107
|
+
if (isLayerDisabled() && (_document$activeEleme = document.activeElement) !== null && _document$activeEleme !== void 0 && _document$activeEleme.closest('[aria-modal]')) {
|
|
116
108
|
return;
|
|
117
109
|
}
|
|
118
110
|
if (shouldDisableFocusTrap) {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import memoizeOne from 'memoize-one';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Here setting ref is not dependent on isOpen flag which is failing in React 18 strict mode
|
|
6
|
+
* Implemented behind ff `platform-design-system-dsp-20476-dropdown-menu`
|
|
7
|
+
* @returns Function to set trigger ref
|
|
8
|
+
*/
|
|
9
|
+
export const useGetMemoizedMergedTriggerRefNew = () => {
|
|
10
|
+
const [getMemoizedMergedTriggerRefNew] = useState(() => memoizeOne((ref, setTriggerRef) => {
|
|
11
|
+
return node => {
|
|
12
|
+
if (node) {
|
|
13
|
+
if (typeof ref === 'function') {
|
|
14
|
+
ref(node);
|
|
15
|
+
} else if (ref) {
|
|
16
|
+
ref.current = node;
|
|
17
|
+
}
|
|
18
|
+
setTriggerRef(node);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}));
|
|
22
|
+
return getMemoizedMergedTriggerRefNew;
|
|
23
|
+
};
|
package/dist/esm/popup.js
CHANGED
|
@@ -17,6 +17,7 @@ import { Box, xcss } from '@atlaskit/primitives';
|
|
|
17
17
|
import { layers } from '@atlaskit/theme/constants';
|
|
18
18
|
import PopperWrapper from './popper-wrapper';
|
|
19
19
|
import { useGetMemoizedMergedTriggerRef } from './use-get-memoized-merged-trigger-ref';
|
|
20
|
+
import { useGetMemoizedMergedTriggerRefNew } from './use-get-memoized-merged-trigger-ref-new';
|
|
20
21
|
var defaultLayer = layers.layer();
|
|
21
22
|
var wrapperStyles = xcss({
|
|
22
23
|
position: 'relative'
|
|
@@ -62,6 +63,7 @@ export var Popup = /*#__PURE__*/memo(function (_ref) {
|
|
|
62
63
|
triggerRef = _useState2[0],
|
|
63
64
|
setTriggerRef = _useState2[1];
|
|
64
65
|
var getMergedTriggerRef = useGetMemoizedMergedTriggerRef();
|
|
66
|
+
var getMergedTriggerRefNew = useGetMemoizedMergedTriggerRefNew();
|
|
65
67
|
var generatedId = useUID();
|
|
66
68
|
var id = providedId || generatedId;
|
|
67
69
|
var renderPopperWrapper = jsx(UNSAFE_LAYERING, {
|
|
@@ -95,7 +97,7 @@ export var Popup = /*#__PURE__*/memo(function (_ref) {
|
|
|
95
97
|
var popupContent = jsx(Manager, null, jsx(Reference, null, function (_ref2) {
|
|
96
98
|
var ref = _ref2.ref;
|
|
97
99
|
return trigger({
|
|
98
|
-
ref: getMergedTriggerRef(ref, setTriggerRef, isOpen),
|
|
100
|
+
ref: !fg('platform-design-system-dsp-20476-dropdown-menu') ? getMergedTriggerRef(ref, setTriggerRef, isOpen) : getMergedTriggerRefNew(ref, setTriggerRef),
|
|
99
101
|
'aria-controls': isOpen ? id : undefined,
|
|
100
102
|
'aria-expanded': isOpen,
|
|
101
103
|
'aria-haspopup': role === 'dialog' && fg('platform_dst_popup-disable-focuslock') ? 'dialog' : true
|
|
@@ -52,17 +52,9 @@ export var useCloseManager = function useCloseManager(_ref) {
|
|
|
52
52
|
if (!doesDomNodeExist) {
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
//if it is a disabled layer, we need to disable its click listener.
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
} else {
|
|
62
|
-
if (isLayerDisabled()) {
|
|
63
|
-
//if it is a disabled layer, we need to disable its click listener.
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
55
|
+
if (isLayerDisabled()) {
|
|
56
|
+
//if it is a disabled layer, we need to disable its click listener.
|
|
57
|
+
return;
|
|
66
58
|
}
|
|
67
59
|
var isClickOnPopup = popupRef && popupRef.contains(target);
|
|
68
60
|
var isClickOnTrigger = triggerRef && triggerRef.contains(target);
|
|
@@ -95,7 +87,7 @@ export var useCloseManager = function useCloseManager(_ref) {
|
|
|
95
87
|
return;
|
|
96
88
|
}
|
|
97
89
|
if (key === 'Tab') {
|
|
98
|
-
var _document$
|
|
90
|
+
var _document$activeEleme;
|
|
99
91
|
// We have cases where we need to close the Popup on Tab press.
|
|
100
92
|
// Example: DropdownMenu
|
|
101
93
|
if (shouldCloseOnTab) {
|
|
@@ -105,7 +97,7 @@ export var useCloseManager = function useCloseManager(_ref) {
|
|
|
105
97
|
closePopup(event);
|
|
106
98
|
return;
|
|
107
99
|
}
|
|
108
|
-
if (isLayerDisabled() && (_document$
|
|
100
|
+
if (isLayerDisabled() && (_document$activeEleme = document.activeElement) !== null && _document$activeEleme !== void 0 && _document$activeEleme.closest('[aria-modal]')) {
|
|
109
101
|
return;
|
|
110
102
|
}
|
|
111
103
|
if (shouldDisableFocusTrap) {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import memoizeOne from 'memoize-one';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Here setting ref is not dependent on isOpen flag which is failing in React 18 strict mode
|
|
7
|
+
* Implemented behind ff `platform-design-system-dsp-20476-dropdown-menu`
|
|
8
|
+
* @returns Function to set trigger ref
|
|
9
|
+
*/
|
|
10
|
+
export var useGetMemoizedMergedTriggerRefNew = function useGetMemoizedMergedTriggerRefNew() {
|
|
11
|
+
var _useState = useState(function () {
|
|
12
|
+
return memoizeOne(function (ref, setTriggerRef) {
|
|
13
|
+
return function (node) {
|
|
14
|
+
if (node) {
|
|
15
|
+
if (typeof ref === 'function') {
|
|
16
|
+
ref(node);
|
|
17
|
+
} else if (ref) {
|
|
18
|
+
ref.current = node;
|
|
19
|
+
}
|
|
20
|
+
setTriggerRef(node);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}),
|
|
25
|
+
_useState2 = _slicedToArray(_useState, 1),
|
|
26
|
+
getMemoizedMergedTriggerRefNew = _useState2[0];
|
|
27
|
+
return getMemoizedMergedTriggerRefNew;
|
|
28
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Dispatch, type SetStateAction } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Here setting ref is not dependent on isOpen flag which is failing in React 18 strict mode
|
|
4
|
+
* Implemented behind ff `platform-design-system-dsp-20476-dropdown-menu`
|
|
5
|
+
* @returns Function to set trigger ref
|
|
6
|
+
*/
|
|
7
|
+
export declare const useGetMemoizedMergedTriggerRefNew: () => import("memoize-one").MemoizedFn<(ref: React.RefCallback<HTMLElement> | React.MutableRefObject<HTMLElement> | null, setTriggerRef: Dispatch<SetStateAction<HTMLElement | null>>) => (node: HTMLElement | null) => void>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Dispatch, type SetStateAction } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Here setting ref is not dependent on isOpen flag which is failing in React 18 strict mode
|
|
4
|
+
* Implemented behind ff `platform-design-system-dsp-20476-dropdown-menu`
|
|
5
|
+
* @returns Function to set trigger ref
|
|
6
|
+
*/
|
|
7
|
+
export declare const useGetMemoizedMergedTriggerRefNew: () => import("memoize-one").MemoizedFn<(ref: React.RefCallback<HTMLElement> | React.MutableRefObject<HTMLElement> | null, setTriggerRef: Dispatch<SetStateAction<HTMLElement | null>>) => (node: HTMLElement | null) => void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/popup",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"description": "A popup displays brief content in an overlay.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -29,10 +29,6 @@
|
|
|
29
29
|
},
|
|
30
30
|
"atlassian": {
|
|
31
31
|
"team": "Design System Team",
|
|
32
|
-
"productPushConsumption": [
|
|
33
|
-
"jira"
|
|
34
|
-
],
|
|
35
|
-
"releaseModel": "continuous",
|
|
36
32
|
"runReact18": true,
|
|
37
33
|
"website": {
|
|
38
34
|
"name": "Popup",
|
|
@@ -45,7 +41,7 @@
|
|
|
45
41
|
"@atlaskit/platform-feature-flags": "^0.3.0",
|
|
46
42
|
"@atlaskit/popper": "^6.2.0",
|
|
47
43
|
"@atlaskit/portal": "^4.9.0",
|
|
48
|
-
"@atlaskit/primitives": "^12.
|
|
44
|
+
"@atlaskit/primitives": "^12.1.0",
|
|
49
45
|
"@atlaskit/theme": "^13.0.0",
|
|
50
46
|
"@atlaskit/tokens": "^1.59.0",
|
|
51
47
|
"@babel/runtime": "^7.0.0",
|
|
@@ -113,6 +109,9 @@
|
|
|
113
109
|
},
|
|
114
110
|
"platform_dst_popup-disable-focuslock": {
|
|
115
111
|
"type": "boolean"
|
|
112
|
+
},
|
|
113
|
+
"platform-design-system-dsp-20476-dropdown-menu": {
|
|
114
|
+
"type": "boolean"
|
|
116
115
|
}
|
|
117
116
|
},
|
|
118
117
|
"homepage": "https://atlassian.design/components/popup/"
|