1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | import { searchIcon } from '@jupyterlab/ui-components';
|
7 | import { Message } from '@lumino/messaging';
|
8 | import { CommandPalette, Panel, Widget } from '@lumino/widgets';
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | const SEARCH_ICON_GROUP_CLASS = 'jp-SearchIconGroup';
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | export class ModalCommandPalette extends Panel {
|
19 | constructor(options: ModalCommandPalette.IOptions) {
|
20 | super();
|
21 | this.addClass('jp-ModalCommandPalette');
|
22 | this.id = 'modal-command-palette';
|
23 | this.palette = options.commandPalette;
|
24 | this._commandPalette.commands.commandExecuted.connect(() => {
|
25 | if (this.isAttached && this.isVisible) {
|
26 | this.hideAndReset();
|
27 | }
|
28 | });
|
29 |
|
30 |
|
31 | this.node.tabIndex = 0;
|
32 | }
|
33 |
|
34 | get palette(): CommandPalette {
|
35 | return this._commandPalette;
|
36 | }
|
37 |
|
38 | set palette(value: CommandPalette) {
|
39 | this._commandPalette = value;
|
40 | if (!this.searchIconGroup) {
|
41 | this._commandPalette.inputNode.insertAdjacentElement(
|
42 | 'afterend',
|
43 | this.createSearchIconGroup()
|
44 | );
|
45 | }
|
46 | this.addWidget(value);
|
47 | this.hideAndReset();
|
48 | }
|
49 |
|
50 | attach(): void {
|
51 | Widget.attach(this, document.body);
|
52 | }
|
53 |
|
54 | detach(): void {
|
55 | Widget.detach(this);
|
56 | }
|
57 |
|
58 | |
59 |
|
60 |
|
61 | hideAndReset(): void {
|
62 | this.hide();
|
63 | this._commandPalette.inputNode.value = '';
|
64 | this._commandPalette.refresh();
|
65 | }
|
66 |
|
67 | |
68 |
|
69 |
|
70 | handleEvent(event: Event): void {
|
71 | switch (event.type) {
|
72 | case 'keydown':
|
73 | this._evtKeydown(event as KeyboardEvent);
|
74 | break;
|
75 | case 'blur': {
|
76 |
|
77 | if (
|
78 |
|
79 | this.node.contains(event.target as HTMLElement) &&
|
80 |
|
81 | !this.node.contains(
|
82 | (event as MouseEvent).relatedTarget as HTMLElement
|
83 | )
|
84 | ) {
|
85 | event.stopPropagation();
|
86 | this.hideAndReset();
|
87 | }
|
88 | break;
|
89 | }
|
90 | case 'contextmenu':
|
91 | event.preventDefault();
|
92 | event.stopPropagation();
|
93 | break;
|
94 | default:
|
95 | break;
|
96 | }
|
97 | }
|
98 |
|
99 | |
100 |
|
101 |
|
102 | protected get searchIconGroup(): HTMLDivElement | undefined {
|
103 | return this._commandPalette.node.getElementsByClassName(
|
104 | SEARCH_ICON_GROUP_CLASS
|
105 | )[0] as HTMLDivElement;
|
106 | }
|
107 |
|
108 | |
109 |
|
110 |
|
111 | protected createSearchIconGroup(): HTMLDivElement {
|
112 | const inputGroup = document.createElement('div');
|
113 | inputGroup.classList.add(SEARCH_ICON_GROUP_CLASS);
|
114 | searchIcon.render(inputGroup);
|
115 | return inputGroup;
|
116 | }
|
117 |
|
118 | |
119 |
|
120 |
|
121 | protected onAfterAttach(msg: Message): void {
|
122 | this.node.addEventListener('keydown', this, true);
|
123 | this.node.addEventListener('contextmenu', this, true);
|
124 | }
|
125 |
|
126 | |
127 |
|
128 |
|
129 | protected onAfterDetach(msg: Message): void {
|
130 | this.node.removeEventListener('keydown', this, true);
|
131 | this.node.removeEventListener('contextmenu', this, true);
|
132 | }
|
133 |
|
134 | protected onBeforeHide(msg: Message): void {
|
135 | document.removeEventListener('blur', this, true);
|
136 | }
|
137 |
|
138 | protected onAfterShow(msg: Message): void {
|
139 | document.addEventListener('blur', this, true);
|
140 | }
|
141 |
|
142 | |
143 |
|
144 |
|
145 | protected onActivateRequest(msg: Message): void {
|
146 | if (this.isAttached) {
|
147 | this.show();
|
148 | this._commandPalette.activate();
|
149 | }
|
150 | }
|
151 |
|
152 | |
153 |
|
154 |
|
155 | protected _evtKeydown(event: KeyboardEvent): void {
|
156 |
|
157 | switch (event.keyCode) {
|
158 | case 27:
|
159 | event.stopPropagation();
|
160 | event.preventDefault();
|
161 | this.hideAndReset();
|
162 | break;
|
163 | default:
|
164 | break;
|
165 | }
|
166 | }
|
167 |
|
168 | private _commandPalette: CommandPalette;
|
169 | }
|
170 |
|
171 | export namespace ModalCommandPalette {
|
172 | export interface IOptions {
|
173 | commandPalette: CommandPalette;
|
174 | }
|
175 | }
|