mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(gestures): add injection token for specifying Hammer.js options (#8106)
Adds the `MAT_HAMMER_OPTIONS` injection token that allows users to pass in options to the Hammer.js constructor. Fixes #7097.
This commit is contained in:
committed by
Jeremy Elbourn
parent
f69c8e6d71
commit
f2a0206691
@@ -9,7 +9,7 @@
|
||||
/**
|
||||
* Stripped-down HammerJS annotations to be used within Material, which are necessary,
|
||||
* because HammerJS is an optional dependency. For the full annotations see:
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/hammerjs
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/hammerjs/index.d.ts
|
||||
*/
|
||||
|
||||
/** @docs-private */
|
||||
@@ -54,3 +54,16 @@ export interface HammerManager {
|
||||
off(events: string, handler?: Function): void;
|
||||
on(events: string, handler: Function): void;
|
||||
}
|
||||
|
||||
/** @docs-private */
|
||||
export interface HammerOptions {
|
||||
cssProps?: {[key: string]: string};
|
||||
domEvents?: boolean;
|
||||
enable?: boolean | ((manager: HammerManager) => boolean);
|
||||
preset?: any[];
|
||||
touchAction?: string;
|
||||
recognizers?: any[];
|
||||
|
||||
inputClass?: HammerInput;
|
||||
inputTarget?: EventTarget;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import {TestBed, async} from '@angular/core/testing';
|
||||
import {Component} from '@angular/core';
|
||||
import {HAMMER_GESTURE_CONFIG} from '@angular/platform-browser';
|
||||
import {GestureConfig, MAT_HAMMER_OPTIONS} from './gesture-config';
|
||||
|
||||
describe('GestureConfig', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [TestApp],
|
||||
providers: [{provide: HAMMER_GESTURE_CONFIG, useClass: GestureConfig}]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
it('should instantiate HammerJS', () => {
|
||||
spyOn(window, 'Hammer' as any).and.callThrough();
|
||||
|
||||
const fixture = TestBed.createComponent(TestApp);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(window['Hammer']).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should be able to pass options to HammerJS', () => {
|
||||
TestBed
|
||||
.resetTestingModule()
|
||||
.configureTestingModule({
|
||||
declarations: [TestApp],
|
||||
providers: [
|
||||
{provide: HAMMER_GESTURE_CONFIG, useClass: GestureConfig},
|
||||
{provide: MAT_HAMMER_OPTIONS, useValue: {cssProps: {touchAction: 'auto'}}}
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
spyOn(window, 'Hammer' as any).and.callThrough();
|
||||
|
||||
const fixture = TestBed.createComponent(TestApp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const button = fixture.debugElement.nativeElement.querySelector('button');
|
||||
const firstCallArgs = window['Hammer'].calls.first().args;
|
||||
|
||||
expect(firstCallArgs[0]).toBe(button);
|
||||
expect(firstCallArgs[1].cssProps.touchAction).toBe('auto');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
@Component({
|
||||
template: `<button (longpress)="noop()">Long press me</button>`
|
||||
})
|
||||
class TestApp {
|
||||
noop() {}
|
||||
}
|
||||
@@ -6,10 +6,22 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Injectable, Optional} from '@angular/core';
|
||||
import {Injectable, InjectionToken, Inject, Optional} from '@angular/core';
|
||||
import {HammerGestureConfig} from '@angular/platform-browser';
|
||||
import {MatCommonModule} from '../common-behaviors/common-module';
|
||||
import {HammerInstance, HammerStatic, Recognizer, RecognizerStatic} from './gesture-annotations';
|
||||
import {
|
||||
HammerStatic,
|
||||
HammerInstance,
|
||||
Recognizer,
|
||||
RecognizerStatic,
|
||||
HammerOptions,
|
||||
} from './gesture-annotations';
|
||||
|
||||
/**
|
||||
* Injection token that can be used to provide options to the Hammerjs instance.
|
||||
* More info at http://hammerjs.github.io/api/.
|
||||
*/
|
||||
export const MAT_HAMMER_OPTIONS = new InjectionToken<HammerOptions>('MAT_HAMMER_OPTIONS');
|
||||
|
||||
/* Adjusts configuration of our gesture library, Hammer. */
|
||||
@Injectable()
|
||||
@@ -26,7 +38,9 @@ export class GestureConfig extends HammerGestureConfig {
|
||||
'slideleft'
|
||||
] : [];
|
||||
|
||||
constructor(@Optional() commonModule?: MatCommonModule) {
|
||||
constructor(
|
||||
@Optional() @Inject(MAT_HAMMER_OPTIONS) private _hammerOptions?: HammerOptions,
|
||||
@Optional() commonModule?: MatCommonModule) {
|
||||
super();
|
||||
if (commonModule) {
|
||||
commonModule._checkHammerIsAvailable();
|
||||
@@ -47,18 +61,18 @@ export class GestureConfig extends HammerGestureConfig {
|
||||
* @returns Newly-created HammerJS instance.
|
||||
*/
|
||||
buildHammer(element: HTMLElement): HammerInstance {
|
||||
const mc = new this._hammer(element);
|
||||
const mc = new this._hammer(element, this._hammerOptions || undefined);
|
||||
|
||||
// Default Hammer Recognizers.
|
||||
let pan = new this._hammer.Pan();
|
||||
let swipe = new this._hammer.Swipe();
|
||||
let press = new this._hammer.Press();
|
||||
const pan = new this._hammer.Pan();
|
||||
const swipe = new this._hammer.Swipe();
|
||||
const press = new this._hammer.Press();
|
||||
|
||||
// Notice that a HammerJS recognizer can only depend on one other recognizer once.
|
||||
// Otherwise the previous `recognizeWith` will be dropped.
|
||||
// TODO: Confirm threshold numbers with Material Design UX Team
|
||||
let slide = this._createRecognizer(pan, {event: 'slide', threshold: 0}, swipe);
|
||||
let longpress = this._createRecognizer(press, {event: 'longpress', time: 500});
|
||||
const slide = this._createRecognizer(pan, {event: 'slide', threshold: 0}, swipe);
|
||||
const longpress = this._createRecognizer(press, {event: 'longpress', time: 500});
|
||||
|
||||
// Overwrite the default `pan` event to use the swipe event.
|
||||
pan.recognizeWith(swipe);
|
||||
|
||||
Reference in New Issue
Block a user