@vaadin/vaadin-combo-box 5.4.11 → 5.5.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-combo-box",
11
11
  "homepage": "https://vaadin.com/components",
12
12
  "name": "@vaadin/vaadin-combo-box",
13
- "version": "5.4.11",
13
+ "version": "5.5.0",
14
14
  "main": "vaadin-combo-box.js",
15
15
  "author": "Vaadin Ltd",
16
16
  "license": "Apache-2.0",
@@ -25,39 +25,40 @@
25
25
  "theme"
26
26
  ],
27
27
  "resolutions": {
28
- "es-abstract": "1.17.6",
29
- "@types/doctrine": "0.0.3",
30
28
  "inherits": "2.0.3",
31
29
  "samsam": "1.1.3",
32
30
  "supports-color": "3.1.2",
33
31
  "type-detect": "1.0.0"
34
32
  },
35
33
  "dependencies": {
36
- "@polymer/iron-a11y-announcer": "^3.0.0",
37
34
  "@polymer/iron-a11y-keys-behavior": "^3.0.0",
35
+ "@polymer/iron-a11y-announcer": "^3.0.0",
38
36
  "@polymer/iron-list": "^3.0.0",
39
37
  "@polymer/iron-resizable-behavior": "^3.0.0",
40
38
  "@polymer/polymer": "^3.0.0",
41
39
  "@vaadin/vaadin-control-state-mixin": "^2.2.2",
42
- "@vaadin/vaadin-element-mixin": "^2.4.1",
43
- "@vaadin/vaadin-item": "^2.3.0",
44
- "@vaadin/vaadin-lumo-styles": "^1.1.1",
45
- "@vaadin/vaadin-material-styles": "^1.1.2",
46
40
  "@vaadin/vaadin-overlay": "^3.5.0",
47
41
  "@vaadin/vaadin-text-field": "^2.8.0",
48
- "@vaadin/vaadin-themable-mixin": "^1.6.1"
49
- },
50
- "scripts": {
51
- "generate-typings": "gen-typescript-declarations --outDir . --verify"
42
+ "@vaadin/vaadin-themable-mixin": "^1.6.1",
43
+ "@vaadin/vaadin-lumo-styles": "^1.1.1",
44
+ "@vaadin/vaadin-material-styles": "^1.1.2",
45
+ "@vaadin/vaadin-item": "^2.3.0",
46
+ "@vaadin/vaadin-element-mixin": "^2.4.1"
52
47
  },
53
48
  "devDependencies": {
54
- "@polymer/iron-component-page": "^4.0.0",
49
+ "@web-padawan/gen-typescript-declarations": "^1.6.2",
50
+ "web-component-tester": "6.9.2",
55
51
  "@polymer/iron-form": "^3.0.0",
52
+ "@polymer/iron-component-page": "^4.0.0",
56
53
  "@polymer/iron-test-helpers": "^3.0.0",
57
54
  "@polymer/paper-input": "^3.0.0",
58
55
  "@vaadin/vaadin-button": "^2.4.0",
56
+ "wct-browser-legacy": "^1.0.1",
59
57
  "@vaadin/vaadin-demo-helpers": "^3.1.0",
60
- "@vaadin/vaadin-dialog": "^2.5.0",
61
- "wct-browser-legacy": "^1.0.1"
58
+ "@vaadin/vaadin-dialog": "^2.5.0"
59
+ },
60
+ "scripts": {
61
+ "generate-typings": "gen-typescript-declarations --outDir . --verify",
62
+ "test": "wct --npm"
62
63
  }
63
64
  }
@@ -122,6 +122,11 @@ interface ComboBoxMixin {
122
122
  */
123
123
  selectedItem: ComboBoxItem|string|null|undefined;
124
124
 
125
+ /**
126
+ * Whether the input element has a non-empty value.
127
+ */
128
+ _hasInputValue: boolean|null|undefined;
129
+
125
130
  /**
126
131
  * Path for label of the item. If `items` is an array of objects, the
127
132
  * `itemLabelPath` is used to fetch the displayed string label for each
@@ -201,10 +206,19 @@ interface ComboBoxMixin {
201
206
  * Filtering and items handling
202
207
  */
203
208
  _inputValueChanged(e: Event): void;
209
+ _inputElementValueChanged(inputElementValue: any): void;
204
210
  _revertInputValue(): void;
211
+ _setInvalid(invalid: boolean): void;
205
212
 
206
213
  /**
207
- * Returns true if `value` is valid, and sets the `invalid` flag appropriately.
214
+ * Override this method to define whether the given `invalid` state should be set.
215
+ */
216
+ _shouldSetInvalid(_invalid: boolean): boolean;
217
+
218
+ /**
219
+ * Validates the field and sets the `invalid` property based on the result.
220
+ *
221
+ * The method fires a `validated` event with the result of the validation.
208
222
  *
209
223
  * @returns True if the value is valid and sets the `invalid` flag appropriately
210
224
  */
@@ -166,6 +166,16 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
166
166
  notify: true
167
167
  },
168
168
 
169
+ /**
170
+ * Whether the input element has a non-empty value.
171
+ * @protected
172
+ */
173
+ _hasInputValue: {
174
+ type: Boolean,
175
+ value: false,
176
+ observer: '_hasInputValueChanged',
177
+ },
178
+
169
179
  /**
170
180
  * Path for label of the item. If `items` is an array of objects, the
171
181
  * `itemLabelPath` is used to fetch the displayed string label for each
@@ -261,7 +271,8 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
261
271
  '_templateOrRendererChanged(_itemTemplate, renderer)',
262
272
  '_loadingChanged(loading)',
263
273
  '_selectedItemChanged(selectedItem, itemValuePath, itemLabelPath)',
264
- '_toggleElementChanged(_toggleElement)'
274
+ '_toggleElementChanged(_toggleElement)',
275
+ '_inputElementValueChanged(_inputElementValue)'
265
276
  ];
266
277
  }
267
278
 
@@ -632,6 +643,7 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
632
643
  this.selectedItem = null;
633
644
 
634
645
  if (this.allowCustomValue) {
646
+ this._inputElementValue = '';
635
647
  this.value = '';
636
648
  }
637
649
 
@@ -704,13 +716,19 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
704
716
  }
705
717
  } else {
706
718
  const toLowerCase = (item) => item && item.toLowerCase && item.toLowerCase();
707
- const itemsMatchedByLabel = this.filteredItems
708
- && this.filteredItems.filter(item => toLowerCase(this._getItemLabel(item)) === toLowerCase(this._inputElementValue))
709
- || [];
719
+
720
+ // Try to find an item whose label matches the input value. A matching item is searched from
721
+ // the filteredItems array (if available) and the selectedItem (if available).
722
+ const itemMatchingByLabel = [...(this.filteredItems || []), this.selectedItem].filter((item) => {
723
+ return toLowerCase(this._getItemLabel(item)) === toLowerCase(this._inputElementValue);
724
+ })[0];
725
+
710
726
  if (this.allowCustomValue
711
727
  // to prevent a repetitive input value being saved after pressing ESC and Tab.
712
- && !itemsMatchedByLabel.length) {
728
+ && !itemMatchingByLabel) {
713
729
 
730
+ // An item matching by label was not found, but custom values are allowed.
731
+ // Dispatch a custom-value-set event with the input value.
714
732
  const e = new CustomEvent('custom-value-set', {detail: this._inputElementValue, composed: true, cancelable: true, bubbles: true});
715
733
  this.dispatchEvent(e);
716
734
  if (!e.defaultPrevented) {
@@ -718,9 +736,11 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
718
736
  this._selectItemForValue(customValue);
719
737
  this.value = customValue;
720
738
  }
721
- } else if (!this.allowCustomValue && !this.opened && itemsMatchedByLabel.length > 0) {
722
- this.value = this._getItemValue(itemsMatchedByLabel[0]);
739
+ } else if (!this.allowCustomValue && !this.opened && itemMatchingByLabel) {
740
+ // An item matching by label was found, select it.
741
+ this.value = this._getItemValue(itemMatchingByLabel);
723
742
  } else {
743
+ // Revert the input value
724
744
  this._inputElementValue = this.selectedItem ? this._getItemLabel(this.selectedItem) : (this.value || '');
725
745
  }
726
746
  }
@@ -755,6 +775,10 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
755
775
  }
756
776
  }
757
777
 
778
+ _inputElementValueChanged(inputElementValue) {
779
+ this._hasInputValue = inputElementValue != null ? inputElementValue.length > 0 : false;
780
+ }
781
+
758
782
  /** @private */
759
783
  _filterFromInput(e) {
760
784
  if (!this.opened && !e.__fromClearButton && !this.autoOpenDisabled) {
@@ -1082,12 +1106,49 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
1082
1106
  }
1083
1107
 
1084
1108
  /**
1085
- * Returns true if `value` is valid, and sets the `invalid` flag appropriately.
1109
+ * Observer to notify about the change of private property.
1110
+ *
1111
+ * @private
1112
+ */
1113
+ _hasInputValueChanged(hasValue, oldHasValue) {
1114
+ if (hasValue || oldHasValue) {
1115
+ this.dispatchEvent(new CustomEvent('has-input-value-changed'));
1116
+ }
1117
+ }
1118
+
1119
+ /**
1120
+ * @param {boolean} invalid
1121
+ * @protected
1122
+ */
1123
+ _setInvalid(invalid) {
1124
+ if (this._shouldSetInvalid(invalid)) {
1125
+ this.invalid = invalid;
1126
+ }
1127
+ }
1128
+
1129
+ /**
1130
+ * Override this method to define whether the given `invalid` state should be set.
1131
+ *
1132
+ * @param {boolean} _invalid
1133
+ * @return {boolean}
1134
+ * @protected
1135
+ */
1136
+ _shouldSetInvalid(_invalid) {
1137
+ return true;
1138
+ }
1139
+
1140
+ /**
1141
+ * Validates the field and sets the `invalid` property based on the result.
1142
+ *
1143
+ * The method fires a `validated` event with the result of the validation.
1086
1144
  *
1087
1145
  * @return {boolean} True if the value is valid and sets the `invalid` flag appropriately
1088
1146
  */
1089
1147
  validate() {
1090
- return !(this.invalid = !this.checkValidity());
1148
+ const isValid = this.checkValidity();
1149
+ this._setInvalid(!isValid);
1150
+ this.dispatchEvent(new CustomEvent('validated', {detail: {valid: isValid}}));
1151
+ return isValid;
1091
1152
  }
1092
1153
 
1093
1154
  /**
@@ -1198,4 +1259,12 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
1198
1259
  * To comply with https://developer.mozilla.org/en-US/docs/Web/Events/change
1199
1260
  * @event change
1200
1261
  */
1262
+
1263
+ /**
1264
+ * Fired whenever the field is validated.
1265
+ *
1266
+ * @event validated
1267
+ * @param {Object} detail
1268
+ * @param {boolean} detail.valid the result of the validation.
1269
+ */
1201
1270
  };
@@ -229,7 +229,7 @@ class ComboBoxElement extends
229
229
  }
230
230
 
231
231
  static get version() {
232
- return '5.4.11';
232
+ return '5.5.0';
233
233
  }
234
234
 
235
235
  static get properties() {