diff --git a/src/lib/core/gestures/gesture-annotations.ts b/src/lib/core/gestures/gesture-annotations.ts
index c7193f31b9e..81d56172a56 100644
--- a/src/lib/core/gestures/gesture-annotations.ts
+++ b/src/lib/core/gestures/gesture-annotations.ts
@@ -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;
+}
diff --git a/src/lib/core/gestures/gesture-config.spec.ts b/src/lib/core/gestures/gesture-config.spec.ts
new file mode 100644
index 00000000000..40abf09d903
--- /dev/null
+++ b/src/lib/core/gestures/gesture-config.spec.ts
@@ -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: ``
+})
+class TestApp {
+ noop() {}
+}
diff --git a/src/lib/core/gestures/gesture-config.ts b/src/lib/core/gestures/gesture-config.ts
index 2299daede94..02a692430eb 100644
--- a/src/lib/core/gestures/gesture-config.ts
+++ b/src/lib/core/gestures/gesture-config.ts
@@ -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('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);