@vaadin/vaadin-text-field 2.9.2 → 2.10.0

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/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "repository": "vaadin/vaadin-text-field",
11
11
  "homepage": "https://vaadin.com/components",
12
12
  "name": "@vaadin/vaadin-text-field",
13
- "version": "2.9.2",
13
+ "version": "2.10.0",
14
14
  "main": "vaadin-text-field.js",
15
15
  "author": "Vaadin Ltd",
16
16
  "license": "Apache-2.0",
@@ -63,7 +63,7 @@ class EmailFieldElement extends TextFieldElement {
63
63
  }
64
64
 
65
65
  static get version() {
66
- return '2.9.2';
66
+ return '2.10.0';
67
67
  }
68
68
 
69
69
  static get template() {
@@ -32,7 +32,7 @@ class IntegerFieldElement extends NumberFieldElement {
32
32
  }
33
33
 
34
34
  static get version() {
35
- return '2.9.2';
35
+ return '2.10.0';
36
36
  }
37
37
 
38
38
  static get properties() {
@@ -49,6 +49,15 @@ declare class NumberFieldElement extends TextFieldElement {
49
49
  step: number;
50
50
  ready(): void;
51
51
  _createConstraintsObserver(): void;
52
+
53
+ /**
54
+ * Native [type=number] inputs don't update their value
55
+ * when you are entering input that the browser is unable to parse
56
+ * e.g. "--5", hence we have to override this method from `InputMixin`
57
+ * so that, when value is empty, it would additionally check
58
+ * for bad input based on the native `validity.badInput` property.
59
+ */
60
+ _setHasInputValue(event: InputEvent|null): void;
52
61
  _valueChanged(newVal: unknown|null, oldVal: unknown|null): void;
53
62
  checkValidity(): boolean;
54
63
  _onKeyDown(e: KeyboardEvent): void;
@@ -105,7 +105,7 @@ class NumberFieldElement extends TextFieldElement {
105
105
  }
106
106
 
107
107
  static get version() {
108
- return '2.9.2';
108
+ return '2.10.0';
109
109
  }
110
110
 
111
111
  static get properties() {
@@ -279,7 +279,7 @@ class NumberFieldElement extends TextFieldElement {
279
279
 
280
280
  /** @private */
281
281
  _setValue(value) {
282
- this.value = this.inputElement.value = String(parseFloat(value));
282
+ this.value = this._inputElementValue = String(parseFloat(value));
283
283
  this.dispatchEvent(new CustomEvent('change', {bubbles: true}));
284
284
  }
285
285
 
@@ -411,6 +411,21 @@ class NumberFieldElement extends TextFieldElement {
411
411
 
412
412
  return super.checkValidity();
413
413
  }
414
+
415
+ /**
416
+ * Native [type=number] inputs don't update their value
417
+ * when you are entering input that the browser is unable to parse
418
+ * e.g. "--5", hence we have to override this method from `InputMixin`
419
+ * so that, when value is empty, it would additionally check
420
+ * for bad input based on the native `validity.badInput` property.
421
+ *
422
+ * @param {InputEvent} event
423
+ * @protected
424
+ * @override
425
+ */
426
+ _setHasInputValue(event) {
427
+ this._hasInputValue = event.target.value.length > 0 || event.target.validity.badInput;
428
+ }
414
429
  }
415
430
 
416
431
  window.customElements.define(NumberFieldElement.is, NumberFieldElement);
@@ -76,7 +76,7 @@ class PasswordFieldElement extends TextFieldElement {
76
76
  }
77
77
 
78
78
  static get version() {
79
- return '2.9.2';
79
+ return '2.10.0';
80
80
  }
81
81
 
82
82
  static get properties() {
@@ -149,7 +149,7 @@ class TextAreaElement extends
149
149
  }
150
150
 
151
151
  static get version() {
152
- return '2.9.2';
152
+ return '2.10.0';
153
153
  }
154
154
 
155
155
  static get properties() {
@@ -275,13 +275,13 @@ class TextAreaElement extends
275
275
  // according to WHATWG spec for <input>, with tests inspired by web-platform-tests
276
276
  // https://html.spec.whatwg.org/multipage/input.html#the-pattern-attribute
277
277
 
278
- if (!this.pattern || !this.inputElement.value) {
278
+ if (!this.pattern || !this._inputElementValue) {
279
279
  // Mark as valid if there is no pattern, or the value is empty
280
280
  return true;
281
281
  }
282
282
 
283
283
  try {
284
- const match = this.inputElement.value.match(this.pattern);
284
+ const match = this._inputElementValue.match(this.pattern);
285
285
  return match ? match[0] === match.input : false;
286
286
  } catch (_) {
287
287
  // If the pattern can not be compiled, then report as valid
@@ -33,6 +33,18 @@ interface TextFieldMixin {
33
33
  readonly inputElement: HTMLElement|null|undefined;
34
34
  readonly _slottedTagName: string;
35
35
 
36
+ /**
37
+ * A property for accessing the input element's value.
38
+ *
39
+ * Override this getter if the property is different from the default `value` one.
40
+ */
41
+ readonly _inputElementValueProperty: string;
42
+
43
+ /**
44
+ * The input element's value.
45
+ */
46
+ _inputElementValue: string;
47
+
36
48
  /**
37
49
  * Whether the value of the control can be automatically completed by the browser.
38
50
  * List of available options at:
@@ -137,6 +149,11 @@ interface TextFieldMixin {
137
149
  */
138
150
  value: string;
139
151
 
152
+ /**
153
+ * Whether the input element has a non-empty value.
154
+ */
155
+ _hasInputValue: boolean|null|undefined;
156
+
140
157
  /**
141
158
  * This property is set to true when the control value is invalid.
142
159
  */
@@ -167,6 +184,11 @@ interface TextFieldMixin {
167
184
  */
168
185
  _enabledCharPattern: string|null|undefined;
169
186
  _createConstraintsObserver(): void;
187
+
188
+ /**
189
+ * Sets the `_hasInputValue` property based on the `input` event.
190
+ */
191
+ _setHasInputValue(event: InputEvent|null): void;
170
192
  _onChange(e: Event): void;
171
193
  _valueChanged(newVal: unknown|null, oldVal: unknown|null): void;
172
194
  _constraintsChanged(required: boolean|undefined, minlength: number|undefined, maxlength: string|undefined, pattern: any): void;
@@ -176,10 +198,17 @@ interface TextFieldMixin {
176
198
  */
177
199
  checkValidity(): boolean;
178
200
  ready(): void;
201
+ _setInvalid(invalid: boolean): void;
179
202
 
180
203
  /**
181
- * Returns true if `value` is valid.
182
- * `<iron-form>` uses this to check the validity for all its elements.
204
+ * Override this method to define whether the given `invalid` state should be set.
205
+ */
206
+ _shouldSetInvalid(_invalid: boolean): boolean;
207
+
208
+ /**
209
+ * Validates the field and sets the `invalid` property based on the result.
210
+ *
211
+ * The method fires a `validated` event with the result of the validation.
183
212
  *
184
213
  * @returns True if the value is valid.
185
214
  */
@@ -292,6 +292,17 @@ export const TextFieldMixin = subclass => class VaadinTextFieldMixin extends sub
292
292
  notify: true
293
293
  },
294
294
 
295
+ /**
296
+ * Whether the input element has a non-empty value.
297
+ *
298
+ * @protected
299
+ */
300
+ _hasInputValue: {
301
+ type: Boolean,
302
+ value: false,
303
+ observer: '_hasInputValueChanged',
304
+ },
305
+
295
306
  /**
296
307
  * This property is set to true when the control value is invalid.
297
308
  * @type {boolean}
@@ -402,6 +413,61 @@ export const TextFieldMixin = subclass => class VaadinTextFieldMixin extends sub
402
413
  this._createMethodObserver('_constraintsChanged(required, minlength, maxlength, pattern)');
403
414
  }
404
415
 
416
+ /**
417
+ * A property for accessing the input element's value.
418
+ *
419
+ * Override this getter if the property is different from the default `value` one.
420
+ *
421
+ * @protected
422
+ * @return {string}
423
+ */
424
+ get _inputElementValueProperty() {
425
+ return 'value';
426
+ }
427
+
428
+ /**
429
+ * The input element's value.
430
+ *
431
+ * @protected
432
+ * @return {string}
433
+ */
434
+ get _inputElementValue() {
435
+ return this.inputElement ? this.inputElement[this._inputElementValueProperty] : undefined;
436
+ }
437
+
438
+ /**
439
+ * The input element's value.
440
+ *
441
+ * @protected
442
+ */
443
+ set _inputElementValue(value) {
444
+ if (this.inputElement) {
445
+ this.inputElement[this._inputElementValueProperty] = value;
446
+ }
447
+ }
448
+
449
+ /**
450
+ * Sets the `_hasInputValue` property based on the `input` event.
451
+ *
452
+ * @param {InputEvent} event
453
+ * @protected
454
+ */
455
+ _setHasInputValue(event) {
456
+ this._hasInputValue = event.target.value.length > 0;
457
+ }
458
+
459
+ /**
460
+ * An input event listener used to update `_hasInputValue` property.
461
+ * Do not override this method.
462
+ *
463
+ * @param {Event} event
464
+ * @private
465
+ */
466
+ __onInput(event) {
467
+ this._setHasInputValue(event);
468
+ this._onInput(event);
469
+ }
470
+
405
471
  /** @private */
406
472
  _onInput(e) {
407
473
  if (this.__preventInput) {
@@ -448,6 +514,17 @@ export const TextFieldMixin = subclass => class VaadinTextFieldMixin extends sub
448
514
  }
449
515
  }
450
516
 
517
+ /**
518
+ * Observer to notify about the change of private property.
519
+ *
520
+ * @private
521
+ */
522
+ _hasInputValueChanged(hasValue, oldHasValue) {
523
+ if (hasValue || oldHasValue) {
524
+ this.dispatchEvent(new CustomEvent('has-input-value-changed'));
525
+ }
526
+ }
527
+
451
528
  /**
452
529
  * @param {!Event} e
453
530
  * @protected
@@ -489,9 +566,9 @@ export const TextFieldMixin = subclass => class VaadinTextFieldMixin extends sub
489
566
  if (this.__userInput) {
490
567
  return;
491
568
  } else if (newVal !== undefined) {
492
- this.inputElement.value = newVal;
569
+ this._inputElementValue = newVal;
493
570
  } else {
494
- this.value = this.inputElement.value = '';
571
+ this.value = this._inputElementValue = '';
495
572
  }
496
573
 
497
574
  if (this.invalid) {
@@ -534,7 +611,7 @@ export const TextFieldMixin = subclass => class VaadinTextFieldMixin extends sub
534
611
  const slotted = this.querySelector(`${this._slottedTagName}[slot="${this._slottedTagName}"]`);
535
612
 
536
613
  if (this.value) {
537
- this.inputElement.value = this.value;
614
+ this._inputElementValue = this.value;
538
615
  this.validate();
539
616
  }
540
617
 
@@ -614,7 +691,7 @@ export const TextFieldMixin = subclass => class VaadinTextFieldMixin extends sub
614
691
  }
615
692
 
616
693
  if (!required && !minlength && !maxlength && !pattern) {
617
- this.invalid = false;
694
+ this._setInvalid(false);
618
695
  } else {
619
696
  this.validate();
620
697
  }
@@ -662,7 +739,7 @@ export const TextFieldMixin = subclass => class VaadinTextFieldMixin extends sub
662
739
 
663
740
  this._createConstraintsObserver();
664
741
 
665
- this._boundOnInput = this._onInput.bind(this);
742
+ this._boundOnInput = this.__onInput.bind(this);
666
743
  this._boundOnChange = this._onChange.bind(this);
667
744
  this._boundOnBlur = this._onBlur.bind(this);
668
745
  this._boundOnFocus = this._onFocus.bind(this);
@@ -709,16 +786,42 @@ export const TextFieldMixin = subclass => class VaadinTextFieldMixin extends sub
709
786
  }
710
787
 
711
788
  /**
712
- * Returns true if `value` is valid.
713
- * `<iron-form>` uses this to check the validity for all its elements.
789
+ * @param {boolean} invalid
790
+ * @protected
791
+ */
792
+ _setInvalid(invalid) {
793
+ if (this._shouldSetInvalid(invalid)) {
794
+ this.invalid = invalid;
795
+ }
796
+ }
797
+
798
+ /**
799
+ * Override this method to define whether the given `invalid` state should be set.
800
+ *
801
+ * @param {boolean} _invalid
802
+ * @return {boolean}
803
+ * @protected
804
+ */
805
+ _shouldSetInvalid(_invalid) {
806
+ return true;
807
+ }
808
+
809
+ /**
810
+ * Validates the field and sets the `invalid` property based on the result.
811
+ *
812
+ * The method fires a `validated` event with the result of the validation.
714
813
  *
715
814
  * @return {boolean} True if the value is valid.
716
815
  */
717
816
  validate() {
718
- return !(this.invalid = !this.checkValidity());
817
+ const isValid = this.checkValidity();
818
+ this._setInvalid(!isValid);
819
+ this.dispatchEvent(new CustomEvent('validated', {detail: {valid: isValid}}));
820
+ return isValid;
719
821
  }
720
822
 
721
823
  clear() {
824
+ this._hasInputValue = false;
722
825
  this.value = '';
723
826
  }
724
827
 
@@ -955,4 +1058,12 @@ export const TextFieldMixin = subclass => class VaadinTextFieldMixin extends sub
955
1058
  *
956
1059
  * @event iron-resize
957
1060
  */
1061
+
1062
+ /**
1063
+ * Fired whenever the field is validated.
1064
+ *
1065
+ * @event validated
1066
+ * @param {Object} detail
1067
+ * @param {boolean} detail.valid the result of the validation.
1068
+ */
958
1069
  };
@@ -116,7 +116,7 @@ class TextFieldElement extends
116
116
  }
117
117
 
118
118
  static get version() {
119
- return '2.9.2';
119
+ return '2.10.0';
120
120
  }
121
121
 
122
122
  static get properties() {