1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 15:53:27 +00:00

[SM-43] create product-switcher (#4189)

* rebase to master

* use bit-menu in product switcher; add focusStrategy to bit-menu

* recommit locales after rebase

* add light style to iconButton, use in product-switcher

* move out of component library

* add buttonType input

* gate behind sm flag

* update aria-label

* add role input to bit-menu

* style changes

* simplify partition logic

* split into two components for Storybook

* update focus styles; update grid sizing to relative

* fix underline on hover

* update attribute binding

* move to layouts dir

* add bitLink; update grid gap

* reorder loose components

* move orgs mock

* move a11y module

* fix aria role bug; add aria label to menu

* update colors

* update ring color

* simplify colors

* remove duplicate link module
This commit is contained in:
Will Martin
2022-12-21 16:50:41 -05:00
committed by GitHub
parent 7d3063942e
commit eeb407b8a4
22 changed files with 387 additions and 32 deletions

View File

@@ -19,7 +19,9 @@ import { MenuComponent } from "./menu.component";
})
export class MenuTriggerForDirective implements OnDestroy {
@HostBinding("attr.aria-expanded") isOpen = false;
@HostBinding("attr.aria-haspopup") hasPopup = "menu";
@HostBinding("attr.aria-haspopup") get hasPopup(): "menu" | "dialog" {
return this.menu?.ariaRole || "menu";
}
@HostBinding("attr.role") role = "button";
@Input("bitMenuTriggerFor") menu: MenuComponent;
@@ -86,9 +88,11 @@ export class MenuTriggerForDirective implements OnDestroy {
}
this.destroyMenu();
});
this.keyDownEventsSub = this.overlayRef
.keydownEvents()
.subscribe((event: KeyboardEvent) => this.menu.keyManager.onKeydown(event));
this.keyDownEventsSub =
this.menu.keyManager &&
this.overlayRef
.keydownEvents()
.subscribe((event: KeyboardEvent) => this.menu.keyManager.onKeydown(event));
}
private destroyMenu() {
@@ -102,9 +106,12 @@ export class MenuTriggerForDirective implements OnDestroy {
private getClosedEvents(): Observable<any> {
const detachments = this.overlayRef.detachments();
const escKey = this.overlayRef
.keydownEvents()
.pipe(filter((event: KeyboardEvent) => event.key === "Escape" || event.key === "Tab"));
const escKey = this.overlayRef.keydownEvents().pipe(
filter((event: KeyboardEvent) => {
const keys = this.menu.ariaRole === "menu" ? ["Escape", "Tab"] : ["Escape"];
return keys.includes(event.key);
})
);
const backdrop = this.overlayRef.backdropClick();
const menuClosed = this.menu.closed;

View File

@@ -2,7 +2,10 @@
<div
(click)="closed.emit()"
class="tw-flex tw-shrink-0 tw-flex-col tw-rounded tw-border tw-border-solid tw-border-secondary-500 tw-bg-background tw-bg-clip-padding tw-py-2"
role="menu"
[attr.role]="ariaRole"
[attr.aria-label]="ariaLabel"
cdkTrapFocus
[cdkTrapFocusAutoCapture]="true"
>
<ng-content></ng-content>
</div>

View File

@@ -8,6 +8,7 @@ import {
ContentChildren,
QueryList,
AfterContentInit,
Input,
} from "@angular/core";
import { MenuItemDirective } from "./menu-item.directive";
@@ -22,9 +23,15 @@ export class MenuComponent implements AfterContentInit {
@Output() closed = new EventEmitter<void>();
@ContentChildren(MenuItemDirective, { descendants: true })
menuItems: QueryList<MenuItemDirective>;
keyManager: FocusKeyManager<MenuItemDirective>;
keyManager?: FocusKeyManager<MenuItemDirective>;
@Input() ariaRole: "menu" | "dialog" = "menu";
@Input() ariaLabel: string;
ngAfterContentInit() {
this.keyManager = new FocusKeyManager(this.menuItems).withWrap();
if (this.ariaRole === "menu") {
this.keyManager = new FocusKeyManager(this.menuItems).withWrap();
}
}
}

View File

@@ -1,3 +1,4 @@
import { A11yModule } from "@angular/cdk/a11y";
import { OverlayModule } from "@angular/cdk/overlay";
import { CommonModule } from "@angular/common";
import { NgModule } from "@angular/core";
@@ -8,7 +9,7 @@ import { MenuTriggerForDirective } from "./menu-trigger-for.directive";
import { MenuComponent } from "./menu.component";
@NgModule({
imports: [CommonModule, OverlayModule],
imports: [A11yModule, CommonModule, OverlayModule],
declarations: [MenuComponent, MenuTriggerForDirective, MenuItemDirective, MenuDividerComponent],
exports: [MenuComponent, MenuTriggerForDirective, MenuItemDirective, MenuDividerComponent],
})