SO I have a component in my Angular application that has tabs for categories of data with an array of values for the content of the tab. I want to use HammerJS to swipe between the tabs for a more native experience. I have installed this virtual scroll package also: https://github.com/rintoj/angular2-virtual-scroll to handle the amount of items I am preparing for the lists under each mat-tab
. I'll start by showing the data and the markup here:
Here is building the dummyData just to show how it is structured:
dummyData: any[] = [];
selectedTab: number;
constructor() {
this.selectedTab = 0;
for (let i = 0; i < 3; i++) {
const x = {
key: i,
value: []
}
for (let j = 0; j < 100; j++) {
x.value.push(j);
}
this.dummyData.push(x);
}
console.log(this.dummyData);
}
and here is the markup that loops this data to show the tabs and the lists:
<mat-tab-group dynamicHeight="true" mat-stretch-tabs [selectedIndex]="selectedTab">
<mat-tab *ngFor="let cat of dummyData" [label]="cat.key">
<ng-template matTabContent>
<virtual-scroll [items]="cat.value" (update)="viewPortItems = $event" (swipeleft)="swipe($event)" (swiperight)="swipe($event)" (swipeup)="swipe($event)" (swipedown)="swipe($event)">
<p *ngFor="let item of viewPortItems; let i = index;">{{ item }}</p>
</virtual-scroll>
</ng-template>
</mat-tab>
</mat-tab-group>
Here is the swipe($event)
method that is triggered for the (swipedirection)
outputs on the virtual-scroll
component:
swipe(event) {
console.log(event);
if (this.selectedTab === 0 && event.type === 'swiperight') { return; }
if ((this.selectedTab + 1) === this.dummyData.length && event.type === 'swipeleft') { return; }
switch (event.type) {
case 'swipeleft':
this.selectedTab += 1;
break;
case 'swiperight':
this.selectedTab -= 1;
break;
}
}
For clarity here is my Hammer Configuration class and imports:
import * as Hammer from 'hammerjs';
import { HammerGestureConfig, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
export class HammerConfig extends HammerGestureConfig {
overrrides = <any>{
'swipe': { velocity: 0.4, threshold: 20, direction: Hammer.DIRECTION_ALL },
'pinch': { enable: false },
'rotate': { enable: false }
}
}
Which is also provided: { provide: HAMMER_GESTURE_CONFIG, useClass: HammerConfig }
The purpose of this is for the user to be able to swipe the screen and move between tabs, like a user would on an Android or iOS application. This setup works correctly and does in fact swipe between the tabs and loads the new data next and also virtual scrolls the data to make sure that only a set amount of items load at first.
My problem is that this now blocks all vertical scrolling from a mobile device as Hammer sets touch-action: none
on the virtual-scroll
component. So I can still scroll with a mouse, but any vertical touch events do not do anything. One thing I also noticed is that the (swipeup)
and (swipedown)
do not trigger any event in my component code. I have also remvoed the swipeup and swipedown outputs just to make sure they aren't hindering the scroll, but still nothing when vertically dragging up or down on the screen.
I also can confirm this doesn't have an issue with using the virtual-scroll
package as I have tried it with a normal div
that is not trying to lazy load the items, but just loads them all at once. Still get the same issue blocking any vertical scroll direction. Since I will be using the virtual-scroll
as that is more important that the gestures for tabs, I want to show my example here with that in the markup.
Anyone find a way to keep the native virtual scroll while enabling the horzontal swipe gestures?
I appreciate any and all help here, thanks in advance!