Skip to content

Commit 942dd4c

Browse files
jtbraunmeta-codesync[bot]
authored andcommitted
Don't dismiss tooltips on scroll while focus is inside them
Summary: Click-triggered tooltips (like the commit filter dropdown) dismiss on any scroll event outside tooltip content, to avoid lingering after their anchor moves. But typing into an input inside a tooltip can shrink content elsewhere on the page (e.g. live-filtering the commit tree), which clamps the scroll container's `scrollTop` and fires a scroll event — dismissing the tooltip out from under the user mid-keystroke. Keep the scroll-dismissal behavior, but skip it while `document.activeElement` is inside a tooltip: if the user is typing in it, it should stay up. Reviewed By: evangrayk Differential Revision: D116539937 fbshipit-source-id: b702b524ac3973406c90b0016992403db7f52b22
1 parent f83f89a commit 942dd4c

2 files changed

Lines changed: 12 additions & 2 deletions

File tree

addons/components/Tooltip.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ export function Tooltip({
158158
}, [visible, onVisible]);
159159

160160
const ref = useRef<HTMLDivElement>(null);
161+
// The portaled tooltip content div, so handlers can tell whether events or
162+
// focus belong to this tooltip instance rather than any tooltip on the page.
163+
const contentRef = useRef<HTMLDivElement | null>(null);
161164
const getContent = () => {
162165
if (visible === 'title') {
163166
return title;
@@ -225,7 +228,11 @@ export function Tooltip({
225228
} else if (
226229
e.target !== document &&
227230
e.target !== document.documentElement &&
228-
!eventIsFromInsideTooltip(e as unknown as MouseEvent)
231+
!eventIsFromInsideTooltip(e as unknown as MouseEvent) &&
232+
// Typing in a tooltip's input can shrink content elsewhere on the page,
233+
// firing a scrollTop-clamp scroll event. Don't dismiss out from under
234+
// the user while focus is inside this tooltip.
235+
!(contentRef.current?.contains(document.activeElement) ?? false)
229236
) {
230237
setVisible(false);
231238
}
@@ -298,6 +305,7 @@ export function Tooltip({
298305
{visible && ref.current && (
299306
<RenderTooltipOnto
300307
delayMs={realDelayMs}
308+
tooltipRef={contentRef}
301309
element={ref.current}
302310
placement={placement}
303311
interactive={interactive}
@@ -334,6 +342,7 @@ function RenderTooltipOnto({
334342
children,
335343
delayMs,
336344
interactive,
345+
tooltipRef,
337346
onTooltipMouseEnter,
338347
onTooltipMouseLeave,
339348
}: {
@@ -342,11 +351,11 @@ function RenderTooltipOnto({
342351
children: ReactNode;
343352
delayMs?: number;
344353
interactive?: boolean;
354+
tooltipRef: React.MutableRefObject<HTMLDivElement | null>;
345355
onTooltipMouseEnter?: () => void;
346356
onTooltipMouseLeave?: () => void;
347357
}) {
348358
const sourceBoundingRect = element.getBoundingClientRect();
349-
const tooltipRef = useRef<HTMLDivElement | null>(null);
350359

351360
const zoom = getZoomLevel();
352361
let effectivePlacement = placement;

addons/vscode/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Fix the cwd quick-switch dropdown on Windows and Linux
1010
- Label Enter and other special keys properly in keyboard shortcut hints
1111
- Improve performance by skipping re-renders when refetched data is unchanged
12+
- Don't dismiss tooltips on scroll while focus is inside them
1213

1314
## 0.1.69
1415

0 commit comments

Comments
 (0)