SHARE
TWEET

src/ui/Header.js

a guest Jul 23rd, 2019 60 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { useEffect, useState } from "react"
  2. import styled from "styled-components"
  3. import { Plus, Menu, X } from "react-feather"
  4. import { Box, Flex, Image, Button } from "rebass"
  5. import { Link, StaticQuery, graphql } from "gatsby"
  6.  
  7. import { isWindow } from "src/utils/checks"
  8. import { Search } from "src/ui/Search"
  9. import { Container } from "src/ui/Container"
  10. import logo from "src/images/logo.png"
  11.  
  12. const isWindowPresent = isWindow()
  13.  
  14.  
  15. const disableScroll = () => {
  16.   if (isWindowPresent) {
  17.     const scrollbarWidth =
  18.       window.innerWidth - window.document.documentElement.clientWidth
  19.     window.document.body.classList.add('modal-open')
  20.     window.document.body.style.paddingRight = `${scrollbarWidth}px`
  21.   }
  22. }
  23.  
  24. const enableScroll = () => {
  25.   if (isWindowPresent) {
  26.     window.document.body.classList.remove('modal-open')
  27.     window.document.body.style.paddingRight = `0px`
  28.   }
  29. }
  30.  
  31. export const Header = ({ hideSearch }) => {
  32.   const [isBurgerMenuOpen, setIsBurgerMenu] = useState(false)
  33.   const [isScrolledTop, setHeaderVisibility] = useState(true)
  34.   let prevScrollPosition = isWindowPresent && window.scrollY
  35.  
  36.   const handleScrollDirection = () => {
  37.     if (prevScrollPosition > window.scrollY && window.scrollY > 100) {
  38.       setHeaderVisibility(true)
  39.     }
  40.     if (prevScrollPosition < window.scrollY && window.scrollY > 150) {
  41.       setHeaderVisibility(false)
  42.     }
  43.     prevScrollPosition = window.scrollY
  44.   }
  45.  
  46.   useEffect(() => {
  47.     isWindowPresent && window.addEventListener("scroll", handleScrollDirection)
  48.     isBurgerMenuOpen ? disableScroll() : enableScroll()
  49.     return () =>
  50.     isWindowPresent && window.removeEventListener("scroll", handleScrollDirection)
  51.   }, [isBurgerMenuOpen])
  52.  
  53.   const handleBurgerMenuClick = e => {
  54.     e.preventDefault()
  55.     setIsBurgerMenu(!isBurgerMenuOpen)
  56.   }
  57.  
  58.   return (
  59.     <StaticQuery
  60.       query={query}
  61.       render={({ allDatoCmsCategory: { nodes } }) => (
  62.         <StyledHeader isVisible={isScrolledTop}>
  63.           {isBurgerMenuOpen && (
  64.             <BurgerMenuBackground
  65.               alignItems={"center"}
  66.               flexDirection={"column"}
  67.               justifyContent={"space-around"}
  68.               backgroundColor="black"
  69.             >
  70.               <Links
  71.                 flexDirection={"column"}
  72.                 alignItems={"center"}
  73.                 justifyContent={"space-between"}
  74.               >
  75.                 {nodes.map(({ slug, title, id }) => (
  76.                   <Link
  77.                     key={id}
  78.                     to={`/category/${slug}`}
  79.                     css={{
  80.                       display: "block",
  81.                       marginBottom: "24px",
  82.                       fontSize: "3.0vh",
  83.                     }}
  84.                   >
  85.                     {title}
  86.                   </Link>
  87.                 ))}
  88.                 {[...serviceLinks, ...mobileLinks].map(({ slug, title }) => (
  89.                   <Link
  90.                     key={slug}
  91.                     to={`/${slug}`}
  92.                     css={{
  93.                       display: "block",
  94.                       marginBottom: "24px",
  95.                       fontSize: "3.0vh",
  96.                     }}
  97.                   >
  98.                     {title}
  99.                   </Link>
  100.                 ))}
  101.               </Links>
  102.             </BurgerMenuBackground>
  103.           )}
  104.           <Container>
  105.             <Flex
  106.               alignItems={"center"}
  107.               justifyContent={"space-between"}
  108.               mb={[0, 0, 0, 3]}
  109.             >
  110.               <Link to="/">
  111.                 <Image
  112.                   src={logo}
  113.                   alt="logo"
  114.                   width={["120px"]}
  115.                   css={{
  116.                     zIndex: "20",
  117.                     position: "relative",
  118.                   }}
  119.                 ></Image>
  120.               </Link>
  121.               {!hideSearch && <StyledSearch position="header" />}
  122.               <SubmitVideoButton variant="primary">
  123.                 <Plus size={"16"}></Plus>
  124.                 <span>Submit video</span>
  125.               </SubmitVideoButton>
  126.               <BurgerMenu onClick={handleBurgerMenuClick}>
  127.                 {!isBurgerMenuOpen && <Menu size={"32"} color={"white"}></Menu>}
  128.                 {isBurgerMenuOpen && <X size={"32"} color={"white"}></X>}
  129.               </BurgerMenu>
  130.             </Flex>
  131.             <Flex justifyContent={"space-between"}>
  132.               <Navigation>
  133.                 <Box as="ul" m={"0"} pl={"0"}>
  134.                   {nodes.map(({ slug, title, id }) => (
  135.                     <Box as="li" key={id} mr={"6"}>
  136.                       <Link to={`/category/${slug}`}>{title}</Link>
  137.                     </Box>
  138.                   ))}
  139.                 </Box>
  140.               </Navigation>
  141.               <Navigation>
  142.                 <Box as="ul" m={"0"} pl={"0"}>
  143.                   {serviceLinks.map(({ slug, title }) => (
  144.                     <Box as="li" key={slug} mr={"6"}>
  145.                       <Link to={`/${slug}`}>{title}</Link>
  146.                     </Box>
  147.                   ))}
  148.                 </Box>
  149.               </Navigation>
  150.             </Flex>
  151.           </Container>
  152.         </StyledHeader>
  153.       )}
  154.     />
  155.   )
  156. }
  157.  
  158. const query = graphql`
  159.   query Categories {
  160.     allDatoCmsCategory {
  161.       nodes {
  162.         title
  163.         slug
  164.         id
  165.       }
  166.     }
  167.   }
  168. `
  169.  
  170. const serviceLinks = [
  171.   { slug: "blog", title: "Blog" },
  172.   { slug: "about-us", title: "About us" },
  173.   { slug: "contact", title: "Contact us" },
  174. ]
  175.  
  176. const mobileLinks = [{ slug: "search", title: "Search" }]
  177.  
  178. const StyledHeader = styled.header`
  179.   background-color: ${({ theme }) => theme.colors.black};
  180.   padding-top: 16px;
  181.   padding-bottom: 16px;
  182.   transition: all 0.2s;
  183.   position: sticky;
  184.   z-index: 100;
  185.   top: -110px;
  186.   transition: top 0.55s ease-in-out;
  187.  
  188.   ${({ isVisible }) =>
  189.     isVisible &&
  190.     `
  191.     top:0;
  192.     `}
  193. `
  194.  
  195. const Navigation = styled.nav`
  196.   ul {
  197.     display: flex;
  198.   }
  199.  
  200.   li {
  201.     list-style: none;
  202.     &:last-child {
  203.       margin-right: 0;
  204.     }
  205.   }
  206.  
  207.   a {
  208.     transition: all 0.3s;
  209.     text-decoration: none;
  210.     font-weight: 500;
  211.     color: ${({ theme }) => theme.colors.white};
  212.  
  213.     &:hover {
  214.       color: ${({ theme }) => theme.colors.red};
  215.     }
  216.   }
  217.  
  218.   @media (max-width: ${({ theme }) => theme.breakpoints[2]}) {
  219.     display: none;
  220.   }
  221. `
  222.  
  223. const SubmitVideoButton = styled(Button)`
  224.   display: flex;
  225.   align-items: center;
  226.  
  227.   span {
  228.     margin-left: 4px;
  229.   }
  230.  
  231.   @media (max-width: ${({ theme }) => theme.breakpoints[2]}) {
  232.     display: none;
  233.   }
  234. `
  235.  
  236. const BurgerMenu = styled.button`
  237.   position: relative;
  238.   width: 40px;
  239.   height: 40px;
  240.   border: 0;
  241.   background-color: transparent;
  242.   display: none;
  243.   outline: none;
  244.   &:hover {
  245.     cursor: pointer;
  246.   }
  247.   svg {
  248.     position: absolute;
  249.     top: 50%;
  250.     left: 50%;
  251.     transform: translate(-50%, -50%);
  252.   }
  253.  
  254.   @media (max-width: ${({ theme }) => theme.breakpoints[2]}) {
  255.     display: block;
  256.   }
  257. `
  258.  
  259. const StyledSearch = styled(Search)`
  260.   transition: all 0.2s;
  261.  
  262.   @media (max-width: ${({ theme }) => theme.breakpoints[2]}) {
  263.     display: none;
  264.   }
  265. `
  266. const BurgerMenuBackground = styled(Flex)`
  267.   position: fixed;
  268.   height: calc(100% + 72px);
  269.   width: 100%;
  270.   top: 0;
  271.   left: 0;
  272.   right: 0;
  273.   bottom: 0;
  274.   a {
  275.     transition: all 0.3s;
  276.     text-decoration: none;
  277.     font-weight: 500;
  278.     color: ${({ theme }) => theme.colors.white};
  279.     &:hover {
  280.       color: ${({ theme }) => theme.colors.red};
  281.     }
  282.   }
  283. `
  284. const Links = styled(Flex)`
  285.   position: absolute;
  286.   top: 50%;
  287.   left: 50%;
  288.   transform: translate(-50%, -50%);
  289. `
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top