UNPKG

5.46 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 } from "tslib";
17import classNames from "classnames";
18import * as React from "react";
19import * as ReactDOM from "react-dom";
20import { Classes } from "../../common";
21import { Dialog } from "../../components";
22import { Hotkey } from "./hotkey";
23import { Hotkeys } from "./hotkeys";
24/**
25 * The delay before showing or hiding the dialog. Should be long enough to
26 * allow all registered hotkey listeners to execute first.
27 */
28var DELAY_IN_MS = 10;
29var HotkeysDialog = /** @class */ (function () {
30 function HotkeysDialog() {
31 var _this = this;
32 this.componentProps = {
33 globalHotkeysGroup: "Global hotkeys",
34 };
35 this.container = null;
36 this.hotkeysQueue = [];
37 this.isDialogShowing = false;
38 this.show = function () {
39 _this.isDialogShowing = true;
40 _this.render();
41 };
42 this.hide = function () {
43 _this.isDialogShowing = false;
44 _this.render();
45 };
46 }
47 HotkeysDialog.prototype.render = function () {
48 if (this.container == null) {
49 this.container = this.getContainer();
50 }
51 ReactDOM.render(this.renderComponent(), this.container);
52 };
53 HotkeysDialog.prototype.unmount = function () {
54 if (this.container != null) {
55 ReactDOM.unmountComponentAtNode(this.container);
56 this.container.remove();
57 this.container = null;
58 }
59 };
60 /**
61 * Because hotkeys can be registered globally and locally and because
62 * event ordering cannot be guaranteed, we use this debouncing method to
63 * allow all hotkey listeners to fire and add their hotkeys to the dialog.
64 *
65 * 10msec after the last listener adds their hotkeys, we render the dialog
66 * and clear the queue.
67 */
68 HotkeysDialog.prototype.enqueueHotkeysForDisplay = function (hotkeys) {
69 this.hotkeysQueue.push(hotkeys);
70 // reset timeout for debounce
71 window.clearTimeout(this.showTimeoutToken);
72 this.showTimeoutToken = window.setTimeout(this.show, DELAY_IN_MS);
73 };
74 HotkeysDialog.prototype.hideAfterDelay = function () {
75 window.clearTimeout(this.hideTimeoutToken);
76 this.hideTimeoutToken = window.setTimeout(this.hide, DELAY_IN_MS);
77 };
78 HotkeysDialog.prototype.isShowing = function () {
79 return this.isDialogShowing;
80 };
81 HotkeysDialog.prototype.getContainer = function () {
82 if (this.container == null) {
83 this.container = document.createElement("div");
84 this.container.classList.add(Classes.PORTAL);
85 document.body.appendChild(this.container);
86 }
87 return this.container;
88 };
89 HotkeysDialog.prototype.renderComponent = function () {
90 return (React.createElement(Dialog, __assign({}, this.componentProps, { className: classNames(Classes.HOTKEY_DIALOG, this.componentProps.className), isOpen: this.isDialogShowing, onClose: this.hide }),
91 React.createElement("div", { className: Classes.DIALOG_BODY }, this.renderHotkeys())));
92 };
93 HotkeysDialog.prototype.renderHotkeys = function () {
94 var _this = this;
95 var hotkeys = this.emptyHotkeyQueue();
96 var elements = hotkeys.map(function (hotkey, index) {
97 var group = hotkey.global === true && hotkey.group == null ? _this.componentProps.globalHotkeysGroup : hotkey.group;
98 return React.createElement(Hotkey, __assign({ key: index }, hotkey, { group: group }));
99 });
100 return React.createElement(Hotkeys, null, elements);
101 };
102 HotkeysDialog.prototype.emptyHotkeyQueue = function () {
103 // flatten then empty the hotkeys queue
104 var hotkeys = this.hotkeysQueue.reduce(function (arr, queued) { return arr.concat(queued); }, []);
105 this.hotkeysQueue.length = 0;
106 return hotkeys;
107 };
108 return HotkeysDialog;
109}());
110// singleton instance
111var HOTKEYS_DIALOG = new HotkeysDialog();
112export function isHotkeysDialogShowing() {
113 return HOTKEYS_DIALOG.isShowing();
114}
115export function setHotkeysDialogProps(props) {
116 for (var key in props) {
117 if (props.hasOwnProperty(key)) {
118 HOTKEYS_DIALOG.componentProps[key] = props[key];
119 }
120 }
121}
122export function showHotkeysDialog(hotkeys) {
123 HOTKEYS_DIALOG.enqueueHotkeysForDisplay(hotkeys);
124}
125export function hideHotkeysDialog() {
126 HOTKEYS_DIALOG.hide();
127}
128/**
129 * Use this function instead of `hideHotkeysDialog` if you need to ensure that all hotkey listeners
130 * have time to execute with the dialog in a consistent open state. This can avoid flickering the
131 * dialog between open and closed states as successive listeners fire.
132 */
133export function hideHotkeysDialogAfterDelay() {
134 HOTKEYS_DIALOG.hideAfterDelay();
135}
136//# sourceMappingURL=hotkeysDialog.js.map
\No newline at end of file