admin管理员组

文章数量:1302404

I am using Chakra UI to create a menu. I have something like this:

<Menu>
    <MenuButton>hover over this</MenuButton>

    <MenuList>
        <Flex>To show/hide this</Flex> 
    </MenuList>
</Menu>

I am trying to dynamically open the tag on hover. The MenuList default is to open on user click. When I click on the button and then hover over it, my hover state works. I am trying to figure out a way so that the user does not have to click on the MenuButton for hovering over it to work.

I am using Chakra UI to create a menu. I have something like this:

<Menu>
    <MenuButton>hover over this</MenuButton>

    <MenuList>
        <Flex>To show/hide this</Flex> 
    </MenuList>
</Menu>

I am trying to dynamically open the tag on hover. The MenuList default is to open on user click. When I click on the button and then hover over it, my hover state works. I am trying to figure out a way so that the user does not have to click on the MenuButton for hovering over it to work.

Share Improve this question edited Jul 12, 2021 at 22:41 Bassem 4,0504 gold badges25 silver badges53 bronze badges asked Jun 6, 2021 at 19:45 Benjamin CarlsonBenjamin Carlson 3234 silver badges14 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

Adding on to Bassem's answer. We can add onMouseEnter and onMouseLeave to the menu list so that it doesn't close when we leave the button.

import React from "react";
import {
  Flex,
  MenuItem,
  Menu,
  MenuButton,
  MenuList,
  Button,
  useDisclosure
} from "@chakra-ui/react";

export default function App() {
  const { isOpen, onOpen, onClose } = useDisclosure();
  return (
    <div className="App">
      <Flex height="100vh" align="center" justifyContent="center" bg="gray.100">
        <Menu isOpen={isOpen}>
          <MenuButton
            as={Button}
            variant="solid"
            colorScheme="teal"
            onMouseEnter={onOpen}
            onMouseLeave={onClose}
          >
            Hover Me
          </MenuButton>
          <MenuList onMouseEnter={onOpen} onMouseLeave={onClose}>
            <MenuItem>Download</MenuItem>
            <MenuItem>Create a Copy</MenuItem>
            <MenuItem>Mark as Draft</MenuItem>
            <MenuItem>Delete</MenuItem>
            <MenuItem>Attend a Workshop</MenuItem>
          </MenuList>
        </Menu>
      </Flex>
    </div>
  );
}

You can read more here https://www.coffeeclass.io/snippets/use-disclosure-menu-chakra-ui

import React, { useRef, useState } from "react";
import { Menu, MenuButton, MenuItem, MenuList } from "@chakra-ui/menu";
import { Button } from "@chakra-ui/button";

// TODO: dynamic button text and items
const PopupNavItem = () => {
  const timerRef = useRef();
  const [isOpenMenu, setIsOpenMenu] = useState(false);

  // menu list pops up automatically when cursor hovers over the button,
  const btnMouseEnterEvent = () => {
    setIsOpenMenu(true);
  };

  //,and vice versa,
  const btnMouseLeaveEvent = () => {
    // async
    timerRef.current = window.setTimeout(() => {
      setIsOpenMenu(false);
    }, 150);
  };

  // when the cursor moves away from the button but entering the menu list,the menu list stays open
  const menuListMouseEnterEvent = () => {
    // when entered, the timer has been cleared
    clearTimeout(timerRef.current);
    timerRef.current = undefined;
    setIsOpenMenu(true);
  };

  // finally, when the cursor moves away from the menu list, menu list closes
  const menuListMouseLeaveEvent = () => {
    setIsOpenMenu(false);
  };

  return (
    <Menu isOpen={isOpenMenu} id={1}>
      <MenuButton
        as={Button}
        variant="solid"
        colorScheme="teal"
        onMouseEnter={btnMouseEnterEvent}
        onMouseLeave={btnMouseLeaveEvent}
      >
        Hover Me
      </MenuButton>
      <MenuList
        onMouseEnter={menuListMouseEnterEvent}
        onMouseLeave={menuListMouseLeaveEvent}
      >
        <MenuItem>Download</MenuItem>
        <MenuItem>Create a Copy</MenuItem>
        <MenuItem>Mark as Draft</MenuItem>
        <MenuItem>Delete</MenuItem>
        <MenuItem>Attend a Workshop</MenuItem>
      </MenuList>
    </Menu>
  );
};

export default PopupNavItem;

For anyone having a hard time with hover rather than click, maybe you can try this one

For that you can use some event listeners: onMouseEnter & onMouseLeave together with useDisclosure hook that can be used to handle Menu open, close, and toggle.

import React from "react";
import {
  Flex,
  MenuItem,
  Menu,
  MenuButton,
  MenuList,
  Button,
  useDisclosure
} from "@chakra-ui/react";

export default function App() {
  const { isOpen, onOpen, onClose } = useDisclosure();
  return (
    <div className="App">
      <Flex height="100vh" align="center" justifyContent="center" bg="gray.100">
        <Menu isOpen={isOpen}>
          <MenuButton
            as={Button}
            variant="solid"
            colorScheme="teal"
            onMouseEnter={onOpen}
            onMouseLeave={onClose}
          >
            Hover Me
          </MenuButton>
          <MenuList>
            <MenuItem>Download</MenuItem>
            <MenuItem>Create a Copy</MenuItem>
            <MenuItem>Mark as Draft</MenuItem>
            <MenuItem>Delete</MenuItem>
            <MenuItem>Attend a Workshop</MenuItem>
          </MenuList>
        </Menu>
      </Flex>
    </div>
  );
}

And here is a working CodeSandbox.

本文标签: javascriptIs there a way to make chakra ui MenuList items always visibleStack Overflow