2019-10-28 20:27:10 +01:00
|
|
|
import { sanitise } from '../lib/utils';
|
2019-11-03 18:45:16 +01:00
|
|
|
import { SELECT_ONE_TYPE } from '../constants';
|
2021-12-17 22:26:52 +01:00
|
|
|
import { ClassNames } from '../interfaces/class-names';
|
|
|
|
import { PassedElementType } from '../interfaces/passed-element-type';
|
2019-11-03 14:18:16 +01:00
|
|
|
|
2017-08-17 14:50:14 +02:00
|
|
|
export default class Input {
|
2019-12-23 19:22:54 +01:00
|
|
|
element: HTMLInputElement;
|
2021-12-17 22:26:52 +01:00
|
|
|
|
|
|
|
type: PassedElementType;
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
classNames: ClassNames;
|
2021-12-17 22:26:52 +01:00
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
preventPaste: boolean;
|
2021-12-17 22:26:52 +01:00
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
isFocussed: boolean;
|
2021-12-17 22:26:52 +01:00
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
isDisabled: boolean;
|
|
|
|
|
|
|
|
constructor({
|
|
|
|
element,
|
|
|
|
type,
|
|
|
|
classNames,
|
|
|
|
preventPaste,
|
|
|
|
}: {
|
|
|
|
element: HTMLInputElement;
|
2021-12-17 22:26:52 +01:00
|
|
|
type: PassedElementType;
|
2019-12-23 19:22:54 +01:00
|
|
|
classNames: ClassNames;
|
|
|
|
preventPaste: boolean;
|
|
|
|
}) {
|
2017-08-17 14:50:14 +02:00
|
|
|
this.element = element;
|
2019-10-29 18:35:20 +01:00
|
|
|
this.type = type;
|
2017-10-10 13:56:36 +02:00
|
|
|
this.classNames = classNames;
|
2019-10-29 18:35:20 +01:00
|
|
|
this.preventPaste = preventPaste;
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
this.isFocussed = this.element.isEqualNode(document.activeElement);
|
2019-10-29 18:35:20 +01:00
|
|
|
this.isDisabled = element.disabled;
|
2018-05-25 10:22:14 +02:00
|
|
|
this._onPaste = this._onPaste.bind(this);
|
|
|
|
this._onInput = this._onInput.bind(this);
|
|
|
|
this._onFocus = this._onFocus.bind(this);
|
|
|
|
this._onBlur = this._onBlur.bind(this);
|
2017-08-23 14:23:37 +02:00
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
set placeholder(placeholder: string) {
|
2018-04-24 13:54:45 +02:00
|
|
|
this.element.placeholder = placeholder;
|
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
get value(): string {
|
2019-02-22 23:04:55 +01:00
|
|
|
return sanitise(this.element.value);
|
2017-10-18 14:05:07 +02:00
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
set value(value: string) {
|
2019-10-29 19:26:11 +01:00
|
|
|
this.element.value = value;
|
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
addEventListeners(): void {
|
2018-05-25 10:22:14 +02:00
|
|
|
this.element.addEventListener('paste', this._onPaste);
|
2019-10-29 18:46:10 +01:00
|
|
|
this.element.addEventListener('input', this._onInput, {
|
|
|
|
passive: true,
|
|
|
|
});
|
|
|
|
this.element.addEventListener('focus', this._onFocus, {
|
|
|
|
passive: true,
|
|
|
|
});
|
|
|
|
this.element.addEventListener('blur', this._onBlur, {
|
|
|
|
passive: true,
|
|
|
|
});
|
2017-08-23 14:23:37 +02:00
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
removeEventListeners(): void {
|
|
|
|
this.element.removeEventListener('input', this._onInput);
|
2018-05-25 10:22:14 +02:00
|
|
|
this.element.removeEventListener('paste', this._onPaste);
|
2019-12-23 19:22:54 +01:00
|
|
|
this.element.removeEventListener('focus', this._onFocus);
|
|
|
|
this.element.removeEventListener('blur', this._onBlur);
|
2017-08-27 14:49:35 +02:00
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
enable(): void {
|
2017-08-23 14:32:07 +02:00
|
|
|
this.element.removeAttribute('disabled');
|
2017-08-29 13:56:54 +02:00
|
|
|
this.isDisabled = false;
|
2017-08-23 14:32:07 +02:00
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
disable(): void {
|
2017-08-23 14:32:07 +02:00
|
|
|
this.element.setAttribute('disabled', '');
|
2017-08-29 13:56:54 +02:00
|
|
|
this.isDisabled = true;
|
2017-08-23 14:32:07 +02:00
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
focus(): void {
|
2017-08-27 14:49:35 +02:00
|
|
|
if (!this.isFocussed) {
|
|
|
|
this.element.focus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
blur(): void {
|
2017-12-10 17:41:39 +01:00
|
|
|
if (this.isFocussed) {
|
|
|
|
this.element.blur();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
clear(setWidth = true): this {
|
2017-08-21 09:53:19 +02:00
|
|
|
if (this.element.value) {
|
|
|
|
this.element.value = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setWidth) {
|
2017-08-21 17:59:56 +02:00
|
|
|
this.setWidth();
|
2017-08-21 09:53:19 +02:00
|
|
|
}
|
|
|
|
|
2018-05-21 18:01:03 +02:00
|
|
|
return this;
|
2017-08-21 09:53:19 +02:00
|
|
|
}
|
2017-08-21 17:59:56 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the correct input width based on placeholder
|
|
|
|
* value or input value
|
|
|
|
*/
|
2019-12-23 19:22:54 +01:00
|
|
|
setWidth(): void {
|
2019-10-28 20:27:10 +01:00
|
|
|
// Resize input to contents or placeholder
|
|
|
|
const { style, value, placeholder } = this.element;
|
|
|
|
style.minWidth = `${placeholder.length + 1}ch`;
|
|
|
|
style.width = `${value.length + 1}ch`;
|
2017-08-27 14:49:35 +02:00
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
setActiveDescendant(activeDescendantID: string): void {
|
2017-10-12 10:35:58 +02:00
|
|
|
this.element.setAttribute('aria-activedescendant', activeDescendantID);
|
2017-08-27 14:49:35 +02:00
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
removeActiveDescendant(): void {
|
2017-08-27 14:49:35 +02:00
|
|
|
this.element.removeAttribute('aria-activedescendant');
|
|
|
|
}
|
2018-05-25 10:22:14 +02:00
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
_onInput(): void {
|
2019-11-03 18:45:16 +01:00
|
|
|
if (this.type !== SELECT_ONE_TYPE) {
|
2018-05-25 10:22:14 +02:00
|
|
|
this.setWidth();
|
|
|
|
}
|
|
|
|
}
|
2018-05-28 17:22:22 +02:00
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
_onPaste(event: ClipboardEvent): void {
|
2019-10-29 18:35:20 +01:00
|
|
|
if (this.preventPaste) {
|
2018-05-28 17:22:22 +02:00
|
|
|
event.preventDefault();
|
2018-05-25 10:22:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
_onFocus(): void {
|
2018-05-25 10:22:14 +02:00
|
|
|
this.isFocussed = true;
|
|
|
|
}
|
|
|
|
|
2019-12-23 19:22:54 +01:00
|
|
|
_onBlur(): void {
|
2018-05-25 10:22:14 +02:00
|
|
|
this.isFocussed = false;
|
|
|
|
}
|
2017-08-17 14:50:14 +02:00
|
|
|
}
|