fix(style): resolve popover overflow issue causing incomplete display

This commit is contained in:
tuscan-blue 2025-04-04 21:17:44 +08:00
parent 20b155e587
commit 71823c5f89
2 changed files with 32 additions and 8 deletions

View File

@ -7,27 +7,33 @@ async function mouseEnterHandler(
this: HTMLAnchorElement, this: HTMLAnchorElement,
{ clientX, clientY }: { clientX: number; clientY: number }, { clientX, clientY }: { clientX: number; clientY: number },
) { ) {
inActivePopover()
const link = this const link = this
link.id = link.innerText
if (link.dataset.noPopover === "true") { if (link.dataset.noPopover === "true") {
return return
} }
async function setPosition(popoverElement: HTMLElement) { async function setPosition(popoverElement: HTMLElement) {
const { x, y } = await computePosition(link, popoverElement, { const { x, y } = await computePosition(link, popoverElement, {
strategy: "fixed",
middleware: [inline({ x: clientX, y: clientY }), shift(), flip()], middleware: [inline({ x: clientX, y: clientY }), shift(), flip()],
}) })
Object.assign(popoverElement.style, { Object.assign(popoverElement.style, {
left: `${x}px`, left: `${x}px`,
top: `${y}px`, transform: `translateY(${y}px)`,
}) })
} }
const hasAlreadyBeenFetched = () => const prevPopoverElement = document.getElementById(`popover-${link.id}`)
[...link.children].some((child) => child.classList.contains("popover")) const hasAlreadyBeenFetched = () => !!prevPopoverElement
// dont refetch if there's already a popover // dont refetch if there's already a popover
if (hasAlreadyBeenFetched()) { if (hasAlreadyBeenFetched()) {
return setPosition(link.lastChild as HTMLElement) setPosition(prevPopoverElement as HTMLElement)
prevPopoverElement?.classList.add("active-popover")
return
} }
const thisUrl = new URL(document.location.href) const thisUrl = new URL(document.location.href)
@ -91,7 +97,9 @@ async function mouseEnterHandler(
} }
setPosition(popoverElement) setPosition(popoverElement)
link.appendChild(popoverElement) popoverElement.id = `popover-${link.id}`
popoverElement?.classList.add("active-popover")
document.body.appendChild(popoverElement)
if (hash !== "") { if (hash !== "") {
const heading = popoverInner.querySelector(hash) as HTMLElement | null const heading = popoverInner.querySelector(hash) as HTMLElement | null
@ -102,10 +110,23 @@ async function mouseEnterHandler(
} }
} }
function inActivePopover() {
const allPopoverElements = document.querySelectorAll(".popover")
if (allPopoverElements) {
allPopoverElements.forEach((popoverElement) =>
popoverElement.classList.remove("active-popover"),
)
}
}
document.addEventListener("nav", () => { document.addEventListener("nav", () => {
const links = [...document.getElementsByClassName("internal")] as HTMLAnchorElement[] const links = [...document.getElementsByClassName("internal")] as HTMLAnchorElement[]
for (const link of links) { for (const link of links) {
link.addEventListener("mouseleave", inActivePopover)
link.addEventListener("mouseenter", mouseEnterHandler) link.addEventListener("mouseenter", mouseEnterHandler)
window.addCleanup(() => link.removeEventListener("mouseenter", mouseEnterHandler)) window.addCleanup(() => {
link.removeEventListener("mouseenter", mouseEnterHandler)
link.removeEventListener("mouseleave", inActivePopover)
})
} }
}) })

View File

@ -16,9 +16,11 @@
.popover { .popover {
z-index: 999; z-index: 999;
position: absolute; position: fixed;
overflow: visible; overflow: visible;
padding: 1rem; padding: 1rem;
top: 0;
will-change: transform;
& > .popover-inner { & > .popover-inner {
position: relative; position: relative;
@ -35,6 +37,7 @@
border-radius: 5px; border-radius: 5px;
box-shadow: 6px 6px 36px 0 rgba(0, 0, 0, 0.25); box-shadow: 6px 6px 36px 0 rgba(0, 0, 0, 0.25);
overflow: auto; overflow: auto;
overscroll-behavior: contain;
white-space: normal; white-space: normal;
user-select: none; user-select: none;
cursor: default; cursor: default;
@ -77,7 +80,7 @@
} }
} }
a:hover .popover, .active-popover,
.popover:hover { .popover:hover {
animation: dropin 0.3s ease; animation: dropin 0.3s ease;
animation-fill-mode: forwards; animation-fill-mode: forwards;