import { EMPTY , Observable , Subject , animationFrameScheduler , combineLatest , defer , finalize , fromEvent , map , switchMap , take , tap , throttleTime } from "rxjs" ; import { ElementOffset , getElement , getElementSize , watchElementContentOffset , watchElementFocus , watchElementOffset } from "~/browser" ; import { Component } from "../../../_" ; /**
 * Annotation
 */ export interface Annotation { active : boolean ; offset : ElementOffset ; } param el param container returns export function watchAnnotation ( el , container ) { const offset$ = defer ( ( ) => combineLatest ( [ watchElementOffset ( el ) , watchElementContentOffset ( container ) ] ) ) . pipe ( map ( ( [ { x , y } , scroll ] ) => { const { width } = getElementSize ( el ) ; return ( { x : x - scroll . x + width / 2 , y : y - scroll . y } ) ; } ) ) ; return watchElementFocus ( el ) . pipe ( switchMap ( active => offset$ . pipe ( map ( offset => ( { active , offset } ) ) , take ( + ! active || Infinity ) ) ) ) ; } param el param container returns export function mountAnnotation ( el , container ) { return defer ( ( ) => { const push$ = new Subject < Annotation > ( ) ; push$ . subscribe ( { next ( { offset } ) { el . style . setProperty ( "--md-tooltip-x" , `${ offset . x }px` ) ; el . style . setProperty ( "--md-tooltip-y" , `${ offset . y }px` ) ; } , complete ( ) { el . style . removeProperty ( "--md-tooltip-x" ) ; el . style . removeProperty ( "--md-tooltip-y" ) ; } } ) ; push$ . pipe ( throttleTime ( 500 , animationFrameScheduler ) , map ( ( ) => container . getBoundingClientRect ( ) ) , map ( ( { x } ) => x ) ) . subscribe ( { next ( origin ) { if ( origin ) el . style . setProperty ( "--md-tooltip-0" , `${ - origin }px` ) ; else el . style . removeProperty ( "--md-tooltip-0" ) ; } , complete ( ) { el . style . removeProperty ( "--md-tooltip-0" ) ; } } ) ; const index = getElement ( ":scope > :last-child" , el ) ; const blur$ = fromEvent ( index , "mousedown" , { once : true } ) ; push$ . pipe ( switchMap ( ( { active } ) => active ? blur$ : EMPTY ) , tap ( ev => ev . preventDefault ( ) ) ) . subscribe ( ( ) => el . blur ( ) ) ; return watchAnnotation ( el , container ) . pipe ( tap ( state => push$ . next ( state ) ) , finalize ( ( ) => push$ . complete ( ) ) , map ( state => ( { ref : el , ... state } ) ) ) ; } ) ; }