Link header to viewport resizes

This commit is contained in:
squidfunk
2020-02-18 10:17:57 +01:00
parent ac7c8e20a8
commit fdff60e33d
8 changed files with 57 additions and 21 deletions

View File

@@ -20,10 +20,21 @@
* IN THE SOFTWARE.
*/
import { OperatorFunction, pipe } from "rxjs"
import { Observable, OperatorFunction, pipe } from "rxjs"
import { shareReplay, switchMap } from "rxjs/operators"
import { Header, watchHeader } from "observables"
import { Header, Viewport, watchHeader } from "observables"
/* ----------------------------------------------------------------------------
* Helper types
* ------------------------------------------------------------------------- */
/**
* Mount options
*/
interface MountOptions {
viewport$: Observable<Viewport> /* Viewport observable */
}
/* ----------------------------------------------------------------------------
* Functions
@@ -32,11 +43,15 @@ import { Header, watchHeader } from "observables"
/**
* Mount header from source observable
*
* @param options - Options
*
* @return Header observable
*/
export function mountHeader(): OperatorFunction<HTMLElement, Header> {
export function mountHeader(
{ viewport$ }: MountOptions
): OperatorFunction<HTMLElement, Header> {
return pipe(
switchMap(watchHeader),
switchMap(el => watchHeader(el, { viewport$ })),
shareReplay(1)
)
}

View File

@@ -165,7 +165,7 @@ export function initialize(config: unknown) {
/* Create header observable */
const header$ = useComponent("header")
.pipe(
mountHeader()
mountHeader({ viewport$ })
)
const main$ = useComponent("main")

View File

@@ -21,6 +21,9 @@
*/
import { Observable, of } from "rxjs"
import { distinctUntilKeyChanged, switchMap } from "rxjs/operators"
import { Viewport } from "../../agent"
/* ----------------------------------------------------------------------------
* Types
@@ -34,6 +37,17 @@ export interface Header {
height: number /* Header visible height */
}
/* ----------------------------------------------------------------------------
* Helper types
* ------------------------------------------------------------------------- */
/**
* Watch options
*/
interface WatchOptions {
viewport$: Observable<Viewport> /* Viewport observable */
}
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
@@ -45,19 +59,26 @@ export interface Header {
* other dynamic behaviors that may be implemented later on.
*
* @param el - Header element
* @param options - Options
*
* @return Header observable
*/
export function watchHeader(
el: HTMLElement
el: HTMLElement, { viewport$ }: WatchOptions
): Observable<Header> {
const styles = getComputedStyle(el)
const sticky = [
"sticky", /* Modern browsers */
"-webkit-sticky" /* Old Safari */
].includes(styles.position)
return of({
sticky,
height: sticky ? el.offsetHeight : 0
})
return viewport$
.pipe(
distinctUntilKeyChanged("size"),
switchMap(() => {
const styles = getComputedStyle(el)
const sticky = [
"sticky", /* Modern browsers */
"-webkit-sticky" /* Old Safari */
].includes(styles.position)
return of({
sticky,
height: sticky ? el.offsetHeight : 0
})
})
)
}