mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2024-06-14 11:52:32 +03:00
Fixed scroll offset when activating linked content tabs
This commit is contained in:
parent
e7a8ae0113
commit
ec9e2a3258
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
8
material/assets/javascripts/bundle.d691e9de.min.js.map
Normal file
8
material/assets/javascripts/bundle.d691e9de.min.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -245,7 +245,7 @@
|
|||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="{{ 'assets/javascripts/bundle.48f2be22.min.js' | url }}"></script>
|
<script src="{{ 'assets/javascripts/bundle.d691e9de.min.js' | url }}"></script>
|
||||||
{% for path in config.extra_javascript %}
|
{% for path in config.extra_javascript %}
|
||||||
<script src="{{ path | url }}"></script>
|
<script src="{{ path | url }}"></script>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -213,7 +213,7 @@ const content$ = defer(() => merge(
|
|||||||
|
|
||||||
/* Content */
|
/* Content */
|
||||||
...getComponentElements("content")
|
...getComponentElements("content")
|
||||||
.map(el => mountContent(el, { target$, print$ })),
|
.map(el => mountContent(el, { viewport$, target$, print$ })),
|
||||||
|
|
||||||
/* Search highlighting */
|
/* Search highlighting */
|
||||||
...getComponentElements("content")
|
...getComponentElements("content")
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
import { Observable, merge } from "rxjs"
|
import { Observable, merge } from "rxjs"
|
||||||
|
|
||||||
import { getElements } from "~/browser"
|
import { Viewport, getElements } from "~/browser"
|
||||||
|
|
||||||
import { Component } from "../../_"
|
import { Component } from "../../_"
|
||||||
import { Annotation } from "../annotation"
|
import { Annotation } from "../annotation"
|
||||||
@ -68,6 +68,7 @@ export type Content =
|
|||||||
* Mount options
|
* Mount options
|
||||||
*/
|
*/
|
||||||
interface MountOptions {
|
interface MountOptions {
|
||||||
|
viewport$: Observable<Viewport> /* Viewport observable */
|
||||||
target$: Observable<HTMLElement> /* Location target observable */
|
target$: Observable<HTMLElement> /* Location target observable */
|
||||||
print$: Observable<boolean> /* Media print observable */
|
print$: Observable<boolean> /* Media print observable */
|
||||||
}
|
}
|
||||||
@ -88,7 +89,7 @@ interface MountOptions {
|
|||||||
* @returns Content component observable
|
* @returns Content component observable
|
||||||
*/
|
*/
|
||||||
export function mountContent(
|
export function mountContent(
|
||||||
el: HTMLElement, { target$, print$ }: MountOptions
|
el: HTMLElement, { viewport$, target$, print$ }: MountOptions
|
||||||
): Observable<Component<Content>> {
|
): Observable<Component<Content>> {
|
||||||
return merge(
|
return merge(
|
||||||
|
|
||||||
@ -110,6 +111,6 @@ export function mountContent(
|
|||||||
|
|
||||||
/* Content tabs */
|
/* Content tabs */
|
||||||
...getElements("[data-tabs]", el)
|
...getElements("[data-tabs]", el)
|
||||||
.map(child => mountContentTabs(child))
|
.map(child => mountContentTabs(child, { viewport$ }))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -37,11 +37,13 @@ import {
|
|||||||
subscribeOn,
|
subscribeOn,
|
||||||
takeLast,
|
takeLast,
|
||||||
takeUntil,
|
takeUntil,
|
||||||
tap
|
tap,
|
||||||
|
withLatestFrom
|
||||||
} from "rxjs"
|
} from "rxjs"
|
||||||
|
|
||||||
import { feature } from "~/_"
|
import { feature } from "~/_"
|
||||||
import {
|
import {
|
||||||
|
Viewport,
|
||||||
getElement,
|
getElement,
|
||||||
getElementContentOffset,
|
getElementContentOffset,
|
||||||
getElementContentSize,
|
getElementContentSize,
|
||||||
@ -66,6 +68,17 @@ export interface ContentTabs {
|
|||||||
active: HTMLLabelElement /* Active tab label */
|
active: HTMLLabelElement /* Active tab label */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Helper types
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mount options
|
||||||
|
*/
|
||||||
|
interface MountOptions {
|
||||||
|
viewport$: Observable<Viewport> /* Viewport observable */
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Functions
|
* Functions
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
@ -102,11 +115,12 @@ export function watchContentTabs(
|
|||||||
* this functionality ourselves.
|
* this functionality ourselves.
|
||||||
*
|
*
|
||||||
* @param el - Content tabs element
|
* @param el - Content tabs element
|
||||||
|
* @param options - Options
|
||||||
*
|
*
|
||||||
* @returns Content tabs component observable
|
* @returns Content tabs component observable
|
||||||
*/
|
*/
|
||||||
export function mountContentTabs(
|
export function mountContentTabs(
|
||||||
el: HTMLElement
|
el: HTMLElement, { viewport$ }: MountOptions
|
||||||
): Observable<Component<ContentTabs>> {
|
): Observable<Component<ContentTabs>> {
|
||||||
|
|
||||||
/* Render content tab previous button for pagination */
|
/* Render content tab previous button for pagination */
|
||||||
@ -189,23 +203,44 @@ export function mountContentTabs(
|
|||||||
|
|
||||||
/* Set up linking of content tabs, if enabled */
|
/* Set up linking of content tabs, if enabled */
|
||||||
if (feature("content.tabs.link"))
|
if (feature("content.tabs.link"))
|
||||||
push$.pipe(skip(1))
|
push$.pipe(
|
||||||
.subscribe(({ active }) => {
|
skip(1),
|
||||||
|
withLatestFrom(viewport$)
|
||||||
|
)
|
||||||
|
.subscribe(([{ active }, { offset }]) => {
|
||||||
const tab = active.innerText.trim()
|
const tab = active.innerText.trim()
|
||||||
for (const set of getElements("[data-tabs]"))
|
if (active.hasAttribute("data-md-switching")) {
|
||||||
for (const input of getElements<HTMLInputElement>(
|
active.removeAttribute("data-md-switching")
|
||||||
":scope > input", set
|
|
||||||
)) {
|
|
||||||
const label = getElement(`label[for="${input.id}"]`)
|
|
||||||
if (label.innerText.trim() === tab) {
|
|
||||||
input.click()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Persist active tabs in local storage */
|
/* Determine viewport offset of active tab */
|
||||||
const tabs = __md_get<string[]>("__tabs") || []
|
} else {
|
||||||
__md_set("__tabs", [...new Set([tab, ...tabs])])
|
const y = el.offsetTop - offset.y
|
||||||
|
|
||||||
|
/* Passively activate other tabs */
|
||||||
|
for (const set of getElements("[data-tabs]"))
|
||||||
|
for (const input of getElements<HTMLInputElement>(
|
||||||
|
":scope > input", set
|
||||||
|
)) {
|
||||||
|
const label = getElement(`label[for="${input.id}"]`)
|
||||||
|
if (
|
||||||
|
label !== active &&
|
||||||
|
label.innerText.trim() === tab
|
||||||
|
) {
|
||||||
|
label.setAttribute("data-md-switching", "")
|
||||||
|
input.click()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bring active tab into view */
|
||||||
|
window.scrollTo({
|
||||||
|
top: el.offsetTop - y
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Persist active tabs in local storage */
|
||||||
|
const tabs = __md_get<string[]>("__tabs") || []
|
||||||
|
__md_set("__tabs", [...new Set([tab, ...tabs])])
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/* Create and return component */
|
/* Create and return component */
|
||||||
|
Loading…
Reference in New Issue
Block a user