UNPKG

@siberiaweb/components

Version:
207 lines (160 loc) 4.59 kB
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 );