import {
Component, Input, ElementRef, Output, EventEmitter, Renderer2, NgZone,
OnInit, OnDestroy, HostBinding, ChangeDetectionStrategy
} from '@angular/core';
import { MouseEvent } from '../../events';
@Component({
selector: 'datatable-scroller',
template: `
`,
host: {
class: 'datatable-scroll'
},
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ScrollerComponent implements OnInit, OnDestroy {
@Input() scrollbarV: boolean = false;
@Input() scrollbarH: boolean = false;
@HostBinding('style.height.px')
@Input() scrollHeight: number;
@HostBinding('style.width.px')
@Input() scrollWidth: number;
@Output() scroll: EventEmitter = new EventEmitter();
scrollYPos: number = 0;
scrollXPos: number = 0;
prevScrollYPos: number = 0;
prevScrollXPos: number = 0;
element: any;
parentElement: any;
onScrollListener: any;
constructor(private ngZone: NgZone, element: ElementRef, private renderer: Renderer2) {
this.element = element.nativeElement;
}
ngOnInit(): void {
// manual bind so we don't always listen
if (this.scrollbarV || this.scrollbarH) {
const renderer = this.renderer;
this.parentElement = renderer.parentNode(renderer.parentNode(this.element));
this.parentElement.addEventListener('scroll', this.onScrolled.bind(this));
}
}
ngOnDestroy(): void {
if (this.scrollbarV || this.scrollbarH) {
this.parentElement.removeEventListener('scroll', this.onScrolled.bind(this));
}
}
setOffset(offsetY: number): void {
if (this.parentElement) {
this.parentElement.scrollTop = offsetY;
}
}
onScrolled(event: MouseEvent): void {
const dom: Element = event.currentTarget;
requestAnimationFrame(() => {
this.scrollYPos = dom.scrollTop;
this.scrollXPos = dom.scrollLeft;
this.updateOffset();
});
}
updateOffset(): void {
let direction: string;
if (this.scrollYPos < this.prevScrollYPos) {
direction = 'down';
} else if (this.scrollYPos > this.prevScrollYPos) {
direction = 'up';
}
this.scroll.emit({
direction,
scrollYPos: this.scrollYPos,
scrollXPos: this.scrollXPos
});
this.prevScrollYPos = this.scrollYPos;
this.prevScrollXPos = this.scrollXPos;
}
}