75 lines
2.1 KiB
TypeScript
75 lines
2.1 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")};
|
|
|
|
${(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;
|