Hello!
I have an issue with dynamic content of my tooltips.
My tooltips can change dynamically based on a condition. The condition changes while the cursor is on the element with the tooltip. For example, this condition changes when I press the button, and my tooltip is on the same button, like this:
<button
use:tooltip={cond ? tooltipOptionsA : tooltipOptionsB}
onclick={() => (cond = !cond)}
>
My Button
</button>
What I see is that when the condition changes, for an instant my tooltip appears in the top-left corner of a page. This happens because the tooltip element is created (marked with comment "(1)" below) and appended (2) to the DOM (body in my case) in the same function, and only later its position is adjusted (3) in another function (mountTooltip).
From src/lib/tooltip.ts:
const createTooltip = () => {
if (Tooltip || visible) return;
Tooltip = document.createElement('div'); // (1) Creating
// ... <omit>
if (!targetElement) {
document.body.append(Tooltip); // (2) Appending
} else {
targetElement.append(Tooltip);
}
};
const mountTooltip = async () => {
if (!Tooltip && Config.visibility) {
// ... <omit>
createTooltip(); // here we initiate the creation of tooltip element (1) and attaching it to the DOM (2)
// ... <omit>
cleanUpPosition = autoUpdate(node, Tooltip!, () => {
if (!Tooltip || !TooltipArrow) return;
computePosition(node, Tooltip!, {
// ... <omit>
}).then(({ x, y, placement, middlewareData }) => {
Tooltip!.style.left = `${x}px`; // (3) update tooltip container position
Tooltip!.style.top = `${y}px`;
// ... <omit>
});
});
// ... <omit>
Config.onMount?.(); // (4) onMount callback is called
}
};
I thought about setting a visibility: hidden class on the container initially and then removing it inside onMount callback which is called inside mountTooltip (4), but I don't have access to the element because it's not passed as an argument. In fact, from onMount I only have access to the configuration and nothing else.
The other option I've explored is using Floating UI middleware to remove the visibility: hidden class, but it doesn't work either because this middleware is called at the wrong moment. I'm not sure if this could possibly work.
Potential solutions:
- If
@floating-ui/dom allows this, append the tooltip after positioning it, so basically switching the order from 1, 2, 3 to 1, 3, 2. This may not be possible if @floating-ui/dom can properly calculate positions only on elements attached to the DOM, but it would be an ideal solution.
- Pass a reference of the tooltip container as an argument into
onMount. This way it will be possible to update classes after the tooltip is mounted, and remove the initial visibility: hidden class. Maybe it would be even better to have a separate callback like onPositionSet instead of combining this with the current onMount callback and breaking existing behavior.
- If the library itself could add
visibility: hidden on a tooltip, and remove it after updating the position, that would also work.
EDIT: After a bit of additional research, I think that option 1 is not really possible, but I added option 3 as a low-effort solution on the library side. (It doesn't exclude option 2 which proposes a change in the API.)
Let me know if you need any additional info.
Thank you!
Hello!
I have an issue with dynamic content of my tooltips.
My tooltips can change dynamically based on a condition. The condition changes while the cursor is on the element with the tooltip. For example, this condition changes when I press the button, and my tooltip is on the same button, like this:
What I see is that when the condition changes, for an instant my tooltip appears in the top-left corner of a page. This happens because the tooltip element is created (marked with comment "(1)" below) and appended (2) to the DOM (body in my case) in the same function, and only later its position is adjusted (3) in another function (
mountTooltip).From
src/lib/tooltip.ts:I thought about setting a
visibility: hiddenclass on the container initially and then removing it insideonMountcallback which is called insidemountTooltip(4), but I don't have access to the element because it's not passed as an argument. In fact, fromonMountI only have access to the configuration and nothing else.The other option I've explored is using Floating UI middleware to remove the
visibility: hiddenclass, but it doesn't work either because this middleware is called at the wrong moment. I'm not sure if this could possibly work.Potential solutions:
@floating-ui/domallows this, append the tooltip after positioning it, so basically switching the order from1, 2, 3to1, 3, 2. This may not be possible if@floating-ui/domcan properly calculate positions only on elements attached to the DOM, but it would be an ideal solution.onMount. This way it will be possible to update classes after the tooltip is mounted, and remove the initialvisibility: hiddenclass. Maybe it would be even better to have a separate callback likeonPositionSetinstead of combining this with the currentonMountcallback and breaking existing behavior.visibility: hiddenon a tooltip, and remove it after updating the position, that would also work.EDIT: After a bit of additional research, I think that option 1 is not really possible, but I added option 3 as a low-effort solution on the library side. (It doesn't exclude option 2 which proposes a change in the API.)
Let me know if you need any additional info.
Thank you!