mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2026-07-23 22:33:42 -04:00
Restructured content observables
This commit is contained in:
@@ -25,11 +25,8 @@ import { Observable, merge } from "rxjs"
|
||||
import { getElements } from "~/browser"
|
||||
|
||||
import { Component } from "../../_"
|
||||
import {
|
||||
Annotation,
|
||||
CodeBlock,
|
||||
mountCodeBlock
|
||||
} from "../code"
|
||||
import { Annotation } from "../annotation"
|
||||
import { CodeBlock, mountCodeBlock } from "../code"
|
||||
import { Details, mountDetails } from "../details"
|
||||
import { DataTable, mountDataTable } from "../table"
|
||||
import { ContentTabs, mountContentTabs } from "../tabs"
|
||||
|
||||
@@ -45,18 +45,18 @@ import {
|
||||
watchElementOffset
|
||||
} from "~/browser"
|
||||
|
||||
import { Component } from "../../../../_"
|
||||
import { Component } from "../../../_"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Code annotation
|
||||
* Annotation
|
||||
*/
|
||||
export interface Annotation {
|
||||
active: boolean /* Code annotation is visible */
|
||||
offset: ElementOffset /* Code annotation offset */
|
||||
active: boolean /* Annotation is active */
|
||||
offset: ElementOffset /* Annotation offset */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
@@ -64,12 +64,12 @@ export interface Annotation {
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Watch code annotation
|
||||
* Watch annotation
|
||||
*
|
||||
* @param el - Code annotation element
|
||||
* @param container - Containing code block element
|
||||
* @param el - Annotation element
|
||||
* @param container - Containing element
|
||||
*
|
||||
* @returns Code annotation observable
|
||||
* @returns Annotation observable
|
||||
*/
|
||||
export function watchAnnotation(
|
||||
el: HTMLElement, container: HTMLElement
|
||||
@@ -88,7 +88,7 @@ export function watchAnnotation(
|
||||
})
|
||||
)
|
||||
|
||||
/* Actively watch code annotation on focus */
|
||||
/* Actively watch annotation on focus */
|
||||
return watchElementFocus(el)
|
||||
.pipe(
|
||||
switchMap(active => offset$
|
||||
@@ -101,12 +101,12 @@ export function watchAnnotation(
|
||||
}
|
||||
|
||||
/**
|
||||
* Mount code annotation
|
||||
* Mount annotation
|
||||
*
|
||||
* @param el - Code annotation element
|
||||
* @param container - Containing code block element
|
||||
* @param el - Annotation element
|
||||
* @param container - Containing element
|
||||
*
|
||||
* @returns Code annotation component observable
|
||||
* @returns Annotation component observable
|
||||
*/
|
||||
export function mountAnnotation(
|
||||
el: HTMLElement, container: HTMLElement
|
||||
@@ -38,7 +38,7 @@ import {
|
||||
} from "~/browser"
|
||||
import { renderAnnotation } from "~/templates"
|
||||
|
||||
import { Component } from "../../../../_"
|
||||
import { Component } from "../../../_"
|
||||
import {
|
||||
Annotation,
|
||||
mountAnnotation
|
||||
@@ -60,11 +60,11 @@ interface MountOptions {
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Find all code annotation markers in the given code block
|
||||
* Find all annotation markers in the given code block
|
||||
*
|
||||
* @param container - Containing code block element
|
||||
* @param container - Containing element
|
||||
*
|
||||
* @returns Code annotation markers
|
||||
* @returns Annotation markers
|
||||
*/
|
||||
function findAnnotationMarkers(container: HTMLElement): Text[] {
|
||||
const markers: Text[] = []
|
||||
@@ -97,18 +97,18 @@ function swap(source: HTMLElement, target: HTMLElement): void {
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Mount code annotation list
|
||||
* Mount annotation list
|
||||
*
|
||||
* This function analyzes the given container code block and checks for markers
|
||||
* referring to elements in the given code annotation list. If no markers are
|
||||
* found, the list is left untouched. Otherwise, list elements are rendered as
|
||||
* code annotations inside the code block.
|
||||
* This function analyzes the containing code block and checks for markers
|
||||
* referring to elements in the given annotation list. If no markers are found,
|
||||
* the list is left untouched. Otherwise, list elements are rendered as
|
||||
* annotations inside the code block.
|
||||
*
|
||||
* @param el - Code annotation list element
|
||||
* @param container - Containing code block element
|
||||
* @param el - Annotation list element
|
||||
* @param container - Containing element
|
||||
* @param options - Options
|
||||
*
|
||||
* @returns Code annotation list component observable
|
||||
* @returns Annotation component observable
|
||||
*/
|
||||
export function mountAnnotationList(
|
||||
el: HTMLElement, container: HTMLElement, { print$ }: MountOptions
|
||||
@@ -138,7 +138,7 @@ export function mountAnnotationList(
|
||||
.subscribe(active => {
|
||||
el.hidden = !active
|
||||
|
||||
/* Move annotation contents back into list */
|
||||
/* Show annotations in code block or list (print) */
|
||||
for (const [id, annotation] of annotations) {
|
||||
const inner = getElement(".md-typeset", annotation)
|
||||
const child = getElement(`li:nth-child(${id})`, el)
|
||||
@@ -1,216 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import ClipboardJS from "clipboard"
|
||||
import {
|
||||
EMPTY,
|
||||
Observable,
|
||||
Subject,
|
||||
defer,
|
||||
distinctUntilChanged,
|
||||
distinctUntilKeyChanged,
|
||||
finalize,
|
||||
map,
|
||||
mergeWith,
|
||||
switchMap,
|
||||
takeLast,
|
||||
takeUntil,
|
||||
tap
|
||||
} from "rxjs"
|
||||
|
||||
import { feature } from "~/_"
|
||||
import {
|
||||
getElementContentSize,
|
||||
watchElementSize
|
||||
} from "~/browser"
|
||||
import { renderClipboardButton } from "~/templates"
|
||||
|
||||
import { Component } from "../../../_"
|
||||
import {
|
||||
Annotation,
|
||||
mountAnnotationList
|
||||
} from "../annotation"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Code block
|
||||
*/
|
||||
export interface CodeBlock {
|
||||
scrollable: boolean /* Code block overflows */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Mount options
|
||||
*/
|
||||
interface MountOptions {
|
||||
print$: Observable<boolean> /* Media print observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Data
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Global sequence number for Clipboard.js integration
|
||||
*/
|
||||
let sequence = 0
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Find candidate list element directly following a code block
|
||||
*
|
||||
* @param el - Code block element
|
||||
*
|
||||
* @returns List element or nothing
|
||||
*/
|
||||
function findCandidateList(el: HTMLElement): HTMLElement | undefined {
|
||||
if (el.nextElementSibling) {
|
||||
const sibling = el.nextElementSibling as HTMLElement
|
||||
if (sibling.tagName === "OL")
|
||||
return sibling
|
||||
|
||||
/* Skip empty paragraphs - see https://bit.ly/3r4ZJ2O */
|
||||
else if (sibling.tagName === "P" && !sibling.children.length)
|
||||
return findCandidateList(sibling)
|
||||
}
|
||||
|
||||
/* Everything else */
|
||||
return undefined
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Watch code block
|
||||
*
|
||||
* This function monitors size changes of the viewport, as well as switches of
|
||||
* content tabs with embedded code blocks, as both may trigger overflow.
|
||||
*
|
||||
* @param el - Code block element
|
||||
*
|
||||
* @returns Code block observable
|
||||
*/
|
||||
export function watchCodeBlock(
|
||||
el: HTMLElement
|
||||
): Observable<CodeBlock> {
|
||||
return watchElementSize(el)
|
||||
.pipe(
|
||||
map(({ width }) => {
|
||||
const content = getElementContentSize(el)
|
||||
return {
|
||||
scrollable: content.width > width
|
||||
}
|
||||
}),
|
||||
distinctUntilKeyChanged("scrollable")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mount code block
|
||||
*
|
||||
* This function ensures that an overflowing code block is focusable through
|
||||
* keyboard, so it can be scrolled without a mouse to improve on accessibility.
|
||||
* Furthermore, if code annotations are enabled, they are mounted if and only
|
||||
* if the code block is currently visible, e.g., not in a hidden content tab.
|
||||
*
|
||||
* @param el - Code block element
|
||||
* @param options - Options
|
||||
*
|
||||
* @returns Code block and annotation component observable
|
||||
*/
|
||||
export function mountCodeBlock(
|
||||
el: HTMLElement, options: MountOptions
|
||||
): Observable<Component<CodeBlock | Annotation>> {
|
||||
const { matches: hover } = matchMedia("(hover)")
|
||||
return defer(() => {
|
||||
const push$ = new Subject<CodeBlock>()
|
||||
push$.subscribe(({ scrollable }) => {
|
||||
if (scrollable && hover)
|
||||
el.setAttribute("tabindex", "0")
|
||||
else
|
||||
el.removeAttribute("tabindex")
|
||||
})
|
||||
|
||||
/* Render button for Clipboard.js integration */
|
||||
if (ClipboardJS.isSupported()) {
|
||||
const parent = el.closest("pre")!
|
||||
parent.id = `__code_${++sequence}`
|
||||
parent.insertBefore(
|
||||
renderClipboardButton(parent.id),
|
||||
el
|
||||
)
|
||||
}
|
||||
|
||||
/* Handle code annotations */
|
||||
const container = el.closest([
|
||||
":not(td.code) > .highlight", /* Code blocks */
|
||||
".highlighttable" /* Code blocks with line numbers */
|
||||
].join(", "))
|
||||
if (container instanceof HTMLElement) {
|
||||
const list = findCandidateList(container)
|
||||
|
||||
/* Mount code annotations, if enabled */
|
||||
if (typeof list !== "undefined" && (
|
||||
container.classList.contains("annotate") ||
|
||||
feature("content.code.annotate")
|
||||
)) {
|
||||
const annotations$ = mountAnnotationList(list, el, options)
|
||||
|
||||
/* Create and return component */
|
||||
return watchCodeBlock(el)
|
||||
.pipe(
|
||||
tap(state => push$.next(state)),
|
||||
finalize(() => push$.complete()),
|
||||
map(state => ({ ref: el, ...state })),
|
||||
mergeWith(watchElementSize(container)
|
||||
.pipe(
|
||||
takeUntil(push$.pipe(takeLast(1))),
|
||||
map(({ width, height }) => width && height),
|
||||
distinctUntilChanged(),
|
||||
switchMap(active => active ? annotations$ : EMPTY)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/* Create and return component */
|
||||
return watchCodeBlock(el)
|
||||
.pipe(
|
||||
tap(state => push$.next(state)),
|
||||
finalize(() => push$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -20,5 +20,197 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
export * from "./_"
|
||||
export * from "./annotation"
|
||||
import ClipboardJS from "clipboard"
|
||||
import {
|
||||
EMPTY,
|
||||
Observable,
|
||||
Subject,
|
||||
defer,
|
||||
distinctUntilChanged,
|
||||
distinctUntilKeyChanged,
|
||||
finalize,
|
||||
map,
|
||||
mergeWith,
|
||||
switchMap,
|
||||
takeLast,
|
||||
takeUntil,
|
||||
tap
|
||||
} from "rxjs"
|
||||
|
||||
import { feature } from "~/_"
|
||||
import {
|
||||
getElementContentSize,
|
||||
watchElementSize
|
||||
} from "~/browser"
|
||||
import { renderClipboardButton } from "~/templates"
|
||||
|
||||
import { Component } from "../../_"
|
||||
import {
|
||||
Annotation,
|
||||
mountAnnotationList
|
||||
} from "../annotation"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Code block
|
||||
*/
|
||||
export interface CodeBlock {
|
||||
scrollable: boolean /* Code block overflows */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Mount options
|
||||
*/
|
||||
interface MountOptions {
|
||||
print$: Observable<boolean> /* Media print observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Data
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Global sequence number for Clipboard.js integration
|
||||
*/
|
||||
let sequence = 0
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Find candidate list element directly following a code block
|
||||
*
|
||||
* @param el - Code block element
|
||||
*
|
||||
* @returns List element or nothing
|
||||
*/
|
||||
function findCandidateList(el: HTMLElement): HTMLElement | undefined {
|
||||
if (el.nextElementSibling) {
|
||||
const sibling = el.nextElementSibling as HTMLElement
|
||||
if (sibling.tagName === "OL")
|
||||
return sibling
|
||||
|
||||
/* Skip empty paragraphs - see https://bit.ly/3r4ZJ2O */
|
||||
else if (sibling.tagName === "P" && !sibling.children.length)
|
||||
return findCandidateList(sibling)
|
||||
}
|
||||
|
||||
/* Everything else */
|
||||
return undefined
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Watch code block
|
||||
*
|
||||
* This function monitors size changes of the viewport, as well as switches of
|
||||
* content tabs with embedded code blocks, as both may trigger overflow.
|
||||
*
|
||||
* @param el - Code block element
|
||||
*
|
||||
* @returns Code block observable
|
||||
*/
|
||||
export function watchCodeBlock(
|
||||
el: HTMLElement
|
||||
): Observable<CodeBlock> {
|
||||
return watchElementSize(el)
|
||||
.pipe(
|
||||
map(({ width }) => {
|
||||
const content = getElementContentSize(el)
|
||||
return {
|
||||
scrollable: content.width > width
|
||||
}
|
||||
}),
|
||||
distinctUntilKeyChanged("scrollable")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mount code block
|
||||
*
|
||||
* This function ensures that an overflowing code block is focusable through
|
||||
* keyboard, so it can be scrolled without a mouse to improve on accessibility.
|
||||
* Furthermore, if code annotations are enabled, they are mounted if and only
|
||||
* if the code block is currently visible, e.g., not in a hidden content tab.
|
||||
*
|
||||
* @param el - Code block element
|
||||
* @param options - Options
|
||||
*
|
||||
* @returns Code block and annotation component observable
|
||||
*/
|
||||
export function mountCodeBlock(
|
||||
el: HTMLElement, options: MountOptions
|
||||
): Observable<Component<CodeBlock | Annotation>> {
|
||||
const { matches: hover } = matchMedia("(hover)")
|
||||
return defer(() => {
|
||||
const push$ = new Subject<CodeBlock>()
|
||||
push$.subscribe(({ scrollable }) => {
|
||||
if (scrollable && hover)
|
||||
el.setAttribute("tabindex", "0")
|
||||
else
|
||||
el.removeAttribute("tabindex")
|
||||
})
|
||||
|
||||
/* Render button for Clipboard.js integration */
|
||||
if (ClipboardJS.isSupported()) {
|
||||
const parent = el.closest("pre")!
|
||||
parent.id = `__code_${++sequence}`
|
||||
parent.insertBefore(
|
||||
renderClipboardButton(parent.id),
|
||||
el
|
||||
)
|
||||
}
|
||||
|
||||
/* Handle code annotations */
|
||||
const container = el.closest([
|
||||
":not(td.code) > .highlight", /* Code blocks */
|
||||
".highlighttable" /* Code blocks with line numbers */
|
||||
].join(", "))
|
||||
if (container instanceof HTMLElement) {
|
||||
const list = findCandidateList(container)
|
||||
|
||||
/* Mount code annotations, if enabled */
|
||||
if (typeof list !== "undefined" && (
|
||||
container.classList.contains("annotate") ||
|
||||
feature("content.code.annotate")
|
||||
)) {
|
||||
const annotations$ = mountAnnotationList(list, el, options)
|
||||
|
||||
/* Create and return component */
|
||||
return watchCodeBlock(el)
|
||||
.pipe(
|
||||
tap(state => push$.next(state)),
|
||||
finalize(() => push$.complete()),
|
||||
map(state => ({ ref: el, ...state })),
|
||||
mergeWith(watchElementSize(container)
|
||||
.pipe(
|
||||
takeUntil(push$.pipe(takeLast(1))),
|
||||
map(({ width, height }) => width && height),
|
||||
distinctUntilChanged(),
|
||||
switchMap(active => active ? annotations$ : EMPTY)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/* Create and return component */
|
||||
return watchCodeBlock(el)
|
||||
.pipe(
|
||||
tap(state => push$.next(state)),
|
||||
finalize(() => push$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ import { Component } from "../../_"
|
||||
*/
|
||||
export interface Details {
|
||||
action: "open" | "close" /* Details state */
|
||||
scroll?: boolean /* Scroll into view */
|
||||
reveal?: boolean /* Details is revealed */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
@@ -89,7 +89,7 @@ export function watchDetails(
|
||||
.pipe(
|
||||
map(target => target.closest("details:not([open])")!),
|
||||
filter(details => el === details),
|
||||
mapTo<Details>({ action: "open", scroll: true })
|
||||
mapTo<Details>({ action: "open", reveal: true })
|
||||
),
|
||||
|
||||
/* Open details on print and close afterwards */
|
||||
@@ -120,12 +120,12 @@ export function mountDetails(
|
||||
): Observable<Component<Details>> {
|
||||
return defer(() => {
|
||||
const push$ = new Subject<Details>()
|
||||
push$.subscribe(({ action, scroll }) => {
|
||||
push$.subscribe(({ action, reveal }) => {
|
||||
if (action === "open")
|
||||
el.setAttribute("open", "")
|
||||
else
|
||||
el.removeAttribute("open")
|
||||
if (scroll)
|
||||
if (reveal)
|
||||
el.scrollIntoView()
|
||||
})
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
export * from "./_"
|
||||
export * from "./annotation"
|
||||
export * from "./code"
|
||||
export * from "./details"
|
||||
export * from "./table"
|
||||
|
||||
@@ -46,7 +46,7 @@ import { Component } from "../_"
|
||||
*/
|
||||
export interface Dialog {
|
||||
message: string /* Dialog message */
|
||||
open: boolean /* Dialog is visible */
|
||||
active: boolean /* Dialog is active */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
@@ -89,7 +89,7 @@ export function watchDialog(
|
||||
of(false).pipe(delay(2000))
|
||||
)
|
||||
.pipe(
|
||||
map(open => ({ message, open }))
|
||||
map(active => ({ message, active }))
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -112,9 +112,9 @@ export function mountDialog(
|
||||
const inner = getElement(".md-typeset", el)
|
||||
return defer(() => {
|
||||
const push$ = new Subject<Dialog>()
|
||||
push$.subscribe(({ message, open }) => {
|
||||
push$.subscribe(({ message, active }) => {
|
||||
inner.textContent = message
|
||||
if (open)
|
||||
if (active)
|
||||
el.setAttribute("data-md-state", "open")
|
||||
else
|
||||
el.removeAttribute("data-md-state")
|
||||
|
||||
@@ -59,7 +59,7 @@ import { Main } from "../../main"
|
||||
export interface Header {
|
||||
height: number /* Header visible height */
|
||||
sticky: boolean /* Header stickyness */
|
||||
hidden: boolean /* User scrolled past threshold */
|
||||
hidden: boolean /* Header is hidden */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
@@ -49,7 +49,7 @@ import { Header } from "../_"
|
||||
* Header
|
||||
*/
|
||||
export interface HeaderTitle {
|
||||
active: boolean /* User scrolled past first headline */
|
||||
active: boolean /* Header title is active */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
@@ -46,7 +46,7 @@ import { Header } from "../header"
|
||||
export interface Main {
|
||||
offset: number /* Main area top offset */
|
||||
height: number /* Main area visible height */
|
||||
active: boolean /* User scrolled past header */
|
||||
active: boolean /* Main area is active */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
@@ -53,7 +53,7 @@ import { Main } from "../main"
|
||||
*/
|
||||
export interface Sidebar {
|
||||
height: number /* Sidebar height */
|
||||
locked: boolean /* User scrolled past header */
|
||||
locked: boolean /* Sidebar is locked */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
@@ -50,7 +50,7 @@ import { Header } from "../header"
|
||||
* Navigation tabs
|
||||
*/
|
||||
export interface Tabs {
|
||||
hidden: boolean /* User scrolled past tabs */
|
||||
hidden: boolean /* Navigation tabs are hidden */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
@@ -49,7 +49,7 @@ import { Main } from "../main"
|
||||
* Back-to-top button
|
||||
*/
|
||||
export interface BackToTop {
|
||||
hidden: boolean /* User scrolled up */
|
||||
hidden: boolean /* Back-to-top button is hidden */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user