DEV Community

Seog-Jun Hong
Seog-Jun Hong

Posted on

Open Source Contribution(w. Codu)

Intro

Through Hacktoberfest, I got to know the open-source project Codu, and I'm one of the contributors of Codu and I keep working on the project. This project is written in Typescript and Nextjs, so there are lots of things to learn through the contribution.

Issue

I started working on the issue 3weeks ago, but I recently could wrap it up and it took some time than I expected.

The issue was to fix the open menu on the Article Sidebar when clicked.
Image description

If you clicked Report Article, then the modal would pop up, but the menu still remained.

Investigate

First, I looked into the code, and found out they used Headless UI to use Popover component. Basically, the Popover doesn't close the menu because it is their one of attributes, so Menu Component should have used instead of Popover.

How to fix

After investigation, I found two ways of refactoring code, one is to use Menu component and the other is to close Popover manually. However, the first way needs lots of time and effort and I didn't want to modify the existing codes.

import { Popover } from '@headlessui/react'
import MyLink from './MyLink'

function MyPopover() {
  return (
    <Popover>
      <Popover.Button>Solutions</Popover.Button>
      <Popover.Panel>
        <Popover.Button as={MyLink} href="/insights">
          Insights
        </Popover.Button>
        {/* ... */}
      </Popover.Panel>
    </Popover>
  )
}
Enter fullscreen mode Exit fullscreen mode

Thus, I easily used Popover.Button between Popover.Panel, and when I clicked the Report Article, the menu was gone as I expected, but unfortunately, Report Modal also disappeared in a second.

 const [isPopoverPanelOpen, setIsPopoverPanelOpen] = useState(true);

  const [isPopoverPanelOpen, setIsPopoverPanelOpen] = useState(true);

  const closePopoverPanel = (e: React.FormEvent) => {
    e.preventDefault();
    setIsPopoverPanelOpen(false);
  };

  const openPopoverPanel = () => {
    setIsPopoverPanelOpen(true);
  };
            <Popover className="ml-4 relative">
            <Popover.Button
              onClick={openPopoverPanel}
              className="rounded-full p-1 hover:bg-neutral-300 dark:hover:bg-neutral-800"
            >
              <span className="sr-only">Open user menu</span>
              <DotsHorizontalIcon className="h-6 w-6" />
            </Popover.Button>
            <Transition
              as={Fragment}
              enter="transition ease-out duration-100"
              enterFrom="transform opacity-0 scale-95"
              enterTo="transform opacity-100 scale-100"
              leave="transition ease-in duration-75"
              leaveFrom="transform opacity-100 scale-100"
              leaveTo="transform opacity-0 scale-95"
            >
              <Popover.Panel
                className={`origin-top-right absolute bottom-14 right-0 lg:left-16 lg:bottom-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white dark:bg-white ring-1 px-1 ring-black ring-opacity-5 focus:outline-none 
                ${isPopoverPanelOpen ? "" : "hidden"}`}
              >
                <div>
                  <ul>
                    <li className="block rounded px-4 py-2 text-neutral-900 hover:bg-neutral-200 dark:text-neutral-700">
                      <a
                        href={`https://twitter.com/intent/tweet?text="${postTitle}", by ${postUsername}&hashtags=coducommunity,codu&url=${postUrl}`}
                      >
                        Share to X
                      </a>
                    </li>
                    <li>
                      <a
                        className="block rounded px-4 py-2 text-neutral-900 hover:bg-neutral-200 dark:text-neutral-700"
                        href={`https://www.linkedin.com/sharing/share-offsite/?url=${postUrl}`}
                      >
                        Share to LinkedIn
                      </a>
                    </li>
                    <li>
                      <button
                        className="block w-full rounded px-4 py-2 text-left text-neutral-900 hover:bg-neutral-200 dark:text-neutral-700"
                        onClick={handleCopyToClipboard}
                      >
                        {label}
                      </button>
                    </li>
                    <li className="block px-4 py-2 text-neutral-900 dark:text-neutral-700 hover:bg-neutral-200 rounded">
                      <button onClick={closePopoverPanel}>
                        <ReportModal
                          type="post"
                          title={postTitle}
                          id={postId}
                        />
                      </button>
                    </li>
                  </ul>
                </div>
              </Popover.Panel>
            </Transition>
          </Popover>
Enter fullscreen mode Exit fullscreen mode

Eventually, I could use another workaround to close the menu while the report modal is open. I created a button with closePopoverPanel function and this updates isPopoverPanelOpen value as false and it closes the menu. And when Popover.Button is clicked it updates isPopoverPanelOpen value as true vice versa. Now, the component can show and hide the menu when Report Article is clicked. This is my PR.

Image description

Top comments (0)