UNPKG

@patternfly/react-core

Version:

This library provides a set of common React components for use with the PatternFly reference implementation.

81 lines (66 loc) 2.36 kB
// @ts-nocheck import getWindow from './getWindow'; import getNodeName from './getNodeName'; import getComputedStyle from './getComputedStyle'; import { isHTMLElement } from './instanceOf'; import isTableElement from './isTableElement'; import getParentNode from './getParentNode'; import getDocumentElement from './getDocumentElement'; /** * @param element */ function getTrueOffsetParent(element: Element): Element | null | undefined { if ( !isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 getComputedStyle(element).position === 'fixed' ) { return null; } const offsetParent = element.offsetParent; if (offsetParent) { const html = getDocumentElement(offsetParent); if ( getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static' && getComputedStyle(html).position !== 'static' ) { return html; } } return offsetParent; } // `.offsetParent` reports `null` for fixed elements, while absolute elements // return the containing block /** * @param element */ function getContainingBlock(element: Element) { let currentNode = getParentNode(element); while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) { const css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that // create a containing block. if (css.transform !== 'none' || css.perspective !== 'none' || (css.willChange && css.willChange !== 'auto')) { return currentNode; } else { currentNode = currentNode.parentNode; } } return null; } // Gets the closest ancestor positioned element. Handles some edge cases, // such as table ancestors and cross browser bugs. /** * @param element */ export default function getOffsetParent(element: Element) { const window = getWindow(element); let offsetParent = getTrueOffsetParent(element); while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') { offsetParent = getTrueOffsetParent(offsetParent); } if (offsetParent && getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static') { return window; } return offsetParent || getContainingBlock(element) || window; }