feat(keycodes): add utilities for checking modifier keys (#13933)

Based off of the conversation in #13790, these changes add some utilities for dealing with modifier keys on keyboard events.
This commit is contained in:
Kristiyan Kostadinov
2018-11-07 18:40:10 +00:00
committed by vivian-hu
parent 31bffb38fe
commit 78998638d3
7 changed files with 109 additions and 12 deletions
+18 -2
View File
@@ -1,10 +1,26 @@
package(default_visibility=["//visibility:public"])
load("//tools:defaults.bzl", "ts_library")
load("//tools:defaults.bzl", "ts_library", "ts_web_test_suite")
ts_library(
name = "keycodes",
module_name = "@angular/cdk/keycodes",
srcs = glob(["**/*.ts"], exclude=["**/*.spec.ts"]),
module_name = "@angular/cdk/keycodes",
deps = ["@matdeps//tslib"],
)
ts_library(
name = "keycodes_test_sources",
srcs = glob(["**/*.spec.ts"]),
deps = [
"@matdeps//@types/jasmine",
"//src/cdk/testing",
":keycodes"
],
testonly = 1,
)
ts_web_test_suite(
name = "unit_tests",
deps = [":keycodes_test_sources"],
)
+56
View File
@@ -0,0 +1,56 @@
import {createKeyboardEvent} from '@angular/cdk/testing';
import {hasModifierKey} from './modifiers';
describe('keyboard modifiers', () => {
it('should check whether the alt key is pressed', () => {
const event = createKeyboardEvent('keydown', 0);
expect(hasModifierKey(event)).toBe(false);
Object.defineProperty(event, 'altKey', {get: () => true});
expect(hasModifierKey(event)).toBe(true);
});
it('should check whether the shift key is pressed', () => {
const event = createKeyboardEvent('keydown', 0);
expect(hasModifierKey(event)).toBe(false);
Object.defineProperty(event, 'shiftKey', {get: () => true});
expect(hasModifierKey(event)).toBe(true);
});
it('should check whether the meta key is pressed', () => {
const event = createKeyboardEvent('keydown', 0);
expect(hasModifierKey(event)).toBe(false);
Object.defineProperty(event, 'metaKey', {get: () => true});
expect(hasModifierKey(event)).toBe(true);
});
it('should check whether the ctrl key is pressed', () => {
const event = createKeyboardEvent('keydown', 0);
expect(hasModifierKey(event)).toBe(false);
Object.defineProperty(event, 'ctrlKey', {get: () => true});
expect(hasModifierKey(event)).toBe(true);
});
it('should check if a particular modifier key is pressed', () => {
const event = createKeyboardEvent('keydown', 0);
Object.defineProperty(event, 'ctrlKey', {get: () => true});
expect(hasModifierKey(event, 'altKey')).toBe(false);
Object.defineProperty(event, 'altKey', {get: () => true});
expect(hasModifierKey(event, 'altKey')).toBe(true);
});
it('should check if multiple specific modifier keys are pressed', () => {
const event = createKeyboardEvent('keydown', 0);
Object.defineProperty(event, 'ctrlKey', {get: () => true});
expect(hasModifierKey(event, 'altKey', 'shiftKey')).toBe(false);
Object.defineProperty(event, 'altKey', {get: () => true});
Object.defineProperty(event, 'shiftKey', {get: () => true});
expect(hasModifierKey(event, 'altKey', 'shiftKey')).toBe(true);
});
});
+21
View File
@@ -0,0 +1,21 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
type ModifierKey = 'altKey' | 'shiftKey' | 'ctrlKey' | 'metaKey';
/**
* Checks whether a modifier key is pressed.
* @param event Event to be checked.
*/
export function hasModifierKey(event: KeyboardEvent, ...modifiers: ModifierKey[]): boolean {
if (modifiers.length) {
return modifiers.some(modifier => event[modifier]);
}
return event.altKey || event.shiftKey || event.ctrlKey || event.metaKey;
}
+1
View File
@@ -7,3 +7,4 @@
*/
export * from './keycodes';
export * from './modifiers';
+2 -4
View File
@@ -9,7 +9,7 @@
import {FocusableOption, FocusKeyManager} from '@angular/cdk/a11y';
import {Direction, Directionality} from '@angular/cdk/bidi';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {END, ENTER, HOME, SPACE} from '@angular/cdk/keycodes';
import {END, ENTER, HOME, SPACE, hasModifierKey} from '@angular/cdk/keycodes';
import {
AfterViewInit,
ChangeDetectionStrategy,
@@ -442,9 +442,7 @@ export class CdkStepper implements AfterViewInit, OnDestroy {
}
_onKeydown(event: KeyboardEvent) {
// TODO(crisbeto): move into a CDK utility once
// the similar PRs for other components are merged in.
const hasModifier = event.altKey || event.shiftKey || event.ctrlKey || event.metaKey;
const hasModifier = hasModifierKey(event);
const keyCode = event.keyCode;
const manager = this._keyManager;
+2 -2
View File
@@ -7,7 +7,7 @@
*/
import {FocusMonitor, FocusableOption, FocusOrigin} from '@angular/cdk/a11y';
import {ENTER, SPACE} from '@angular/cdk/keycodes';
import {ENTER, SPACE, hasModifierKey} from '@angular/cdk/keycodes';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
@@ -140,7 +140,7 @@ export class MatExpansionPanelHeader implements OnDestroy, FocusableOption {
// Toggle for space and enter keys.
case SPACE:
case ENTER:
if (!event.altKey && !event.metaKey && !event.shiftKey && !event.ctrlKey) {
if (!hasModifierKey(event)) {
event.preventDefault();
this._toggle();
}