mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2024-06-14 11:52:32 +03:00
Added support for variable sized header
This commit is contained in:
parent
a6bc272778
commit
b0ebcc8d5b
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
material/assets/javascripts/bundle.7cbaf05d.min.js.map
Normal file
1
material/assets/javascripts/bundle.7cbaf05d.min.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"assets/javascripts/bundle.js": "assets/javascripts/bundle.4a3df536.min.js",
|
"assets/javascripts/bundle.js": "assets/javascripts/bundle.7cbaf05d.min.js",
|
||||||
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.4a3df536.min.js.map",
|
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.7cbaf05d.min.js.map",
|
||||||
"assets/javascripts/worker/packer.js": "assets/javascripts/worker/packer.c14659e8.min.js",
|
"assets/javascripts/worker/packer.js": "assets/javascripts/worker/packer.c14659e8.min.js",
|
||||||
"assets/javascripts/worker/packer.js.map": "assets/javascripts/worker/packer.c14659e8.min.js.map",
|
"assets/javascripts/worker/packer.js.map": "assets/javascripts/worker/packer.c14659e8.min.js.map",
|
||||||
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.0a5433f7.min.js",
|
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.0a5433f7.min.js",
|
||||||
|
@ -190,7 +190,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="{{ 'assets/javascripts/bundle.4a3df536.min.js' | url }}"></script>
|
<script src="{{ 'assets/javascripts/bundle.7cbaf05d.min.js' | url }}"></script>
|
||||||
<script id="__lang" type="application/json">
|
<script id="__lang" type="application/json">
|
||||||
{%- set translations = {} -%}
|
{%- set translations = {} -%}
|
||||||
{%- for key in [
|
{%- for key in [
|
||||||
|
@ -24,6 +24,31 @@
|
|||||||
* Functions
|
* Functions
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set sidebar offset
|
||||||
|
*
|
||||||
|
* @param el - Sidebar element
|
||||||
|
* @param value - Sidebar offset
|
||||||
|
*/
|
||||||
|
export function setSidebarOffset(
|
||||||
|
el: HTMLElement, value: number
|
||||||
|
): void {
|
||||||
|
el.style.top = `${value}px`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset sidebar offset
|
||||||
|
*
|
||||||
|
* @param el - Sidebar element
|
||||||
|
*/
|
||||||
|
export function resetSidebarOffset(
|
||||||
|
el: HTMLElement
|
||||||
|
): void {
|
||||||
|
el.style.top = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set sidebar height
|
* Set sidebar height
|
||||||
*
|
*
|
||||||
|
@ -24,6 +24,7 @@ import { Observable, OperatorFunction, pipe } from "rxjs"
|
|||||||
import { map, shareReplay, switchMap } from "rxjs/operators"
|
import { map, shareReplay, switchMap } from "rxjs/operators"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
Header,
|
||||||
Main,
|
Main,
|
||||||
NavigationLayer,
|
NavigationLayer,
|
||||||
Sidebar,
|
Sidebar,
|
||||||
@ -70,6 +71,7 @@ export type Navigation =
|
|||||||
* Mount options
|
* Mount options
|
||||||
*/
|
*/
|
||||||
interface MountOptions {
|
interface MountOptions {
|
||||||
|
header$: Observable<Header> /* Header observable */
|
||||||
main$: Observable<Main> /* Main area observable */
|
main$: Observable<Main> /* Main area observable */
|
||||||
viewport$: Observable<Viewport> /* Viewport observable */
|
viewport$: Observable<Viewport> /* Viewport observable */
|
||||||
screen$: Observable<boolean> /* Screen media observable */
|
screen$: Observable<boolean> /* Screen media observable */
|
||||||
@ -87,7 +89,7 @@ interface MountOptions {
|
|||||||
* @return Operator function
|
* @return Operator function
|
||||||
*/
|
*/
|
||||||
export function mountNavigation(
|
export function mountNavigation(
|
||||||
{ main$, viewport$, screen$ }: MountOptions
|
{ header$, main$, viewport$, screen$ }: MountOptions
|
||||||
): OperatorFunction<HTMLElement, Navigation> {
|
): OperatorFunction<HTMLElement, Navigation> {
|
||||||
return pipe(
|
return pipe(
|
||||||
switchMap(el => screen$
|
switchMap(el => screen$
|
||||||
@ -98,7 +100,7 @@ export function mountNavigation(
|
|||||||
if (screen) {
|
if (screen) {
|
||||||
return watchSidebar(el, { main$, viewport$ })
|
return watchSidebar(el, { main$, viewport$ })
|
||||||
.pipe(
|
.pipe(
|
||||||
paintSidebar(el),
|
paintSidebar(el, { header$ }),
|
||||||
map(sidebar => ({ sidebar }))
|
map(sidebar => ({ sidebar }))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ export function mountTableOfContents(
|
|||||||
/* Watch and paint sidebar */
|
/* Watch and paint sidebar */
|
||||||
const sidebar$ = watchSidebar(el, { main$, viewport$ })
|
const sidebar$ = watchSidebar(el, { main$, viewport$ })
|
||||||
.pipe(
|
.pipe(
|
||||||
paintSidebar(el)
|
paintSidebar(el, { header$ })
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Watch and paint anchor list (scroll spy) */
|
/* Watch and paint anchor list (scroll spy) */
|
||||||
|
@ -161,7 +161,7 @@ export function initialize(config: unknown) {
|
|||||||
|
|
||||||
const navigation$ = useComponent("navigation")
|
const navigation$ = useComponent("navigation")
|
||||||
.pipe(
|
.pipe(
|
||||||
mountNavigation({ main$, viewport$, screen$ })
|
mountNavigation({ header$, main$, viewport$, screen$ })
|
||||||
)
|
)
|
||||||
|
|
||||||
const toc$ = useComponent("toc")
|
const toc$ = useComponent("toc")
|
||||||
|
@ -88,9 +88,9 @@ export function watchViewport(): Observable<Viewport> {
|
|||||||
export function watchViewportAt(
|
export function watchViewportAt(
|
||||||
el: HTMLElement, { header$, viewport$ }: WatchRelativeOptions
|
el: HTMLElement, { header$, viewport$ }: WatchRelativeOptions
|
||||||
): Observable<Viewport> {
|
): Observable<Viewport> {
|
||||||
return combineLatest([viewport$, header$])
|
return combineLatest([header$, viewport$])
|
||||||
.pipe(
|
.pipe(
|
||||||
map(([{ offset, size }, { height }]) => ({
|
map(([{ height }, { offset, size }]) => ({
|
||||||
offset: {
|
offset: {
|
||||||
x: offset.x - el.offsetLeft,
|
x: offset.x - el.offsetLeft,
|
||||||
y: offset.y - el.offsetTop + height
|
y: offset.y - el.offsetTop + height
|
||||||
|
@ -149,9 +149,9 @@ export function watchAnchorList(
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
/* Re-compute partition when viewport offset changes */
|
/* Re-compute partition when viewport offset changes */
|
||||||
switchMap(index => combineLatest(viewport$, adjust$)
|
switchMap(index => combineLatest(adjust$, viewport$)
|
||||||
.pipe(
|
.pipe(
|
||||||
scan(([prev, next], [{ offset: { y } }, adjust]) => {
|
scan(([prev, next], [adjust, { offset: { y } }]) => {
|
||||||
|
|
||||||
/* Look forward */
|
/* Look forward */
|
||||||
while (next.length) {
|
while (next.length) {
|
||||||
|
@ -83,29 +83,30 @@ export function watchMain(
|
|||||||
)
|
)
|
||||||
|
|
||||||
/* Compute the main area's visible height */
|
/* Compute the main area's visible height */
|
||||||
const height$ = combineLatest([viewport$, adjust$])
|
const height$ = combineLatest([adjust$, viewport$])
|
||||||
.pipe(
|
.pipe(
|
||||||
map(([{ offset: { y }, size: { height } }, adjust]) => {
|
map(([adjust, { offset: { y }, size: { height } }]) => {
|
||||||
const top = el.offsetTop
|
const top = el.offsetTop
|
||||||
const bottom = el.offsetHeight + top
|
const bottom = el.offsetHeight + top
|
||||||
return height
|
return height
|
||||||
- Math.max(0, top - y, adjust)
|
- Math.max(0, top - y, adjust)
|
||||||
- Math.max(0, height + y - bottom)
|
- Math.max(0, height + y - bottom)
|
||||||
}),
|
}),
|
||||||
|
map(height => Math.max(0, height)),
|
||||||
distinctUntilChanged()
|
distinctUntilChanged()
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Compute whether the viewport offset is past the main area's top */
|
/* Compute whether the viewport offset is past the main area's top */
|
||||||
const active$ = combineLatest([viewport$, adjust$])
|
const active$ = combineLatest([adjust$, viewport$])
|
||||||
.pipe(
|
.pipe(
|
||||||
map(([{ offset: { y } }, adjust]) => y >= el.offsetTop - adjust),
|
map(([adjust, { offset: { y } }]) => y >= el.offsetTop - adjust),
|
||||||
distinctUntilChanged()
|
distinctUntilChanged()
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Combine into a single hot observable */
|
/* Combine into a single hot observable */
|
||||||
return combineLatest([height$, adjust$, active$])
|
return combineLatest([adjust$, height$, active$])
|
||||||
.pipe(
|
.pipe(
|
||||||
map(([height, adjust, active]) => ({
|
map(([adjust, height, active]) => ({
|
||||||
offset: el.offsetTop - adjust,
|
offset: el.offsetTop - adjust,
|
||||||
height,
|
height,
|
||||||
active
|
active
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { equals } from "ramda"
|
|
||||||
import {
|
import {
|
||||||
MonoTypeOperatorFunction,
|
MonoTypeOperatorFunction,
|
||||||
Observable,
|
Observable,
|
||||||
@ -30,21 +29,26 @@ import {
|
|||||||
} from "rxjs"
|
} from "rxjs"
|
||||||
import {
|
import {
|
||||||
distinctUntilChanged,
|
distinctUntilChanged,
|
||||||
|
distinctUntilKeyChanged,
|
||||||
finalize,
|
finalize,
|
||||||
map,
|
map,
|
||||||
observeOn,
|
observeOn,
|
||||||
shareReplay,
|
shareReplay,
|
||||||
tap
|
tap,
|
||||||
|
withLatestFrom
|
||||||
} from "rxjs/operators"
|
} from "rxjs/operators"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
resetSidebarHeight,
|
resetSidebarHeight,
|
||||||
resetSidebarLock,
|
resetSidebarLock,
|
||||||
|
resetSidebarOffset,
|
||||||
setSidebarHeight,
|
setSidebarHeight,
|
||||||
setSidebarLock
|
setSidebarLock,
|
||||||
|
setSidebarOffset
|
||||||
} from "actions"
|
} from "actions"
|
||||||
|
|
||||||
import { Viewport } from "../../agent"
|
import { Viewport } from "../../agent"
|
||||||
|
import { Header } from "../../header"
|
||||||
import { Main } from "../_"
|
import { Main } from "../_"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
@ -71,6 +75,13 @@ interface WatchOptions {
|
|||||||
viewport$: Observable<Viewport> /* Viewport observable */
|
viewport$: Observable<Viewport> /* Viewport observable */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paint options
|
||||||
|
*/
|
||||||
|
interface PaintOptions {
|
||||||
|
header$: Observable<Header> /* Header observable */
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Functions
|
* Functions
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
@ -93,30 +104,42 @@ export function watchSidebar(
|
|||||||
): Observable<Sidebar> {
|
): Observable<Sidebar> {
|
||||||
|
|
||||||
/* Adjust for internal main area offset */
|
/* Adjust for internal main area offset */
|
||||||
const adjust = parseFloat(
|
const adjust$ = viewport$
|
||||||
getComputedStyle(el.parentElement!)
|
.pipe(
|
||||||
.getPropertyValue("padding-top")
|
distinctUntilKeyChanged("size"),
|
||||||
)
|
map(() => parseFloat(
|
||||||
|
getComputedStyle(el.parentElement!)
|
||||||
|
.getPropertyValue("padding-top")
|
||||||
|
)),
|
||||||
|
distinctUntilChanged()
|
||||||
|
)
|
||||||
|
|
||||||
/* Compute the sidebar's available height */
|
/* Compute the sidebar's available height */
|
||||||
const height$ = combineLatest([viewport$, main$])
|
const height$ = viewport$
|
||||||
.pipe(
|
.pipe(
|
||||||
map(([{ offset: { y } }, { offset, height }]) => {
|
withLatestFrom(adjust$, main$),
|
||||||
return height - adjust + Math.min(adjust, Math.max(0, y - offset))
|
map(([{ offset: { y } }, adjust, { offset, height }]) => (
|
||||||
})
|
height
|
||||||
|
+ Math.min(adjust, Math.max(0, y - offset))
|
||||||
|
- adjust
|
||||||
|
)),
|
||||||
|
distinctUntilChanged()
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Compute whether the sidebar should be locked */
|
/* Compute whether the sidebar should be locked */
|
||||||
const lock$ = combineLatest([viewport$, main$])
|
const lock$ = viewport$
|
||||||
.pipe(
|
.pipe(
|
||||||
map(([{ offset: { y } }, { offset }]) => y >= offset + adjust)
|
withLatestFrom(adjust$, main$),
|
||||||
|
map(([{ offset: { y } }, adjust, { offset }]) => (
|
||||||
|
y >= offset + adjust
|
||||||
|
)),
|
||||||
|
distinctUntilChanged()
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Combine into single hot observable */
|
/* Combine into single hot observable */
|
||||||
return combineLatest([height$, lock$])
|
return combineLatest([height$, lock$])
|
||||||
.pipe(
|
.pipe(
|
||||||
map(([height, lock]) => ({ height, lock })),
|
map(([height, lock]) => ({ height, lock })),
|
||||||
distinctUntilChanged<Sidebar>(equals),
|
|
||||||
shareReplay(1)
|
shareReplay(1)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -127,23 +150,35 @@ export function watchSidebar(
|
|||||||
* Paint sidebar
|
* Paint sidebar
|
||||||
*
|
*
|
||||||
* @param el - Sidebar element
|
* @param el - Sidebar element
|
||||||
|
* @param options - Options
|
||||||
*
|
*
|
||||||
* @return Operator function
|
* @return Operator function
|
||||||
*/
|
*/
|
||||||
export function paintSidebar(
|
export function paintSidebar(
|
||||||
el: HTMLElement
|
el: HTMLElement, { header$ }: PaintOptions
|
||||||
): MonoTypeOperatorFunction<Sidebar> {
|
): MonoTypeOperatorFunction<Sidebar> {
|
||||||
return pipe(
|
return pipe(
|
||||||
|
|
||||||
/* Defer repaint to next animation frame */
|
/* Defer repaint to next animation frame */
|
||||||
observeOn(animationFrameScheduler),
|
observeOn(animationFrameScheduler),
|
||||||
tap(({ height, lock }) => {
|
withLatestFrom(header$),
|
||||||
|
tap(([{ height, lock }, { height: offset }]) => {
|
||||||
setSidebarHeight(el, height)
|
setSidebarHeight(el, height)
|
||||||
setSidebarLock(el, lock)
|
setSidebarLock(el, lock)
|
||||||
|
|
||||||
|
/* Set offset in locked state depending on header height */
|
||||||
|
if (lock)
|
||||||
|
setSidebarOffset(el, offset)
|
||||||
|
else
|
||||||
|
resetSidebarOffset(el)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/* Re-map to sidebar */
|
||||||
|
map(([sidebar]) => sidebar),
|
||||||
|
|
||||||
/* Reset on complete or error */
|
/* Reset on complete or error */
|
||||||
finalize(() => {
|
finalize(() => {
|
||||||
|
resetSidebarOffset(el)
|
||||||
resetSidebarHeight(el)
|
resetSidebarHeight(el)
|
||||||
resetSidebarLock(el)
|
resetSidebarLock(el)
|
||||||
})
|
})
|
||||||
|
@ -90,9 +90,9 @@ export function watchNavigationLayer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Determine topmost layer */
|
/* Determine topmost layer */
|
||||||
const layer$ = merge(
|
const layer$ = merge(...[...table.keys()].map(input => (
|
||||||
...[...table.keys()].map(input => fromEvent(input, "change"))
|
fromEvent(input, "change")
|
||||||
)
|
)))
|
||||||
.pipe(
|
.pipe(
|
||||||
map(() => getElementOrThrow(".md-nav__list", table.get(
|
map(() => getElementOrThrow(".md-nav__list", table.get(
|
||||||
findLast(({ checked }) => checked, [...table.keys()])!
|
findLast(({ checked }) => checked, [...table.keys()])!
|
||||||
|
Loading…
Reference in New Issue
Block a user