diff --git a/graphql-types.ts b/graphql-types.ts index 30aa8e54f..bdc60a66f 100644 --- a/graphql-types.ts +++ b/graphql-types.ts @@ -258,6 +258,8 @@ export type DirectoryCtimeArgs = { export type Site = Node & { buildTime?: Maybe; siteMetadata?: Maybe; + port?: Maybe; + host?: Maybe; polyfill?: Maybe; pathPrefix?: Maybe; id: Scalars['ID']; @@ -1009,6 +1011,8 @@ export type QueryAllDirectoryArgs = { export type QuerySiteArgs = { buildTime?: Maybe; siteMetadata?: Maybe; + port?: Maybe; + host?: Maybe; polyfill?: Maybe; pathPrefix?: Maybe; id?: Maybe; @@ -2183,6 +2187,8 @@ export type SiteFieldsEnum = | 'siteMetadata___contacts___links___medium' | 'siteMetadata___contacts___links___devto' | 'siteMetadata___contacts___links___instagram' + | 'port' + | 'host' | 'polyfill' | 'pathPrefix' | 'id' @@ -2284,6 +2290,8 @@ export type SiteGroupConnection = { export type SiteFilterInput = { buildTime?: Maybe; siteMetadata?: Maybe; + port?: Maybe; + host?: Maybe; polyfill?: Maybe; pathPrefix?: Maybe; id?: Maybe; diff --git a/src/components/design-system/organism/menu.tsx b/src/components/design-system/organism/menu.tsx index d2a0f645f..e5f40d20d 100644 --- a/src/components/design-system/organism/menu.tsx +++ b/src/components/design-system/organism/menu.tsx @@ -1,15 +1,20 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { tracking } from "../../../logic/tracking"; import styled, { css } from "styled-components"; import { Container } from "../atoms/container"; import { slugs } from "../../../logic/slug"; import { MenuItemWithTracking } from "../../menu-item-with-tracking"; -const MenuContainer = styled.div` +interface MenuContainerProps { + shouldHide: boolean; +} + +const MenuContainer = styled.div` background-color: ${(props) => props.theme.light.primaryColor}; box-shadow: inset 0 -2px 5px rgba(0, 0, 0, 0.1); position: fixed; - top: 0; + top: ${(props) => (props.shouldHide ? "-55px" : 0)}; + transition: top 0.3s ease 0s; width: 100%; height: 55px; z-index: 300; @@ -56,47 +61,92 @@ const NavBarMenuItem = styled(MenuItemWithTracking)` `}; `; +enum ScrollDirection { + up, + down, +} + +const useScrollDirection = () => { + const threshold = 100; + const [scrollDir, setScrollDir] = useState(ScrollDirection.up); + + useEffect(() => { + let previousScrollYPosition = window.pageYOffset; + + const scrolledMoreThanThreshold = (currentScrollYPosition: number) => + Math.abs(currentScrollYPosition - previousScrollYPosition) > threshold; + + const isScrollingUp = (currentScrollYPosition: number) => + currentScrollYPosition > previousScrollYPosition; + + const updateScrollDir = () => { + const currentScrollYPosition = window.pageYOffset; + + if (scrolledMoreThanThreshold(currentScrollYPosition)) { + const newScrollDirection = isScrollingUp(currentScrollYPosition) + ? ScrollDirection.down + : ScrollDirection.up; + setScrollDir(newScrollDirection); + previousScrollYPosition = + currentScrollYPosition > 0 ? currentScrollYPosition : 0; + } + }; + + const onScroll = () => window.requestAnimationFrame(updateScrollDir); + + window.addEventListener("scroll", onScroll); + + return () => window.removeEventListener("scroll", onScroll); + }, []); + + return scrollDir; +}; + export interface MenuProps { trackingCategory: string; pathname: string; } -export const Menu: React.FC = ({ trackingCategory, pathname }) => ( - - - - {"Home"} - - - {"Blog"} - - - {"About me"} - - - -); +export const Menu: React.FC = ({ trackingCategory, pathname }) => { + const direction = useScrollDirection(); + + return ( + + + + {"Home"} + + + {"Blog"} + + + {"About me"} + + + + ); +};