import { Observable , Subject , defer , filter , finalize , map , mapTo , merge , tap } from "rxjs" ; import { Component } from "../../_" ; /**
 * Details
 */ export interface Details { action : "open" | "close" ; reveal ? : boolean ; } /**
 * Watch options
 */ interface WatchOptions { target$ : Observable < HTMLElement > ; print$ : Observable < boolean > ; } /**
 * Mount options
 */ interface MountOptions { target$ : Observable < HTMLElement > ; print$ : Observable < boolean > ; } param el param options returns export function watchDetails ( el , { target$ , print$ } ) { let open = true ; return merge ( target$ . pipe ( map ( target => target . closest ( "details:not([open])" ) ! ) , filter ( details => el === details ) , mapTo < Details > ( { action : "open" , reveal : true } ) ) , print$ . pipe ( filter ( active => active || ! open ) , tap ( ( ) => open = el . open ) , map ( active => ( { action : active ? "open" : "close" } ) as Details ) ) ) ; } param el param options returns export function mountDetails ( el , options ) { return defer ( ( ) => { const push$ = new Subject < Details > ( ) ; push$ . subscribe ( ( { action , reveal } ) => { if ( action === "open" ) el . setAttribute ( "open" , "" ) ; else el . removeAttribute ( "open" ) ; if ( reveal ) el . scrollIntoView ( ) ; } ) ; return watchDetails ( el , options ) . pipe ( tap ( state => push$ . next ( state ) ) , finalize ( ( ) => push$ . complete ( ) ) , map ( state => ( { ref : el , ... state } ) ) ) ; } ) ; }