Elia Weiss
Elia Weiss

Reputation: 10020

position absolute - float within screen limits (React)

I'm trying to create an App with a global dictionary; so that when a word that appears in the dictionary is hovered than a small box appears next to it with a definition.

The problem is that the text in the dictionary can appear any where on the screen, and I need to align the floating box so that it will not be displayed out side of the screen

Similar to this

Edit n3qz2r80lj

only that I need to be able to style the floating box, like this

Edit nkx112o8qm

Note that the box display outside of the screen:

enter image description here

I tired to use ui material ToolTip but it throws

TypeError Cannot read property 'className' of undefined

Edit 0m0qzp126p

I solved a similar problem before with jQuery, where I dynamically calculated the position of the box, relative to the screen and the current element.

but I don't know how to do it in react, mainly since I don't know how to get the position of the current element dynamical.

Please help

Upvotes: 1

Views: 688

Answers (2)

wiesson
wiesson

Reputation: 6832

To give an idea where to start, have a look at useCallback and refs for React. With the given information from node.getBoundingClientRect(), you could calculate if your tooltip is outside the visible area of the browser.

// edit: useCallback won't work in this case, because the visibility is triggered by a css hover and the dimensions are not yet available for the hidden tooltip. Here is a possible solution with useRef and use useEffect though:

function ToolTip({ word, description }) {
  const [left, setLeft] = useState(0);
  const [hover, setHover] = useState(false);
  const ref = useRef(null);

  useEffect(() => {
    if (ref.current) {
      const { right } = ref.current.getBoundingClientRect();
      if (window.innerWidth < right) {
        setLeft(window.innerWidth - right);
      }
    }
  }, [hover]);

  return (
    <span
      desc={description}
      className="dashed"
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => {
        setHover(false);
        setLeft(0);
      }}
    >
      {word}
      <div ref={ref} className="explain" style={{ left }}>
        <h2>{word}</h2>
        {description}
      </div>
    </span>
  );
}

Codepen example: https://codesandbox.io/s/lk60yj307

Upvotes: 1

Elia Weiss
Elia Weiss

Reputation: 10020

I was able to do it with

https://www.npmjs.com/package/@syncfusion/ej2-react-popups

Edit xvl9747zq4

But I still wonder what is the correct way to do it in code.

Upvotes: 0

Related Questions