Skip to content

Conversation

@jdeichert
Copy link
Contributor

@jdeichert jdeichert commented Jan 30, 2026

Motivations

This PR fixes an issue where tooltips, when out of view, aren't technically hidden and can cause scrollbars unnecessarily.

Using the hide middleware from FloatingUI to handle this, as suggested by @ZakaryH.

Before

Tooltip remains visible when scrolled out of view, leading to the scrollable area increasing.

NOTE: for some reason when the combobox opens, the scrollbar within the story jumps. I can't repro on production, but it DOES happen on our production stories. Seems to be specific to storybook?

Screen.Recording.2026-01-30.at.2.58.54.PM.mov

After

Tooltip no longer is visible when out of view.

Screen.Recording.2026-01-30.at.2.59.10.PM.mov

Changes

Fixed

  • Hide tooltips when out of view

Testing

  1. Pull this branch
  2. Copy the snippet below into docs/components/Combobox/Web.stories.tsx
  3. Run storybook and visit the new story
  4. Repeat the steps shown in the videos above:
    • Scroll down to the combobox, focus it, blur it to close the content
    • Scroll up on the inner container and you'll no longer see the tooltip once it is scrolled out of view
    • Try forcing isHidden: false, repeat the steps and you'll see the tooltip still visible as it's scrolled outside of the inner container
Snippet...

const ComboboxInScrollableContainer: ComponentStory<typeof Combobox> = args => {
  const [selected, setSelected] = useState<ComboboxOption[]>([]);

  return (
    <div
      style={{
        width: "80%",
        background: "red",
        overflowY: "auto",
        border: "1px solid #ccc",
        padding: "16px",
      }}
    >
      <Page title="Teammates" width="narrow">
        <div style={{ backgroundColor: "blue", height: "100vh" }}>
          <div
            style={{
              height: "200px",
              backgroundColor: "green",
            }}
          />
          <div
            style={{
              height: "200px",
              backgroundColor: "green",
            }}
          />
          <div
            style={{
              height: "200px",
              backgroundColor: "green",
            }}
          />
          <div
            style={{
              height: "200px",
              backgroundColor: "green",
            }}
          />
          <div
            style={{
              height: "200px",
              backgroundColor: "green",
            }}
          />

          <div
            style={{
              maxWidth: "200px",
            }}
          >
            <Combobox
              {...args}
              label="Teammates Teammates Teammates"
              onSelect={setSelected}
              selected={selected}
            >
              <Combobox.Option id="1" label="Bilbo Baggins" />
              <Combobox.Option id="2" label="Frodo Baggins" />
              <Combobox.Option id="3" label="Pippin Took" />
              <Combobox.Option id="4" label="Merry Brandybuck" />
              <Combobox.Option id="5" label="Sam Gamgee" />
              <Combobox.Option id="6" label="Aragorn" />
              <Combobox.Option id="7" label="Gimli" />
              <Combobox.Option id="8" label="Legolas" />
              <Combobox.Option id="9" label="Gandalf" />
              <Combobox.Option id="10" label="Gollum" />

              <Combobox.Action
                label="Add Teammate"
                onClick={() => {
                  alert("Added a new teammate ✅");
                }}
              />
            </Combobox>
          </div>
        </div>
      </Page>
    </div>
  );
};

export const InScrollableContainer = ComboboxInScrollableContainer.bind({});
InScrollableContainer.args = {};

When a tooltip was scrolled out of view, it was still visible.

This is now fixed using FloatingUI's `hide()` middleware to detect when it's out of view.
style={floatingStyles.float}
ref={setTooltipRef}
role="tooltip"
hidden={isHidden}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensures it's hidden from screen readers

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 30, 2026

Deploying atlantis with  Cloudflare Pages  Cloudflare Pages

Latest commit: 24f89c0
Status: ✅  Deploy successful!
Preview URL: https://ee485c58.atlantis.pages.dev
Branch Preview URL: https://job-148568-hide-tooltips-whe.atlantis.pages.dev

View logs

@jdeichert jdeichert marked this pull request as ready for review January 30, 2026 23:10
@jdeichert jdeichert requested a review from a team as a code owner January 30, 2026 23:10
@ZakaryH
Copy link
Contributor

ZakaryH commented Feb 2, 2026

I know this fix is for Combobox, even still I wanted to try it on just a Chip to see what happens there and I've realized we almost certainly need some more CSS rules on that. if I put it in

<div style={{ width: 200px }}>
  <Chip label="Something that is clearly going to exceed the dimensions of the parent or container of the Chip" />
</div>
image

it's not respected and doesn't truncate!

it should be a max-width: 100% or change it to be display: flex. I don't recall why it's inline-flex to begin with 🤔

this isn't directly related, since the Combobox's setup accounts for this, so I'm fine with doing this in a different PR.

@jdeichert
Copy link
Contributor Author

it's not respected and doesn't truncate!

it should be a max-width: 100% or change it to be display: flex. I don't recall why it's inline-flex to begin with 🤔

this isn't directly related, since the Combobox's setup accounts for this, so I'm fine with doing this in a different PR.

I can log a bug ticket for that. Indeed that sounds like it's outside the scope of this Tooltip issue.

@ZakaryH
Copy link
Contributor

ZakaryH commented Feb 2, 2026

these changes make sense, though I haven't tried it in product to see if it solves the initial issue or not.

I'm also realizing that we could improve this further by using useFocus and useHover to trigger the tooltip's open state, get rid of our handlers, and use proper conditional rendering passing an open value to useFloating.

also, the whileElementsMounted we have can be overly aggressive in some scenarios such as having the element focused, but then scrolling around. we'll see a ton of logging because it's still rendered....

image

I don't expect that to happen often though, and it's an existing problem.

Copy link
Contributor

@ZakaryH ZakaryH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, the only thing I would ask for are some visual regression tests. still happy to approve without them though.

@@ -1,88 +1,59 @@
import {
Copy link
Contributor Author

@jdeichert jdeichert Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ZakaryH I updated the tooltip tests as discussed.

I broke it into 2 commits:

  1. with my fix disabled, so it's the before state: eb0c2ed
  2. with my fix enabled, and you can see the offscreen tooltip is no more! 24f89c0

Demo is here if you want to test while running the docs site: http://localhost:5173/visual-tests/tooltip

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before After
Image Image

Copy link
Contributor

@ZakaryH ZakaryH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still LGTM thanks for adding the tests!

@ZakaryH ZakaryH merged commit 0299b36 into master Feb 6, 2026
15 checks passed
@ZakaryH ZakaryH deleted the JOB-148568/hide-tooltips-when-out-of-view branch February 6, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants