@atlaskit/dropdown-menu 12.5.3 → 12.6.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 +16 -0
- package/dist/cjs/dropdown-menu.js +59 -18
- package/dist/cjs/internal/components/focus-manager.js +4 -3
- package/dist/cjs/internal/components/menu-wrapper.js +11 -2
- package/dist/cjs/internal/utils/handle-focus.js +21 -3
- package/dist/es2019/dropdown-menu.js +57 -17
- package/dist/es2019/internal/components/focus-manager.js +4 -3
- package/dist/es2019/internal/components/menu-wrapper.js +11 -2
- package/dist/es2019/internal/utils/handle-focus.js +22 -4
- package/dist/esm/dropdown-menu.js +57 -17
- package/dist/esm/internal/components/focus-manager.js +4 -3
- package/dist/esm/internal/components/menu-wrapper.js +11 -2
- package/dist/esm/internal/utils/handle-focus.js +22 -4
- package/dist/types/dropdown-menu.d.ts +0 -2
- package/dist/types/internal/components/focus-manager.d.ts +2 -1
- package/dist/types/internal/components/menu-wrapper.d.ts +1 -1
- package/dist/types/internal/utils/handle-focus.d.ts +1 -1
- package/dist/types/types.d.ts +4 -1
- package/dist/types-ts4.5/dropdown-menu.d.ts +0 -2
- package/dist/types-ts4.5/internal/components/focus-manager.d.ts +2 -1
- package/dist/types-ts4.5/internal/components/menu-wrapper.d.ts +1 -1
- package/dist/types-ts4.5/internal/utils/handle-focus.d.ts +1 -1
- package/dist/types-ts4.5/types.d.ts +4 -1
- package/package.json +8 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/dropdown-menu
|
|
2
2
|
|
|
3
|
+
## 12.6.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 12.6.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#70573](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/70573) [`ee7c6dd6b8b2`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/ee7c6dd6b8b2) - [ux] Accessibility changes. We are testing the ability to close the dropdown menu by pressing the Tab key when `shouldRenderToParent` is `true` behind a feature flag. If this fix is successful it will be available in a later release.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 12.5.3
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -5,7 +5,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.default =
|
|
8
|
+
exports.default = void 0;
|
|
9
9
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
10
10
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
11
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
@@ -19,6 +19,7 @@ var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
|
|
|
19
19
|
var _useControlled = _interopRequireDefault(require("@atlaskit/ds-lib/use-controlled"));
|
|
20
20
|
var _useFocusEvent = _interopRequireDefault(require("@atlaskit/ds-lib/use-focus-event"));
|
|
21
21
|
var _chevronDown = _interopRequireDefault(require("@atlaskit/icon/glyph/chevron-down"));
|
|
22
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
22
23
|
var _popup = _interopRequireDefault(require("@atlaskit/popup"));
|
|
23
24
|
var _constants = require("@atlaskit/theme/constants");
|
|
24
25
|
var _focusManager = _interopRequireDefault(require("./internal/components/focus-manager"));
|
|
@@ -26,7 +27,9 @@ var _menuWrapper = _interopRequireDefault(require("./internal/components/menu-wr
|
|
|
26
27
|
var _selectionStore = _interopRequireDefault(require("./internal/context/selection-store"));
|
|
27
28
|
var _useRegisterItemWithFocusManager = _interopRequireDefault(require("./internal/hooks/use-register-item-with-focus-manager"));
|
|
28
29
|
var _useGeneratedId = _interopRequireWildcard(require("./internal/utils/use-generated-id"));
|
|
29
|
-
var _excluded = ["ref", "aria-controls", "aria-expanded", "aria-haspopup"];
|
|
30
|
+
var _excluded = ["ref", "aria-controls", "aria-expanded", "aria-haspopup"];
|
|
31
|
+
/* eslint-disable import/order */
|
|
32
|
+
// eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
|
|
30
33
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
31
34
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
32
35
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -42,8 +45,6 @@ var opposites = {
|
|
|
42
45
|
auto: 'auto',
|
|
43
46
|
end: 'start'
|
|
44
47
|
};
|
|
45
|
-
var KEY_SPACE = exports.KEY_SPACE = ' ';
|
|
46
|
-
var KEY_ENTER = exports.KEY_ENTER = 'Enter';
|
|
47
48
|
var getFallbackPlacements = function getFallbackPlacements(placement) {
|
|
48
49
|
var placementPieces = placement.split('-');
|
|
49
50
|
var mainAxis = placementPieces[0];
|
|
@@ -136,6 +137,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
136
137
|
var _itemRef$current;
|
|
137
138
|
// The trigger element must be focused to avoid problems with an incorrectly focused element after closing DropdownMenu
|
|
138
139
|
itemRef === null || itemRef === void 0 || (_itemRef$current = itemRef.current) === null || _itemRef$current === void 0 || _itemRef$current.focus();
|
|
140
|
+
setTriggeredUsingKeyboard(false);
|
|
139
141
|
}
|
|
140
142
|
setLocalIsOpen(newValue);
|
|
141
143
|
onOpenChange({
|
|
@@ -144,10 +146,25 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
144
146
|
});
|
|
145
147
|
}, [itemRef, onOpenChange, isLocalOpen, setLocalIsOpen]);
|
|
146
148
|
var handleOnClose = (0, _react.useCallback)(function (event) {
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
if ((0, _platformFeatureFlags.getBooleanFF)('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
150
|
+
if (event.key !== 'Escape' && event.key !== 'Tab' && event.target.closest("[id^=".concat(_useGeneratedId.PREFIX, "] [aria-haspopup]"))) {
|
|
151
|
+
// Check if it is within dropdown and it is a trigger button
|
|
152
|
+
// if it is a nested dropdown, clicking trigger won't close the dropdown
|
|
153
|
+
// Dropdown can be closed by pressing Escape, Tab or Shift + Tab
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
|
|
157
|
+
requestAnimationFrame(function () {
|
|
158
|
+
var _itemRef$current2;
|
|
159
|
+
(_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 || _itemRef$current2.focus();
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
if (event.key !== 'Escape' && event.target.closest("[id^=".concat(_useGeneratedId.PREFIX, "] [aria-haspopup]"))) {
|
|
164
|
+
// Check if it is within dropdown and it is a trigger button
|
|
165
|
+
// if it is a nested dropdown, clicking trigger won't close the dropdown
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
151
168
|
}
|
|
152
169
|
var newValue = false;
|
|
153
170
|
setLocalIsOpen(newValue);
|
|
@@ -155,7 +172,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
155
172
|
isOpen: newValue,
|
|
156
173
|
event: event
|
|
157
174
|
});
|
|
158
|
-
}, [onOpenChange, setLocalIsOpen]);
|
|
175
|
+
}, [onOpenChange, setLocalIsOpen, itemRef]);
|
|
159
176
|
var _useFocus = (0, _useFocusEvent.default)(),
|
|
160
177
|
isFocused = _useFocus.isFocused,
|
|
161
178
|
bindFocus = _useFocus.bindFocus;
|
|
@@ -176,17 +193,35 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
176
193
|
return (0, _bindEventListener.bind)(window, {
|
|
177
194
|
type: 'keydown',
|
|
178
195
|
listener: function openOnKeyDown(e) {
|
|
179
|
-
if (
|
|
180
|
-
|
|
181
|
-
e.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
196
|
+
if ((0, _platformFeatureFlags.getBooleanFF)('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
197
|
+
var isNestedTriggerButton;
|
|
198
|
+
if (e.target instanceof HTMLElement) {
|
|
199
|
+
isNestedTriggerButton = e.target.closest("[id^=".concat(_useGeneratedId.PREFIX, "] [aria-haspopup]"));
|
|
200
|
+
}
|
|
201
|
+
if (e.key === _keycodes.KEY_DOWN && !isNestedTriggerButton) {
|
|
202
|
+
// prevent page scroll
|
|
203
|
+
e.preventDefault();
|
|
204
|
+
handleTriggerClicked(e);
|
|
205
|
+
} else if ((e.code === _keycodes.KEY_SPACE || e.key === _keycodes.KEY_ENTER) && e.detail === 0) {
|
|
206
|
+
// This allows us to focus on the first element if the dropdown was triggered by a custom trigger with a custom onClick
|
|
207
|
+
setTriggeredUsingKeyboard(true);
|
|
208
|
+
} else if (e.key === _keycodes.KEY_TAB && isNestedTriggerButton) {
|
|
209
|
+
// This closes dropdown if it is a nested dropdown
|
|
210
|
+
handleOnClose(e);
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
if (e.key === _keycodes.KEY_DOWN) {
|
|
214
|
+
// prevent page scroll
|
|
215
|
+
e.preventDefault();
|
|
216
|
+
handleTriggerClicked(e);
|
|
217
|
+
} else if ((e.code === _keycodes.KEY_SPACE || e.key === _keycodes.KEY_ENTER) && e.detail === 0) {
|
|
218
|
+
// This allows us to focus on the first element if the dropdown was triggered by a custom trigger with a custom onClick
|
|
219
|
+
setTriggeredUsingKeyboard(true);
|
|
220
|
+
}
|
|
186
221
|
}
|
|
187
222
|
}
|
|
188
223
|
});
|
|
189
|
-
}, [isFocused, isLocalOpen, handleTriggerClicked]);
|
|
224
|
+
}, [isFocused, isLocalOpen, handleTriggerClicked, handleOnClose]);
|
|
190
225
|
return /*#__PURE__*/_react.default.createElement(_selectionStore.default, null, /*#__PURE__*/_react.default.createElement(_popup.default, {
|
|
191
226
|
id: isLocalOpen ? id : undefined,
|
|
192
227
|
shouldFlip: shouldFlip,
|
|
@@ -198,6 +233,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
198
233
|
testId: testId && "".concat(testId, "--content"),
|
|
199
234
|
shouldUseCaptureOnOutsideClick: true,
|
|
200
235
|
shouldRenderToParent: shouldRenderToParent,
|
|
236
|
+
shouldDisableFocusLock: (0, _platformFeatureFlags.getBooleanFF)('platform.design-system-team.disable-focus-lock-in-popup_7kb4d') ? true : false,
|
|
201
237
|
trigger: function trigger(_ref2) {
|
|
202
238
|
var ref = _ref2.ref,
|
|
203
239
|
ariaControls = _ref2['aria-controls'],
|
|
@@ -231,7 +267,9 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
231
267
|
content: function content(_ref3) {
|
|
232
268
|
var setInitialFocusRef = _ref3.setInitialFocusRef,
|
|
233
269
|
update = _ref3.update;
|
|
234
|
-
return /*#__PURE__*/_react.default.createElement(_focusManager.default,
|
|
270
|
+
return /*#__PURE__*/_react.default.createElement(_focusManager.default, {
|
|
271
|
+
onClose: handleOnClose
|
|
272
|
+
}, /*#__PURE__*/_react.default.createElement(_menuWrapper.default, {
|
|
235
273
|
spacing: spacing,
|
|
236
274
|
maxHeight: MAX_HEIGHT,
|
|
237
275
|
maxWidth: 800,
|
|
@@ -240,6 +278,9 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
240
278
|
isLoading: isLoading,
|
|
241
279
|
statusLabel: statusLabel,
|
|
242
280
|
setInitialFocusRef: isTriggeredUsingKeyboard || autoFocus ? setInitialFocusRef : undefined,
|
|
281
|
+
shouldRenderToParent: shouldRenderToParent,
|
|
282
|
+
isTriggeredUsingKeyboard: isTriggeredUsingKeyboard,
|
|
283
|
+
autoFocus: autoFocus,
|
|
243
284
|
testId: testId && "".concat(testId, "--menu-wrapper")
|
|
244
285
|
}, children));
|
|
245
286
|
}
|
|
@@ -27,10 +27,11 @@ var FocusManagerContext = exports.FocusManagerContext = /*#__PURE__*/(0, _react.
|
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
* Focus manager logic
|
|
30
|
+
* Focus manager logic.
|
|
31
31
|
*/
|
|
32
32
|
var FocusManager = function FocusManager(_ref) {
|
|
33
|
-
var children = _ref.children
|
|
33
|
+
var children = _ref.children,
|
|
34
|
+
onClose = _ref.onClose;
|
|
34
35
|
var menuItemRefs = (0, _react.useRef)([]);
|
|
35
36
|
var registerRef = (0, _react.useCallback)(function (ref) {
|
|
36
37
|
if (ref && !menuItemRefs.current.includes(ref)) {
|
|
@@ -43,7 +44,7 @@ var FocusManager = function FocusManager(_ref) {
|
|
|
43
44
|
(0, _react.useEffect)(function () {
|
|
44
45
|
return (0, _bindEventListener.bind)(window, {
|
|
45
46
|
type: 'keydown',
|
|
46
|
-
listener: (0, _handleFocus.default)(menuItemRefs.current, isLayerDisabled)
|
|
47
|
+
listener: (0, _handleFocus.default)(menuItemRefs.current, isLayerDisabled, onClose)
|
|
47
48
|
});
|
|
48
49
|
});
|
|
49
50
|
var contextValue = {
|
|
@@ -8,6 +8,7 @@ exports.default = void 0;
|
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
var _react2 = require("@emotion/react");
|
|
10
10
|
var _menuGroup = _interopRequireDefault(require("@atlaskit/menu/menu-group"));
|
|
11
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
11
12
|
var _primitives = require("@atlaskit/primitives");
|
|
12
13
|
var _spinner = _interopRequireDefault(require("@atlaskit/spinner"));
|
|
13
14
|
var _focusManager = require("../components/focus-manager");
|
|
@@ -49,8 +50,11 @@ var MenuWrapper = function MenuWrapper(_ref2) {
|
|
|
49
50
|
onUpdate = _ref2.onUpdate,
|
|
50
51
|
statusLabel = _ref2.statusLabel,
|
|
51
52
|
setInitialFocusRef = _ref2.setInitialFocusRef,
|
|
53
|
+
shouldRenderToParent = _ref2.shouldRenderToParent,
|
|
52
54
|
spacing = _ref2.spacing,
|
|
53
|
-
testId = _ref2.testId
|
|
55
|
+
testId = _ref2.testId,
|
|
56
|
+
isTriggeredUsingKeyboard = _ref2.isTriggeredUsingKeyboard,
|
|
57
|
+
autoFocus = _ref2.autoFocus;
|
|
54
58
|
var _useContext = (0, _react.useContext)(_focusManager.FocusManagerContext),
|
|
55
59
|
menuItemRefs = _useContext.menuItemRefs;
|
|
56
60
|
var closeOnMenuItemClick = function closeOnMenuItemClick(e) {
|
|
@@ -79,8 +83,13 @@ var MenuWrapper = function MenuWrapper(_ref2) {
|
|
|
79
83
|
var firstFocusableRef = (_menuItemRefs$find = menuItemRefs.find(function (ref) {
|
|
80
84
|
return !ref.hasAttribute('disabled');
|
|
81
85
|
})) !== null && _menuItemRefs$find !== void 0 ? _menuItemRefs$find : null;
|
|
86
|
+
if ((0, _platformFeatureFlags.getBooleanFF)('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
87
|
+
if (shouldRenderToParent && (isTriggeredUsingKeyboard || autoFocus)) {
|
|
88
|
+
firstFocusableRef === null || firstFocusableRef === void 0 || firstFocusableRef.focus();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
82
91
|
setInitialFocusRef === null || setInitialFocusRef === void 0 || setInitialFocusRef(firstFocusableRef);
|
|
83
|
-
}, [menuItemRefs, setInitialFocusRef]);
|
|
92
|
+
}, [menuItemRefs, setInitialFocusRef, autoFocus, shouldRenderToParent, isTriggeredUsingKeyboard]);
|
|
84
93
|
return (0, _react2.jsx)(_menuGroup.default, {
|
|
85
94
|
isLoading: isLoading,
|
|
86
95
|
maxHeight: maxHeight,
|
|
@@ -7,11 +7,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.default = handleFocus;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _keycodes = require("@atlaskit/ds-lib/keycodes");
|
|
10
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
10
11
|
var _actionMap;
|
|
11
12
|
var actionMap = (_actionMap = {}, (0, _defineProperty2.default)(_actionMap, _keycodes.KEY_DOWN, 'next'), (0, _defineProperty2.default)(_actionMap, _keycodes.KEY_UP, 'prev'), (0, _defineProperty2.default)(_actionMap, _keycodes.KEY_HOME, 'first'), (0, _defineProperty2.default)(_actionMap, _keycodes.KEY_END, 'last'), _actionMap);
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
|
-
* currentFocusedIdx + 1 will not work if the next focusable element
|
|
15
|
+
* `currentFocusedIdx + 1` will not work if the next focusable element
|
|
15
16
|
* is disabled. So, we need to iterate through the following menu items
|
|
16
17
|
* to find one that isn't disabled. If all following elements are disabled,
|
|
17
18
|
* return undefined.
|
|
@@ -27,7 +28,7 @@ var getNextFocusableElement = function getNextFocusableElement(refs, currentFocu
|
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
|
-
* currentFocusedIdx - 1 will not work if the prev focusable element
|
|
31
|
+
* `currentFocusedIdx - 1` will not work if the prev focusable element
|
|
31
32
|
* is disabled. So, we need to iterate through the previous menu items
|
|
32
33
|
* to find one that isn't disabled. If all previous elements are disabled,
|
|
33
34
|
* return undefined.
|
|
@@ -41,13 +42,20 @@ var getPrevFocusableElement = function getPrevFocusableElement(refs, currentFocu
|
|
|
41
42
|
currentFocusedIdx--;
|
|
42
43
|
}
|
|
43
44
|
};
|
|
44
|
-
function handleFocus(refs, isLayerDisabled) {
|
|
45
|
+
function handleFocus(refs, isLayerDisabled, onClose) {
|
|
45
46
|
return function (e) {
|
|
46
47
|
var currentFocusedIdx = refs.findIndex(function (el) {
|
|
47
48
|
var _document$activeEleme;
|
|
48
49
|
return (_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.isSameNode(el);
|
|
49
50
|
});
|
|
50
51
|
if (isLayerDisabled()) {
|
|
52
|
+
if ((0, _platformFeatureFlags.getBooleanFF)('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
53
|
+
// if nested dropdown isOpen we need to close on Tab key press
|
|
54
|
+
if (e.key === _keycodes.KEY_TAB && !e.shiftKey) {
|
|
55
|
+
onClose(e);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
// if it is a nested dropdown and the level of the given dropdown is not the current level,
|
|
52
60
|
// we don't need to have focus on it
|
|
53
61
|
return;
|
|
@@ -60,6 +68,11 @@ function handleFocus(refs, isLayerDisabled) {
|
|
|
60
68
|
if (currentFocusedIdx < refs.length - 1) {
|
|
61
69
|
var _nextFocusableElement = getNextFocusableElement(refs, currentFocusedIdx);
|
|
62
70
|
_nextFocusableElement === null || _nextFocusableElement === void 0 || _nextFocusableElement.focus();
|
|
71
|
+
} else {
|
|
72
|
+
if ((0, _platformFeatureFlags.getBooleanFF)('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
73
|
+
var firstFocusableElement = getNextFocusableElement(refs, -1);
|
|
74
|
+
firstFocusableElement === null || firstFocusableElement === void 0 || firstFocusableElement.focus();
|
|
75
|
+
}
|
|
63
76
|
}
|
|
64
77
|
break;
|
|
65
78
|
case 'prev':
|
|
@@ -68,6 +81,11 @@ function handleFocus(refs, isLayerDisabled) {
|
|
|
68
81
|
if (currentFocusedIdx > 0) {
|
|
69
82
|
var _prevFocusableElement = getPrevFocusableElement(refs, currentFocusedIdx);
|
|
70
83
|
_prevFocusableElement === null || _prevFocusableElement === void 0 || _prevFocusableElement.focus();
|
|
84
|
+
} else {
|
|
85
|
+
if ((0, _platformFeatureFlags.getBooleanFF)('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
86
|
+
var lastFocusableElement = getPrevFocusableElement(refs, refs.length);
|
|
87
|
+
lastFocusableElement === null || lastFocusableElement === void 0 || lastFocusableElement.focus();
|
|
88
|
+
}
|
|
71
89
|
}
|
|
72
90
|
break;
|
|
73
91
|
case 'first':
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
/* eslint-disable import/order */
|
|
2
3
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
4
|
import { bind } from 'bind-event-listener';
|
|
4
5
|
import Button from '@atlaskit/button/new';
|
|
5
|
-
import { KEY_DOWN } from '@atlaskit/ds-lib/keycodes';
|
|
6
|
+
import { KEY_DOWN, KEY_ENTER, KEY_SPACE, KEY_TAB } from '@atlaskit/ds-lib/keycodes';
|
|
6
7
|
import mergeRefs from '@atlaskit/ds-lib/merge-refs';
|
|
7
8
|
import noop from '@atlaskit/ds-lib/noop';
|
|
8
9
|
import useControlledState from '@atlaskit/ds-lib/use-controlled';
|
|
9
10
|
import useFocus from '@atlaskit/ds-lib/use-focus-event';
|
|
10
11
|
import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
|
|
12
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
11
13
|
import Popup from '@atlaskit/popup';
|
|
12
14
|
// eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
|
|
13
15
|
import { gridSize as gridSizeFn, layers } from '@atlaskit/theme/constants';
|
|
@@ -27,8 +29,6 @@ const opposites = {
|
|
|
27
29
|
auto: 'auto',
|
|
28
30
|
end: 'start'
|
|
29
31
|
};
|
|
30
|
-
export const KEY_SPACE = ' ';
|
|
31
|
-
export const KEY_ENTER = 'Enter';
|
|
32
32
|
const getFallbackPlacements = placement => {
|
|
33
33
|
const placementPieces = placement.split('-');
|
|
34
34
|
const mainAxis = placementPieces[0];
|
|
@@ -106,6 +106,7 @@ const DropdownMenu = ({
|
|
|
106
106
|
var _itemRef$current;
|
|
107
107
|
// The trigger element must be focused to avoid problems with an incorrectly focused element after closing DropdownMenu
|
|
108
108
|
itemRef === null || itemRef === void 0 ? void 0 : (_itemRef$current = itemRef.current) === null || _itemRef$current === void 0 ? void 0 : _itemRef$current.focus();
|
|
109
|
+
setTriggeredUsingKeyboard(false);
|
|
109
110
|
}
|
|
110
111
|
setLocalIsOpen(newValue);
|
|
111
112
|
onOpenChange({
|
|
@@ -114,10 +115,25 @@ const DropdownMenu = ({
|
|
|
114
115
|
});
|
|
115
116
|
}, [itemRef, onOpenChange, isLocalOpen, setLocalIsOpen]);
|
|
116
117
|
const handleOnClose = useCallback(event => {
|
|
117
|
-
if (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
119
|
+
if (event.key !== 'Escape' && event.key !== 'Tab' && event.target.closest(`[id^=${PREFIX}] [aria-haspopup]`)) {
|
|
120
|
+
// Check if it is within dropdown and it is a trigger button
|
|
121
|
+
// if it is a nested dropdown, clicking trigger won't close the dropdown
|
|
122
|
+
// Dropdown can be closed by pressing Escape, Tab or Shift + Tab
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
|
|
126
|
+
requestAnimationFrame(() => {
|
|
127
|
+
var _itemRef$current2;
|
|
128
|
+
(_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 ? void 0 : _itemRef$current2.focus();
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
if (event.key !== 'Escape' && event.target.closest(`[id^=${PREFIX}] [aria-haspopup]`)) {
|
|
133
|
+
// Check if it is within dropdown and it is a trigger button
|
|
134
|
+
// if it is a nested dropdown, clicking trigger won't close the dropdown
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
121
137
|
}
|
|
122
138
|
const newValue = false;
|
|
123
139
|
setLocalIsOpen(newValue);
|
|
@@ -125,7 +141,7 @@ const DropdownMenu = ({
|
|
|
125
141
|
isOpen: newValue,
|
|
126
142
|
event
|
|
127
143
|
});
|
|
128
|
-
}, [onOpenChange, setLocalIsOpen]);
|
|
144
|
+
}, [onOpenChange, setLocalIsOpen, itemRef]);
|
|
129
145
|
const {
|
|
130
146
|
isFocused,
|
|
131
147
|
bindFocus
|
|
@@ -147,17 +163,35 @@ const DropdownMenu = ({
|
|
|
147
163
|
return bind(window, {
|
|
148
164
|
type: 'keydown',
|
|
149
165
|
listener: function openOnKeyDown(e) {
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
e.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
166
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
167
|
+
let isNestedTriggerButton;
|
|
168
|
+
if (e.target instanceof HTMLElement) {
|
|
169
|
+
isNestedTriggerButton = e.target.closest(`[id^=${PREFIX}] [aria-haspopup]`);
|
|
170
|
+
}
|
|
171
|
+
if (e.key === KEY_DOWN && !isNestedTriggerButton) {
|
|
172
|
+
// prevent page scroll
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
handleTriggerClicked(e);
|
|
175
|
+
} else if ((e.code === KEY_SPACE || e.key === KEY_ENTER) && e.detail === 0) {
|
|
176
|
+
// This allows us to focus on the first element if the dropdown was triggered by a custom trigger with a custom onClick
|
|
177
|
+
setTriggeredUsingKeyboard(true);
|
|
178
|
+
} else if (e.key === KEY_TAB && isNestedTriggerButton) {
|
|
179
|
+
// This closes dropdown if it is a nested dropdown
|
|
180
|
+
handleOnClose(e);
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
if (e.key === KEY_DOWN) {
|
|
184
|
+
// prevent page scroll
|
|
185
|
+
e.preventDefault();
|
|
186
|
+
handleTriggerClicked(e);
|
|
187
|
+
} else if ((e.code === KEY_SPACE || e.key === KEY_ENTER) && e.detail === 0) {
|
|
188
|
+
// This allows us to focus on the first element if the dropdown was triggered by a custom trigger with a custom onClick
|
|
189
|
+
setTriggeredUsingKeyboard(true);
|
|
190
|
+
}
|
|
157
191
|
}
|
|
158
192
|
}
|
|
159
193
|
});
|
|
160
|
-
}, [isFocused, isLocalOpen, handleTriggerClicked]);
|
|
194
|
+
}, [isFocused, isLocalOpen, handleTriggerClicked, handleOnClose]);
|
|
161
195
|
return /*#__PURE__*/React.createElement(SelectionStore, null, /*#__PURE__*/React.createElement(Popup, {
|
|
162
196
|
id: isLocalOpen ? id : undefined,
|
|
163
197
|
shouldFlip: shouldFlip,
|
|
@@ -169,6 +203,7 @@ const DropdownMenu = ({
|
|
|
169
203
|
testId: testId && `${testId}--content`,
|
|
170
204
|
shouldUseCaptureOnOutsideClick: true,
|
|
171
205
|
shouldRenderToParent: shouldRenderToParent,
|
|
206
|
+
shouldDisableFocusLock: getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d') ? true : false,
|
|
172
207
|
trigger: ({
|
|
173
208
|
ref,
|
|
174
209
|
'aria-controls': ariaControls,
|
|
@@ -205,7 +240,9 @@ const DropdownMenu = ({
|
|
|
205
240
|
content: ({
|
|
206
241
|
setInitialFocusRef,
|
|
207
242
|
update
|
|
208
|
-
}) => /*#__PURE__*/React.createElement(FocusManager,
|
|
243
|
+
}) => /*#__PURE__*/React.createElement(FocusManager, {
|
|
244
|
+
onClose: handleOnClose
|
|
245
|
+
}, /*#__PURE__*/React.createElement(MenuWrapper, {
|
|
209
246
|
spacing: spacing,
|
|
210
247
|
maxHeight: MAX_HEIGHT,
|
|
211
248
|
maxWidth: 800,
|
|
@@ -214,6 +251,9 @@ const DropdownMenu = ({
|
|
|
214
251
|
isLoading: isLoading,
|
|
215
252
|
statusLabel: statusLabel,
|
|
216
253
|
setInitialFocusRef: isTriggeredUsingKeyboard || autoFocus ? setInitialFocusRef : undefined,
|
|
254
|
+
shouldRenderToParent: shouldRenderToParent,
|
|
255
|
+
isTriggeredUsingKeyboard: isTriggeredUsingKeyboard,
|
|
256
|
+
autoFocus: autoFocus,
|
|
217
257
|
testId: testId && `${testId}--menu-wrapper`
|
|
218
258
|
}, children))
|
|
219
259
|
}));
|
|
@@ -18,10 +18,11 @@ export const FocusManagerContext = /*#__PURE__*/createContext({
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* Focus manager logic
|
|
21
|
+
* Focus manager logic.
|
|
22
22
|
*/
|
|
23
23
|
const FocusManager = ({
|
|
24
|
-
children
|
|
24
|
+
children,
|
|
25
|
+
onClose
|
|
25
26
|
}) => {
|
|
26
27
|
const menuItemRefs = useRef([]);
|
|
27
28
|
const registerRef = useCallback(ref => {
|
|
@@ -36,7 +37,7 @@ const FocusManager = ({
|
|
|
36
37
|
useEffect(() => {
|
|
37
38
|
return bind(window, {
|
|
38
39
|
type: 'keydown',
|
|
39
|
-
listener: handleFocus(menuItemRefs.current, isLayerDisabled)
|
|
40
|
+
listener: handleFocus(menuItemRefs.current, isLayerDisabled, onClose)
|
|
40
41
|
});
|
|
41
42
|
});
|
|
42
43
|
const contextValue = {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { useContext, useEffect, useLayoutEffect } from 'react';
|
|
3
3
|
import { jsx } from '@emotion/react';
|
|
4
4
|
import MenuGroup from '@atlaskit/menu/menu-group';
|
|
5
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
5
6
|
import { Box, xcss } from '@atlaskit/primitives';
|
|
6
7
|
import Spinner from '@atlaskit/spinner';
|
|
7
8
|
import { FocusManagerContext } from '../components/focus-manager';
|
|
@@ -39,8 +40,11 @@ const MenuWrapper = ({
|
|
|
39
40
|
onUpdate,
|
|
40
41
|
statusLabel,
|
|
41
42
|
setInitialFocusRef,
|
|
43
|
+
shouldRenderToParent,
|
|
42
44
|
spacing,
|
|
43
|
-
testId
|
|
45
|
+
testId,
|
|
46
|
+
isTriggeredUsingKeyboard,
|
|
47
|
+
autoFocus
|
|
44
48
|
}) => {
|
|
45
49
|
const {
|
|
46
50
|
menuItemRefs
|
|
@@ -69,8 +73,13 @@ const MenuWrapper = ({
|
|
|
69
73
|
useEffect(() => {
|
|
70
74
|
var _menuItemRefs$find;
|
|
71
75
|
const firstFocusableRef = (_menuItemRefs$find = menuItemRefs.find(ref => !ref.hasAttribute('disabled'))) !== null && _menuItemRefs$find !== void 0 ? _menuItemRefs$find : null;
|
|
76
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
77
|
+
if (shouldRenderToParent && (isTriggeredUsingKeyboard || autoFocus)) {
|
|
78
|
+
firstFocusableRef === null || firstFocusableRef === void 0 ? void 0 : firstFocusableRef.focus();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
72
81
|
setInitialFocusRef === null || setInitialFocusRef === void 0 ? void 0 : setInitialFocusRef(firstFocusableRef);
|
|
73
|
-
}, [menuItemRefs, setInitialFocusRef]);
|
|
82
|
+
}, [menuItemRefs, setInitialFocusRef, autoFocus, shouldRenderToParent, isTriggeredUsingKeyboard]);
|
|
74
83
|
return jsx(MenuGroup, {
|
|
75
84
|
isLoading: isLoading,
|
|
76
85
|
maxHeight: maxHeight,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { KEY_DOWN, KEY_END, KEY_HOME, KEY_UP } from '@atlaskit/ds-lib/keycodes';
|
|
1
|
+
import { KEY_DOWN, KEY_END, KEY_HOME, KEY_TAB, KEY_UP } from '@atlaskit/ds-lib/keycodes';
|
|
2
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
2
3
|
const actionMap = {
|
|
3
4
|
[KEY_DOWN]: 'next',
|
|
4
5
|
[KEY_UP]: 'prev',
|
|
@@ -7,7 +8,7 @@ const actionMap = {
|
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
|
-
* currentFocusedIdx + 1 will not work if the next focusable element
|
|
11
|
+
* `currentFocusedIdx + 1` will not work if the next focusable element
|
|
11
12
|
* is disabled. So, we need to iterate through the following menu items
|
|
12
13
|
* to find one that isn't disabled. If all following elements are disabled,
|
|
13
14
|
* return undefined.
|
|
@@ -23,7 +24,7 @@ const getNextFocusableElement = (refs, currentFocusedIdx) => {
|
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
|
-
* currentFocusedIdx - 1 will not work if the prev focusable element
|
|
27
|
+
* `currentFocusedIdx - 1` will not work if the prev focusable element
|
|
27
28
|
* is disabled. So, we need to iterate through the previous menu items
|
|
28
29
|
* to find one that isn't disabled. If all previous elements are disabled,
|
|
29
30
|
* return undefined.
|
|
@@ -37,13 +38,20 @@ const getPrevFocusableElement = (refs, currentFocusedIdx) => {
|
|
|
37
38
|
currentFocusedIdx--;
|
|
38
39
|
}
|
|
39
40
|
};
|
|
40
|
-
export default function handleFocus(refs, isLayerDisabled) {
|
|
41
|
+
export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
41
42
|
return e => {
|
|
42
43
|
const currentFocusedIdx = refs.findIndex(el => {
|
|
43
44
|
var _document$activeEleme;
|
|
44
45
|
return (_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.isSameNode(el);
|
|
45
46
|
});
|
|
46
47
|
if (isLayerDisabled()) {
|
|
48
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
49
|
+
// if nested dropdown isOpen we need to close on Tab key press
|
|
50
|
+
if (e.key === KEY_TAB && !e.shiftKey) {
|
|
51
|
+
onClose(e);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
// if it is a nested dropdown and the level of the given dropdown is not the current level,
|
|
48
56
|
// we don't need to have focus on it
|
|
49
57
|
return;
|
|
@@ -56,6 +64,11 @@ export default function handleFocus(refs, isLayerDisabled) {
|
|
|
56
64
|
if (currentFocusedIdx < refs.length - 1) {
|
|
57
65
|
const nextFocusableElement = getNextFocusableElement(refs, currentFocusedIdx);
|
|
58
66
|
nextFocusableElement === null || nextFocusableElement === void 0 ? void 0 : nextFocusableElement.focus();
|
|
67
|
+
} else {
|
|
68
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
69
|
+
const firstFocusableElement = getNextFocusableElement(refs, -1);
|
|
70
|
+
firstFocusableElement === null || firstFocusableElement === void 0 ? void 0 : firstFocusableElement.focus();
|
|
71
|
+
}
|
|
59
72
|
}
|
|
60
73
|
break;
|
|
61
74
|
case 'prev':
|
|
@@ -64,6 +77,11 @@ export default function handleFocus(refs, isLayerDisabled) {
|
|
|
64
77
|
if (currentFocusedIdx > 0) {
|
|
65
78
|
const prevFocusableElement = getPrevFocusableElement(refs, currentFocusedIdx);
|
|
66
79
|
prevFocusableElement === null || prevFocusableElement === void 0 ? void 0 : prevFocusableElement.focus();
|
|
80
|
+
} else {
|
|
81
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
82
|
+
const lastFocusableElement = getPrevFocusableElement(refs, refs.length);
|
|
83
|
+
lastFocusableElement === null || lastFocusableElement === void 0 ? void 0 : lastFocusableElement.focus();
|
|
84
|
+
}
|
|
67
85
|
}
|
|
68
86
|
break;
|
|
69
87
|
case 'first':
|
|
@@ -5,15 +5,17 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
|
5
5
|
var _excluded = ["ref", "aria-controls", "aria-expanded", "aria-haspopup"];
|
|
6
6
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
7
7
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
8
|
+
/* eslint-disable import/order */
|
|
8
9
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
9
10
|
import { bind } from 'bind-event-listener';
|
|
10
11
|
import Button from '@atlaskit/button/new';
|
|
11
|
-
import { KEY_DOWN } from '@atlaskit/ds-lib/keycodes';
|
|
12
|
+
import { KEY_DOWN, KEY_ENTER, KEY_SPACE, KEY_TAB } from '@atlaskit/ds-lib/keycodes';
|
|
12
13
|
import mergeRefs from '@atlaskit/ds-lib/merge-refs';
|
|
13
14
|
import noop from '@atlaskit/ds-lib/noop';
|
|
14
15
|
import useControlledState from '@atlaskit/ds-lib/use-controlled';
|
|
15
16
|
import useFocus from '@atlaskit/ds-lib/use-focus-event';
|
|
16
17
|
import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
|
|
18
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
17
19
|
import Popup from '@atlaskit/popup';
|
|
18
20
|
// eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
|
|
19
21
|
import { gridSize as gridSizeFn, layers } from '@atlaskit/theme/constants';
|
|
@@ -33,8 +35,6 @@ var opposites = {
|
|
|
33
35
|
auto: 'auto',
|
|
34
36
|
end: 'start'
|
|
35
37
|
};
|
|
36
|
-
export var KEY_SPACE = ' ';
|
|
37
|
-
export var KEY_ENTER = 'Enter';
|
|
38
38
|
var getFallbackPlacements = function getFallbackPlacements(placement) {
|
|
39
39
|
var placementPieces = placement.split('-');
|
|
40
40
|
var mainAxis = placementPieces[0];
|
|
@@ -127,6 +127,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
127
127
|
var _itemRef$current;
|
|
128
128
|
// The trigger element must be focused to avoid problems with an incorrectly focused element after closing DropdownMenu
|
|
129
129
|
itemRef === null || itemRef === void 0 || (_itemRef$current = itemRef.current) === null || _itemRef$current === void 0 || _itemRef$current.focus();
|
|
130
|
+
setTriggeredUsingKeyboard(false);
|
|
130
131
|
}
|
|
131
132
|
setLocalIsOpen(newValue);
|
|
132
133
|
onOpenChange({
|
|
@@ -135,10 +136,25 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
135
136
|
});
|
|
136
137
|
}, [itemRef, onOpenChange, isLocalOpen, setLocalIsOpen]);
|
|
137
138
|
var handleOnClose = useCallback(function (event) {
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
140
|
+
if (event.key !== 'Escape' && event.key !== 'Tab' && event.target.closest("[id^=".concat(PREFIX, "] [aria-haspopup]"))) {
|
|
141
|
+
// Check if it is within dropdown and it is a trigger button
|
|
142
|
+
// if it is a nested dropdown, clicking trigger won't close the dropdown
|
|
143
|
+
// Dropdown can be closed by pressing Escape, Tab or Shift + Tab
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
|
|
147
|
+
requestAnimationFrame(function () {
|
|
148
|
+
var _itemRef$current2;
|
|
149
|
+
(_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 || _itemRef$current2.focus();
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
if (event.key !== 'Escape' && event.target.closest("[id^=".concat(PREFIX, "] [aria-haspopup]"))) {
|
|
154
|
+
// Check if it is within dropdown and it is a trigger button
|
|
155
|
+
// if it is a nested dropdown, clicking trigger won't close the dropdown
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
142
158
|
}
|
|
143
159
|
var newValue = false;
|
|
144
160
|
setLocalIsOpen(newValue);
|
|
@@ -146,7 +162,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
146
162
|
isOpen: newValue,
|
|
147
163
|
event: event
|
|
148
164
|
});
|
|
149
|
-
}, [onOpenChange, setLocalIsOpen]);
|
|
165
|
+
}, [onOpenChange, setLocalIsOpen, itemRef]);
|
|
150
166
|
var _useFocus = useFocus(),
|
|
151
167
|
isFocused = _useFocus.isFocused,
|
|
152
168
|
bindFocus = _useFocus.bindFocus;
|
|
@@ -167,17 +183,35 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
167
183
|
return bind(window, {
|
|
168
184
|
type: 'keydown',
|
|
169
185
|
listener: function openOnKeyDown(e) {
|
|
170
|
-
if (
|
|
171
|
-
|
|
172
|
-
e.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
186
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
187
|
+
var isNestedTriggerButton;
|
|
188
|
+
if (e.target instanceof HTMLElement) {
|
|
189
|
+
isNestedTriggerButton = e.target.closest("[id^=".concat(PREFIX, "] [aria-haspopup]"));
|
|
190
|
+
}
|
|
191
|
+
if (e.key === KEY_DOWN && !isNestedTriggerButton) {
|
|
192
|
+
// prevent page scroll
|
|
193
|
+
e.preventDefault();
|
|
194
|
+
handleTriggerClicked(e);
|
|
195
|
+
} else if ((e.code === KEY_SPACE || e.key === KEY_ENTER) && e.detail === 0) {
|
|
196
|
+
// This allows us to focus on the first element if the dropdown was triggered by a custom trigger with a custom onClick
|
|
197
|
+
setTriggeredUsingKeyboard(true);
|
|
198
|
+
} else if (e.key === KEY_TAB && isNestedTriggerButton) {
|
|
199
|
+
// This closes dropdown if it is a nested dropdown
|
|
200
|
+
handleOnClose(e);
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
if (e.key === KEY_DOWN) {
|
|
204
|
+
// prevent page scroll
|
|
205
|
+
e.preventDefault();
|
|
206
|
+
handleTriggerClicked(e);
|
|
207
|
+
} else if ((e.code === KEY_SPACE || e.key === KEY_ENTER) && e.detail === 0) {
|
|
208
|
+
// This allows us to focus on the first element if the dropdown was triggered by a custom trigger with a custom onClick
|
|
209
|
+
setTriggeredUsingKeyboard(true);
|
|
210
|
+
}
|
|
177
211
|
}
|
|
178
212
|
}
|
|
179
213
|
});
|
|
180
|
-
}, [isFocused, isLocalOpen, handleTriggerClicked]);
|
|
214
|
+
}, [isFocused, isLocalOpen, handleTriggerClicked, handleOnClose]);
|
|
181
215
|
return /*#__PURE__*/React.createElement(SelectionStore, null, /*#__PURE__*/React.createElement(Popup, {
|
|
182
216
|
id: isLocalOpen ? id : undefined,
|
|
183
217
|
shouldFlip: shouldFlip,
|
|
@@ -189,6 +223,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
189
223
|
testId: testId && "".concat(testId, "--content"),
|
|
190
224
|
shouldUseCaptureOnOutsideClick: true,
|
|
191
225
|
shouldRenderToParent: shouldRenderToParent,
|
|
226
|
+
shouldDisableFocusLock: getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d') ? true : false,
|
|
192
227
|
trigger: function trigger(_ref2) {
|
|
193
228
|
var ref = _ref2.ref,
|
|
194
229
|
ariaControls = _ref2['aria-controls'],
|
|
@@ -222,7 +257,9 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
222
257
|
content: function content(_ref3) {
|
|
223
258
|
var setInitialFocusRef = _ref3.setInitialFocusRef,
|
|
224
259
|
update = _ref3.update;
|
|
225
|
-
return /*#__PURE__*/React.createElement(FocusManager,
|
|
260
|
+
return /*#__PURE__*/React.createElement(FocusManager, {
|
|
261
|
+
onClose: handleOnClose
|
|
262
|
+
}, /*#__PURE__*/React.createElement(MenuWrapper, {
|
|
226
263
|
spacing: spacing,
|
|
227
264
|
maxHeight: MAX_HEIGHT,
|
|
228
265
|
maxWidth: 800,
|
|
@@ -231,6 +268,9 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
231
268
|
isLoading: isLoading,
|
|
232
269
|
statusLabel: statusLabel,
|
|
233
270
|
setInitialFocusRef: isTriggeredUsingKeyboard || autoFocus ? setInitialFocusRef : undefined,
|
|
271
|
+
shouldRenderToParent: shouldRenderToParent,
|
|
272
|
+
isTriggeredUsingKeyboard: isTriggeredUsingKeyboard,
|
|
273
|
+
autoFocus: autoFocus,
|
|
234
274
|
testId: testId && "".concat(testId, "--menu-wrapper")
|
|
235
275
|
}, children));
|
|
236
276
|
}
|
|
@@ -18,10 +18,11 @@ export var FocusManagerContext = /*#__PURE__*/createContext({
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* Focus manager logic
|
|
21
|
+
* Focus manager logic.
|
|
22
22
|
*/
|
|
23
23
|
var FocusManager = function FocusManager(_ref) {
|
|
24
|
-
var children = _ref.children
|
|
24
|
+
var children = _ref.children,
|
|
25
|
+
onClose = _ref.onClose;
|
|
25
26
|
var menuItemRefs = useRef([]);
|
|
26
27
|
var registerRef = useCallback(function (ref) {
|
|
27
28
|
if (ref && !menuItemRefs.current.includes(ref)) {
|
|
@@ -34,7 +35,7 @@ var FocusManager = function FocusManager(_ref) {
|
|
|
34
35
|
useEffect(function () {
|
|
35
36
|
return bind(window, {
|
|
36
37
|
type: 'keydown',
|
|
37
|
-
listener: handleFocus(menuItemRefs.current, isLayerDisabled)
|
|
38
|
+
listener: handleFocus(menuItemRefs.current, isLayerDisabled, onClose)
|
|
38
39
|
});
|
|
39
40
|
});
|
|
40
41
|
var contextValue = {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { useContext, useEffect, useLayoutEffect } from 'react';
|
|
3
3
|
import { jsx } from '@emotion/react';
|
|
4
4
|
import MenuGroup from '@atlaskit/menu/menu-group';
|
|
5
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
5
6
|
import { Box, xcss } from '@atlaskit/primitives';
|
|
6
7
|
import Spinner from '@atlaskit/spinner';
|
|
7
8
|
import { FocusManagerContext } from '../components/focus-manager';
|
|
@@ -41,8 +42,11 @@ var MenuWrapper = function MenuWrapper(_ref2) {
|
|
|
41
42
|
onUpdate = _ref2.onUpdate,
|
|
42
43
|
statusLabel = _ref2.statusLabel,
|
|
43
44
|
setInitialFocusRef = _ref2.setInitialFocusRef,
|
|
45
|
+
shouldRenderToParent = _ref2.shouldRenderToParent,
|
|
44
46
|
spacing = _ref2.spacing,
|
|
45
|
-
testId = _ref2.testId
|
|
47
|
+
testId = _ref2.testId,
|
|
48
|
+
isTriggeredUsingKeyboard = _ref2.isTriggeredUsingKeyboard,
|
|
49
|
+
autoFocus = _ref2.autoFocus;
|
|
46
50
|
var _useContext = useContext(FocusManagerContext),
|
|
47
51
|
menuItemRefs = _useContext.menuItemRefs;
|
|
48
52
|
var closeOnMenuItemClick = function closeOnMenuItemClick(e) {
|
|
@@ -71,8 +75,13 @@ var MenuWrapper = function MenuWrapper(_ref2) {
|
|
|
71
75
|
var firstFocusableRef = (_menuItemRefs$find = menuItemRefs.find(function (ref) {
|
|
72
76
|
return !ref.hasAttribute('disabled');
|
|
73
77
|
})) !== null && _menuItemRefs$find !== void 0 ? _menuItemRefs$find : null;
|
|
78
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
79
|
+
if (shouldRenderToParent && (isTriggeredUsingKeyboard || autoFocus)) {
|
|
80
|
+
firstFocusableRef === null || firstFocusableRef === void 0 || firstFocusableRef.focus();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
74
83
|
setInitialFocusRef === null || setInitialFocusRef === void 0 || setInitialFocusRef(firstFocusableRef);
|
|
75
|
-
}, [menuItemRefs, setInitialFocusRef]);
|
|
84
|
+
}, [menuItemRefs, setInitialFocusRef, autoFocus, shouldRenderToParent, isTriggeredUsingKeyboard]);
|
|
76
85
|
return jsx(MenuGroup, {
|
|
77
86
|
isLoading: isLoading,
|
|
78
87
|
maxHeight: maxHeight,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
var _actionMap;
|
|
3
|
-
import { KEY_DOWN, KEY_END, KEY_HOME, KEY_UP } from '@atlaskit/ds-lib/keycodes';
|
|
3
|
+
import { KEY_DOWN, KEY_END, KEY_HOME, KEY_TAB, KEY_UP } from '@atlaskit/ds-lib/keycodes';
|
|
4
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
4
5
|
var actionMap = (_actionMap = {}, _defineProperty(_actionMap, KEY_DOWN, 'next'), _defineProperty(_actionMap, KEY_UP, 'prev'), _defineProperty(_actionMap, KEY_HOME, 'first'), _defineProperty(_actionMap, KEY_END, 'last'), _actionMap);
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
* currentFocusedIdx + 1 will not work if the next focusable element
|
|
8
|
+
* `currentFocusedIdx + 1` will not work if the next focusable element
|
|
8
9
|
* is disabled. So, we need to iterate through the following menu items
|
|
9
10
|
* to find one that isn't disabled. If all following elements are disabled,
|
|
10
11
|
* return undefined.
|
|
@@ -20,7 +21,7 @@ var getNextFocusableElement = function getNextFocusableElement(refs, currentFocu
|
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
|
-
* currentFocusedIdx - 1 will not work if the prev focusable element
|
|
24
|
+
* `currentFocusedIdx - 1` will not work if the prev focusable element
|
|
24
25
|
* is disabled. So, we need to iterate through the previous menu items
|
|
25
26
|
* to find one that isn't disabled. If all previous elements are disabled,
|
|
26
27
|
* return undefined.
|
|
@@ -34,13 +35,20 @@ var getPrevFocusableElement = function getPrevFocusableElement(refs, currentFocu
|
|
|
34
35
|
currentFocusedIdx--;
|
|
35
36
|
}
|
|
36
37
|
};
|
|
37
|
-
export default function handleFocus(refs, isLayerDisabled) {
|
|
38
|
+
export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
38
39
|
return function (e) {
|
|
39
40
|
var currentFocusedIdx = refs.findIndex(function (el) {
|
|
40
41
|
var _document$activeEleme;
|
|
41
42
|
return (_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.isSameNode(el);
|
|
42
43
|
});
|
|
43
44
|
if (isLayerDisabled()) {
|
|
45
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
46
|
+
// if nested dropdown isOpen we need to close on Tab key press
|
|
47
|
+
if (e.key === KEY_TAB && !e.shiftKey) {
|
|
48
|
+
onClose(e);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
44
52
|
// if it is a nested dropdown and the level of the given dropdown is not the current level,
|
|
45
53
|
// we don't need to have focus on it
|
|
46
54
|
return;
|
|
@@ -53,6 +61,11 @@ export default function handleFocus(refs, isLayerDisabled) {
|
|
|
53
61
|
if (currentFocusedIdx < refs.length - 1) {
|
|
54
62
|
var _nextFocusableElement = getNextFocusableElement(refs, currentFocusedIdx);
|
|
55
63
|
_nextFocusableElement === null || _nextFocusableElement === void 0 || _nextFocusableElement.focus();
|
|
64
|
+
} else {
|
|
65
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
66
|
+
var firstFocusableElement = getNextFocusableElement(refs, -1);
|
|
67
|
+
firstFocusableElement === null || firstFocusableElement === void 0 || firstFocusableElement.focus();
|
|
68
|
+
}
|
|
56
69
|
}
|
|
57
70
|
break;
|
|
58
71
|
case 'prev':
|
|
@@ -61,6 +74,11 @@ export default function handleFocus(refs, isLayerDisabled) {
|
|
|
61
74
|
if (currentFocusedIdx > 0) {
|
|
62
75
|
var _prevFocusableElement = getPrevFocusableElement(refs, currentFocusedIdx);
|
|
63
76
|
_prevFocusableElement === null || _prevFocusableElement === void 0 || _prevFocusableElement.focus();
|
|
77
|
+
} else {
|
|
78
|
+
if (getBooleanFF('platform.design-system-team.disable-focus-lock-in-popup_7kb4d')) {
|
|
79
|
+
var lastFocusableElement = getPrevFocusableElement(refs, refs.length);
|
|
80
|
+
lastFocusableElement === null || lastFocusableElement === void 0 || lastFocusableElement.focus();
|
|
81
|
+
}
|
|
64
82
|
}
|
|
65
83
|
break;
|
|
66
84
|
case 'first':
|
|
@@ -13,9 +13,10 @@ export declare const FocusManagerContext: React.Context<{
|
|
|
13
13
|
registerRef: (ref: FocusableElement) => void;
|
|
14
14
|
}>;
|
|
15
15
|
/**
|
|
16
|
-
* Focus manager logic
|
|
16
|
+
* Focus manager logic.
|
|
17
17
|
*/
|
|
18
18
|
declare const FocusManager: FC<{
|
|
19
19
|
children: ReactNode;
|
|
20
|
+
onClose: (e: KeyboardEvent) => void;
|
|
20
21
|
}>;
|
|
21
22
|
export default FocusManager;
|
|
@@ -7,5 +7,5 @@ import { MenuWrapperProps } from '../../types';
|
|
|
7
7
|
* if a CheckboxItem or RadioItem is clicked.
|
|
8
8
|
* It also sets focus to the first menu item when opened.
|
|
9
9
|
*/
|
|
10
|
-
declare const MenuWrapper: ({ children, isLoading, maxHeight, maxWidth, onClose, onUpdate, statusLabel, setInitialFocusRef, spacing, testId, }: MenuWrapperProps) => jsx.JSX.Element;
|
|
10
|
+
declare const MenuWrapper: ({ children, isLoading, maxHeight, maxWidth, onClose, onUpdate, statusLabel, setInitialFocusRef, shouldRenderToParent, spacing, testId, isTriggeredUsingKeyboard, autoFocus, }: MenuWrapperProps) => jsx.JSX.Element;
|
|
11
11
|
export default MenuWrapper;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { FocusableElement } from '../../types';
|
|
2
|
-
export default function handleFocus(refs: Array<FocusableElement>, isLayerDisabled: () => boolean): (e: KeyboardEvent) => void;
|
|
2
|
+
export default function handleFocus(refs: Array<FocusableElement>, isLayerDisabled: () => boolean, onClose: (e: KeyboardEvent) => void): (e: KeyboardEvent) => void;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { KeyboardEvent, MouseEvent, ReactElement, ReactNode, Ref } from 'react';
|
|
|
2
2
|
import type { CustomItemComponentProps, CustomItemProps, MenuGroupProps, SectionProps } from '@atlaskit/menu/types';
|
|
3
3
|
import type { ContentProps, TriggerProps } from '@atlaskit/popup/types';
|
|
4
4
|
export type FocusableElement = HTMLAnchorElement | HTMLButtonElement;
|
|
5
|
-
export type Action = 'next' | 'prev' | 'first' | 'last';
|
|
5
|
+
export type Action = 'next' | 'prev' | 'first' | 'last' | 'tab';
|
|
6
6
|
export type Placement = 'auto-start' | 'auto' | 'auto-end' | 'top-start' | 'top' | 'top-end' | 'right-start' | 'right' | 'right-end' | 'bottom-end' | 'bottom' | 'bottom-start' | 'left-end' | 'left' | 'left-start';
|
|
7
7
|
export type ItemId = string;
|
|
8
8
|
export type GroupId = string;
|
|
@@ -49,6 +49,9 @@ export interface MenuWrapperProps extends MenuGroupProps {
|
|
|
49
49
|
onUpdate: ContentProps['update'];
|
|
50
50
|
isLoading?: DropdownMenuProps['isLoading'];
|
|
51
51
|
statusLabel?: DropdownMenuProps['statusLabel'];
|
|
52
|
+
shouldRenderToParent?: boolean;
|
|
53
|
+
isTriggeredUsingKeyboard?: boolean;
|
|
54
|
+
autoFocus?: boolean;
|
|
52
55
|
}
|
|
53
56
|
export interface DropdownMenuGroupProps extends SectionProps {
|
|
54
57
|
}
|
|
@@ -13,9 +13,10 @@ export declare const FocusManagerContext: React.Context<{
|
|
|
13
13
|
registerRef: (ref: FocusableElement) => void;
|
|
14
14
|
}>;
|
|
15
15
|
/**
|
|
16
|
-
* Focus manager logic
|
|
16
|
+
* Focus manager logic.
|
|
17
17
|
*/
|
|
18
18
|
declare const FocusManager: FC<{
|
|
19
19
|
children: ReactNode;
|
|
20
|
+
onClose: (e: KeyboardEvent) => void;
|
|
20
21
|
}>;
|
|
21
22
|
export default FocusManager;
|
|
@@ -7,5 +7,5 @@ import { MenuWrapperProps } from '../../types';
|
|
|
7
7
|
* if a CheckboxItem or RadioItem is clicked.
|
|
8
8
|
* It also sets focus to the first menu item when opened.
|
|
9
9
|
*/
|
|
10
|
-
declare const MenuWrapper: ({ children, isLoading, maxHeight, maxWidth, onClose, onUpdate, statusLabel, setInitialFocusRef, spacing, testId, }: MenuWrapperProps) => jsx.JSX.Element;
|
|
10
|
+
declare const MenuWrapper: ({ children, isLoading, maxHeight, maxWidth, onClose, onUpdate, statusLabel, setInitialFocusRef, shouldRenderToParent, spacing, testId, isTriggeredUsingKeyboard, autoFocus, }: MenuWrapperProps) => jsx.JSX.Element;
|
|
11
11
|
export default MenuWrapper;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { FocusableElement } from '../../types';
|
|
2
|
-
export default function handleFocus(refs: Array<FocusableElement>, isLayerDisabled: () => boolean): (e: KeyboardEvent) => void;
|
|
2
|
+
export default function handleFocus(refs: Array<FocusableElement>, isLayerDisabled: () => boolean, onClose: (e: KeyboardEvent) => void): (e: KeyboardEvent) => void;
|
|
@@ -2,7 +2,7 @@ import { KeyboardEvent, MouseEvent, ReactElement, ReactNode, Ref } from 'react';
|
|
|
2
2
|
import type { CustomItemComponentProps, CustomItemProps, MenuGroupProps, SectionProps } from '@atlaskit/menu/types';
|
|
3
3
|
import type { ContentProps, TriggerProps } from '@atlaskit/popup/types';
|
|
4
4
|
export type FocusableElement = HTMLAnchorElement | HTMLButtonElement;
|
|
5
|
-
export type Action = 'next' | 'prev' | 'first' | 'last';
|
|
5
|
+
export type Action = 'next' | 'prev' | 'first' | 'last' | 'tab';
|
|
6
6
|
export type Placement = 'auto-start' | 'auto' | 'auto-end' | 'top-start' | 'top' | 'top-end' | 'right-start' | 'right' | 'right-end' | 'bottom-end' | 'bottom' | 'bottom-start' | 'left-end' | 'left' | 'left-start';
|
|
7
7
|
export type ItemId = string;
|
|
8
8
|
export type GroupId = string;
|
|
@@ -49,6 +49,9 @@ export interface MenuWrapperProps extends MenuGroupProps {
|
|
|
49
49
|
onUpdate: ContentProps['update'];
|
|
50
50
|
isLoading?: DropdownMenuProps['isLoading'];
|
|
51
51
|
statusLabel?: DropdownMenuProps['statusLabel'];
|
|
52
|
+
shouldRenderToParent?: boolean;
|
|
53
|
+
isTriggeredUsingKeyboard?: boolean;
|
|
54
|
+
autoFocus?: boolean;
|
|
52
55
|
}
|
|
53
56
|
export interface DropdownMenuGroupProps extends SectionProps {
|
|
54
57
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/dropdown-menu",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.6.1",
|
|
4
4
|
"description": "A dropdown menu displays a list of actions or options to a user.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
"@atlaskit/layering": "^0.2.0",
|
|
34
34
|
"@atlaskit/menu": "^2.1.0",
|
|
35
35
|
"@atlaskit/platform-feature-flags": "^0.2.2",
|
|
36
|
-
"@atlaskit/popup": "^1.
|
|
37
|
-
"@atlaskit/primitives": "^
|
|
36
|
+
"@atlaskit/popup": "^1.13.0",
|
|
37
|
+
"@atlaskit/primitives": "^4.0.0",
|
|
38
38
|
"@atlaskit/spinner": "^16.0.0",
|
|
39
39
|
"@atlaskit/theme": "^12.6.0",
|
|
40
|
-
"@atlaskit/tokens": "^1.
|
|
40
|
+
"@atlaskit/tokens": "^1.39.0",
|
|
41
41
|
"@babel/runtime": "^7.0.0",
|
|
42
42
|
"@emotion/react": "^11.7.1",
|
|
43
43
|
"bind-event-listener": "^2.1.1"
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"@testing-library/dom": "^8.17.1",
|
|
57
57
|
"@testing-library/react": "^12.1.5",
|
|
58
58
|
"@testing-library/react-hooks": "^8.0.1",
|
|
59
|
+
"@testing-library/user-event": "^14.4.3",
|
|
59
60
|
"jest-in-case": "^1.0.2",
|
|
60
61
|
"jscodeshift": "^0.13.0",
|
|
61
62
|
"raf-stub": "^2.0.1",
|
|
@@ -110,6 +111,9 @@
|
|
|
110
111
|
},
|
|
111
112
|
"platform.design-system-team.update-input-border-wdith_5abwv": {
|
|
112
113
|
"type": "boolean"
|
|
114
|
+
},
|
|
115
|
+
"platform.design-system-team.disable-focus-lock-in-popup_7kb4d": {
|
|
116
|
+
"type": "boolean"
|
|
113
117
|
}
|
|
114
118
|
},
|
|
115
119
|
"homepage": "https://atlassian.design/components/dropdown-menu/",
|