Skip to content

Commit 3e797c5

Browse files
feat: add cool new dropdowns off header
1 parent 6d762ba commit 3e797c5

File tree

1 file changed

+120
-70
lines changed

1 file changed

+120
-70
lines changed

src/components/Common/Header.tsx

Lines changed: 120 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@ import { PlayType } from 'src/types'
66
import { useRouter } from 'next/router'
77
import { DiscordIcon } from './Icons'
88
import { useCallback, useContext, useEffect, useState } from 'react'
9+
import { motion, AnimatePresence } from 'framer-motion'
910
import { AuthContext, ModalContext, WindowSizeContext } from 'src/contexts'
1011
import { LeaderboardNavBadge } from '../Leaderboard/LeaderboardNavBadge'
1112
import { useLeaderboardStatus } from 'src/hooks/useLeaderboardStatus'
1213

1314
export const Header: React.FC = () => {
1415
const [showMenu, setShowMenu] = useState(false)
16+
const [showPlayDropdown, setShowPlayDropdown] = useState(false)
17+
const [showMoreDropdown, setShowMoreDropdown] = useState(false)
18+
const [showProfileDropdown, setShowProfileDropdown] = useState(false)
1519
const { isMobile } = useContext(WindowSizeContext)
1620

1721
const { user, connectLichess, logout } = useContext(AuthContext)
@@ -70,32 +74,46 @@ export const Header: React.FC = () => {
7074
}, [showMenu])
7175

7276
const userInfo = user?.lichessId ? (
73-
<div className="group relative flex w-full items-center gap-3 rounded bg-background-1 px-3 py-2 md:w-auto">
77+
<div
78+
className="relative flex w-full items-center gap-3 rounded bg-background-1 px-3 py-2 md:w-auto"
79+
onMouseEnter={() => setShowProfileDropdown(true)}
80+
onMouseLeave={() => setShowProfileDropdown(false)}
81+
>
7482
<span className="material-symbols-outlined text-3xl">account_circle</span>
7583
<div className="flex flex-col">
7684
<p className="text-sm">{user?.displayName}</p>
7785
<p className="text-xs text-secondary">View Info</p>
7886
</div>
79-
<div className="absolute bottom-[100%] left-0 z-50 hidden w-full overflow-hidden rounded bg-background-2 group-hover:flex group-hover:flex-col md:bottom-auto md:top-[100%]">
80-
<Link
81-
href="/profile"
82-
className="flex w-full items-center justify-start px-3 py-2 hover:bg-background-3"
83-
>
84-
Profile
85-
</Link>
86-
<Link
87-
href="/settings"
88-
className="flex w-full items-center justify-start px-3 py-2 hover:bg-background-3"
89-
>
90-
Settings
91-
</Link>
92-
<button
93-
onClick={logout}
94-
className="flex w-full items-center justify-start px-3 py-2 hover:bg-background-3"
95-
>
96-
Logout
97-
</button>
98-
</div>
87+
<AnimatePresence>
88+
{showProfileDropdown && (
89+
<motion.div
90+
initial={{ opacity: 0, y: -10 }}
91+
animate={{ opacity: 1, y: 0 }}
92+
exit={{ opacity: 0, y: -10 }}
93+
transition={{ duration: 0.2 }}
94+
className="absolute bottom-[100%] left-0 z-50 w-full overflow-hidden rounded border border-white/10 bg-background-1 shadow-lg md:bottom-auto md:top-[100%]"
95+
>
96+
<Link
97+
href="/profile"
98+
className="flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
99+
>
100+
Profile
101+
</Link>
102+
<Link
103+
href="/settings"
104+
className="flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
105+
>
106+
Settings
107+
</Link>
108+
<button
109+
onClick={logout}
110+
className="flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
111+
>
112+
Logout
113+
</button>
114+
</motion.div>
115+
)}
116+
</AnimatePresence>
99117
</div>
100118
) : (
101119
<button onClick={connectLichess}>Sign in</button>
@@ -110,31 +128,43 @@ export const Header: React.FC = () => {
110128
</Link>
111129
<div className="hidden flex-row gap-1 *:px-2 *:py-1 md:flex">
112130
<div
113-
className={`${router.pathname.startsWith('/play') && 'bg-background-1'} group relative`}
131+
className={`${router.pathname.startsWith('/play') && 'bg-background-1'} relative`}
132+
onMouseEnter={() => setShowPlayDropdown(true)}
133+
onMouseLeave={() => setShowPlayDropdown(false)}
114134
>
115135
<button className="uppercase">Play</button>
116-
<div className="absolute left-0 top-[100%] z-30 hidden w-48 flex-col items-start bg-background-1 group-hover:flex">
117-
<button
118-
onClick={() => startGame('againstMaia')}
119-
className="flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
120-
>
121-
Play Maia
122-
</button>
123-
<button
124-
onClick={() => startGame('handAndBrain')}
125-
className="flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
126-
>
127-
Play Hand and Brain
128-
</button>
129-
<a
130-
className="flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
131-
href="https://lichess.org/@/maia1"
132-
target="_blank"
133-
rel="noreferrer"
134-
>
135-
Play Maia on Lichess
136-
</a>
137-
</div>
136+
<AnimatePresence>
137+
{showPlayDropdown && (
138+
<motion.div
139+
initial={{ opacity: 0, y: -10 }}
140+
animate={{ opacity: 1, y: 0 }}
141+
exit={{ opacity: 0, y: -10 }}
142+
transition={{ duration: 0.2 }}
143+
className="absolute left-0 top-[100%] z-30 w-48 overflow-hidden rounded border border-white/10 bg-background-1 shadow-lg"
144+
>
145+
<button
146+
onClick={() => startGame('againstMaia')}
147+
className="flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
148+
>
149+
Play Maia
150+
</button>
151+
<button
152+
onClick={() => startGame('handAndBrain')}
153+
className="flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
154+
>
155+
Play Hand and Brain
156+
</button>
157+
<a
158+
className="flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
159+
href="https://lichess.org/@/maia1"
160+
target="_blank"
161+
rel="noreferrer"
162+
>
163+
Play Maia on Lichess
164+
</a>
165+
</motion.div>
166+
)}
167+
</AnimatePresence>
138168
</div>
139169
<Link
140170
href="/analysis"
@@ -166,35 +196,55 @@ export const Header: React.FC = () => {
166196
>
167197
Leaderboard
168198
</Link>
169-
<div className="group relative">
199+
<div
200+
className="relative"
201+
onMouseEnter={() => setShowMoreDropdown(true)}
202+
onMouseLeave={() => setShowMoreDropdown(false)}
203+
>
170204
<button className="-gap-1 flex items-center">
171205
<p className="uppercase">More</p>
172-
<i className="material-symbols-outlined">arrow_drop_down</i>
173-
</button>
174-
<div className="absolute left-0 top-[100%] z-30 hidden w-32 flex-col items-start bg-background-1 group-hover:flex">
175-
<Link
176-
href="/blog"
177-
className="flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
178-
>
179-
Blog
180-
</Link>
181-
<a
182-
target="_blank"
183-
rel="noreferrer"
184-
href="https://twitch.tv/maiachess"
185-
className="flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
186-
>
187-
Watch
188-
</a>
189-
<a
190-
target="_blank"
191-
rel="noreferrer"
192-
href="https://forms.gle/XYeoTJF4YgUu4Vq28"
193-
className="flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
206+
<motion.i
207+
className="material-symbols-outlined"
208+
animate={{ rotate: showMoreDropdown ? 180 : 0 }}
209+
transition={{ duration: 0.2 }}
194210
>
195-
Feedback
196-
</a>
197-
</div>
211+
arrow_drop_down
212+
</motion.i>
213+
</button>
214+
<AnimatePresence>
215+
{showMoreDropdown && (
216+
<motion.div
217+
initial={{ opacity: 0, y: -10 }}
218+
animate={{ opacity: 1, y: 0 }}
219+
exit={{ opacity: 0, y: -10 }}
220+
transition={{ duration: 0.2 }}
221+
className="absolute left-0 top-[100%] z-30 w-32 overflow-hidden rounded border border-white/10 bg-background-1 shadow-lg"
222+
>
223+
<Link
224+
href="/blog"
225+
className="flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
226+
>
227+
Blog
228+
</Link>
229+
<a
230+
target="_blank"
231+
rel="noreferrer"
232+
href="https://twitch.tv/maiachess"
233+
className="flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
234+
>
235+
Watch
236+
</a>
237+
<a
238+
target="_blank"
239+
rel="noreferrer"
240+
href="https://forms.gle/XYeoTJF4YgUu4Vq28"
241+
className="flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
242+
>
243+
Feedback
244+
</a>
245+
</motion.div>
246+
)}
247+
</AnimatePresence>
198248
</div>
199249
</div>
200250
</div>

0 commit comments

Comments
 (0)