@jupyterlab/shortcuts-extension 5.4.0-alpha.3 → 5.4.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/NewShortcutItem.d.ts +44 -0
- package/lib/components/NewShortcutItem.js +107 -0
- package/lib/components/NewShortcutItem.js.map +1 -0
- package/lib/components/ShortcutCustomOptions.d.ts +20 -0
- package/lib/components/ShortcutCustomOptions.js +173 -0
- package/lib/components/ShortcutCustomOptions.js.map +1 -0
- package/lib/components/ShortcutItem.d.ts +9 -2
- package/lib/components/ShortcutItem.js +104 -30
- package/lib/components/ShortcutItem.js.map +1 -1
- package/lib/components/ShortcutList.d.ts +1 -0
- package/lib/components/ShortcutList.js +1 -1
- package/lib/components/ShortcutList.js.map +1 -1
- package/lib/components/ShortcutUI.d.ts +18 -1
- package/lib/components/ShortcutUI.js +80 -118
- package/lib/components/ShortcutUI.js.map +1 -1
- package/lib/components/TopNav.d.ts +2 -0
- package/lib/components/TopNav.js +6 -23
- package/lib/components/TopNav.js.map +1 -1
- package/lib/index.js +12 -7
- package/lib/index.js.map +1 -1
- package/lib/registry.d.ts +9 -3
- package/lib/registry.js +173 -24
- package/lib/registry.js.map +1 -1
- package/lib/types.d.ts +49 -3
- package/lib/types.js.map +1 -1
- package/package.json +10 -6
- package/src/components/NewShortcutItem.tsx +154 -0
- package/src/components/ShortcutCustomOptions.tsx +235 -0
- package/src/components/ShortcutItem.tsx +176 -31
- package/src/components/ShortcutList.tsx +2 -0
- package/src/components/ShortcutUI.tsx +109 -162
- package/src/components/TopNav.tsx +17 -33
- package/src/index.ts +19 -8
- package/src/registry.ts +215 -29
- package/src/types.ts +58 -3
- package/style/base.css +103 -1
- package/style/index.css +3 -0
- package/style/index.js +3 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ISignal } from '@lumino/signaling';
|
|
2
|
+
import type { ICustomOptions, IKeybinding, IShortcutRegistry, IShortcutTarget, IShortcutUI } from '../types';
|
|
3
|
+
import type { IShortcutItemProps } from './ShortcutItem';
|
|
4
|
+
/** Props for ShortcutItem component */
|
|
5
|
+
export interface INewShortcutItemProps {
|
|
6
|
+
findConflictsFor: IShortcutRegistry['findConflictsFor'];
|
|
7
|
+
showSelectors: boolean;
|
|
8
|
+
external: IShortcutUI.IExternalBundle;
|
|
9
|
+
}
|
|
10
|
+
export declare class NewShortcutItem implements IShortcutItemProps {
|
|
11
|
+
constructor(options: INewShortcutItemProps);
|
|
12
|
+
showSelectors: boolean;
|
|
13
|
+
external: IShortcutUI.IExternalBundle;
|
|
14
|
+
get shortcut(): IShortcutTarget;
|
|
15
|
+
get changed(): ISignal<NewShortcutItem, void>;
|
|
16
|
+
/**
|
|
17
|
+
* Reset the shortcut.
|
|
18
|
+
*/
|
|
19
|
+
reset: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* Add a new keybinding.
|
|
22
|
+
*/
|
|
23
|
+
addKeybinding: (target: IShortcutTarget, keys: string[]) => Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Replace the given keybinding with a new keybinding as defined by given keys.
|
|
26
|
+
*/
|
|
27
|
+
replaceKeybinding: (target: IShortcutTarget, keybinding: IKeybinding, keys: string[]) => Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Delete a single keybinding for given shortcut target.
|
|
30
|
+
*/
|
|
31
|
+
deleteKeybinding: (target: IShortcutTarget, keybinding: IKeybinding) => Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Reset keybindings for given target to defaults.
|
|
34
|
+
*/
|
|
35
|
+
resetKeybindings: (target: IShortcutTarget) => Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Update the selector and args for a user defined shortcut.
|
|
38
|
+
*/
|
|
39
|
+
setCustomOptions: (target: IShortcutTarget, options: ICustomOptions) => Promise<boolean>;
|
|
40
|
+
updateCommand: (command: string, category: string) => void;
|
|
41
|
+
private _shortcut;
|
|
42
|
+
findConflictsFor: (keys: string[], selector: string) => IShortcutTarget[];
|
|
43
|
+
private _changed;
|
|
44
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Jupyter Development Team.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { Signal } from '@lumino/signaling';
|
|
6
|
+
export class NewShortcutItem {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
/**
|
|
9
|
+
* Reset the shortcut.
|
|
10
|
+
*/
|
|
11
|
+
this.reset = () => {
|
|
12
|
+
this._shortcut = {
|
|
13
|
+
id: 'new shortcut',
|
|
14
|
+
command: '',
|
|
15
|
+
keybindings: [],
|
|
16
|
+
selector: 'body',
|
|
17
|
+
category: '',
|
|
18
|
+
args: {}
|
|
19
|
+
};
|
|
20
|
+
this._changed.emit();
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Add a new keybinding.
|
|
24
|
+
*/
|
|
25
|
+
this.addKeybinding = async (target, keys) => {
|
|
26
|
+
this._shortcut.keybindings.push({ keys, isDefault: false });
|
|
27
|
+
this._changed.emit();
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Replace the given keybinding with a new keybinding as defined by given keys.
|
|
31
|
+
*/
|
|
32
|
+
this.replaceKeybinding = async (target, keybinding, keys) => {
|
|
33
|
+
//Remove empty keys and delete keybindings if there is no new key.
|
|
34
|
+
keys = keys.filter(key => key !== '');
|
|
35
|
+
if (!keys.length) {
|
|
36
|
+
return this.deleteKeybinding(target, keybinding);
|
|
37
|
+
}
|
|
38
|
+
const index = this._shortcut.keybindings.findIndex(binding => binding.keys === keybinding.keys);
|
|
39
|
+
if (index > -1) {
|
|
40
|
+
this._shortcut.keybindings[index] = { keys, isDefault: false };
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
void this.addKeybinding(target, keys);
|
|
44
|
+
}
|
|
45
|
+
this._changed.emit();
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Delete a single keybinding for given shortcut target.
|
|
49
|
+
*/
|
|
50
|
+
this.deleteKeybinding = async (target, keybinding) => {
|
|
51
|
+
const index = this._shortcut.keybindings.findIndex(binding => binding.keys === keybinding.keys);
|
|
52
|
+
if (index > -1) {
|
|
53
|
+
this._shortcut.keybindings.splice(index, 1);
|
|
54
|
+
this._changed.emit();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Reset keybindings for given target to defaults.
|
|
59
|
+
*/
|
|
60
|
+
this.resetKeybindings = async (target) => {
|
|
61
|
+
this._shortcut = {
|
|
62
|
+
...this._shortcut,
|
|
63
|
+
keybindings: []
|
|
64
|
+
};
|
|
65
|
+
this._changed.emit();
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Update the selector and args for a user defined shortcut.
|
|
69
|
+
*/
|
|
70
|
+
this.setCustomOptions = async (target, options) => {
|
|
71
|
+
this._shortcut = {
|
|
72
|
+
...this._shortcut,
|
|
73
|
+
selector: options.selector,
|
|
74
|
+
args: options.args
|
|
75
|
+
};
|
|
76
|
+
this._changed.emit();
|
|
77
|
+
return true;
|
|
78
|
+
};
|
|
79
|
+
this.updateCommand = (command, category) => {
|
|
80
|
+
this._shortcut = {
|
|
81
|
+
...this._shortcut,
|
|
82
|
+
command,
|
|
83
|
+
category
|
|
84
|
+
};
|
|
85
|
+
this._changed.emit();
|
|
86
|
+
};
|
|
87
|
+
this._changed = new Signal(this);
|
|
88
|
+
this._shortcut = {
|
|
89
|
+
id: 'new shortcut',
|
|
90
|
+
command: '',
|
|
91
|
+
keybindings: [],
|
|
92
|
+
selector: 'body',
|
|
93
|
+
category: '',
|
|
94
|
+
args: {}
|
|
95
|
+
};
|
|
96
|
+
this.findConflictsFor = options.findConflictsFor;
|
|
97
|
+
this.showSelectors = options.showSelectors;
|
|
98
|
+
this.external = options.external;
|
|
99
|
+
}
|
|
100
|
+
get shortcut() {
|
|
101
|
+
return this._shortcut;
|
|
102
|
+
}
|
|
103
|
+
get changed() {
|
|
104
|
+
return this._changed;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=NewShortcutItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NewShortcutItem.js","sourceRoot":"","sources":["../../src/components/NewShortcutItem.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Dialog } from '@jupyterlab/apputils';
|
|
2
|
+
import { CodeEditor } from '@jupyterlab/codeeditor';
|
|
3
|
+
import type { ITranslator } from '@jupyterlab/translation';
|
|
4
|
+
import type { ICustomOptions, IShortcutTarget } from '../types';
|
|
5
|
+
export declare class CustomOptionsDialog extends Dialog<ICustomOptions> {
|
|
6
|
+
constructor(options: {
|
|
7
|
+
shortcut: IShortcutTarget;
|
|
8
|
+
editorFactory: CodeEditor.Factory;
|
|
9
|
+
translator: ITranslator;
|
|
10
|
+
readOnly: boolean;
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* Overwrite the keyboard event to prevent the dialog from submitting when
|
|
14
|
+
* pressing Enter in the JSON editor.
|
|
15
|
+
*
|
|
16
|
+
* For all other keys (and Enter outside the JSON editor), delegate to the
|
|
17
|
+
* base dialog handler to preserve standard keyboard behavior.
|
|
18
|
+
*/
|
|
19
|
+
protected _evtKeydown(event: KeyboardEvent): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Jupyter Development Team.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { Dialog } from '@jupyterlab/apputils';
|
|
6
|
+
import { CodeEditor } from '@jupyterlab/codeeditor';
|
|
7
|
+
import { Widget } from '@lumino/widgets';
|
|
8
|
+
export class CustomOptionsDialog extends Dialog {
|
|
9
|
+
constructor(options) {
|
|
10
|
+
const { shortcut, translator, editorFactory } = options;
|
|
11
|
+
const trans = translator.load('jupyterlab');
|
|
12
|
+
const body = new CustomOptionsDialogBody(shortcut, translator, editorFactory, () => this._checkValidation(), options.readOnly);
|
|
13
|
+
const buttons = [];
|
|
14
|
+
if (options.readOnly) {
|
|
15
|
+
buttons.push(Dialog.cancelButton({ label: trans.__('OK') }));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
buttons.push(Dialog.cancelButton({ label: trans.__('Cancel') }));
|
|
19
|
+
buttons.push(Dialog.okButton({ label: trans.__('Apply') }));
|
|
20
|
+
}
|
|
21
|
+
super({
|
|
22
|
+
title: options.readOnly
|
|
23
|
+
? trans.__('Shortcut Options')
|
|
24
|
+
: trans.__('Custom Shortcut Options'),
|
|
25
|
+
body,
|
|
26
|
+
buttons
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Overwrite the keyboard event to prevent the dialog from submitting when
|
|
31
|
+
* pressing Enter in the JSON editor.
|
|
32
|
+
*
|
|
33
|
+
* For all other keys (and Enter outside the JSON editor), delegate to the
|
|
34
|
+
* base dialog handler to preserve standard keyboard behavior.
|
|
35
|
+
*/
|
|
36
|
+
_evtKeydown(event) {
|
|
37
|
+
if (event.key === 'Enter') {
|
|
38
|
+
// If focus is inside the JSON editor, prevent the dialog from treating
|
|
39
|
+
// Enter as a submit/activate-default-button key.
|
|
40
|
+
const jsonEditorNode = this.node.querySelector('.jp-JSONEditor');
|
|
41
|
+
const activeElement = document.activeElement;
|
|
42
|
+
if (jsonEditorNode instanceof HTMLElement &&
|
|
43
|
+
activeElement instanceof HTMLElement &&
|
|
44
|
+
jsonEditorNode.contains(activeElement)) {
|
|
45
|
+
event.stopPropagation();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Fallback to the default dialog behavior.
|
|
50
|
+
super._evtKeydown(event);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Body widget for the custom options dialog.
|
|
55
|
+
*/
|
|
56
|
+
class CustomOptionsDialogBody extends Widget {
|
|
57
|
+
constructor(shortcut, translator, editorFactory, checkValidation, readOnly) {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
super();
|
|
60
|
+
const trans = translator.load('jupyterlab');
|
|
61
|
+
this.addClass('jp-Shortcuts-CustomOptionsDialogBody');
|
|
62
|
+
// Create main container
|
|
63
|
+
const container = document.createElement('div');
|
|
64
|
+
container.className = 'jp-Shortcuts-CustomOptionDialog-container';
|
|
65
|
+
// Selector section
|
|
66
|
+
const selectorLabel = document.createElement('label');
|
|
67
|
+
selectorLabel.textContent = trans.__('Selector:');
|
|
68
|
+
selectorLabel.className = 'jp-Dialog-label';
|
|
69
|
+
this._selectorInput = document.createElement('input');
|
|
70
|
+
this._selectorInput.type = 'text';
|
|
71
|
+
this._selectorInput.disabled = readOnly !== null && readOnly !== void 0 ? readOnly : false;
|
|
72
|
+
this._selectorInput.value = shortcut.selector;
|
|
73
|
+
this._selectorInput.className = 'jp-mod-styled';
|
|
74
|
+
container.appendChild(selectorLabel);
|
|
75
|
+
container.appendChild(this._selectorInput);
|
|
76
|
+
// Args section
|
|
77
|
+
const argsLabel = document.createElement('label');
|
|
78
|
+
argsLabel.textContent = trans.__('Arguments:');
|
|
79
|
+
argsLabel.className = 'jp-Dialog-label';
|
|
80
|
+
container.appendChild(argsLabel);
|
|
81
|
+
if (readOnly) {
|
|
82
|
+
const argsPre = document.createElement('pre');
|
|
83
|
+
argsPre.textContent = JSON.stringify((_a = shortcut.args) !== null && _a !== void 0 ? _a : {}, undefined, 2);
|
|
84
|
+
container.appendChild(argsPre);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// Create dedicated JSON editor widget
|
|
88
|
+
this._editorWidget = new JSONEditorWidget((_b = shortcut.args) !== null && _b !== void 0 ? _b : {}, editorFactory, checkValidation);
|
|
89
|
+
container.appendChild(this._editorWidget.node);
|
|
90
|
+
}
|
|
91
|
+
this.node.appendChild(container);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get the value from the dialog body.
|
|
95
|
+
*/
|
|
96
|
+
getValue() {
|
|
97
|
+
var _a, _b;
|
|
98
|
+
const argsText = (_b = (_a = this._editorWidget) === null || _a === void 0 ? void 0 : _a.getJSON()) !== null && _b !== void 0 ? _b : '{}';
|
|
99
|
+
let args;
|
|
100
|
+
try {
|
|
101
|
+
args = JSON.parse(argsText);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error(`Invalid JSON in arguments: ${error instanceof Error ? error.message : String(error)}`);
|
|
105
|
+
args = {};
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
selector: this._selectorInput.value,
|
|
109
|
+
args
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Dispose resources.
|
|
114
|
+
*/
|
|
115
|
+
dispose() {
|
|
116
|
+
var _a;
|
|
117
|
+
(_a = this._editorWidget) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
118
|
+
super.dispose();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* A dedicated widget for JSON editing with validation.
|
|
123
|
+
*/
|
|
124
|
+
class JSONEditorWidget extends Widget {
|
|
125
|
+
constructor(initialArgs, editorFactory, checkValidation) {
|
|
126
|
+
super();
|
|
127
|
+
/**
|
|
128
|
+
* Validate the JSON sources.
|
|
129
|
+
*/
|
|
130
|
+
this._validateJSON = () => {
|
|
131
|
+
try {
|
|
132
|
+
const text = this._editor.model.sharedModel.getSource();
|
|
133
|
+
JSON.parse(text);
|
|
134
|
+
this.node.classList.remove('jp-mod-error');
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
this.node.classList.add('jp-mod-error');
|
|
138
|
+
}
|
|
139
|
+
this._checkValidation();
|
|
140
|
+
};
|
|
141
|
+
this.addClass('jp-JSONEditor');
|
|
142
|
+
this._checkValidation = checkValidation;
|
|
143
|
+
const editorHostNode = document.createElement('div');
|
|
144
|
+
editorHostNode.className = 'jp-JSONEditor-host';
|
|
145
|
+
const model = new CodeEditor.Model({ mimeType: 'application/json' });
|
|
146
|
+
const content = JSON.stringify(initialArgs, null, 2);
|
|
147
|
+
model.sharedModel.setSource(content);
|
|
148
|
+
this._editor = editorFactory({
|
|
149
|
+
host: editorHostNode,
|
|
150
|
+
model,
|
|
151
|
+
config: {
|
|
152
|
+
readOnly: false
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
this.node.appendChild(editorHostNode);
|
|
156
|
+
this._editor.model.sharedModel.changed.connect(this._validateJSON, this);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get the current JSON text.
|
|
160
|
+
*/
|
|
161
|
+
getJSON() {
|
|
162
|
+
return this._editor.model.sharedModel.getSource();
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Dispose of the resources.
|
|
166
|
+
*/
|
|
167
|
+
dispose() {
|
|
168
|
+
this._editor.model.sharedModel.changed.disconnect(this._validateJSON, this);
|
|
169
|
+
this._editor.dispose();
|
|
170
|
+
super.dispose();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=ShortcutCustomOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShortcutCustomOptions.js","sourceRoot":"","sources":["../../src/components/ShortcutCustomOptions.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIzC,MAAM,OAAO,mBAAoB,SAAQ,MAAsB;IAC7D,YAAY,OAKX;QACC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QACxD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE5C,MAAM,IAAI,GAAG,IAAI,uBAAuB,CACtC,QAAQ,EACR,UAAU,EACV,aAAa,EACb,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAC7B,OAAO,CAAC,QAAQ,CACjB,CAAC;QAEF,MAAM,OAAO,GAAqB,EAAE,CAAC;QACrC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,KAAK,CAAC;YACJ,KAAK,EAAE,OAAO,CAAC,QAAQ;gBACrB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC;gBAC9B,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAAC;YACvC,IAAI;YACJ,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACO,WAAW,CAAC,KAAoB;QACxC,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YAC1B,uEAAuE;YACvE,iDAAiD;YACjD,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACjE,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC;YAC7C,IACE,cAAc,YAAY,WAAW;gBACrC,aAAa,YAAY,WAAW;gBACpC,cAAc,CAAC,QAAQ,CAAC,aAAa,CAAC,EACtC,CAAC;gBACD,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,OAAO;YACT,CAAC;QACH,CAAC;QACD,2CAA2C;QAC3C,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,uBACJ,SAAQ,MAAM;IAMd,YACE,QAAyB,EACzB,UAAuB,EACvB,aAAiC,EACjC,eAA2B,EAC3B,QAAiB;;QAEjB,KAAK,EAAE,CAAC;QACR,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE5C,IAAI,CAAC,QAAQ,CAAC,sCAAsC,CAAC,CAAC;QAEtD,wBAAwB;QACxB,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAChD,SAAS,CAAC,SAAS,GAAG,2CAA2C,CAAC;QAElE,mBAAmB;QACnB,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACtD,aAAa,CAAC,WAAW,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;QAClD,aAAa,CAAC,SAAS,GAAG,iBAAiB,CAAC;QAE5C,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,cAAc,CAAC,IAAI,GAAG,MAAM,CAAC;QAClC,IAAI,CAAC,cAAc,CAAC,QAAQ,GAAG,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,KAAK,CAAC;QACjD,IAAI,CAAC,cAAc,CAAC,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC;QAC9C,IAAI,CAAC,cAAc,CAAC,SAAS,GAAG,eAAe,CAAC;QAEhD,SAAS,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QACrC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE3C,eAAe;QACf,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAClD,SAAS,CAAC,WAAW,GAAG,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;QAC/C,SAAS,CAAC,SAAS,GAAG,iBAAiB,CAAC;QACxC,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAEjC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC9C,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,MAAA,QAAQ,CAAC,IAAI,mCAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;YACxE,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,sCAAsC;YACtC,IAAI,CAAC,aAAa,GAAG,IAAI,gBAAgB,CACvC,MAAA,QAAQ,CAAC,IAAI,mCAAI,EAAE,EACnB,aAAa,EACb,eAAe,CAChB,CAAC;YACF,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,QAAQ;;QACN,MAAM,QAAQ,GAAG,MAAA,MAAA,IAAI,CAAC,aAAa,0CAAE,OAAO,EAAE,mCAAI,IAAI,CAAC;QACvD,IAAI,IAAgB,CAAC;QAErB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,8BACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;YACF,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK;YACnC,IAAI;SACL,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,OAAO;;QACL,MAAA,IAAI,CAAC,aAAa,0CAAE,OAAO,EAAE,CAAC;QAC9B,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,gBAAiB,SAAQ,MAAM;IAInC,YACE,WAAoC,EACpC,aAAiC,EACjC,eAA2B;QAE3B,KAAK,EAAE,CAAC;QA8BV;;WAEG;QACK,kBAAa,GAAG,GAAG,EAAE;YAC3B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;gBACxD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC1C,CAAC;YACD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,CAAC,CAAC;QAzCA,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC;QACxC,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACrD,cAAc,CAAC,SAAS,GAAG,oBAAoB,CAAC;QAEhD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACrD,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAErC,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC;YAC3B,IAAI,EAAE,cAAc;YACpB,KAAK;YACL,MAAM,EAAE;gBACN,QAAQ,EAAE,KAAK;aAChB;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QAEtC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAC3E,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;IACpD,CAAC;IAgBD;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QAC5E,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -9,8 +9,14 @@ export interface IShortcutItemProps {
|
|
|
9
9
|
resetKeybindings: IShortcutUI['resetKeybindings'];
|
|
10
10
|
deleteKeybinding: IShortcutUI['deleteKeybinding'];
|
|
11
11
|
findConflictsFor: IShortcutRegistry['findConflictsFor'];
|
|
12
|
+
setCustomOptions: IShortcutUI['setCustomOptions'];
|
|
12
13
|
showSelectors: boolean;
|
|
13
14
|
external: IShortcutUI.IExternalBundle;
|
|
15
|
+
newShortcutUtils?: {
|
|
16
|
+
searchQuery: string;
|
|
17
|
+
updateCommand: (command: string, category: string) => void;
|
|
18
|
+
saveShortcut: () => Promise<void>;
|
|
19
|
+
};
|
|
14
20
|
}
|
|
15
21
|
/** State for ShortcutItem component */
|
|
16
22
|
export interface IShortcutItemState {
|
|
@@ -26,7 +32,7 @@ export declare class ShortcutItem extends React.Component<IShortcutItemProps, IS
|
|
|
26
32
|
private _onActionRequested;
|
|
27
33
|
/** Toggle display state of input box */
|
|
28
34
|
private toggleInputNew;
|
|
29
|
-
/** Transform special key names into unicode characters */
|
|
35
|
+
/** Transform special key names into unicode characters for Mac */
|
|
30
36
|
toSymbols: (value: string) => string;
|
|
31
37
|
getCategoryCell(): JSX.Element;
|
|
32
38
|
getLabelCell(): JSX.Element;
|
|
@@ -36,7 +42,7 @@ export declare class ShortcutItem extends React.Component<IShortcutItemProps, IS
|
|
|
36
42
|
getClassNameForShortCuts(nonEmptyBindings: IKeybinding[]): string;
|
|
37
43
|
toggleInputReplaceMethod(location: number): void;
|
|
38
44
|
getDisplayReplaceInput(location: number): boolean;
|
|
39
|
-
|
|
45
|
+
getOrDisplayIfNeeded(force: boolean): JSX.Element;
|
|
40
46
|
getShortCutAsInput(binding: IKeybinding, location: number): JSX.Element;
|
|
41
47
|
getShortCutForDisplayOnly(binding: IKeybinding): JSX.Element[];
|
|
42
48
|
isLocationBeingEdited(location: number): boolean;
|
|
@@ -53,6 +59,7 @@ export declare class ShortcutItem extends React.Component<IShortcutItemProps, IS
|
|
|
53
59
|
* Create a unique conflict identifier.
|
|
54
60
|
*/
|
|
55
61
|
private _conflictId;
|
|
62
|
+
private _getFilteredCommands;
|
|
56
63
|
private get _nonEmptyBindings();
|
|
57
64
|
render(): JSX.Element;
|
|
58
65
|
private _trans;
|
|
@@ -2,9 +2,19 @@
|
|
|
2
2
|
* Copyright (c) Jupyter Development Team.
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
|
+
import { Button } from '@jupyter/react-components';
|
|
6
|
+
import { checkIcon, editIcon, HTMLSelect, infoIcon } from '@jupyterlab/ui-components';
|
|
5
7
|
import { Platform } from '@lumino/domutils';
|
|
6
8
|
import * as React from 'react';
|
|
9
|
+
import { CustomOptionsDialog } from './ShortcutCustomOptions';
|
|
7
10
|
import { CONFLICT_CONTAINER_CLASS, ShortcutInput } from './ShortcutInput';
|
|
11
|
+
import { ShortcutRegistry } from '../registry';
|
|
12
|
+
const MAC_SYMBOLS = {
|
|
13
|
+
Ctrl: '⌃',
|
|
14
|
+
Alt: '⌥',
|
|
15
|
+
Shift: '⇧',
|
|
16
|
+
Accel: '⌘'
|
|
17
|
+
};
|
|
8
18
|
/** React component for each command shortcut item */
|
|
9
19
|
export class ShortcutItem extends React.Component {
|
|
10
20
|
constructor(props) {
|
|
@@ -17,28 +27,18 @@ export class ShortcutItem extends React.Component {
|
|
|
17
27
|
conflicts: new Map()
|
|
18
28
|
});
|
|
19
29
|
};
|
|
20
|
-
/** Transform special key names into unicode characters */
|
|
30
|
+
/** Transform special key names into unicode characters for Mac */
|
|
21
31
|
this.toSymbols = (value) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
else if (key === 'Accel' && Platform.IS_MAC) {
|
|
33
|
-
return (result + ' ⌘').trim();
|
|
34
|
-
}
|
|
35
|
-
else if (key === 'Accel') {
|
|
36
|
-
return (result + ' ⌃').trim();
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
return (result + ' ' + key).trim();
|
|
40
|
-
}
|
|
41
|
-
}, '');
|
|
32
|
+
if (!Platform.IS_MAC) {
|
|
33
|
+
return value
|
|
34
|
+
.split(' ')
|
|
35
|
+
.map(key => (key === 'Accel' ? 'Ctrl' : key))
|
|
36
|
+
.join(' ');
|
|
37
|
+
}
|
|
38
|
+
return value
|
|
39
|
+
.split(' ')
|
|
40
|
+
.map(key => { var _a; return (_a = MAC_SYMBOLS[key]) !== null && _a !== void 0 ? _a : key; })
|
|
41
|
+
.join(' ');
|
|
42
42
|
};
|
|
43
43
|
this._trans = this.props.external.translator.load('jupyterlab');
|
|
44
44
|
this.state = {
|
|
@@ -75,17 +75,62 @@ export class ShortcutItem extends React.Component {
|
|
|
75
75
|
}
|
|
76
76
|
getLabelCell() {
|
|
77
77
|
var _a;
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
if (this.props.newShortcutUtils) {
|
|
79
|
+
const filteredShortcuts = this._getFilteredCommands();
|
|
80
|
+
return (React.createElement("div", { className: "jp-Shortcuts-Cell" },
|
|
81
|
+
React.createElement(HTMLSelect, { value: this.props.shortcut.command, options: [
|
|
82
|
+
{ value: '', label: this._trans.__('Select a command') },
|
|
83
|
+
...filteredShortcuts.map(shortcut => ({
|
|
84
|
+
value: shortcut.command,
|
|
85
|
+
label: `${shortcut.category}: ${shortcut.label}`
|
|
86
|
+
}))
|
|
87
|
+
], onChange: e => {
|
|
88
|
+
var _a, _b, _c;
|
|
89
|
+
const shortcut = filteredShortcuts.find(shortcut => shortcut.command === e.target.value);
|
|
90
|
+
(_a = this.props.newShortcutUtils) === null || _a === void 0 ? void 0 : _a.updateCommand((_b = shortcut === null || shortcut === void 0 ? void 0 : shortcut.command) !== null && _b !== void 0 ? _b : '', (_c = shortcut === null || shortcut === void 0 ? void 0 : shortcut.category) !== null && _c !== void 0 ? _c : '');
|
|
91
|
+
} })));
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
return (React.createElement("div", { className: "jp-Shortcuts-Cell" },
|
|
95
|
+
React.createElement("div", { className: "jp-label" }, (_a = this.props.shortcut.label) !== null && _a !== void 0 ? _a : this._trans.__('(Command label missing)'))));
|
|
96
|
+
}
|
|
80
97
|
}
|
|
81
98
|
getResetShortCutLink() {
|
|
82
|
-
return (React.createElement("a", { className: "jp-Shortcuts-Reset", onClick: () => this.props.resetKeybindings(this.props.shortcut) }, this.
|
|
99
|
+
return (React.createElement("a", { className: "jp-Shortcuts-Reset", onClick: () => this.props.resetKeybindings(this.props.shortcut) }, this.props.shortcut.userDefined
|
|
100
|
+
? this._trans.__('Delete')
|
|
101
|
+
: this._trans.__('Reset')));
|
|
83
102
|
}
|
|
84
103
|
getSourceCell() {
|
|
104
|
+
var _a;
|
|
85
105
|
const allDefault = this.props.shortcut.keybindings.every(binding => binding.isDefault);
|
|
106
|
+
const editable = this.props.shortcut.userDefined || !!this.props.newShortcutUtils;
|
|
107
|
+
const showOptionsButtonTitle = editable
|
|
108
|
+
? this._trans.__('Custom options')
|
|
109
|
+
: this._trans.__('Show options');
|
|
86
110
|
return (React.createElement("div", { className: "jp-Shortcuts-Cell" },
|
|
87
|
-
React.createElement("div", { className: "jp-Shortcuts-SourceCell" }, allDefault ? this._trans.__('Default') : this._trans.__('Custom')),
|
|
88
|
-
!allDefault ? this.getResetShortCutLink() : ''
|
|
111
|
+
!this.props.newShortcutUtils && (React.createElement("div", { className: "jp-Shortcuts-SourceCell" }, allDefault ? this._trans.__('Default') : this._trans.__('Custom'))),
|
|
112
|
+
!allDefault ? this.getResetShortCutLink() : '',
|
|
113
|
+
this.props.external.editorFactory && (React.createElement(Button, { className: "jp-mod-styled jp-mod-reject jp-Shortcuts-CustomOptions", onClick: async () => {
|
|
114
|
+
if (!this.props.external.editorFactory) {
|
|
115
|
+
console.error('Cannot build the custom options form');
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const dialog = new CustomOptionsDialog({
|
|
119
|
+
shortcut: this.props.shortcut,
|
|
120
|
+
translator: this.props.external.translator,
|
|
121
|
+
editorFactory: this.props.external.editorFactory,
|
|
122
|
+
readOnly: !editable
|
|
123
|
+
});
|
|
124
|
+
const result = await dialog.launch();
|
|
125
|
+
if (result.button.accept && editable && result.value) {
|
|
126
|
+
await this.props.setCustomOptions(this.props.shortcut, result.value);
|
|
127
|
+
}
|
|
128
|
+
}, title: showOptionsButtonTitle, "aria-label": showOptionsButtonTitle, appearance: 'neutral' }, editable ? (React.createElement(editIcon.react, { tag: null })) : (React.createElement(infoIcon.react, { tag: null })))),
|
|
129
|
+
!!this.props.newShortcutUtils && (React.createElement(React.Fragment, null,
|
|
130
|
+
React.createElement(Button, { className: "jp-mod-styled jp-mod-accept jp-Shortcuts-SaveNew", onClick: (_a = this.props.newShortcutUtils) === null || _a === void 0 ? void 0 : _a.saveShortcut, title: this._trans.__('Save shortcut'), "aria-label": this._trans.__('Save shortcut'), appearance: "neutral", disabled: !this.props.shortcut.command ||
|
|
131
|
+
!this.props.shortcut.keybindings.length ||
|
|
132
|
+
this.props.shortcut.keybindings.every(binding => !binding.keys || binding.keys.length === 0) },
|
|
133
|
+
React.createElement(checkIcon.react, { tag: null }))))));
|
|
89
134
|
}
|
|
90
135
|
getOptionalSelectorCell() {
|
|
91
136
|
return this.props.showSelectors ? (React.createElement("div", { className: "jp-Shortcuts-Cell" },
|
|
@@ -117,7 +162,7 @@ export class ShortcutItem extends React.Component {
|
|
|
117
162
|
getDisplayReplaceInput(location) {
|
|
118
163
|
return this.state.displayReplaceInput[location];
|
|
119
164
|
}
|
|
120
|
-
|
|
165
|
+
getOrDisplayIfNeeded(force) {
|
|
121
166
|
const classes = ['jp-Shortcuts-Or'];
|
|
122
167
|
if (force || this.state.displayNewInput) {
|
|
123
168
|
classes.push('jp-Shortcuts-Or-Forced');
|
|
@@ -133,7 +178,11 @@ export class ShortcutItem extends React.Component {
|
|
|
133
178
|
}
|
|
134
179
|
getShortCutForDisplayOnly(binding) {
|
|
135
180
|
return binding.keys.map((keyboardKey, index) => (React.createElement("div", { className: "jp-Shortcuts-ShortcutKeysContainer", key: index },
|
|
136
|
-
React.createElement("div", { className: "jp-Shortcuts-ShortcutKeys" }, this.toSymbols(keyboardKey)
|
|
181
|
+
React.createElement("div", { className: "jp-Shortcuts-ShortcutKeys" }, this.toSymbols(keyboardKey)
|
|
182
|
+
.split(' ')
|
|
183
|
+
.map((keyPart, keyPartIndex, keyParts) => (React.createElement(React.Fragment, { key: `${index}-${keyPart}-${keyPartIndex}` },
|
|
184
|
+
React.createElement("span", { className: "jp-ContextualShortcut-Key" }, keyPart),
|
|
185
|
+
keyPartIndex + 1 < keyParts.length ? ' + ' : null)))),
|
|
137
186
|
index + 1 < binding.keys.length ? (React.createElement("div", { className: "jp-Shortcuts-Comma" }, ",")) : null)));
|
|
138
187
|
}
|
|
139
188
|
isLocationBeingEdited(location) {
|
|
@@ -146,7 +195,7 @@ export class ShortcutItem extends React.Component {
|
|
|
146
195
|
: this.getShortCutForDisplayOnly(binding),
|
|
147
196
|
!(index === this._nonEmptyBindings.length - 1 &&
|
|
148
197
|
Object.values(this.state.displayReplaceInput).some(Boolean)) &&
|
|
149
|
-
this.
|
|
198
|
+
this.getOrDisplayIfNeeded(index < this._nonEmptyBindings.length - 1)));
|
|
150
199
|
}
|
|
151
200
|
getAddLink() {
|
|
152
201
|
return (React.createElement("a", { className: !this.state.displayNewInput ? 'jp-Shortcuts-Plus' : '', onClick: () => {
|
|
@@ -220,12 +269,37 @@ export class ShortcutItem extends React.Component {
|
|
|
220
269
|
'_' +
|
|
221
270
|
conflict.conflictsWith.map(target => target.id).join(''));
|
|
222
271
|
}
|
|
272
|
+
_getFilteredCommands() {
|
|
273
|
+
var _a, _b;
|
|
274
|
+
const registry = new ShortcutRegistry({
|
|
275
|
+
commandRegistry: this.props.external.commandRegistry,
|
|
276
|
+
allCommands: true
|
|
277
|
+
});
|
|
278
|
+
const filteredShortcuts = ShortcutRegistry.matchItems(registry, (_b = (_a = this.props.newShortcutUtils) === null || _a === void 0 ? void 0 : _a.searchQuery) !== null && _b !== void 0 ? _b : '')
|
|
279
|
+
.map((item) => item.item)
|
|
280
|
+
.filter(target => !target.command.startsWith('__internal:'));
|
|
281
|
+
filteredShortcuts.sort((a, b) => {
|
|
282
|
+
var _a, _b;
|
|
283
|
+
const compareA = a.category;
|
|
284
|
+
const compareB = b.category;
|
|
285
|
+
const compareResult = compareA.localeCompare(compareB);
|
|
286
|
+
if (compareResult) {
|
|
287
|
+
return compareResult;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
const aLabel = (_a = a['label']) !== null && _a !== void 0 ? _a : '';
|
|
291
|
+
const bLabel = (_b = b['label']) !== null && _b !== void 0 ? _b : '';
|
|
292
|
+
return aLabel.localeCompare(bLabel);
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
return filteredShortcuts;
|
|
296
|
+
}
|
|
223
297
|
get _nonEmptyBindings() {
|
|
224
298
|
return this.props.shortcut.keybindings.filter(binding => binding.keys.filter(k => k != '').length !== 0);
|
|
225
299
|
}
|
|
226
300
|
render() {
|
|
227
301
|
return (React.createElement(React.Fragment, null,
|
|
228
|
-
React.createElement("div", { className:
|
|
302
|
+
React.createElement("div", { className: `jp-Shortcuts-Row${this.props.newShortcutUtils ? ' jp-Shortcuts-Row-newShortcut' : ''}`, "data-shortcut": this.props.shortcut.id },
|
|
229
303
|
this.getCategoryCell(),
|
|
230
304
|
this.getLabelCell(),
|
|
231
305
|
this.getShortCutsCell(this._nonEmptyBindings),
|