Bjarki
Bjarki

Reputation: 231

Tooltip / Popper.js - Resize after adding tooltip title dynamically

I'm using Material-UI's <Tooltip /> component to show dynamically fetched data. I trigger the AJAX call to fetch the data in the onOpen callback. Initially I'm showing a loading spinner but I replace that with the data fetched.

My problem is that the tooltip grows downwards with the new content, such that it goes under my cursor which makes the tooltip think I hovered it again, triggering another fetch for data.

Example how I'm using it:

<Tooltip
    title={
        users ? (
            <Grid container direction="column" spacing={8}>
                {users.map(user => (
                    <Grid item key={user}>
                        {user}
                    </Grid>
                ))}
            </Grid>
        ) : <Loading />
    }
>
    <span>hover me</span>
</Tooltip>

Codesandbox: https://codesandbox.io/s/yq5j9qky7v

Looking at the Popper.js implementation, they have a method called scheduleUpdate to trigger redraw of the tooltip (adjust position and size) https://github.com/FezVrasta/popper.js/blob/master/docs/_includes/popper-documentation.md#popperscheduleupdate

My question is, is it possible to tap into that using only the Material-UI Tooltip component wrapper?

Thanks in advance!

Upvotes: 2

Views: 1359

Answers (2)

A. Rabus
A. Rabus

Reputation: 519

i packed the tooltip component (and its childre) in its own component and then used useEffect to update some useState variable and set the title to the useState variable. This way only changes in value trigger the remote API query.

looks a bit like:

const MyInput = (props) => {
  const [icdInfo, setIcdInfo] = useState({code: '', text: ''});
  const {id, value, placement, ...rest} = props;
  useEffect(() => {
    const fetchDescription = async (code) => {
        return await myApi.get(`${apiUrl}/${code}`);
    };
    fetchDescription(value)
        .then((r) => {
          setIcdInfo({code: icd_code, text: r.data.text || 'Unknown'});
        })
        .catch((e) => {
          setIcdInfo({code: '', text: 'Error'});
        });
    return () => {};
  }, [value, icdInfo]);
  return (
    <Tooltip title={icdInfo.text} >
      <Child {...rest} />
    </Tooltip>
  );
};

Upvotes: 0

user1569666
user1569666

Reputation: 21

i had the same issue, fixed it by calling after i updated the contents of the Popper:

window.dispatchEvent(new Event("resize") ) 

Upvotes: 2

Related Questions