UNPKG

@carbon/ibm-products

Version:
65 lines (63 loc) 2.21 kB
/** * Copyright IBM Corp. 2020, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ //#region src/components/PageHeader/next/utils.ts /** * Copyright IBM Corp. 2025 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ /** * ---------- * Utilities * ---------- */ const getHeaderOffset = (el) => { const scrollableContainer = scrollableAncestor(el); const offsetMeasuringTop = el ? el.getBoundingClientRect().top : 0; if (scrollableContainer === document.scrollingElement) return offsetMeasuringTop >= 0 ? offsetMeasuringTop : 0; else { const scrollableContainerTop = scrollableContainer ? scrollableContainer.getBoundingClientRect().top : 0; const totalHeaderOffset = offsetMeasuringTop !== 0 ? offsetMeasuringTop - scrollableContainerTop : 0; return totalHeaderOffset >= 0 ? totalHeaderOffset : 0; } }; const windowExists = typeof window !== `undefined`; /** * Determines if the given target is scrollable * * @param {HTMLElement} target * @returns {boolean} */ const scrollable = (target) => { const style = window.getComputedStyle(target); const tagName = target.tagName.toLowerCase(); if (tagName === "body" || tagName === "html") return /(auto|scroll)/.test(style.overflow); return /(auto|scroll|hidden)/.test(style.overflow); }; /** * Recursively looks for the scrollable ancestor */ const scrollableAncestorInner = (target) => { if (target.parentNode && target.parentNode !== document) if (scrollable(target.parentNode)) return target.parentNode; else return scrollableAncestorInner(target.parentNode); else return document.scrollingElement; }; /** * Walks up the parent nodes to identify the first scrollable ancestor * * @param {HTMLElement} target * @returns {HTMLElement} */ const scrollableAncestor = (target) => { if (!windowExists || !target) return null; const style = window.getComputedStyle(target); if (!target || !style || style.position === "fixed") return document.scrollingElement; return scrollableAncestorInner(target); }; //#endregion export { getHeaderOffset, scrollableAncestor };