mirror of
https://github.com/vercel/commerce.git
synced 2025-07-06 13:01:22 +00:00
Merge pull request #12 from sesamyab/danielgent/ch220/mobile-menu
Danielgent/ch220/mobile menu
This commit is contained in:
commit
d85d13960c
11
components/common/Navbar/DesktopNavMenu.module.css
Normal file
11
components/common/Navbar/DesktopNavMenu.module.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.navMenu {
|
||||||
|
@apply hidden ml-6 space-x-4 lg:block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
@apply items-center transition ease-in-out duration-75 cursor-pointer text-accent-0 border-b-2 border-opacity-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link:hover {
|
||||||
|
@apply border-b-2 border-opacity-40;
|
||||||
|
}
|
28
components/common/Navbar/DesktopNavMenu.tsx
Normal file
28
components/common/Navbar/DesktopNavMenu.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { FC, } from 'react'
|
||||||
|
import s from './DesktopNavMenu.module.css'
|
||||||
|
import Link from 'next/link'
|
||||||
|
|
||||||
|
interface Link {
|
||||||
|
href: string
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
interface DesktopNavMenuProps {
|
||||||
|
links?: Link[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const DesktopNavMenu: FC<DesktopNavMenuProps> = ({ links }) => {
|
||||||
|
return (
|
||||||
|
<nav className={s.navMenu}>
|
||||||
|
<Link href="/search">
|
||||||
|
<a className={s.link}>All</a>
|
||||||
|
</Link>
|
||||||
|
{links?.map((l) => (
|
||||||
|
<Link href={l.href} key={l.href}>
|
||||||
|
<a className={s.link}>{l.label}</a>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DesktopNavMenu
|
34
components/common/Navbar/MenuButton.module.css
Normal file
34
components/common/Navbar/MenuButton.module.css
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
.menuButton {
|
||||||
|
cursor: pointer;
|
||||||
|
height: 30px;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 30px;
|
||||||
|
@apply lg:hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuButton::after,
|
||||||
|
.menuButton::before {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
content: '';
|
||||||
|
height: 1px;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuButton::after {
|
||||||
|
transform: translateY(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuButton::before {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuButton.isOpen::before {
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuButton.isOpen::after {
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
19
components/common/Navbar/MenuButton.tsx
Normal file
19
components/common/Navbar/MenuButton.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { FC } from 'react'
|
||||||
|
import s from './MenuButton.module.css'
|
||||||
|
import cn from 'classnames'
|
||||||
|
|
||||||
|
interface MenuButtonProps {
|
||||||
|
isOpen: boolean
|
||||||
|
onClick: any
|
||||||
|
}
|
||||||
|
|
||||||
|
const MenuButton: FC<MenuButtonProps> = ({ isOpen, onClick }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={onClick}
|
||||||
|
className={cn(s.menuButton, { [s.isOpen]: isOpen })}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MenuButton
|
27
components/common/Navbar/MobileNavMenu.module.css
Normal file
27
components/common/Navbar/MobileNavMenu.module.css
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
.navMenu {
|
||||||
|
@apply lg:hidden;
|
||||||
|
|
||||||
|
background-color: #000;
|
||||||
|
bottom: 0;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 2.333rem;
|
||||||
|
left: 0;
|
||||||
|
letter-spacing: -0.25px;
|
||||||
|
padding: 60px 1rem 40px;
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
top: 50px;
|
||||||
|
transform: translateY(-100%);
|
||||||
|
transition: transform 0.2s ease 0.1s, visibility 0.3s;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navMenu.isOpen {
|
||||||
|
transform: translateY(0);
|
||||||
|
transition-delay: 0s;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
@apply block;
|
||||||
|
}
|
30
components/common/Navbar/MobileNavMenu.tsx
Normal file
30
components/common/Navbar/MobileNavMenu.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { FC } from 'react'
|
||||||
|
import s from './MobileNavMenu.module.css'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import cn from 'classnames'
|
||||||
|
|
||||||
|
interface Link {
|
||||||
|
href: string
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
interface MobileNavMenuProps {
|
||||||
|
links?: Link[]
|
||||||
|
isOpen: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const MobileNavMenu: FC<MobileNavMenuProps> = ({ links, isOpen }) => {
|
||||||
|
return (
|
||||||
|
<nav className={cn(s.navMenu, { [s.isOpen]: isOpen })}>
|
||||||
|
<Link href="/search">
|
||||||
|
<a className={s.link}>All</a>
|
||||||
|
</Link>
|
||||||
|
{links?.map((l) => (
|
||||||
|
<Link href={l.href} key={l.href}>
|
||||||
|
<a className={s.link}>{l.label}</a>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MobileNavMenu
|
@ -3,7 +3,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.navContainer {
|
.navContainer {
|
||||||
@apply bg-secondary;
|
@apply bg-secondary relative z-40;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
}
|
}
|
||||||
.searchContainer {
|
.searchContainer {
|
||||||
@ -11,22 +11,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav {
|
.nav {
|
||||||
@apply relative flex flex-row justify-between;
|
@apply relative flex flex-row justify-between z-40;
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navMenu {
|
|
||||||
@apply hidden ml-6 space-x-4 lg:block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link {
|
|
||||||
@apply items-center transition ease-in-out duration-75 cursor-pointer text-accent-0 border-b-2 border-opacity-0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link:hover {
|
|
||||||
@apply border-b-2 border-opacity-40;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
@apply cursor-pointer;
|
@apply cursor-pointer;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import { FC } from 'react'
|
import { FC, useState } from 'react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import s from './Navbar.module.css'
|
import s from './Navbar.module.css'
|
||||||
import NavbarRoot from './NavbarRoot'
|
import NavbarRoot from './NavbarRoot'
|
||||||
|
import MenuButton from './MenuButton'
|
||||||
|
import DesktopNavMenu from './DesktopNavMenu'
|
||||||
|
import MobileNavMenu from './MobileNavMenu'
|
||||||
import { Logo, Container } from '@components/ui'
|
import { Logo, Container } from '@components/ui'
|
||||||
import { Searchbar, UserNav } from '@components/common'
|
import { Searchbar, UserNav } from '@components/common'
|
||||||
|
|
||||||
@ -13,42 +16,41 @@ interface NavbarProps {
|
|||||||
links?: Link[]
|
links?: Link[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const Navbar: FC<NavbarProps> = ({ links }) => (
|
const Navbar: FC<NavbarProps> = ({ links }) => {
|
||||||
<NavbarRoot>
|
const [isMenuOpen, setIsMenuOpen] = useState(false)
|
||||||
<div className={s.navContainer}>
|
return (
|
||||||
<Container>
|
<NavbarRoot>
|
||||||
<div className={s.nav}>
|
<div className={s.navContainer}>
|
||||||
<div className="flex items-center flex-1">
|
|
||||||
<Link href="/">
|
|
||||||
<a className={s.logo} aria-label="Logo">
|
|
||||||
<Logo />
|
|
||||||
</a>
|
|
||||||
</Link>
|
|
||||||
<nav className={s.navMenu}>
|
|
||||||
<Link href="/search">
|
|
||||||
<a className={s.link}>All</a>
|
|
||||||
</Link>
|
|
||||||
{links?.map((l) => (
|
|
||||||
<Link href={l.href} key={l.href}>
|
|
||||||
<a className={s.link}>{l.label}</a>
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-end flex-1 space-x-8">
|
|
||||||
<UserNav />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Container>
|
|
||||||
</div>
|
|
||||||
{process.env.COMMERCE_SEARCH_ENABLED && (
|
|
||||||
<div className={s.searchContainer}>
|
|
||||||
<Container>
|
<Container>
|
||||||
<Searchbar />
|
<div className={s.nav}>
|
||||||
|
<div className="flex items-center flex-1">
|
||||||
|
<Link href="/">
|
||||||
|
<a className={s.logo} aria-label="Logo">
|
||||||
|
<Logo />
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
<DesktopNavMenu links={links} />
|
||||||
|
</div>
|
||||||
|
<MenuButton
|
||||||
|
isOpen={isMenuOpen}
|
||||||
|
onClick={() => setIsMenuOpen(!isMenuOpen)}
|
||||||
|
/>
|
||||||
|
<div className="flex items-center justify-end flex-1 space-x-8">
|
||||||
|
<UserNav />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
)}
|
{process.env.COMMERCE_SEARCH_ENABLED && (
|
||||||
</NavbarRoot>
|
<div className={s.searchContainer}>
|
||||||
)
|
<Container>
|
||||||
|
<Searchbar />
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<MobileNavMenu links={links} isOpen={isMenuOpen} />
|
||||||
|
</NavbarRoot>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export default Navbar
|
export default Navbar
|
||||||
|
Loading…
x
Reference in New Issue
Block a user