Skip to content
This repository was archived by the owner on Jan 19, 2025. It is now read-only.

Commit 9a1af24

Browse files
authored
Merge pull request #72 from chicio/header-animation 🚀
Animate sticky header #71
2 parents 6d4e426 + 9516d36 commit 9a1af24

File tree

2 files changed

+100
-42
lines changed

2 files changed

+100
-42
lines changed

graphql-types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ export type DirectoryCtimeArgs = {
258258
export type Site = Node & {
259259
buildTime?: Maybe<Scalars['Date']>;
260260
siteMetadata?: Maybe<SiteSiteMetadata>;
261+
port?: Maybe<Scalars['Int']>;
262+
host?: Maybe<Scalars['String']>;
261263
polyfill?: Maybe<Scalars['Boolean']>;
262264
pathPrefix?: Maybe<Scalars['String']>;
263265
id: Scalars['ID'];
@@ -1009,6 +1011,8 @@ export type QueryAllDirectoryArgs = {
10091011
export type QuerySiteArgs = {
10101012
buildTime?: Maybe<DateQueryOperatorInput>;
10111013
siteMetadata?: Maybe<SiteSiteMetadataFilterInput>;
1014+
port?: Maybe<IntQueryOperatorInput>;
1015+
host?: Maybe<StringQueryOperatorInput>;
10121016
polyfill?: Maybe<BooleanQueryOperatorInput>;
10131017
pathPrefix?: Maybe<StringQueryOperatorInput>;
10141018
id?: Maybe<StringQueryOperatorInput>;
@@ -2183,6 +2187,8 @@ export type SiteFieldsEnum =
21832187
| 'siteMetadata___contacts___links___medium'
21842188
| 'siteMetadata___contacts___links___devto'
21852189
| 'siteMetadata___contacts___links___instagram'
2190+
| 'port'
2191+
| 'host'
21862192
| 'polyfill'
21872193
| 'pathPrefix'
21882194
| 'id'
@@ -2284,6 +2290,8 @@ export type SiteGroupConnection = {
22842290
export type SiteFilterInput = {
22852291
buildTime?: Maybe<DateQueryOperatorInput>;
22862292
siteMetadata?: Maybe<SiteSiteMetadataFilterInput>;
2293+
port?: Maybe<IntQueryOperatorInput>;
2294+
host?: Maybe<StringQueryOperatorInput>;
22872295
polyfill?: Maybe<BooleanQueryOperatorInput>;
22882296
pathPrefix?: Maybe<StringQueryOperatorInput>;
22892297
id?: Maybe<StringQueryOperatorInput>;
Lines changed: 92 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
import React from "react";
1+
import React, { useEffect, useState } from "react";
22
import { tracking } from "../../../logic/tracking";
33
import styled, { css } from "styled-components";
44
import { Container } from "../atoms/container";
55
import { slugs } from "../../../logic/slug";
66
import { MenuItemWithTracking } from "../../menu-item-with-tracking";
77

8-
const MenuContainer = styled.div`
8+
interface MenuContainerProps {
9+
shouldHide: boolean;
10+
}
11+
12+
const MenuContainer = styled.div<MenuContainerProps>`
913
background-color: ${(props) => props.theme.light.primaryColor};
1014
box-shadow: inset 0 -2px 5px rgba(0, 0, 0, 0.1);
1115
position: fixed;
12-
top: 0;
16+
top: ${(props) => (props.shouldHide ? "-55px" : 0)};
17+
transition: top 0.3s ease 0s;
1318
width: 100%;
1419
height: 55px;
1520
z-index: 300;
@@ -56,47 +61,92 @@ const NavBarMenuItem = styled(MenuItemWithTracking)`
5661
`};
5762
`;
5863

64+
enum ScrollDirection {
65+
up,
66+
down,
67+
}
68+
69+
const useScrollDirection = () => {
70+
const threshold = 100;
71+
const [scrollDir, setScrollDir] = useState(ScrollDirection.up);
72+
73+
useEffect(() => {
74+
let previousScrollYPosition = window.pageYOffset;
75+
76+
const scrolledMoreThanThreshold = (currentScrollYPosition: number) =>
77+
Math.abs(currentScrollYPosition - previousScrollYPosition) > threshold;
78+
79+
const isScrollingUp = (currentScrollYPosition: number) =>
80+
currentScrollYPosition > previousScrollYPosition;
81+
82+
const updateScrollDir = () => {
83+
const currentScrollYPosition = window.pageYOffset;
84+
85+
if (scrolledMoreThanThreshold(currentScrollYPosition)) {
86+
const newScrollDirection = isScrollingUp(currentScrollYPosition)
87+
? ScrollDirection.down
88+
: ScrollDirection.up;
89+
setScrollDir(newScrollDirection);
90+
previousScrollYPosition =
91+
currentScrollYPosition > 0 ? currentScrollYPosition : 0;
92+
}
93+
};
94+
95+
const onScroll = () => window.requestAnimationFrame(updateScrollDir);
96+
97+
window.addEventListener("scroll", onScroll);
98+
99+
return () => window.removeEventListener("scroll", onScroll);
100+
}, []);
101+
102+
return scrollDir;
103+
};
104+
59105
export interface MenuProps {
60106
trackingCategory: string;
61107
pathname: string;
62108
}
63109

64-
export const Menu: React.FC<MenuProps> = ({ trackingCategory, pathname }) => (
65-
<MenuContainer>
66-
<NavBar>
67-
<NavBarMenuItem
68-
selected={pathname === "/"}
69-
to={"/"}
70-
trackingData={{
71-
action: tracking.action.open_home,
72-
category: trackingCategory,
73-
label: tracking.label.header,
74-
}}
75-
>
76-
{"Home"}
77-
</NavBarMenuItem>
78-
<NavBarMenuItem
79-
selected={pathname !== slugs.aboutMe}
80-
to={slugs.blog}
81-
trackingData={{
82-
action: tracking.action.open_blog,
83-
category: trackingCategory,
84-
label: tracking.label.header,
85-
}}
86-
>
87-
{"Blog"}
88-
</NavBarMenuItem>
89-
<NavBarMenuItem
90-
selected={pathname === slugs.aboutMe}
91-
to={slugs.aboutMe}
92-
trackingData={{
93-
action: tracking.action.open_about_me,
94-
category: trackingCategory,
95-
label: tracking.label.header,
96-
}}
97-
>
98-
{"About me"}
99-
</NavBarMenuItem>
100-
</NavBar>
101-
</MenuContainer>
102-
);
110+
export const Menu: React.FC<MenuProps> = ({ trackingCategory, pathname }) => {
111+
const direction = useScrollDirection();
112+
113+
return (
114+
<MenuContainer shouldHide={direction == ScrollDirection.down}>
115+
<NavBar>
116+
<NavBarMenuItem
117+
selected={pathname === "/"}
118+
to={"/"}
119+
trackingData={{
120+
action: tracking.action.open_home,
121+
category: trackingCategory,
122+
label: tracking.label.header,
123+
}}
124+
>
125+
{"Home"}
126+
</NavBarMenuItem>
127+
<NavBarMenuItem
128+
selected={pathname !== slugs.aboutMe}
129+
to={slugs.blog}
130+
trackingData={{
131+
action: tracking.action.open_blog,
132+
category: trackingCategory,
133+
label: tracking.label.header,
134+
}}
135+
>
136+
{"Blog"}
137+
</NavBarMenuItem>
138+
<NavBarMenuItem
139+
selected={pathname === slugs.aboutMe}
140+
to={slugs.aboutMe}
141+
trackingData={{
142+
action: tracking.action.open_about_me,
143+
category: trackingCategory,
144+
label: tracking.label.header,
145+
}}
146+
>
147+
{"About me"}
148+
</NavBarMenuItem>
149+
</NavBar>
150+
</MenuContainer>
151+
);
152+
};

0 commit comments

Comments
 (0)