Reputation: 54949
I am using Tailwind + Headless UI to create a hamburger Menu bar on mobile to show the menu on click. But when I click on the menu it does not close automatically and creates a bad UX.
<Disclosure
as="nav"
className="fixed top-0 left-0 right-0 z-10 w-full bg-white shadow"
>
{({ open }) => (
<>
<div className="px-2 mx-auto max-w-7xl sm:px-4 lg:px-8">
<div className="flex justify-between h-16">
<div className="flex px-2 lg:px-0">
<div className="flex items-center flex-shrink-0">
<Link href="/">
<a className="relative block w-12 h-12">
<Image
src="/img/logo.png"
alt="NFT Volt Logo"
layout="fill"
className="w-auto h-6 lg:block"
/>
</a>
</Link>
</div>
<div className="hidden lg:ml-6 lg:flex lg:space-x-1">
{navLinks.map((link) => (
<NavLink key={link.id} href={link.href}>
{link.name}
</NavLink>
))}
</div>
</div>
<div className="flex items-center justify-center flex-1 px-2 lg:ml-6 lg:justify-end">
<div className="w-full max-w-lg lg:max-w-xs">
<label htmlFor="search" className="sr-only">
Search
</label>
<div className="relative">
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<SearchIcon
className="w-5 h-5 text-gray-400"
aria-hidden="true"
/>
</div>
<input
id="search"
name="search"
className="block w-full py-2 pl-10 pr-3 leading-5 placeholder-gray-500 bg-white border border-gray-300 rounded-md focus:outline-none focus:placeholder-gray-400 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="Search NFT projects..."
type="search"
/>
</div>
</div>
<Link href="/list-project" passHref>
<a
href="#"
className="items-center hidden px-4 py-2 ml-6 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-md shadow-sm lg:inline-flex hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 whitespace-nowrap"
>
List your Project
</a>
</Link>
</div>
<div className="flex items-center lg:hidden">
{/* Mobile menu button */}
<Disclosure.Button className="inline-flex items-center justify-center p-2 text-gray-400 rounded-md hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500">
<span className="sr-only">
Open main menu
</span>
{open ? (
<XIcon
className="block w-6 h-6"
aria-hidden="true"
/>
) : (
<MenuIcon
className="block w-6 h-6"
aria-hidden="true"
/>
)}
</Disclosure.Button>
</div>
</div>
</div>
<Disclosure.Panel className="lg:hidden">
<div className="pt-2 pb-3 space-y-1">
{/* {navLinks.map((link) => (
<NavLinkMobile
key={link.id}
href={link.href}
onClick={() => {
console.log('click');
close();
}}
>
{link.name}
</NavLinkMobile>
))} */}
{navLinks.map((link) => (
<Disclosure.Button
as={NavLinkMobile}
key={link.id}
href={link.href}
>
{link.name}
</Disclosure.Button>
))}
<NavLinkMobile href="/list-project">
List your Project
</NavLinkMobile>
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
Tried to add manually close on click but doesn't seem to work.
Upvotes: 3
Views: 11663
Reputation: 1
useEffect(()=>{
let handler =()=>{
setToggle(false);
};
document.addEventListener("mousedown", handler);
});
This code will close the MenuBar when clicked on the outside of the page or some content.
Upvotes: 0
Reputation: 91
Use can use the close prop from Disclose itself. import it this way ({ open, close }) and use it
onClick={() => {
close();
}}
Upvotes: 1
Reputation: 11
Try using Next.js Router's push function to navigate the user when the Disclosure.Button is clicked.
At the top of your component, call the useRouter hook:
const router = useRouter();
With that, you can modify your JSX by adding an onClick property where you then call router.push({path}) , like this:
{
navLinks.map((link) => (
<Disclosure.Button
as="a"
key={link.id}
onClick={() => {
router.push(`${link.href}`);
}}
>
{link.name}
</Disclosure.Button>
));
}
Using the Next.js router will navigate the user to the desired href while still allowing the Disclosure render prop to toggle from open to closed.
For more infomation, check out - https://nextjs.org/docs/api-reference/next/router#routerpush
Upvotes: 0
Reputation: 480
The trick is to wrap the links with <Disclosure.Button>
</Disclosure.Button>
and it will close automatically the panel.
See: https://headlessui.dev/react/disclosure#closing-disclosures-manually
Upvotes: 2