@@ -30,6 +30,8 @@ import {
30
30
endWith ,
31
31
finalize ,
32
32
map ,
33
+ repeat ,
34
+ skip ,
33
35
takeLast ,
34
36
takeUntil ,
35
37
tap
@@ -61,8 +63,8 @@ export interface BackToTop {
61
63
*/
62
64
interface WatchOptions {
63
65
viewport$ : Observable < Viewport > /* Viewport observable */
64
- header$ : Observable < Header > /* Header observable */
65
66
main$ : Observable < Main > /* Main area observable */
67
+ target$ : Observable < HTMLElement > /* Location target observable */
66
68
}
67
69
68
70
/**
@@ -72,6 +74,7 @@ interface MountOptions {
72
74
viewport$ : Observable < Viewport > /* Viewport observable */
73
75
header$ : Observable < Header > /* Header observable */
74
76
main$ : Observable < Main > /* Main area observable */
77
+ target$ : Observable < HTMLElement > /* Location target observable */
75
78
}
76
79
77
80
/* ----------------------------------------------------------------------------
@@ -87,33 +90,33 @@ interface MountOptions {
87
90
* @returns Back-to-top observable
88
91
*/
89
92
export function watchBackToTop (
90
- _el : HTMLElement , { viewport$, main$ } : WatchOptions
93
+ _el : HTMLElement , { viewport$, main$, target$ } : WatchOptions
91
94
) : Observable < BackToTop > {
92
95
93
96
/* Compute direction */
94
97
const direction$ = viewport$
95
98
. pipe (
96
99
map ( ( { offset : { y } } ) => y ) ,
97
100
bufferCount ( 2 , 1 ) ,
98
- map ( ( [ a , b ] ) => a > b && b ) ,
101
+ map ( ( [ a , b ] ) => a > b ) ,
99
102
distinctUntilChanged ( )
100
103
)
101
104
102
- /* Compute whether button should be hidden */
103
- const hidden $ = main$
105
+ /* Compute whether main area is active */
106
+ const active $ = main$
104
107
. pipe (
105
- distinctUntilKeyChanged ( " active" )
108
+ map ( ( { active } ) => active )
106
109
)
107
110
108
111
/* Compute threshold for hiding */
109
- return combineLatest ( [ hidden $, direction$ ] )
112
+ return combineLatest ( [ active $, direction$ ] )
110
113
. pipe (
111
- map ( ( [ { active } , direction ] ) => ( {
112
- hidden : ! ( active && direction )
113
- } ) ) ,
114
- distinctUntilChanged ( ( a , b ) => (
115
- a . hidden === b . hidden
116
- ) )
114
+ map ( ( [ active , direction ] ) => ! ( active && direction ) ) ,
115
+ distinctUntilChanged ( ) ,
116
+ takeUntil ( target$ . pipe ( skip ( 1 ) ) ) ,
117
+ endWith ( true ) ,
118
+ repeat ( { delay : 250 } ) ,
119
+ map ( hidden => ( { hidden } ) )
117
120
)
118
121
}
119
122
@@ -128,7 +131,7 @@ export function watchBackToTop(
128
131
* @returns Back-to-top component observable
129
132
*/
130
133
export function mountBackToTop (
131
- el : HTMLElement , { viewport$, header$, main$ } : MountOptions
134
+ el : HTMLElement , { viewport$, header$, main$, target$ } : MountOptions
132
135
) : Observable < Component < BackToTop > > {
133
136
const push$ = new Subject < BackToTop > ( )
134
137
push$ . subscribe ( {
@@ -164,7 +167,7 @@ export function mountBackToTop(
164
167
} )
165
168
166
169
/* Create and return component */
167
- return watchBackToTop ( el , { viewport$, header $, main $ } )
170
+ return watchBackToTop ( el , { viewport$, main $, target $ } )
168
171
. pipe (
169
172
tap ( state => push$ . next ( state ) ) ,
170
173
finalize ( ( ) => push$ . complete ( ) ) ,
0 commit comments