4
0
forked from crowetic/commerce

Feature/hamburger menu (#540)

* Setup Mobile Menu Sidebar

* Setup Basic Mobile Menu Items Styling

* Implement full width styling for mobile devices

* Cleanup

Co-authored-by: Nine <at059214@Abdurahmans-MacBook-Pro.local>
This commit is contained in:
Nine 2021-11-25 19:09:21 +01:00 committed by GitHub
parent a01568bc3a
commit 82cb719ad6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 123 additions and 17 deletions

View File

@ -13,6 +13,7 @@ import { useAcceptCookies } from '@lib/hooks/useAcceptCookies'
import { Sidebar, Button, LoadingDots } from '@components/ui' import { Sidebar, Button, LoadingDots } from '@components/ui'
import PaymentMethodView from '@components/checkout/PaymentMethodView' import PaymentMethodView from '@components/checkout/PaymentMethodView'
import CheckoutSidebarView from '@components/checkout/CheckoutSidebarView' import CheckoutSidebarView from '@components/checkout/CheckoutSidebarView'
import MenuSidebarView, { Link } from '../UserNav/MenuSidebarView'
import LoginView from '@components/auth/LoginView' import LoginView from '@components/auth/LoginView'
import s from './Layout.module.css' import s from './Layout.module.css'
@ -74,12 +75,14 @@ const ModalUI: FC = () => {
) : null ) : null
} }
const SidebarView: FC<{ sidebarView: string; closeSidebar(): any }> = ({ const SidebarView: FC<{
sidebarView, sidebarView: string
closeSidebar, closeSidebar(): any
}) => { links: Link[]
}> = ({ sidebarView, closeSidebar, links }) => {
return ( return (
<Sidebar onClose={closeSidebar}> <Sidebar onClose={closeSidebar}>
{sidebarView === 'MOBILEMENU_VIEW' && <MenuSidebarView links={links} />}
{sidebarView === 'CART_VIEW' && <CartSidebarView />} {sidebarView === 'CART_VIEW' && <CartSidebarView />}
{sidebarView === 'CHECKOUT_VIEW' && <CheckoutSidebarView />} {sidebarView === 'CHECKOUT_VIEW' && <CheckoutSidebarView />}
{sidebarView === 'PAYMENT_VIEW' && <PaymentMethodView />} {sidebarView === 'PAYMENT_VIEW' && <PaymentMethodView />}
@ -88,10 +91,14 @@ const SidebarView: FC<{ sidebarView: string; closeSidebar(): any }> = ({
) )
} }
const SidebarUI: FC = () => { const SidebarUI: FC<{ links: any }> = ({ links }) => {
const { displaySidebar, closeSidebar, sidebarView } = useUI() const { displaySidebar, closeSidebar, sidebarView } = useUI()
return displaySidebar ? ( return displaySidebar ? (
<SidebarView sidebarView={sidebarView} closeSidebar={closeSidebar} /> <SidebarView
sidebarView={sidebarView}
closeSidebar={closeSidebar}
links={links}
/>
) : null ) : null
} }
@ -113,7 +120,7 @@ const Layout: FC<Props> = ({
<main className="fit">{children}</main> <main className="fit">{children}</main>
<Footer pages={pageProps.pages} /> <Footer pages={pageProps.pages} />
<ModalUI /> <ModalUI />
<SidebarUI /> <SidebarUI links={navBarlinks} />
<FeatureBar <FeatureBar
title="This site uses cookies to improve your experience. By clicking, you agree to our Privacy Policy." title="This site uses cookies to improve your experience. By clicking, you agree to our Privacy Policy."
hide={acceptedCookies} hide={acceptedCookies}

View File

@ -9,6 +9,7 @@ interface Link {
href: string href: string
label: string label: string
} }
interface NavbarProps { interface NavbarProps {
links?: Link[] links?: Link[]
} }

View File

@ -22,7 +22,7 @@ const SidebarLayout: FC<ComponentProps> = ({
<button <button
onClick={handleClose} onClick={handleClose}
aria-label="Close" aria-label="Close"
className="hover:text-accent-5 transition ease-in-out duration-150 flex items-center focus:outline-none" className="hover:text-accent-5 transition ease-in-out duration-150 flex items-center focus:outline-none mr-6"
> >
<Cross className="h-6 w-6 hover:text-accent-3" /> <Cross className="h-6 w-6 hover:text-accent-3" />
<span className="ml-2 text-accent-7 text-sm ">Close</span> <span className="ml-2 text-accent-7 text-sm ">Close</span>

View File

@ -0,0 +1,7 @@
.root {
@apply px-4 sm:px-6 sm:w-full flex-1 z-20;
}
.item {
@apply text-2xl font-bold;
}

View File

@ -0,0 +1,41 @@
import Link from 'next/link'
import s from './MenuSidebarView.module.css'
import { FC } from 'react'
import { useUI } from '@components/ui/context'
import SidebarLayout from '@components/common/SidebarLayout'
import { Link as LinkProps} from '.'
interface MenuProps {
links?: LinkProps[]
}
const MenuSidebarView: FC<MenuProps> = (props) => {
const { closeSidebar } = useUI()
const handleClose = () => closeSidebar()
return (
<SidebarLayout handleClose={handleClose}>
<div className={s.root}>
<nav>
<ul>
<li className={s.item}>
<Link href="/search">
<a>All</a>
</Link>
</li>
{props.links?.map((l: any) => (
<li key={l.href} className={s.item}>
<Link href={l.href}>
<a>{l.label}</a>
</Link>
</li>
))}
</ul>
</nav>
</div>
</SidebarLayout>
)
}
export default MenuSidebarView

View File

@ -0,0 +1,6 @@
export { default } from './MenuSidebarView'
export interface Link {
href: string
label: string
}

View File

@ -1,5 +1,5 @@
.root { .root {
@apply relative; @apply relative flex items-center;
} }
.list { .list {
@ -7,14 +7,14 @@
} }
.item { .item {
@apply mr-6 cursor-pointer relative transition ease-in-out duration-100 flex items-center outline-none text-primary; @apply ml-6 cursor-pointer relative transition ease-in-out duration-100 flex items-center outline-none text-primary;
&:hover { &:hover {
@apply text-accent-6 transition scale-110 duration-100; @apply text-accent-6 transition scale-110 duration-100;
} }
&:last-child { &:first-child {
@apply mr-0; @apply ml-0;
} }
&:focus, &:focus,
@ -35,6 +35,11 @@
@apply inline-flex justify-center rounded-full; @apply inline-flex justify-center rounded-full;
} }
.avatarButton:focus { .mobileMenu {
@apply outline-none; @apply flex lg:hidden ml-6
} }
.avatarButton:focus,
.mobileMenu:focus {
@apply outline-none;
}

View File

@ -10,6 +10,7 @@ import { useUI } from '@components/ui/context'
import Button from '@components/ui/Button' import Button from '@components/ui/Button'
import DropdownMenu from './DropdownMenu' import DropdownMenu from './DropdownMenu'
import s from './UserNav.module.css' import s from './UserNav.module.css'
import Menu from '@components/icons/Menu'
interface Props { interface Props {
className?: string className?: string
@ -20,7 +21,8 @@ const countItem = (count: number, item: LineItem) => count + item.quantity
const UserNav: FC<Props> = ({ className }) => { const UserNav: FC<Props> = ({ className }) => {
const { data } = useCart() const { data } = useCart()
const { data: customer } = useCustomer() const { data: customer } = useCustomer()
const { toggleSidebar, closeSidebarIfPresent, openModal } = useUI() const { toggleSidebar, closeSidebarIfPresent, openModal, setSidebarView } =
useUI()
const itemsCount = data?.lineItems.reduce(countItem, 0) ?? 0 const itemsCount = data?.lineItems.reduce(countItem, 0) ?? 0
return ( return (
@ -31,7 +33,10 @@ const UserNav: FC<Props> = ({ className }) => {
<Button <Button
className={s.item} className={s.item}
variant="naked" variant="naked"
onClick={toggleSidebar} onClick={() => {
setSidebarView('CART_VIEW')
toggleSidebar()
}}
aria-label={`Cart items: ${itemsCount}`} aria-label={`Cart items: ${itemsCount}`}
> >
<Bag /> <Bag />
@ -65,6 +70,19 @@ const UserNav: FC<Props> = ({ className }) => {
)} )}
</li> </li>
)} )}
<li className={s.mobileMenu}>
<Button
className={s.item}
variant="naked"
onClick={() => {
setSidebarView('MOBILEMENU_VIEW')
toggleSidebar()
}}
aria-label="Menu"
>
<Menu />
</Button>
</li>
</ul> </ul>
</nav> </nav>
) )

21
components/icons/Menu.tsx Normal file
View File

@ -0,0 +1,21 @@
const Menu = ({ ...props }) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
{...props}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16m-7 6h7"
/>
</svg>
)
}
export default Menu

View File

@ -48,7 +48,7 @@ const Sidebar: FC<SidebarProps> = ({ children, onClose }) => {
> >
<div className="absolute inset-0 overflow-hidden"> <div className="absolute inset-0 overflow-hidden">
<div className={s.backdrop} onClick={onClose} /> <div className={s.backdrop} onClick={onClose} />
<section className="absolute inset-y-0 right-0 max-w-full flex outline-none pl-10"> <section className="absolute inset-y-0 right-0 w-full md:w-auto max-w-full flex outline-none md:pl-10">
<div className="h-full w-full md:w-screen md:max-w-md"> <div className="h-full w-full md:w-screen md:max-w-md">
<div className={s.sidebar} ref={contentRef}> <div className={s.sidebar} ref={contentRef}>
{children} {children}