1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-17 09:59:41 +00:00

[CL-724] Vault list item keyboard nav dialog (#15591)

* add focus-visible-within util

* wip: add grid a11y dialog to vault

* add story and i18n
This commit is contained in:
Will Martin
2025-07-12 23:21:34 -04:00
committed by GitHub
parent 6c4d853b15
commit 50f8fbf56b
11 changed files with 189 additions and 4 deletions

View File

@@ -200,3 +200,7 @@ export const VAULT_BROWSER_INTRO_CAROUSEL = new StateDefinition(
"vaultBrowserIntroCarousel",
"disk",
);
export const VAULT_ITEM_GROUP_NAVIGATION_DIALOG = new StateDefinition(
"vaultItemGroupNavigationDialog",
"disk",
);

View File

@@ -1 +1,4 @@
export * from "./a11y-cell.directive";
export * from "./a11y-grid.directive";
export * from "./a11y-row.directive";
export * from "./a11y-title.directive";

View File

@@ -0,0 +1,47 @@
import { Directive, ElementRef, inject, input, output } from "@angular/core";
import { takeUntilDestroyed, toObservable } from "@angular/core/rxjs-interop";
import { filter, fromEvent, map, switchMap } from "rxjs";
@Directive({
selector: "[bitFocusVisibleWithin]",
})
export class FocusVisibleWithinDirective {
private elementRef = inject(ElementRef) as ElementRef<HTMLElement>;
/**
* Emits when the host element has a child with `:focus-visible`.
*
* The target selector can be narrowed with the `selector` input.
**/
bitFocusVisibleWithin = output<void>();
/**
* The child selector to watch.
*
* Defaults to `:focus-visble`, but sometimes it may be useful to be more specific, e.g. `foo-bar:focus-visible`.
**/
selector = input<`${string}:focus-visible`>(":focus-visible");
constructor() {
toObservable(this.selector)
.pipe(
switchMap((selector) =>
fromEvent(this.elementRef.nativeElement, "focusin").pipe(
map(() => {
const activeEl = document.activeElement;
return (
!!activeEl &&
this.elementRef.nativeElement.contains(activeEl) &&
activeEl.matches(selector)
);
}),
),
),
filter((hasFocusVisibleWithin) => hasFocusVisibleWithin),
takeUntilDestroyed(),
)
.subscribe(() => {
this.bitFocusVisibleWithin.emit();
});
}
}

View File

@@ -1,2 +1,3 @@
export * from "./focus-visible-within";
export * from "./function-to-observable";
export * from "./i18n-mock.service";