@brandup/ui-input 1.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # brandup-ui-input
2
+
3
+ [![Build Status](https://dev.azure.com/brandup/BrandUp%20Core/_apis/build/status%2FBrandUp%2Fbrandup-ui-kit?branchName=master)]()
4
+
5
+ ## Installation
6
+
7
+ Install NPM package [@brandup/ui](https://www.npmjs.com/package/@brandup/ui-kit).
8
+
9
+ ```
10
+ npm i @brandup/ui-kit@latest
11
+ ```
12
+
13
+ ## InputControl
14
+
15
+ `InputControl<InputType>` - это базовый абстрактный класс для элементов пользовательсково ввода в форме. Реализуется
16
+ относительно `HTMLInputElement`, `HTMLTextAreaElement`, `HTMLSelectElement`.
17
+
18
+ `InputControl` наследует интерфейс `IInputControl`, чтобы можно было абстрагироваться от реализации.
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@brandup/ui-input",
3
+ "description": "Input control type and styles.",
4
+ "keywords": [
5
+ "brandup",
6
+ "javascript",
7
+ "typescript",
8
+ "ui"
9
+ ],
10
+ "author": {
11
+ "name": "Dmitry Kovyazin",
12
+ "email": "it@brandup.online"
13
+ },
14
+ "homepage": "https://github.com/brandup-online/brandup-ui/npm/brandup-ui-input",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/brandup-online/brandup-ui.git"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/brandup-online/brandup-ui/issues",
21
+ "email": "it@brandup.online"
22
+ },
23
+ "license": "Apache-2.0",
24
+ "version": "1.0.18",
25
+ "main": "source/index.ts",
26
+ "types": "source/index.ts",
27
+ "dependencies": {
28
+ "@brandup/ui": "^1.0.32",
29
+ "@brandup/ui-kit": "^1.0.18"
30
+ },
31
+ "files": [
32
+ "source",
33
+ "README.md"
34
+ ]
35
+ }
@@ -0,0 +1 @@
1
+ export * from "./input"
@@ -0,0 +1 @@
1
+ // Тут могут быть общие стили для класса ui-input.
@@ -0,0 +1,107 @@
1
+ import { UIElement } from "@brandup/ui";
2
+ import "./input.less";
3
+
4
+ type InputType = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
5
+ type FormInput<T> = T extends InputType ? T : never;
6
+
7
+ export const INPUT_CSS_CLASS = "ui-input";
8
+
9
+ export abstract class InputControl<T extends InputType> extends UIElement implements IInputControl {
10
+ protected __valueElem: FormInput<T>;
11
+ protected __submitEvent?: (e: SubmitEvent) => void;
12
+ private __isValidating?: boolean; // true, когда выполняется checkValidity в validate.
13
+
14
+ constructor(valueElem: FormInput<T>) {
15
+ super();
16
+
17
+ this.__valueElem = valueElem;
18
+
19
+ this.__initForm();
20
+ }
21
+
22
+ get form(): HTMLFormElement | null { return this.__valueElem.form; }
23
+ get disabled(): boolean { return this.__valueElem.disabled; }
24
+ get required(): boolean { return this.__valueElem.required; }
25
+ get readonly(): boolean { return this.__valueElem.hasAttribute("readonly") || this.__valueElem.hasAttribute("data-readonly"); }
26
+
27
+ private __initForm() {
28
+ this.__valueElem.addEventListener("invalid", (e: Event) => {
29
+ e.preventDefault();
30
+
31
+ this.__submitForm();
32
+ });
33
+
34
+ this.__submitEvent = (e: SubmitEvent) => {
35
+ if ((<HTMLButtonElement>e.submitter).formNoValidate || (<HTMLFormElement>e.target).noValidate)
36
+ return; // Не делаем валидацию, если она отключена в форме или в инициаторе события submit
37
+
38
+ if (this.disabled)
39
+ return;
40
+
41
+ if (!this.validate()) {
42
+ if (!e.defaultPrevented) {
43
+ e.stopPropagation();
44
+ this.focus();
45
+ }
46
+
47
+ e.preventDefault();
48
+
49
+ return false;
50
+ }
51
+ };
52
+
53
+ if (this.form)
54
+ this.form.addEventListener("submit", this.__submitEvent);
55
+ }
56
+
57
+ protected __submitForm() {
58
+ const form = this.form;
59
+ if (!this.readonly && !this.disabled && form)
60
+ form.dispatchEvent(new SubmitEvent("submit", { submitter: form, cancelable: true }));
61
+ }
62
+
63
+ protected _onRenderElement(elem: HTMLElement) {
64
+ elem.classList.add(INPUT_CSS_CLASS);
65
+
66
+ if (this.required)
67
+ elem.classList.add("required");
68
+ if (this.readonly)
69
+ elem.classList.add("readonly");
70
+ if (this.disabled)
71
+ elem.classList.add("disabled");
72
+ }
73
+
74
+ validate(): boolean {
75
+ if (this.__isValidating)
76
+ return true;
77
+
78
+ this.__isValidating = true;
79
+ const result = this.__valueElem.checkValidity();
80
+ this.__isValidating = false;
81
+
82
+ return result;
83
+ }
84
+
85
+ focus(): void {
86
+ this.__valueElem.focus();
87
+ this.element?.scrollIntoView({ block: "center", inline: "center" });
88
+ }
89
+
90
+ destroy() {
91
+ if (this.form && this.__submitEvent)
92
+ this.form.removeEventListener("submit", this.__submitEvent);
93
+
94
+ super.destroy();
95
+ }
96
+ }
97
+
98
+ export interface IInputControl {
99
+ get form(): HTMLFormElement | null;
100
+ get disabled(): boolean;
101
+ get required(): boolean;
102
+ get readonly(): boolean;
103
+
104
+ validate(): boolean;
105
+ focus(): void;
106
+ destroy(): void;
107
+ }