42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
|
|
import { createContext, useContext } from 'react'
|
||
|
|
|
||
|
|
export const ScrollContext = createContext<HTMLElement | null>(null)
|
||
|
|
export const useScrollRoot = () => useContext(ScrollContext)
|
||
|
|
|
||
|
|
// delete all the toastz
|
||
|
|
export function toastNuke() {
|
||
|
|
document.querySelectorAll('.layout-tooltip').forEach((e) => e.remove())
|
||
|
|
}
|
||
|
|
window.addEventListener('popstate', toastNuke)
|
||
|
|
|
||
|
|
// janky tooltips which are evil!1!
|
||
|
|
export function toast(anchorId: string, message: string) {
|
||
|
|
const anchor = document.getElementById(anchorId)
|
||
|
|
if (!anchor) return
|
||
|
|
|
||
|
|
const dialog = anchor.closest('dialog') ?? document.body
|
||
|
|
const parent = dialog.getBoundingClientRect()
|
||
|
|
const rect = anchor.getBoundingClientRect()
|
||
|
|
const elem = document.createElement('span')
|
||
|
|
|
||
|
|
// monospace font 4 da win
|
||
|
|
const tooltipWidth = message.length * 8
|
||
|
|
const clampedLeft = Math.max(
|
||
|
|
tooltipWidth / 2 + 8,
|
||
|
|
Math.min(rect.left + rect.width / 2, window.innerWidth - tooltipWidth / 2 - 8),
|
||
|
|
)
|
||
|
|
|
||
|
|
elem.classList.add('layout-tooltip', 'animation-scroll-in')
|
||
|
|
elem.textContent = message
|
||
|
|
elem.style.cssText = `
|
||
|
|
position: absolute;
|
||
|
|
left: ${clampedLeft - parent.left}px;
|
||
|
|
top: ${rect.top - parent.top - 8}px;
|
||
|
|
transform: translateX(-50%) translateY(-100%);
|
||
|
|
`
|
||
|
|
|
||
|
|
toastNuke()
|
||
|
|
dialog.appendChild(elem)
|
||
|
|
setTimeout(() => elem.remove(), 2000)
|
||
|
|
}
|