fix(popover): popover id calculation + scroll consistency
This commit is contained in:
parent
b1a920e5c0
commit
e9b60c7285
1 changed files with 23 additions and 27 deletions
|
@ -9,10 +9,7 @@ async function mouseEnterHandler(
|
|||
this: HTMLAnchorElement,
|
||||
{ clientX, clientY }: { clientX: number; clientY: number },
|
||||
) {
|
||||
clearActivePopover()
|
||||
|
||||
const link = this
|
||||
const id = randomIdNonSecure()
|
||||
if (link.dataset.noPopover === "true") {
|
||||
return
|
||||
}
|
||||
|
@ -27,23 +24,33 @@ async function mouseEnterHandler(
|
|||
})
|
||||
}
|
||||
|
||||
const prevPopoverElement = document.getElementById(`popover-${id}`)
|
||||
const hasAlreadyBeenFetched = () => !!document.getElementById(`popover-${id}`)
|
||||
function showPopover(popoverElement: HTMLElement) {
|
||||
popoverElement.classList.add("active-popover")
|
||||
setPosition(popoverElement as HTMLElement)
|
||||
|
||||
// dont refetch if there's already a popover
|
||||
if (hasAlreadyBeenFetched()) {
|
||||
setPosition(prevPopoverElement as HTMLElement)
|
||||
prevPopoverElement?.classList.add("active-popover")
|
||||
return
|
||||
if (hash !== "") {
|
||||
const targetAnchor = `#popover-internal-${hash.slice(1)}`
|
||||
const heading = popoverInner.querySelector(targetAnchor) as HTMLElement | null
|
||||
if (heading) {
|
||||
// leave ~12px of buffer when scrolling to a heading
|
||||
popoverInner.scroll({ top: heading.offsetTop - 12, behavior: "instant" })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const thisUrl = new URL(document.location.href)
|
||||
thisUrl.hash = ""
|
||||
thisUrl.search = ""
|
||||
const targetUrl = new URL(link.href)
|
||||
const hash = decodeURIComponent(targetUrl.hash)
|
||||
targetUrl.hash = ""
|
||||
targetUrl.search = ""
|
||||
const popoverId = `popover-${link.dataset.slug ?? randomIdNonSecure()}`
|
||||
const prevPopoverElement = document.getElementById(popoverId)
|
||||
const hasAlreadyBeenFetched = () => !!document.getElementById(popoverId)
|
||||
|
||||
// dont refetch if there's already a popover
|
||||
if (hasAlreadyBeenFetched()) {
|
||||
showPopover(prevPopoverElement as HTMLElement)
|
||||
return
|
||||
}
|
||||
|
||||
const response = await fetchCanonical(targetUrl).catch((err) => {
|
||||
console.error(err)
|
||||
|
@ -59,12 +66,12 @@ async function mouseEnterHandler(
|
|||
const [contentTypeCategory, typeInfo] = contentType.split("/")
|
||||
|
||||
const popoverElement = document.createElement("div")
|
||||
popoverElement.id = popoverId
|
||||
popoverElement.classList.add("popover")
|
||||
const popoverInner = document.createElement("div")
|
||||
popoverInner.classList.add("popover-inner")
|
||||
popoverElement.appendChild(popoverInner)
|
||||
|
||||
popoverInner.dataset.contentType = contentType ?? undefined
|
||||
popoverElement.appendChild(popoverInner)
|
||||
|
||||
switch (contentTypeCategory) {
|
||||
case "image":
|
||||
|
@ -100,19 +107,8 @@ async function mouseEnterHandler(
|
|||
elts.forEach((elt) => popoverInner.appendChild(elt))
|
||||
}
|
||||
|
||||
setPosition(popoverElement)
|
||||
popoverElement.id = `popover-${id}`
|
||||
popoverElement.classList.add("active-popover")
|
||||
document.body.appendChild(popoverElement)
|
||||
|
||||
if (hash !== "") {
|
||||
const targetAnchor = `#popover-internal-${hash.slice(1)}`
|
||||
const heading = popoverInner.querySelector(targetAnchor) as HTMLElement | null
|
||||
if (heading) {
|
||||
// leave ~12px of buffer when scrolling to a heading
|
||||
popoverInner.scroll({ top: heading.offsetTop - 12, behavior: "instant" })
|
||||
}
|
||||
}
|
||||
showPopover(popoverElement)
|
||||
}
|
||||
|
||||
function clearActivePopover() {
|
||||
|
|
Loading…
Add table
Reference in a new issue