Harsha M V
Harsha M V

Reputation: 54949

Tailwind + Headless UI: Close Mobile Menu after click or clickaway

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

Answers (4)

user26885086
user26885086

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

Mennah Jafar
Mennah Jafar

Reputation: 91

Use can use the close prop from Disclose itself. import it this way ({ open, close }) and use it

onClick={() => {
  close();
}}

Upvotes: 1

Austin J.
Austin J.

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

Juan Schwindt
Juan Schwindt

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

Related Questions