58 lines
2.1 KiB
JavaScript
58 lines
2.1 KiB
JavaScript
// src/internal/offset.ts
|
|
function getOffset(element, parent) {
|
|
return {
|
|
top: Math.round(element.getBoundingClientRect().top - parent.getBoundingClientRect().top),
|
|
left: Math.round(element.getBoundingClientRect().left - parent.getBoundingClientRect().left)
|
|
};
|
|
}
|
|
|
|
// src/internal/scroll.ts
|
|
var locks = /* @__PURE__ */ new Set();
|
|
function getScrollbarWidth() {
|
|
const documentWidth = document.documentElement.clientWidth;
|
|
return Math.abs(window.innerWidth - documentWidth);
|
|
}
|
|
function lockBodyScrolling(lockingEl) {
|
|
locks.add(lockingEl);
|
|
if (!document.body.classList.contains("sl-scroll-lock")) {
|
|
const scrollbarWidth = getScrollbarWidth();
|
|
document.body.classList.add("sl-scroll-lock");
|
|
document.body.style.setProperty("--sl-scroll-lock-size", `${scrollbarWidth}px`);
|
|
}
|
|
}
|
|
function unlockBodyScrolling(lockingEl) {
|
|
locks.delete(lockingEl);
|
|
if (locks.size === 0) {
|
|
document.body.classList.remove("sl-scroll-lock");
|
|
document.body.style.removeProperty("--sl-scroll-lock-size");
|
|
}
|
|
}
|
|
function scrollIntoView(element, container, direction = "vertical", behavior = "smooth") {
|
|
const offset = getOffset(element, container);
|
|
const offsetTop = offset.top + container.scrollTop;
|
|
const offsetLeft = offset.left + container.scrollLeft;
|
|
const minX = container.scrollLeft;
|
|
const maxX = container.scrollLeft + container.offsetWidth;
|
|
const minY = container.scrollTop;
|
|
const maxY = container.scrollTop + container.offsetHeight;
|
|
if (direction === "horizontal" || direction === "both") {
|
|
if (offsetLeft < minX) {
|
|
container.scrollTo({ left: offsetLeft, behavior });
|
|
} else if (offsetLeft + element.clientWidth > maxX) {
|
|
container.scrollTo({ left: offsetLeft - container.offsetWidth + element.clientWidth, behavior });
|
|
}
|
|
}
|
|
if (direction === "vertical" || direction === "both") {
|
|
if (offsetTop < minY) {
|
|
container.scrollTo({ top: offsetTop, behavior });
|
|
} else if (offsetTop + element.clientHeight > maxY) {
|
|
container.scrollTo({ top: offsetTop - container.offsetHeight + element.clientHeight, behavior });
|
|
}
|
|
}
|
|
}
|
|
|
|
export {
|
|
lockBodyScrolling,
|
|
unlockBodyScrolling,
|
|
scrollIntoView
|
|
};
|