Skip to content

Commit b90d540

Browse files
authored
feat: close maximized panels with escape key (#2533)
fixes: #1165 Was annoyed with this while working on something, add handling to escape close maximize fields. Exclude if inputs are focused (ex. monaco uses escape to deselect, but doesn't consume it, native searches clear field but don't consume it either).
1 parent 1e1b473 commit b90d540

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

packages/golden-layout/src/LayoutManager.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ export class LayoutManager extends EventEmitter {
170170
this._onUnload = this._onUnload.bind(this);
171171
this._windowBlur = this._windowBlur.bind(this);
172172
this._windowFocus = this._windowFocus.bind(this);
173+
this._windowKeydown = this._windowKeydown.bind(this);
173174

174175
this.config = this._createConfig(config);
175176
this._originalContainer = container;
@@ -498,6 +499,7 @@ export class LayoutManager extends EventEmitter {
498499
$(window).off('resize', this._onResize);
499500
$(window).off('unload beforeunload', this._onUnload);
500501
$(window).off('blur.lm').off('focus.lm');
502+
$(window).off('keydown', this._windowKeydown);
501503
this.root.callDownwards('_$destroy', [], true);
502504
this.root.contentItems = [];
503505
this.tabDropPlaceholder.remove();
@@ -1023,7 +1025,8 @@ export class LayoutManager extends EventEmitter {
10231025
$(window)
10241026
.on('unload beforeunload', this._onUnload)
10251027
.on('blur.lm', this._windowBlur)
1026-
.on('focus.lm', this._windowFocus);
1028+
.on('focus.lm', this._windowFocus)
1029+
.on('keydown', this._windowKeydown);
10271030
}
10281031

10291032
/**
@@ -1037,6 +1040,31 @@ export class LayoutManager extends EventEmitter {
10371040
this.root.element.removeClass('lm_window_blur');
10381041
}
10391042

1043+
/**
1044+
* Handles the escape key to close maximized items, as long as the focus isn't within an input.
1045+
* The escape key has local behaviors in inputs like the Monaco editor or search that we don't
1046+
* want to react to as they are not captured.
1047+
*
1048+
* @private
1049+
* @param e The keydown event
1050+
*/
1051+
_windowKeydown(e: JQuery.KeyDownEvent) {
1052+
if (e.key === 'Escape' && this._maximisedItem !== null) {
1053+
const active = document.activeElement;
1054+
if (
1055+
active &&
1056+
(active.tagName === 'INPUT' ||
1057+
active.tagName === 'TEXTAREA' ||
1058+
active.tagName === 'SELECT' ||
1059+
(active as HTMLElement).isContentEditable)
1060+
) {
1061+
return;
1062+
}
1063+
1064+
this._maximisedItem.toggleMaximise();
1065+
}
1066+
}
1067+
10401068
/**
10411069
* Debounces resize events
10421070
*/

packages/grid/src/key-handlers/SelectionKeyHandler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ class SelectionKeyHandler extends KeyHandler {
9696
return true;
9797
}
9898
case 'Escape':
99+
if (grid.state.selectedRanges.length === 0) return false;
99100
grid.clearSelectedRanges();
100-
// Event consumed, but propagation not stopped
101-
// so the shortcut could be handled by the global handler
102-
return { preventDefault: false, stopPropagation: false };
101+
// consume the event, and stop propagation only if there were selected ranges to clear
102+
return { preventDefault: false, stopPropagation: true };
103103
case 'Enter':
104104
if (grid.state.selectedRanges.length > 0) {
105105
grid.moveCursorInDirection(

0 commit comments

Comments
 (0)