Skip to content

fix(helpers): don't create the tooltip just to hide it - #43

Merged
gohabereg merged 3 commits into
mainfrom
fix/tooltip-hide-without-instance
Oct 19, 2026
Merged

gohabereg merged 3 commits into
mainfrom
fix/tooltip-hide-without-instance

Conversation

@gohabereg

@gohabereg gohabereg commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Bug

Destroying a popover that never showed a hint leaves a window scroll listener on the page.

tooltip.hide() in @editorjs/helpers called prepare(), which constructs the CodeX Tooltips singleton when none exists. Constructing it registers window.addEventListener('scroll', ...), and the singleton is only released by an explicit tooltip.destroy(). ui-kit's popover items call tooltip.hide() from their own destroy(), so tearing down any popover created a tooltip just to hide it.

Found in document-model, where an e2e test checks that destroying an editor removes every document/window listener it added: once the UI plugins destroy their popovers (editor-js/document-model#174), the only listener left behind is this one.

Fix

  • hide() does nothing when no tooltip exists yet. show() and onHover() still create it on first use.
  • Version bumps so the fix gets published: @editorjs/helpers 1.2.2 → 1.2.3, and @editorjs/ui-kit 2.0.0 → 2.0.1, because ui-kit bundles the tooltip wrapper into its own dist.
  • codex-tooltip ^1.0.6 → ^1.1.0 (Only hold the element and scroll listener while the tooltip is shown codex-team/codex.tooltips#32). 1.1.0 keeps the tooltip's element and window scroll listener only while it is shown, so a tooltip that was shown no longer outlives every popover. The hide() fix above covers teardown that never showed a hint; this covers the case where one was shown. ui-kit bundles the tooltip, so 2.0.1 ships with it.

Verification

  • New packages/helpers/src/tooltip/tooltip.test.ts (codex-tooltip replaced by a stand-in): hide() with no tooltip, and after destroy(), constructs nothing; hide() hides an existing tooltip; show() creates it. The two "constructs nothing" cases fail without the fix.
  • yarn test (198 tests) and yarn build pass. The changed files are lint-clean; repo-wide yarn lint reports the same 417 errors as main.
  • ui-kit's Playwright suite passes with codex-tooltip 1.1.0 (242 passed; the 2 skipped are Chromium-only accessibility-tree checks).
  • In Editor.js (editor-js/document-model), with this ui-kit build: destroying editors, including one whose hint was hovered, leaves no window listener and no tooltip element on Chromium and WebKit. The full e2e suite shows no regressions.

🤖 Generated with Claude Code

gohabereg and others added 2 commits October 16, 2026 21:07
tooltip.hide() called prepare(), which constructs the CodeX Tooltips
singleton when none exists. Constructing it registers a window scroll
listener, and the singleton is only released by an explicit destroy().
ui-kit's popover items call tooltip.hide() from their destroy(), so
tearing down a popover whose hints were never shown created a tooltip
and left that listener on the page.

hide() now does nothing when no tooltip exists. show() and onHover()
still create it on first use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ui-kit bundles the helpers tooltip wrapper into its dist, so it needs a
release of its own to ship the tooltip hide() fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1.1.0 only keeps the tooltip's element and window scroll listener while
it is shown. ui-kit bundles the tooltip, so this is what ui-kit 2.0.1
ships with.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gohabereg
gohabereg merged commit 5ad97fb into main Oct 19, 2026
4 checks passed
@gohabereg
gohabereg deleted the fix/tooltip-hide-without-instance branch October 19, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants