Added animation to content tabs

This commit is contained in:
squidfunk
2021-12-18 00:36:45 +01:00
parent dffcba47fb
commit 4b2a97a51d
7 changed files with 74 additions and 26 deletions

View File

@@ -29,12 +29,14 @@ import {
map,
mapTo,
merge,
startWith,
tap
} from "rxjs"
import {
getElement,
getElementOffset,
getElementSize,
getElements
} from "~/browser"
@@ -65,15 +67,19 @@ export interface ContentTabs {
export function watchContentTabs(
el: HTMLElement
): Observable<ContentTabs> {
return merge(...getElements(":scope > input", el)
.map(input => fromEvent(input, "change")
.pipe(
mapTo<ContentTabs>({
active: getElement(`label[for=${input.id}]`)
})
)
const inputs = getElements(":scope > input", el)
return merge(...inputs.map(input => fromEvent(input, "change")
.pipe(
mapTo<ContentTabs>({
active: getElement(`label[for=${input.id}]`)
})
)
))
.pipe(
startWith({
active: getElement(`label[for=${inputs[0].id}]`)
} as ContentTabs)
)
)
}
/**
@@ -94,12 +100,29 @@ export function mountContentTabs(
const container = getElement(".tabbed-labels", el)
return defer(() => {
const push$ = new Subject<ContentTabs>()
push$.subscribe(({ active }) => {
const { x } = getElementOffset(active)
container.scrollTo({
behavior: "smooth",
left: x
})
push$.subscribe({
/* Handle emission */
next({ active }) {
const offset = getElementOffset(active)
const { width } = getElementSize(active)
/* Set tab indicator offset and width */
el.style.setProperty("--md-indicator-x", `${offset.x}px`)
el.style.setProperty("--md-indicator-width", `${width}px`)
/* Smoothly scroll container */
container.scrollTo({
behavior: "smooth",
left: offset.x
})
},
/* Handle complete */
complete() {
el.style.removeProperty("--md-indicator-x")
el.style.removeProperty("--md-indicator-width")
}
})
/* Create and return component */