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>
|
||||
{% endblock %}
|
||||
{% 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 %}
|
||||
<script src="{{ path | url }}"></script>
|
||||
{% endfor %}
|
||||
|
@ -213,7 +213,7 @@ const content$ = defer(() => merge(
|
||||
|
||||
/* Content */
|
||||
...getComponentElements("content")
|
||||
.map(el => mountContent(el, { target$, print$ })),
|
||||
.map(el => mountContent(el, { viewport$, target$, print$ })),
|
||||
|
||||
/* Search highlighting */
|
||||
...getComponentElements("content")
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
import { Observable, merge } from "rxjs"
|
||||
|
||||
import { getElements } from "~/browser"
|
||||
import { Viewport, getElements } from "~/browser"
|
||||
|
||||
import { Component } from "../../_"
|
||||
import { Annotation } from "../annotation"
|
||||
@ -68,6 +68,7 @@ export type Content =
|
||||
* Mount options
|
||||
*/
|
||||
interface MountOptions {
|
||||
viewport$: Observable<Viewport> /* Viewport observable */
|
||||
target$: Observable<HTMLElement> /* Location target observable */
|
||||
print$: Observable<boolean> /* Media print observable */
|
||||
}
|
||||
@ -88,7 +89,7 @@ interface MountOptions {
|
||||
* @returns Content component observable
|
||||
*/
|
||||
export function mountContent(
|
||||
el: HTMLElement, { target$, print$ }: MountOptions
|
||||
el: HTMLElement, { viewport$, target$, print$ }: MountOptions
|
||||
): Observable<Component<Content>> {
|
||||
return merge(
|
||||
|
||||
@ -110,6 +111,6 @@ export function mountContent(
|
||||
|
||||
/* Content tabs */
|
||||
...getElements("[data-tabs]", el)
|
||||
.map(child => mountContentTabs(child))
|
||||
.map(child => mountContentTabs(child, { viewport$ }))
|
||||
)
|
||||
}
|
||||
|
@ -37,11 +37,13 @@ import {
|
||||
subscribeOn,
|
||||
takeLast,
|
||||
takeUntil,
|
||||
tap
|
||||
tap,
|
||||
withLatestFrom
|
||||
} from "rxjs"
|
||||
|
||||
import { feature } from "~/_"
|
||||
import {
|
||||
Viewport,
|
||||
getElement,
|
||||
getElementContentOffset,
|
||||
getElementContentSize,
|
||||
@ -66,6 +68,17 @@ export interface ContentTabs {
|
||||
active: HTMLLabelElement /* Active tab label */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Mount options
|
||||
*/
|
||||
interface MountOptions {
|
||||
viewport$: Observable<Viewport> /* Viewport observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
@ -102,11 +115,12 @@ export function watchContentTabs(
|
||||
* this functionality ourselves.
|
||||
*
|
||||
* @param el - Content tabs element
|
||||
* @param options - Options
|
||||
*
|
||||
* @returns Content tabs component observable
|
||||
*/
|
||||
export function mountContentTabs(
|
||||
el: HTMLElement
|
||||
el: HTMLElement, { viewport$ }: MountOptions
|
||||
): Observable<Component<ContentTabs>> {
|
||||
|
||||
/* Render content tab previous button for pagination */
|
||||
@ -189,23 +203,44 @@ export function mountContentTabs(
|
||||
|
||||
/* Set up linking of content tabs, if enabled */
|
||||
if (feature("content.tabs.link"))
|
||||
push$.pipe(skip(1))
|
||||
.subscribe(({ active }) => {
|
||||
push$.pipe(
|
||||
skip(1),
|
||||
withLatestFrom(viewport$)
|
||||
)
|
||||
.subscribe(([{ active }, { offset }]) => {
|
||||
const tab = active.innerText.trim()
|
||||
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.innerText.trim() === tab) {
|
||||
input.click()
|
||||
break
|
||||
}
|
||||
}
|
||||
if (active.hasAttribute("data-md-switching")) {
|
||||
active.removeAttribute("data-md-switching")
|
||||
|
||||
/* Persist active tabs in local storage */
|
||||
const tabs = __md_get<string[]>("__tabs") || []
|
||||
__md_set("__tabs", [...new Set([tab, ...tabs])])
|
||||
/* Determine viewport offset of active tab */
|
||||
} else {
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user