mirror of
https://github.com/bitwarden/browser
synced 2026-02-10 21:50:15 +00:00
78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
import {
|
|
AfterContentInit,
|
|
Directive,
|
|
EventEmitter,
|
|
Host,
|
|
HostBinding,
|
|
HostListener,
|
|
model,
|
|
OnChanges,
|
|
Output,
|
|
} from "@angular/core";
|
|
|
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
|
|
|
import { BitIconButtonComponent } from "../icon-button/icon-button.component";
|
|
|
|
import { BitFormFieldComponent } from "./form-field.component";
|
|
|
|
@Directive({
|
|
selector: "[bitPasswordInputToggle]",
|
|
host: {
|
|
"[attr.aria-pressed]": "toggled()",
|
|
},
|
|
})
|
|
export class BitPasswordInputToggleDirective implements AfterContentInit, OnChanges {
|
|
/**
|
|
* Whether the input is toggled to show the password.
|
|
*/
|
|
readonly toggled = model(false);
|
|
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
|
|
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
|
|
@Output() toggledChange = new EventEmitter<boolean>();
|
|
|
|
@HostBinding("attr.title") title = this.i18nService.t("toggleVisibility");
|
|
@HostBinding("attr.aria-label") label = this.i18nService.t("toggleVisibility");
|
|
|
|
/**
|
|
* Click handler to toggle the state of the input type.
|
|
*/
|
|
@HostListener("click") onClick() {
|
|
this.toggled.update((toggled) => !toggled);
|
|
this.toggledChange.emit(this.toggled());
|
|
|
|
this.update();
|
|
}
|
|
|
|
constructor(
|
|
@Host() private button: BitIconButtonComponent,
|
|
private formField: BitFormFieldComponent,
|
|
private i18nService: I18nService,
|
|
) {}
|
|
|
|
get icon() {
|
|
return this.toggled() ? "bwi-eye-slash" : "bwi-eye";
|
|
}
|
|
|
|
ngOnChanges(): void {
|
|
this.update();
|
|
}
|
|
|
|
ngAfterContentInit(): void {
|
|
const input = this.formField.input();
|
|
if (input?.type) {
|
|
this.toggled.set(input.type() !== "password");
|
|
}
|
|
this.button.icon.set(this.icon);
|
|
}
|
|
|
|
private update() {
|
|
this.button.icon.set(this.icon);
|
|
const input = this.formField.input();
|
|
if (input?.type != null) {
|
|
input.type.set(this.toggled() ? "text" : "password");
|
|
input?.spellcheck?.set(this.toggled() ? false : undefined);
|
|
}
|
|
}
|
|
}
|