UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

103 lines (102 loc) 3.56 kB
const Dom = { methods: { /** * Scroll an element into view if it is not fully visible in its nearest scrollable ancestor. * @param {Element} ref */ scrollElementIntoViewIfNeeded(ref, opt_center, opt_behavior, opt_parent) { if (ref.scrollIntoViewIfNeeded) { this.scrollIntoViewIfNeeded(ref, opt_center, opt_behavior, opt_parent); } else { this.scrollIntoView(ref, "bottom", false, opt_behavior, opt_parent); } }, /** * Scroll an element to the top or bottom of its scroll ancestor. * @param {Element} ref */ scrollElementIntoView(ref, opt_scrollToTop, opt_behavior, opt_parent) { if (opt_scrollToTop === "center") { this.scrollIntoView(ref, "center", false, opt_behavior, opt_parent); return; } if (opt_scrollToTop === false) { this.scrollIntoView(ref, "bottom", false, opt_behavior, opt_parent); } else { this.scrollIntoView(ref, "top", false, opt_behavior, opt_parent); } }, scrollIntoViewIfNeeded(ref, opt_center, opt_behavior, opt_parent) { const dir = opt_center ? "center" : void 0; this.scrollIntoView(ref, dir, true, opt_behavior, opt_parent); }, scrollIntoView(ref, opt_dir, opt_ifNeeded, opt_behavior, opt_parent) { if (!ref || !ref.parentElement) { return; } const offsetTop = ref.offsetTop; const refParent = opt_parent || ref.parentElement; const scrollBounds = this._getScrollBounds(refParent); const parentHeight = scrollBounds.bottom - scrollBounds.top; const elHeight = this._getElementHeight(ref); const offsetBottom = offsetTop + elHeight; let scrollTop = -1; switch (opt_dir) { case "top": scrollTop = offsetTop; break; case "center": scrollTop = offsetTop + (elHeight - parentHeight) / 2; break; case "bottom": scrollTop = scrollTop = offsetBottom - parentHeight; break; default: if (offsetTop - scrollBounds.top <= parentHeight / 2) { scrollTop = offsetTop; } else { scrollTop = offsetBottom - parentHeight; } break; } this._setScrollTop(refParent, scrollTop, scrollBounds, offsetTop, offsetBottom, opt_ifNeeded, opt_behavior); }, _setScrollTop(el, scrollTop, bounds, offsetTop, offsetBottom, opt_isNeeded, opt_behavior) { bounds = bounds || this._getScrollBounds(el); const parentHeight = bounds.bottom - bounds.top; if (opt_isNeeded && this._inScrollBounds(offsetTop, offsetBottom, bounds)) { if (offsetTop < bounds.top) { scrollTop = offsetTop; } else if (offsetBottom > bounds.bottom) { scrollTop = offsetBottom - parentHeight; } else { return; } } if (opt_behavior) { el.scrollTo({ top: scrollTop, behavior: opt_behavior }); } else { el.scrollTop = scrollTop; } }, _getElementHeight(el) { return el.getBoundingClientRect().height; }, _getScrollBounds(el) { const height = this._getElementHeight(el); const scrollTop = el.scrollTop; return { top: scrollTop, bottom: scrollTop + height }; }, _inScrollBounds(top, bottom, bounds) { const height = bottom - top; return bottom <= bounds.bottom + 3 * height / 4 && top >= bounds.top - height / 4; } } }; export { Dom as default }; //# sourceMappingURL=dom.js.map