@vaadin/vaadin-combo-box 5.4.7 → 5.4.11

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/README.md CHANGED
@@ -1,21 +1,18 @@
1
- [![npm latest version](https://badgen.net/npm/v/@vaadin/vaadin-combo-box/latest)](https://www.npmjs.com/package/@vaadin/vaadin-combo-box)
2
- [![npm next version](https://badgen.net/npm/v/@vaadin/vaadin-combo-box/next)](https://www.npmjs.com/package/@vaadin/vaadin-combo-box)
3
- [![Bower version](https://badgen.net/github/release/vaadin/vaadin-combo-box)](https://github.com/vaadin/vaadin-combo-box/releases)
4
- [![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/vaadin/vaadin-combo-box)
5
- [![Build Status](https://travis-ci.org/vaadin/vaadin-combo-box.svg?branch=master)](https://travis-ci.org/vaadin/vaadin-combo-box)
6
- [![Coverage Status](https://coveralls.io/repos/github/vaadin/vaadin-combo-box/badge.svg?branch=master)](https://coveralls.io/github/vaadin/vaadin-combo-box?branch=master)
7
- [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/vaadin/web-components?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
1
+ # <vaadin-combo-box>
8
2
 
9
- [![Published on Vaadin Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0.svg)](https://vaadin.com/directory/component/vaadinvaadin-combo-box)
10
- [![Stars on vaadin.com/directory](https://img.shields.io/vaadin-directory/star/vaadinvaadin-combo-box.svg)](https://vaadin.com/directory/component/vaadinvaadin-combo-box)
3
+ > ⚠️ Starting from Vaadin 20, the source code and issues for this component are migrated to the [`vaadin/web-components`](https://github.com/vaadin/web-components/tree/master/packages/vaadin-combo-box) monorepository.
4
+ > This repository contains the source code and releases of `<vaadin-combo-box>` for the Vaadin versions 10 to 19.
11
5
 
12
- # &lt;vaadin-combo-box&gt;
6
+ [&lt;vaadin-combo-box&gt;](https://vaadin.com/components/vaadin-combo-box) is a Web Component combining a dropdown list with an input field for filtering the list of items, part of the [Vaadin components](https://vaadin.com/components).
13
7
 
14
8
  [Live Demo ↗](https://vaadin.com/components/vaadin-combo-box/html-examples)
15
9
  |
16
10
  [API documentation ↗](https://vaadin.com/components/vaadin-combo-box/html-api)
17
11
 
18
- [&lt;vaadin-combo-box&gt;](https://vaadin.com/components/vaadin-combo-box) is a Web Component combining a dropdown list with an input field for filtering the list of items, part of the [Vaadin components](https://vaadin.com/components).
12
+ [![npm latest version](https://badgen.net/npm/v/@vaadin/vaadin-combo-box/latest)](https://www.npmjs.com/package/@vaadin/vaadin-combo-box)
13
+ [![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/vaadin/vaadin-combo-box)
14
+ [![Published on Vaadin Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0.svg)](https://vaadin.com/directory/component/vaadinvaadin-combo-box)
15
+ [![Discord](https://img.shields.io/discord/732335336448852018?label=discord)](https://discord.gg/PHmkCKC)
19
16
 
20
17
  <!--
21
18
  ```
@@ -95,18 +92,18 @@ To use the Material theme, import the correspondent file from the `theme/materia
95
92
 
96
93
  - The components with the Lumo theme:
97
94
 
98
- `theme/lumo/vaadin-combo-box.html`
95
+ `theme/lumo/vaadin-combo-box.html`
99
96
  `theme/lumo/vaadin-combo-box-light.html`
100
97
 
101
98
  - The components with the Material theme:
102
99
 
103
- `theme/material/vaadin-combo-box.html`
100
+ `theme/material/vaadin-combo-box.html`
104
101
  `theme/material/vaadin-combo-box-light.html`
105
102
 
106
- - Alias for `theme/lumo/vaadin-combo-box.html`
103
+ - Alias for `theme/lumo/vaadin-combo-box.html`
107
104
  `theme/lumo/vaadin-combo-box-light.html`
108
105
 
109
- `vaadin-combo-box.html`
106
+ `vaadin-combo-box.html`
110
107
  `vaadin-combo-box-light.html`
111
108
 
112
109
 
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.7",
13
+ "version": "5.4.11",
14
14
  "main": "vaadin-combo-box.js",
15
15
  "author": "Vaadin Ltd",
16
16
  "license": "Apache-2.0",
@@ -33,31 +33,31 @@
33
33
  "type-detect": "1.0.0"
34
34
  },
35
35
  "dependencies": {
36
- "@polymer/iron-a11y-keys-behavior": "^3.0.0",
37
36
  "@polymer/iron-a11y-announcer": "^3.0.0",
37
+ "@polymer/iron-a11y-keys-behavior": "^3.0.0",
38
38
  "@polymer/iron-list": "^3.0.0",
39
39
  "@polymer/iron-resizable-behavior": "^3.0.0",
40
40
  "@polymer/polymer": "^3.0.0",
41
41
  "@vaadin/vaadin-control-state-mixin": "^2.2.2",
42
- "@vaadin/vaadin-overlay": "^3.5.0",
43
- "@vaadin/vaadin-text-field": "^2.8.0",
44
- "@vaadin/vaadin-themable-mixin": "^1.6.1",
42
+ "@vaadin/vaadin-element-mixin": "^2.4.1",
43
+ "@vaadin/vaadin-item": "^2.3.0",
45
44
  "@vaadin/vaadin-lumo-styles": "^1.1.1",
46
45
  "@vaadin/vaadin-material-styles": "^1.1.2",
47
- "@vaadin/vaadin-item": "^2.3.0",
48
- "@vaadin/vaadin-element-mixin": "^2.4.1"
46
+ "@vaadin/vaadin-overlay": "^3.5.0",
47
+ "@vaadin/vaadin-text-field": "^2.8.0",
48
+ "@vaadin/vaadin-themable-mixin": "^1.6.1"
49
49
  },
50
50
  "scripts": {
51
51
  "generate-typings": "gen-typescript-declarations --outDir . --verify"
52
52
  },
53
53
  "devDependencies": {
54
- "@polymer/iron-form": "^3.0.0",
55
54
  "@polymer/iron-component-page": "^4.0.0",
55
+ "@polymer/iron-form": "^3.0.0",
56
56
  "@polymer/iron-test-helpers": "^3.0.0",
57
57
  "@polymer/paper-input": "^3.0.0",
58
58
  "@vaadin/vaadin-button": "^2.4.0",
59
- "wct-browser-legacy": "^1.0.1",
60
59
  "@vaadin/vaadin-demo-helpers": "^3.1.0",
61
- "@vaadin/vaadin-dialog": "^2.5.0"
60
+ "@vaadin/vaadin-dialog": "^2.5.0",
61
+ "wct-browser-legacy": "^1.0.1"
62
62
  }
63
63
  }
@@ -23,6 +23,9 @@ $_documentContainer.innerHTML = `<dom-module id="vaadin-combo-box-overlay-styles
23
23
  </dom-module>`;
24
24
 
25
25
  document.head.appendChild($_documentContainer.content);
26
+ let memoizedTemplate;
27
+
28
+
26
29
  /**
27
30
  * The overlay element.
28
31
  *
@@ -41,6 +44,26 @@ class ComboBoxOverlayElement extends OverlayElement {
41
44
  return 'vaadin-combo-box-overlay';
42
45
  }
43
46
 
47
+ static get properties() {
48
+ return {
49
+ /**
50
+ * The element to position/align the dropdown by.
51
+ */
52
+ positionTarget: {
53
+ type: Object
54
+ }
55
+ };
56
+ }
57
+
58
+ static get template() {
59
+ if (!memoizedTemplate) {
60
+ memoizedTemplate = super.template.cloneNode(true);
61
+ memoizedTemplate.content.querySelector('[part~="overlay"]').removeAttribute('tabindex');
62
+ }
63
+
64
+ return memoizedTemplate;
65
+ }
66
+
44
67
  connectedCallback() {
45
68
  super.connectedCallback();
46
69
 
@@ -60,6 +83,19 @@ class ComboBoxOverlayElement extends OverlayElement {
60
83
  const content = this.shadowRoot.querySelector('[part~="content"]');
61
84
  content.parentNode.insertBefore(loader, content);
62
85
  }
86
+
87
+ /**
88
+ * Override OverlayElement._outsideClickListener to prevent closing the
89
+ * overlay when clicking into the combo box input element
90
+ * @param event
91
+ * @private
92
+ */
93
+ _outsideClickListener(event) {
94
+ const eventPath = event.composedPath();
95
+ if (eventPath.indexOf(this.positionTarget) < 0 && eventPath.indexOf(this) < 0) {
96
+ this.close();
97
+ }
98
+ }
63
99
  }
64
100
 
65
101
  customElements.define(ComboBoxOverlayElement.is, ComboBoxOverlayElement);
@@ -83,7 +119,7 @@ class ComboBoxDropdownElement extends DisableUpgradeMixin(
83
119
  display: none;
84
120
  }
85
121
  </style>
86
- <vaadin-combo-box-overlay id="overlay" hidden\$="[[hidden]]" opened="[[opened]]" template="{{template}}" style="align-items: stretch; margin: 0;" theme\$="[[theme]]">
122
+ <vaadin-combo-box-overlay id="overlay" hidden\$="[[hidden]]" position-target="[[positionTarget]]" opened="{{opened}}" template="{{template}}" style="align-items: stretch; margin: 0;" theme\$="[[theme]]">
87
123
  <slot></slot>
88
124
  </vaadin-combo-box-overlay>
89
125
  `;
@@ -130,7 +166,6 @@ class ComboBoxDropdownElement extends DisableUpgradeMixin(
130
166
  constructor() {
131
167
  super();
132
168
  this._boundSetPosition = this._setPosition.bind(this);
133
- this._boundOutsideClickListener = this._outsideClickListener.bind(this);
134
169
  }
135
170
 
136
171
  connectedCallback() {
@@ -186,26 +221,13 @@ class ComboBoxDropdownElement extends DisableUpgradeMixin(
186
221
  this._setPosition();
187
222
 
188
223
  window.addEventListener('scroll', this._boundSetPosition, true);
189
- document.addEventListener('click', this._boundOutsideClickListener, true);
190
224
  this.dispatchEvent(new CustomEvent('vaadin-combo-box-dropdown-opened', {bubbles: true, composed: true}));
191
225
  } else if (!this.__emptyItems) {
192
226
  window.removeEventListener('scroll', this._boundSetPosition, true);
193
- document.removeEventListener('click', this._boundOutsideClickListener, true);
194
227
  this.dispatchEvent(new CustomEvent('vaadin-combo-box-dropdown-closed', {bubbles: true, composed: true}));
195
228
  }
196
229
  }
197
230
 
198
-
199
- // We need to listen on 'click' event and capture it and close the overlay before
200
- // propagating the event to the listener in the button. Otherwise, if the clicked button would call
201
- // open(), this would happen: https://www.youtube.com/watch?v=Z86V_ICUCD4
202
- _outsideClickListener(event) {
203
- const eventPath = event.composedPath();
204
- if (eventPath.indexOf(this.positionTarget) < 0 && eventPath.indexOf(this.$.overlay) < 0) {
205
- this.opened = false;
206
- }
207
- }
208
-
209
231
  _isPositionFixed(element) {
210
232
  const offsetParent = this._getOffsetParent(element);
211
233
 
@@ -260,7 +260,7 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
260
260
  '_filteredItemsChanged(filteredItems.*, itemValuePath, itemLabelPath)',
261
261
  '_templateOrRendererChanged(_itemTemplate, renderer)',
262
262
  '_loadingChanged(loading)',
263
- '_selectedItemChanged(selectedItem, itemLabelPath)',
263
+ '_selectedItemChanged(selectedItem, itemValuePath, itemLabelPath)',
264
264
  '_toggleElementChanged(_toggleElement)'
265
265
  ];
266
266
  }
@@ -576,16 +576,36 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
576
576
  */
577
577
  _onEscape(e) {
578
578
  if (this.autoOpenDisabled) {
579
- this._focusedIndex = -1;
580
- this.cancel();
581
- } else if (this.opened) {
582
- this._stopPropagation(e);
583
-
584
- if (this._focusedIndex > -1) {
579
+ // Auto-open is disabled
580
+ if (this.opened || (this.value !== this._inputElementValue && this._inputElementValue.length > 0)) {
581
+ // The overlay is open or
582
+ // the input value has changed but the change hasn't been committed, so cancel it.
583
+ this._stopPropagation(e);
585
584
  this._focusedIndex = -1;
586
- this._revertInputValue();
587
- } else {
588
585
  this.cancel();
586
+ } else if (this.clearButtonVisible && !this.opened && !!this.value) {
587
+ this._stopPropagation(e);
588
+ // The clear button is visible and the overlay is closed, so clear the value.
589
+ this._clear();
590
+ }
591
+ } else {
592
+ // Auto-open is enabled
593
+ if (this.opened) {
594
+ // The overlay is open
595
+ this._stopPropagation(e);
596
+
597
+ if (this._focusedIndex > -1) {
598
+ // An item is focused, revert the input to the filtered value
599
+ this._focusedIndex = -1;
600
+ this._revertInputValue();
601
+ } else {
602
+ // No item is focused, cancel the change and close the overlay
603
+ this.cancel();
604
+ }
605
+ } else if (this.clearButtonVisible && !!this.value) {
606
+ this._stopPropagation(e);
607
+ // The clear button is visible and the overlay is closed, so clear the value.
608
+ this._clear();
589
609
  }
590
610
  }
591
611
  }
@@ -683,8 +703,9 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
683
703
  this.value = '';
684
704
  }
685
705
  } else {
706
+ const toLowerCase = (item) => item && item.toLowerCase && item.toLowerCase();
686
707
  const itemsMatchedByLabel = this.filteredItems
687
- && this.filteredItems.filter(item => this._getItemLabel(item) === this._inputElementValue)
708
+ && this.filteredItems.filter(item => toLowerCase(this._getItemLabel(item)) === toLowerCase(this._inputElementValue))
688
709
  || [];
689
710
  if (this.allowCustomValue
690
711
  // to prevent a repetitive input value being saved after pressing ESC and Tab.
@@ -697,7 +718,7 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
697
718
  this._selectItemForValue(customValue);
698
719
  this.value = customValue;
699
720
  }
700
- } else if (!this.allowCustomValue && !this.opened && itemsMatchedByLabel.length == 1) {
721
+ } else if (!this.allowCustomValue && !this.opened && itemsMatchedByLabel.length > 0) {
701
722
  this.value = this._getItemValue(itemsMatchedByLabel[0]);
702
723
  } else {
703
724
  this._inputElementValue = this.selectedItem ? this._getItemLabel(this.selectedItem) : (this.value || '');
@@ -1045,7 +1066,7 @@ export const ComboBoxMixin = subclass => class VaadinComboBoxMixinElement extend
1045
1066
  event.composedPath()[0].focus();
1046
1067
  return;
1047
1068
  }
1048
- if (!this._closeOnBlurIsPrevented) {
1069
+ if (!this.readonly && !this._closeOnBlurIsPrevented) {
1049
1070
  this._closeOrCommit();
1050
1071
  }
1051
1072
  }
@@ -229,7 +229,7 @@ class ComboBoxElement extends
229
229
  }
230
230
 
231
231
  static get version() {
232
- return '5.4.7';
232
+ return '5.4.11';
233
233
  }
234
234
 
235
235
  static get properties() {
@@ -358,12 +358,8 @@ class ComboBoxElement extends
358
358
  // Stop propagation of Esc in capturing phase so that
359
359
  // vaadin-text-field will not handle Esc as a shortcut
360
360
  // to clear the value.
361
- // We need to set this listener for "this.inputElement"
362
- // instead of just "this", otherwise keyboard navigation behaviour
363
- // breaks a bit on Safari and some related tests fail.
364
- this.inputElement.addEventListener('keydown', e => {
361
+ this.addEventListener('keydown', e => {
365
362
  if (this._isEventKey(e, 'esc')) {
366
- this._stopPropagation(e);
367
363
  // Trigger _onEscape method of vaadin-combo-box-mixin because
368
364
  // bubbling phase is not reached.
369
365
  this._onEscape(e);