atomiks / tippyjs

Tooltip, popover, dropdown, and menu library
https://atomiks.github.io/tippyjs/
MIT License
11.92k stars 520 forks source link

onMount should tigger before box becomes visible #888

Open mvastola opened 3 years ago

mvastola commented 3 years ago

This is similar to #845, but it's not really a question -- it's somewhere between a bug report and a feature request:

First off, this is a great plugin, so thanks a lot for creating/maintaining it.

I'm having a lot of trouble due to the fact that I can't write a callback to run between the time tippy is mounted to the DOM and when it becomes visible to the user. In my case (though I think there are many more), I'm trying to use the select2 widget, which determines its size based on the size of its container (which I can set via CSS, but can't be queried until the div is mounted and displayed -- though not necessarily visible -- on the screen).

It would be great if either another event callback be added or onMount be configured to trigger immediately after the mount, as (I would argue) it's name suggests.

The suggestion in #845 -- using CSS to keep tippy invisible until my callback is done isn't an ideal solution for a couple of reasons:

As for compatibility with older versions (which I'm sure would be a concern), due to the unpredictability in timing in onMount, I can't immediately think of any use cases for onMount that both (a) would be complicated by this change and (b) wouldn't already be better served by using onShow or onShown.

If its not feasible to do this, I can think of a couple of other solutions that would make it easier to work around this issue:

atomiks commented 3 years ago

Unfortunately I think it's a breaking change to move where onMount() gets called. What I can recommend is patch-package and add your own custom hook for this major version. Not super clean but it'll work fine! In the meantime, architecturally, this may be an issue inherently that we might be able to solve with a new major version in the future.

Alternatively, you might be able to use your own render() function to achieve what you want?