Preventing ReactJS tooltips from exceeding the boundaries of the screen

Here is a simple demo showcasing blocks with tooltips that appear when hovered over. However, there seems to be an issue with the functionality.

The tooltip should ideally be displayed either from the left or right side of the block. To determine the size and position of the tooltip accurately, it needs to be displayed first. The calculation for positioning the tooltip can only be done after it is visible.

You can view the code on CodeSandbox here

// JavaScript code...
.block {
  // CSS styles...
}

.hover-block {
  // CSS styles...
}

.hidden {
  display: none;
}
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
  
<div id="root"></div>

Answer №1

I managed to find a solution by modifying how the element is hidden: visibility:hidden was used instead of display:none

export default function HoveredBlock({ blockStyle }) {
  const [blockRect, setBlockRect] = useState();
  const [hoverRect, setHoverRect] = useState();
  const [showHover, setShowHover] = useState(false);

  const [coords, setCoords] = useState();

  const blockRef = useCallback((node) => {
    if (node) {
      setBlockRect(node.getBoundingClientRect());
    }
  }, []);

  const hoverRef = useCallback((node) => {
    if (node) {
      setHoverRect(node.getBoundingClientRect());
    }
  }, []);

  useEffect(() => {
    if (showHover) {
      console.log({ blockRect, hoverRect });
      const coords = calcCoords(blockRect, hoverRect);

      setCoords(coords);
    }
  }, [showHover, blockRect, hoverRect]);

  return (
    <>
      <div
        ref={blockRef}
        className="block"
        style={blockStyle}
        onMouseEnter={() => setShowHover(true)}
        onMouseLeave={() => setShowHover(false)}
      />
      <div
        ref={hoverRef}
        className={cx("hover-block", {
          hidden: !showHover || !coords
        })}
        style={{
          left: coords && coords.x,
          top: coords && coords.y
        }}
      ></div>
    </>
  );
}
.block {
  width: 100px;
  height: 100px;
  background-color: aquamarine;
  margin-left: 20%;
}

.hover-block {
  position: fixed;
  width: 100px;
  height: 100px;
  background-color: coral;
}

.hidden {
  visibility: hidden;
}

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

Display picture on webpage in 10 seconds

Hi, I'm working on a website project and I've run into an issue where I need to use JavaScript, but I haven't mastered it yet. I have a background image slideshow set up where a new image appears every 6 seconds. My idea is to have the sec ...

What are the steps to integrate my server-side PHP code into this form wizard?

Having created a straightforward 3 step form wizard for registration, I encountered an issue at the last stage when users click on submit. The desired action is to direct users to the PHP code that has been written. Update: Despite updating the HTML code ...

The act of exporting components from the main index file allows for

I have assigned a components folder where I created various components that I want to export to the index.js file and then export all of them from there. This is an example from one of the components files: export default ToggleSwitch; Now, in the inde ...

Displaying Child Component in Parent Component After Click Event on Another Child Component: How to Implement Angular Parent/Children Click Events

After delving into Angular 7 for a few weeks, I find myself faced with the challenge of toggling the visibility of a child component called <app-child-2> within a Parent component named <parent>. This toggle action needs to be triggered by a cl ...

Converting multi-dimensional array into a structured table format

Query about arrays: Here is the array structure I am working with: Array ( [0] => Array ( [0] => Project [1] => Time ) [1] => Array ( [0] => Google [1] => 2 ...

What is the best way to expand an object without including any null values?

Imagine a scenario where there is an object: var user = { "Name": "Dan", "Age": 27, "Hobbies": null }; and it needs to be merged with the following base object to ensure all necessary properties are present: var base = { "Name": nul ...

What is the best way to identify identical companies, consolidate them into a single entity, and combine their weights for a more

I've been experimenting with various methods such as filter, reduce, and includes, but I'm struggling to grasp the concept of how to solve this. Here is an array of objects that I have: [ { name: 'GrapeCo', weight: 0.15 }, { name: ...

Tips for verifying the presence of a 3D model from Spline API within the DOM using Next.js

I am in the process of developing a brand new website and I have integrated a 3D model from spline, although it is taking quite some time to load. To improve user experience, I decided to implement a loader/Spinner. However, I'm facing the challenge o ...

Is there a way to simulate the change event on a react-select component using react-testing-library?

If I'm unable to directly test the internal components using react-testing-library, how can I effectively test a component that utilizes react-select? For example, if there is a conditional rendering based on the value of the react-select, which does ...

"Hover over the image to see it enlarge and reveal text displayed on top using CSS3

I have been working on creating a responsive image page for my website. I've managed to make the images responsive and centered, no matter the size of the browser window. However, I encountered an issue where when I hover over an image, it enlarges a ...

A blank screen of errors pops up when attempting to update through a form

Encountering a white error screen when attempting to add an item using a form in Python / Django. I'm currently debugging the issue but lacking information. Any guidance on where to look next would be greatly appreciated. Models.py from __future__ i ...

Alert displayed at the center of the browser when the value surpasses the specified number

My webpage retrieves SNMP data using PHP and displays it with HTML, color-coding the values. I want to add a pop-up alert when a value exceeds a certain number. I have attempted different jQuery solutions without success. The PHP code to get the value: ...

Combining objects in JavaScript

I am currently working on converting the object received from the server into a format compatible with the backend system. I have a received object that looks like this { 'User.permissions.user.view.dashboard': true, 'Admin.permissio ...

Fetching data using JSONRequest sample code

I am new to web development and this is my first attempt at using JSON. On the JSON website (http://www.json.org/JSONRequest.html), they recommend using JSONRequest.get for certain tasks. However, I keep running into an error stating "JSONRequest is not ...

What is the best way to prevent labels from floating to the top when in focus?

How can I prevent the label from floating on top when focusing on a date picker using Material UI? I have tried several methods but nothing seems to work. I attempted using InputLabelProps={{ shrink: false }} but it did not resolve the issue. Here is a li ...

What is the process for locating and displaying a database in WordPress?

I seem to be facing a challenge when it comes to developing a new functionality since I am relatively new to both WordPress and web development. My current goal is to incorporate a search feature into my project. The idea is that when a user enters a sea ...

Tips for displaying a sub-menu upon hovering

I am attempting to display the list of sub-menu items when hovering over the main menu item. I have tried using the following CSS code, but it did not work as expected. Any assistance will be greatly appreciated. CSS: summary.header__menu-item.list-menu__ ...

Error encountered: Material-Table threw a TypeError stating that Object(...) was not recognized as a function within the module located at ../node_modules/@material-ui/pickers/dist/material-ui-p

Attempting to set up material-table in my React project is proving to be challenging. When trying the example code from https://github.com/mbrn/material-table, I encountered an error message related to a module file. I have attempted to update material-ui ...

What is the process for setting %20 to represent a space in URL parameters?

I am currently working on developing an android application that involves sending data to the server side using GPRS and SMS (via an SMS gateway). The challenge I am facing is with formatting the data before sending it to the SMS gateway. The format provid ...

How do I create more space in Vitepress to prevent the text from feeling cramped and allow it to display in a larger area?

Below is the content of my index.md file: --- # https://vitepress.dev/reference/default-theme-home-page layout: home hero: name: "TP2" text: "Analyzing the code of TP2 by Breno Mazzali Medeiros Tomazelli and Philippe Bouchard" ta ...