@siberiaweb/components
Version:
207 lines (160 loc) • 4.59 kB
text/typescript
import CSS from "./CSS";
import Icon from "../icon/Icon";
import Input from "../input/Input";
/**
* Поле ввода пароля.
*/
export default class InputPassword extends Input {
/**
* Наименование компонента.
*/
public static readonly COMPONENT_NAME: string = "sw-input-password";
/**
* Разрешение просмотра пароля.
*/
public static readonly ATTR_REVEAL: string = "reveal";
/**
* Значок для просмотра пароля.
*/
private readonly revealIcon: Icon;
/**
* Наблюдаемые атрибуты.
*/
public static get observedAttributes(): string[] {
return Input.observedAttributes.concat(
[
InputPassword.ATTR_REVEAL
]
);
}
/**
* Вывод пароля.
*/
private showPassword(): void {
this.getControl().type = "text";
}
/**
* Скрытие пароля.
*/
private hidePassword(): void {
this.getControl().type = "password";
}
/**
* Создание значка для просмотра пароля.
*/
private createRevealIcon(): Icon {
let icon = document.createElement( Icon.COMPONENT_NAME ) as Icon;
icon.classList.add( CSS.REVEAL_ICON );
icon.addEventListener( "mousedown", (
event: MouseEvent
): void => {
if ( this.disabled ) {
return;
}
if ( ( event.button === 0 ) && !( event.altKey || event.ctrlKey || event.shiftKey ) ) {
this.showPassword();
event.preventDefault();
}
} );
icon.addEventListener( "mouseup", (
event: MouseEvent
): void => {
this.hidePassword();
event.preventDefault();
} );
icon.addEventListener( "mouseleave", (): void => {
this.hidePassword();
} );
return icon;
}
/**
* Вывод или скрытие значка для просмотра пароля.
*/
private checkDisplayRevealIcon(): void {
if ( this.reveal ) {
if ( this.isEmpty() ) {
this.revealIcon.remove();
}
else {
this.addTrailingIcon( this.revealIcon );
}
}
else {
this.revealIcon.remove();
}
}
/**
* Инициализация элемента управления.
*/
private initInputPasswordControl(): void {
this.getControl().type = "password";
this.getControl().addEventListener( "copy", (
event: Event
): void => {
event.preventDefault();
} );
this.getControl().addEventListener( "input", (): void => {
this.checkDisplayRevealIcon();
} );
}
/**
* @override
*/
protected firstConnectedCallback() {
super.firstConnectedCallback();
this.classList.add( CSS.INPUT_PASSWORD );
}
/**
* Обработка изменения атрибута "reveal".
*/
protected attrRevealChange(): void {
this.checkDisplayRevealIcon();
}
/**
* @override
*/
protected attrValueChange(
newValue: string | null
) {
super.attrValueChange( newValue );
this.checkDisplayRevealIcon();
}
/**
* @override
*/
protected attributeChangedCallback(
name: string,
oldValue: string | null,
newValue: string | null
): void {
super.attributeChangedCallback( name, oldValue, newValue );
if ( name === InputPassword.ATTR_REVEAL ) {
this.attrRevealChange();
}
}
/**
* Получение признака разрешения просмотра пароля.
*/
public get reveal(): boolean {
return this.hasAttribute( InputPassword.ATTR_REVEAL );
}
/**
* Установка признака разрешения просмотра пароля.
*
* @param value Значение.
*/
public set reveal(
value: boolean
) {
this.toggleAttribute( InputPassword.ATTR_REVEAL, value );
}
/**
* Конструктор.
*/
constructor() {
super();
this.revealIcon = this.createRevealIcon();
this.initInputPasswordControl();
}
}
InputPassword.define( Icon );