UNPKG

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
/** * 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', }); }