@vaadin/combo-box 23.0.0-alpha3 → 23.0.0-beta2

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/combo-box",
3
- "version": "23.0.0-alpha3",
3
+ "version": "23.0.0-beta2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -17,6 +17,7 @@
17
17
  "url": "https://github.com/vaadin/web-components/issues"
18
18
  },
19
19
  "main": "vaadin-combo-box.js",
20
+ "type": "module",
20
21
  "files": [
21
22
  "src",
22
23
  "theme",
@@ -33,23 +34,23 @@
33
34
  "dependencies": {
34
35
  "@open-wc/dedupe-mixin": "^1.3.0",
35
36
  "@polymer/polymer": "^3.0.0",
36
- "@vaadin/component-base": "23.0.0-alpha3",
37
- "@vaadin/field-base": "23.0.0-alpha3",
38
- "@vaadin/input-container": "23.0.0-alpha3",
39
- "@vaadin/item": "23.0.0-alpha3",
40
- "@vaadin/vaadin-lumo-styles": "23.0.0-alpha3",
41
- "@vaadin/vaadin-material-styles": "23.0.0-alpha3",
42
- "@vaadin/vaadin-overlay": "23.0.0-alpha3",
43
- "@vaadin/vaadin-themable-mixin": "23.0.0-alpha3"
37
+ "@vaadin/component-base": "23.0.0-beta2",
38
+ "@vaadin/field-base": "23.0.0-beta2",
39
+ "@vaadin/input-container": "23.0.0-beta2",
40
+ "@vaadin/item": "23.0.0-beta2",
41
+ "@vaadin/vaadin-lumo-styles": "23.0.0-beta2",
42
+ "@vaadin/vaadin-material-styles": "23.0.0-beta2",
43
+ "@vaadin/vaadin-overlay": "23.0.0-beta2",
44
+ "@vaadin/vaadin-themable-mixin": "23.0.0-beta2"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@esm-bundle/chai": "^4.3.4",
47
- "@vaadin/dialog": "23.0.0-alpha3",
48
- "@vaadin/polymer-legacy-adapter": "23.0.0-alpha3",
48
+ "@vaadin/dialog": "23.0.0-beta2",
49
+ "@vaadin/polymer-legacy-adapter": "23.0.0-beta2",
49
50
  "@vaadin/testing-helpers": "^0.3.2",
50
- "@vaadin/text-field": "23.0.0-alpha3",
51
+ "@vaadin/text-field": "23.0.0-beta2",
51
52
  "lit": "^2.0.0",
52
53
  "sinon": "^9.2.0"
53
54
  },
54
- "gitHead": "490037919a9e054cc002c1b3be0c94a1603e1a44"
55
+ "gitHead": "a276f7a0fd00e5459b87267468e0dd0d4fb6f7f3"
55
56
  }
@@ -313,6 +313,8 @@ export const ComboBoxMixin = (subclass) =>
313
313
  return;
314
314
  }
315
315
 
316
+ this.$.dropdown._scroller.requestContentUpdate();
317
+
316
318
  this._getItemElements().forEach((item) => {
317
319
  item.requestContentUpdate();
318
320
  });
@@ -414,6 +416,21 @@ export const ComboBoxMixin = (subclass) =>
414
416
  _handleClearButtonClick(event) {
415
417
  event.preventDefault();
416
418
  this._clear();
419
+
420
+ // De-select dropdown item
421
+ if (this.opened) {
422
+ this.requestContentUpdate();
423
+ }
424
+ }
425
+
426
+ /**
427
+ * @param {Event} event
428
+ * @protected
429
+ */
430
+ _onHostClick(_event) {
431
+ if (!this.autoOpenDisabled) {
432
+ this.open();
433
+ }
417
434
  }
418
435
 
419
436
  /** @private */
@@ -430,8 +447,8 @@ export const ComboBoxMixin = (subclass) =>
430
447
  } else {
431
448
  this.open();
432
449
  }
433
- } else if (!this.autoOpenDisabled) {
434
- this.open();
450
+ } else {
451
+ this._onHostClick(e);
435
452
  }
436
453
 
437
454
  this._closeOnBlurIsPrevented = false;
@@ -695,17 +712,20 @@ export const ComboBoxMixin = (subclass) =>
695
712
  }
696
713
  } else {
697
714
  const toLowerCase = (item) => item && item.toLowerCase && item.toLowerCase();
698
- const itemsMatchedByLabel =
699
- (this.filteredItems &&
700
- this.filteredItems.filter(
701
- (item) => toLowerCase(this._getItemLabel(item)) === toLowerCase(this._inputElementValue)
702
- )) ||
703
- [];
715
+
716
+ // Try to find an item whose label matches the input value. A matching item is searched from
717
+ // the filteredItems array (if available) and the selectedItem (if available).
718
+ const itemMatchingByLabel = [...(this.filteredItems || []), this.selectedItem].find((item) => {
719
+ return toLowerCase(this._getItemLabel(item)) === toLowerCase(this._inputElementValue);
720
+ });
721
+
704
722
  if (
705
723
  this.allowCustomValue &&
706
724
  // to prevent a repetitive input value being saved after pressing ESC and Tab.
707
- !itemsMatchedByLabel.length
725
+ !itemMatchingByLabel
708
726
  ) {
727
+ // An item matching by label was not found, but custom values are allowed.
728
+ // Dispatch a custom-value-set event with the input value.
709
729
  const e = new CustomEvent('custom-value-set', {
710
730
  detail: this._inputElementValue,
711
731
  composed: true,
@@ -718,9 +738,11 @@ export const ComboBoxMixin = (subclass) =>
718
738
  this._selectItemForValue(customValue);
719
739
  this.value = customValue;
720
740
  }
721
- } else if (!this.allowCustomValue && !this.opened && itemsMatchedByLabel.length > 0) {
722
- this.value = this._getItemValue(itemsMatchedByLabel[0]);
741
+ } else if (!this.allowCustomValue && !this.opened && itemMatchingByLabel) {
742
+ // An item matching by label was found, select it.
743
+ this.value = this._getItemValue(itemMatchingByLabel);
723
744
  } else {
745
+ // Revert the input value
724
746
  this._inputElementValue = this.selectedItem ? this._getItemLabel(this.selectedItem) : this.value || '';
725
747
  }
726
748
  }
@@ -934,10 +956,14 @@ export const ComboBoxMixin = (subclass) =>
934
956
  if (e.path === 'filteredItems' || e.path === 'filteredItems.splices') {
935
957
  this._setOverlayItems(this.filteredItems);
936
958
 
937
- this._focusedIndex =
938
- this.opened || this.autoOpenDisabled
939
- ? this.$.dropdown.indexOfLabel(this.filter)
940
- : this._indexOfValue(this.value, this.filteredItems);
959
+ const filterIndex = this.$.dropdown.indexOfLabel(this.filter);
960
+ if (this.opened) {
961
+ this._focusedIndex = filterIndex;
962
+ } else {
963
+ // Pre-select item matching the filter to focus it later when overlay opens
964
+ const valueIndex = this._indexOfValue(this.value, this.filteredItems);
965
+ this._focusedIndex = filterIndex === -1 ? valueIndex : filterIndex;
966
+ }
941
967
 
942
968
  // see https://github.com/vaadin/web-components/issues/2615
943
969
  if (this.selectedItem === null && this._focusedIndex >= 0) {
@@ -136,8 +136,8 @@ export class ComboBoxScroller extends PolymerElement {
136
136
  }
137
137
 
138
138
  __openedChanged(opened) {
139
- if (this.__virtualizer && opened) {
140
- this.__virtualizer.update();
139
+ if (opened) {
140
+ this.requestContentUpdate();
141
141
  }
142
142
  }
143
143
 
@@ -163,6 +163,12 @@ export class ComboBoxScroller extends PolymerElement {
163
163
  });
164
164
  }
165
165
 
166
+ requestContentUpdate() {
167
+ if (this.__virtualizer) {
168
+ this.__virtualizer.update();
169
+ }
170
+ }
171
+
166
172
  scrollIntoView(index) {
167
173
  if (!(this.opened && index >= 0)) {
168
174
  return;
@@ -232,29 +238,29 @@ export class ComboBoxScroller extends PolymerElement {
232
238
  this.__virtualizer.flush();
233
239
  // Ensure the total count of items is properly announced.
234
240
  this.setAttribute('aria-setsize', items.length);
235
- this.__virtualizer.update();
241
+ this.requestContentUpdate();
236
242
  }
237
243
  }
238
244
 
239
245
  /** @private */
240
246
  __loadingChanged(loading) {
241
247
  if (this.__virtualizer && !loading) {
242
- setTimeout(() => this.__virtualizer.update());
248
+ setTimeout(() => this.requestContentUpdate());
243
249
  }
244
250
  }
245
251
 
246
252
  /** @private */
247
253
  __focusedIndexChanged(index) {
248
254
  if (this.__virtualizer && index >= 0) {
249
- this.__virtualizer.update();
255
+ this.requestContentUpdate();
250
256
  this.scrollIntoView(index);
251
257
  }
252
258
  }
253
259
 
254
260
  /** @private */
255
261
  __rendererChanged(renderer, oldRenderer) {
256
- if (this.__virtualizer && (renderer || oldRenderer)) {
257
- this.__virtualizer.update();
262
+ if (renderer || oldRenderer) {
263
+ this.requestContentUpdate();
258
264
  }
259
265
  }
260
266
 
@@ -183,8 +183,8 @@ class ComboBox extends ComboBoxDataProviderMixin(
183
183
  >
184
184
  <slot name="prefix" slot="prefix"></slot>
185
185
  <slot name="input"></slot>
186
- <div id="clearButton" part="clear-button" slot="suffix"></div>
187
- <div id="toggleButton" part="toggle-button" slot="suffix"></div>
186
+ <div id="clearButton" part="clear-button" slot="suffix" aria-hidden="true"></div>
187
+ <div id="toggleButton" part="toggle-button" slot="suffix" aria-hidden="true"></div>
188
188
  </vaadin-input-container>
189
189
 
190
190
  <div part="helper-text">
@@ -293,6 +293,19 @@ class ComboBox extends ComboBoxDataProviderMixin(
293
293
 
294
294
  this._handleClearButtonClick(event);
295
295
  }
296
+
297
+ /**
298
+ * @param {Event} event
299
+ * @protected
300
+ */
301
+ _onHostClick(event) {
302
+ const path = event.composedPath();
303
+
304
+ // Open dropdown only when clicking on the label or input field
305
+ if (path.includes(this._labelNode) || path.includes(this._positionTarget)) {
306
+ super._onHostClick(event);
307
+ }
308
+ }
296
309
  }
297
310
 
298
311
  customElements.define(ComboBox.is, ComboBox);