1

I have an Ant Design Dropdown component in a React application. The dropdown includes submenus. Right now, the submenu items close when they're clicked on. I would like them to instead remain open on click.

The Ant Design docs have a solution for this for the base level dropdown menu items, however, this doesn't work for sub menu items.

I also came across this Github issue where the problem is supposedly solved. However, the solution uses the old overlay prop for the Dropdown component, which is deprecated in favor of the menu prop.

Finally, I tried adding a div around the label of the submenu items with onClick={(e) => e.stopPropagation()}. This mostly works, except the menu item has some padding around itself, so the label does not take up the full space that the menu item takes up. Because of this, the submenu does not close when you click in the center of it (on the label), but it still closes if you click around the edge (on the padding).

1 Answer 1

1

I was able to find a pretty hacky way of accomplishing this without using the deprecated overlay prop. I had to manually manage the dropdown's state, as well as the menu state. I also had to use a ref to tell the menu when not to close.

import type { DropdownProps } from 'antd';
import { Dropdown } from 'antd';
import React, { useRef, useState } from 'react';

export const PersistentDropdown: React.FC<DropdownProps> = ({ children, ...props }) => {
  const [open, setOpen] = useState(false);
  const closeItem = useRef(true);
  const [openKeys, setOpenKeys] = useState<string[]>([]);

  return (
    <Dropdown
      {...props}
      open={open}
      onOpenChange={(nextOpen, info) => {
        if (info.source === 'trigger' || nextOpen) {
          setTimeout(() => setOpen(nextOpen), 0);
        }
      }}
      menu={
        props.menu && {
          ...props.menu,
          openKeys,
          onOpenChange: (keys: string[]) => {
            if (closeItem.current) {
              setOpenKeys(keys);
            } else {
              closeItem.current = true;
            }
          },
          onClick: () => (closeItem.current = false),
        }
      }
    >
      {children}
    </Dropdown>
  );
};

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.