UNPKG

4.53 kBJavaScriptView Raw
1/* -----------------------------------------------------------------------------
2| Copyright (c) Jupyter Development Team.
3| Distributed under the terms of the Modified BSD License.
4|----------------------------------------------------------------------------*/
5import { searchIcon } from '@jupyterlab/ui-components';
6import { Panel, Widget } from '@lumino/widgets';
7/**
8 * Class name identifying the input group with search icon.
9 */
10const SEARCH_ICON_GROUP_CLASS = 'jp-SearchIconGroup';
11/**
12 * Wrap the command palette in a modal to make it more usable.
13 */
14export class ModalCommandPalette extends Panel {
15 constructor(options) {
16 super();
17 this.addClass('jp-ModalCommandPalette');
18 this.id = 'modal-command-palette';
19 this.palette = options.commandPalette;
20 this._commandPalette.commands.commandExecuted.connect(() => {
21 if (this.isAttached && this.isVisible) {
22 this.hideAndReset();
23 }
24 });
25 // required to properly receive blur and focus events;
26 // selection of items with mouse may not work without this.
27 this.node.tabIndex = 0;
28 }
29 get palette() {
30 return this._commandPalette;
31 }
32 set palette(value) {
33 this._commandPalette = value;
34 if (!this.searchIconGroup) {
35 this._commandPalette.inputNode.insertAdjacentElement('afterend', this.createSearchIconGroup());
36 }
37 this.addWidget(value);
38 this.hideAndReset();
39 }
40 attach() {
41 Widget.attach(this, document.body);
42 }
43 detach() {
44 Widget.detach(this);
45 }
46 /**
47 * Hide the modal command palette and reset its search.
48 */
49 hideAndReset() {
50 this.hide();
51 this._commandPalette.inputNode.value = '';
52 this._commandPalette.refresh();
53 }
54 /**
55 * Handle incoming events.
56 */
57 handleEvent(event) {
58 switch (event.type) {
59 case 'keydown':
60 this._evtKeydown(event);
61 break;
62 case 'blur': {
63 // if the focus shifted outside of this DOM element, hide and reset.
64 if (
65 // focus went away from child element
66 this.node.contains(event.target) &&
67 // and it did NOT go to another child element but someplace else
68 !this.node.contains(event.relatedTarget)) {
69 event.stopPropagation();
70 this.hideAndReset();
71 }
72 break;
73 }
74 case 'contextmenu':
75 event.preventDefault();
76 event.stopPropagation();
77 break;
78 default:
79 break;
80 }
81 }
82 /**
83 * Find the element with search icon group.
84 */
85 get searchIconGroup() {
86 return this._commandPalette.node.getElementsByClassName(SEARCH_ICON_GROUP_CLASS)[0];
87 }
88 /**
89 * Create element with search icon group.
90 */
91 createSearchIconGroup() {
92 const inputGroup = document.createElement('div');
93 inputGroup.classList.add(SEARCH_ICON_GROUP_CLASS);
94 searchIcon.render(inputGroup);
95 return inputGroup;
96 }
97 /**
98 * A message handler invoked on an `'after-attach'` message.
99 */
100 onAfterAttach(msg) {
101 this.node.addEventListener('keydown', this, true);
102 this.node.addEventListener('contextmenu', this, true);
103 }
104 /**
105 * A message handler invoked on an `'after-detach'` message.
106 */
107 onAfterDetach(msg) {
108 this.node.removeEventListener('keydown', this, true);
109 this.node.removeEventListener('contextmenu', this, true);
110 }
111 onBeforeHide(msg) {
112 document.removeEventListener('blur', this, true);
113 }
114 onAfterShow(msg) {
115 document.addEventListener('blur', this, true);
116 }
117 /**
118 * A message handler invoked on an `'activate-request'` message.
119 */
120 onActivateRequest(msg) {
121 if (this.isAttached) {
122 this.show();
123 this._commandPalette.activate();
124 }
125 }
126 /**
127 * Handle the `'keydown'` event for the widget.
128 */
129 _evtKeydown(event) {
130 // Check for escape key
131 switch (event.keyCode) {
132 case 27: // Escape.
133 event.stopPropagation();
134 event.preventDefault();
135 this.hideAndReset();
136 break;
137 default:
138 break;
139 }
140 }
141}
142//# sourceMappingURL=commandpalette.js.map
\No newline at end of file