@deephaven/components 0.5.2-beta.0 → 0.6.1-demo.10

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.
Files changed (119) hide show
  1. package/dist/AutoCompleteInput.js +410 -448
  2. package/dist/AutoCompleteInput.js.map +1 -1
  3. package/dist/AutoResizeTextarea.js +17 -46
  4. package/dist/AutoResizeTextarea.js.map +1 -1
  5. package/dist/BasicModal.js +18 -19
  6. package/dist/BasicModal.js.map +1 -1
  7. package/dist/Button.js +30 -21
  8. package/dist/Button.js.map +1 -1
  9. package/dist/ButtonGroup.js +6 -4
  10. package/dist/ButtonGroup.js.map +1 -1
  11. package/dist/ButtonOld.js +10 -8
  12. package/dist/ButtonOld.js.map +1 -1
  13. package/dist/CardFlip.js +10 -8
  14. package/dist/CardFlip.js.map +1 -1
  15. package/dist/Checkbox.js +18 -31
  16. package/dist/Checkbox.js.map +1 -1
  17. package/dist/Collapse.js +65 -105
  18. package/dist/Collapse.js.map +1 -1
  19. package/dist/ComboBox.js +432 -460
  20. package/dist/ComboBox.js.map +1 -1
  21. package/dist/CustomTimeSelect.js +485 -517
  22. package/dist/CustomTimeSelect.js.map +1 -1
  23. package/dist/DebouncedSearchInput.js +61 -91
  24. package/dist/DebouncedSearchInput.js.map +1 -1
  25. package/dist/DeephavenSpinner.js +6 -6
  26. package/dist/DeephavenSpinner.js.map +1 -1
  27. package/dist/DragUtils.js +65 -113
  28. package/dist/DragUtils.js.map +1 -1
  29. package/dist/DraggableItemList.d.ts +1 -0
  30. package/dist/DraggableItemList.d.ts.map +1 -1
  31. package/dist/DraggableItemList.js +219 -257
  32. package/dist/DraggableItemList.js.map +1 -1
  33. package/dist/HierarchicalCheckboxMenu.js +160 -227
  34. package/dist/HierarchicalCheckboxMenu.js.map +1 -1
  35. package/dist/ItemList.d.ts +4 -2
  36. package/dist/ItemList.d.ts.map +1 -1
  37. package/dist/ItemList.js +595 -598
  38. package/dist/ItemList.js.map +1 -1
  39. package/dist/ItemListItem.js +194 -215
  40. package/dist/ItemListItem.js.map +1 -1
  41. package/dist/LoadingOverlay.js +9 -10
  42. package/dist/LoadingOverlay.js.map +1 -1
  43. package/dist/LoadingSpinner.js +4 -3
  44. package/dist/LoadingSpinner.js.map +1 -1
  45. package/dist/MaskedInput.js +59 -70
  46. package/dist/MaskedInput.js.map +1 -1
  47. package/dist/Option.js +5 -3
  48. package/dist/Option.js.map +1 -1
  49. package/dist/RadioGroup.js +16 -34
  50. package/dist/RadioGroup.js.map +1 -1
  51. package/dist/RadioItem.js +14 -33
  52. package/dist/RadioItem.js.map +1 -1
  53. package/dist/SearchInput.js +42 -75
  54. package/dist/SearchInput.js.map +1 -1
  55. package/dist/Select.js +10 -8
  56. package/dist/Select.js.map +1 -1
  57. package/dist/SelectValueList.js +97 -134
  58. package/dist/SelectValueList.js.map +1 -1
  59. package/dist/SocketedButton.js +13 -11
  60. package/dist/SocketedButton.js.map +1 -1
  61. package/dist/ThemeExport.js.map +1 -1
  62. package/dist/TimeInput.js +16 -53
  63. package/dist/TimeInput.js.map +1 -1
  64. package/dist/TimeSlider.js +62 -88
  65. package/dist/TimeSlider.js.map +1 -1
  66. package/dist/ToastNotification.js +14 -13
  67. package/dist/ToastNotification.js.map +1 -1
  68. package/dist/UISwitch.js +9 -8
  69. package/dist/UISwitch.js.map +1 -1
  70. package/dist/context-actions/ContextActionUtils.js +173 -231
  71. package/dist/context-actions/ContextActionUtils.js.map +1 -1
  72. package/dist/context-actions/ContextActions.js +135 -177
  73. package/dist/context-actions/ContextActions.js.map +1 -1
  74. package/dist/context-actions/ContextMenu.js +509 -543
  75. package/dist/context-actions/ContextMenu.js.map +1 -1
  76. package/dist/context-actions/ContextMenuItem.js +32 -22
  77. package/dist/context-actions/ContextMenuItem.js.map +1 -1
  78. package/dist/context-actions/ContextMenuRoot.js +112 -152
  79. package/dist/context-actions/ContextMenuRoot.js.map +1 -1
  80. package/dist/context-actions/GlobalContextAction.js +49 -84
  81. package/dist/context-actions/GlobalContextAction.js.map +1 -1
  82. package/dist/context-actions/GlobalContextActions.js +25 -57
  83. package/dist/context-actions/GlobalContextActions.js.map +1 -1
  84. package/dist/context-actions/index.js +4 -4
  85. package/dist/context-actions/index.js.map +1 -1
  86. package/dist/index.js +39 -39
  87. package/dist/index.js.map +1 -1
  88. package/dist/menu-actions/DropdownMenu.js +126 -159
  89. package/dist/menu-actions/DropdownMenu.js.map +1 -1
  90. package/dist/menu-actions/Menu.js +215 -245
  91. package/dist/menu-actions/Menu.js.map +1 -1
  92. package/dist/menu-actions/index.js +1 -1
  93. package/dist/menu-actions/index.js.map +1 -1
  94. package/dist/navigation/Menu.js +14 -18
  95. package/dist/navigation/Menu.js.map +1 -1
  96. package/dist/navigation/MenuItem.js +15 -14
  97. package/dist/navigation/MenuItem.js.map +1 -1
  98. package/dist/navigation/Page.js +7 -5
  99. package/dist/navigation/Page.js.map +1 -1
  100. package/dist/navigation/Stack.js +14 -39
  101. package/dist/navigation/Stack.js.map +1 -1
  102. package/dist/navigation/index.js +4 -4
  103. package/dist/navigation/index.js.map +1 -1
  104. package/dist/popper/Popper.js +209 -235
  105. package/dist/popper/Popper.js.map +1 -1
  106. package/dist/popper/Tooltip.js +227 -257
  107. package/dist/popper/Tooltip.js.map +1 -1
  108. package/dist/popper/index.js +2 -2
  109. package/dist/popper/index.js.map +1 -1
  110. package/dist/shortcuts/GlobalShortcuts.js +2 -2
  111. package/dist/shortcuts/GlobalShortcuts.js.map +1 -1
  112. package/dist/shortcuts/Shortcut.js +263 -291
  113. package/dist/shortcuts/Shortcut.js.map +1 -1
  114. package/dist/shortcuts/ShortcutRegistry.js +48 -71
  115. package/dist/shortcuts/ShortcutRegistry.js.map +1 -1
  116. package/dist/shortcuts/index.js +4 -4
  117. package/dist/shortcuts/index.js.map +1 -1
  118. package/dist/tsconfig.tsbuildinfo +1 -1
  119. 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 './ContextActionUtils';
34
- import ContextMenuItem from './ContextMenuItem';
35
- import LoadingSpinner from '../LoadingSpinner';
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
- var ContextMenu = /*#__PURE__*/function (_PureComponent) {
40
- _inherits(ContextMenu, _PureComponent);
41
-
42
- var _super = _createSuper(ContextMenu);
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
- _classCallCheck(this, ContextMenu);
23
+ e.stopPropagation();
24
+ e.preventDefault();
25
+ }
48
26
 
49
- _this = _super.call(this, props);
27
+ constructor(props) {
28
+ super(props);
50
29
 
51
- _defineProperty(_assertThisInitialized(_this), "container", void 0);
30
+ _defineProperty(this, "container", void 0);
52
31
 
53
- _defineProperty(_assertThisInitialized(_this), "oldFocus", void 0);
32
+ _defineProperty(this, "oldFocus", void 0);
54
33
 
55
- _defineProperty(_assertThisInitialized(_this), "activeSubMenuRef", void 0);
34
+ _defineProperty(this, "activeSubMenuRef", void 0);
56
35
 
57
- _defineProperty(_assertThisInitialized(_this), "subMenuTimer", void 0);
36
+ _defineProperty(this, "subMenuTimer", void 0);
58
37
 
59
- _defineProperty(_assertThisInitialized(_this), "rAF", void 0);
38
+ _defineProperty(this, "rAF", void 0);
60
39
 
61
- _defineProperty(_assertThisInitialized(_this), "initialPosition", void 0);
40
+ _defineProperty(this, "initialPosition", void 0);
62
41
 
63
- _this.handleBlur = _this.handleBlur.bind(_assertThisInitialized(_this));
64
- _this.handleCloseSubMenu = _this.handleCloseSubMenu.bind(_assertThisInitialized(_this));
65
- _this.handleKeyDown = _this.handleKeyDown.bind(_assertThisInitialized(_this));
66
- _this.handleMenuItemClick = _this.handleMenuItemClick.bind(_assertThisInitialized(_this));
67
- _this.handleMenuItemContextMenu = _this.handleMenuItemContextMenu.bind(_assertThisInitialized(_this));
68
- _this.handleMenuItemMouseMove = _this.handleMenuItemMouseMove.bind(_assertThisInitialized(_this));
69
- _this.handleMouseLeave = _this.handleMouseLeave.bind(_assertThisInitialized(_this));
70
- _this.handleWindowResize = _this.handleWindowResize.bind(_assertThisInitialized(_this));
71
- _this.container = /*#__PURE__*/React.createRef();
72
- _this.oldFocus = document.activeElement;
73
- _this.activeSubMenuRef = /*#__PURE__*/React.createRef();
74
- _this.subMenuTimer = 0;
75
- _this.rAF = 0;
76
- _this.initialPosition = {
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
- _this.state = {
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
- _createClass(ContextMenu, [{
96
- key: "componentDidMount",
97
- value: function componentDidMount() {
98
- var _this2 = this;
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
- this.initMenu();
101
- this.verifyPosition();
102
- window.addEventListener('resize', this.handleWindowResize); // rAF is needed to wait for a submenus popper to be created before
103
- // attempting to set focus, however on a quick mount/unmount when
104
- // mousing past an item, the submenu could be unmounted before the
105
- // async rAF finishes, so it is cancelled in willUnmount()
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
- if (prevProps.actions !== actions) {
100
+ if (activeSubMenu !== prevState.activeSubMenu) {
101
+ if (activeSubMenu == null) {
134
102
  var _this$container$curre2;
135
103
 
136
- this.initMenu();
137
-
138
- if (!((_this$container$curre2 = this.container.current) !== null && _this$container$curre2 !== void 0 && _this$container$curre2.contains(document.activeElement))) {
139
- var _this$container$curre3;
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
- return this.getMouseIndex();
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
- if (options.separateKeyboardMouse) {
172
- this.setState({
173
- keyboardIndex: index
174
- });
175
- } else {
176
- this.setMouseIndex(index);
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
- var actions = this.props.actions;
206
- var menuItems = ContextActionUtils.getMenuItems(actions);
207
- var nonPromiseItems = [];
124
+ this.verifyPosition();
125
+ }
208
126
 
209
- for (var i = menuItems.length - 1; i >= 0; i -= 1) {
210
- var menuItem = menuItems[i];
127
+ componentWillUnmount() {
128
+ this.cancelPromises();
129
+ window.removeEventListener('resize', this.handleWindowResize);
130
+ cancelAnimationFrame(this.rAF);
131
+ }
211
132
 
212
- if (menuItem instanceof Promise) {
213
- this.initMenuPromise(menuItem);
214
- } else {
215
- nonPromiseItems.push(menuItem);
216
- }
217
- }
133
+ getKeyboardIndex() {
134
+ var {
135
+ options
136
+ } = this.props;
218
137
 
219
- this.setState({
220
- mouseIndex: -1,
221
- keyboardIndex: keyboardIndex,
222
- activeSubMenu: null,
223
- menuItems: ContextActionUtils.sortActions(nonPromiseItems)
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
- if (index >= 0) {
243
- var pendingItems = state.pendingItems.slice();
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
- return null;
253
- });
254
- }, function (error) {
255
- if (PromiseUtils.isCanceled(error)) {
256
- return; // Canceled promise is ignored
257
- } // remove failed item from pending list
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
- _this3.setState(function (state) {
261
- var index = state.pendingItems.indexOf(cancellablePromise);
169
+ setMouseIndex(index) {
170
+ this.setState({
171
+ mouseIndex: index
172
+ });
173
+ }
262
174
 
263
- if (index >= 0) {
264
- var pendingItems = state.pendingItems.slice();
265
- pendingItems.splice(index, 1);
266
- return {
267
- pendingItems: pendingItems
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
- return null;
272
- }); // Log the error
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
- log.error(error);
276
- });
277
- }
278
- }, {
279
- key: "cancelPromises",
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
- key: "setActiveSubMenuPosition",
293
- value: function setActiveSubMenuPosition() {
294
- if (this.activeSubMenuRef.current === null) return;
295
- var parentRect = this.activeSubMenuRef.current.getBoundingClientRect(); // intentionally rect.right, we want the sub menu to start at the right edge of the current menu
204
+ this.setState({
205
+ mouseIndex: -1,
206
+ keyboardIndex,
207
+ activeSubMenu: null,
208
+ menuItems: ContextActionUtils.sortActions(nonPromiseItems)
209
+ });
210
+ }
296
211
 
297
- this.setState({
298
- subMenuTop: parentRect.top,
299
- subMenuLeft: parentRect.right,
300
- subMenuParentHeight: parentRect.height,
301
- subMenuParentWidth: parentRect.width
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
- * Verifies the position of this menu in relation to the parent to make sure it's on screen.
306
- * Will update the top left state (updatePosition) if necessary (causing a re-render)
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
- if (top + height > window.innerHeight) {
353
- // can it be flipped to above? include offset if submenu (defaults to 0 if not submenu)
354
- if (top - height - subMenuParentHeight > 0) {
355
- // flip like a native menu would
356
- top -= height - subMenuParentHeight;
357
- } else {
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
- if (left + width > window.innerWidth) {
364
- // less picky about left right positioning, just keep it going off to right
365
- left = left - width - subMenuParentWidth;
366
- }
251
+ return null;
252
+ }); // Log the error
367
253
 
368
- if (oldLeft !== left || oldTop !== top) {
369
- // parent owns positioning as single source of truth, ask to update props
370
- this.setState({
371
- hasOverflow: hasOverflow
372
- });
373
- updatePosition(top, left);
374
- }
375
- } // since window resize doesn't trigger blur, listen and close the menu
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
- key: "handleWindowResize",
379
- value: function handleWindowResize() {
380
- if (!this.container.current) {
381
- return;
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
- this.closeMenu(true);
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
- if (!this.container.current.contains(e.relatedTarget)) {
395
- var element = e.relatedTarget;
396
- var isContextMenuChild = false;
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
- if (!isContextMenuChild) {
404
- // close all submenus on blur
405
- this.closeMenu(true);
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
- key: "isEscapeKey",
413
- value: function isEscapeKey(key) {
414
- var left = this.props.left;
415
- return key === 'Escape' || left < 0 && key === 'ArrowRight' || key === 'ArrowLeft';
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
- return;
431
- }
369
+ if (!this.container.current.contains(e.relatedTarget)) {
370
+ var element = e.relatedTarget;
371
+ var isContextMenuChild = false;
432
372
 
433
- if (e.key === 'ArrowRight') {
434
- if (oldFocus >= 0 && oldFocus <= menuItems.length) {
435
- openSubMenu = true;
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 (openSubMenu) {
448
- this.openSubMenu(oldFocus);
449
- e.preventDefault();
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
- if (this.oldFocus instanceof HTMLElement) {
461
- this.oldFocus.focus();
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
- e.preventDefault();
466
- e.stopPropagation();
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: "openSubMenu",
471
- value: function openSubMenu(index) {
472
- var _this$state = this.state,
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
- this.closeSubMenu();
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
- key: "handleMenuItemClick",
516
- value: function handleMenuItemClick(menuItem, e) {
423
+
424
+ if (openSubMenu) {
425
+ this.openSubMenu(oldFocus);
517
426
  e.preventDefault();
518
427
  e.stopPropagation();
519
- var menuItems = this.state.menuItems;
520
-
521
- if (menuItem != null && !menuItem.disabled) {
522
- if (menuItem.actions != null) {
523
- this.openSubMenu(menuItems.indexOf(menuItem));
524
- } else if (menuItem.action != null) {
525
- menuItem.action();
526
- this.closeMenu(true);
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
- key: "handleMenuItemContextMenu",
532
- value: function handleMenuItemContextMenu(menuItem, e) {
533
- if (e.metaKey) {
534
- return;
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
- this.handleMenuItemClick(menuItem, e);
480
+ handleCloseSubMenu(closeAllMenus) {
481
+ if (closeAllMenus) {
482
+ this.closeMenu(true);
483
+ } else {
484
+ this.closeSubMenu();
538
485
  }
539
- }, {
540
- key: "handleMenuItemMouseMove",
541
- value: function handleMenuItemMouseMove(menuItem) {
542
- var menuItems = this.state.menuItems;
543
- var focusIndex = menuItems.indexOf(menuItem);
544
- this.setMouseIndex(focusIndex);
545
-
546
- if (focusIndex >= 0 && focusIndex < menuItems.length && !menuItem.disabled) {
547
- this.openSubMenu(focusIndex);
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
- key: "handleMouseLeave",
552
- value: function handleMouseLeave() {
553
- this.setMouseIndex(-1);
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
- var menuItemElement = /*#__PURE__*/React.createElement(ContextMenuItem, {
586
- key: i,
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
- var pendingElement = null;
513
+ handleMenuItemMouseMove(menuItem) {
514
+ var {
515
+ menuItems
516
+ } = this.state;
517
+ var focusIndex = menuItems.indexOf(menuItem);
518
+ this.setMouseIndex(focusIndex);
600
519
 
601
- if (pendingItems.length > 0) {
602
- pendingElement = /*#__PURE__*/React.createElement("div", {
603
- className: "loading"
604
- }, /*#__PURE__*/React.createElement(LoadingSpinner, null));
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 menuStyle = this.props.menuStyle; // don't show submenu until it has an position initialized
608
-
609
- var showSubmenu = activeSubMenu !== null && subMenuTop !== null && subMenuLeft !== null;
610
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
611
- className: classNames({
612
- 'has-overflow': hasOverflow
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
- top: subMenuTop,
631
- left: subMenuLeft,
632
- updatePosition: function updatePosition(verifiedTop, verifiedLeft) {
633
- _this5.setState({
634
- subMenuTop: verifiedTop,
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
- e.stopPropagation();
650
- e.preventDefault();
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
- return ContextMenu;
655
- }(PureComponent);
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
- closeMenu: function closeMenu() {// no-op
622
+
623
+ closeMenu() {// no-op
661
624
  },
662
- onMenuOpened: function onMenuOpened() {// no-op
625
+
626
+ onMenuOpened() {// no-op
663
627
  },
664
- onMenuClosed: function onMenuClosed() {// no-op
628
+
629
+ onMenuClosed() {// no-op
665
630
  },
631
+
666
632
  options: {},
667
633
  menuStyle: {}
668
634
  });