import { Observable , Subject , bufferCount , combineLatest , distinctUntilChanged , distinctUntilKeyChanged , endWith , finalize , map , repeat , skip , takeLast , takeUntil , tap } from "rxjs" ; import { Viewport } from "~/browser" ; import { Component } from "../_" ; import { Header } from "../header" ; import { Main } from "../main" ; /**
 * Back-to-top button
 */ export interface BackToTop { hidden : boolean ; } /**
 * Watch options
 */ interface WatchOptions { viewport$ : Observable < Viewport > ; main$ : Observable < Main > ; target$ : Observable < HTMLElement > ; } /**
 * Mount options
 */ interface MountOptions { viewport$ : Observable < Viewport > ; header$ : Observable < Header > ; main$ : Observable < Main > ; target$ : Observable < HTMLElement > ; } param _el param options returns export function watchBackToTop ( _el , { viewport$ , main$ , target$ } ) { const direction$ = viewport$ . pipe ( map ( ( { offset : { y } } ) => y ) , bufferCount ( 2 , 1 ) , map ( ( [ a , b ] ) => a > b ) , distinctUntilChanged ( ) ) ; const active$ = main$ . pipe ( map ( ( { active } ) => active ) ) ; return combineLatest ( [ active$ , direction$ ] ) . pipe ( map ( ( [ active , direction ] ) => ! ( active && direction ) ) , distinctUntilChanged ( ) , takeUntil ( target$ . pipe ( skip ( 1 ) ) ) , endWith ( true ) , repeat ( { delay : 250 } ) , map ( hidden => ( { hidden } ) ) ) ; } param el param options returns export function mountBackToTop ( el , { viewport$ , header$ , main$ , target$ } ) { const push$ = new Subject < BackToTop > ( ) ; push$ . subscribe ( { next ( { hidden } ) { if ( hidden ) { el . setAttribute ( "data-md-state" , "hidden" ) ; el . setAttribute ( "tabindex" , "-1" ) ; el . blur ( ) ; } else { el . removeAttribute ( "data-md-state" ) ; el . removeAttribute ( "tabindex" ) ; } } , complete ( ) { el . style . top = "" ; el . setAttribute ( "data-md-state" , "hidden" ) ; el . removeAttribute ( "tabindex" ) ; } } ) ; header$ . pipe ( takeUntil ( push$ . pipe ( endWith ( 0 ) , takeLast ( 1 ) ) ) , distinctUntilKeyChanged ( "height" ) ) . subscribe ( ( { height } ) => { el . style . top = `${ height + 16 }px` ; } ) ; return watchBackToTop ( el , { viewport$ , main$ , target$ } ) . pipe ( tap ( state => push$ . next ( state ) ) , finalize ( ( ) => push$ . complete ( ) ) , map ( state => ( { ref : el , ... state } ) ) ) ; }