This commit is contained in:
Jacky Zhao 2023-06-17 16:05:46 -07:00
parent cb89cce183
commit 8bfee04c8c
10 changed files with 143 additions and 16 deletions

View file

@ -2,10 +2,30 @@ import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
import { Fragment, jsx, jsxs } from 'preact/jsx-runtime'
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
function Content({ tree }: QuartzComponentProps) {
// @ts-ignore (preact makes it angry)
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
return <article>{content}</article>
// @ts-ignore
import popoverScript from './scripts/popover.inline'
import popoverStyle from './styles/popover.scss'
interface Options {
enablePopover: boolean
}
export default (() => Content) satisfies QuartzComponentConstructor
const defaultOptions: Options = {
enablePopover: true
}
export default ((opts?: Partial<Options>) => {
function Content({ tree }: QuartzComponentProps) {
// @ts-ignore (preact makes it angry)
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
return <article>{content}</article>
}
const enablePopover = opts?.enablePopover ?? defaultOptions.enablePopover
if (enablePopover) {
Content.afterDOMLoaded = popoverScript
Content.css = popoverStyle
}
return Content
}) satisfies QuartzComponentConstructor

View file

@ -0,0 +1,41 @@
import { computePosition, inline, shift, autoPlacement } from "@floating-ui/dom"
document.addEventListener("nav", () => {
const links = [...document.getElementsByClassName("internal")] as HTMLLinkElement[]
const p = new DOMParser()
for (const link of links) {
link.addEventListener("mouseenter", async ({ clientX, clientY }) => {
if (link.dataset.fetchedPopover === "true") return
const url = link.href
const contents = await fetch(`${url}`)
.then((res) => res.text())
.catch((err) => {
console.error(err)
})
if (!contents) return
const html = p.parseFromString(contents, "text/html")
const elts = [...html.getElementsByClassName("popover-hint")]
if (elts.length === 0) return
const popoverElement = document.createElement("div")
popoverElement.classList.add("popover")
elts.forEach(elt => popoverElement.appendChild(elt))
const { x, y } = await computePosition(link, popoverElement, {
middleware: [inline({
x: clientX,
y: clientY
}), shift(), autoPlacement()]
})
Object.assign(popoverElement.style, {
left: `${x}px`,
top: `${y}px`,
})
link.appendChild(popoverElement)
link.dataset.fetchedPopover = "true"
})
}
})

View file

@ -22,11 +22,13 @@ function toggleToc(this: HTMLElement) {
}
function setupToc() {
const toc = document.getElementById("toc")!
const content = toc.nextElementSibling as HTMLElement
content.style.maxHeight = content.scrollHeight + "px"
toc.removeEventListener("click", toggleToc)
toc.addEventListener("click", toggleToc)
const toc = document.getElementById("toc")
if (toc) {
const content = toc.nextElementSibling as HTMLElement
content.style.maxHeight = content.scrollHeight + "px"
toc.removeEventListener("click", toggleToc)
toc.addEventListener("click", toggleToc)
}
}
window.addEventListener("resize", setupToc)

View file

@ -0,0 +1,43 @@
@keyframes dropin {
0% {
opacity: 0;
visibility: hidden;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
visibility: visible;
}
}
.popover {
z-index: 999;
position: absolute;
overflow: scroll;
width: 30rem;
height: 20rem;
padding: 0 1rem;
margin-top: -1rem;
border: 1px solid var(--lightgray);
background-color: var(--light);
border-radius: 5px;
box-shadow: 6px 6px 36px 0 rgba(0,0,0,0.25);
font-weight: initial;
visibility: hidden;
opacity: 0;
transition: opacity 0.2s ease, visibility 0.2s ease;
@media all and (max-width: 600px) {
display: none !important;
}
}
a:hover .popover, .popover:hover {
animation: dropin 0.5s ease;
opacity: 1;
visibility: visible;
}