@atlaskit/dropdown-menu 12.20.1 → 12.20.2
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 +8 -0
- package/dist/cjs/internal/components/focus-manager.js +40 -41
- package/dist/cjs/internal/utils/handle-focus.js +10 -8
- package/dist/es2019/internal/components/focus-manager.js +38 -43
- package/dist/es2019/internal/utils/handle-focus.js +10 -8
- package/dist/esm/internal/components/focus-manager.js +41 -42
- package/dist/esm/internal/utils/handle-focus.js +10 -8
- package/dist/types/internal/utils/handle-focus.d.ts +3 -1
- package/dist/types-ts4.5/internal/utils/handle-focus.d.ts +3 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/dropdown-menu
|
|
2
2
|
|
|
3
|
+
## 12.20.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#152984](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/152984)
|
|
8
|
+
[`9520c882dcf30`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/9520c882dcf30) -
|
|
9
|
+
Fix async dropdown item ordering
|
|
10
|
+
|
|
3
11
|
## 12.20.1
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
8
|
exports.default = exports.FocusManagerContext = void 0;
|
|
9
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
10
11
|
var _bindEventListener = require("bind-event-listener");
|
|
11
12
|
var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
|
|
@@ -33,21 +34,52 @@ var FocusManager = function FocusManager(_ref) {
|
|
|
33
34
|
var children = _ref.children,
|
|
34
35
|
onClose = _ref.onClose;
|
|
35
36
|
var menuItemRefs = (0, _react.useRef)([]);
|
|
36
|
-
|
|
37
|
+
// Used to force a re-render only
|
|
38
|
+
var _useState = (0, _react.useState)(0),
|
|
39
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
40
|
+
refresh = _useState2[0],
|
|
41
|
+
setRefresh = _useState2[1];
|
|
42
|
+
var registerMode = (0, _react.useRef)('ordered');
|
|
43
|
+
registerMode.current = 'ordered';
|
|
37
44
|
var registerRef = (0, _react.useCallback)(function (ref) {
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
if (!ref || menuItemRefs.current.includes(ref)) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
switch (registerMode.current) {
|
|
49
|
+
case 'ordered':
|
|
50
|
+
menuItemRefs.current.push(ref);
|
|
51
|
+
break;
|
|
52
|
+
case 'unordered':
|
|
53
|
+
// Reset and force a rerender
|
|
54
|
+
registerMode.current = 'regenerate';
|
|
55
|
+
menuItemRefs.current = [];
|
|
56
|
+
setRefresh(refresh + 1);
|
|
57
|
+
break;
|
|
58
|
+
case 'regenerate':
|
|
59
|
+
// Ignore registrations until the next render cycle
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
throw new Error("Unexpected case of ".concat(registerMode.current));
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
// Updating register ref on force reload will cause `useRegisterItemWithFocusManager` to re-register
|
|
66
|
+
[refresh]);
|
|
40
67
|
var _UNSAFE_useLayering = (0, _layering.UNSAFE_useLayering)(),
|
|
41
68
|
isLayerDisabled = _UNSAFE_useLayering.isLayerDisabled;
|
|
69
|
+
|
|
70
|
+
// Intentionally rebinding on each render
|
|
71
|
+
(0, _react.useEffect)(function () {
|
|
72
|
+
if (registerMode.current === 'ordered') {
|
|
73
|
+
// Use effect is called after rendering is complete and useEffects of the children a called first
|
|
74
|
+
registerMode.current = 'unordered';
|
|
75
|
+
}
|
|
76
|
+
});
|
|
42
77
|
(0, _react.useEffect)(function () {
|
|
43
|
-
// Intentionally reset count on each render
|
|
44
|
-
registerRefCalls.current = 0;
|
|
45
|
-
// Intentionally rebinding on each render
|
|
46
78
|
return (0, _bindEventListener.bind)(window, {
|
|
47
79
|
type: 'keydown',
|
|
48
|
-
listener: (0, _handleFocus.default)(menuItemRefs
|
|
80
|
+
listener: (0, _handleFocus.default)(menuItemRefs, isLayerDisabled, onClose)
|
|
49
81
|
});
|
|
50
|
-
});
|
|
82
|
+
}, [isLayerDisabled, onClose]);
|
|
51
83
|
var contextValue = {
|
|
52
84
|
menuItemRefs: menuItemRefs.current,
|
|
53
85
|
registerRef: registerRef
|
|
@@ -56,37 +88,4 @@ var FocusManager = function FocusManager(_ref) {
|
|
|
56
88
|
value: contextValue
|
|
57
89
|
}, children);
|
|
58
90
|
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Insert the ref at the call position in the array.
|
|
62
|
-
* If the ref is already in the array, move it to the call position.
|
|
63
|
-
* If the call position is after the current position, ignore the call.
|
|
64
|
-
*
|
|
65
|
-
* @param ref
|
|
66
|
-
* @param menuItemRefs
|
|
67
|
-
* @param registerRefCalls
|
|
68
|
-
*/
|
|
69
|
-
function upsertRefAtFirstPosition(ref, menuItemRefs, registerRefCalls) {
|
|
70
|
-
var positionOnCall = registerRefCalls.current++;
|
|
71
|
-
|
|
72
|
-
// Add the ref to the correct position
|
|
73
|
-
if (!menuItemRefs.current.includes(ref)) {
|
|
74
|
-
menuItemRefs.current.splice(positionOnCall, 0, ref);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
var positionCurrent = menuItemRefs.current.indexOf(ref);
|
|
78
|
-
if (positionOnCall === positionCurrent) {
|
|
79
|
-
// No change needed
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
if (positionOnCall > positionCurrent) {
|
|
83
|
-
// Ignore and so keep the count the same
|
|
84
|
-
registerRefCalls.current--;
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Update the position of the ref in the array
|
|
89
|
-
menuItemRefs.current.splice(positionCurrent, 1);
|
|
90
|
-
menuItemRefs.current.splice(positionOnCall, 0, ref);
|
|
91
|
-
}
|
|
92
91
|
var _default = exports.default = FocusManager;
|
|
@@ -45,7 +45,9 @@ var getPrevFocusableElement = function getPrevFocusableElement(refs, currentFocu
|
|
|
45
45
|
};
|
|
46
46
|
function handleFocus(refs, isLayerDisabled, onClose) {
|
|
47
47
|
return function (e) {
|
|
48
|
-
var
|
|
48
|
+
var _refs$current;
|
|
49
|
+
var currentRefs = (_refs$current = refs.current) !== null && _refs$current !== void 0 ? _refs$current : refs;
|
|
50
|
+
var currentFocusedIdx = currentRefs.findIndex(function (el) {
|
|
49
51
|
var _document$activeEleme;
|
|
50
52
|
return (_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.isSameNode(el);
|
|
51
53
|
});
|
|
@@ -78,11 +80,11 @@ function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
78
80
|
case 'next':
|
|
79
81
|
// Always cancelling the event to prevent scrolling
|
|
80
82
|
e.preventDefault();
|
|
81
|
-
if (currentFocusedIdx <
|
|
82
|
-
var _nextFocusableElement = getNextFocusableElement(
|
|
83
|
+
if (currentFocusedIdx < currentRefs.length - 1) {
|
|
84
|
+
var _nextFocusableElement = getNextFocusableElement(currentRefs, currentFocusedIdx);
|
|
83
85
|
_nextFocusableElement === null || _nextFocusableElement === void 0 || _nextFocusableElement.focus();
|
|
84
86
|
} else {
|
|
85
|
-
var firstFocusableElement = getNextFocusableElement(
|
|
87
|
+
var firstFocusableElement = getNextFocusableElement(currentRefs, -1);
|
|
86
88
|
firstFocusableElement === null || firstFocusableElement === void 0 || firstFocusableElement.focus();
|
|
87
89
|
}
|
|
88
90
|
break;
|
|
@@ -90,23 +92,23 @@ function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
90
92
|
// Always cancelling the event to prevent scrolling
|
|
91
93
|
e.preventDefault();
|
|
92
94
|
if (currentFocusedIdx > 0) {
|
|
93
|
-
var _prevFocusableElement = getPrevFocusableElement(
|
|
95
|
+
var _prevFocusableElement = getPrevFocusableElement(currentRefs, currentFocusedIdx);
|
|
94
96
|
_prevFocusableElement === null || _prevFocusableElement === void 0 || _prevFocusableElement.focus();
|
|
95
97
|
} else {
|
|
96
|
-
var lastFocusableElement = getPrevFocusableElement(
|
|
98
|
+
var lastFocusableElement = getPrevFocusableElement(currentRefs, currentRefs.length);
|
|
97
99
|
lastFocusableElement === null || lastFocusableElement === void 0 || lastFocusableElement.focus();
|
|
98
100
|
}
|
|
99
101
|
break;
|
|
100
102
|
case 'first':
|
|
101
103
|
e.preventDefault();
|
|
102
104
|
// Search for first non-disabled element if first element is disabled
|
|
103
|
-
var nextFocusableElement = getNextFocusableElement(
|
|
105
|
+
var nextFocusableElement = getNextFocusableElement(currentRefs, -1);
|
|
104
106
|
nextFocusableElement === null || nextFocusableElement === void 0 || nextFocusableElement.focus();
|
|
105
107
|
break;
|
|
106
108
|
case 'last':
|
|
107
109
|
e.preventDefault();
|
|
108
110
|
// Search for last non-disabled element if last element is disabled
|
|
109
|
-
var prevFocusableElement = getPrevFocusableElement(
|
|
111
|
+
var prevFocusableElement = getPrevFocusableElement(currentRefs, currentRefs.length);
|
|
110
112
|
prevFocusableElement === null || prevFocusableElement === void 0 || prevFocusableElement.focus();
|
|
111
113
|
break;
|
|
112
114
|
default:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { createContext, useCallback, useEffect, useRef } from 'react';
|
|
1
|
+
import React, { createContext, useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { bind } from 'bind-event-listener';
|
|
3
3
|
import __noop from '@atlaskit/ds-lib/noop';
|
|
4
4
|
import { UNSAFE_useLayering } from '@atlaskit/layering';
|
|
@@ -25,20 +25,48 @@ const FocusManager = ({
|
|
|
25
25
|
onClose
|
|
26
26
|
}) => {
|
|
27
27
|
const menuItemRefs = useRef([]);
|
|
28
|
-
|
|
29
|
-
const
|
|
28
|
+
// Used to force a re-render only
|
|
29
|
+
const [refresh, setRefresh] = useState(0);
|
|
30
|
+
const registerMode = useRef('ordered');
|
|
31
|
+
registerMode.current = 'ordered';
|
|
32
|
+
const registerRef = useCallback(ref => {
|
|
33
|
+
if (!ref || menuItemRefs.current.includes(ref)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
switch (registerMode.current) {
|
|
37
|
+
case 'ordered':
|
|
38
|
+
menuItemRefs.current.push(ref);
|
|
39
|
+
break;
|
|
40
|
+
case 'unordered':
|
|
41
|
+
// Reset and force a rerender
|
|
42
|
+
registerMode.current = 'regenerate';
|
|
43
|
+
menuItemRefs.current = [];
|
|
44
|
+
setRefresh(refresh + 1);
|
|
45
|
+
break;
|
|
46
|
+
case 'regenerate':
|
|
47
|
+
// Ignore registrations until the next render cycle
|
|
48
|
+
break;
|
|
49
|
+
default:
|
|
50
|
+
throw new Error(`Unexpected case of ${registerMode.current}`);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
// Updating register ref on force reload will cause `useRegisterItemWithFocusManager` to re-register
|
|
54
|
+
[refresh]);
|
|
30
55
|
const {
|
|
31
56
|
isLayerDisabled
|
|
32
57
|
} = UNSAFE_useLayering();
|
|
58
|
+
|
|
59
|
+
// Intentionally rebinding on each render
|
|
33
60
|
useEffect(() => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
type: 'keydown',
|
|
39
|
-
listener: handleFocus(menuItemRefs.current, isLayerDisabled, onClose)
|
|
40
|
-
});
|
|
61
|
+
if (registerMode.current === 'ordered') {
|
|
62
|
+
// Use effect is called after rendering is complete and useEffects of the children a called first
|
|
63
|
+
registerMode.current = 'unordered';
|
|
64
|
+
}
|
|
41
65
|
});
|
|
66
|
+
useEffect(() => bind(window, {
|
|
67
|
+
type: 'keydown',
|
|
68
|
+
listener: handleFocus(menuItemRefs, isLayerDisabled, onClose)
|
|
69
|
+
}), [isLayerDisabled, onClose]);
|
|
42
70
|
const contextValue = {
|
|
43
71
|
menuItemRefs: menuItemRefs.current,
|
|
44
72
|
registerRef
|
|
@@ -47,37 +75,4 @@ const FocusManager = ({
|
|
|
47
75
|
value: contextValue
|
|
48
76
|
}, children);
|
|
49
77
|
};
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Insert the ref at the call position in the array.
|
|
53
|
-
* If the ref is already in the array, move it to the call position.
|
|
54
|
-
* If the call position is after the current position, ignore the call.
|
|
55
|
-
*
|
|
56
|
-
* @param ref
|
|
57
|
-
* @param menuItemRefs
|
|
58
|
-
* @param registerRefCalls
|
|
59
|
-
*/
|
|
60
|
-
function upsertRefAtFirstPosition(ref, menuItemRefs, registerRefCalls) {
|
|
61
|
-
const positionOnCall = registerRefCalls.current++;
|
|
62
|
-
|
|
63
|
-
// Add the ref to the correct position
|
|
64
|
-
if (!menuItemRefs.current.includes(ref)) {
|
|
65
|
-
menuItemRefs.current.splice(positionOnCall, 0, ref);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const positionCurrent = menuItemRefs.current.indexOf(ref);
|
|
69
|
-
if (positionOnCall === positionCurrent) {
|
|
70
|
-
// No change needed
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
if (positionOnCall > positionCurrent) {
|
|
74
|
-
// Ignore and so keep the count the same
|
|
75
|
-
registerRefCalls.current--;
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Update the position of the ref in the array
|
|
80
|
-
menuItemRefs.current.splice(positionCurrent, 1);
|
|
81
|
-
menuItemRefs.current.splice(positionOnCall, 0, ref);
|
|
82
|
-
}
|
|
83
78
|
export default FocusManager;
|
|
@@ -41,7 +41,9 @@ const getPrevFocusableElement = (refs, currentFocusedIdx) => {
|
|
|
41
41
|
};
|
|
42
42
|
export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
43
43
|
return e => {
|
|
44
|
-
|
|
44
|
+
var _refs$current;
|
|
45
|
+
const currentRefs = (_refs$current = refs.current) !== null && _refs$current !== void 0 ? _refs$current : refs;
|
|
46
|
+
const currentFocusedIdx = currentRefs.findIndex(el => {
|
|
45
47
|
var _document$activeEleme;
|
|
46
48
|
return (_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.isSameNode(el);
|
|
47
49
|
});
|
|
@@ -74,11 +76,11 @@ export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
74
76
|
case 'next':
|
|
75
77
|
// Always cancelling the event to prevent scrolling
|
|
76
78
|
e.preventDefault();
|
|
77
|
-
if (currentFocusedIdx <
|
|
78
|
-
const nextFocusableElement = getNextFocusableElement(
|
|
79
|
+
if (currentFocusedIdx < currentRefs.length - 1) {
|
|
80
|
+
const nextFocusableElement = getNextFocusableElement(currentRefs, currentFocusedIdx);
|
|
79
81
|
nextFocusableElement === null || nextFocusableElement === void 0 ? void 0 : nextFocusableElement.focus();
|
|
80
82
|
} else {
|
|
81
|
-
const firstFocusableElement = getNextFocusableElement(
|
|
83
|
+
const firstFocusableElement = getNextFocusableElement(currentRefs, -1);
|
|
82
84
|
firstFocusableElement === null || firstFocusableElement === void 0 ? void 0 : firstFocusableElement.focus();
|
|
83
85
|
}
|
|
84
86
|
break;
|
|
@@ -86,23 +88,23 @@ export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
86
88
|
// Always cancelling the event to prevent scrolling
|
|
87
89
|
e.preventDefault();
|
|
88
90
|
if (currentFocusedIdx > 0) {
|
|
89
|
-
const prevFocusableElement = getPrevFocusableElement(
|
|
91
|
+
const prevFocusableElement = getPrevFocusableElement(currentRefs, currentFocusedIdx);
|
|
90
92
|
prevFocusableElement === null || prevFocusableElement === void 0 ? void 0 : prevFocusableElement.focus();
|
|
91
93
|
} else {
|
|
92
|
-
const lastFocusableElement = getPrevFocusableElement(
|
|
94
|
+
const lastFocusableElement = getPrevFocusableElement(currentRefs, currentRefs.length);
|
|
93
95
|
lastFocusableElement === null || lastFocusableElement === void 0 ? void 0 : lastFocusableElement.focus();
|
|
94
96
|
}
|
|
95
97
|
break;
|
|
96
98
|
case 'first':
|
|
97
99
|
e.preventDefault();
|
|
98
100
|
// Search for first non-disabled element if first element is disabled
|
|
99
|
-
const nextFocusableElement = getNextFocusableElement(
|
|
101
|
+
const nextFocusableElement = getNextFocusableElement(currentRefs, -1);
|
|
100
102
|
nextFocusableElement === null || nextFocusableElement === void 0 ? void 0 : nextFocusableElement.focus();
|
|
101
103
|
break;
|
|
102
104
|
case 'last':
|
|
103
105
|
e.preventDefault();
|
|
104
106
|
// Search for last non-disabled element if last element is disabled
|
|
105
|
-
const prevFocusableElement = getPrevFocusableElement(
|
|
107
|
+
const prevFocusableElement = getPrevFocusableElement(currentRefs, currentRefs.length);
|
|
106
108
|
prevFocusableElement === null || prevFocusableElement === void 0 ? void 0 : prevFocusableElement.focus();
|
|
107
109
|
break;
|
|
108
110
|
default:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import React, { createContext, useCallback, useEffect, useRef, useState } from 'react';
|
|
2
3
|
import { bind } from 'bind-event-listener';
|
|
3
4
|
import __noop from '@atlaskit/ds-lib/noop';
|
|
4
5
|
import { UNSAFE_useLayering } from '@atlaskit/layering';
|
|
@@ -24,21 +25,52 @@ var FocusManager = function FocusManager(_ref) {
|
|
|
24
25
|
var children = _ref.children,
|
|
25
26
|
onClose = _ref.onClose;
|
|
26
27
|
var menuItemRefs = useRef([]);
|
|
27
|
-
|
|
28
|
+
// Used to force a re-render only
|
|
29
|
+
var _useState = useState(0),
|
|
30
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
31
|
+
refresh = _useState2[0],
|
|
32
|
+
setRefresh = _useState2[1];
|
|
33
|
+
var registerMode = useRef('ordered');
|
|
34
|
+
registerMode.current = 'ordered';
|
|
28
35
|
var registerRef = useCallback(function (ref) {
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
if (!ref || menuItemRefs.current.includes(ref)) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
switch (registerMode.current) {
|
|
40
|
+
case 'ordered':
|
|
41
|
+
menuItemRefs.current.push(ref);
|
|
42
|
+
break;
|
|
43
|
+
case 'unordered':
|
|
44
|
+
// Reset and force a rerender
|
|
45
|
+
registerMode.current = 'regenerate';
|
|
46
|
+
menuItemRefs.current = [];
|
|
47
|
+
setRefresh(refresh + 1);
|
|
48
|
+
break;
|
|
49
|
+
case 'regenerate':
|
|
50
|
+
// Ignore registrations until the next render cycle
|
|
51
|
+
break;
|
|
52
|
+
default:
|
|
53
|
+
throw new Error("Unexpected case of ".concat(registerMode.current));
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
// Updating register ref on force reload will cause `useRegisterItemWithFocusManager` to re-register
|
|
57
|
+
[refresh]);
|
|
31
58
|
var _UNSAFE_useLayering = UNSAFE_useLayering(),
|
|
32
59
|
isLayerDisabled = _UNSAFE_useLayering.isLayerDisabled;
|
|
60
|
+
|
|
61
|
+
// Intentionally rebinding on each render
|
|
62
|
+
useEffect(function () {
|
|
63
|
+
if (registerMode.current === 'ordered') {
|
|
64
|
+
// Use effect is called after rendering is complete and useEffects of the children a called first
|
|
65
|
+
registerMode.current = 'unordered';
|
|
66
|
+
}
|
|
67
|
+
});
|
|
33
68
|
useEffect(function () {
|
|
34
|
-
// Intentionally reset count on each render
|
|
35
|
-
registerRefCalls.current = 0;
|
|
36
|
-
// Intentionally rebinding on each render
|
|
37
69
|
return bind(window, {
|
|
38
70
|
type: 'keydown',
|
|
39
|
-
listener: handleFocus(menuItemRefs
|
|
71
|
+
listener: handleFocus(menuItemRefs, isLayerDisabled, onClose)
|
|
40
72
|
});
|
|
41
|
-
});
|
|
73
|
+
}, [isLayerDisabled, onClose]);
|
|
42
74
|
var contextValue = {
|
|
43
75
|
menuItemRefs: menuItemRefs.current,
|
|
44
76
|
registerRef: registerRef
|
|
@@ -47,37 +79,4 @@ var FocusManager = function FocusManager(_ref) {
|
|
|
47
79
|
value: contextValue
|
|
48
80
|
}, children);
|
|
49
81
|
};
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Insert the ref at the call position in the array.
|
|
53
|
-
* If the ref is already in the array, move it to the call position.
|
|
54
|
-
* If the call position is after the current position, ignore the call.
|
|
55
|
-
*
|
|
56
|
-
* @param ref
|
|
57
|
-
* @param menuItemRefs
|
|
58
|
-
* @param registerRefCalls
|
|
59
|
-
*/
|
|
60
|
-
function upsertRefAtFirstPosition(ref, menuItemRefs, registerRefCalls) {
|
|
61
|
-
var positionOnCall = registerRefCalls.current++;
|
|
62
|
-
|
|
63
|
-
// Add the ref to the correct position
|
|
64
|
-
if (!menuItemRefs.current.includes(ref)) {
|
|
65
|
-
menuItemRefs.current.splice(positionOnCall, 0, ref);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
var positionCurrent = menuItemRefs.current.indexOf(ref);
|
|
69
|
-
if (positionOnCall === positionCurrent) {
|
|
70
|
-
// No change needed
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
if (positionOnCall > positionCurrent) {
|
|
74
|
-
// Ignore and so keep the count the same
|
|
75
|
-
registerRefCalls.current--;
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Update the position of the ref in the array
|
|
80
|
-
menuItemRefs.current.splice(positionCurrent, 1);
|
|
81
|
-
menuItemRefs.current.splice(positionOnCall, 0, ref);
|
|
82
|
-
}
|
|
83
82
|
export default FocusManager;
|
|
@@ -38,7 +38,9 @@ var getPrevFocusableElement = function getPrevFocusableElement(refs, currentFocu
|
|
|
38
38
|
};
|
|
39
39
|
export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
40
40
|
return function (e) {
|
|
41
|
-
var
|
|
41
|
+
var _refs$current;
|
|
42
|
+
var currentRefs = (_refs$current = refs.current) !== null && _refs$current !== void 0 ? _refs$current : refs;
|
|
43
|
+
var currentFocusedIdx = currentRefs.findIndex(function (el) {
|
|
42
44
|
var _document$activeEleme;
|
|
43
45
|
return (_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.isSameNode(el);
|
|
44
46
|
});
|
|
@@ -71,11 +73,11 @@ export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
71
73
|
case 'next':
|
|
72
74
|
// Always cancelling the event to prevent scrolling
|
|
73
75
|
e.preventDefault();
|
|
74
|
-
if (currentFocusedIdx <
|
|
75
|
-
var _nextFocusableElement = getNextFocusableElement(
|
|
76
|
+
if (currentFocusedIdx < currentRefs.length - 1) {
|
|
77
|
+
var _nextFocusableElement = getNextFocusableElement(currentRefs, currentFocusedIdx);
|
|
76
78
|
_nextFocusableElement === null || _nextFocusableElement === void 0 || _nextFocusableElement.focus();
|
|
77
79
|
} else {
|
|
78
|
-
var firstFocusableElement = getNextFocusableElement(
|
|
80
|
+
var firstFocusableElement = getNextFocusableElement(currentRefs, -1);
|
|
79
81
|
firstFocusableElement === null || firstFocusableElement === void 0 || firstFocusableElement.focus();
|
|
80
82
|
}
|
|
81
83
|
break;
|
|
@@ -83,23 +85,23 @@ export default function handleFocus(refs, isLayerDisabled, onClose) {
|
|
|
83
85
|
// Always cancelling the event to prevent scrolling
|
|
84
86
|
e.preventDefault();
|
|
85
87
|
if (currentFocusedIdx > 0) {
|
|
86
|
-
var _prevFocusableElement = getPrevFocusableElement(
|
|
88
|
+
var _prevFocusableElement = getPrevFocusableElement(currentRefs, currentFocusedIdx);
|
|
87
89
|
_prevFocusableElement === null || _prevFocusableElement === void 0 || _prevFocusableElement.focus();
|
|
88
90
|
} else {
|
|
89
|
-
var lastFocusableElement = getPrevFocusableElement(
|
|
91
|
+
var lastFocusableElement = getPrevFocusableElement(currentRefs, currentRefs.length);
|
|
90
92
|
lastFocusableElement === null || lastFocusableElement === void 0 || lastFocusableElement.focus();
|
|
91
93
|
}
|
|
92
94
|
break;
|
|
93
95
|
case 'first':
|
|
94
96
|
e.preventDefault();
|
|
95
97
|
// Search for first non-disabled element if first element is disabled
|
|
96
|
-
var nextFocusableElement = getNextFocusableElement(
|
|
98
|
+
var nextFocusableElement = getNextFocusableElement(currentRefs, -1);
|
|
97
99
|
nextFocusableElement === null || nextFocusableElement === void 0 || nextFocusableElement.focus();
|
|
98
100
|
break;
|
|
99
101
|
case 'last':
|
|
100
102
|
e.preventDefault();
|
|
101
103
|
// Search for last non-disabled element if last element is disabled
|
|
102
|
-
var prevFocusableElement = getPrevFocusableElement(
|
|
104
|
+
var prevFocusableElement = getPrevFocusableElement(currentRefs, currentRefs.length);
|
|
103
105
|
prevFocusableElement === null || prevFocusableElement === void 0 || prevFocusableElement.focus();
|
|
104
106
|
break;
|
|
105
107
|
default:
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { type FocusableElement } from '../../types';
|
|
2
|
-
export default function handleFocus(refs:
|
|
2
|
+
export default function handleFocus(refs: {
|
|
3
|
+
current: Array<FocusableElement>;
|
|
4
|
+
}, isLayerDisabled: () => boolean, onClose: (e: KeyboardEvent) => void): (e: KeyboardEvent) => void;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { type FocusableElement } from '../../types';
|
|
2
|
-
export default function handleFocus(refs:
|
|
2
|
+
export default function handleFocus(refs: {
|
|
3
|
+
current: Array<FocusableElement>;
|
|
4
|
+
}, isLayerDisabled: () => boolean, onClose: (e: KeyboardEvent) => void): (e: KeyboardEvent) => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/dropdown-menu",
|
|
3
|
-
"version": "12.20.
|
|
3
|
+
"version": "12.20.2",
|
|
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/"
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"@atlaskit/ds-lib": "^3.1.0",
|
|
29
29
|
"@atlaskit/icon": "^22.22.0",
|
|
30
30
|
"@atlaskit/layering": "^0.6.0",
|
|
31
|
-
"@atlaskit/menu": "^2.
|
|
31
|
+
"@atlaskit/menu": "^2.13.0",
|
|
32
32
|
"@atlaskit/platform-feature-flags": "^0.3.0",
|
|
33
33
|
"@atlaskit/popup": "^1.28.0",
|
|
34
34
|
"@atlaskit/primitives": "^12.2.0",
|
|
35
35
|
"@atlaskit/spinner": "^16.3.0",
|
|
36
|
-
"@atlaskit/theme": "^13.
|
|
36
|
+
"@atlaskit/theme": "^13.1.0",
|
|
37
37
|
"@atlaskit/tokens": "^2.0.0",
|
|
38
38
|
"@babel/runtime": "^7.0.0",
|
|
39
39
|
"@emotion/react": "^11.7.1",
|