1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 13:23:34 +00:00

[PM-16291] Prevent parent components from closing when esc key is pressed on select and menu (#15214)

This commit is contained in:
Vicki League
2025-06-30 11:03:24 -04:00
committed by GitHub
parent 04ddea5bf3
commit a2fd4a3779
3 changed files with 26 additions and 0 deletions

View File

@@ -1,5 +1,6 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { hasModifierKey } from "@angular/cdk/keycodes";
import { Overlay, OverlayConfig, OverlayRef } from "@angular/cdk/overlay";
import { TemplatePortal } from "@angular/cdk/portal";
import {
@@ -76,6 +77,13 @@ export class MenuTriggerForDirective implements OnDestroy {
this.overlayRef.attach(templatePortal);
this.closedEventsSub = this.getClosedEvents().subscribe((event: KeyboardEvent | undefined) => {
// Closing the menu is handled in this.destroyMenu, so we want to prevent the escape key
// from doing its normal default action, which would otherwise cause a parent component
// (like a dialog) or extension window to close
if (event?.key === "Escape" && !hasModifierKey(event)) {
event.preventDefault();
}
if (["Tab", "Escape"].includes(event?.key)) {
// Required to ensure tab order resumes correctly
this.elementRef.nativeElement.focus();

View File

@@ -9,6 +9,7 @@
[clearable]="false"
(close)="onClose()"
appendTo="body"
[keyDownFn]="onKeyDown"
>
<ng-template ng-option-tmp let-item="item">
<div class="tw-flex" [title]="item.label">

View File

@@ -1,6 +1,7 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { hasModifierKey } from "@angular/cdk/keycodes";
import {
Component,
ContentChildren,
@@ -185,4 +186,20 @@ export class SelectComponent<T> implements BitFormFieldControl, ControlValueAcce
protected onClose() {
this.closed.emit();
}
/**
* Prevent Escape key press from propagating to parent components
* (for example, parent dialog should not close when Escape is pressed in the select)
*
* @returns true to keep default key behavior; false to prevent default key behavior
*
* Needs to be arrow function to retain `this` scope.
*/
protected onKeyDown = (event: KeyboardEvent) => {
if (this.select.isOpen && event.key === "Escape" && !hasModifierKey(event)) {
event.stopPropagation();
}
return true;
};
}