From b78b87d56cde9b033fa239b565221ecc2f9a99a4 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Sun, 17 Mar 2019 15:33:04 +0800 Subject: [PATCH] fix: allow scrolling on clickable elements on mobile Closes #867 --- README.md | 2 +- package-lock.json | 14 +++++----- package.json | 4 +-- .../src/modules/common/click.directive.ts | 7 ++++- projects/demos/app/demo-app.module.ts | 13 ++++++++-- projects/demos/app/hammer-config.ts | 26 +++++++++++++++++++ 6 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 projects/demos/app/hammer-config.ts diff --git a/README.md b/README.md index ed8f29111..72c96fe38 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ As there are so many events to show on each month, it doesn’t provide a lot of ### Does this calendar work with mobile? -This library is not optimised for mobile. Due to the complex nature of a calendar component, it is non trivial to build a calendar that has a great UX on both desktop and mobile. It is recommended to build your own calendar component for mobile that has a dedicated UX. You may be able to get some degree of mobile support by setting some custom CSS rules for smaller screens and [including hammerjs](http://hammerjs.github.io/) but your mileage may vary. +This library is not optimised for mobile. Due to the complex nature of a calendar component, it is non trivial to build a calendar that has a great UX on both desktop and mobile. It is recommended to build your own calendar component for mobile that has a dedicated UX. You may be able to get some degree of mobile support by setting some custom CSS rules for smaller screens, [including hammerjs](http://hammerjs.github.io/) and using a [custom hammerjs config](https://github.com/mattlewis92/angular-calendar/blob/master/projects/demos/app/hammer-config.ts) to allow scrolling on clickable elements. ### How do I use a custom template? diff --git a/package-lock.json b/package-lock.json index caa5ab7b8..e4b0c841e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "angular-calendar", - "version": "0.26.5", + "version": "0.26.8", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1993,17 +1993,17 @@ } }, "angular-draggable-droppable": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/angular-draggable-droppable/-/angular-draggable-droppable-4.0.2.tgz", - "integrity": "sha512-Ch0YARWRraXy61UOdgNKvjkCbUcSgIATHtR2Yb31MHdia5y1bdrs+2UvIBUx5nIQOLIJBvPb0SEnEFZJgvEMJA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/angular-draggable-droppable/-/angular-draggable-droppable-4.2.0.tgz", + "integrity": "sha512-Kod9Lxj8JonnxdI0MlVyy2vb+1RirR1EOaTF2I0OPSus51OE7mMjUMql9SwYEhq3PIJdnpTHiT+/KbqklTtZVw==", "requires": { "tslib": "^1.9.0" } }, "angular-resizable-element": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/angular-resizable-element/-/angular-resizable-element-3.2.2.tgz", - "integrity": "sha512-Lf3jnZMdndAdasAXRImpmFMe+I596rY2ttMPmWMW9zIp2QeyriNbr8l3VEfUJWnCW14oNsO8SHRAYUXBphm/Lw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/angular-resizable-element/-/angular-resizable-element-3.2.4.tgz", + "integrity": "sha512-Qd/WRTaJgmDJoeWzmK0F52I3X0nLtFPirmsVC2ceic4EQ/3X2yYFCOWgCtH+PvMZct6Whoky3OQLqCpFXQsKHQ==", "requires": { "tslib": "^1.9.0" } diff --git a/package.json b/package.json index 51eb58cae..834de4b61 100644 --- a/package.json +++ b/package.json @@ -131,8 +131,8 @@ "@angular/core": ">=6.0.0 <9.0.0" }, "dependencies": { - "angular-draggable-droppable": "^4.0.2", - "angular-resizable-element": "^3.2.2", + "angular-draggable-droppable": "^4.2.0", + "angular-resizable-element": "^3.2.4", "calendar-utils": "^0.2.2", "positioning": "^1.4.0" }, diff --git a/projects/angular-calendar/src/modules/common/click.directive.ts b/projects/angular-calendar/src/modules/common/click.directive.ts index 5d2deca65..7d7dade9b 100644 --- a/projects/angular-calendar/src/modules/common/click.directive.ts +++ b/projects/angular-calendar/src/modules/common/click.directive.ts @@ -16,7 +16,7 @@ const clickElements = new Set(); selector: '[mwlClick]' }) export class ClickDirective implements OnInit, OnDestroy { - @Output('mwlClick') click: EventEmitter = new EventEmitter(); // tslint:disable-line + @Output('mwlClick') click = new EventEmitter(); // tslint:disable-line private removeListener: () => void; @@ -27,6 +27,11 @@ export class ClickDirective implements OnInit, OnDestroy { ) {} ngOnInit(): void { + this.renderer.setAttribute( + this.elm.nativeElement, + 'data-calendar-clickable', + 'true' + ); clickElements.add(this.elm.nativeElement); const eventName: string = typeof window !== 'undefined' && typeof window['Hammer'] !== 'undefined' diff --git a/projects/demos/app/demo-app.module.ts b/projects/demos/app/demo-app.module.ts index d496d8e42..cd208efcb 100644 --- a/projects/demos/app/demo-app.module.ts +++ b/projects/demos/app/demo-app.module.ts @@ -1,14 +1,17 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; -import { BrowserModule } from '@angular/platform-browser'; +import { + BrowserModule, + HAMMER_GESTURE_CONFIG +} from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgbTabsetModule, NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'; import { Angulartics2Module } from 'angulartics2'; -import { Angulartics2GoogleAnalytics } from 'angulartics2/ga'; import { DemoAppComponent } from './demo-app.component'; import { DemoComponent as DefaultDemoComponent } from './demo-modules/kitchen-sink/component'; import { DemoModule as DefaultDemoModule } from './demo-modules/kitchen-sink/module'; import { environment } from '../environments/environment'; +import { CustomHammerConfig } from './hammer-config'; @NgModule({ declarations: [DemoAppComponent], @@ -297,6 +300,12 @@ import { environment } from '../environments/environment'; developerMode: !environment.production }) ], + providers: [ + { + provide: HAMMER_GESTURE_CONFIG, + useClass: CustomHammerConfig + } + ], bootstrap: [DemoAppComponent] }) export class DemoAppModule {} diff --git a/projects/demos/app/hammer-config.ts b/projects/demos/app/hammer-config.ts new file mode 100644 index 000000000..5932d3b98 --- /dev/null +++ b/projects/demos/app/hammer-config.ts @@ -0,0 +1,26 @@ +import { HammerGestureConfig } from '@angular/platform-browser'; + +declare const Hammer: any; + +export class CustomHammerConfig extends HammerGestureConfig { + buildHammer(element: HTMLElement) { + let options = {}; + + if (element.hasAttribute('data-calendar-clickable')) { + options = { touchAction: 'pan-y' }; + } + + const mc = new Hammer(element, options); + + // keep default angular config + mc.get('pinch').set({ enable: true }); + mc.get('rotate').set({ enable: true }); + + // retain support for angular overrides object + Object.keys(this.overrides).forEach(eventName => { + mc.get(eventName).set(this.overrides[eventName]); + }); + + return mc; + } +}