What is the best way to display a menu at the location of a mouse click?

Trying to display a custom menu at the location of a mouse click within a div, but it doesn't seem to be working as expected. The visibility logic works fine, but when clicking on the div, the menu only opens under the Typography element. Should the Menu be positioned elsewhere?

Check out how it's currently displaying - menu under Typography. The menu appears in the same place regardless of where I click inside the div, when ideally it should show up at the exact position of the mouse click.

Below is an example of the current setup with some code removed for clarity:


interface PositionState {
  x: number;
  y: number;
}

function WebAppTypeCard({
  id,
  name,
  image,
  description,
  image_url,
}: WebAppCardTypeProps) {
  const [visible, setVisible] = useState<boolean>(false);
  const [webApps, setWebApps] = useState<IWebApp[]>([]);
  const [position, setPosition] = useState<PositionState>({ x: 0, y: 0 });

 useEffect(() => {
    fetch(`${process.env.REACT_APP_API_URL}/webapp/read_all/${id}`, {
      headers: headers,
    })
      .then((data) => {
        return data.json();
      })
      .then((res) => {
        setWebApps(res);
      });
  }, []);


  const handleClick = (e: any) => {
    if (webApps.length > 1) {
      setPosition({ x: e.clientX, y: e.clientY }); // <--- Set position and make menu visible on mouse click
      console.log(position);
      setVisible(true);
    } else {
      window.open(selectedWALink);
    }
  };

  const handleMouseLeave = () => {
    setVisible(false);
  };

  const style = (x: number, y: number) => {
    return {
      top: x,
      left: y,
    };
  };

  const Menu = () => {
    return (
      <div style={style(position.x, position.y)}>
        {webApps.map((a) => {
          return (
            <div key={a.id} onClick={() => handleMenuClick(a.link)}>
              {a.name}
            </div>
          );
        })}
      </div>
    );
  };

  return (
    <div className="cardContainer" onMouseLeave={handleMouseLeave} onClick={handleClick}>
      <div>
        <div
          style={{
            display: "flex",
            justifyContent: "center",
          }}
        >
          <img
            className="appImg"
            src={image_url}
            width={65}
            height={65}
            style={{ paddingTop: 15 }}
            alt="Image not found"
          />
        </div>
        <div
          style={{
            paddingTop: 10,
            width: 110,
            textAlign: "center",
            marginLeft: 8,
            marginRight: 15,
          }}
        >
          <Typography noWrap variant="body2" gutterBottom>
            {name}
          </Typography>
        </div>
        {visible ? <Menu /> : null} 
      </div>
    </div>
  );
}

export default WebAppTypeCard;

Answer №1

Why not simply apply a fixed position and utilize CSS to adjust the top and left positions based on the user's click location? You can toggle visibility with each click - if visible, hide it; if hidden, display it again while updating its position for the next click.

I'm unfamiliar with implementing this in react, but I've successfully addressed similar issues in Angular before!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The flex-basis property seems to be malfunctioning as the image suddenly vanishes when

While my question may seem similar to others, the issue at hand is actually quite different. Here's how it appears in Chrome https://i.sstatic.net/tngvr.jpg Safari https://i.sstatic.net/eE74k.png In Safari, you'll notice that the map disappear ...

It appears that the jQuery.post() method is being overlooked or bypassed for unknown reasons

Trying to understand why the call to jQuery.post() isn't fetching the data or running the function after the fetch. Three files are included: an HTML file, a JavaScript file, and a PHP file. The HTML contains the modal element intended to appear when ...

Bootstrap only allows for styling the border row and outside of a table

I'm looking to remove the vertical border of a table using bootstrap, except for the outside border as illustrated below. https://i.sstatic.net/RYq7o.png I've attempted to achieve this by: <table class="table no-footer worker-data tabl ...

Problem with uploading special characters (čžćšđ) in Uploadify

I've encountered an issue with uploading images using . When I upload images with characters such as (čžćšđ) like "čžćšđ.jpg", the characters get corrupted and the uploaded image ends up looking like čćžšđ.jpg. How can I pr ...

Place the <span> element at the bottom of the <ul> list

Struggling to align the captions of an image carousel at the bottom of the <ul>. No matter what I try, it just doesn't look right. Check out my Fiddle here Below is the HTML structure: <div class="carousel"> <ul> <l ...

Difficulty encountered while trying to access JSON object

I've been utilizing the LinkedIn JS API to retrieve a list of individuals. The data is returned in JSON format, and here is the callback function: .result(function (result) { profile = result.values[0]; // Perform an action with the f ...

Pictures are not aligned at the center of the bigger card container

I am facing an issue with centering images on my cards. The containers look fine on PC (centered) when smaller, but on responsive mode they revert back to the larger size and are left aligned. I want the images in the card containers to be centered regardl ...

JavaScript that is subtle and lacks function parameters

Suppose you have: <div id="data" onclick="handleData(1)">Datum 1</div> and you prefer late binding instead: <div id="data">Datum 1</div> <script> $("#data").click(function() { handleData(1); }) </script&g ...

What steps can I take to incorporate a user-controlled autoscroll feature into this Carousel?

I am in the process of creating a "slideshow" using text boxes that can be scrolled with arrow buttons. My goal is to have the slideshow automatically scroll only until the user interacts by clicking one of the arrow buttons. Below is the state logic re ...

Limiting the quantity in SimpleCart (js)

Currently, I am working on a WordPress website where I am using simpleCart(js) to add a shopping cart feature. I sell unique articles and do not require users to add more than one article to their cart. My main concern is how to prevent users from adding ...

Should arrays of objects be kept in databases or JavaScript files?

Here is a small excerpt from an array of objects utilized on my website. It's just a snippet and not the full JS file. I have several JS files like this, some reaching up to 500 lines of code. Currently delving into databases ...

"Incorporating JSON and Ajax to dynamically populate one select based on the selection in another select

I need to display data from a JSON file in select options, and here is the structure of my JSON file: [{ "vehicle": "car1", "type": [ {"name" : "BMW", "details" : [{ "color" : "red", "price" : "50000" }, ...

What is the best way to set up a clickable image without making the entire div clickable?

Is it possible to make just a specific image clickable within a div without making the entire div clickable? I have an image inside an anchor tag and a surrounding div that is clickable. The issue is that the entire space around the first image, .home, is ...

Unable to locate image files stored in vendor/images in the Rails 4 view

I have successfully set up a custom bootstrap theme with Rails 4, and placed the image file here: /vendor/assets/images/custom_bootstrap_theme/demo/bg01.jpg The index.html.erb file is referencing this image as follows: <img src="/vendor/assets/image ...

Eliminate the golden hue from the input field when autofill is activated

Can anyone help me figure out how to get rid of this unsightly chrome background that appears when autofill is enabled? (See below for reference.) I've attempted the following solutions: *:focus { outline: 0; } input:-webkit-autofill { -webk ...

Designing a layout with one box on top and two beneath it, covering the entire page, can be achieved by following these steps

https://i.sstatic.net/A1eUh.png I am currently working on a project where I want to divide the screen into three sections. One section will cover half of the screen to display an image slider, and the remaining half will have two sections which is already ...

Utilizing Dojo widgets in Xpages

I'm having trouble applying CSS to certain dojo elements within my Xpage. Here is the CSS style sheet I am using: .formFields { color: rgb(5, 56, 107); font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: nor ...

What is the best way to access nested objects in React Native?

Here is the JSON data I am working with: [ { id: 51, name: 'Boat Neck Blouse', image: { id: 669, date_created: '2018-08-27T10:05:39', date_created_gmt: '2018-08-27T10:05:39', date_modified ...

What is the best way to position a table caption at the top of a table?

I need help setting up a calendar within a table structure, and I'm struggling to add a caption at the top of the table. Unfortunately, I can't modify the current table structure. I want it to resemble the example shown below: https://i.sstatic. ...

How can one display an integer value instead of a scientific value in an AngularJS view?

I came up with this handy function that handles the conversion from dp (density independent) to px (pixels): $rootScope.dp2px = function(dp) { if(!!dp) { var px = window.devicePixelRatio * dp / 160; return px.toPrecision(2); } else ...