lion/packages/ui/components/overlays/utils/is-visible.js
2022-10-31 16:55:07 +01:00

49 lines
1.3 KiB
JavaScript

/**
* @param {CSSStyleDeclaration} styles
*/
const hasStyleVisibility = ({ visibility, display }) =>
visibility !== 'hidden' && display !== 'none';
/**
* @param {CSSStyleDeclaration} styles
*/
const isDisplayContents = ({ display }) => display === 'contents';
/**
* @param {HTMLElement} element
* @returns {boolean} Whether the element is visible
*/
export function isVisible(element) {
if (!element) {
return false;
}
// Check if element is connected to the DOM
if (!element.isConnected) {
return false;
}
// Check inline styles to avoid a reflow
// matches display: none, visibility: hidden on element
if (!hasStyleVisibility(element.style)) {
return false;
}
const computedStyle = window.getComputedStyle(element);
// Check computed styles
// matches display: none, visibility: hidden on element and visibility: hidden from parent
if (!hasStyleVisibility(computedStyle)) {
return false;
}
// Allow element that delegates layout (i.e. display: contents)
// matches display: contents
if (isDisplayContents(computedStyle)) {
return true;
}
// display: none is not inherited, so finally check if element has calculated width or height
// matches display: none from parent
return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
}