@blueprintjs/core
Version:
Core styles & components
94 lines (92 loc) • 4.54 kB
JavaScript
/*
* Copyright 2016 Palantir Technologies, Inc. All rights reserved.
* Licensed under the BSD-3 License as modified (the “License”); you may obtain a copy
* of the license at https://github.com/palantir/blueprint/blob/master/LICENSE
* and https://github.com/palantir/blueprint/blob/master/PATENTS
*/
;
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var React = require("react");
var ReactDOM = require("react-dom");
var abstractComponent_1 = require("../../common/abstractComponent");
var Classes = require("../../common/classes");
var position_1 = require("../../common/position");
var utils_1 = require("../../common/utils");
var popover_1 = require("../popover/popover");
var CONSTRAINTS = [{ attachment: "together", pin: true, to: "window" }];
var TRANSITION_DURATION = 100;
var ContextMenu = (function (_super) {
tslib_1.__extends(ContextMenu, _super);
function ContextMenu() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = {
isOpen: false,
};
_this.cancelContextMenu = function (e) { return e.preventDefault(); };
_this.handleBackdropContextMenu = function (e) {
// HACKHACK: React function to remove from the event pool (not sure why it's not in typings #66)
e.persist();
e.preventDefault();
// wait for backdrop to disappear so we can find the "real" element at event coordinates.
// timeout duration is equivalent to transition duration so we know it's animated out.
_this.setTimeout(function () {
// retrigger context menu event at the element beneath the backdrop.
// if it has a `contextmenu` event handler then it'll be invoked.
// if it doesn't, no native menu will show (at least on OSX) :(
var newTarget = document.elementFromPoint(e.clientX, e.clientY);
newTarget.dispatchEvent(new MouseEvent("contextmenu", e));
}, TRANSITION_DURATION);
};
_this.handlePopoverInteraction = function (nextOpenState) {
if (!nextOpenState) {
_this.hide();
}
};
return _this;
}
ContextMenu.prototype.render = function () {
// prevent right-clicking in a context menu
var content = React.createElement("div", { onContextMenu: this.cancelContextMenu }, this.state.menu);
return (React.createElement(popover_1.Popover, { backdropProps: { onContextMenu: this.handleBackdropContextMenu }, constraints: CONSTRAINTS, content: content, enforceFocus: false, isModal: true, isOpen: this.state.isOpen, onInteraction: this.handlePopoverInteraction, position: position_1.Position.RIGHT_TOP, popoverClassName: Classes.MINIMAL, useSmartArrowPositioning: false, transitionDuration: TRANSITION_DURATION },
React.createElement("div", { className: Classes.CONTEXT_MENU_POPOVER_TARGET, style: this.state.offset })));
};
ContextMenu.prototype.show = function (menu, offset, onClose) {
this.setState({ isOpen: true, menu: menu, offset: offset, onClose: onClose });
};
ContextMenu.prototype.hide = function () {
var onClose = this.state.onClose;
this.setState({ isOpen: false, onClose: null });
utils_1.safeInvoke(onClose);
};
return ContextMenu;
}(abstractComponent_1.AbstractComponent));
var contextMenu;
/**
* Show the given menu element at the given offset from the top-left corner of the viewport.
* The menu will appear below-right of this point and will flip to below-left if there is not enough
* room onscreen. The optional callback will be invoked when this menu closes.
*/
function show(menu, offset, onClose) {
if (contextMenu == null) {
var contextMenuElement = document.createElement("div");
contextMenuElement.classList.add(Classes.CONTEXT_MENU);
document.body.appendChild(contextMenuElement);
contextMenu = ReactDOM.render(React.createElement(ContextMenu, null), contextMenuElement);
}
contextMenu.show(menu, offset, onClose);
}
exports.show = show;
/** Hide the open context menu. */
function hide() {
if (contextMenu != null) {
contextMenu.hide();
}
}
exports.hide = hide;
/** Return whether a context menu is currently open. */
function isOpen() {
return contextMenu != null && contextMenu.state.isOpen;
}
exports.isOpen = isOpen;
//# sourceMappingURL=contextMenu.js.map