feat(frontend): password visibilty toggle

This commit is contained in:
Gregor Kleen 2021-03-26 16:05:02 +01:00
parent 2d8428c566
commit f0e45477fa
3 changed files with 106 additions and 0 deletions

View File

@ -1,6 +1,7 @@
import { Checkbox } from './checkbox';
import { FileInput } from './file-input';
import { FileMaxSize } from './file-max-size';
import { Password } from './password';
import './inputs.sass';
import './radio-group.sass';
@ -9,4 +10,5 @@ export const InputUtils = [
Checkbox,
FileInput,
FileMaxSize,
Password,
];

View File

@ -273,3 +273,30 @@ option
.form--vertical__cell
vertical-align: top
// PASSWORD INPUT
.password-input__wrapper
display: grid
grid-template-areas: 'input toggle'
width: 100%
max-width: 600px
grid-template-rows: auto
grid-template-columns: 1fr auto
.password-input__input
grid-area: input
.password-input__toggle
grid-area: toggle
display: flex
justify-content: center
align-content: center
flex-direction: column
padding: 7px
cursor: pointer
color: var(--color-fontsec)
&:hover
color: var(--color-font)

View File

@ -0,0 +1,77 @@
import { Utility } from '../../core/utility';
const PASSWORD_INITIALIZED_CLASS = 'password-input--initialized';
@Utility({
selector: 'input[type="password"]:not([uw-no-password])',
})
export class Password {
_element;
_iconEl;
_toggleContainerEl;
constructor(element) {
if (!element)
throw new Error('Password utility cannot be setup without an element!');
if (element.classList.contains(PASSWORD_INITIALIZED_CLASS))
return false;
this._element = element;
this._element.classList.add('password-input__input');
const siblingEl = this._element.nextSibling;
const parentEl = this._element.parentElement;
const wrapperEl = document.createElement('div');
wrapperEl.classList.add('password-input__wrapper');
wrapperEl.appendChild(this._element);
this._toggleContainerEl = document.createElement('div');
this._toggleContainerEl.classList.add('password-input__toggle');
wrapperEl.appendChild(this._toggleContainerEl);
this._iconEl = document.createElement('i');
this._iconEl.classList.add('fas', 'fa-fw');
this._toggleContainerEl.appendChild(this._iconEl);
parentEl.insertBefore(wrapperEl, siblingEl);
this._element.classList.add(PASSWORD_INITIALIZED_CLASS);
}
start() {
this.updateVisibleIcon(this.isVisible());
this._toggleContainerEl.addEventListener('mouseover', () => {
this.updateVisibleIcon(!this.isVisible());
});
this._toggleContainerEl.addEventListener('mouseout', () => {
this.updateVisibleIcon(this.isVisible());
});
this._toggleContainerEl.addEventListener('click', (event) => {
event.preventDefault();
event.stopPropagation();
this.setVisible(!this.isVisible());
});
}
isVisible() {
return this._element.type !== 'password';
}
setVisible(visible) {
this._element.type = visible ? 'text' : 'password';
this.updateVisibleIcon(visible);
}
updateVisibleIcon(visible) {
function visibleClass(visible) {
return 'fa-' + (visible ? 'eye' : 'eye-slash');
}
this._iconEl.classList.remove(visibleClass(!visible));
this._iconEl.classList.add(visibleClass(!!visible));
}
}