Skip to content

fix(super-editor): flip tooltip when clipped by viewport#3836

Open
dani-beltran wants to merge 6 commits into
superdoc-dev:mainfrom
dani-beltran:main
Open

fix(super-editor): flip tooltip when clipped by viewport#3836
dani-beltran wants to merge 6 commits into
superdoc-dev:mainfrom
dani-beltran:main

Conversation

@dani-beltran

@dani-beltran dani-beltran commented Jul 17, 2026

Copy link
Copy Markdown

Fixes #3786

Tooltip positioning wasn't detecting viewport collisions, it only clamped horizontally, so tooltips could still overflow on top.

This PR fixes the issue, while also refactoring some other components using the same duplicated logic. Also created a repro test for the bug.

Before After
Screenshot 2026-07-18 at 01 31 32 Screenshot 2026-07-18 at 01 32 48

Refactor notes:

  • Extracted the positioning logic into a standalone util function to reduce component complexity and avoid duplicated code.
  • SdTooltip, FontFamilyCombobox and ToolbarDropdown, all share the new utility for positioning
  • Expanded the utility to support additional alignments (bottom-start, bottom-end, etc.) to match FontFamilyCombobox's alignment behavior
  • Added support for calculating available space to fit dropdown height, needed by ToolbarDropdown
  • Added unit tests for the new utility functions

Demo of how FontFamilyCombobox and ToolbarDropdown components behave after the change. They retain the same behavior as before. 👇

output

@dani-beltran
dani-beltran requested a review from a team as a code owner July 17, 2026 23:37
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0967f00061

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +108 to +109
case 'top-start':
top = triggerRect.top - contentHeight - offset;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Clamp flipped long dropdowns to the viewport

When a bottom-start dropdown flips upward, this subtracts the full content height before callers apply the new maxHeight; for example the existing long-menu case with a 500px menu, trigger top=260, and only 248px available above computes top=-244px, then renders a 248px-tall menu mostly offscreen. Use the constrained render height or clamp to the gutter as the previous dropdown code did, otherwise long toolbar/font dropdowns near the bottom still get clipped after flipping.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed

.fade-in-scale-up-transition-enter-active,
.fade-in-scale-up-transition-leave-active {
transform-origin: bottom center;
transform-origin: center;

@dani-beltran dani-beltran Jul 17, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I changed the animation origin to be position agnostic, since the tooltip could be now on top or bottom positions. It looks good, barely noticeable difference. However, this is modifying the original animation, so I am considering changing it.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c7b4b2b2a9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

const { placement = 'top', offset = 0, flip = true } = options;
const triggerRect = triggerElem.getBoundingClientRect();
const contentWidth = contentElem.offsetWidth;
const contentHeight = contentElem.offsetHeight;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use scrollHeight when deciding dropdown flips

For toolbar/font dropdowns, menuPosition.maxHeight is kept in component state after a close, so the element created on the next open can already be constrained by the previous max-height. Measuring offsetHeight here then uses the clipped height rather than the full menu height; for example a 500px menu reopened near the bottom with a stale 120px maxHeight and 200px below/400px above will no longer flip upward, leaving the long menu clipped below. The previous inline dropdown logic used scrollHeight for this decision, so this should measure the scrollable height with an offset fallback.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Sure, but using scrollHeight instead of offsetHeight will mess up content components that are not dropdowns. I will add some way of detecting that is a dropdown or add a parameter in the function to indicate it is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Toolbar tooltips are cut off by edge of the window

1 participant