All files / src/app/shell/header/back-to-top back-to-top.component.ts

28.57% Statements 6/21
0% Branches 0/8
16.66% Functions 1/6
28.57% Lines 6/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 602x             2x           2x             2x   1x 1x                                                                        
import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core';
 
@Component({
  selector: 'ish-back-to-top',
  templateUrl: './back-to-top.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class BackToTopComponent {
  /**
   * @description
   * Button will not show if window.scrollY is less than MARGIN_TOP.
   * Should be any desired value > 0
   */
  private static readonly MARGIN_TOP = 50;
 
  /**
   * @description
   * Button will show if user has scrolled at least SCROLL_MIN upwards.
   * If set to 0 the button will show as soon as user scrolls upwards
   */
  private static readonly SCROLL_MIN = 50;
 
  isVisible = false;
  private previousOffset = 0;
 
  jump() {
    window.scrollTo(0, 0);
  }
 
  private hide() {
    this.isVisible = false;
  }
 
  private show() {
    this.isVisible = true;
  }
 
  private updateOffset() {
    this.previousOffset = window.scrollY;
  }
 
  @HostListener('window:scroll') onWindowScroll() {
    const diff = this.previousOffset - window.scrollY;
 
    const scrollsDown = diff < 0;
    const isAtTop = window.scrollY < BackToTopComponent.MARGIN_TOP;
    const hasEnoughIntention = diff > BackToTopComponent.SCROLL_MIN;
 
    if (scrollsDown || isAtTop) {
      this.updateOffset();
      this.hide();
    } else if (!this.isVisible && !hasEnoughIntention) {
      this.hide();
    } else {
      this.updateOffset();
      this.show();
    }
  }
}