diff --git a/.changeset/eight-years-pump.md b/.changeset/eight-years-pump.md new file mode 100644 index 000000000..bd9967cd7 --- /dev/null +++ b/.changeset/eight-years-pump.md @@ -0,0 +1,5 @@ +--- +"@lion/overlays": patch +--- + +fix: isVisible check on elements with display:contents diff --git a/packages/overlays/src/utils/is-visible.js b/packages/overlays/src/utils/is-visible.js index 8458b07a1..eeb8d9dc4 100644 --- a/packages/overlays/src/utils/is-visible.js +++ b/packages/overlays/src/utils/is-visible.js @@ -4,6 +4,11 @@ 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 @@ -24,12 +29,20 @@ export function isVisible(element) { return false; } + const computedStyle = window.getComputedStyle(element); + // Check computed styles - // matches display: none, visbility: hidden on element and visibility: hidden from parent - if (!hasStyleVisibility(window.getComputedStyle(element))) { + // 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); diff --git a/packages/overlays/test/utils-tests/get-focusable-elements.test.js b/packages/overlays/test/utils-tests/get-focusable-elements.test.js index 8df8a0b56..a66b0ba24 100644 --- a/packages/overlays/test/utils-tests/get-focusable-elements.test.js +++ b/packages/overlays/test/utils-tests/get-focusable-elements.test.js @@ -53,12 +53,16 @@ describe('getFocusableElements()', () => { + +