@intility/bifrost-react
Version:
React library for Intility's design system, Bifrost.
42 lines (41 loc) • 1.82 kB
JavaScript
/**
* Check if an element has overflowing scroll content
* @param element DOM node
* @returns true if the element has any scroll overflow
* @example
* // find closest parent element that currently has a scrollbar
* const scrollContainer = closestElement(isScrollableRightNow, element)
*/ export function isScrollableRightNow(element) {
return element.scrollHeight > element.clientHeight;
}
/**
* Check if an element can render a scrollbar
* @param element DOM node
* @returns true if overflowY is 'auto' or 'scroll'
* @example
* // find closest parent element that can be scrolled (but may not have a scrollbar currently)
* const scrollContainer = closestElement(isEverScrollable, element)
*/ export function isEverScrollable(element) {
// `<body>` can have overflow CSS applied to it, but will never actually be scrollable (the `<html>` element will scroll instead)
if (element === document.body) return false;
const css = getComputedStyle(element);
return css.overflowY === "auto" || css.overflowY === "scroll";
}
/**
* Find closest parent element in the DOM tree
* @param predicate Function that is called for each parent element until it returns true
* @param element Child element (DOM node) to start traversing from
* @returns First parent element where predicate returns true, or root node (`document.documentElement`)
* @example
* // find closest parent `<table>` element
* const closestTable = closestElement(el => el.tagName === 'table', element)
*/ export default function closestElement(predicate, element) {
if (!element || !element.parentElement) {
return document.documentElement;
}
if (predicate(element)) {
return element;
}
// walk up the tree through recursion
return closestElement(predicate, element.parentElement);
}