@atlaskit/dropdown-menu 12.8.4 → 12.9.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/dropdown-menu.js +26 -46
- package/dist/cjs/internal/components/menu-wrapper.js +2 -5
- package/dist/cjs/internal/utils/handle-focus.js +7 -14
- package/dist/es2019/dropdown-menu.js +26 -46
- package/dist/es2019/internal/components/menu-wrapper.js +2 -5
- package/dist/es2019/internal/utils/handle-focus.js +7 -14
- package/dist/esm/dropdown-menu.js +26 -46
- package/dist/esm/internal/components/menu-wrapper.js +2 -5
- package/dist/esm/internal/utils/handle-focus.js +7 -14
- package/dist/types/types.d.ts +3 -2
- package/dist/types-ts4.5/types.d.ts +3 -2
- package/package.json +11 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/dropdown-menu
|
|
2
2
|
|
|
3
|
+
## 12.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#91117](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/91117) [`06ed35f020fb`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/06ed35f020fb) - Add support for React 18.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
|
|
13
|
+
## 12.8.5
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#84970](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/84970) [`ad0e069e2829`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/ad0e069e2829) - This removes the `platform.design-system-team.disable-focus-lock-in-popup_7kb4d` feature flag. The dropdown menu can be closed by pressing Tab or Shift + Tab if `shouldRenderToParent` is true.
|
|
18
|
+
|
|
3
19
|
## 12.8.4
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -19,7 +19,6 @@ 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");
|
|
23
22
|
var _popup = _interopRequireDefault(require("@atlaskit/popup"));
|
|
24
23
|
var _constants = require("@atlaskit/theme/constants");
|
|
25
24
|
var _focusManager = _interopRequireDefault(require("./internal/components/focus-manager"));
|
|
@@ -146,25 +145,17 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
146
145
|
});
|
|
147
146
|
}, [itemRef, onOpenChange, isLocalOpen, setLocalIsOpen]);
|
|
148
147
|
var handleOnClose = (0, _react.useCallback)(function (event) {
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
-
}
|
|
148
|
+
if (event.key !== 'Escape' && event.key !== 'Tab' && event.target.closest("[id^=".concat(_useGeneratedId.PREFIX, "] [aria-haspopup]"))) {
|
|
149
|
+
// Check if it is within dropdown and it is a trigger button
|
|
150
|
+
// if it is a nested dropdown, clicking trigger won't close the dropdown
|
|
151
|
+
// Dropdown can be closed by pressing Escape, Tab or Shift + Tab
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
|
|
155
|
+
requestAnimationFrame(function () {
|
|
156
|
+
var _itemRef$current2;
|
|
157
|
+
(_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 || _itemRef$current2.focus();
|
|
158
|
+
});
|
|
168
159
|
}
|
|
169
160
|
var newValue = false;
|
|
170
161
|
setLocalIsOpen(newValue);
|
|
@@ -193,31 +184,20 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
193
184
|
return (0, _bindEventListener.bind)(window, {
|
|
194
185
|
type: 'keydown',
|
|
195
186
|
listener: function openOnKeyDown(e) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
-
}
|
|
187
|
+
var isNestedTriggerButton;
|
|
188
|
+
if (e.target instanceof HTMLElement) {
|
|
189
|
+
isNestedTriggerButton = e.target.closest("[id^=".concat(_useGeneratedId.PREFIX, "] [aria-haspopup]"));
|
|
190
|
+
}
|
|
191
|
+
if (e.key === _keycodes.KEY_DOWN && !isNestedTriggerButton) {
|
|
192
|
+
// prevent page scroll
|
|
193
|
+
e.preventDefault();
|
|
194
|
+
handleTriggerClicked(e);
|
|
195
|
+
} else if ((e.code === _keycodes.KEY_SPACE || e.key === _keycodes.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 === _keycodes.KEY_TAB && isNestedTriggerButton) {
|
|
199
|
+
// This closes dropdown if it is a nested dropdown
|
|
200
|
+
handleOnClose(e);
|
|
221
201
|
}
|
|
222
202
|
}
|
|
223
203
|
});
|
|
@@ -233,7 +213,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
233
213
|
testId: testId && "".concat(testId, "--content"),
|
|
234
214
|
shouldUseCaptureOnOutsideClick: true,
|
|
235
215
|
shouldRenderToParent: shouldRenderToParent,
|
|
236
|
-
shouldDisableFocusLock:
|
|
216
|
+
shouldDisableFocusLock: true,
|
|
237
217
|
trigger: function trigger(_ref2) {
|
|
238
218
|
var ref = _ref2.ref,
|
|
239
219
|
ariaControls = _ref2['aria-controls'],
|
|
@@ -8,7 +8,6 @@ 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");
|
|
12
11
|
var _primitives = require("@atlaskit/primitives");
|
|
13
12
|
var _spinner = _interopRequireDefault(require("@atlaskit/spinner"));
|
|
14
13
|
var _focusManager = require("../components/focus-manager");
|
|
@@ -83,10 +82,8 @@ var MenuWrapper = function MenuWrapper(_ref2) {
|
|
|
83
82
|
var firstFocusableRef = (_menuItemRefs$find = menuItemRefs.find(function (ref) {
|
|
84
83
|
return !ref.hasAttribute('disabled');
|
|
85
84
|
})) !== null && _menuItemRefs$find !== void 0 ? _menuItemRefs$find : null;
|
|
86
|
-
if ((
|
|
87
|
-
|
|
88
|
-
firstFocusableRef === null || firstFocusableRef === void 0 || firstFocusableRef.focus();
|
|
89
|
-
}
|
|
85
|
+
if (shouldRenderToParent && (isTriggeredUsingKeyboard || autoFocus)) {
|
|
86
|
+
firstFocusableRef === null || firstFocusableRef === void 0 || firstFocusableRef.focus();
|
|
90
87
|
}
|
|
91
88
|
setInitialFocusRef === null || setInitialFocusRef === void 0 || setInitialFocusRef(firstFocusableRef);
|
|
92
89
|
}, [menuItemRefs, setInitialFocusRef, autoFocus, shouldRenderToParent, isTriggeredUsingKeyboard]);
|
|
@@ -7,7 +7,6 @@ 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");
|
|
11
10
|
var _actionMap;
|
|
12
11
|
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);
|
|
13
12
|
|
|
@@ -49,11 +48,9 @@ function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
49
48
|
return (_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.isSameNode(el);
|
|
50
49
|
});
|
|
51
50
|
if (isLayerDisabled()) {
|
|
52
|
-
if
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
onClose(e);
|
|
56
|
-
}
|
|
51
|
+
// if nested dropdown isOpen we need to close on Tab key press
|
|
52
|
+
if (e.key === _keycodes.KEY_TAB && !e.shiftKey) {
|
|
53
|
+
onClose(e);
|
|
57
54
|
}
|
|
58
55
|
|
|
59
56
|
// if it is a nested dropdown and the level of the given dropdown is not the current level,
|
|
@@ -69,10 +66,8 @@ function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
69
66
|
var _nextFocusableElement = getNextFocusableElement(refs, currentFocusedIdx);
|
|
70
67
|
_nextFocusableElement === null || _nextFocusableElement === void 0 || _nextFocusableElement.focus();
|
|
71
68
|
} else {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
firstFocusableElement === null || firstFocusableElement === void 0 || firstFocusableElement.focus();
|
|
75
|
-
}
|
|
69
|
+
var firstFocusableElement = getNextFocusableElement(refs, -1);
|
|
70
|
+
firstFocusableElement === null || firstFocusableElement === void 0 || firstFocusableElement.focus();
|
|
76
71
|
}
|
|
77
72
|
break;
|
|
78
73
|
case 'prev':
|
|
@@ -82,10 +77,8 @@ function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
82
77
|
var _prevFocusableElement = getPrevFocusableElement(refs, currentFocusedIdx);
|
|
83
78
|
_prevFocusableElement === null || _prevFocusableElement === void 0 || _prevFocusableElement.focus();
|
|
84
79
|
} else {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
lastFocusableElement === null || lastFocusableElement === void 0 || lastFocusableElement.focus();
|
|
88
|
-
}
|
|
80
|
+
var lastFocusableElement = getPrevFocusableElement(refs, refs.length);
|
|
81
|
+
lastFocusableElement === null || lastFocusableElement === void 0 || lastFocusableElement.focus();
|
|
89
82
|
}
|
|
90
83
|
break;
|
|
91
84
|
case 'first':
|
|
@@ -9,7 +9,6 @@ import noop from '@atlaskit/ds-lib/noop';
|
|
|
9
9
|
import useControlledState from '@atlaskit/ds-lib/use-controlled';
|
|
10
10
|
import useFocus from '@atlaskit/ds-lib/use-focus-event';
|
|
11
11
|
import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
|
|
12
|
-
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
13
12
|
import Popup from '@atlaskit/popup';
|
|
14
13
|
// eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
|
|
15
14
|
import { gridSize as gridSizeFn, layers } from '@atlaskit/theme/constants';
|
|
@@ -115,25 +114,17 @@ const DropdownMenu = ({
|
|
|
115
114
|
});
|
|
116
115
|
}, [itemRef, onOpenChange, isLocalOpen, setLocalIsOpen]);
|
|
117
116
|
const handleOnClose = useCallback(event => {
|
|
118
|
-
if (
|
|
119
|
-
if
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
}
|
|
117
|
+
if (event.key !== 'Escape' && event.key !== 'Tab' && event.target.closest(`[id^=${PREFIX}] [aria-haspopup]`)) {
|
|
118
|
+
// Check if it is within dropdown and it is a trigger button
|
|
119
|
+
// if it is a nested dropdown, clicking trigger won't close the dropdown
|
|
120
|
+
// Dropdown can be closed by pressing Escape, Tab or Shift + Tab
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
|
|
124
|
+
requestAnimationFrame(() => {
|
|
125
|
+
var _itemRef$current2;
|
|
126
|
+
(_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 ? void 0 : _itemRef$current2.focus();
|
|
127
|
+
});
|
|
137
128
|
}
|
|
138
129
|
const newValue = false;
|
|
139
130
|
setLocalIsOpen(newValue);
|
|
@@ -163,31 +154,20 @@ const DropdownMenu = ({
|
|
|
163
154
|
return bind(window, {
|
|
164
155
|
type: 'keydown',
|
|
165
156
|
listener: function openOnKeyDown(e) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
+
let isNestedTriggerButton;
|
|
158
|
+
if (e.target instanceof HTMLElement) {
|
|
159
|
+
isNestedTriggerButton = e.target.closest(`[id^=${PREFIX}] [aria-haspopup]`);
|
|
160
|
+
}
|
|
161
|
+
if (e.key === KEY_DOWN && !isNestedTriggerButton) {
|
|
162
|
+
// prevent page scroll
|
|
163
|
+
e.preventDefault();
|
|
164
|
+
handleTriggerClicked(e);
|
|
165
|
+
} else if ((e.code === KEY_SPACE || e.key === KEY_ENTER) && e.detail === 0) {
|
|
166
|
+
// This allows us to focus on the first element if the dropdown was triggered by a custom trigger with a custom onClick
|
|
167
|
+
setTriggeredUsingKeyboard(true);
|
|
168
|
+
} else if (e.key === KEY_TAB && isNestedTriggerButton) {
|
|
169
|
+
// This closes dropdown if it is a nested dropdown
|
|
170
|
+
handleOnClose(e);
|
|
191
171
|
}
|
|
192
172
|
}
|
|
193
173
|
});
|
|
@@ -203,7 +183,7 @@ const DropdownMenu = ({
|
|
|
203
183
|
testId: testId && `${testId}--content`,
|
|
204
184
|
shouldUseCaptureOnOutsideClick: true,
|
|
205
185
|
shouldRenderToParent: shouldRenderToParent,
|
|
206
|
-
shouldDisableFocusLock:
|
|
186
|
+
shouldDisableFocusLock: true,
|
|
207
187
|
trigger: ({
|
|
208
188
|
ref,
|
|
209
189
|
'aria-controls': ariaControls,
|
|
@@ -2,7 +2,6 @@
|
|
|
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';
|
|
6
5
|
import { Box, xcss } from '@atlaskit/primitives';
|
|
7
6
|
import Spinner from '@atlaskit/spinner';
|
|
8
7
|
import { FocusManagerContext } from '../components/focus-manager';
|
|
@@ -73,10 +72,8 @@ const MenuWrapper = ({
|
|
|
73
72
|
useEffect(() => {
|
|
74
73
|
var _menuItemRefs$find;
|
|
75
74
|
const firstFocusableRef = (_menuItemRefs$find = menuItemRefs.find(ref => !ref.hasAttribute('disabled'))) !== null && _menuItemRefs$find !== void 0 ? _menuItemRefs$find : null;
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
firstFocusableRef === null || firstFocusableRef === void 0 ? void 0 : firstFocusableRef.focus();
|
|
79
|
-
}
|
|
75
|
+
if (shouldRenderToParent && (isTriggeredUsingKeyboard || autoFocus)) {
|
|
76
|
+
firstFocusableRef === null || firstFocusableRef === void 0 ? void 0 : firstFocusableRef.focus();
|
|
80
77
|
}
|
|
81
78
|
setInitialFocusRef === null || setInitialFocusRef === void 0 ? void 0 : setInitialFocusRef(firstFocusableRef);
|
|
82
79
|
}, [menuItemRefs, setInitialFocusRef, autoFocus, shouldRenderToParent, isTriggeredUsingKeyboard]);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
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';
|
|
3
2
|
const actionMap = {
|
|
4
3
|
[KEY_DOWN]: 'next',
|
|
5
4
|
[KEY_UP]: 'prev',
|
|
@@ -45,11 +44,9 @@ export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
45
44
|
return (_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.isSameNode(el);
|
|
46
45
|
});
|
|
47
46
|
if (isLayerDisabled()) {
|
|
48
|
-
if
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
onClose(e);
|
|
52
|
-
}
|
|
47
|
+
// if nested dropdown isOpen we need to close on Tab key press
|
|
48
|
+
if (e.key === KEY_TAB && !e.shiftKey) {
|
|
49
|
+
onClose(e);
|
|
53
50
|
}
|
|
54
51
|
|
|
55
52
|
// if it is a nested dropdown and the level of the given dropdown is not the current level,
|
|
@@ -65,10 +62,8 @@ export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
65
62
|
const nextFocusableElement = getNextFocusableElement(refs, currentFocusedIdx);
|
|
66
63
|
nextFocusableElement === null || nextFocusableElement === void 0 ? void 0 : nextFocusableElement.focus();
|
|
67
64
|
} else {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
firstFocusableElement === null || firstFocusableElement === void 0 ? void 0 : firstFocusableElement.focus();
|
|
71
|
-
}
|
|
65
|
+
const firstFocusableElement = getNextFocusableElement(refs, -1);
|
|
66
|
+
firstFocusableElement === null || firstFocusableElement === void 0 ? void 0 : firstFocusableElement.focus();
|
|
72
67
|
}
|
|
73
68
|
break;
|
|
74
69
|
case 'prev':
|
|
@@ -78,10 +73,8 @@ export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
78
73
|
const prevFocusableElement = getPrevFocusableElement(refs, currentFocusedIdx);
|
|
79
74
|
prevFocusableElement === null || prevFocusableElement === void 0 ? void 0 : prevFocusableElement.focus();
|
|
80
75
|
} else {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
lastFocusableElement === null || lastFocusableElement === void 0 ? void 0 : lastFocusableElement.focus();
|
|
84
|
-
}
|
|
76
|
+
const lastFocusableElement = getPrevFocusableElement(refs, refs.length);
|
|
77
|
+
lastFocusableElement === null || lastFocusableElement === void 0 ? void 0 : lastFocusableElement.focus();
|
|
85
78
|
}
|
|
86
79
|
break;
|
|
87
80
|
case 'first':
|
|
@@ -15,7 +15,6 @@ import noop from '@atlaskit/ds-lib/noop';
|
|
|
15
15
|
import useControlledState from '@atlaskit/ds-lib/use-controlled';
|
|
16
16
|
import useFocus from '@atlaskit/ds-lib/use-focus-event';
|
|
17
17
|
import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
|
|
18
|
-
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
19
18
|
import Popup from '@atlaskit/popup';
|
|
20
19
|
// eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
|
|
21
20
|
import { gridSize as gridSizeFn, layers } from '@atlaskit/theme/constants';
|
|
@@ -136,25 +135,17 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
136
135
|
});
|
|
137
136
|
}, [itemRef, onOpenChange, isLocalOpen, setLocalIsOpen]);
|
|
138
137
|
var handleOnClose = useCallback(function (event) {
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
}
|
|
138
|
+
if (event.key !== 'Escape' && event.key !== 'Tab' && event.target.closest("[id^=".concat(PREFIX, "] [aria-haspopup]"))) {
|
|
139
|
+
// Check if it is within dropdown and it is a trigger button
|
|
140
|
+
// if it is a nested dropdown, clicking trigger won't close the dropdown
|
|
141
|
+
// Dropdown can be closed by pressing Escape, Tab or Shift + Tab
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
|
|
145
|
+
requestAnimationFrame(function () {
|
|
146
|
+
var _itemRef$current2;
|
|
147
|
+
(_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 || _itemRef$current2.focus();
|
|
148
|
+
});
|
|
158
149
|
}
|
|
159
150
|
var newValue = false;
|
|
160
151
|
setLocalIsOpen(newValue);
|
|
@@ -183,31 +174,20 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
183
174
|
return bind(window, {
|
|
184
175
|
type: 'keydown',
|
|
185
176
|
listener: function openOnKeyDown(e) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
+
var isNestedTriggerButton;
|
|
178
|
+
if (e.target instanceof HTMLElement) {
|
|
179
|
+
isNestedTriggerButton = e.target.closest("[id^=".concat(PREFIX, "] [aria-haspopup]"));
|
|
180
|
+
}
|
|
181
|
+
if (e.key === KEY_DOWN && !isNestedTriggerButton) {
|
|
182
|
+
// prevent page scroll
|
|
183
|
+
e.preventDefault();
|
|
184
|
+
handleTriggerClicked(e);
|
|
185
|
+
} else if ((e.code === KEY_SPACE || e.key === KEY_ENTER) && e.detail === 0) {
|
|
186
|
+
// This allows us to focus on the first element if the dropdown was triggered by a custom trigger with a custom onClick
|
|
187
|
+
setTriggeredUsingKeyboard(true);
|
|
188
|
+
} else if (e.key === KEY_TAB && isNestedTriggerButton) {
|
|
189
|
+
// This closes dropdown if it is a nested dropdown
|
|
190
|
+
handleOnClose(e);
|
|
211
191
|
}
|
|
212
192
|
}
|
|
213
193
|
});
|
|
@@ -223,7 +203,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
|
|
|
223
203
|
testId: testId && "".concat(testId, "--content"),
|
|
224
204
|
shouldUseCaptureOnOutsideClick: true,
|
|
225
205
|
shouldRenderToParent: shouldRenderToParent,
|
|
226
|
-
shouldDisableFocusLock:
|
|
206
|
+
shouldDisableFocusLock: true,
|
|
227
207
|
trigger: function trigger(_ref2) {
|
|
228
208
|
var ref = _ref2.ref,
|
|
229
209
|
ariaControls = _ref2['aria-controls'],
|
|
@@ -2,7 +2,6 @@
|
|
|
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';
|
|
6
5
|
import { Box, xcss } from '@atlaskit/primitives';
|
|
7
6
|
import Spinner from '@atlaskit/spinner';
|
|
8
7
|
import { FocusManagerContext } from '../components/focus-manager';
|
|
@@ -75,10 +74,8 @@ var MenuWrapper = function MenuWrapper(_ref2) {
|
|
|
75
74
|
var firstFocusableRef = (_menuItemRefs$find = menuItemRefs.find(function (ref) {
|
|
76
75
|
return !ref.hasAttribute('disabled');
|
|
77
76
|
})) !== null && _menuItemRefs$find !== void 0 ? _menuItemRefs$find : null;
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
firstFocusableRef === null || firstFocusableRef === void 0 || firstFocusableRef.focus();
|
|
81
|
-
}
|
|
77
|
+
if (shouldRenderToParent && (isTriggeredUsingKeyboard || autoFocus)) {
|
|
78
|
+
firstFocusableRef === null || firstFocusableRef === void 0 || firstFocusableRef.focus();
|
|
82
79
|
}
|
|
83
80
|
setInitialFocusRef === null || setInitialFocusRef === void 0 || setInitialFocusRef(firstFocusableRef);
|
|
84
81
|
}, [menuItemRefs, setInitialFocusRef, autoFocus, shouldRenderToParent, isTriggeredUsingKeyboard]);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
var _actionMap;
|
|
3
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';
|
|
5
4
|
var actionMap = (_actionMap = {}, _defineProperty(_actionMap, KEY_DOWN, 'next'), _defineProperty(_actionMap, KEY_UP, 'prev'), _defineProperty(_actionMap, KEY_HOME, 'first'), _defineProperty(_actionMap, KEY_END, 'last'), _actionMap);
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -42,11 +41,9 @@ export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
42
41
|
return (_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.isSameNode(el);
|
|
43
42
|
});
|
|
44
43
|
if (isLayerDisabled()) {
|
|
45
|
-
if
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
onClose(e);
|
|
49
|
-
}
|
|
44
|
+
// if nested dropdown isOpen we need to close on Tab key press
|
|
45
|
+
if (e.key === KEY_TAB && !e.shiftKey) {
|
|
46
|
+
onClose(e);
|
|
50
47
|
}
|
|
51
48
|
|
|
52
49
|
// if it is a nested dropdown and the level of the given dropdown is not the current level,
|
|
@@ -62,10 +59,8 @@ export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
62
59
|
var _nextFocusableElement = getNextFocusableElement(refs, currentFocusedIdx);
|
|
63
60
|
_nextFocusableElement === null || _nextFocusableElement === void 0 || _nextFocusableElement.focus();
|
|
64
61
|
} else {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
firstFocusableElement === null || firstFocusableElement === void 0 || firstFocusableElement.focus();
|
|
68
|
-
}
|
|
62
|
+
var firstFocusableElement = getNextFocusableElement(refs, -1);
|
|
63
|
+
firstFocusableElement === null || firstFocusableElement === void 0 || firstFocusableElement.focus();
|
|
69
64
|
}
|
|
70
65
|
break;
|
|
71
66
|
case 'prev':
|
|
@@ -75,10 +70,8 @@ export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
75
70
|
var _prevFocusableElement = getPrevFocusableElement(refs, currentFocusedIdx);
|
|
76
71
|
_prevFocusableElement === null || _prevFocusableElement === void 0 || _prevFocusableElement.focus();
|
|
77
72
|
} else {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
lastFocusableElement === null || lastFocusableElement === void 0 || lastFocusableElement.focus();
|
|
81
|
-
}
|
|
73
|
+
var lastFocusableElement = getPrevFocusableElement(refs, refs.length);
|
|
74
|
+
lastFocusableElement === null || lastFocusableElement === void 0 || lastFocusableElement.focus();
|
|
82
75
|
}
|
|
83
76
|
break;
|
|
84
77
|
case 'first':
|
package/dist/types/types.d.ts
CHANGED
|
@@ -96,8 +96,9 @@ export interface DropdownMenuProps<TriggerElement extends HTMLElement = HTMLElem
|
|
|
96
96
|
*/
|
|
97
97
|
shouldFlip?: boolean;
|
|
98
98
|
/**
|
|
99
|
-
* The root element where the
|
|
100
|
-
* `true`
|
|
99
|
+
* The root element where the dropdown menu content should be rendered.
|
|
100
|
+
* `true` renders the dropdown menu in the DOM node closest to the trigger and avoids focus trap with tab keys.
|
|
101
|
+
* `false` renders the dropdown menu in React.Portal.
|
|
101
102
|
* Defaults to `false`.
|
|
102
103
|
*/
|
|
103
104
|
shouldRenderToParent?: boolean;
|
|
@@ -96,8 +96,9 @@ export interface DropdownMenuProps<TriggerElement extends HTMLElement = HTMLElem
|
|
|
96
96
|
*/
|
|
97
97
|
shouldFlip?: boolean;
|
|
98
98
|
/**
|
|
99
|
-
* The root element where the
|
|
100
|
-
* `true`
|
|
99
|
+
* The root element where the dropdown menu content should be rendered.
|
|
100
|
+
* `true` renders the dropdown menu in the DOM node closest to the trigger and avoids focus trap with tab keys.
|
|
101
|
+
* `false` renders the dropdown menu in React.Portal.
|
|
101
102
|
* Defaults to `false`.
|
|
102
103
|
*/
|
|
103
104
|
shouldRenderToParent?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/dropdown-menu",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.9.0",
|
|
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/"
|
|
@@ -23,33 +23,35 @@
|
|
|
23
23
|
"website": {
|
|
24
24
|
"name": "Dropdown menu",
|
|
25
25
|
"category": "Components"
|
|
26
|
-
}
|
|
26
|
+
},
|
|
27
|
+
"runReact18": true
|
|
27
28
|
},
|
|
28
29
|
"dependencies": {
|
|
29
|
-
"@atlaskit/button": "^17.
|
|
30
|
+
"@atlaskit/button": "^17.12.0",
|
|
30
31
|
"@atlaskit/codemod-utils": "^4.2.0",
|
|
31
|
-
"@atlaskit/ds-lib": "^2.
|
|
32
|
+
"@atlaskit/ds-lib": "^2.3.0",
|
|
32
33
|
"@atlaskit/icon": "^22.1.0",
|
|
33
34
|
"@atlaskit/layering": "^0.2.0",
|
|
34
35
|
"@atlaskit/menu": "^2.1.0",
|
|
35
36
|
"@atlaskit/platform-feature-flags": "^0.2.2",
|
|
36
|
-
"@atlaskit/popup": "^1.
|
|
37
|
-
"@atlaskit/primitives": "^5.
|
|
37
|
+
"@atlaskit/popup": "^1.14.0",
|
|
38
|
+
"@atlaskit/primitives": "^5.5.0",
|
|
38
39
|
"@atlaskit/spinner": "^16.0.0",
|
|
39
|
-
"@atlaskit/theme": "^12.
|
|
40
|
-
"@atlaskit/tokens": "^1.
|
|
40
|
+
"@atlaskit/theme": "^12.7.0",
|
|
41
|
+
"@atlaskit/tokens": "^1.43.0",
|
|
41
42
|
"@babel/runtime": "^7.0.0",
|
|
42
43
|
"@emotion/react": "^11.7.1",
|
|
43
44
|
"bind-event-listener": "^2.1.1"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|
|
46
|
-
"react": "^16.8.0",
|
|
47
|
+
"react": "^16.8.0 || ^17.0.0 || ~18.2.0",
|
|
47
48
|
"react-dom": "^16.8.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
51
|
"@af/accessibility-testing": "*",
|
|
51
52
|
"@af/integration-testing": "*",
|
|
52
53
|
"@af/visual-regression": "*",
|
|
54
|
+
"@atlaskit/modal-dialog": "*",
|
|
53
55
|
"@atlaskit/visual-regression": "*",
|
|
54
56
|
"@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1",
|
|
55
57
|
"@atlassian/feature-flags-test-utils": "*",
|
|
@@ -111,9 +113,6 @@
|
|
|
111
113
|
},
|
|
112
114
|
"platform.design-system-team.update-input-border-wdith_5abwv": {
|
|
113
115
|
"type": "boolean"
|
|
114
|
-
},
|
|
115
|
-
"platform.design-system-team.disable-focus-lock-in-popup_7kb4d": {
|
|
116
|
-
"type": "boolean"
|
|
117
116
|
}
|
|
118
117
|
},
|
|
119
118
|
"homepage": "https://atlassian.design/components/dropdown-menu/",
|