mirror of
https://github.com/bitwarden/browser.git
synced 2024-10-28 07:49:41 +01:00
60 lines
2.3 KiB
TypeScript
60 lines
2.3 KiB
TypeScript
import { Component, HostListener, Input, Optional } from "@angular/core";
|
|
import { BehaviorSubject, map } from "rxjs";
|
|
|
|
import { NavBaseComponent } from "./nav-base.component";
|
|
import { NavGroupComponent } from "./nav-group.component";
|
|
import { SideNavService } from "./side-nav.service";
|
|
|
|
@Component({
|
|
selector: "bit-nav-item",
|
|
templateUrl: "./nav-item.component.html",
|
|
providers: [{ provide: NavBaseComponent, useExisting: NavItemComponent }],
|
|
})
|
|
export class NavItemComponent extends NavBaseComponent {
|
|
/** Forces active styles to be shown, regardless of the `routerLinkActiveOptions` */
|
|
@Input() forceActiveStyles? = false;
|
|
|
|
/**
|
|
* Is `true` if `to` matches the current route
|
|
*/
|
|
private _isActive = false;
|
|
protected setIsActive(isActive: boolean) {
|
|
this._isActive = isActive;
|
|
if (this._isActive && this.parentNavGroup) {
|
|
this.parentNavGroup.setOpen(true);
|
|
}
|
|
}
|
|
protected get showActiveStyles() {
|
|
return this.forceActiveStyles || (this._isActive && !this.hideActiveStyles);
|
|
}
|
|
|
|
/**
|
|
* The design spec calls for the an outline to wrap the entire element when the template's anchor/button has :focus-visible.
|
|
* Usually, we would use :focus-within for this. However, that matches when a child element has :focus instead of :focus-visible.
|
|
*
|
|
* Currently, the browser does not have a pseudo selector that combines these two, e.g. :focus-visible-within (WICG/focus-visible#151)
|
|
* To make our own :focus-visible-within functionality, we use event delegation on the host and manually check if the focus target (denoted with the .fvw class) matches :focus-visible. We then map that state to some styles, so the entire component can have an outline.
|
|
*/
|
|
protected focusVisibleWithin$ = new BehaviorSubject(false);
|
|
protected fvwStyles$ = this.focusVisibleWithin$.pipe(
|
|
map((value) =>
|
|
value ? "tw-z-10 tw-rounded tw-outline-none tw-ring tw-ring-inset tw-ring-text-alt2" : "",
|
|
),
|
|
);
|
|
@HostListener("focusin", ["$event.target"])
|
|
onFocusIn(target: HTMLElement) {
|
|
this.focusVisibleWithin$.next(target.matches(".fvw:focus-visible"));
|
|
}
|
|
@HostListener("focusout")
|
|
onFocusOut() {
|
|
this.focusVisibleWithin$.next(false);
|
|
}
|
|
|
|
constructor(
|
|
protected sideNavService: SideNavService,
|
|
@Optional() private parentNavGroup: NavGroupComponent,
|
|
) {
|
|
super();
|
|
}
|
|
}
|