import { Directive, Inject, Renderer2, ElementRef, Input, AfterViewInit } from '@angular/core'; import { WINDOW } from '@arrow/bom/core'; import { fromEvent } from 'rxjs'; import { ArrowService, BomListConfig } from '@arrow/bom/core'; import { ConfigService } from '@arrow/bom/config'; export type StickTo = 'top' | 'right' | 'left' | 'bottom'; const CLASS_NAME = 'bom-stick-to-'; @Directive({ selector: '[bomSticky]' }) export class StickyDirective implements AfterViewInit { @Input() target: StickTo = 'top'; @Input() headerEl: ElementRef; @Input() config: BomListConfig; isMyArrow: boolean; constructor( @Inject(WINDOW) private window: any, private renderer: Renderer2, private hostElement: ElementRef, private arrow: ArrowService, private _config: ConfigService ) { this.isMyArrow = this._config.getTarget() === 'myarrow'; } ngAfterViewInit() { const htmlEl = this.hostElement.nativeElement; const wrapperEl = this.config && this.config.wrapperEl ? this.config.wrapperEl : window; const scroll$ = fromEvent(wrapperEl, 'scroll'); let isStuck = false; scroll$.subscribe(($event: Event) => { if (!this.config || !this.config.stickyHeader) return; const childEl = this.hostElement.nativeElement.children[0]; const top = this.window !== wrapperEl ? htmlEl.getBoundingClientRect().top - wrapperEl.getBoundingClientRect().top : htmlEl.getBoundingClientRect().top; if (top - this.config.stickyTopPx < 0) { const distanceToTop = top - this.config.stickyTopPx; this.renderer.addClass( this.hostElement.nativeElement, `${CLASS_NAME}${this.target}` ); let headerTop; let scrollArrowsTop if (this.isMyArrow) { headerTop = `${Math.abs(distanceToTop)+55}px`; scrollArrowsTop = `${Math.abs(distanceToTop)+70}px`; } else { headerTop = `${Math.abs(distanceToTop)+35}px`; scrollArrowsTop = `${Math.abs(distanceToTop)+50}px`; } childEl.style.top = headerTop; document.getElementById('scrollArrowsContainer').style.top = scrollArrowsTop; document.getElementById('scrollArrowsBg').style.top = scrollArrowsTop; isStuck = true; } else if (isStuck) { if (this.isMyArrow) { document.getElementById('scrollArrowsContainer').style.top = '10px'; document.getElementById('scrollArrowsBg').style.top = '10px'; } else { document.getElementById('scrollArrowsContainer').style.top = '15px'; document.getElementById('scrollArrowsBg').style.top = '15px'; } isStuck = false; this.renderer.removeClass( this.hostElement.nativeElement, `${CLASS_NAME}${this.target}` ); } }); } }