Skip to content

Commit b0957f3

Browse files
feat: Add mobile navbar (#3186)
1 parent 173ab29 commit b0957f3

File tree

2 files changed

+119
-44
lines changed

2 files changed

+119
-44
lines changed

site/src/components/NavbarView/NavbarView.stories.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,17 @@ ForMember.args = {
2727
return Promise.resolve()
2828
},
2929
}
30+
31+
export const SmallViewport = Template.bind({})
32+
SmallViewport.args = {
33+
user: MockUser,
34+
onSignOut: () => {
35+
return Promise.resolve()
36+
},
37+
}
38+
SmallViewport.parameters = {
39+
viewport: {
40+
defaultViewport: "tablet",
41+
},
42+
chromatic: { viewports: [420] },
43+
}
+105-44
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
import Drawer from "@material-ui/core/Drawer"
2+
import IconButton from "@material-ui/core/IconButton"
13
import List from "@material-ui/core/List"
24
import ListItem from "@material-ui/core/ListItem"
35
import { fade, makeStyles } from "@material-ui/core/styles"
6+
import MenuIcon from "@material-ui/icons/Menu"
7+
import { useState } from "react"
48
import { NavLink, useLocation } from "react-router-dom"
59
import * as TypesGen from "../../api/typesGenerated"
610
import { navHeight } from "../../theme/constants"
@@ -19,41 +23,66 @@ export const Language = {
1923
users: "Users",
2024
}
2125

22-
export const NavbarView: React.FC<NavbarViewProps> = ({ user, onSignOut }) => {
26+
const NavItems: React.FC<{ className?: string; linkClassName?: string }> = ({ className }) => {
2327
const styles = useStyles()
2428
const location = useLocation()
29+
30+
return (
31+
<List className={combineClasses([styles.navItems, className])}>
32+
<ListItem button className={styles.item}>
33+
<NavLink
34+
className={combineClasses([styles.link, location.pathname.startsWith("/@") && "active"])}
35+
to="/workspaces"
36+
>
37+
{Language.workspaces}
38+
</NavLink>
39+
</ListItem>
40+
<ListItem button className={styles.item}>
41+
<NavLink className={styles.link} to="/templates">
42+
{Language.templates}
43+
</NavLink>
44+
</ListItem>
45+
<ListItem button className={styles.item}>
46+
<NavLink className={styles.link} to="/users">
47+
{Language.users}
48+
</NavLink>
49+
</ListItem>
50+
</List>
51+
)
52+
}
53+
54+
export const NavbarView: React.FC<NavbarViewProps> = ({ user, onSignOut }) => {
55+
const styles = useStyles()
56+
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
57+
2558
return (
2659
<nav className={styles.root}>
27-
<List className={styles.fixed}>
28-
<ListItem className={styles.item}>
29-
<NavLink className={styles.logo} to="/workspaces">
60+
<IconButton
61+
aria-label="Open menu"
62+
className={styles.mobileMenuButton}
63+
onClick={() => {
64+
setIsDrawerOpen(true)
65+
}}
66+
>
67+
<MenuIcon />
68+
</IconButton>
69+
70+
<Drawer anchor="left" open={isDrawerOpen} onClose={() => setIsDrawerOpen(false)}>
71+
<div className={styles.drawer}>
72+
<div className={styles.drawerHeader}>
3073
<Logo fill="white" opacity={1} width={125} />
31-
</NavLink>
32-
</ListItem>
33-
<ListItem button className={styles.item}>
34-
<NavLink
35-
className={combineClasses([
36-
styles.link,
37-
location.pathname.startsWith("/@") && "active",
38-
])}
39-
to="/workspaces"
40-
>
41-
{Language.workspaces}
42-
</NavLink>
43-
</ListItem>
44-
<ListItem button className={styles.item}>
45-
<NavLink className={styles.link} to="/templates">
46-
{Language.templates}
47-
</NavLink>
48-
</ListItem>
49-
<ListItem button className={styles.item}>
50-
<NavLink className={styles.link} to="/users">
51-
{Language.users}
52-
</NavLink>
53-
</ListItem>
54-
</List>
55-
<div className={styles.fullWidth} />
56-
<div className={styles.fixed}>
74+
</div>
75+
<NavItems />
76+
</div>
77+
</Drawer>
78+
79+
<NavLink className={styles.logo} to="/workspaces">
80+
<Logo fill="white" opacity={1} width={125} />
81+
</NavLink>
82+
83+
<NavItems className={styles.desktopNavItems} />
84+
85+
<div className={styles.profileButton}>
5786
{user && <UserDropdown user={user} onSignOut={onSignOut} />}
5887
</div>
5988
</nav>
@@ -64,9 +93,7 @@ const useStyles = makeStyles((theme) => ({
6493
root: {
6594
position: "relative",
6695
display: "flex",
67-
flex: 0,
68-
flexDirection: "row",
69-
justifyContent: "center",
96+
justifyContent: "space-between",
7097
alignItems: "center",
7198
height: navHeight,
7299
background: theme.palette.background.paper,
@@ -76,14 +103,37 @@ const useStyles = makeStyles((theme) => ({
76103
borderTop: `1px solid ${theme.palette.divider}`,
77104
},
78105
borderBottom: `1px solid ${theme.palette.divider}`,
106+
107+
[theme.breakpoints.up("md")]: {
108+
justifyContent: "flex-start",
109+
},
79110
},
80-
fixed: {
81-
flex: 0,
82-
display: "flex",
111+
drawer: {
112+
width: 250,
113+
},
114+
drawerHeader: {
115+
padding: theme.spacing(2),
116+
paddingTop: theme.spacing(4),
117+
paddingBottom: theme.spacing(4),
118+
},
119+
navItems: {
83120
padding: 0,
84121
},
85-
fullWidth: {
86-
flex: 1,
122+
desktopNavItems: {
123+
display: "none",
124+
[theme.breakpoints.up("md")]: {
125+
display: "flex",
126+
},
127+
},
128+
profileButton: {
129+
[theme.breakpoints.up("md")]: {
130+
marginLeft: "auto",
131+
},
132+
},
133+
mobileMenuButton: {
134+
[theme.breakpoints.up("md")]: {
135+
display: "none",
136+
},
87137
},
88138
logo: {
89139
alignItems: "center",
@@ -107,8 +157,7 @@ const useStyles = makeStyles((theme) => ({
107157
color: "hsl(220, 11%, 71%)",
108158
display: "flex",
109159
fontSize: 16,
110-
height: navHeight,
111-
padding: `0 ${theme.spacing(3)}px`,
160+
padding: `${theme.spacing(1.5)}px ${theme.spacing(2)}px`,
112161
textDecoration: "none",
113162
transition: "background-color 0.3s ease",
114163

@@ -124,13 +173,25 @@ const useStyles = makeStyles((theme) => ({
124173

125174
"&::before": {
126175
content: `" "`,
127-
bottom: 0,
128-
left: theme.spacing(3),
176+
left: 0,
177+
width: 2,
178+
height: "100%",
129179
background: theme.palette.secondary.dark,
130-
right: theme.spacing(3),
131-
height: 2,
132180
position: "absolute",
181+
182+
[theme.breakpoints.up("md")]: {
183+
bottom: 0,
184+
left: theme.spacing(3),
185+
width: `calc(100% - 2 * ${theme.spacing(3)}px)`,
186+
right: theme.spacing(3),
187+
height: 2,
188+
},
133189
},
134190
},
191+
192+
[theme.breakpoints.up("md")]: {
193+
height: navHeight,
194+
padding: `0 ${theme.spacing(3)}px`,
195+
},
135196
},
136197
}))

0 commit comments

Comments
 (0)