-
-
Notifications
You must be signed in to change notification settings - Fork 534
[BUG] when first rendered, Tooltip component does not recognize existing anchors #1020
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Independently of when it gets rendered, the tooltip should recognize existing anchors, so I'm not sure what might be the problem in your case. Anyway, I strongly encourage you to use a set amount of tooltip instances (i.e. don't render them dynamically alongside your items), since although it might seem like it will be easier to render different content for each item this way, you're likely to run into other problems later.
As I believe you've already seen, there are some features such as the |
@gabrieljablonski , the problem I'm trying to solve here is actually due to a different issue. The way the current component is designed, it does not re-render when the anchor width/height changes. You see, the tooltip is often shown dynamically based on whether the anchor DOM box fits the text. For instance, initially a grid cell may be wide enough to fit the entire text but when a user makes the grid column narrower, the grid cell does not fit that text any longer so a tooltip showing the entire text is desirable. Tooltip component currently only rerenders/retrieves its content when any of the data-tooltip-* attributes change. In my case, I want to dynamically set the tooltip content based on the width of the anchor which would trigger the tooltip on or off. The way I solved it before I described above by rendering the tooltip component dynamically based on mouse entering/leaving the anchor. I think if you could trigger the recalculation of the content of the tooltip when the mouse enters/leaves the anchor, it would solve my use case. |
Just to make sure I understand correctly. You have an anchor element which should have a tooltip only when its width is smaller than a certain threshold, correct? Here's an idea that might work (click on the text to toggle the width) You can just set |
Ok, I think I figured out how to make it work. In my pointer events (enter/leave) I can call forceUpdate which will force the Tooltip to retrieve the new content. The issue I still have is that data-tooltip-content or data-tooltip-html only take a string but I need to render React elements as content sometimes. Render and children support it but you cannot use it on an anchor since attributes are always string. This prevents me from using a shared Tooltip instance since I need to use its render or children properties. Any idea how to make it work?
… On May 3, 2023, at 5:33 PM, Gabriel Jablonski ***@***.***> wrote:
Independently of when it gets rendered, the tooltip should recognize existing anchors, so I'm not sure what might be the problem in your case.
Anyway, I strongly encourage you to use a set amount of tooltip instances (i.e. don't render them dynamically alongside your items), since although it might seem like it will be easier to render different content for each item this way, you're likely to run into other problems later.
I want to create it dynamically because every tooltip instance should support unique set of property values, so I cannot use just one shared instance.
As I believe you've already seen, there are some features such as the render prop which help in rendering completely different content using the same tooltip instance.
—
Reply to this email directly, view it on GitHub <#1020 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ACVPDEBZXS3DX7TWEH3UVBTXELTNZANCNFSM6AAAAAAXVBSBU4>.
You are receiving this because you authored the thread.
|
Check this brief example on the README. |
Yes but it still does not resolve the case of rendering the type ChildrenType (Element | ElementType | ReactNode) which is the render's method return type
… On May 3, 2023, at 6:24 PM, Gabriel Jablonski ***@***.***> wrote:
The issue I still have is that data-tooltip-content or data-tooltip-html only take a string but I need to render React elements as content sometimes.
Check this brief example <https://github.com/ReactTooltip/react-tooltip#jsx-note> on the README. renderToStaticMarkup() should be able to render any React component to a string.
—
Reply to this email directly, view it on GitHub <#1020 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ACVPDEAUBTBCRTB5HSTJSUTXELZL5ANCNFSM6AAAAAAXVBSBU4>.
You are receiving this because you authored the thread.
|
To follow up on my previous comment, the reason the tooltip does not pop up when created dynamically when the mouse enters an anchor associated with it through its id is because the anchor's mouseenter event handler is only set up when the Tooltip is first rendered: By that time, it is already too late since I use the mouseenter event on the anchor to render the Tooltip. Thus, upgrading from version 4 to version 5 does not work for me, unfortunately. And I cannot use a global instance of Tooltip because I have to support the content which is of type ReactNode|ReactFragment that cannot be set on data-tooltip-html property. I can use a separate instance of Tooltip per anchor but if every cell of my datagrid is a potential anchor it creates a performance nightmare when my datagrid has hundreds of cells rendered. |
@gabrieljablonski , I think my use case would be resolved if the TooltipProvider/TooltipWrapper pattern (which is now marked deprecated for some reason) added a setContent method to the React context (useTooltip) which I could call with a new content in my own mouseenter event handler added to an anchor. setContent method would cause rerendering of the global tooltip. |
Not sure what you mean. You should either use
It wasn't clear before, but now I understand the issue, and there's not much that can be done about this. At the instant you render the tooltip component, there's no way to know if the user is currently hovering an anchor element. It could be almost achieved by using
I don't understand what you mean. You should be able to do something like this without any problems. <span
data-tooltip-id="my-tooltip"
data-tooltip-html={ReactDOMServer.renderToStaticMarkup(<MyTooltipContent />)}
>
my cell content
</span>
<Tooltip id="my-tooltip" />
Definitely don't.
We've decided to drop support for this feature since it is very cumbersome to use, and adds a ton of unnecessary complexity to the component. It will be removed in a future version. My suggestions:
But IMO you should really avoid controlling the state manually, as it is likely to give you other headaches in the future. |
renderToStaticMarkup takes a ReactElement:
export function renderToStaticMarkup(element: ReactElement): string;
Render property on the Tooltip has a return type of ChildrenType:
render?: (render: { content: string | null; activeAnchor: HTMLElement | null }) => ChildrenType
type ChildrenType = Element | ElementType | ReactNode
If I want to replace render/children property on the Tooltip with a data-tooltip-html I would have to do:
data-tooltip-html={renderToStaticMarkup(ChildrenType)} which does not work
ChildrenType and ReactElement are not exactly the same thing. For instance, ReactNode (part of ChildrenType) takes an array of ReactElements or a ReactFragment which is often the case when rendering a tooltip with a list of items.
… On May 4, 2023, at 11:34 AM, Gabriel Jablonski ***@***.***> wrote:
Yes but it still does not resolve the case of rendering the type ChildrenType (Element | ElementType | ReactNode) which is the render's method return type
Not sure what you mean. You should either use data-tooltip-html by itself, or the render prop. I don't think you'd achieve anything useful by using both.
the reason the tooltip does not pop up when created dynamically when the mouse enters an anchor associated with it through its id is because the anchor's mouseenter event handler is only set up when the Tooltip is first rendered
It wasn't clear before, but now I understand the issue, and there's not much that can be done about this. At the instant you render the tooltip component, there's no way to know if the user is currently hovering an anchor element. It could be almost achieved by using mousemove alongside mouseenter, but that's far from ideal, and sure to introduce a whole set of other problems.
And I cannot use a global instance of Tooltip because I have to support the content which is of type ReactNode|ReactFragment that cannot be set on data-tooltip-html property.
I don't understand what you mean. You should be able to do something like this without any problems. <MyTooltipContent /> is a React component.
<span
data-tooltip-id="my-tooltip"
data-tooltip-html={ReactDOMServer.renderToStaticMarkup(<MyTooltipContent />)}
>
my cell content
</span>
<Tooltip id="my-tooltip" />
I can use a separate instance of Tooltip per anchor
Definitely don't.
I think my use case would be resolved if the TooltipProvider/TooltipWrapper pattern (which is now marked deprecated for some reason)
We've decided to drop support for this feature since it is very cumbersome to use, and adds a ton of unnecessary complexity to the component. It will be removed in a future version.
My suggestions:
Make sure ReactDOMServer.renderToStaticMarkup() doesn't work for you (I honestly have no idea why it wouldn't though, I use it without any issues on my personal projects with decently complex React components as the content)
Are you REALLY SURE that ReactDOMServer.renderToStaticMarkup() doesn't work for you? If that's the case, you can control the tooltip state manually (have a look at the docs <https://react-tooltip.com/docs/examples/state>). The idea is that you can set the isOpen state manually on your onPointerEnter and onPointerLeave event handlers.
But IMO you should really avoid controlling the state manually, as it is likely to give you other headaches in the future.
—
Reply to this email directly, view it on GitHub <#1020 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ACVPDEB66QYYEGCGFQRHIWDXEPSEFANCNFSM6AAAAAAXVBSBU4>.
You are receiving this because you authored the thread.
|
Just wrap it with an HTML element. const content: ChildrenType = ...
<span
...
data-tooltip-html={renderToStaticMarkup(<div>{content}</div>)}
/> |
If this is still a problem, feel free to reopen with more info. |
Describe the bug
This worked in v4 of the component.
I want to be able to create a Tooltip component dynamically per anchor only when the mouse enters the anchor, and destroy it when the mouse leaves it. I want to create it dynamically because every tooltip instance should support unique set of property values, so I cannot use just one shared instance. But I do not want to always create a tooltip instance when I create an anchor as it will have performance issues. I had the following logic that worked in v4 (this is my custom AnchorWithTooltip component):
What happens here is that when the mouse enters the anchor, the isShowing state property is set to true, so the Tooltip component renders. When the mouse leaves the anchor, the isShowing state property is set to false and the Tooltip component is unmounted.
When I looked at the code of the TooltipController, it looks like it does not recognize the pre-existing anchor associated with the Tooltip by id so the tooltip is not shown.
I realize that this is probably by design but I would really appreciate if you could make the necessary change to enable such behavior.
And thanks again for refactoring the component. It looks great.
Version of Package
latest
To Reproduce
See the explanation above
Expected behavior
See the explanation above
Desktop (please complete the following information if possible or delete this section):
The text was updated successfully, but these errors were encountered: