Skip to content

Commit b426535

Browse files
Mobile navbar (#72)
* Add mobile navbar/conditional rendering * Remove visibility of mobile navbar on desktop * Minor CSS styling fixes * Add functionality alongside navbar * Add changes to mobile navbar * Add more conditional rendering to UI * Remove remaining issues * Resolve styling issues
1 parent 07e000a commit b426535

File tree

5 files changed

+169
-3308
lines changed

5 files changed

+169
-3308
lines changed

client/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
"@fontsource/oxygen-mono": "^4.5.2",
99
"@reach/window-size": "^0.16.0",
1010
"@styled-icons/bootstrap": "^10.34.0",
11+
"@styled-icons/boxicons-regular": "^10.38.0",
1112
"@styled-icons/boxicons-solid": "^10.38.0",
13+
"@styled-icons/evaicons-outline": "^10.34.0",
1214
"@styled-icons/open-iconic": "^10.18.0",
1315
"@testing-library/jest-dom": "^5.16.2",
1416
"@testing-library/react": "^12.1.2",
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Link, useLocation } from 'react-router-dom'
2+
import styled, { css } from 'styled-components'
3+
4+
const Navbar = styled.div`
5+
@media screen and (max-width: 800px) {
6+
font-family: ${({ theme }) => theme.secondaryFonts};
7+
position: absolute;
8+
z-index: 10;
9+
top: 0;
10+
left: 0;
11+
overflow-x: hidden;
12+
padding-top: 20px;
13+
transform: ${(props) =>
14+
props.showMobileNavbar ? 'translateY(0em)' : 'translateY(-60em)'};
15+
transition: 0.6s ease;
16+
width: 100%;
17+
height: 100%;
18+
display: flex;
19+
flex-direction: column;
20+
justify-content: center;
21+
align-items: center;
22+
text-align: center;
23+
background-color: ${({ theme }) => theme.black};
24+
}
25+
`
26+
27+
const StyledLink = styled(Link)`
28+
text-decoration: none;
29+
color: white;
30+
padding-left: 200px;
31+
padding-right: 200px;
32+
font-weight: bold;
33+
transition: 0.2s ease;
34+
margin: 0.3em;
35+
font-size: 6vw;
36+
:hover {
37+
background-color: ${({ theme }) => theme.navy};
38+
}
39+
${({ selected }) =>
40+
selected &&
41+
css`
42+
background-color: ${({ theme }) => theme.navy};
43+
`}
44+
`
45+
46+
function MobileBar({ showMobileNavbar }: { showMobileNavbar: boolean }) {
47+
const location = useLocation()
48+
return (
49+
<Navbar showMobileNavbar={showMobileNavbar}>
50+
<StyledLink to="" selected={location.pathname === '/'}>
51+
Clock
52+
</StyledLink>
53+
<StyledLink to="/lifelines" selected={location.pathname === '/lifelines'}>
54+
Lifelines
55+
</StyledLink>
56+
<StyledLink to="/settings" selected={location.pathname === '/settings'}>
57+
Settings
58+
</StyledLink>
59+
</Navbar>
60+
)
61+
}
62+
63+
export default MobileBar

client/src/components/ui/NavBar.tsx

Lines changed: 88 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Menu } from '@styled-icons/boxicons-regular'
2+
import { CloseOutline } from '@styled-icons/evaicons-outline'
13
import { useEffect, useState } from 'react'
24
import { FullScreenHandle } from 'react-full-screen'
35
import { Link } from 'react-router-dom'
@@ -6,14 +8,16 @@ import styled from 'styled-components'
68
import EnterFullscreen from '../../components/buttons/EnterFullscreen'
79
import ExitFullscreen from '../../components/buttons/ExitFullscreen'
810
import clock from '../../images/clock.png'
11+
import MobileBar from '../buttons/MobileBar'
912

1013
const NavBox = styled.div`
1114
font-family: ${({ theme }) => theme.secondaryFonts};
15+
1216
${(props) =>
1317
props.isFullScreen ? 'position: absolute;' : 'overflow: hidden;'}
1418
width: 100%;
15-
height: 8vh;
16-
z-index: 4;
19+
${(props) => (props.mobileWidth ? 'height: 2vh;' : 'height: 9vh;')}
20+
z-index: 11;
1721
background-color: ${({ theme }) => theme.black};
1822
1923
margin-top: ${(props) =>
@@ -24,6 +28,8 @@ const NavBox = styled.div`
2428
? 'translateY(-12.5em)'
2529
: 'translateY(0px)'};
2630
transition: 0.3s ease-out;
31+
${(props) =>
32+
props.showMobileNavbar ? 'position: absolute' : 'position: relative'}
2733
`
2834

2935
const PageLink = styled.div`
@@ -70,6 +76,20 @@ const Image = styled.div`
7076
scale(0.25, 0.25);
7177
`
7278

79+
const StyledMenu = styled(Menu)`
80+
float: right;
81+
color: white;
82+
size: 2.5em;
83+
display: block;
84+
`
85+
86+
const StyledCloseOutline = styled(CloseOutline)`
87+
float: right;
88+
color: white;
89+
size: 2.5em;
90+
display: block;
91+
`
92+
7393
function NavBar({
7494
handle,
7595
isFullScreen,
@@ -79,6 +99,17 @@ function NavBar({
7999
isFullScreen: boolean
80100
atHome: boolean
81101
}) {
102+
const [mobileWidth, setMobileWidth] = useState(
103+
window.matchMedia('(max-width: 800px)').matches,
104+
)
105+
useEffect(() => {
106+
window
107+
.matchMedia('(max-width: 800px)')
108+
.addEventListener('change', (e) => setMobileWidth(e.matches))
109+
}, [])
110+
111+
const [showMobileNavbar, setMobileNavbar] = useState(false)
112+
82113
function MouseTrack(): boolean {
83114
const [y, setY] = useState()
84115
useEffect(() => {
@@ -94,37 +125,62 @@ function NavBar({
94125
})
95126
return y && y <= 100 ? true : false
96127
}
128+
97129
return (
98-
<NavBox isFullScreen={!isFullScreen} inBounds={MouseTrack()}>
99-
<Link to="/">
100-
<HomeLink>
101-
<Button>
102-
Climate Clock
103-
<Image>
104-
<img src={clock} alt="climate_clock_logo" />
105-
</Image>
106-
</Button>
107-
</HomeLink>
108-
</Link>
109-
{atHome ? (
110-
<FullScreenButton>
111-
{isFullScreen ? (
112-
<EnterFullscreen handle={handle} />
113-
) : (
114-
<ExitFullscreen handle={handle} />
115-
)}
116-
</FullScreenButton>
117-
) : (
118-
' '
119-
)}
120-
121-
<Link to="/settings">
122-
<PageLink>Settings</PageLink>
123-
</Link>
124-
<Link to="/lifelines">
125-
<PageLink>Lifelines</PageLink>
126-
</Link>
127-
</NavBox>
130+
<>
131+
<NavBox isFullScreen={!isFullScreen} inBounds={MouseTrack()}>
132+
<Link to="/">
133+
<HomeLink>
134+
<Button>
135+
Climate Clock
136+
<Image>
137+
<img src={clock} alt="climate_clock_logo" />
138+
</Image>
139+
</Button>
140+
</HomeLink>
141+
</Link>
142+
{atHome ? (
143+
<FullScreenButton>
144+
{isFullScreen ? (
145+
<EnterFullscreen handle={handle} />
146+
) : (
147+
<ExitFullscreen handle={handle} />
148+
)}
149+
</FullScreenButton>
150+
) : (
151+
' '
152+
)}
153+
{mobileWidth ? (
154+
[
155+
!showMobileNavbar ? (
156+
<StyledMenu
157+
size="2.5em"
158+
onClick={() => {
159+
setMobileNavbar(!showMobileNavbar)
160+
}}
161+
/>
162+
) : (
163+
<StyledCloseOutline
164+
size="2.5em"
165+
onClick={() => {
166+
setMobileNavbar(!showMobileNavbar)
167+
}}
168+
/>
169+
),
170+
]
171+
) : (
172+
<>
173+
<Link to="/settings">
174+
<PageLink>Settings</PageLink>
175+
</Link>
176+
<Link to="/lifelines">
177+
<PageLink>Lifelines</PageLink>
178+
</Link>
179+
</>
180+
)}
181+
</NavBox>
182+
{mobileWidth && <MobileBar showMobileNavbar={showMobileNavbar} />}
183+
</>
128184
)
129185
}
130186

client/yarn.lock

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,6 +1714,14 @@
17141714
"@babel/runtime" "^7.14.0"
17151715
"@styled-icons/styled-icon" "^10.6.3"
17161716

1717+
"@styled-icons/boxicons-regular@^10.38.0":
1718+
version "10.38.0"
1719+
resolved "https://registry.yarnpkg.com/@styled-icons/boxicons-regular/-/boxicons-regular-10.38.0.tgz#1eb80b4f94a18a9b77b11dee5204aa23378d37ec"
1720+
integrity sha512-xjhafoa0/EeYtQOyTw+ohuSlBx599t8l8++JH1tQlM0l73dP4icTpF4znYL+HhZeaUe3D+UhrkfWuBBua2w2Qw==
1721+
dependencies:
1722+
"@babel/runtime" "^7.15.3"
1723+
"@styled-icons/styled-icon" "^10.6.3"
1724+
17171725
"@styled-icons/boxicons-solid@^10.38.0":
17181726
version "10.38.0"
17191727
resolved "https://registry.yarnpkg.com/@styled-icons/boxicons-solid/-/boxicons-solid-10.38.0.tgz#bb2a6e21f3412c97ae8029396e3ca9fb107c7658"
@@ -1722,6 +1730,14 @@
17221730
"@babel/runtime" "^7.15.3"
17231731
"@styled-icons/styled-icon" "^10.6.3"
17241732

1733+
"@styled-icons/evaicons-outline@^10.34.0":
1734+
version "10.34.0"
1735+
resolved "https://registry.yarnpkg.com/@styled-icons/evaicons-outline/-/evaicons-outline-10.34.0.tgz#a75c01763539a182834aefd6b60e9db0a45eef7b"
1736+
integrity sha512-ONPKJO+u3DB/rsCJdIKt6OBoKBvIvM/EsulxuWniRPPr0rR5lwueGocJpJmEUi+C4gsMllBSkcL5cOdFyd1Nbw==
1737+
dependencies:
1738+
"@babel/runtime" "^7.14.0"
1739+
"@styled-icons/styled-icon" "^10.6.3"
1740+
17251741
"@styled-icons/open-iconic@^10.18.0":
17261742
version "10.18.0"
17271743
resolved "https://registry.yarnpkg.com/@styled-icons/open-iconic/-/open-iconic-10.18.0.tgz#658bd6aee9232d0983c7aa8949713221c7d5bb87"

0 commit comments

Comments
 (0)