diff --git a/packages/unity-bootstrap-theme/src/js/anchor-menu.js b/packages/unity-bootstrap-theme/src/js/anchor-menu.js index 6dbbbe13c..0c80c0d79 100644 --- a/packages/unity-bootstrap-theme/src/js/anchor-menu.js +++ b/packages/unity-bootstrap-theme/src/js/anchor-menu.js @@ -15,9 +15,9 @@ function initAnchorMenu() { const globalHeader = document.getElementById(globalHeaderId); const navbar = document.getElementById("uds-anchor-menu"); if (!navbar || !globalHeader) { - console.warn( - "Anchor menu initialization failed: required elements not found" - ); + return; + } + if (Array.from(navbar.classList).some(cls => cls.startsWith("sc-"))) { return; } @@ -53,8 +53,6 @@ function initAnchorMenu() { const target = document.getElementById(targetId); if (target) { anchorTargets.set(anchor, target); - } else { - console.warn(`Anchor menu: target element "${targetId}" not found`); } } @@ -199,7 +197,7 @@ function initAnchorMenu() { e.preventDefault(); if (!anchorTarget || !document.body.contains(anchorTarget)) { - console.warn("Anchor target no longer exists in DOM"); + console.warn("Anchor target no longer exists in DOM"); // This should be rare but if the target element has been removed from the DOM, this will make debuggin easier in webspark sites return; } @@ -212,7 +210,6 @@ function initAnchorMenu() { const topOffset = headerBottom + navbarHeight; const targetTop = anchorTarget.getBoundingClientRect().top; const viewportMid = window.innerHeight / 2; - console.log("viewportmid", viewportMid, "targetTop", targetTop); if (targetTop >= topOffset && targetTop <= viewportMid) { history.replaceState(null, "", anchor.getAttribute("href")); @@ -221,8 +218,6 @@ function initAnchorMenu() { } } - // Get current viewport height and calculate the scroll offset so that the - // top of section is visible when you click on the anchor. const viewportHeight = window.innerHeight; const targetQuarterPosition = Math.round(viewportHeight * 0.35); // 35% was determined to be a good position for the section top after testing different offsets, including centering the section in the viewport. Can work in wordpress or any other platform where there are admin toolbars @@ -245,7 +240,6 @@ function initAnchorMenu() { e.target.classList.add("active"); - // Update the URL hash without triggering a scroll const targetHash = anchor.getAttribute("href"); if (targetHash) { history.replaceState(null, "", targetHash); diff --git a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.jsx b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.jsx index 8c4ff25fc..b5c4bfc87 100644 --- a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.jsx +++ b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.jsx @@ -56,11 +56,21 @@ export const AnchorMenu = ({ showMenu: false, sticky: false, }); - const headerHeight = isSmallDevice ? 110 : 142; + + const getPageHeader = () => + document.getElementById("asu-header") || + document.getElementById("headerContainer") || + document.getElementById("asuHeader"); + + const getHeaderBottomOffset = () => { + const pageHeader = getPageHeader(); + return Math.max(pageHeader?.getBoundingClientRect().bottom || 0, 0); + }; const handleWindowScroll = () => { const newState = {}; const curPos = window.scrollY; + const headerBottomOffset = getHeaderBottomOffset(); // Select first next sibling element of the anchor menu const firstElement = document .getElementById(firstElementId) @@ -77,7 +87,7 @@ export const AnchorMenu = ({ // Change active containers on scroll const subsHeight = state.hasHeader - ? headerHeight + anchorMenuHeight + ? headerBottomOffset + anchorMenuHeight : anchorMenuHeight; items?.forEach(({ targetIdName }) => { const container = document.getElementById(targetIdName); @@ -105,10 +115,7 @@ export const AnchorMenu = ({ // Is ASU Header on the document const isHeader = () => { - const pageHeader = - document.getElementById("asu-header") || - document.getElementById("headerContainer") || - document.getElementById("asuHeader"); + const pageHeader = getPageHeader(); return !!pageHeader; }; @@ -162,9 +169,10 @@ export const AnchorMenu = ({ }, [state.hasHeader]); const handleClickLink = container => { + const headerBottomOffset = getHeaderBottomOffset(); // Set scroll position considering if ASU Header is setted or not const curScroll = - window.scrollY - (state.hasHeader ? headerHeight + 100 : 100); + window.scrollY - (state.hasHeader ? headerBottomOffset + 100 : 100); const anchorMenuHeight = isSmallDevice ? 410 : 90; // Set where to scroll to let scrollTo = @@ -187,11 +195,19 @@ export const AnchorMenu = ({ })); }; + const headerBottomOffset = state.hasHeader ? getHeaderBottomOffset() : 0; + const WrapperComponent = isBootstrap ? "div" : AnchorMenuWrapper; + const wrapperProps = isBootstrap + ? {} + : { + // @ts-ignore + requiresAltMenuSpacing: state.hasAltMenuSpacing, + }; + return ( items?.length > 0 && ( -
{isSmallDevice ? ( @@ -265,7 +284,7 @@ export const AnchorMenu = ({
-
+ ) ); }; diff --git a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx index ae14629ab..8766a4777 100644 --- a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx +++ b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.stories.jsx @@ -95,8 +95,7 @@ const Template = args => { return ( <> - {/* Bootstrap version of anchor menu depends on the header component */} - {isBootstrap &&
} +
diff --git a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.styles.js b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.styles.js index bb019213f..64cd9a6e9 100644 --- a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.styles.js +++ b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.styles.js @@ -3,16 +3,9 @@ import styled from "styled-components"; const AnchorMenuWrapper = styled.div` &.sticky { position: fixed; - top: 0; + top: var(--uds-anchor-menu-top, 0px); left: 0; width: 100%; - &.with-header { - top: ${({ requiresAltMenuSpacing }) => - requiresAltMenuSpacing ? "112px" : "142px"}; - @media (max-width: 992px) { - top: 110px; - } - } } .mobile-menu-toggler { background-color: transparent;