svelte-5-ui-lib
Version:
Svelte 5 UI Lib is a UI library built from scratch to leverage Svelte 5's runes system, creating smooth, reactive components.
113 lines (112 loc) • 5.15 kB
JavaScript
import Popover from './Popover.svelte';
import { popover } from './theme';
/**
* Calculates the position for a tooltip relative to a reference element.
* @param options - The options for positioning
* @returns The calculated position for the tooltip and arrow
*/
function calculateTooltipPosition({ tooltipRect, referenceRect, position, offset, arrowRect }) {
const scrollX = window.scrollX || document.documentElement.scrollLeft;
const scrollY = window.scrollY || document.documentElement.scrollTop;
let top, left, arrowTop, arrowLeft;
switch (position) {
case 'top':
top = referenceRect.top + scrollY - tooltipRect.height - 10 - offset;
left = referenceRect.left + scrollX + referenceRect.width / 2 - tooltipRect.width / 2;
if (arrowRect && offset === 0) {
arrowTop = tooltipRect.height - 5;
arrowLeft = tooltipRect.width / 2 - arrowRect.width / 2;
}
break;
case 'top-start':
top = referenceRect.top + scrollY - tooltipRect.height - 10 - offset;
left = referenceRect.left + scrollX;
if (arrowRect && offset === 0) {
arrowTop = tooltipRect.height - 5;
arrowLeft = referenceRect.width / 2 - arrowRect.width / 2;
}
break;
case 'top-end':
top = referenceRect.top + scrollY - tooltipRect.height - 10 - offset;
left = referenceRect.right + scrollX - tooltipRect.width;
if (arrowRect && offset === 0) {
arrowTop = tooltipRect.height - 5;
arrowLeft = tooltipRect.width - referenceRect.width / 2 - arrowRect.width / 2;
}
break;
case 'bottom':
top = referenceRect.bottom + scrollY + 10 + offset;
left = referenceRect.left + scrollX + referenceRect.width / 2 - tooltipRect.width / 2;
if (arrowRect && offset === 0) {
arrowTop = -arrowRect.height + 9;
arrowLeft = tooltipRect.width / 2 - arrowRect.width / 2;
}
break;
case 'bottom-start':
top = referenceRect.bottom + scrollY + 10 + offset;
left = referenceRect.left + scrollX;
if (arrowRect && offset === 0) {
arrowTop = -arrowRect.height + 9;
arrowLeft = referenceRect.width / 2 - arrowRect.width / 2;
}
break;
case 'bottom-end':
top = referenceRect.bottom + scrollY + 10 + offset;
left = referenceRect.right + scrollX - tooltipRect.width;
if (arrowRect && offset === 0) {
arrowTop = -arrowRect.height + 9;
arrowLeft = tooltipRect.width - referenceRect.width / 2 - arrowRect.width / 2;
}
break;
case 'left':
top = referenceRect.top + scrollY + referenceRect.height / 2 - tooltipRect.height / 2;
left = referenceRect.left + scrollX - tooltipRect.width - 10 - offset;
if (arrowRect && offset === 0) {
arrowTop = tooltipRect.height / 2 - arrowRect.height / 2;
arrowLeft = tooltipRect.width - 5;
}
break;
case 'left-start':
top = referenceRect.top + scrollY;
left = referenceRect.left + scrollX - tooltipRect.width - 10 - offset;
if (arrowRect && offset === 0) {
arrowTop = arrowRect.height;
arrowLeft = tooltipRect.width - 5;
}
break;
case 'left-end':
top = referenceRect.bottom + scrollY - tooltipRect.height;
left = referenceRect.left + scrollX - tooltipRect.width - 10 - offset;
if (arrowRect && offset === 0) {
arrowTop = tooltipRect.height - arrowRect.height * 2;
arrowLeft = tooltipRect.width - 5;
}
break;
case 'right':
top = referenceRect.top + scrollY + referenceRect.height / 2 - tooltipRect.height / 2;
left = referenceRect.right + scrollX + 10 + offset;
if (arrowRect && offset === 0) {
arrowTop = tooltipRect.height / 2 - arrowRect.height / 2;
arrowLeft = -arrowRect.width / 2 + 2;
}
break;
case 'right-start':
top = referenceRect.top + scrollY;
left = referenceRect.right + scrollX + 10 + offset;
if (arrowRect && offset === 0) {
arrowTop = arrowRect.height;
arrowLeft = -arrowRect.width / 2 + 2;
}
break;
case 'right-end':
top = referenceRect.bottom + scrollY - tooltipRect.height;
left = referenceRect.right + scrollX + 10 + offset;
if (arrowRect && offset === 0) {
arrowTop = tooltipRect.height - arrowRect.height * 2;
arrowLeft = -arrowRect.width / 2 + 2;
}
break;
}
return { top, left, arrowTop, arrowLeft };
}
export { Popover, popover, calculateTooltipPosition };