Monorepo for Tangled
Something went wrong. Try again.
TypeScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980import type { Attachment } from "svelte/attachments";
export function popoverSingleton() { let openHide: (() => void) | undefined;
return { claim(hide: () => void) { if (openHide && openHide !== hide) openHide(); openHide = hide; }, release(hide: () => void) { if (openHide === hide) openHide = undefined; } };}
export function popoverAnchorName(prefix: string, id: string) { return `--${prefix}-${id.replace(/[^a-zA-Z0-9_-]/g, "-")}`;}
export type PopoverOrigin = "tl" | "tr" | "bl" | "br";
const corners: Record<PopoverOrigin, string> = { tl: "top-left", tr: "top-right", bl: "bottom-left", br: "bottom-right"};
const along = (center: number, start: number, extent: number, near: string, far: string) => { if (extent === 0) return "center"; const fraction = (center - start) / extent; if (fraction < 1 / 3) return near; if (fraction > 2 / 3) return far; return "center";};
export const popoverOrigin = ( anchor: () => HTMLElement | undefined, origin?: () => PopoverOrigin | undefined ): Attachment<HTMLElement> => (node) => { const measure = () => { const fixed = origin?.(); if (fixed) { node.setAttribute("data-popover-origin", corners[fixed]); return; }
const trigger = anchor()?.getBoundingClientRect(); if (!trigger) return; const panel = node.getBoundingClientRect(); if (panel.width === 0 || panel.height === 0) return;
const block = along( trigger.top + trigger.height / 2, panel.top, panel.height, "top", "bottom" ); const inline = along( trigger.left + trigger.width / 2, panel.left, panel.width, "left", "right" ); node.setAttribute("data-popover-origin", `${block}-${inline}`); };
const onToggle = (event: ToggleEvent) => { if (event.newState === "open") measure(); };
node.addEventListener("toggle", onToggle); return () => node.removeEventListener("toggle", onToggle); };