UNPKG

6.75 kBJavaScriptView Raw
1/*
2 * Copyright 2016 Palantir Technologies, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import { __assign, __extends, __rest } from "tslib";
17/**
18 * @fileoverview This component is DEPRECATED, and the code is frozen.
19 * All changes & bugfixes should be made to ContextMenu2 instead.
20 */
21import classNames from "classnames";
22import * as React from "react";
23import * as ReactDOM from "react-dom";
24import { AbstractPureComponent2, Classes, Position } from "../../common";
25import { Popover } from "../popover/popover";
26var POPPER_MODIFIERS = {
27 preventOverflow: { boundariesElement: "viewport" },
28};
29var TRANSITION_DURATION = 100;
30/* istanbul ignore next */
31/**
32 * ContextMenu component.
33 *
34 * @see https://blueprintjs.com/docs/#core/components/context-menu
35 * @deprecated use ContextMenu2
36 */
37var ContextMenu = /** @class */ (function (_super) {
38 __extends(ContextMenu, _super);
39 function ContextMenu() {
40 var _this = _super !== null && _super.apply(this, arguments) || this;
41 _this.state = {
42 isDarkTheme: false,
43 isOpen: false,
44 };
45 _this.cancelContextMenu = function (e) { return e.preventDefault(); };
46 _this.handleBackdropContextMenu = function (e) {
47 // React function to remove from the event pool, useful when using a event within a callback
48 e.persist();
49 e.preventDefault();
50 // wait for backdrop to disappear so we can find the "real" element at event coordinates.
51 // timeout duration is equivalent to transition duration so we know it's animated out.
52 _this.setTimeout(function () {
53 // retrigger context menu event at the element beneath the backdrop.
54 // if it has a `contextmenu` event handler then it'll be invoked.
55 // if it doesn't, no native menu will show (at least on OSX) :(
56 var newTarget = document.elementFromPoint(e.clientX, e.clientY);
57 var view = e.view, newEventInit = __rest(e, ["view"]);
58 newTarget === null || newTarget === void 0 ? void 0 : newTarget.dispatchEvent(new MouseEvent("contextmenu", newEventInit));
59 }, TRANSITION_DURATION);
60 };
61 _this.handlePopoverInteraction = function (nextOpenState) {
62 if (!nextOpenState) {
63 // delay the actual hiding till the event queue clears
64 // to avoid flicker of opening twice
65 _this.requestAnimationFrame(function () { return _this.hide(); });
66 }
67 };
68 return _this;
69 }
70 ContextMenu.prototype.render = function () {
71 var _a;
72 // prevent right-clicking in a context menu
73 var content = React.createElement("div", { onContextMenu: this.cancelContextMenu }, this.state.menu);
74 var popoverClassName = classNames((_a = {}, _a[Classes.DARK] = this.state.isDarkTheme, _a));
75 // HACKHACK: workaround until we have access to Popper#scheduleUpdate().
76 // https://github.com/palantir/blueprint/issues/692
77 // Generate key based on offset so a new Popover instance is created
78 // when offset changes, to force recomputing position.
79 var key = this.state.offset === undefined ? "" : "".concat(this.state.offset.left, "x").concat(this.state.offset.top);
80 // wrap the popover in a positioned div to make sure it is properly
81 // offset on the screen.
82 /* eslint-disable deprecation/deprecation */
83 return (React.createElement("div", { className: Classes.CONTEXT_MENU_POPOVER_TARGET, style: this.state.offset },
84 React.createElement(Popover, __assign({}, this.props, { backdropProps: { onContextMenu: this.handleBackdropContextMenu }, content: content, enforceFocus: false, key: key, hasBackdrop: true, isOpen: this.state.isOpen, minimal: true, modifiers: POPPER_MODIFIERS, onInteraction: this.handlePopoverInteraction, position: Position.RIGHT_TOP, popoverClassName: popoverClassName, target: React.createElement("div", null), transitionDuration: TRANSITION_DURATION }))));
85 /* eslint-enable deprecation/deprecation */
86 };
87 ContextMenu.prototype.show = function (menu, offset, onClose, isDarkTheme) {
88 if (isDarkTheme === void 0) { isDarkTheme = false; }
89 this.setState({ isOpen: true, menu: menu, offset: offset, onClose: onClose, isDarkTheme: isDarkTheme });
90 };
91 ContextMenu.prototype.hide = function () {
92 var _a, _b;
93 (_b = (_a = this.state).onClose) === null || _b === void 0 ? void 0 : _b.call(_a);
94 this.setState({ isOpen: false, onClose: undefined });
95 };
96 return ContextMenu;
97}(AbstractPureComponent2));
98var contextMenuElement;
99// eslint-disable-next-line deprecation/deprecation
100var contextMenu;
101/**
102 * Show the given menu element at the given offset from the top-left corner of the viewport.
103 * The menu will appear below-right of this point and will flip to below-left if there is not enough
104 * room onscreen. The optional callback will be invoked when this menu closes.
105 *
106 * @deprecated use ContextMenu2
107 */
108export function show(menu, offset, onClose, isDarkTheme) {
109 if (contextMenuElement === undefined) {
110 contextMenuElement = document.createElement("div");
111 contextMenuElement.classList.add(Classes.CONTEXT_MENU);
112 document.body.appendChild(contextMenuElement);
113 /* eslint-disable deprecation/deprecation */
114 contextMenu = ReactDOM.render(React.createElement(ContextMenu, { onClosed: remove }), contextMenuElement);
115 /* eslint-enable deprecation/deprecation */
116 }
117 contextMenu.show(menu, offset, onClose, isDarkTheme);
118}
119/** Hide the open context menu. */
120export function hide() {
121 contextMenu === null || contextMenu === void 0 ? void 0 : contextMenu.hide();
122}
123/** Return whether a context menu is currently open. */
124export function isOpen() {
125 return contextMenu != null && contextMenu.state.isOpen;
126}
127function remove() {
128 if (contextMenuElement != null) {
129 ReactDOM.unmountComponentAtNode(contextMenuElement);
130 contextMenuElement.remove();
131 contextMenuElement = undefined;
132 contextMenu = undefined;
133 }
134}
135//# sourceMappingURL=contextMenu.js.map
\No newline at end of file