UNPKG

@kubit-ui-web/react-components

Version:

Kubit React Components is a customizable, accessible library of React web components, designed to enhance your application's user experience

127 lines 6.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getClippingRect = exports.getClippingElementAncestors = exports.hasFixedPositionAncestor = exports.getClientRectFromClippingAncestor = exports.getInnerBoundingClientRect = void 0; const getBoundingClientRect_1 = require("./getBoundingClientRect"); const getDocumentRect_1 = require("./getDocumentRect"); const getOverflowAncestors_1 = require("./getOverflowAncestors"); const getParentNode_1 = require("./getParentNode"); const getViewportRect_1 = require("./getViewportRect"); const is_utils_1 = require("./is.utils"); const node_1 = require("./node"); const rectToClientRect_1 = require("./rectToClientRect"); /** * Get the client inner rect (with borders) */ const getInnerBoundingClientRect = (element, strategy) => { const clientRect = (0, getBoundingClientRect_1.getBoundingClientRect)(element, strategy === 'fixed'); const top = clientRect.top + element.clientTop; const left = clientRect.left + element.clientLeft; const width = element.clientWidth; const height = element.clientHeight; const x = left; const y = top; return { width, height, x, y, }; }; exports.getInnerBoundingClientRect = getInnerBoundingClientRect; const getClientRectFromClippingAncestor = (clippingAncestor, strategy) => { let rect; if (clippingAncestor === 'viewport') { rect = (0, getViewportRect_1.getViewportRect)(strategy); } else if (clippingAncestor === 'document') { rect = (0, getDocumentRect_1.getDocumentRect)(window.document.documentElement); } else if ((0, is_utils_1.isElement)(clippingAncestor)) { rect = (0, exports.getInnerBoundingClientRect)(clippingAncestor, strategy); } else { const mutableRect = { ...clippingAncestor }; if ((0, is_utils_1.isClientRectVisualViewportBased)()) { mutableRect.x -= window.visualViewport?.offsetLeft || 0; mutableRect.y -= window.visualViewport?.offsetTop || 0; } rect = mutableRect; } return (0, rectToClientRect_1.rectToClientRect)(rect); }; exports.getClientRectFromClippingAncestor = getClientRectFromClippingAncestor; const hasFixedPositionAncestor = (element, stopNode) => { const parentNode = (0, getParentNode_1.getParentNode)(element); if (parentNode === stopNode || !(0, is_utils_1.isElement)(parentNode) || (0, is_utils_1.isLastTraversableNode)(parentNode)) { return false; } return (window.getComputedStyle(parentNode).position === 'fixed' || (0, exports.hasFixedPositionAncestor)(parentNode, stopNode)); }; exports.hasFixedPositionAncestor = hasFixedPositionAncestor; /** * A "clipping ancestor" is an `overflow` element with the characteristic of * clipping (or hiding) child elements. This returns all clipping ancestors * of the given element up the tree. */ const getClippingElementAncestors = (element) => { let result = (0, getOverflowAncestors_1.getOverflowAncestors)(element).filter(el => (0, is_utils_1.isElement)(el) && (0, node_1.getNodeName)(el) !== 'body'); let currentContainingBlockComputedStyle = null; const elementIsFixed = window.getComputedStyle(element).position === 'fixed'; let currentNode = elementIsFixed ? (0, getParentNode_1.getParentNode)(element) : element; // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block while ((0, is_utils_1.isElement)(currentNode) && !(0, is_utils_1.isLastTraversableNode)(currentNode)) { const computedStyle = window.getComputedStyle(currentNode); const currentNodeIsContaining = (0, is_utils_1.isContainingBlock)(currentNode); if (!currentNodeIsContaining && computedStyle.position === 'fixed') { currentContainingBlockComputedStyle = null; } const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : (!currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && ['absolute', 'fixed'].includes(currentContainingBlockComputedStyle.position)) || ((0, is_utils_1.isOverflowElement)(currentNode) && !currentNodeIsContaining && (0, exports.hasFixedPositionAncestor)(element, currentNode)); if (shouldDropCurrentNode) { // Drop non-containing blocks. result = result.filter(ancestor => ancestor !== currentNode); } else { // Record last containing block for next iteration. currentContainingBlockComputedStyle = computedStyle; } currentNode = (0, getParentNode_1.getParentNode)(currentNode); } return result; }; exports.getClippingElementAncestors = getClippingElementAncestors; /** * Gets the maximum area that the element is visible in due to any number of clipping ancestors. * A "clipping ancestor" is an `overflow` element with the characteristic of * clipping (or hiding) child elements. This returns all clipping ancestors * of the given element up the tree. */ const getClippingRect = ({ element, boundary, rootBoundary, strategy, }) => { const elementClippingAncestors = boundary === 'clippingAncestors' ? (0, exports.getClippingElementAncestors)(element) : [...boundary]; const clippingAncestors = [...elementClippingAncestors, rootBoundary]; const firstClippingAncestor = clippingAncestors[0]; const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => { const rect = (0, exports.getClientRectFromClippingAncestor)(clippingAncestor, strategy); accRect.top = Math.max(rect.top, accRect.top); accRect.right = Math.min(rect.right, accRect.right); accRect.bottom = Math.min(rect.bottom, accRect.bottom); accRect.left = Math.max(rect.left, accRect.left); return accRect; }, (0, exports.getClientRectFromClippingAncestor)(firstClippingAncestor, strategy)); return { width: clippingRect.right - clippingRect.left, height: clippingRect.bottom - clippingRect.top, x: clippingRect.left, y: clippingRect.top, }; }; exports.getClippingRect = getClippingRect; //# sourceMappingURL=getClippinRect.js.map