@brandup/ui-input 1.0.39 → 1.0.40

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/source/input.ts +38 -22
package/package.json CHANGED
@@ -24,12 +24,12 @@
24
24
  "email": "it@brandup.online"
25
25
  },
26
26
  "license": "Apache-2.0",
27
- "version": "1.0.39",
27
+ "version": "1.0.40",
28
28
  "main": "source/index.ts",
29
29
  "types": "source/index.ts",
30
30
  "dependencies": {
31
31
  "@brandup/ui": "^2.0.7",
32
- "@brandup/ui-kit": "^1.0.39"
32
+ "@brandup/ui-kit": "^1.0.40"
33
33
  },
34
34
  "files": [
35
35
  "source",
package/source/input.ts CHANGED
@@ -68,34 +68,24 @@ export abstract class InputControl<T extends InputType, TEvents = {}>
68
68
  protected __syncValue(): void {}
69
69
 
70
70
  private __initForm() {
71
+ // Логика валидации — штатная: ограничения объявлены на поле-носителе, решение принимает
72
+ // браузер, он же блокирует отправку и поднимает invalid. Контрол только отражает это
73
+ // классом и своё событие submit не досылает — обработчики формы получают ровно то же,
74
+ // что и у обычных input/textarea.
75
+ //
76
+ // Гасим лишь показ подсказки: поле уведено с экрана, привязать её не к чему, и браузер
77
+ // вместо неё пишет в консоль «not focusable». Состояние видно по классу invalid.
71
78
  this.__invalidEvent = (e: Event) => {
72
79
  e.preventDefault();
73
80
 
74
- this.__submitForm();
81
+ this.element.classList.add("invalid");
75
82
  };
76
83
  this.__valueElem.addEventListener("invalid", this.__invalidEvent);
77
84
 
78
- this.__submitEvent = (e: SubmitEvent) => {
79
- // Значение синхронизируем до любых проверок и независимо от них: при отключённой
80
- // валидации обработчик выходит ниже, а форма всё равно отправится уже с этим значением.
81
- // Событие submit приходит до действия по умолчанию, поэтому успеваем.
82
- this.__syncValue();
83
-
84
- if ((e.submitter as HTMLButtonElement | null)?.formNoValidate || (<HTMLFormElement>e.target).noValidate)
85
- return; // Не делаем валидацию, если она отключена в форме или в инициаторе события submit
86
-
87
- if (this.disabled) return;
88
-
89
- if (!this.validate()) {
90
- if (!e.defaultPrevented) {
91
- e.stopPropagation();
92
- this.focus();
93
- }
94
-
95
- e.preventDefault();
96
- return;
97
- }
98
- };
85
+ // Значение переносим в поле формы до отправки. Проверять здесь нечего: контрол объявляет
86
+ // свои ограничения через setCustomValidity, а решение принимает браузер до submit он
87
+ // уже отказал бы. Синхронизация нужна и при отключённой валидации, поэтому она первым делом.
88
+ this.__submitEvent = () => this.__syncValue();
99
89
 
100
90
  if (!this.form) return;
101
91
 
@@ -116,6 +106,32 @@ export abstract class InputControl<T extends InputType, TEvents = {}>
116
106
  this.__valueElem.ownerDocument.addEventListener("submit", this.__submitCaptureEvent, true);
117
107
  }
118
108
 
109
+ /**
110
+ * Отправка формы по Enter — как у обычного `input`: браузер сам проверит валидность,
111
+ * поднимет отменяемый `submit` и отправит форму.
112
+ *
113
+ * Не то же, что {@link __submitForm}: тот лишь диспатчит событие, а синтетическое событие
114
+ * вызывает обработчиков, но саму отправку не запускает — форма с `action` никуда не уходила.
115
+ *
116
+ * Неявная отправка в браузере равносильна нажатию первой кнопки отправки, поэтому её же
117
+ * передаём инициатором: от неё зависят `formaction`, `formnovalidate` и `e.submitter`.
118
+ */
119
+ protected __requestSubmit() {
120
+ const form = this.form;
121
+ if (this.readonly || this.disabled || !form) return;
122
+
123
+ if (typeof form.requestSubmit !== "function") {
124
+ this.__submitForm(); // движок без requestSubmit — хотя бы уведомим обработчиков
125
+ return;
126
+ }
127
+
128
+ const submitter = form.querySelector<HTMLButtonElement>(
129
+ "button[type=submit], input[type=submit], button:not([type])"
130
+ );
131
+
132
+ form.requestSubmit(submitter ?? undefined);
133
+ }
134
+
119
135
  protected __submitForm() {
120
136
  const form = this.form;
121
137
  if (!this.readonly && !this.disabled && form)