1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-07 12:13:45 +00:00

[CL-1034] tooltip should only show on focus-visible (#18767)

This commit is contained in:
Will Martin
2026-02-06 10:43:52 -05:00
committed by GitHub
parent eb402a7ee8
commit 9bdfc68aa2
2 changed files with 27 additions and 4 deletions

View File

@@ -28,8 +28,8 @@ export const TOOLTIP_DELAY_MS = 800;
host: {
"(mouseenter)": "showTooltip()",
"(mouseleave)": "hideTooltip()",
"(focus)": "showTooltip()",
"(blur)": "hideTooltip()",
"(focusin)": "onFocusIn($event)",
"(focusout)": "onFocusOut()",
"[attr.aria-describedby]": "resolvedDescribedByIds()",
},
})
@@ -125,6 +125,20 @@ export class TooltipDirective implements OnInit, OnDestroy {
this.destroyTooltip();
};
/**
* Show tooltip on focus-visible (keyboard navigation) but not on regular focus (mouse click).
*/
protected onFocusIn(event: FocusEvent) {
const target = event.target as HTMLElement;
if (target.matches(":focus-visible")) {
this.showTooltip();
}
}
protected onFocusOut() {
this.hideTooltip();
}
protected readonly resolvedDescribedByIds = computed(() => {
if (this.addTooltipToDescribedby()) {
if (this.currentDescribedByIds) {

View File

@@ -103,13 +103,22 @@ describe("TooltipDirective (visibility only)", () => {
expect(isVisible()).toBe(true);
}));
it("sets isVisible to true on focus", fakeAsync(() => {
it("sets isVisible to true on focus-visible", fakeAsync(() => {
const button: HTMLButtonElement = fixture.debugElement.query(By.css("button")).nativeElement;
const directive = getDirective();
const isVisible = (directive as unknown as { isVisible: () => boolean }).isVisible;
button.dispatchEvent(new Event("focus"));
// Mock matches to return true for :focus-visible (simulates keyboard navigation)
const originalMatches = button.matches.bind(button);
button.matches = jest.fn((selector: string) => {
if (selector === ":focus-visible") {
return true;
}
return originalMatches(selector);
});
button.dispatchEvent(new FocusEvent("focusin", { bubbles: true }));
tick(TOOLTIP_DELAY_MS);
expect(isVisible()).toBe(true);
}));