Newer
Older
gnexus-ui-kit / src / js / demo-navigation.js
export default function demoNavigation() {
  const navItems = [...document.querySelectorAll(".docs-sidebar .list-item")];
  const sections = [...document.querySelectorAll(".docs-content .section[id]")];

  if (!navItems.length || !sections.length) {
    return;
  }

  const setActive = id => {
    navItems.forEach(item => {
      const link = item.querySelector(".list-action");
      item.classList.toggle("list-item-active", link?.getAttribute("href") === `#${id}`);
    });
  };

  const getActiveSection = () => {
    const anchor = Math.min(window.innerHeight * 0.35, 280);
    let active = sections[0];

    for (const section of sections) {
      const rect = section.getBoundingClientRect();

      if (rect.top <= anchor) {
        active = section;
      } else {
        break;
      }
    }

    return active;
  };

  let ticking = false;

  const updateActive = () => {
    ticking = false;
    const active = getActiveSection();

    if (active?.id) {
      setActive(active.id);
    }
  };

  const requestUpdate = () => {
    if (ticking) {
      return;
    }

    ticking = true;
    window.requestAnimationFrame(updateActive);
  };

  window.addEventListener("scroll", requestUpdate, { passive: true });
  window.addEventListener("resize", requestUpdate);

  if (window.location.hash) {
    setActive(window.location.hash.slice(1));
  } else {
    updateActive();
  }
}