blog / themes /landing /components /MobileMenu.js
sandy-try's picture
Upload 699 files
1b72d7e verified
'use client'
import { useState, useRef, useEffect } from 'react'
import { Transition } from '@headlessui/react'
import Link from 'next/link'
import CONFIG from '../config'
import { siteConfig } from '@/lib/config'
export default function MobileMenu() {
const [mobileNavOpen, setMobileNavOpen] = useState(false)
const trigger = useRef(null)
const mobileNav = useRef(null)
// close the mobile menu on click outside
useEffect(() => {
const clickHandler = ({ target }) => {
if (!mobileNav.current || !trigger.current) return
if (!mobileNavOpen || mobileNav.current.contains(target) || trigger.current.contains(target)) return
setMobileNavOpen(false)
}
document.addEventListener('click', clickHandler)
return () => document.removeEventListener('click', clickHandler)
})
// close the mobile menu if the esc key is pressed
useEffect(() => {
const keyHandler = ({ keyCode }) => {
if (!mobileNavOpen || keyCode !== 27) return
setMobileNavOpen(false)
}
document.addEventListener('keydown', keyHandler)
return () => document.removeEventListener('keydown', keyHandler)
})
return (
<div className="flex md:hidden">
{/* Hamburger button */}
<button
ref={trigger}
className={`hamburger ${mobileNavOpen && 'active'}`}
aria-controls="mobile-nav"
aria-expanded={mobileNavOpen}
onClick={() => setMobileNavOpen(!mobileNavOpen)}
>
<span className="sr-only">Menu</span>
<svg className="w-6 h-6 fill-current text-gray-900" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<rect y="4" width="24" height="2" />
<rect y="11" width="24" height="2" />
<rect y="18" width="24" height="2" />
</svg>
</button>
{/* Mobile navigation */}
<div ref={mobileNav}>
<Transition
show={mobileNavOpen}
as="nav"
id="mobile-nav"
className="absolute top-full h-screen pb-16 z-20 left-0 w-full overflow-scroll bg-white"
enter="transition ease-out duration-200 transform"
enterFrom="opacity-0 -translate-y-2"
enterTo="opacity-100"
leave="transition ease-out duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<ul className="px-5 py-2">
<li>
<Link href={siteConfig('LANDING_HEADER_BUTTON_1_URL', null, CONFIG)} className="flex font-medium w-full text-gray-600 hover:text-gray-900 py-2 justify-center" onClick={() => setMobileNavOpen(false)}>
<div>{siteConfig('LANDING_HEADER_BUTTON_1_TITLE', null, CONFIG)}</div>
</Link>
</li>
<li>
<Link href={siteConfig('LANDING_HEADER_BUTTON_2_URL', null, CONFIG)} className="btn-sm text-gray-200 bg-gray-900 hover:bg-gray-800 w-full my-2" onClick={() => setMobileNavOpen(false)}>
<span>{siteConfig('LANDING_HEADER_BUTTON_2_TITLE', null, CONFIG)}</span>
<svg className="w-3 h-3 fill-current text-gray-400 shrink-0 ml-2 -mr-1" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<path d="M11.707 5.293L7 .586 5.586 2l3 3H0v2h8.586l-3 3L7 11.414l4.707-4.707a1 1 0 000-1.414z" fill="#999" fillRule="nonzero" />
</svg>
</Link>
</li>
</ul>
</Transition>
</div>
</div>
)
}