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

"Troubleshooting: Why isn't my jQuery AJAX POST request successfully sending data to

Here is the jQuery code snippet that I am currently working with: $("#dropbin").droppable( { accept: '#dragme', hoverClass: "drag-enter", drop: function(event) { var noteid = "<?=isset($_POST['noteid']) ? ...

What is the proper way for AJAX to function in WordPress when there is no output function available?

I am looking to incorporate AJAX functionality into my WordPress site to make a call to a third-party API. The goal is to update the state of some checkboxes based on the response received. While I have experience with AJAX, my previous implementations in ...

"Clicking on the dropdown menu will consistently result in it collapsing

When it comes to a DropDown menu, the typical expectation is that when an option is selected, the menu will collapse. However, in my situation, I do not want the dropdown menu to collapse if the user is attempting to log in and clicks on the Username and P ...

Start a new typescript project from scratch

Seeking assistance in setting up a blank TypeScript project with a package.json, TypeScript and HTML file. I am looking for something akin to the Stackblitz blank-typescript project. If anyone could provide me with a step-by-step guide on how to create su ...

Having issues with retrieving data using findOne or findById in Express and Node JS, receiving undefined values

Currently, I am working on a microservice dedicated to sending random OTP codes via email. Below is the code for my findbyattr endpoint: router.get('/findbyattr/:email', async (request, response) =>{ try { let requestEmail = reque ...

Utilize the MaterialUI DataGrid to showcase nested object values in a visually appealing

Hey there, fellow coders! I'm currently working on fetching data from an API and displaying it in a data grid using React.js. Here's the format of the data I'm receiving from the API: {data: Array(200)} data : (200) [{…}, {…}, {…}, { ...

Save the URLs of multiple images uploaded to Firebase in Firestore

Can anyone provide assistance in updating this code to ensure it waits for the upload to complete before saving the image URLs to firestore? I am inexperienced with async and await and am struggling to resolve this issue. Despite trying to save to firest ...

Python (Selenium) - Guide on extracting and storing data from multiple pages into a single CSV file

I am facing a challenge with scraping data from a web page that contains a table spanning multiple pages. I am using Python with selenium for this task. The website in question is: The issue I am encountering is related to navigating through the pages of ...

The component <FormControl /> does not support the variant prop

It's perplexing to me why <FormControl /> doesn't seem to accept the prop variant. Even though the documentation suggests that this prop is available. import React from "react"; import { render } from "react-dom"; import FormControl from " ...

Need help with styling for disabled autocomplete? Check out the attached image

I'm currently working with material-ui and react to create a basic form. Everything is functioning properly except for a small UI issue that I can't seem to figure out how to resolve. When I utilize the browser's auto-complete feature, the i ...

Issues arise when Angular properties become undefined following the initialization or OnInit functions

There seems to be a peculiar issue with the properties of an angular component that I have set up. It appears that these properties are losing their values after the initialization process. The component is essentially a basic HTML file containing a video ...

What causes the discrepancy in results between the quoted printable encoding operation in JavaScript and Oracle?

Programming Languages: // JavaScript code snippet //https://www.npmjs.com/package/utf8 //https://github.com/mathiasbynens/quoted-printable par_comment_qoted = quotedPrintable.encode(utf8.encode('test ąčęė')); console.log('par_comment_qot ...

Is there a way to verify if an email is already registered within a MERN stack application

I am in the process of creating a registration form and need to verify if an email already exists within the system. Below is the React code snippet showcasing the structure for better understanding. In the schema, emails are defined as unique. AuthContr ...

Dealing with object properties that may not always be present in Vue.js template tags

Encountering a fatal error TypeError: Cannot read properties of null (reading 'propThatSometimesDoesNotExist') when utilizing the code below: <template> <div> <img v-if="obj.propThatSometimesDoesNotExist" :src=" ...

Getter and Setter Implementation in Typescript without Using Classes

Check out these various SO questions discussing Typescript getters/setters: from 2015, Jan 2018, Sept 2018, and more. Now, the question arises - what is the best approach to define Typescript types for getters/setters in a plain JavaScript object without ...

Display the outcome of a POST request on the webpage

Currently working with node.js/express and have a view that includes a form. This form POSTs to a route which returns JSON data. I want to be able to submit the form and display the returned data underneath the form on the same view without refreshing the ...

Having trouble deleting a component from an array in React?

I am facing an issue with my array and component functions. Each component has a handleRemove function that is supposed to remove the selected component from the array. However, the function is not working as expected. Instead of deleting just the selected ...

Is it possible to use JavaScript to forcefully transition a CSS keyframe animation to its end state?

One dilemma I am facing involves CSS keyframe animations triggered by scroll behavior. When users scroll too quickly, I would like JavaScript to help send some of the animations to their 'finished/final' state, especially since the animations bui ...

The view of the Google map is filled with numerous rounded tiles

Map divided into 3x3 tiles I am looking to customize the appearance of my map and remove all spaces and rounded corners to create a seamless, undivided visual. Is there a way to modify a map tile attribute to achieve this effect? Below is the code snippet ...

Bootstrap struggles to create panels of uniform size

Here is the code snippet I am currently working with: <div class="col-md-4"> <div class="panel panel-default"> <div class="panel-heading"> <h4><i class="fa fa-fw fa-tasks"></i> Extreme Performance</ ...