@deephaven/components 0.5.2-beta.0 → 0.6.1-demo.8
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/dist/AutoCompleteInput.js +410 -448
- package/dist/AutoCompleteInput.js.map +1 -1
- package/dist/AutoResizeTextarea.js +17 -46
- package/dist/AutoResizeTextarea.js.map +1 -1
- package/dist/BasicModal.js +18 -19
- package/dist/BasicModal.js.map +1 -1
- package/dist/Button.js +30 -21
- package/dist/Button.js.map +1 -1
- package/dist/ButtonGroup.js +6 -4
- package/dist/ButtonGroup.js.map +1 -1
- package/dist/ButtonOld.js +10 -8
- package/dist/ButtonOld.js.map +1 -1
- package/dist/CardFlip.js +10 -8
- package/dist/CardFlip.js.map +1 -1
- package/dist/Checkbox.js +18 -31
- package/dist/Checkbox.js.map +1 -1
- package/dist/Collapse.js +65 -105
- package/dist/Collapse.js.map +1 -1
- package/dist/ComboBox.js +432 -460
- package/dist/ComboBox.js.map +1 -1
- package/dist/CustomTimeSelect.js +485 -517
- package/dist/CustomTimeSelect.js.map +1 -1
- package/dist/DebouncedSearchInput.js +61 -91
- package/dist/DebouncedSearchInput.js.map +1 -1
- package/dist/DeephavenSpinner.js +6 -6
- package/dist/DeephavenSpinner.js.map +1 -1
- package/dist/DragUtils.js +65 -113
- package/dist/DragUtils.js.map +1 -1
- package/dist/DraggableItemList.d.ts +1 -0
- package/dist/DraggableItemList.d.ts.map +1 -1
- package/dist/DraggableItemList.js +219 -257
- package/dist/DraggableItemList.js.map +1 -1
- package/dist/HierarchicalCheckboxMenu.js +160 -227
- package/dist/HierarchicalCheckboxMenu.js.map +1 -1
- package/dist/ItemList.d.ts +4 -2
- package/dist/ItemList.d.ts.map +1 -1
- package/dist/ItemList.js +595 -598
- package/dist/ItemList.js.map +1 -1
- package/dist/ItemListItem.js +194 -215
- package/dist/ItemListItem.js.map +1 -1
- package/dist/LoadingOverlay.js +9 -10
- package/dist/LoadingOverlay.js.map +1 -1
- package/dist/LoadingSpinner.js +4 -3
- package/dist/LoadingSpinner.js.map +1 -1
- package/dist/MaskedInput.js +59 -70
- package/dist/MaskedInput.js.map +1 -1
- package/dist/Option.js +5 -3
- package/dist/Option.js.map +1 -1
- package/dist/RadioGroup.js +16 -34
- package/dist/RadioGroup.js.map +1 -1
- package/dist/RadioItem.js +14 -33
- package/dist/RadioItem.js.map +1 -1
- package/dist/SearchInput.js +42 -75
- package/dist/SearchInput.js.map +1 -1
- package/dist/Select.js +10 -8
- package/dist/Select.js.map +1 -1
- package/dist/SelectValueList.js +97 -134
- package/dist/SelectValueList.js.map +1 -1
- package/dist/SocketedButton.js +13 -11
- package/dist/SocketedButton.js.map +1 -1
- package/dist/ThemeExport.js.map +1 -1
- package/dist/TimeInput.js +16 -53
- package/dist/TimeInput.js.map +1 -1
- package/dist/TimeSlider.js +62 -88
- package/dist/TimeSlider.js.map +1 -1
- package/dist/ToastNotification.js +14 -13
- package/dist/ToastNotification.js.map +1 -1
- package/dist/UISwitch.js +9 -8
- package/dist/UISwitch.js.map +1 -1
- package/dist/context-actions/ContextActionUtils.js +173 -231
- package/dist/context-actions/ContextActionUtils.js.map +1 -1
- package/dist/context-actions/ContextActions.js +135 -177
- package/dist/context-actions/ContextActions.js.map +1 -1
- package/dist/context-actions/ContextMenu.js +509 -543
- package/dist/context-actions/ContextMenu.js.map +1 -1
- package/dist/context-actions/ContextMenuItem.js +32 -22
- package/dist/context-actions/ContextMenuItem.js.map +1 -1
- package/dist/context-actions/ContextMenuRoot.js +112 -152
- package/dist/context-actions/ContextMenuRoot.js.map +1 -1
- package/dist/context-actions/GlobalContextAction.js +49 -84
- package/dist/context-actions/GlobalContextAction.js.map +1 -1
- package/dist/context-actions/GlobalContextActions.js +25 -57
- package/dist/context-actions/GlobalContextActions.js.map +1 -1
- package/dist/context-actions/index.js +4 -4
- package/dist/context-actions/index.js.map +1 -1
- package/dist/index.js +39 -39
- package/dist/index.js.map +1 -1
- package/dist/menu-actions/DropdownMenu.js +126 -159
- package/dist/menu-actions/DropdownMenu.js.map +1 -1
- package/dist/menu-actions/Menu.js +215 -245
- package/dist/menu-actions/Menu.js.map +1 -1
- package/dist/menu-actions/index.js +1 -1
- package/dist/menu-actions/index.js.map +1 -1
- package/dist/navigation/Menu.js +14 -18
- package/dist/navigation/Menu.js.map +1 -1
- package/dist/navigation/MenuItem.js +15 -14
- package/dist/navigation/MenuItem.js.map +1 -1
- package/dist/navigation/Page.js +7 -5
- package/dist/navigation/Page.js.map +1 -1
- package/dist/navigation/Stack.js +14 -39
- package/dist/navigation/Stack.js.map +1 -1
- package/dist/navigation/index.js +4 -4
- package/dist/navigation/index.js.map +1 -1
- package/dist/popper/Popper.js +209 -235
- package/dist/popper/Popper.js.map +1 -1
- package/dist/popper/Tooltip.js +227 -257
- package/dist/popper/Tooltip.js.map +1 -1
- package/dist/popper/index.js +2 -2
- package/dist/popper/index.js.map +1 -1
- package/dist/shortcuts/GlobalShortcuts.js +2 -2
- package/dist/shortcuts/GlobalShortcuts.js.map +1 -1
- package/dist/shortcuts/Shortcut.js +263 -291
- package/dist/shortcuts/Shortcut.js.map +1 -1
- package/dist/shortcuts/ShortcutRegistry.js +48 -71
- package/dist/shortcuts/ShortcutRegistry.js.map +1 -1
- package/dist/shortcuts/index.js +4 -4
- package/dist/shortcuts/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +30 -54
|
@@ -1,83 +1,62 @@
|
|
|
1
|
-
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
2
|
-
|
|
3
1
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
4
2
|
|
|
5
3
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
6
4
|
|
|
7
|
-
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
8
|
-
|
|
9
|
-
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
10
|
-
|
|
11
|
-
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
12
|
-
|
|
13
|
-
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
14
|
-
|
|
15
|
-
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
16
|
-
|
|
17
|
-
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); }; }
|
|
18
|
-
|
|
19
|
-
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
|
20
|
-
|
|
21
|
-
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
22
|
-
|
|
23
|
-
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
24
|
-
|
|
25
|
-
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
26
|
-
|
|
27
5
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
28
6
|
|
|
29
7
|
import React, { PureComponent } from 'react';
|
|
30
8
|
import classNames from 'classnames';
|
|
31
9
|
import Log from '@deephaven/log';
|
|
32
10
|
import { PromiseUtils } from '@deephaven/utils';
|
|
33
|
-
import ContextActionUtils from
|
|
34
|
-
import ContextMenuItem from
|
|
35
|
-
import LoadingSpinner from
|
|
11
|
+
import ContextActionUtils from "./ContextActionUtils.js";
|
|
12
|
+
import ContextMenuItem from "./ContextMenuItem.js";
|
|
13
|
+
import LoadingSpinner from "../LoadingSpinner.js";
|
|
36
14
|
var log = Log.module('ContextMenu');
|
|
37
15
|
|
|
38
16
|
/** Do not use this class directly. Use ContextMenuRoot and ContextActions instead. */
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
function ContextMenu(props) {
|
|
45
|
-
var _this;
|
|
17
|
+
class ContextMenu extends PureComponent {
|
|
18
|
+
static handleContextMenu(e) {
|
|
19
|
+
if (e.metaKey) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
46
22
|
|
|
47
|
-
|
|
23
|
+
e.stopPropagation();
|
|
24
|
+
e.preventDefault();
|
|
25
|
+
}
|
|
48
26
|
|
|
49
|
-
|
|
27
|
+
constructor(props) {
|
|
28
|
+
super(props);
|
|
50
29
|
|
|
51
|
-
_defineProperty(
|
|
30
|
+
_defineProperty(this, "container", void 0);
|
|
52
31
|
|
|
53
|
-
_defineProperty(
|
|
32
|
+
_defineProperty(this, "oldFocus", void 0);
|
|
54
33
|
|
|
55
|
-
_defineProperty(
|
|
34
|
+
_defineProperty(this, "activeSubMenuRef", void 0);
|
|
56
35
|
|
|
57
|
-
_defineProperty(
|
|
36
|
+
_defineProperty(this, "subMenuTimer", void 0);
|
|
58
37
|
|
|
59
|
-
_defineProperty(
|
|
38
|
+
_defineProperty(this, "rAF", void 0);
|
|
60
39
|
|
|
61
|
-
_defineProperty(
|
|
40
|
+
_defineProperty(this, "initialPosition", void 0);
|
|
62
41
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
42
|
+
this.handleBlur = this.handleBlur.bind(this);
|
|
43
|
+
this.handleCloseSubMenu = this.handleCloseSubMenu.bind(this);
|
|
44
|
+
this.handleKeyDown = this.handleKeyDown.bind(this);
|
|
45
|
+
this.handleMenuItemClick = this.handleMenuItemClick.bind(this);
|
|
46
|
+
this.handleMenuItemContextMenu = this.handleMenuItemContextMenu.bind(this);
|
|
47
|
+
this.handleMenuItemMouseMove = this.handleMenuItemMouseMove.bind(this);
|
|
48
|
+
this.handleMouseLeave = this.handleMouseLeave.bind(this);
|
|
49
|
+
this.handleWindowResize = this.handleWindowResize.bind(this);
|
|
50
|
+
this.container = /*#__PURE__*/React.createRef();
|
|
51
|
+
this.oldFocus = document.activeElement;
|
|
52
|
+
this.activeSubMenuRef = /*#__PURE__*/React.createRef();
|
|
53
|
+
this.subMenuTimer = 0;
|
|
54
|
+
this.rAF = 0;
|
|
55
|
+
this.initialPosition = {
|
|
77
56
|
top: props.top,
|
|
78
57
|
left: props.left
|
|
79
58
|
};
|
|
80
|
-
|
|
59
|
+
this.state = {
|
|
81
60
|
menuItems: [],
|
|
82
61
|
pendingItems: [],
|
|
83
62
|
activeSubMenu: null,
|
|
@@ -89,580 +68,567 @@ var ContextMenu = /*#__PURE__*/function (_PureComponent) {
|
|
|
89
68
|
keyboardIndex: -1,
|
|
90
69
|
mouseIndex: -1
|
|
91
70
|
};
|
|
92
|
-
return _this;
|
|
93
71
|
}
|
|
94
72
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
73
|
+
componentDidMount() {
|
|
74
|
+
this.initMenu();
|
|
75
|
+
this.verifyPosition();
|
|
76
|
+
window.addEventListener('resize', this.handleWindowResize); // rAF is needed to wait for a submenus popper to be created before
|
|
77
|
+
// attempting to set focus, however on a quick mount/unmount when
|
|
78
|
+
// mousing past an item, the submenu could be unmounted before the
|
|
79
|
+
// async rAF finishes, so it is cancelled in willUnmount()
|
|
80
|
+
|
|
81
|
+
this.rAF = window.requestAnimationFrame(() => {
|
|
82
|
+
var _this$container$curre;
|
|
83
|
+
|
|
84
|
+
(_this$container$curre = this.container.current) === null || _this$container$curre === void 0 ? void 0 : _this$container$curre.focus();
|
|
85
|
+
var {
|
|
86
|
+
onMenuOpened
|
|
87
|
+
} = this.props;
|
|
88
|
+
onMenuOpened(this);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
99
91
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
this.rAF = window.requestAnimationFrame(function () {
|
|
108
|
-
var _this2$container$curr;
|
|
109
|
-
|
|
110
|
-
(_this2$container$curr = _this2.container.current) === null || _this2$container$curr === void 0 ? void 0 : _this2$container$curr.focus();
|
|
111
|
-
var onMenuOpened = _this2.props.onMenuOpened;
|
|
112
|
-
onMenuOpened(_this2);
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}, {
|
|
116
|
-
key: "componentDidUpdate",
|
|
117
|
-
value: function componentDidUpdate(prevProps, prevState) {
|
|
118
|
-
var actions = this.props.actions;
|
|
119
|
-
var activeSubMenu = this.state.activeSubMenu;
|
|
120
|
-
|
|
121
|
-
if (activeSubMenu !== prevState.activeSubMenu) {
|
|
122
|
-
if (activeSubMenu == null) {
|
|
123
|
-
var _this$container$curre;
|
|
124
|
-
|
|
125
|
-
// close sub menu, refocus parent menu
|
|
126
|
-
(_this$container$curre = this.container.current) === null || _this$container$curre === void 0 ? void 0 : _this$container$curre.focus();
|
|
127
|
-
} else {
|
|
128
|
-
// open sub menu, set its initial position
|
|
129
|
-
this.setActiveSubMenuPosition();
|
|
130
|
-
}
|
|
131
|
-
}
|
|
92
|
+
componentDidUpdate(prevProps, prevState) {
|
|
93
|
+
var {
|
|
94
|
+
actions
|
|
95
|
+
} = this.props;
|
|
96
|
+
var {
|
|
97
|
+
activeSubMenu
|
|
98
|
+
} = this.state;
|
|
132
99
|
|
|
133
|
-
|
|
100
|
+
if (activeSubMenu !== prevState.activeSubMenu) {
|
|
101
|
+
if (activeSubMenu == null) {
|
|
134
102
|
var _this$container$curre2;
|
|
135
103
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
(_this$container$curre3 = this.container.current) === null || _this$container$curre3 === void 0 ? void 0 : _this$container$curre3.focus();
|
|
142
|
-
}
|
|
104
|
+
// close sub menu, refocus parent menu
|
|
105
|
+
(_this$container$curre2 = this.container.current) === null || _this$container$curre2 === void 0 ? void 0 : _this$container$curre2.focus();
|
|
106
|
+
} else {
|
|
107
|
+
// open sub menu, set its initial position
|
|
108
|
+
this.setActiveSubMenuPosition();
|
|
143
109
|
}
|
|
144
|
-
|
|
145
|
-
this.verifyPosition();
|
|
146
|
-
}
|
|
147
|
-
}, {
|
|
148
|
-
key: "componentWillUnmount",
|
|
149
|
-
value: function componentWillUnmount() {
|
|
150
|
-
this.cancelPromises();
|
|
151
|
-
window.removeEventListener('resize', this.handleWindowResize);
|
|
152
|
-
cancelAnimationFrame(this.rAF);
|
|
153
110
|
}
|
|
154
|
-
}, {
|
|
155
|
-
key: "getKeyboardIndex",
|
|
156
|
-
value: function getKeyboardIndex() {
|
|
157
|
-
var options = this.props.options;
|
|
158
|
-
|
|
159
|
-
if (options.separateKeyboardMouse) {
|
|
160
|
-
var keyboardIndex = this.state.keyboardIndex;
|
|
161
|
-
return keyboardIndex;
|
|
162
|
-
}
|
|
163
111
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}, {
|
|
167
|
-
key: "setKeyboardIndex",
|
|
168
|
-
value: function setKeyboardIndex(index) {
|
|
169
|
-
var options = this.props.options;
|
|
112
|
+
if (prevProps.actions !== actions) {
|
|
113
|
+
var _this$container$curre3;
|
|
170
114
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
this.
|
|
115
|
+
this.initMenu();
|
|
116
|
+
|
|
117
|
+
if (!((_this$container$curre3 = this.container.current) !== null && _this$container$curre3 !== void 0 && _this$container$curre3.contains(document.activeElement))) {
|
|
118
|
+
var _this$container$curre4;
|
|
119
|
+
|
|
120
|
+
(_this$container$curre4 = this.container.current) === null || _this$container$curre4 === void 0 ? void 0 : _this$container$curre4.focus();
|
|
177
121
|
}
|
|
178
122
|
}
|
|
179
|
-
}, {
|
|
180
|
-
key: "getMouseIndex",
|
|
181
|
-
value: function getMouseIndex() {
|
|
182
|
-
var mouseIndex = this.state.mouseIndex;
|
|
183
|
-
return mouseIndex;
|
|
184
|
-
}
|
|
185
|
-
}, {
|
|
186
|
-
key: "setMouseIndex",
|
|
187
|
-
value: function setMouseIndex(index) {
|
|
188
|
-
this.setState({
|
|
189
|
-
mouseIndex: index
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
}, {
|
|
193
|
-
key: "initMenu",
|
|
194
|
-
value: function initMenu() {
|
|
195
|
-
// cancel any pending close and promises
|
|
196
|
-
this.cancelPromises();
|
|
197
|
-
cancelAnimationFrame(this.rAF);
|
|
198
|
-
var options = this.props.options;
|
|
199
|
-
var keyboardIndex = options.initialKeyboardIndex;
|
|
200
|
-
|
|
201
|
-
if (keyboardIndex === undefined) {
|
|
202
|
-
keyboardIndex = -1;
|
|
203
|
-
}
|
|
204
123
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
var nonPromiseItems = [];
|
|
124
|
+
this.verifyPosition();
|
|
125
|
+
}
|
|
208
126
|
|
|
209
|
-
|
|
210
|
-
|
|
127
|
+
componentWillUnmount() {
|
|
128
|
+
this.cancelPromises();
|
|
129
|
+
window.removeEventListener('resize', this.handleWindowResize);
|
|
130
|
+
cancelAnimationFrame(this.rAF);
|
|
131
|
+
}
|
|
211
132
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
}
|
|
133
|
+
getKeyboardIndex() {
|
|
134
|
+
var {
|
|
135
|
+
options
|
|
136
|
+
} = this.props;
|
|
218
137
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
keyboardIndex
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
});
|
|
138
|
+
if (options.separateKeyboardMouse) {
|
|
139
|
+
var {
|
|
140
|
+
keyboardIndex
|
|
141
|
+
} = this.state;
|
|
142
|
+
return keyboardIndex;
|
|
225
143
|
}
|
|
226
|
-
}, {
|
|
227
|
-
key: "initMenuPromise",
|
|
228
|
-
value: function initMenuPromise(promise) {
|
|
229
|
-
var _this3 = this;
|
|
230
|
-
|
|
231
|
-
// make all promises cancellable
|
|
232
|
-
var cancellablePromise = PromiseUtils.makeCancelable(promise);
|
|
233
|
-
this.setState(function (state) {
|
|
234
|
-
return {
|
|
235
|
-
pendingItems: state.pendingItems.concat(cancellablePromise)
|
|
236
|
-
};
|
|
237
|
-
});
|
|
238
|
-
cancellablePromise.then(function (resolvedMenuItems) {
|
|
239
|
-
_this3.setState(function (state) {
|
|
240
|
-
var index = state.pendingItems.indexOf(cancellablePromise);
|
|
241
144
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
pendingItems.splice(index, 1);
|
|
245
|
-
return {
|
|
246
|
-
menuItems: ContextActionUtils.sortActions(state.menuItems.concat(resolvedMenuItems)),
|
|
247
|
-
pendingItems: pendingItems
|
|
248
|
-
};
|
|
249
|
-
} // This item is stale, don't update the menu
|
|
145
|
+
return this.getMouseIndex();
|
|
146
|
+
}
|
|
250
147
|
|
|
148
|
+
setKeyboardIndex(index) {
|
|
149
|
+
var {
|
|
150
|
+
options
|
|
151
|
+
} = this.props;
|
|
251
152
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
153
|
+
if (options.separateKeyboardMouse) {
|
|
154
|
+
this.setState({
|
|
155
|
+
keyboardIndex: index
|
|
156
|
+
});
|
|
157
|
+
} else {
|
|
158
|
+
this.setMouseIndex(index);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
258
161
|
|
|
162
|
+
getMouseIndex() {
|
|
163
|
+
var {
|
|
164
|
+
mouseIndex
|
|
165
|
+
} = this.state;
|
|
166
|
+
return mouseIndex;
|
|
167
|
+
}
|
|
259
168
|
|
|
260
|
-
|
|
261
|
-
|
|
169
|
+
setMouseIndex(index) {
|
|
170
|
+
this.setState({
|
|
171
|
+
mouseIndex: index
|
|
172
|
+
});
|
|
173
|
+
}
|
|
262
174
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
175
|
+
initMenu() {
|
|
176
|
+
// cancel any pending close and promises
|
|
177
|
+
this.cancelPromises();
|
|
178
|
+
cancelAnimationFrame(this.rAF);
|
|
179
|
+
var {
|
|
180
|
+
options
|
|
181
|
+
} = this.props;
|
|
182
|
+
var keyboardIndex = options.initialKeyboardIndex;
|
|
183
|
+
|
|
184
|
+
if (keyboardIndex === undefined) {
|
|
185
|
+
keyboardIndex = -1;
|
|
186
|
+
}
|
|
270
187
|
|
|
271
|
-
|
|
272
|
-
|
|
188
|
+
var {
|
|
189
|
+
actions
|
|
190
|
+
} = this.props;
|
|
191
|
+
var menuItems = ContextActionUtils.getMenuItems(actions);
|
|
192
|
+
var nonPromiseItems = [];
|
|
273
193
|
|
|
194
|
+
for (var i = menuItems.length - 1; i >= 0; i -= 1) {
|
|
195
|
+
var menuItem = menuItems[i];
|
|
274
196
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
value: function cancelPromises() {
|
|
281
|
-
var pendingItems = this.state.pendingItems;
|
|
282
|
-
pendingItems.map(function (item) {
|
|
283
|
-
return item.cancel();
|
|
284
|
-
});
|
|
197
|
+
if (menuItem instanceof Promise) {
|
|
198
|
+
this.initMenuPromise(menuItem);
|
|
199
|
+
} else {
|
|
200
|
+
nonPromiseItems.push(menuItem);
|
|
201
|
+
}
|
|
285
202
|
}
|
|
286
|
-
/**
|
|
287
|
-
* Sets the unverfied start position of a submenu. Submenu then self-verfies
|
|
288
|
-
* its own position and potentially reports back a new position.
|
|
289
|
-
*/
|
|
290
203
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
204
|
+
this.setState({
|
|
205
|
+
mouseIndex: -1,
|
|
206
|
+
keyboardIndex,
|
|
207
|
+
activeSubMenu: null,
|
|
208
|
+
menuItems: ContextActionUtils.sortActions(nonPromiseItems)
|
|
209
|
+
});
|
|
210
|
+
}
|
|
296
211
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
212
|
+
initMenuPromise(promise) {
|
|
213
|
+
// make all promises cancellable
|
|
214
|
+
var cancellablePromise = PromiseUtils.makeCancelable(promise);
|
|
215
|
+
this.setState(state => ({
|
|
216
|
+
pendingItems: state.pendingItems.concat(cancellablePromise)
|
|
217
|
+
}));
|
|
218
|
+
cancellablePromise.then(resolvedMenuItems => {
|
|
219
|
+
this.setState(state => {
|
|
220
|
+
var index = state.pendingItems.indexOf(cancellablePromise);
|
|
221
|
+
|
|
222
|
+
if (index >= 0) {
|
|
223
|
+
var pendingItems = state.pendingItems.slice();
|
|
224
|
+
pendingItems.splice(index, 1);
|
|
225
|
+
return {
|
|
226
|
+
menuItems: ContextActionUtils.sortActions(state.menuItems.concat(resolvedMenuItems)),
|
|
227
|
+
pendingItems
|
|
228
|
+
};
|
|
229
|
+
} // This item is stale, don't update the menu
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
return null;
|
|
302
233
|
});
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
* By default it tries to top-align with parent, at the right side of the parent.
|
|
308
|
-
* Because we aren't a native context menu and can't escape window bounds, we also do
|
|
309
|
-
* somethings to better fit on screen, such as the "nudge" offset position, and further
|
|
310
|
-
* allow overflow scrolling for large menus in a small window.
|
|
311
|
-
*/
|
|
312
|
-
|
|
313
|
-
}, {
|
|
314
|
-
key: "verifyPosition",
|
|
315
|
-
value: function verifyPosition() {
|
|
316
|
-
var _this$container$curre4, _this$container$curre5, _this$container$curre6, _this$container$curre7;
|
|
317
|
-
|
|
318
|
-
var _this$props = this.props,
|
|
319
|
-
options = _this$props.options,
|
|
320
|
-
updatePosition = _this$props.updatePosition,
|
|
321
|
-
subMenuParentWidth = _this$props.subMenuParentWidth,
|
|
322
|
-
subMenuParentHeight = _this$props.subMenuParentHeight,
|
|
323
|
-
oldTop = _this$props.top,
|
|
324
|
-
oldLeft = _this$props.left;
|
|
325
|
-
|
|
326
|
-
if (!this.container.current || options.doNotVerifyPosition) {
|
|
327
|
-
return;
|
|
328
|
-
} // initial position is used rather than current position,
|
|
329
|
-
// as the number of menu items can change (actions can bubble)
|
|
330
|
-
// and menu should always be positioned relative to spawn point
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
var _this$initialPosition = this.initialPosition,
|
|
334
|
-
top = _this$initialPosition.top,
|
|
335
|
-
left = _this$initialPosition.left;
|
|
336
|
-
|
|
337
|
-
var _ref = (_this$container$curre4 = (_this$container$curre5 = this.container.current) === null || _this$container$curre5 === void 0 ? void 0 : _this$container$curre5.getBoundingClientRect()) !== null && _this$container$curre4 !== void 0 ? _this$container$curre4 : {
|
|
338
|
-
width: 0,
|
|
339
|
-
height: 0
|
|
340
|
-
},
|
|
341
|
-
width = _ref.width,
|
|
342
|
-
height = _ref.height;
|
|
343
|
-
|
|
344
|
-
var hasOverflow = ((_this$container$curre6 = (_this$container$curre7 = this.container.current) === null || _this$container$curre7 === void 0 ? void 0 : _this$container$curre7.scrollHeight) !== null && _this$container$curre6 !== void 0 ? _this$container$curre6 : 0) > window.innerHeight;
|
|
234
|
+
}, error => {
|
|
235
|
+
if (PromiseUtils.isCanceled(error)) {
|
|
236
|
+
return; // Canceled promise is ignored
|
|
237
|
+
} // remove failed item from pending list
|
|
345
238
|
|
|
346
|
-
if (height === 0 || width === 0) {
|
|
347
|
-
// We don't have a height or width yet, don't bother doing anything
|
|
348
|
-
return;
|
|
349
|
-
} // does it fit below?
|
|
350
239
|
|
|
240
|
+
this.setState(state => {
|
|
241
|
+
var index = state.pendingItems.indexOf(cancellablePromise);
|
|
351
242
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
// still doesnt fit? okay, position at bottom edge
|
|
359
|
-
top = window.innerHeight - height;
|
|
243
|
+
if (index >= 0) {
|
|
244
|
+
var pendingItems = state.pendingItems.slice();
|
|
245
|
+
pendingItems.splice(index, 1);
|
|
246
|
+
return {
|
|
247
|
+
pendingItems
|
|
248
|
+
};
|
|
360
249
|
}
|
|
361
|
-
}
|
|
362
250
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
left = left - width - subMenuParentWidth;
|
|
366
|
-
}
|
|
251
|
+
return null;
|
|
252
|
+
}); // Log the error
|
|
367
253
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
254
|
+
log.error(error);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
cancelPromises() {
|
|
259
|
+
var {
|
|
260
|
+
pendingItems
|
|
261
|
+
} = this.state;
|
|
262
|
+
pendingItems.map(item => item.cancel());
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Sets the unverfied start position of a submenu. Submenu then self-verfies
|
|
266
|
+
* its own position and potentially reports back a new position.
|
|
267
|
+
*/
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
setActiveSubMenuPosition() {
|
|
271
|
+
if (this.activeSubMenuRef.current === null) return;
|
|
272
|
+
var parentRect = this.activeSubMenuRef.current.getBoundingClientRect(); // intentionally rect.right, we want the sub menu to start at the right edge of the current menu
|
|
273
|
+
|
|
274
|
+
this.setState({
|
|
275
|
+
subMenuTop: parentRect.top,
|
|
276
|
+
subMenuLeft: parentRect.right,
|
|
277
|
+
subMenuParentHeight: parentRect.height,
|
|
278
|
+
subMenuParentWidth: parentRect.width
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Verifies the position of this menu in relation to the parent to make sure it's on screen.
|
|
283
|
+
* Will update the top left state (updatePosition) if necessary (causing a re-render)
|
|
284
|
+
* By default it tries to top-align with parent, at the right side of the parent.
|
|
285
|
+
* Because we aren't a native context menu and can't escape window bounds, we also do
|
|
286
|
+
* somethings to better fit on screen, such as the "nudge" offset position, and further
|
|
287
|
+
* allow overflow scrolling for large menus in a small window.
|
|
288
|
+
*/
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
verifyPosition() {
|
|
292
|
+
var _this$container$curre5, _this$container$curre6, _this$container$curre7, _this$container$curre8;
|
|
293
|
+
|
|
294
|
+
var {
|
|
295
|
+
options,
|
|
296
|
+
updatePosition,
|
|
297
|
+
subMenuParentWidth,
|
|
298
|
+
subMenuParentHeight,
|
|
299
|
+
top: oldTop,
|
|
300
|
+
left: oldLeft
|
|
301
|
+
} = this.props;
|
|
302
|
+
|
|
303
|
+
if (!this.container.current || options.doNotVerifyPosition) {
|
|
304
|
+
return;
|
|
305
|
+
} // initial position is used rather than current position,
|
|
306
|
+
// as the number of menu items can change (actions can bubble)
|
|
307
|
+
// and menu should always be positioned relative to spawn point
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
var {
|
|
311
|
+
top,
|
|
312
|
+
left
|
|
313
|
+
} = this.initialPosition;
|
|
314
|
+
var {
|
|
315
|
+
width,
|
|
316
|
+
height
|
|
317
|
+
} = (_this$container$curre5 = (_this$container$curre6 = this.container.current) === null || _this$container$curre6 === void 0 ? void 0 : _this$container$curre6.getBoundingClientRect()) !== null && _this$container$curre5 !== void 0 ? _this$container$curre5 : {
|
|
318
|
+
width: 0,
|
|
319
|
+
height: 0
|
|
320
|
+
};
|
|
321
|
+
var hasOverflow = ((_this$container$curre7 = (_this$container$curre8 = this.container.current) === null || _this$container$curre8 === void 0 ? void 0 : _this$container$curre8.scrollHeight) !== null && _this$container$curre7 !== void 0 ? _this$container$curre7 : 0) > window.innerHeight;
|
|
322
|
+
|
|
323
|
+
if (height === 0 || width === 0) {
|
|
324
|
+
// We don't have a height or width yet, don't bother doing anything
|
|
325
|
+
return;
|
|
326
|
+
} // does it fit below?
|
|
376
327
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
if (
|
|
381
|
-
|
|
328
|
+
|
|
329
|
+
if (top + height > window.innerHeight) {
|
|
330
|
+
// can it be flipped to above? include offset if submenu (defaults to 0 if not submenu)
|
|
331
|
+
if (top - height - subMenuParentHeight > 0) {
|
|
332
|
+
// flip like a native menu would
|
|
333
|
+
top -= height - subMenuParentHeight;
|
|
334
|
+
} else {
|
|
335
|
+
// still doesnt fit? okay, position at bottom edge
|
|
336
|
+
top = window.innerHeight - height;
|
|
382
337
|
}
|
|
338
|
+
}
|
|
383
339
|
|
|
384
|
-
|
|
340
|
+
if (left + width > window.innerWidth) {
|
|
341
|
+
// less picky about left right positioning, just keep it going off to right
|
|
342
|
+
left = left - width - subMenuParentWidth;
|
|
385
343
|
}
|
|
386
|
-
}, {
|
|
387
|
-
key: "handleBlur",
|
|
388
|
-
value: function handleBlur(e) {
|
|
389
|
-
if (!this.container.current) {
|
|
390
|
-
log.warn('Container is null!');
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
344
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
345
|
+
if (oldLeft !== left || oldTop !== top) {
|
|
346
|
+
// parent owns positioning as single source of truth, ask to update props
|
|
347
|
+
this.setState({
|
|
348
|
+
hasOverflow
|
|
349
|
+
});
|
|
350
|
+
updatePosition(top, left);
|
|
351
|
+
}
|
|
352
|
+
} // since window resize doesn't trigger blur, listen and close the menu
|
|
397
353
|
|
|
398
|
-
while (element && !isContextMenuChild) {
|
|
399
|
-
isContextMenuChild = element.hasAttribute('data-dh-context-menu');
|
|
400
|
-
element = element.parentElement;
|
|
401
|
-
}
|
|
402
354
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
}
|
|
407
|
-
}
|
|
355
|
+
handleWindowResize() {
|
|
356
|
+
if (!this.container.current) {
|
|
357
|
+
return;
|
|
408
358
|
}
|
|
409
|
-
/** Returns whether the specified key should remove the menu. Depends on the side the parent is on. */
|
|
410
359
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
360
|
+
this.closeMenu(true);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
handleBlur(e) {
|
|
364
|
+
if (!this.container.current) {
|
|
365
|
+
log.warn('Container is null!');
|
|
366
|
+
return;
|
|
416
367
|
}
|
|
417
|
-
}, {
|
|
418
|
-
key: "handleKeyDown",
|
|
419
|
-
value: function handleKeyDown(e) {
|
|
420
|
-
var menuItems = this.state.menuItems;
|
|
421
|
-
var oldFocus = this.getKeyboardIndex();
|
|
422
|
-
var newFocus = oldFocus;
|
|
423
|
-
var openSubMenu = false;
|
|
424
|
-
|
|
425
|
-
if (e.key === 'Enter' || e.key === ' ') {
|
|
426
|
-
if (oldFocus >= 0 && oldFocus < menuItems.length) {
|
|
427
|
-
this.handleMenuItemClick(menuItems[oldFocus], e);
|
|
428
|
-
}
|
|
429
368
|
|
|
430
|
-
|
|
431
|
-
|
|
369
|
+
if (!this.container.current.contains(e.relatedTarget)) {
|
|
370
|
+
var element = e.relatedTarget;
|
|
371
|
+
var isContextMenuChild = false;
|
|
432
372
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
} else {
|
|
437
|
-
newFocus = 0;
|
|
438
|
-
}
|
|
439
|
-
} else if (this.isEscapeKey(e.key)) {
|
|
440
|
-
newFocus = null;
|
|
441
|
-
} else if (e.key === 'ArrowUp' || e.shiftKey && e.key === 'Tab') {
|
|
442
|
-
newFocus = ContextActionUtils.getNextMenuItem(newFocus, -1, menuItems);
|
|
443
|
-
} else if (e.key === 'ArrowDown' || e.key === 'Tab') {
|
|
444
|
-
newFocus = ContextActionUtils.getNextMenuItem(newFocus, 1, menuItems);
|
|
373
|
+
while (element && !isContextMenuChild) {
|
|
374
|
+
isContextMenuChild = element.hasAttribute('data-dh-context-menu');
|
|
375
|
+
element = element.parentElement;
|
|
445
376
|
}
|
|
446
377
|
|
|
447
|
-
if (
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
e.stopPropagation();
|
|
451
|
-
return;
|
|
378
|
+
if (!isContextMenuChild) {
|
|
379
|
+
// close all submenus on blur
|
|
380
|
+
this.closeMenu(true);
|
|
452
381
|
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/** Returns whether the specified key should remove the menu. Depends on the side the parent is on. */
|
|
453
385
|
|
|
454
|
-
if (oldFocus !== newFocus) {
|
|
455
|
-
if (newFocus !== null) {
|
|
456
|
-
this.setKeyboardIndex(newFocus);
|
|
457
|
-
} else {
|
|
458
|
-
this.closeMenu();
|
|
459
386
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
387
|
+
isEscapeKey(key) {
|
|
388
|
+
var {
|
|
389
|
+
left
|
|
390
|
+
} = this.props;
|
|
391
|
+
return key === 'Escape' || left < 0 && key === 'ArrowRight' || key === 'ArrowLeft';
|
|
392
|
+
}
|
|
464
393
|
|
|
465
|
-
|
|
466
|
-
|
|
394
|
+
handleKeyDown(e) {
|
|
395
|
+
var {
|
|
396
|
+
menuItems
|
|
397
|
+
} = this.state;
|
|
398
|
+
var oldFocus = this.getKeyboardIndex();
|
|
399
|
+
var newFocus = oldFocus;
|
|
400
|
+
var openSubMenu = false;
|
|
401
|
+
|
|
402
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
403
|
+
if (oldFocus >= 0 && oldFocus < menuItems.length) {
|
|
404
|
+
this.handleMenuItemClick(menuItems[oldFocus], e);
|
|
467
405
|
}
|
|
406
|
+
|
|
407
|
+
return;
|
|
468
408
|
}
|
|
469
|
-
|
|
470
|
-
key
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
menuItems = _this$state.menuItems,
|
|
474
|
-
activeSubMenu = _this$state.activeSubMenu;
|
|
475
|
-
var newSubMenu = menuItems[index].actions ? index : null;
|
|
476
|
-
if (activeSubMenu === newSubMenu) return;
|
|
477
|
-
this.setState({
|
|
478
|
-
activeSubMenu: newSubMenu,
|
|
479
|
-
subMenuTop: null,
|
|
480
|
-
subMenuLeft: null
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
}, {
|
|
484
|
-
key: "closeMenu",
|
|
485
|
-
value: function closeMenu() {
|
|
486
|
-
var _this4 = this;
|
|
487
|
-
|
|
488
|
-
var closeAll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
489
|
-
var _this$props2 = this.props,
|
|
490
|
-
closeMenu = _this$props2.closeMenu,
|
|
491
|
-
onMenuClosed = _this$props2.onMenuClosed;
|
|
492
|
-
cancelAnimationFrame(this.rAF);
|
|
493
|
-
this.rAF = window.requestAnimationFrame(function () {
|
|
494
|
-
closeMenu(closeAll);
|
|
495
|
-
onMenuClosed(_this4);
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
}, {
|
|
499
|
-
key: "closeSubMenu",
|
|
500
|
-
value: function closeSubMenu() {
|
|
501
|
-
this.setState({
|
|
502
|
-
activeSubMenu: null
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
}, {
|
|
506
|
-
key: "handleCloseSubMenu",
|
|
507
|
-
value: function handleCloseSubMenu(closeAllMenus) {
|
|
508
|
-
if (closeAllMenus) {
|
|
509
|
-
this.closeMenu(true);
|
|
409
|
+
|
|
410
|
+
if (e.key === 'ArrowRight') {
|
|
411
|
+
if (oldFocus >= 0 && oldFocus <= menuItems.length) {
|
|
412
|
+
openSubMenu = true;
|
|
510
413
|
} else {
|
|
511
|
-
|
|
414
|
+
newFocus = 0;
|
|
512
415
|
}
|
|
416
|
+
} else if (this.isEscapeKey(e.key)) {
|
|
417
|
+
newFocus = null;
|
|
418
|
+
} else if (e.key === 'ArrowUp' || e.shiftKey && e.key === 'Tab') {
|
|
419
|
+
newFocus = ContextActionUtils.getNextMenuItem(newFocus, -1, menuItems);
|
|
420
|
+
} else if (e.key === 'ArrowDown' || e.key === 'Tab') {
|
|
421
|
+
newFocus = ContextActionUtils.getNextMenuItem(newFocus, 1, menuItems);
|
|
513
422
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
423
|
+
|
|
424
|
+
if (openSubMenu) {
|
|
425
|
+
this.openSubMenu(oldFocus);
|
|
517
426
|
e.preventDefault();
|
|
518
427
|
e.stopPropagation();
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
if (oldFocus !== newFocus) {
|
|
432
|
+
if (newFocus !== null) {
|
|
433
|
+
this.setKeyboardIndex(newFocus);
|
|
434
|
+
} else {
|
|
435
|
+
this.closeMenu();
|
|
436
|
+
|
|
437
|
+
if (this.oldFocus instanceof HTMLElement) {
|
|
438
|
+
this.oldFocus.focus();
|
|
527
439
|
}
|
|
528
440
|
}
|
|
441
|
+
|
|
442
|
+
e.preventDefault();
|
|
443
|
+
e.stopPropagation();
|
|
529
444
|
}
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
openSubMenu(index) {
|
|
448
|
+
var {
|
|
449
|
+
menuItems,
|
|
450
|
+
activeSubMenu
|
|
451
|
+
} = this.state;
|
|
452
|
+
var newSubMenu = menuItems[index].actions ? index : null;
|
|
453
|
+
if (activeSubMenu === newSubMenu) return;
|
|
454
|
+
this.setState({
|
|
455
|
+
activeSubMenu: newSubMenu,
|
|
456
|
+
subMenuTop: null,
|
|
457
|
+
subMenuLeft: null
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
closeMenu() {
|
|
462
|
+
var closeAll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
463
|
+
var {
|
|
464
|
+
closeMenu,
|
|
465
|
+
onMenuClosed
|
|
466
|
+
} = this.props;
|
|
467
|
+
cancelAnimationFrame(this.rAF);
|
|
468
|
+
this.rAF = window.requestAnimationFrame(() => {
|
|
469
|
+
closeMenu(closeAll);
|
|
470
|
+
onMenuClosed(this);
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
closeSubMenu() {
|
|
475
|
+
this.setState({
|
|
476
|
+
activeSubMenu: null
|
|
477
|
+
});
|
|
478
|
+
}
|
|
536
479
|
|
|
537
|
-
|
|
480
|
+
handleCloseSubMenu(closeAllMenus) {
|
|
481
|
+
if (closeAllMenus) {
|
|
482
|
+
this.closeMenu(true);
|
|
483
|
+
} else {
|
|
484
|
+
this.closeSubMenu();
|
|
538
485
|
}
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
handleMenuItemClick(menuItem, e) {
|
|
489
|
+
e.preventDefault();
|
|
490
|
+
e.stopPropagation();
|
|
491
|
+
var {
|
|
492
|
+
menuItems
|
|
493
|
+
} = this.state;
|
|
494
|
+
|
|
495
|
+
if (menuItem != null && !menuItem.disabled) {
|
|
496
|
+
if (menuItem.actions != null) {
|
|
497
|
+
this.openSubMenu(menuItems.indexOf(menuItem));
|
|
498
|
+
} else if (menuItem.action != null) {
|
|
499
|
+
menuItem.action();
|
|
500
|
+
this.closeMenu(true);
|
|
548
501
|
}
|
|
549
502
|
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
handleMenuItemContextMenu(menuItem, e) {
|
|
506
|
+
if (e.metaKey) {
|
|
507
|
+
return;
|
|
554
508
|
}
|
|
555
|
-
}, {
|
|
556
|
-
key: "render",
|
|
557
|
-
value: function render() {
|
|
558
|
-
var _this5 = this;
|
|
559
|
-
|
|
560
|
-
var menuItemElements = [];
|
|
561
|
-
var _this$props3 = this.props,
|
|
562
|
-
top = _this$props3.top,
|
|
563
|
-
left = _this$props3.left;
|
|
564
|
-
var _this$state2 = this.state,
|
|
565
|
-
activeSubMenu = _this$state2.activeSubMenu,
|
|
566
|
-
hasOverflow = _this$state2.hasOverflow,
|
|
567
|
-
keyboardIndex = _this$state2.keyboardIndex,
|
|
568
|
-
menuItems = _this$state2.menuItems,
|
|
569
|
-
mouseIndex = _this$state2.mouseIndex,
|
|
570
|
-
pendingItems = _this$state2.pendingItems,
|
|
571
|
-
subMenuTop = _this$state2.subMenuTop,
|
|
572
|
-
subMenuLeft = _this$state2.subMenuLeft,
|
|
573
|
-
subMenuParentWidth = _this$state2.subMenuParentWidth,
|
|
574
|
-
subMenuParentHeight = _this$state2.subMenuParentHeight;
|
|
575
|
-
|
|
576
|
-
for (var i = 0; i < menuItems.length; i += 1) {
|
|
577
|
-
var menuItem = menuItems[i];
|
|
578
|
-
|
|
579
|
-
if (i > 0 && menuItem.group !== menuItems[i - 1].group) {
|
|
580
|
-
menuItemElements.push( /*#__PURE__*/React.createElement("hr", {
|
|
581
|
-
key: "".concat(i, ".separator")
|
|
582
|
-
}));
|
|
583
|
-
}
|
|
584
509
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
ref: activeSubMenu === i ? this.activeSubMenuRef : null,
|
|
588
|
-
isKeyboardSelected: keyboardIndex === i,
|
|
589
|
-
isMouseSelected: mouseIndex === i,
|
|
590
|
-
menuItem: menuItem,
|
|
591
|
-
closeMenu: this.handleCloseSubMenu,
|
|
592
|
-
onMenuItemClick: this.handleMenuItemClick,
|
|
593
|
-
onMenuItemMouseMove: this.handleMenuItemMouseMove,
|
|
594
|
-
onMenuItemContextMenu: this.handleMenuItemContextMenu
|
|
595
|
-
});
|
|
596
|
-
menuItemElements.push(menuItemElement);
|
|
597
|
-
}
|
|
510
|
+
this.handleMenuItemClick(menuItem, e);
|
|
511
|
+
}
|
|
598
512
|
|
|
599
|
-
|
|
513
|
+
handleMenuItemMouseMove(menuItem) {
|
|
514
|
+
var {
|
|
515
|
+
menuItems
|
|
516
|
+
} = this.state;
|
|
517
|
+
var focusIndex = menuItems.indexOf(menuItem);
|
|
518
|
+
this.setMouseIndex(focusIndex);
|
|
600
519
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
520
|
+
if (focusIndex >= 0 && focusIndex < menuItems.length && !menuItem.disabled) {
|
|
521
|
+
this.openSubMenu(focusIndex);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
handleMouseLeave() {
|
|
526
|
+
this.setMouseIndex(-1);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
render() {
|
|
530
|
+
var menuItemElements = [];
|
|
531
|
+
var {
|
|
532
|
+
top,
|
|
533
|
+
left
|
|
534
|
+
} = this.props;
|
|
535
|
+
var {
|
|
536
|
+
activeSubMenu,
|
|
537
|
+
hasOverflow,
|
|
538
|
+
keyboardIndex,
|
|
539
|
+
menuItems,
|
|
540
|
+
mouseIndex,
|
|
541
|
+
pendingItems,
|
|
542
|
+
subMenuTop,
|
|
543
|
+
subMenuLeft,
|
|
544
|
+
subMenuParentWidth,
|
|
545
|
+
subMenuParentHeight
|
|
546
|
+
} = this.state;
|
|
547
|
+
|
|
548
|
+
for (var i = 0; i < menuItems.length; i += 1) {
|
|
549
|
+
var menuItem = menuItems[i];
|
|
550
|
+
|
|
551
|
+
if (i > 0 && menuItem.group !== menuItems[i - 1].group) {
|
|
552
|
+
menuItemElements.push( /*#__PURE__*/React.createElement("hr", {
|
|
553
|
+
key: "".concat(i, ".separator")
|
|
554
|
+
}));
|
|
605
555
|
}
|
|
606
556
|
|
|
607
|
-
var
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
}, 'context-menu-container'),
|
|
614
|
-
style: _objectSpread({
|
|
615
|
-
top: top,
|
|
616
|
-
left: left
|
|
617
|
-
}, menuStyle),
|
|
618
|
-
ref: this.container,
|
|
619
|
-
"data-dh-context-menu": true,
|
|
620
|
-
onBlur: this.handleBlur,
|
|
621
|
-
onKeyDown: this.handleKeyDown,
|
|
622
|
-
onMouseLeave: this.handleMouseLeave,
|
|
623
|
-
onContextMenu: ContextMenu.handleContextMenu,
|
|
624
|
-
role: "menuitem",
|
|
625
|
-
tabIndex: 0
|
|
626
|
-
}, menuItemElements, pendingElement), showSubmenu && activeSubMenu !== null && subMenuTop !== null && subMenuLeft !== null && /*#__PURE__*/React.createElement(ContextMenu, {
|
|
627
|
-
key: "sub-".concat(activeSubMenu),
|
|
628
|
-
actions: menuItems[activeSubMenu].actions || [],
|
|
557
|
+
var menuItemElement = /*#__PURE__*/React.createElement(ContextMenuItem, {
|
|
558
|
+
key: i,
|
|
559
|
+
ref: activeSubMenu === i ? this.activeSubMenuRef : null,
|
|
560
|
+
isKeyboardSelected: keyboardIndex === i,
|
|
561
|
+
isMouseSelected: mouseIndex === i,
|
|
562
|
+
menuItem: menuItem,
|
|
629
563
|
closeMenu: this.handleCloseSubMenu,
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
subMenuLeft: verifiedLeft
|
|
636
|
-
});
|
|
637
|
-
},
|
|
638
|
-
subMenuParentWidth: subMenuParentWidth,
|
|
639
|
-
subMenuParentHeight: subMenuParentHeight
|
|
640
|
-
}));
|
|
564
|
+
onMenuItemClick: this.handleMenuItemClick,
|
|
565
|
+
onMenuItemMouseMove: this.handleMenuItemMouseMove,
|
|
566
|
+
onMenuItemContextMenu: this.handleMenuItemContextMenu
|
|
567
|
+
});
|
|
568
|
+
menuItemElements.push(menuItemElement);
|
|
641
569
|
}
|
|
642
|
-
}], [{
|
|
643
|
-
key: "handleContextMenu",
|
|
644
|
-
value: function handleContextMenu(e) {
|
|
645
|
-
if (e.metaKey) {
|
|
646
|
-
return;
|
|
647
|
-
}
|
|
648
570
|
|
|
649
|
-
|
|
650
|
-
|
|
571
|
+
var pendingElement = null;
|
|
572
|
+
|
|
573
|
+
if (pendingItems.length > 0) {
|
|
574
|
+
pendingElement = /*#__PURE__*/React.createElement("div", {
|
|
575
|
+
className: "loading"
|
|
576
|
+
}, /*#__PURE__*/React.createElement(LoadingSpinner, null));
|
|
651
577
|
}
|
|
652
|
-
}]);
|
|
653
578
|
|
|
654
|
-
|
|
655
|
-
|
|
579
|
+
var {
|
|
580
|
+
menuStyle
|
|
581
|
+
} = this.props; // don't show submenu until it has an position initialized
|
|
582
|
+
|
|
583
|
+
var showSubmenu = activeSubMenu !== null && subMenuTop !== null && subMenuLeft !== null;
|
|
584
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
585
|
+
className: classNames({
|
|
586
|
+
'has-overflow': hasOverflow
|
|
587
|
+
}, 'context-menu-container'),
|
|
588
|
+
style: _objectSpread({
|
|
589
|
+
top,
|
|
590
|
+
left
|
|
591
|
+
}, menuStyle),
|
|
592
|
+
ref: this.container,
|
|
593
|
+
"data-dh-context-menu": true,
|
|
594
|
+
onBlur: this.handleBlur,
|
|
595
|
+
onKeyDown: this.handleKeyDown,
|
|
596
|
+
onMouseLeave: this.handleMouseLeave,
|
|
597
|
+
onContextMenu: ContextMenu.handleContextMenu,
|
|
598
|
+
role: "menuitem",
|
|
599
|
+
tabIndex: 0
|
|
600
|
+
}, menuItemElements, pendingElement), showSubmenu && activeSubMenu !== null && subMenuTop !== null && subMenuLeft !== null && /*#__PURE__*/React.createElement(ContextMenu, {
|
|
601
|
+
key: "sub-".concat(activeSubMenu),
|
|
602
|
+
actions: menuItems[activeSubMenu].actions || [],
|
|
603
|
+
closeMenu: this.handleCloseSubMenu,
|
|
604
|
+
top: subMenuTop,
|
|
605
|
+
left: subMenuLeft,
|
|
606
|
+
updatePosition: (verifiedTop, verifiedLeft) => {
|
|
607
|
+
this.setState({
|
|
608
|
+
subMenuTop: verifiedTop,
|
|
609
|
+
subMenuLeft: verifiedLeft
|
|
610
|
+
});
|
|
611
|
+
},
|
|
612
|
+
subMenuParentWidth: subMenuParentWidth,
|
|
613
|
+
subMenuParentHeight: subMenuParentHeight
|
|
614
|
+
}));
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
}
|
|
656
618
|
|
|
657
619
|
_defineProperty(ContextMenu, "defaultProps", {
|
|
658
620
|
subMenuParentWidth: 0,
|
|
659
621
|
subMenuParentHeight: 0,
|
|
660
|
-
|
|
622
|
+
|
|
623
|
+
closeMenu() {// no-op
|
|
661
624
|
},
|
|
662
|
-
|
|
625
|
+
|
|
626
|
+
onMenuOpened() {// no-op
|
|
663
627
|
},
|
|
664
|
-
|
|
628
|
+
|
|
629
|
+
onMenuClosed() {// no-op
|
|
665
630
|
},
|
|
631
|
+
|
|
666
632
|
options: {},
|
|
667
633
|
menuStyle: {}
|
|
668
634
|
});
|