mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-09-30 01:07:01 +08:00
Tooltip: ensure tooltip stays if focus moves from anchor into content
The tooltip has behaviour to ensure that when the focus moves from the anchor to the tooltip that the tooltip does not hide, however it only worked if the focus was the immediate child of the tooltip. In our case (see attached bug) the focus was moving into a link deeply nested within the contents of the tooltip. This CL updates the code to make use of the blur target & relatedTarget properties to detect this case and not hide the tooltip. Fixed: 406543379 Change-Id: I7ad19fbde17e275663465e0bb86f8b2ea8ba768e Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6402534 Commit-Queue: Alina Varkki <alinavarkki@chromium.org> Auto-Submit: Jack Franklin <jacktfranklin@chromium.org> Reviewed-by: Alina Varkki <alinavarkki@chromium.org>
This commit is contained in:
committed by
Devtools-frontend LUCI CQ
parent
c14787393e
commit
eb541d6436
@@ -199,6 +199,28 @@ describe('Tooltip', () => {
|
||||
assert.isFalse(container.querySelector('devtools-tooltip')?.open);
|
||||
});
|
||||
|
||||
it('should not hide the tooltip if focus moves from the anchor into deep DOM within the tooltip', async () => {
|
||||
const container = renderTooltip({variant: 'rich', attribute: 'aria-details'});
|
||||
const anchor = container.querySelector('button');
|
||||
assert.exists(anchor);
|
||||
const tooltip = container.querySelector('devtools-tooltip');
|
||||
assert.exists(tooltip);
|
||||
// Make some nested DOM for this; this test exists because of a bug where
|
||||
// the tooltip only stayed open if the focused element was an immediate
|
||||
// child, so for this test we make a nested DOM structure and test on that.
|
||||
tooltip.innerHTML = '<div><span><p class="deep-nested">nested</p></span></div>';
|
||||
|
||||
anchor.dispatchEvent(new FocusEvent('focus'));
|
||||
await checkForPendingActivity();
|
||||
assert.isTrue(tooltip.open);
|
||||
const richContents = container.querySelector('devtools-tooltip')?.querySelector('p.deep-nested');
|
||||
assert.exists(richContents);
|
||||
|
||||
anchor.dispatchEvent(new FocusEvent('blur', {relatedTarget: richContents}));
|
||||
await checkForPendingActivity();
|
||||
assert.isTrue(tooltip.open); // tooltip should still be open
|
||||
});
|
||||
|
||||
it('automatically sets and updates jslog', () => {
|
||||
const container = renderTooltip({jslogContext: 'context'});
|
||||
const tooltip = container.querySelector('devtools-tooltip');
|
||||
|
||||
@@ -160,6 +160,17 @@ export class Tooltip extends HTMLElement {
|
||||
if (this.#timeout) {
|
||||
window.clearTimeout(this.#timeout);
|
||||
}
|
||||
// If the event is a blur event, then:
|
||||
// 1. event.currentTarget = the element that got blurred
|
||||
// 2. event.relatedTarget = the element that gained focus
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/relatedTarget
|
||||
// If the blurred element (1) was our anchor, and the newly focused element
|
||||
// (2) is within the tooltip, we do not want to hide the tooltip.
|
||||
if (event && this.variant === 'rich' && event.target === this.#anchor && event.relatedTarget instanceof Node &&
|
||||
this.contains(event.relatedTarget)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't hide a rich tooltip when hovering over the tooltip itself.
|
||||
if (event && this.variant === 'rich' &&
|
||||
(event.relatedTarget === this || (event.relatedTarget as Element)?.parentElement === this)) {
|
||||
|
||||
Reference in New Issue
Block a user