svelte-ux
Version:
- Increment version in `package.json` and commit as `Version bump to x.y.z` - `npm run publish`
47 lines (46 loc) • 1.95 kB
JavaScript
/**
* Find the closest scrollable parent
* - see: https://stackoverflow.com/questions/35939886/find-first-scrollable-parent
* - see: https://gist.github.com/twxia/bb20843c495a49644be6ea3804c0d775
*/
export function getScrollParent(node) {
var _a, _b;
const isElement = node instanceof HTMLElement;
const overflowX = isElement && ((_a = window === null || window === void 0 ? void 0 : window.getComputedStyle(node).overflowX) !== null && _a !== void 0 ? _a : 'visible');
const overflowY = isElement && ((_b = window === null || window === void 0 ? void 0 : window.getComputedStyle(node).overflowY) !== null && _b !== void 0 ? _b : 'visible');
const isHorozontalScrollable = !['visible', 'hidden'].includes(overflowX) && node.scrollWidth > node.clientWidth;
const isVerticalScrollable = !['visible', 'hidden'].includes(overflowY) && node.scrollHeight > node.clientHeight;
if (isHorozontalScrollable || isVerticalScrollable) {
return node;
}
else if (node.parentNode) {
return getScrollParent(node.parentNode);
}
else {
return document.body;
}
}
/**
* Scroll node into view of closely scrollable (overflown) parent. Like `node.scrollIntoView()` but will only scroll immediate container (not viewport)
*/
export function scrollIntoView(node) {
// TODO: Consider only scrolling if needed
const scrollParent = getScrollParent(node);
const nodeOffset = {
top: node.offsetTop,
left: node.offsetLeft,
};
const optionCenter = {
left: node.clientWidth / 2,
top: node.clientHeight / 2,
};
const containerCenter = {
left: scrollParent.clientWidth / 2,
top: scrollParent.clientHeight / 2,
};
scrollParent.scroll({
top: nodeOffset.top + optionCenter.top - containerCenter.top,
left: nodeOffset.left + optionCenter.left - containerCenter.left,
behavior: 'smooth',
});
}