Skip to content
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

[BUG] Wide tooltips can overflow the window boundaries in version 5 #1139

Closed
dylemma opened this issue Dec 15, 2023 · 7 comments · Fixed by #1140
Closed

[BUG] Wide tooltips can overflow the window boundaries in version 5 #1139

dylemma opened this issue Dec 15, 2023 · 7 comments · Fixed by #1140
Labels

Comments

@dylemma
Copy link

dylemma commented Dec 15, 2023

Bug description
When you have a tooltip with long content, it can overflow the window. Solutions to similar reported issues are apparently unavailable in v5. It's particularly apparent when using a left/right placement with dynamic content and/or dynamic layout.

Version of Package
v5.25.0

To Reproduce
See https://codesandbox.io/p/sandbox/react-tooltip-overflow-9srs73
or just do

<Tooltip
  id="my-tooltip"
  place="left"
  float
/>
<span
  data-tooltip-id="my-tooltip"
  data-tooltip-content="Here is a very long string of text that will surely cause issues if I try to render it all in one line"
>
  Hover me
</span>

with some CSS that puts the <span> near the center of the screen.

Expected behavior
One of the following:

  • "squish" the tooltip so that it fits at its specified place (allowing the tooltip content to line-wrap)
  • have the tooltip ignore its place directive, e.g. if I set place="left" and it doesn't fit on the left or right, have it go to top/bottom if one of those would fit it on screen
  • provide some way for me to affect the tooltip's positioning myself (existing props in v5 don't seem to give me enough power to accomplish either of the above two behaviors)

Screenshots
image

Additional context
#476 and #599 seem related, but all of the suggested solutions seem unavailable in v5:

  • Can't use overridePosition in v5, and the position prop doesn't accept functions
  • afterShow no longer provides access to the tooltip element (AFAICT), so it is no longer possible to set its styles during the callback
  • Setting a max-width on the tooltip does not work because the width depends on the position of the anchor element relative to the edges of the screen
@gabrieljablonski
Copy link
Member

gabrieljablonski commented Dec 15, 2023

The most "natural" way to do this in V5 would be to use floating-ui's middlewares options to achieve your second suggestion.

have the tooltip ignore its place directive, e.g. if I set place="left" and it doesn't fit on the left or right, have it go to top/bottom if one of those would fit it on screen

As you've pointed out, it already does it for same-axis overflow (left switches to right if no space left, top to bottom, and so on) with the flip() middleware, but it indeed doesn't happen cross-axis (e.g. left to bottom).

This is kind of a weird situation to "fix", since different use-cases would call for different solutions (for example, your "squish" suggestion is totally valid in some cases), but since we already do the left<->right/top<->bottom flip, I don't see why not do this one as well.

See fallbackAxisSideDirection if you're interested in the details (here's also how you'd go about it using the middlewares tooltip prop), but react-tooltip@5.25.1-beta.1140.0 offers the cross-axis flip behavior by default.

@dylemma
Copy link
Author

dylemma commented Dec 18, 2023

Thanks for your reply, this looks very helpful. I'll give this a try and report back (and close the issue) once I figure out what middleware fits my use case.

@gabrieljablonski
Copy link
Member

We'll close the issue once #1140 gets merged. Just let us know if it works properly, or if you have other suggestions about this.

@dylemma
Copy link
Author

dylemma commented Dec 18, 2023

Hm okay. I think I still want the "squish" behavior even with the fallbackAxisSideDirection setting, so I arrived at a hybrid that uses flip() plus size with a minimum width to accomplish a best-fit "squish", then a flip with the fallback axis to have it as a fallback when the best-fit doesn't do the trick. https://codesandbox.io/p/sandbox/react-tooltip-overflow-forked-pjz72c

middlewares={[
  offset(10),
  flip(),
  size({
    apply: ({ availableWidth, availableHeight, elements }) => {
      Object.assign(elements.floating.style, {
        maxWidth: `${Math.max(200, availableWidth - 50)}px`,
      });
    },
  }),
  shift({ padding: 5 }),
  flip({
    fallbackAxisSideDirection: "start",
  }),
]}

(I'm not sure why the -50 in the maxWidth expression was so important. At first, my goal was to set a margin away from the edge of the window, but small values like -10 or even -30 didn't seem to have an effect.)

@gabrieljablonski
Copy link
Member

That's good to know. I'm considering adding a section on our documentation covering more clearly (and with examples like this) how to use different middlewares.

Though this isn't a huge issue, since most users are completely fine with just the default behavior, so something to get to eventually.

@gabrieljablonski gabrieljablonski added the Awaiting merge Issue is fixed on a PR that will me merged soon. label Dec 18, 2023
@gabrieljablonski
Copy link
Member

Official release react-tooltip@5.25.1 fixes this and some other stuff.

@gabrieljablonski gabrieljablonski removed the Awaiting merge Issue is fixed on a PR that will me merged soon. label Dec 27, 2023
@andreimatei
Copy link

Some of tooltips are too large to fit on a single line, so I want them wrapped (instead of clipped). @dylemma's snippet helped me, thanks!
I understand that 5.25.1 improved something in the area, but it didn't seem to help with the wrapping. Perhaps that too could be added to the default behavior?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants