Files
webmail/lib/popover-shift.ts
T

36 lines
1.3 KiB
TypeScript

/**
* How far a popover has to move sideways to stay `margin` px inside `bounds`.
* When it is wider than the bounds its start edge wins, so the first entries
* stay reachable.
*/
export function popoverShift(
popover: { left: number; right: number },
bounds: { left: number; right: number },
margin = 8,
): number {
const overEnd = popover.right - (bounds.right - margin);
const shift = overEnd > 0 ? -overEnd : 0;
const overStart = bounds.left + margin - (popover.left + shift);
return overStart > 0 ? shift + overStart : shift;
}
/**
* Whether a popover that opens under its button fits the window's height: if not,
* it opens above the button when there's more room there, and either way it gets a
* height cap and scrolls. Null when it fits as it is.
*/
export function popoverFitHeight(
popover: { top: number; height: number },
trigger: { top: number },
viewportHeight: number,
margin = 10,
gap = 4,
): { above: boolean; maxHeight: number } | null {
if (popover.top + popover.height <= viewportHeight - margin) return null;
const below = viewportHeight - margin - popover.top;
const above = trigger.top - gap - margin;
return above > below
? { above: true, maxHeight: Math.min(popover.height, above) }
: { above: false, maxHeight: Math.max(0, below) };
}