1
0
mirror of https://github.com/vercel/commerce.git synced 2025-07-25 11:11:24 +00:00
Files
assets
components
auth
cart
common
Avatar
FeatureBar
Footer
Head
HomeAllProductsGrid
I18nWidget
Layout
Navbar
Searchbar
UserNav
DropdownMenu.module.css
DropdownMenu.tsx
UserNav.module.css
UserNav.tsx
index.ts
index.ts
icons
product
ui
wishlist
config
docs
framework
lib
pages
public
.editorconfig
.env.template
.gitignore
.prettierignore
CHANGELOG.md
README.md
codegen.json
global.d.ts
license.md
next-env.d.ts
next.config.js
package.json
postcss.config.js
tailwind.config.js
tsconfig.json
yarn.lock
commerce/components/common/UserNav/DropdownMenu.tsx
2021-01-11 13:55:45 -03:00

126 lines
3.2 KiB
TypeScript

import cn from 'classnames'
import Link from 'next/link'
import { FC, useRef, useState, useEffect } from 'react'
import { useTheme } from 'next-themes'
import { useRouter } from 'next/router'
import s from './DropdownMenu.module.css'
import { Avatar } from '@components/common'
import { Moon, Sun } from '@components/icons'
import { useUI } from '@components/ui/context'
import ClickOutside from '@lib/click-outside'
import useLogout from '@framework/auth/use-logout'
import {
disableBodyScroll,
enableBodyScroll,
clearAllBodyScrollLocks,
} from 'body-scroll-lock'
interface DropdownMenuProps {
open?: boolean
}
const LINKS = [
{
name: 'My Orders',
href: '/orders',
},
{
name: 'My Profile',
href: '/profile',
},
{
name: 'My Cart',
href: '/cart',
},
]
const DropdownMenu: FC<DropdownMenuProps> = ({ open = false }) => {
const logout = useLogout()
const { pathname } = useRouter()
const { theme, setTheme } = useTheme()
const [display, setDisplay] = useState(false)
const { closeSidebarIfPresent } = useUI()
const ref = useRef() as React.MutableRefObject<HTMLUListElement>
useEffect(() => {
if (ref.current) {
if (display) {
disableBodyScroll(ref.current)
} else {
enableBodyScroll(ref.current)
}
}
return () => {
clearAllBodyScrollLocks()
}
}, [display])
return (
<ClickOutside active={display} onClick={() => setDisplay(false)}>
<div>
<button
className={s.avatarButton}
onClick={() => setDisplay(!display)}
aria-label="Menu"
>
<Avatar />
</button>
{display && (
<ul className={s.dropdownMenu} ref={ref}>
{LINKS.map(({ name, href }) => (
<li key={href}>
<div>
<Link href={href}>
<a
className={cn(s.link, {
[s.active]: pathname === href,
})}
onClick={() => {
setDisplay(false)
closeSidebarIfPresent()
}}
>
{name}
</a>
</Link>
</div>
</li>
))}
<li>
<a
className={cn(s.link, 'justify-between')}
onClick={() => {
theme === 'dark' ? setTheme('light') : setTheme('dark')
setDisplay(false)
}}
>
<div>
Theme: <strong>{theme}</strong>{' '}
</div>
<div className="ml-3">
{theme == 'dark' ? (
<Moon width={20} height={20} />
) : (
<Sun width="20" height={20} />
)}
</div>
</a>
</li>
<li>
<a
className={cn(s.link, 'border-t border-accents-2 mt-4')}
onClick={() => logout()}
>
Logout
</a>
</li>
</ul>
)}
</div>
</ClickOutside>
)
}
export default DropdownMenu