Skip to content

Commit 9d96d20

Browse files
vursenweb-padawan
andauthored
feat: add manual validation mode (#8097)
Co-authored-by: web-padawan <iamkulykov@gmail.com>
1 parent 8d91c82 commit 9d96d20

20 files changed

+174
-64
lines changed

.eslintrc.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,21 @@
6161
},
6262
"overrides": [
6363
{
64-
// Prevent using optional-chaining in source files, as it is not supported by Polymer analyzer
6564
"files": ["packages/*/src/**/*.js"],
6665
"rules": {
67-
"es/no-optional-chaining": "error"
66+
// Prevent using optional-chaining in source files, as it is not supported by Polymer analyzer
67+
"es/no-optional-chaining": "error",
68+
"no-restricted-syntax": [
69+
"error",
70+
{
71+
"selector": "ForInStatement",
72+
"message": "for..in loops are slower than Object.{keys,values,entries} and have their caveats."
73+
},
74+
{
75+
"selector": "CallExpression[callee.property.name='validate']",
76+
"message": "Don't call validate() directly - it bypasses manual validation mode. Use _requestValidation() instead"
77+
}
78+
]
6879
}
6980
},
7081
{

packages/checkbox-group/src/vaadin-checkbox-group-mixin.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ export const CheckboxGroupMixin = (superclass) =>
264264
});
265265

266266
if (oldValue !== undefined) {
267-
this.validate();
267+
this._requestValidation();
268268
}
269269
}
270270

@@ -304,7 +304,7 @@ export const CheckboxGroupMixin = (superclass) =>
304304
// Do not validate when focusout is caused by document
305305
// losing focus, which happens on browser tab switch.
306306
if (!focused && document.hasFocus()) {
307-
this.validate();
307+
this._requestValidation();
308308
}
309309
}
310310
};

packages/checkbox/src/vaadin-checkbox-mixin.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,14 @@ export const CheckboxMixin = (superclass) =>
222222
// Do not validate when focusout is caused by document
223223
// losing focus, which happens on browser tab switch.
224224
if (!focused && document.hasFocus()) {
225-
this.validate();
225+
this._requestValidation();
226226
}
227227
}
228228

229229
/** @private */
230230
_checkedChanged(checked) {
231231
if (checked || this.__oldChecked) {
232-
this.validate();
232+
this._requestValidation();
233233
}
234234

235235
this.__oldChecked = checked;
@@ -246,7 +246,7 @@ export const CheckboxMixin = (superclass) =>
246246
super._requiredChanged(required);
247247

248248
if (required === false) {
249-
this.validate();
249+
this._requestValidation();
250250
}
251251
}
252252

packages/combo-box/src/vaadin-combo-box-light-mixin.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,6 @@ export const ComboBoxLightMixin = (superClass) =>
9999
});
100100
}
101101

102-
/**
103-
* Returns true if the current input value satisfies all constraints (if any).
104-
* @return {boolean}
105-
*/
106-
checkValidity() {
107-
if (this.inputElement && this.inputElement.validate) {
108-
return this.inputElement.validate();
109-
}
110-
return super.checkValidity();
111-
}
112-
113102
/**
114103
* @protected
115104
* @override

packages/combo-box/src/vaadin-combo-box-mixin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ export const ComboBoxMixin = (subclass) =>
11771177
// Do not validate when focusout is caused by document
11781178
// losing focus, which happens on browser tab switch.
11791179
if (document.hasFocus()) {
1180-
this.validate();
1180+
this._requestValidation();
11811181
}
11821182

11831183
if (this.value !== this._lastCommittedValue) {

packages/custom-field/src/vaadin-custom-field-mixin.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ export const CustomFieldMixin = (superClass) =>
159159
super._setFocused(focused);
160160

161161
if (!focused) {
162-
this.validate();
162+
this._requestValidation();
163163
}
164164
}
165165

@@ -203,7 +203,7 @@ export const CustomFieldMixin = (superClass) =>
203203
super._requiredChanged(required);
204204

205205
if (required === false) {
206-
this.validate();
206+
this._requestValidation();
207207
}
208208
}
209209

@@ -233,7 +233,7 @@ export const CustomFieldMixin = (superClass) =>
233233
event.stopPropagation();
234234

235235
this.__setValue();
236-
this.validate();
236+
this._requestValidation();
237237
this.dispatchEvent(
238238
new CustomEvent('change', {
239239
bubbles: true,
@@ -299,7 +299,7 @@ export const CustomFieldMixin = (superClass) =>
299299
this.__applyInputsValue(value || '\t');
300300

301301
if (oldValue !== undefined) {
302-
this.validate();
302+
this._requestValidation();
303303
}
304304
}
305305

packages/date-picker/src/vaadin-date-picker-mixin.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ export const DatePickerMixin = (subclass) =>
479479
// Do not validate when focusout is caused by document
480480
// losing focus, which happens on browser tab switch.
481481
if (document.hasFocus()) {
482-
this.validate();
482+
this._requestValidation();
483483
}
484484
}
485485
}
@@ -624,13 +624,8 @@ export const DatePickerMixin = (subclass) =>
624624
!this._selectedDate || dateAllowed(this._selectedDate, this._minDate, this._maxDate, this.isDateDisabled);
625625

626626
let inputValidity = true;
627-
if (this.inputElement) {
628-
if (this.inputElement.checkValidity) {
629-
inputValidity = this.inputElement.checkValidity();
630-
} else if (this.inputElement.validate) {
631-
// Iron-form-elements have the validate API
632-
inputValidity = this.inputElement.validate();
633-
}
627+
if (this.inputElement && this.inputElement.checkValidity) {
628+
inputValidity = this.inputElement.checkValidity();
634629
}
635630

636631
return inputValid && isDateValid && inputValidity;
@@ -717,10 +712,10 @@ export const DatePickerMixin = (subclass) =>
717712
const unparsableValue = this.__unparsableValue;
718713

719714
if (this.__committedValue !== this.value) {
720-
this.validate();
715+
this._requestValidation();
721716
this.dispatchEvent(new CustomEvent('change', { bubbles: true }));
722717
} else if (this.__committedUnparsableValue !== unparsableValue) {
723-
this.validate();
718+
this._requestValidation();
724719
this.dispatchEvent(new CustomEvent('unparsable-change'));
725720
}
726721

@@ -849,7 +844,7 @@ export const DatePickerMixin = (subclass) =>
849844

850845
if (oldValue !== undefined) {
851846
// Validate only if `value` changes after initialization.
852-
this.validate();
847+
this._requestValidation();
853848
}
854849
}
855850
} else {
@@ -1015,7 +1010,7 @@ export const DatePickerMixin = (subclass) =>
10151010
// Needed in case the value was not changed: open and close dropdown,
10161011
// especially on outside click. On Esc key press, do not validate.
10171012
if (!this.value && !this._keyboardActive) {
1018-
this.validate();
1013+
this._requestValidation();
10191014
}
10201015
}
10211016

packages/date-time-picker/src/vaadin-date-time-picker-mixin.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ export const DateTimePickerMixin = (superClass) =>
370370
// Do not validate when focusout is caused by document
371371
// losing focus, which happens on browser tab switch.
372372
if (!focused && document.hasFocus()) {
373-
this.validate();
373+
this._requestValidation();
374374
}
375375
}
376376

@@ -414,7 +414,7 @@ export const DateTimePickerMixin = (superClass) =>
414414
event.stopPropagation();
415415

416416
if (this.__dispatchChangeForValue === this.value) {
417-
this.validate();
417+
this._requestValidation();
418418
this.__dispatchChange();
419419
}
420420
this.__dispatchChangeForValue = undefined;
@@ -473,7 +473,7 @@ export const DateTimePickerMixin = (superClass) =>
473473
newDatePicker.max = this.__formatDateISO(this.__maxDateTime, this.__defaultDateMinMaxValue);
474474

475475
// Disable default internal validation for the component
476-
newDatePicker.validate = () => {};
476+
newDatePicker.manualValidation = true;
477477
}
478478

479479
/** @private */
@@ -501,7 +501,7 @@ export const DateTimePickerMixin = (superClass) =>
501501
this.__updateTimePickerMinMax();
502502

503503
// Disable default internal validation for the component
504-
newTimePicker.validate = () => {};
504+
newTimePicker.manualValidation = true;
505505
}
506506

507507
/** @private */
@@ -603,7 +603,7 @@ export const DateTimePickerMixin = (superClass) =>
603603
}
604604

605605
if (this.__oldRequired && !required) {
606-
this.validate();
606+
this._requestValidation();
607607
}
608608

609609
this.__oldRequired = required;
@@ -796,7 +796,7 @@ export const DateTimePickerMixin = (superClass) =>
796796
this.__updateTimePickerMinMax();
797797

798798
if (this.__datePicker && this.__timePicker && this.value) {
799-
this.validate();
799+
this._requestValidation();
800800
}
801801
}
802802

@@ -809,7 +809,7 @@ export const DateTimePickerMixin = (superClass) =>
809809
this.__updateTimePickerMinMax();
810810

811811
if (this.__datePicker && this.__timePicker && this.value) {
812-
this.validate();
812+
this._requestValidation();
813813
}
814814
}
815815

@@ -910,7 +910,7 @@ export const DateTimePickerMixin = (superClass) =>
910910
// run initial validation here. Lit version runs observers differently and
911911
// this observer is executed first - ignore it to prevent validating twice.
912912
if ((this.min && this.__minDateTime) || (this.max && this.__maxDateTime)) {
913-
this.validate();
913+
this._requestValidation();
914914
}
915915
}
916916
}

packages/field-base/src/input-constraints-mixin.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ export const InputConstraintsMixin = dedupingMixin(
9090
const isLastConstraintRemoved = this.__previousHasConstraints && !hasConstraints;
9191

9292
if ((this._hasValue || this.invalid) && hasConstraints) {
93-
this.validate();
94-
} else if (isLastConstraintRemoved) {
93+
this._requestValidation();
94+
} else if (isLastConstraintRemoved && !this.manualValidation) {
9595
this._setInvalid(false);
9696
}
9797

@@ -109,7 +109,7 @@ export const InputConstraintsMixin = dedupingMixin(
109109
_onChange(event) {
110110
event.stopPropagation();
111111

112-
this.validate();
112+
this._requestValidation();
113113

114114
this.dispatchEvent(
115115
new CustomEvent('change', {

packages/field-base/src/input-field-mixin.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export const InputFieldMixin = (superclass) =>
9797
// Do not validate when focusout is caused by document
9898
// losing focus, which happens on browser tab switch.
9999
if (!focused && document.hasFocus()) {
100-
this.validate();
100+
this._requestValidation();
101101
}
102102
}
103103

@@ -112,7 +112,7 @@ export const InputFieldMixin = (superclass) =>
112112
super._onInput(event);
113113

114114
if (this.invalid) {
115-
this.validate();
115+
this._requestValidation();
116116
}
117117
}
118118

@@ -133,7 +133,7 @@ export const InputFieldMixin = (superclass) =>
133133
}
134134

135135
if (this.invalid) {
136-
this.validate();
136+
this._requestValidation();
137137
}
138138
}
139139
};

0 commit comments

Comments
 (0)