@atlaskit/editor-common 72.1.1 → 72.2.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 +21 -0
- package/dist/cjs/analytics/types/enums.js +1 -1
- package/dist/cjs/styles/shared/code-block.js +1 -3
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/cjs/ui-menu/Dropdown/index.js +1 -1
- package/dist/cjs/ui-menu/DropdownMenu/index.js +23 -7
- package/dist/cjs/ui-menu/MenuArrowKeyNavigationProvider/index.js +68 -51
- package/dist/cjs/ui-react/with-react-editor-view-outer-listeners.js +4 -4
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/analytics/types/enums.js +1 -1
- package/dist/es2019/styles/shared/code-block.js +3 -6
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/es2019/ui-menu/Dropdown/index.js +1 -1
- package/dist/es2019/ui-menu/DropdownMenu/index.js +23 -7
- package/dist/es2019/ui-menu/MenuArrowKeyNavigationProvider/index.js +60 -51
- package/dist/es2019/ui-react/with-react-editor-view-outer-listeners.js +3 -3
- package/dist/es2019/version.json +1 -1
- package/dist/esm/analytics/types/enums.js +1 -1
- package/dist/esm/styles/shared/code-block.js +1 -2
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/esm/ui-menu/Dropdown/index.js +1 -1
- package/dist/esm/ui-menu/DropdownMenu/index.js +23 -7
- package/dist/esm/ui-menu/MenuArrowKeyNavigationProvider/index.js +66 -52
- package/dist/esm/ui-react/with-react-editor-view-outer-listeners.js +4 -4
- package/dist/esm/version.json +1 -1
- package/dist/types/analytics/types/enums.d.ts +1 -1
- package/dist/types/analytics/types/events.d.ts +3 -2
- package/dist/types/analytics/types/general-events.d.ts +8 -3
- package/dist/types/types/editor-plugin.d.ts +24 -2
- package/dist/types/types/floating-toolbar.d.ts +10 -0
- package/dist/types/types/type-ahead.d.ts +8 -0
- package/dist/types/ui-menu/DropdownMenu/index.d.ts +1 -1
- package/dist/types/ui-menu/DropdownMenu/types.d.ts +1 -0
- package/dist/types/ui-menu/MenuArrowKeyNavigationProvider/index.d.ts +3 -2
- package/dist/types/ui-react/with-react-editor-view-outer-listeners.d.ts +1 -1
- package/package.json +8 -8
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useLayoutEffect, useRef } from 'react';
|
|
1
|
+
import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This component is a wrapper of vertical menus which listens to keydown events of children
|
|
@@ -9,27 +9,34 @@ export const MenuArrowKeyNavigationProvider = ({
|
|
|
9
9
|
handleClose,
|
|
10
10
|
disableArrowKeyNavigation,
|
|
11
11
|
keyDownHandlerContext,
|
|
12
|
-
|
|
12
|
+
closeOnTab,
|
|
13
|
+
onSelection
|
|
13
14
|
}) => {
|
|
14
15
|
const wrapperRef = useRef(null);
|
|
15
|
-
const currentSelectedItemIndex =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
const [currentSelectedItemIndex, setCurrentSelectedItemIndex] = useState(-1);
|
|
17
|
+
const incrementIndex = useCallback(list => {
|
|
18
|
+
const currentIndex = currentSelectedItemIndex;
|
|
19
|
+
let nextIndex = (currentIndex + 1) % list.length; // Skips disabled items. Previously this function relied on a list of enabled elements which caused a
|
|
20
|
+
// difference between currentIndex and the item index in the menu.
|
|
21
|
+
|
|
22
|
+
while (nextIndex !== currentIndex && list[nextIndex].getAttribute('aria-disabled') === 'true') {
|
|
23
|
+
nextIndex = (nextIndex + 1) % list.length;
|
|
22
24
|
}
|
|
23
|
-
};
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
setCurrentSelectedItemIndex(nextIndex);
|
|
27
|
+
return nextIndex;
|
|
28
|
+
}, [currentSelectedItemIndex]);
|
|
29
|
+
const decrementIndex = useCallback(list => {
|
|
30
|
+
const currentIndex = currentSelectedItemIndex;
|
|
31
|
+
let nextIndex = (list.length + currentIndex - 1) % list.length;
|
|
32
|
+
|
|
33
|
+
while (nextIndex !== currentIndex && list[nextIndex].getAttribute('aria-disabled') === 'true') {
|
|
34
|
+
nextIndex = (list.length + nextIndex - 1) % list.length;
|
|
30
35
|
}
|
|
31
|
-
};
|
|
32
36
|
|
|
37
|
+
setCurrentSelectedItemIndex(nextIndex);
|
|
38
|
+
return nextIndex;
|
|
39
|
+
}, [currentSelectedItemIndex]);
|
|
33
40
|
useLayoutEffect(() => {
|
|
34
41
|
if (disableArrowKeyNavigation) {
|
|
35
42
|
return;
|
|
@@ -41,49 +48,47 @@ export const MenuArrowKeyNavigationProvider = ({
|
|
|
41
48
|
|
|
42
49
|
|
|
43
50
|
const handleKeyDown = event => {
|
|
44
|
-
var _wrapperRef$current
|
|
51
|
+
var _wrapperRef$current;
|
|
45
52
|
|
|
46
53
|
const targetElement = event.target; //Tab key on menu items can be handled in the parent components of dropdown menus with KeydownHandlerContext
|
|
47
54
|
|
|
48
|
-
if (event.key === 'Tab' &&
|
|
55
|
+
if (event.key === 'Tab' && closeOnTab) {
|
|
49
56
|
handleClose(event);
|
|
50
57
|
keyDownHandlerContext === null || keyDownHandlerContext === void 0 ? void 0 : keyDownHandlerContext.handleTab();
|
|
51
58
|
return;
|
|
52
59
|
} //To trap the focus inside the toolbar using left and right arrow keys
|
|
53
60
|
|
|
54
61
|
|
|
55
|
-
const focusableElements =
|
|
62
|
+
const focusableElements = getFocusableElements(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current);
|
|
56
63
|
|
|
57
64
|
if (!focusableElements || (focusableElements === null || focusableElements === void 0 ? void 0 : focusableElements.length) === 0) {
|
|
58
65
|
return;
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
if (!((_wrapperRef$current = wrapperRef.current) !== null && _wrapperRef$current !== void 0 && _wrapperRef$current.contains(targetElement))) {
|
|
62
|
-
|
|
69
|
+
setCurrentSelectedItemIndex(-1);
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
switch (event.key) {
|
|
66
73
|
case 'ArrowDown':
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
break;
|
|
74
|
+
{
|
|
75
|
+
var _focusableElements$fo;
|
|
76
|
+
|
|
77
|
+
const focusIndex = incrementIndex(focusableElements);
|
|
78
|
+
(_focusableElements$fo = focusableElements[focusIndex]) === null || _focusableElements$fo === void 0 ? void 0 : _focusableElements$fo.focus();
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
76
82
|
|
|
77
83
|
case 'ArrowUp':
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
break;
|
|
84
|
+
{
|
|
85
|
+
var _focusableElements$fo2;
|
|
86
|
+
|
|
87
|
+
const focusIndex = decrementIndex(focusableElements);
|
|
88
|
+
(_focusableElements$fo2 = focusableElements[focusIndex]) === null || _focusableElements$fo2 === void 0 ? void 0 : _focusableElements$fo2.focus();
|
|
89
|
+
event.preventDefault();
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
87
92
|
//ArrowLeft/Right on the menu should close the menus
|
|
88
93
|
//then logic to retain the focus can be handled in the parent components with KeydownHandlerContext
|
|
89
94
|
|
|
@@ -93,8 +98,11 @@ export const MenuArrowKeyNavigationProvider = ({
|
|
|
93
98
|
return;
|
|
94
99
|
}
|
|
95
100
|
|
|
101
|
+
if (!targetElement.closest('[data-testid="editor-floating-toolbar"]')) {
|
|
102
|
+
keyDownHandlerContext === null || keyDownHandlerContext === void 0 ? void 0 : keyDownHandlerContext.handleArrowLeft();
|
|
103
|
+
}
|
|
104
|
+
|
|
96
105
|
handleClose(event);
|
|
97
|
-
keyDownHandlerContext === null || keyDownHandlerContext === void 0 ? void 0 : keyDownHandlerContext.handleArrowLeft();
|
|
98
106
|
break;
|
|
99
107
|
|
|
100
108
|
case 'ArrowRight':
|
|
@@ -103,14 +111,24 @@ export const MenuArrowKeyNavigationProvider = ({
|
|
|
103
111
|
return;
|
|
104
112
|
}
|
|
105
113
|
|
|
114
|
+
if (!targetElement.closest('[data-testid="editor-floating-toolbar"]')) {
|
|
115
|
+
keyDownHandlerContext === null || keyDownHandlerContext === void 0 ? void 0 : keyDownHandlerContext.handleArrowRight();
|
|
116
|
+
}
|
|
117
|
+
|
|
106
118
|
handleClose(event);
|
|
107
|
-
keyDownHandlerContext === null || keyDownHandlerContext === void 0 ? void 0 : keyDownHandlerContext.handleArrowRight();
|
|
108
119
|
break;
|
|
109
120
|
|
|
110
121
|
case 'Escape':
|
|
111
122
|
handleClose(event);
|
|
112
123
|
break;
|
|
113
124
|
|
|
125
|
+
case 'Enter':
|
|
126
|
+
if (typeof onSelection === 'function') {
|
|
127
|
+
onSelection(currentSelectedItemIndex);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
break;
|
|
131
|
+
|
|
114
132
|
default:
|
|
115
133
|
return;
|
|
116
134
|
}
|
|
@@ -120,9 +138,9 @@ export const MenuArrowKeyNavigationProvider = ({
|
|
|
120
138
|
return () => {
|
|
121
139
|
document.removeEventListener('keydown', handleKeyDown);
|
|
122
140
|
};
|
|
123
|
-
}, [currentSelectedItemIndex, wrapperRef, handleClose, disableArrowKeyNavigation, keyDownHandlerContext,
|
|
141
|
+
}, [currentSelectedItemIndex, wrapperRef, handleClose, disableArrowKeyNavigation, keyDownHandlerContext, closeOnTab, onSelection, incrementIndex, decrementIndex]);
|
|
124
142
|
return /*#__PURE__*/React.createElement("div", {
|
|
125
|
-
className: "custom-key-handler-wrapper",
|
|
143
|
+
className: "menu-key-handler-wrapper custom-key-handler-wrapper",
|
|
126
144
|
ref: wrapperRef
|
|
127
145
|
}, children);
|
|
128
146
|
};
|
|
@@ -134,13 +152,4 @@ function getFocusableElements(rootNode) {
|
|
|
134
152
|
|
|
135
153
|
const focusableModalElements = rootNode.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, div[tabindex="-1"]') || [];
|
|
136
154
|
return Array.from(focusableModalElements);
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* This method filters out all the disabled menu items
|
|
140
|
-
*/
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
function getEnabledElements(rootNode) {
|
|
144
|
-
const focusableElements = getFocusableElements(rootNode);
|
|
145
|
-
return focusableElements.filter(element => !element.querySelector('[role="button"][aria-disabled="true"]') && !element.querySelector('[role="menuitem"][aria-disabled="true"]'));
|
|
146
155
|
}
|
|
@@ -42,7 +42,7 @@ class WithOutsideClick extends PureComponent {
|
|
|
42
42
|
return false;
|
|
43
43
|
} else if (evt.code === 'Enter' && this.props.handleEnterKeydown) {
|
|
44
44
|
this.props.handleEnterKeydown(evt);
|
|
45
|
-
} else if (evt.code === 'Tab' && this.props.handleEscapeKeydown && this.props.
|
|
45
|
+
} else if (evt.code === 'Tab' && this.props.handleEscapeKeydown && this.props.closeOnTab) {
|
|
46
46
|
//The menus should be closed when the tab is pressed as it takes the focus out of the menu
|
|
47
47
|
this.props.handleEscapeKeydown(evt);
|
|
48
48
|
}
|
|
@@ -89,7 +89,7 @@ export default function withReactEditorViewOuterListeners(Component) {
|
|
|
89
89
|
handleClickOutside,
|
|
90
90
|
handleEnterKeydown,
|
|
91
91
|
handleEscapeKeydown,
|
|
92
|
-
|
|
92
|
+
closeOnTab,
|
|
93
93
|
...props
|
|
94
94
|
}) => {
|
|
95
95
|
const isActiveComponent = hasIsOpen(props) ? props.isOpen : true;
|
|
@@ -104,7 +104,7 @@ export default function withReactEditorViewOuterListeners(Component) {
|
|
|
104
104
|
handleClickOutside: handleClickOutside,
|
|
105
105
|
handleEnterKeydown: handleEnterKeydown,
|
|
106
106
|
handleEscapeKeydown: handleEscapeKeydown,
|
|
107
|
-
|
|
107
|
+
closeOnTab: closeOnTab
|
|
108
108
|
}, /*#__PURE__*/React.createElement(Component, props)));
|
|
109
109
|
};
|
|
110
110
|
}
|
package/dist/es2019/version.json
CHANGED
|
@@ -89,7 +89,7 @@ export var ACTION;
|
|
|
89
89
|
ACTION["SYNCHRONY_ENTITY_ERROR"] = "synchronyEntityError";
|
|
90
90
|
ACTION["SYNCHRONY_ERROR"] = "synchronyError";
|
|
91
91
|
ACTION["TEXT_LINK_MARK_TRANSFORMED"] = "textLinkMarkTransformed";
|
|
92
|
-
ACTION["
|
|
92
|
+
ACTION["DEDUPE_MARKS_TRANSFORMED_V2"] = "dedupeMarksTransformedV2";
|
|
93
93
|
ACTION["NODES_MISSING_CONTENT_TRANSFORMED"] = "nodesMissingContentTransformed";
|
|
94
94
|
ACTION["INDENTATION_MARKS_TRANSFORMED"] = "indentationMarksTransformed";
|
|
95
95
|
ACTION["INVALID_MEDIA_CONTENT_TRANSFORMED"] = "invalidMediaContentTransformed";
|
|
@@ -7,7 +7,6 @@ import { akEditorCodeFontFamily, akEditorLineHeight, akEditorTableCellMinWidth,
|
|
|
7
7
|
import { DN20, DN400, DN50, DN800, N20, N30, N400, N800 } from '@atlaskit/theme/colors';
|
|
8
8
|
import { themed } from '@atlaskit/theme/components';
|
|
9
9
|
import { borderRadius, fontSize, gridSize } from '@atlaskit/theme/constants';
|
|
10
|
-
import { TaskDecisionSharedCssClassName } from './task-decision';
|
|
11
10
|
export var CodeBlockSharedCssClassName = {
|
|
12
11
|
CODEBLOCK_CONTAINER: 'code-block',
|
|
13
12
|
CODEBLOCK_START: 'code-block--start',
|
|
@@ -38,4 +37,4 @@ export var codeBlockSharedStyles = function codeBlockSharedStyles(props) {
|
|
|
38
37
|
dark: "var(--ds-text, ".concat(DN800, ")")
|
|
39
38
|
})(props), borderRadius(), gridSize(), relativeFontSizeToBase16(fontSize()));
|
|
40
39
|
};
|
|
41
|
-
export var codeBlockInListSafariFix = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n
|
|
40
|
+
export var codeBlockInListSafariFix = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n ::before {\n content: ' ';\n line-height: ", ";\n }\n\n > p:first-child,\n > .code-block:first-child,\n > .ProseMirror-gapcursor:first-child + .code-block {\n margin-top: -", "em !important;\n }\n"])), akEditorLineHeight, akEditorLineHeight);
|
|
@@ -22,7 +22,7 @@ import { themed } from '@atlaskit/theme/components';
|
|
|
22
22
|
import { borderRadius, gridSize } from '@atlaskit/theme/constants';
|
|
23
23
|
import Layer from '../Layer';
|
|
24
24
|
var packageName = "@atlaskit/editor-common";
|
|
25
|
-
var packageVersion = "72.
|
|
25
|
+
var packageVersion = "72.2.0";
|
|
26
26
|
var halfFocusRing = 1;
|
|
27
27
|
var dropOffset = "0, ".concat(gridSize(), "px");
|
|
28
28
|
|
|
@@ -81,7 +81,7 @@ export var Dropdown = /*#__PURE__*/function (_PureComponent) {
|
|
|
81
81
|
}, /*#__PURE__*/React.createElement(MenuArrowKeyNavigationProvider, {
|
|
82
82
|
disableArrowKeyNavigation: disableArrowKeyNavigation,
|
|
83
83
|
keyDownHandlerContext: keyDownHandlerContext,
|
|
84
|
-
|
|
84
|
+
closeOnTab: true,
|
|
85
85
|
handleClose: function handleClose(event) {
|
|
86
86
|
return onOpenChange && onOpenChange({
|
|
87
87
|
isOpen: false,
|
|
@@ -81,7 +81,8 @@ var DropdownMenuWrapper = /*#__PURE__*/function (_PureComponent) {
|
|
|
81
81
|
_this = _super.call.apply(_super, [this].concat(args));
|
|
82
82
|
|
|
83
83
|
_defineProperty(_assertThisInitialized(_this), "state", {
|
|
84
|
-
popupPlacement: ['bottom', 'left']
|
|
84
|
+
popupPlacement: ['bottom', 'left'],
|
|
85
|
+
selectionIndex: -1
|
|
85
86
|
});
|
|
86
87
|
|
|
87
88
|
_defineProperty(_assertThisInitialized(_this), "handleRef", function (target) {
|
|
@@ -100,7 +101,7 @@ var DropdownMenuWrapper = /*#__PURE__*/function (_PureComponent) {
|
|
|
100
101
|
}
|
|
101
102
|
});
|
|
102
103
|
|
|
103
|
-
_defineProperty(_assertThisInitialized(_this), "
|
|
104
|
+
_defineProperty(_assertThisInitialized(_this), "handleCloseAndFocus", function () {
|
|
104
105
|
var _this$state$target, _this$state$target$qu;
|
|
105
106
|
|
|
106
107
|
_this.handleClose();
|
|
@@ -139,7 +140,8 @@ var DropdownMenuWrapper = /*#__PURE__*/function (_PureComponent) {
|
|
|
139
140
|
zIndex = _this$props.zIndex,
|
|
140
141
|
shouldUseDefaultRole = _this$props.shouldUseDefaultRole,
|
|
141
142
|
disableArrowKeyNavigation = _this$props.disableArrowKeyNavigation,
|
|
142
|
-
keyDownHandlerContext = _this$props.keyDownHandlerContext
|
|
143
|
+
keyDownHandlerContext = _this$props.keyDownHandlerContext,
|
|
144
|
+
onItemActivated = _this$props.onItemActivated;
|
|
143
145
|
return jsx(Popup, {
|
|
144
146
|
target: isOpen ? target : undefined,
|
|
145
147
|
mountTo: mountTo,
|
|
@@ -152,9 +154,22 @@ var DropdownMenuWrapper = /*#__PURE__*/function (_PureComponent) {
|
|
|
152
154
|
offset: offset
|
|
153
155
|
}, jsx(MenuArrowKeyNavigationProvider, {
|
|
154
156
|
disableArrowKeyNavigation: disableArrowKeyNavigation,
|
|
155
|
-
handleClose: this.
|
|
157
|
+
handleClose: this.handleCloseAndFocus,
|
|
156
158
|
keyDownHandlerContext: keyDownHandlerContext,
|
|
157
|
-
|
|
159
|
+
onSelection: function onSelection(index) {
|
|
160
|
+
var result = [];
|
|
161
|
+
|
|
162
|
+
if (typeof onItemActivated === 'function') {
|
|
163
|
+
result = items.reduce(function (result, group) {
|
|
164
|
+
return result.concat(group.items);
|
|
165
|
+
}, result);
|
|
166
|
+
onItemActivated({
|
|
167
|
+
item: result[index],
|
|
168
|
+
shouldCloseMenu: false
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
closeOnTab: true
|
|
158
173
|
}, jsx(DropListWithOutsideListeners, {
|
|
159
174
|
isOpen: true,
|
|
160
175
|
appearance: "tall",
|
|
@@ -163,7 +178,7 @@ var DropdownMenuWrapper = /*#__PURE__*/function (_PureComponent) {
|
|
|
163
178
|
shouldFitContainer: true,
|
|
164
179
|
isTriggerNotTabbable: true,
|
|
165
180
|
handleClickOutside: this.handleClose,
|
|
166
|
-
handleEscapeKeydown: this.
|
|
181
|
+
handleEscapeKeydown: this.handleCloseAndFocus,
|
|
167
182
|
targetRef: this.state.target
|
|
168
183
|
}, jsx("div", {
|
|
169
184
|
style: {
|
|
@@ -238,7 +253,8 @@ function DropdownMenuItem(_ref) {
|
|
|
238
253
|
theme: theme
|
|
239
254
|
});
|
|
240
255
|
},
|
|
241
|
-
tabIndex: -1
|
|
256
|
+
tabIndex: -1,
|
|
257
|
+
"aria-disabled": item.isDisabled ? 'true' : 'false'
|
|
242
258
|
}, jsx(CustomItem, {
|
|
243
259
|
item: item,
|
|
244
260
|
key: (_item$key2 = item.key) !== null && _item$key2 !== void 0 ? _item$key2 : String(item.content),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* This component is a wrapper of vertical menus which listens to keydown events of children
|
|
@@ -9,26 +10,38 @@ export var MenuArrowKeyNavigationProvider = function MenuArrowKeyNavigationProvi
|
|
|
9
10
|
handleClose = _ref.handleClose,
|
|
10
11
|
disableArrowKeyNavigation = _ref.disableArrowKeyNavigation,
|
|
11
12
|
keyDownHandlerContext = _ref.keyDownHandlerContext,
|
|
12
|
-
|
|
13
|
+
closeOnTab = _ref.closeOnTab,
|
|
14
|
+
onSelection = _ref.onSelection;
|
|
13
15
|
var wrapperRef = useRef(null);
|
|
14
|
-
var currentSelectedItemIndex = useRef(-1);
|
|
15
16
|
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
currentSelectedItemIndex
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
var _useState = useState(-1),
|
|
18
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
19
|
+
currentSelectedItemIndex = _useState2[0],
|
|
20
|
+
setCurrentSelectedItemIndex = _useState2[1];
|
|
21
|
+
|
|
22
|
+
var incrementIndex = useCallback(function (list) {
|
|
23
|
+
var currentIndex = currentSelectedItemIndex;
|
|
24
|
+
var nextIndex = (currentIndex + 1) % list.length; // Skips disabled items. Previously this function relied on a list of enabled elements which caused a
|
|
25
|
+
// difference between currentIndex and the item index in the menu.
|
|
26
|
+
|
|
27
|
+
while (nextIndex !== currentIndex && list[nextIndex].getAttribute('aria-disabled') === 'true') {
|
|
28
|
+
nextIndex = (nextIndex + 1) % list.length;
|
|
21
29
|
}
|
|
22
|
-
};
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
setCurrentSelectedItemIndex(nextIndex);
|
|
32
|
+
return nextIndex;
|
|
33
|
+
}, [currentSelectedItemIndex]);
|
|
34
|
+
var decrementIndex = useCallback(function (list) {
|
|
35
|
+
var currentIndex = currentSelectedItemIndex;
|
|
36
|
+
var nextIndex = (list.length + currentIndex - 1) % list.length;
|
|
37
|
+
|
|
38
|
+
while (nextIndex !== currentIndex && list[nextIndex].getAttribute('aria-disabled') === 'true') {
|
|
39
|
+
nextIndex = (list.length + nextIndex - 1) % list.length;
|
|
29
40
|
}
|
|
30
|
-
};
|
|
31
41
|
|
|
42
|
+
setCurrentSelectedItemIndex(nextIndex);
|
|
43
|
+
return nextIndex;
|
|
44
|
+
}, [currentSelectedItemIndex]);
|
|
32
45
|
useLayoutEffect(function () {
|
|
33
46
|
if (disableArrowKeyNavigation) {
|
|
34
47
|
return;
|
|
@@ -40,49 +53,48 @@ export var MenuArrowKeyNavigationProvider = function MenuArrowKeyNavigationProvi
|
|
|
40
53
|
|
|
41
54
|
|
|
42
55
|
var handleKeyDown = function handleKeyDown(event) {
|
|
43
|
-
var _wrapperRef$current
|
|
56
|
+
var _wrapperRef$current;
|
|
44
57
|
|
|
45
58
|
var targetElement = event.target; //Tab key on menu items can be handled in the parent components of dropdown menus with KeydownHandlerContext
|
|
46
59
|
|
|
47
|
-
if (event.key === 'Tab' &&
|
|
60
|
+
if (event.key === 'Tab' && closeOnTab) {
|
|
48
61
|
handleClose(event);
|
|
49
62
|
keyDownHandlerContext === null || keyDownHandlerContext === void 0 ? void 0 : keyDownHandlerContext.handleTab();
|
|
50
63
|
return;
|
|
51
64
|
} //To trap the focus inside the toolbar using left and right arrow keys
|
|
52
65
|
|
|
53
66
|
|
|
54
|
-
var focusableElements =
|
|
67
|
+
var focusableElements = getFocusableElements(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current);
|
|
55
68
|
|
|
56
69
|
if (!focusableElements || (focusableElements === null || focusableElements === void 0 ? void 0 : focusableElements.length) === 0) {
|
|
57
70
|
return;
|
|
58
71
|
}
|
|
59
72
|
|
|
60
73
|
if (!((_wrapperRef$current = wrapperRef.current) !== null && _wrapperRef$current !== void 0 && _wrapperRef$current.contains(targetElement))) {
|
|
61
|
-
|
|
74
|
+
setCurrentSelectedItemIndex(-1);
|
|
62
75
|
}
|
|
63
76
|
|
|
64
77
|
switch (event.key) {
|
|
65
78
|
case 'ArrowDown':
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
break;
|
|
79
|
+
{
|
|
80
|
+
var _focusableElements$fo;
|
|
81
|
+
|
|
82
|
+
var focusIndex = incrementIndex(focusableElements);
|
|
83
|
+
(_focusableElements$fo = focusableElements[focusIndex]) === null || _focusableElements$fo === void 0 ? void 0 : _focusableElements$fo.focus();
|
|
84
|
+
event.preventDefault();
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
75
87
|
|
|
76
88
|
case 'ArrowUp':
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
89
|
+
{
|
|
90
|
+
var _focusableElements$_f;
|
|
91
|
+
|
|
92
|
+
var _focusIndex = decrementIndex(focusableElements);
|
|
93
|
+
|
|
94
|
+
(_focusableElements$_f = focusableElements[_focusIndex]) === null || _focusableElements$_f === void 0 ? void 0 : _focusableElements$_f.focus();
|
|
95
|
+
event.preventDefault();
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
86
98
|
//ArrowLeft/Right on the menu should close the menus
|
|
87
99
|
//then logic to retain the focus can be handled in the parent components with KeydownHandlerContext
|
|
88
100
|
|
|
@@ -92,8 +104,11 @@ export var MenuArrowKeyNavigationProvider = function MenuArrowKeyNavigationProvi
|
|
|
92
104
|
return;
|
|
93
105
|
}
|
|
94
106
|
|
|
107
|
+
if (!targetElement.closest('[data-testid="editor-floating-toolbar"]')) {
|
|
108
|
+
keyDownHandlerContext === null || keyDownHandlerContext === void 0 ? void 0 : keyDownHandlerContext.handleArrowLeft();
|
|
109
|
+
}
|
|
110
|
+
|
|
95
111
|
handleClose(event);
|
|
96
|
-
keyDownHandlerContext === null || keyDownHandlerContext === void 0 ? void 0 : keyDownHandlerContext.handleArrowLeft();
|
|
97
112
|
break;
|
|
98
113
|
|
|
99
114
|
case 'ArrowRight':
|
|
@@ -102,14 +117,24 @@ export var MenuArrowKeyNavigationProvider = function MenuArrowKeyNavigationProvi
|
|
|
102
117
|
return;
|
|
103
118
|
}
|
|
104
119
|
|
|
120
|
+
if (!targetElement.closest('[data-testid="editor-floating-toolbar"]')) {
|
|
121
|
+
keyDownHandlerContext === null || keyDownHandlerContext === void 0 ? void 0 : keyDownHandlerContext.handleArrowRight();
|
|
122
|
+
}
|
|
123
|
+
|
|
105
124
|
handleClose(event);
|
|
106
|
-
keyDownHandlerContext === null || keyDownHandlerContext === void 0 ? void 0 : keyDownHandlerContext.handleArrowRight();
|
|
107
125
|
break;
|
|
108
126
|
|
|
109
127
|
case 'Escape':
|
|
110
128
|
handleClose(event);
|
|
111
129
|
break;
|
|
112
130
|
|
|
131
|
+
case 'Enter':
|
|
132
|
+
if (typeof onSelection === 'function') {
|
|
133
|
+
onSelection(currentSelectedItemIndex);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
break;
|
|
137
|
+
|
|
113
138
|
default:
|
|
114
139
|
return;
|
|
115
140
|
}
|
|
@@ -119,9 +144,9 @@ export var MenuArrowKeyNavigationProvider = function MenuArrowKeyNavigationProvi
|
|
|
119
144
|
return function () {
|
|
120
145
|
document.removeEventListener('keydown', handleKeyDown);
|
|
121
146
|
};
|
|
122
|
-
}, [currentSelectedItemIndex, wrapperRef, handleClose, disableArrowKeyNavigation, keyDownHandlerContext,
|
|
147
|
+
}, [currentSelectedItemIndex, wrapperRef, handleClose, disableArrowKeyNavigation, keyDownHandlerContext, closeOnTab, onSelection, incrementIndex, decrementIndex]);
|
|
123
148
|
return /*#__PURE__*/React.createElement("div", {
|
|
124
|
-
className: "custom-key-handler-wrapper",
|
|
149
|
+
className: "menu-key-handler-wrapper custom-key-handler-wrapper",
|
|
125
150
|
ref: wrapperRef
|
|
126
151
|
}, children);
|
|
127
152
|
};
|
|
@@ -133,15 +158,4 @@ function getFocusableElements(rootNode) {
|
|
|
133
158
|
|
|
134
159
|
var focusableModalElements = rootNode.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, div[tabindex="-1"]') || [];
|
|
135
160
|
return Array.from(focusableModalElements);
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* This method filters out all the disabled menu items
|
|
139
|
-
*/
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
function getEnabledElements(rootNode) {
|
|
143
|
-
var focusableElements = getFocusableElements(rootNode);
|
|
144
|
-
return focusableElements.filter(function (element) {
|
|
145
|
-
return !element.querySelector('[role="button"][aria-disabled="true"]') && !element.querySelector('[role="menuitem"][aria-disabled="true"]');
|
|
146
|
-
});
|
|
147
161
|
}
|
|
@@ -6,7 +6,7 @@ import _inherits from "@babel/runtime/helpers/inherits";
|
|
|
6
6
|
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
7
7
|
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
8
8
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
9
|
-
var _excluded = ["handleClickOutside", "handleEnterKeydown", "handleEscapeKeydown", "
|
|
9
|
+
var _excluded = ["handleClickOutside", "handleEnterKeydown", "handleEscapeKeydown", "closeOnTab"];
|
|
10
10
|
|
|
11
11
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
12
12
|
|
|
@@ -70,7 +70,7 @@ var WithOutsideClick = /*#__PURE__*/function (_PureComponent) {
|
|
|
70
70
|
return false;
|
|
71
71
|
} else if (evt.code === 'Enter' && _this.props.handleEnterKeydown) {
|
|
72
72
|
_this.props.handleEnterKeydown(evt);
|
|
73
|
-
} else if (evt.code === 'Tab' && _this.props.handleEscapeKeydown && _this.props.
|
|
73
|
+
} else if (evt.code === 'Tab' && _this.props.handleEscapeKeydown && _this.props.closeOnTab) {
|
|
74
74
|
//The menus should be closed when the tab is pressed as it takes the focus out of the menu
|
|
75
75
|
_this.props.handleEscapeKeydown(evt);
|
|
76
76
|
}
|
|
@@ -125,7 +125,7 @@ export default function withReactEditorViewOuterListeners(Component) {
|
|
|
125
125
|
var handleClickOutside = _ref.handleClickOutside,
|
|
126
126
|
handleEnterKeydown = _ref.handleEnterKeydown,
|
|
127
127
|
handleEscapeKeydown = _ref.handleEscapeKeydown,
|
|
128
|
-
|
|
128
|
+
closeOnTab = _ref.closeOnTab,
|
|
129
129
|
props = _objectWithoutProperties(_ref, _excluded);
|
|
130
130
|
|
|
131
131
|
var isActiveComponent = hasIsOpen(props) ? props.isOpen : true;
|
|
@@ -140,7 +140,7 @@ export default function withReactEditorViewOuterListeners(Component) {
|
|
|
140
140
|
handleClickOutside: handleClickOutside,
|
|
141
141
|
handleEnterKeydown: handleEnterKeydown,
|
|
142
142
|
handleEscapeKeydown: handleEscapeKeydown,
|
|
143
|
-
|
|
143
|
+
closeOnTab: closeOnTab
|
|
144
144
|
}, /*#__PURE__*/React.createElement(Component, props));
|
|
145
145
|
});
|
|
146
146
|
};
|
package/dist/esm/version.json
CHANGED
|
@@ -89,7 +89,7 @@ export declare enum ACTION {
|
|
|
89
89
|
SYNCHRONY_ENTITY_ERROR = "synchronyEntityError",
|
|
90
90
|
SYNCHRONY_ERROR = "synchronyError",
|
|
91
91
|
TEXT_LINK_MARK_TRANSFORMED = "textLinkMarkTransformed",
|
|
92
|
-
|
|
92
|
+
DEDUPE_MARKS_TRANSFORMED_V2 = "dedupeMarksTransformedV2",
|
|
93
93
|
NODES_MISSING_CONTENT_TRANSFORMED = "nodesMissingContentTransformed",
|
|
94
94
|
INDENTATION_MARKS_TRANSFORMED = "indentationMarksTransformed",
|
|
95
95
|
INVALID_MEDIA_CONTENT_TRANSFORMED = "invalidMediaContentTransformed",
|
|
@@ -90,13 +90,14 @@ declare type SynchronyEntityErrorAEP = OperationalAEP<ACTION.SYNCHRONY_ENTITY_ER
|
|
|
90
90
|
declare type ContentComponentErrorAEP = OperationalAEP<ACTION.ERRORED, ACTION_SUBJECT.CONTENT_COMPONENT, undefined, {
|
|
91
91
|
component: CONTENT_COMPONENT;
|
|
92
92
|
error: string;
|
|
93
|
-
errorStack?: string;
|
|
94
93
|
selection: {
|
|
95
94
|
[key: string]: string;
|
|
96
95
|
};
|
|
97
96
|
position: number;
|
|
98
97
|
docSize: number;
|
|
99
|
-
},
|
|
98
|
+
}, {
|
|
99
|
+
errorStack?: string;
|
|
100
|
+
}>;
|
|
100
101
|
export declare type ErrorEventAttributes = {
|
|
101
102
|
error: Error;
|
|
102
103
|
errorInfo: React.ErrorInfo;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { RichMediaLayout } from '@atlaskit/adf-schema';
|
|
2
|
-
import type { ADFEntityMark } from '@atlaskit/adf-utils/types';
|
|
3
2
|
import type { FeatureFlagKey } from '../../types/feature-flags';
|
|
4
3
|
import { PropsDifference, ShallowPropsDifference } from '../../utils';
|
|
5
4
|
import type { SEVERITY } from '../../utils/analytics';
|
|
@@ -172,8 +171,14 @@ declare type CodeBlockLanguageSelectedAEP = TrackAEP<ACTION.LANGUAGE_SELECTED, A
|
|
|
172
171
|
}, undefined>;
|
|
173
172
|
declare type MediaLinkTransformedAEP = OperationalAEP<ACTION.MEDIA_LINK_TRANSFORMED, ACTION_SUBJECT.EDITOR, undefined, undefined, undefined>;
|
|
174
173
|
declare type TextLinkCodeMarkTransformedAEP = OperationalAEP<ACTION.TEXT_LINK_MARK_TRANSFORMED, ACTION_SUBJECT.EDITOR, undefined, undefined, undefined>;
|
|
175
|
-
declare type DedupeMarksTransformedAEP = OperationalAEP<ACTION.
|
|
176
|
-
|
|
174
|
+
declare type DedupeMarksTransformedAEP = OperationalAEP<ACTION.DEDUPE_MARKS_TRANSFORMED_V2, ACTION_SUBJECT.EDITOR, undefined,
|
|
175
|
+
/** UGC WARNING
|
|
176
|
+
*
|
|
177
|
+
* DO NOT include `mark` attributes - only the types
|
|
178
|
+
*
|
|
179
|
+
*/
|
|
180
|
+
{
|
|
181
|
+
discardedMarkTypes: string[];
|
|
177
182
|
}, undefined>;
|
|
178
183
|
declare type IndentationMarksTransformedAEP = OperationalAEP<ACTION.INDENTATION_MARKS_TRANSFORMED, ACTION_SUBJECT.EDITOR, undefined, undefined, undefined>;
|
|
179
184
|
declare type NodesMissingContentTransformedAEP = OperationalAEP<ACTION.NODES_MISSING_CONTENT_TRANSFORMED, ACTION_SUBJECT.EDITOR, undefined, undefined, undefined>;
|