Skip to content

Commit 04716b1

Browse files
crisbetommalerba
authored andcommitted
fix(expansion-panel): don't handle enter/space if modifier is pressed (#13790)
Doesn't `preventDefault` and handle the enter and space key presses if the user is pressing any of the modifier keys. Fixes #13783.
1 parent 5d54920 commit 04716b1

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

src/cdk/testing/event-objects.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,14 @@ export function createTouchEvent(type: string, pageX = 0, pageY = 0) {
5656
/** Dispatches a keydown event from an element. */
5757
export function createKeyboardEvent(type: string, keyCode: number, target?: Element, key?: string) {
5858
let event = document.createEvent('KeyboardEvent') as any;
59-
// Firefox does not support `initKeyboardEvent`, but supports `initKeyEvent`.
60-
let initEventFn = (event.initKeyEvent || event.initKeyboardEvent).bind(event);
6159
let originalPreventDefault = event.preventDefault;
6260

63-
initEventFn(type, true, true, window, 0, 0, 0, 0, 0, keyCode);
61+
// Firefox does not support `initKeyboardEvent`, but supports `initKeyEvent`.
62+
if (event.initKeyEvent) {
63+
event.initKeyEvent(type, true, true, window, 0, 0, 0, 0, 0, keyCode);
64+
} else {
65+
event.initKeyboardEvent(type, true, true, window, 0, key, 0, '', false);
66+
}
6467

6568
// Webkit Browsers don't set the keyCode when calling the init function.
6669
// See related bug https://bugs.webkit.org/show_bug.cgi?id=16735

src/lib/expansion/expansion-panel-header.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,11 @@ export class MatExpansionPanelHeader implements OnDestroy, FocusableOption {
140140
// Toggle for space and enter keys.
141141
case SPACE:
142142
case ENTER:
143-
event.preventDefault();
144-
this._toggle();
143+
if (!event.altKey && !event.metaKey && !event.shiftKey && !event.ctrlKey) {
144+
event.preventDefault();
145+
this._toggle();
146+
}
147+
145148
break;
146149
default:
147150
if (this.panel.accordion) {

src/lib/expansion/expansion.spec.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {By} from '@angular/platform-browser';
44
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
55
import {MatExpansionModule, MatExpansionPanel} from './index';
66
import {SPACE, ENTER} from '@angular/cdk/keycodes';
7-
import {dispatchKeyboardEvent} from '@angular/cdk/testing';
7+
import {dispatchKeyboardEvent, createKeyboardEvent, dispatchEvent} from '@angular/cdk/testing';
88

99

1010
describe('MatExpansionPanel', () => {
@@ -139,6 +139,24 @@ describe('MatExpansionPanel', () => {
139139
expect(event.defaultPrevented).toBe(true);
140140
});
141141

142+
it('should not toggle if a modifier key is pressed', () => {
143+
const fixture = TestBed.createComponent(PanelWithContent);
144+
const headerEl = fixture.nativeElement.querySelector('.mat-expansion-panel-header');
145+
146+
spyOn(fixture.componentInstance.panel, 'toggle');
147+
148+
['altKey', 'metaKey', 'shiftKey', 'ctrlKey'].forEach(modifier => {
149+
const event = createKeyboardEvent('keydown', ENTER);
150+
Object.defineProperty(event, modifier, {get: () => true});
151+
152+
dispatchEvent(headerEl, event);
153+
fixture.detectChanges();
154+
155+
expect(fixture.componentInstance.panel.toggle).not.toHaveBeenCalled();
156+
expect(event.defaultPrevented).toBe(false);
157+
});
158+
});
159+
142160
it('should not be able to focus content while closed', fakeAsync(() => {
143161
const fixture = TestBed.createComponent(PanelWithContent);
144162
fixture.componentInstance.expanded = true;

0 commit comments

Comments
 (0)