Files
web2.0-frontend/src/components/Header.tsx
T
Simeon Pursiainen e4784e1932 Master
2025-09-11 21:21:13 +03:00

82 lines
2.4 KiB
TypeScript

import React, { useState, useEffect, useRef } from "react";
import throttle from "lodash/throttle";
import styled from "styled-components";
import colors from "@theme/colors";
import breakpoints from "@theme/breakpoints";
import Navigation from "./Navigation";
import NavigationMobile from "./NavigationMobile";
import HeaderLogo from "./HeaderLogo";
import BlockScroll from "./BlockScroll";
const StyledHeader = styled.header`
display: flex;
flex-flow: row nowrap;
@media screen and (max-width: ${breakpoints.mobile}) {
flex-flow: column nowrap;
}
`;
const Sticky = styled.div<{ $isHidden?: boolean; $mobileMenuOpen?: boolean }>`
position: sticky;
top: 0;
z-index: 10;
padding: 0 1rem;
background-color: ${colors.darkBlue};
transition: all 200ms ease-out;
height: ${(p) => (p.$mobileMenuOpen ? "100vh" : "unset")};
/* tape to allow mobile dropdown menu scrolling */
@media screen and (max-width: ${breakpoints.mobile}) {
overflow-y: ${(p) => (p.$mobileMenuOpen ? "auto" : "visible")};
overflow-x: hidden;
-webkit-overflow-scrolling: touch; /* apparently some ios optimization for smoother scrolin' */
}
${(p) => (p.$isHidden ? (`
transition: all 200ms ease-in;
transform: translateY(-100%);
`) : null)}
`;
const PREVENT_IS_HIDDEN_Y = 150;
const Header: React.FC = () => {
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [isHidden, setHidden] = useState(false);
const yCoord = useRef(0);
const handleMobileMenuClick = () => setMobileMenuOpen(!mobileMenuOpen);
useEffect(() => {
const handleScroll = () => {
const newCoord = window.pageYOffset;
if (!mobileMenuOpen && newCoord > yCoord.current && newCoord > PREVENT_IS_HIDDEN_Y) {
setHidden(true);
} else {
setHidden(false);
}
yCoord.current = newCoord;
};
const func = throttle(handleScroll, 200);
// Prevents hide when clicking mobileMenuOpen
handleScroll();
window.addEventListener("scroll", func);
return () => window.removeEventListener("scroll", func);
}, [mobileMenuOpen]);
return (
<Sticky $isHidden={isHidden} $mobileMenuOpen={mobileMenuOpen}>
{ mobileMenuOpen && (
<BlockScroll />
)}
<StyledHeader>
<HeaderLogo />
<Navigation onMobileMenuOpen={handleMobileMenuClick} />
</StyledHeader>
<NavigationMobile mobileMenuOpen={mobileMenuOpen} />
</Sticky>
);
};
export default Header;