Header Menu Component

An example of a Functional React

by Aaron Fryer

TypeScript

import React, { useState, useEffect } from "react";
import { Link } from "gatsby";
import { Bem } from "../../utils/bem";
import { MenuProps, MenuItem } from "../Menu";
import "./styles.scss";

export const HeaderMenu = ({ items, pathname }: MenuProps) => {
  const [isSticky, setSticky] = useState(false);
  const component = new Bem("c-header-menu");
  const container = new Bem("c-header-menu-container");
  const handleScroll = () => {
    setSticky(window.scrollY >= (window.innerHeight - 106));
  };

  useEffect(() => {
    window.addEventListener("scroll", handleScroll);

    return () => {
      window.removeEventListener("scroll", () => handleScroll);
    };
  }, []);

  const renderMenuItem = ({ name, path }: MenuItem) => {
    return (
      <li className={component.with("item", { active: pathname === path })} key={`${name}-${path}`}>
        <Link to={path}>{name}</Link>
      </li>
    );
  };

  return (
    <nav className={container.with("", { sticky: isSticky })}>
      <ul className={component.with()}>
        {items.map(renderMenuItem)}
      </ul>
    </nav>
  );
};

export default HeaderMenu;