Skip to content

Commit

Permalink
feat(keycodes): add utilities for checking modifier keys
Browse files Browse the repository at this point in the history
Based off of the conversation in #13790, these changes add some utilities for dealing with modifier keys on keyboard events.
  • Loading branch information
crisbeto committed Nov 3, 2018
1 parent 76044e8 commit afc33bb
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 8 deletions.
20 changes: 18 additions & 2 deletions src/cdk/keycodes/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
package(default_visibility=["//visibility:public"])

load("//tools:defaults.bzl", "ts_library")
load("//tools:defaults.bzl", "ts_library", "jasmine_node_test", "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 = [
"@npm//@types/jasmine",
"//src/cdk/testing",
":keycodes"
],
testonly = 1,
)

ts_web_test_suite(
name = "unit_tests",
deps = [":keycodes_test_sources"],
)
56 changes: 56 additions & 0 deletions src/cdk/keycodes/modifiers.spec.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 21 additions & 0 deletions src/cdk/keycodes/modifiers.ts
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions src/cdk/keycodes/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
*/

export * from './keycodes';
export * from './modifiers';
6 changes: 2 additions & 4 deletions src/cdk/stepper/stepper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions src/lib/expansion/expansion-panel-header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();
}
Expand Down
8 changes: 8 additions & 0 deletions tools/defaults.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,11 @@ def ng_web_test_suite(deps = [], srcs = [], static_css = [], bootstrap = [], **k
] + bootstrap,
**kwargs
)


def ts_web_test_suite(srcs = [], **kwargs):
_ts_web_test_suite(
# Required for running the compiled ng modules that use TypeScript import helpers.
srcs = ["@matdeps//node_modules/tslib:tslib.js"] + srcs,
**kwargs
)

0 comments on commit afc33bb

Please sign in to comment.