From 2f257936099c1633b19f344d84fdd7f1d1810922 Mon Sep 17 00:00:00 2001 From: Tim Down <158919+timdown@users.noreply.github.com> Date: Tue, 12 May 2026 10:42:26 +0100 Subject: [PATCH] Merge pull request #33353 from overleaf/td-pricing-tooltip-esc Dismiss Bootstrap tooltips via Esc key GitOrigin-RevId: 2368a0691fd811180f908309f99b1f9a02c225ee --- .../web/frontend/js/features/tooltip/index.ts | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/services/web/frontend/js/features/tooltip/index.ts b/services/web/frontend/js/features/tooltip/index.ts index 73f5456134..173e20319b 100644 --- a/services/web/frontend/js/features/tooltip/index.ts +++ b/services/web/frontend/js/features/tooltip/index.ts @@ -11,18 +11,44 @@ function getElementWidth(el: Element) { return el.scrollWidth - elPaddingX - elBorderX } +const visibleInstances = new Set() + +function handleEscapeKey(e: KeyboardEvent) { + if (e.key === 'Escape') { + visibleInstances.forEach(instance => instance.hide()) + e.stopPropagation() + } +} + +function createTooltip(element: Element): Tooltip { + const instance = new Tooltip(element) + element.addEventListener('show.bs.tooltip', () => { + if (visibleInstances.size === 0) { + document.addEventListener('keydown', handleEscapeKey, { capture: true }) + } + visibleInstances.add(instance) + }) + element.addEventListener('hide.bs.tooltip', () => { + visibleInstances.delete(instance) + if (visibleInstances.size === 0) { + document.removeEventListener('keydown', handleEscapeKey, { + capture: true, + }) + } + }) + return instance +} + const footerLanguageElement = document.querySelector( '[data-ol-lang-selector-tooltip]' ) as Element if (footerLanguageElement) { - // eslint-disable-next-line no-new - new Tooltip(footerLanguageElement) + createTooltip(footerLanguageElement) } const allTooltips = document.querySelectorAll('[data-bs-toggle="tooltip"]') allTooltips.forEach(element => { - // eslint-disable-next-line no-new - new Tooltip(element) + createTooltip(element) }) const possibleBadgeTooltips = document.querySelectorAll('[data-badge-tooltip]') @@ -36,8 +62,7 @@ possibleBadgeTooltips.forEach(element => { if (element.parentElement) { const parentWidth = getElementWidth(element.parentElement) if (element.scrollWidth > parentWidth) { - // eslint-disable-next-line no-new - new Tooltip(element) + createTooltip(element) } else { element.parentElement.style.maxWidth = 'none' }