@vaadin/combo-box 24.2.0-alpha4 → 24.2.0-dev.385a0a5b2

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": "24.2.0-alpha4",
3
+ "version": "24.2.0-dev.385a0a5b2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -38,21 +38,21 @@
38
38
  "dependencies": {
39
39
  "@open-wc/dedupe-mixin": "^1.3.0",
40
40
  "@polymer/polymer": "^3.0.0",
41
- "@vaadin/a11y-base": "24.2.0-alpha4",
42
- "@vaadin/component-base": "24.2.0-alpha4",
43
- "@vaadin/field-base": "24.2.0-alpha4",
44
- "@vaadin/input-container": "24.2.0-alpha4",
45
- "@vaadin/item": "24.2.0-alpha4",
46
- "@vaadin/lit-renderer": "24.2.0-alpha4",
47
- "@vaadin/overlay": "24.2.0-alpha4",
48
- "@vaadin/vaadin-lumo-styles": "24.2.0-alpha4",
49
- "@vaadin/vaadin-material-styles": "24.2.0-alpha4",
50
- "@vaadin/vaadin-themable-mixin": "24.2.0-alpha4"
41
+ "@vaadin/a11y-base": "24.2.0-dev.385a0a5b2",
42
+ "@vaadin/component-base": "24.2.0-dev.385a0a5b2",
43
+ "@vaadin/field-base": "24.2.0-dev.385a0a5b2",
44
+ "@vaadin/input-container": "24.2.0-dev.385a0a5b2",
45
+ "@vaadin/item": "24.2.0-dev.385a0a5b2",
46
+ "@vaadin/lit-renderer": "24.2.0-dev.385a0a5b2",
47
+ "@vaadin/overlay": "24.2.0-dev.385a0a5b2",
48
+ "@vaadin/vaadin-lumo-styles": "24.2.0-dev.385a0a5b2",
49
+ "@vaadin/vaadin-material-styles": "24.2.0-dev.385a0a5b2",
50
+ "@vaadin/vaadin-themable-mixin": "24.2.0-dev.385a0a5b2"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@esm-bundle/chai": "^4.3.4",
54
- "@vaadin/testing-helpers": "^0.4.2",
55
- "@vaadin/text-field": "24.2.0-alpha4",
54
+ "@vaadin/testing-helpers": "^0.4.3",
55
+ "@vaadin/text-field": "24.2.0-dev.385a0a5b2",
56
56
  "lit": "^2.0.0",
57
57
  "sinon": "^13.0.2"
58
58
  },
@@ -60,5 +60,5 @@
60
60
  "web-types.json",
61
61
  "web-types.lit.json"
62
62
  ],
63
- "gitHead": "aaf7c5ebfea62628210eead4229be1718ac6b129"
63
+ "gitHead": "9d84e4049890430a33e91ff64a6e751a1ba9b9d9"
64
64
  }
@@ -3,8 +3,8 @@
3
3
  * Copyright (c) 2017 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import type { TemplateResult } from 'lit';
7
6
  import type { DirectiveResult } from 'lit/directive.js';
7
+ import type { LitRendererResult } from '@vaadin/lit-renderer';
8
8
  import { LitRendererDirective } from '@vaadin/lit-renderer';
9
9
  import type { ComboBox, ComboBoxItemModel } from '../vaadin-combo-box.js';
10
10
 
@@ -12,7 +12,7 @@ export type ComboBoxLitRenderer<TItem> = (
12
12
  item: TItem,
13
13
  model: ComboBoxItemModel<TItem>,
14
14
  comboBox: ComboBox<TItem>,
15
- ) => TemplateResult;
15
+ ) => LitRendererResult;
16
16
 
17
17
  export class ComboBoxRendererDirective<TItem> extends LitRendererDirective<ComboBox, ComboBoxLitRenderer<TItem>> {
18
18
  /**
@@ -4,6 +4,7 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import type { DisabledMixinClass } from '@vaadin/a11y-base/src/disabled-mixin.js';
7
+ import type { FocusMixinClass } from '@vaadin/a11y-base/src/focus-mixin.js';
7
8
  import type { KeyboardMixinClass } from '@vaadin/a11y-base/src/keyboard-mixin.js';
8
9
  import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
9
10
  import type { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
@@ -152,6 +153,7 @@ interface ComboBoxLight<TItem = ComboBoxDefaultItem>
152
153
  InputMixinClass,
153
154
  DisabledMixinClass,
154
155
  ThemableMixinClass,
156
+ FocusMixinClass,
155
157
  ThemePropertyMixinClass,
156
158
  ValidateMixinClass {}
157
159
 
@@ -180,7 +180,7 @@ class ComboBoxLight extends ComboBoxDataProviderMixin(ComboBoxMixin(ValidateMixi
180
180
  * @return {boolean}
181
181
  */
182
182
  checkValidity() {
183
- if (this.inputElement.validate) {
183
+ if (this.inputElement && this.inputElement.validate) {
184
184
  return this.inputElement.validate();
185
185
  }
186
186
  return super.checkValidity();
@@ -199,16 +199,16 @@ class ComboBoxLight extends ComboBoxDataProviderMixin(ComboBoxMixin(ValidateMixi
199
199
  * @protected
200
200
  * @override
201
201
  */
202
- _onFocusout(event) {
202
+ _shouldRemoveFocus(event) {
203
203
  const isBlurringControlButtons = event.target === this._toggleElement || event.target === this.clearElement;
204
204
  const isFocusingInputElement = event.relatedTarget && event.relatedTarget === this._nativeInput;
205
205
 
206
206
  // prevent closing the overlay when moving focus from clear or toggle buttons to the internal input
207
207
  if (isBlurringControlButtons && isFocusingInputElement) {
208
- return;
208
+ return false;
209
209
  }
210
210
 
211
- super._onFocusout(event);
211
+ return super._shouldRemoveFocus(event);
212
212
  }
213
213
  }
214
214
 
@@ -5,9 +5,11 @@
5
5
  */
6
6
  import type { Constructor } from '@open-wc/dedupe-mixin';
7
7
  import type { DisabledMixinClass } from '@vaadin/a11y-base/src/disabled-mixin.js';
8
+ import type { FocusMixinClass } from '@vaadin/a11y-base/src/focus-mixin.js';
8
9
  import type { KeyboardMixinClass } from '@vaadin/a11y-base/src/keyboard-mixin.js';
9
10
  import type { OverlayClassMixinClass } from '@vaadin/component-base/src/overlay-class-mixin.js';
10
11
  import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
12
+ import type { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
11
13
  import type { ComboBox } from './vaadin-combo-box.js';
12
14
  import type { ComboBoxDefaultItem, ComboBoxItemModel, ComboBoxItemRenderer } from './vaadin-combo-box-item-mixin.js';
13
15
 
@@ -19,9 +21,11 @@ export declare function ComboBoxMixin<TItem, T extends Constructor<HTMLElement>>
19
21
  base: T,
20
22
  ): Constructor<ComboBoxMixinClass<TItem>> &
21
23
  Constructor<DisabledMixinClass> &
24
+ Constructor<FocusMixinClass> &
22
25
  Constructor<InputMixinClass> &
23
26
  Constructor<KeyboardMixinClass> &
24
27
  Constructor<OverlayClassMixinClass> &
28
+ Constructor<ValidateMixinClass> &
25
29
  T;
26
30
 
27
31
  export declare class ComboBoxMixinClass<TItem> {
@@ -4,6 +4,7 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
7
+ import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
7
8
  import { isElementFocused } from '@vaadin/a11y-base/src/focus-utils.js';
8
9
  import { KeyboardMixin } from '@vaadin/a11y-base/src/keyboard-mixin.js';
9
10
  import { isTouch } from '@vaadin/component-base/src/browser-utils.js';
@@ -11,6 +12,7 @@ import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js'
11
12
  import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
12
13
  import { processTemplates } from '@vaadin/component-base/src/templates.js';
13
14
  import { InputMixin } from '@vaadin/field-base/src/input-mixin.js';
15
+ import { ValidateMixin } from '@vaadin/field-base/src/validate-mixin.js';
14
16
  import { VirtualKeyboardController } from '@vaadin/field-base/src/virtual-keyboard-controller.js';
15
17
  import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
16
18
 
@@ -45,15 +47,17 @@ function findItemIndex(items, callback) {
45
47
  /**
46
48
  * @polymerMixin
47
49
  * @mixes ControllerMixin
50
+ * @mixes ValidateMixin
48
51
  * @mixes DisabledMixin
49
52
  * @mixes InputMixin
50
53
  * @mixes KeyboardMixin
54
+ * @mixes FocusMixin
51
55
  * @mixes OverlayClassMixin
52
56
  * @param {function(new:HTMLElement)} subclass
53
57
  */
54
58
  export const ComboBoxMixin = (subclass) =>
55
59
  class ComboBoxMixinClass extends OverlayClassMixin(
56
- ControllerMixin(KeyboardMixin(InputMixin(DisabledMixin(subclass)))),
60
+ ControllerMixin(ValidateMixin(FocusMixin(KeyboardMixin(InputMixin(DisabledMixin(subclass)))))),
57
61
  ) {
58
62
  static get properties() {
59
63
  return {
@@ -253,7 +257,6 @@ export const ComboBoxMixin = (subclass) =>
253
257
 
254
258
  constructor() {
255
259
  super();
256
- this._boundOnFocusout = this._onFocusout.bind(this);
257
260
  this._boundOverlaySelectedItemChanged = this._overlaySelectedItemChanged.bind(this);
258
261
  this._boundOnClearButtonMouseDown = this.__onClearButtonMouseDown.bind(this);
259
262
  this._boundOnClick = this._onClick.bind(this);
@@ -320,8 +323,6 @@ export const ComboBoxMixin = (subclass) =>
320
323
  this._initOverlay();
321
324
  this._initScroller();
322
325
 
323
- this.addEventListener('focusout', this._boundOnFocusout);
324
-
325
326
  this._lastCommittedValue = this.value;
326
327
 
327
328
  this.addEventListener('click', this._boundOnClick);
@@ -1085,6 +1086,12 @@ export const ComboBoxMixin = (subclass) =>
1085
1086
 
1086
1087
  /** @private */
1087
1088
  _detectAndDispatchChange() {
1089
+ // Do not validate when focusout is caused by document
1090
+ // losing focus, which happens on browser tab switch.
1091
+ if (document.hasFocus()) {
1092
+ this.validate();
1093
+ }
1094
+
1088
1095
  if (this.value !== this._lastCommittedValue) {
1089
1096
  this.dispatchEvent(new CustomEvent('change', { bubbles: true }));
1090
1097
  this._lastCommittedValue = this.value;
@@ -1227,20 +1234,18 @@ export const ComboBoxMixin = (subclass) =>
1227
1234
  }
1228
1235
  }
1229
1236
 
1230
- /** @private */
1231
- _onFocusout(event) {
1232
- // VoiceOver on iOS fires `focusout` event when moving focus to the item in the dropdown.
1233
- // Do not focus the input in this case, because it would break announcement for the item.
1234
- if (event.relatedTarget && event.relatedTarget.localName === `${this._tagNamePrefix}-item`) {
1235
- return;
1236
- }
1237
+ /**
1238
+ * Override method inherited from `FocusMixin`
1239
+ * to close the overlay on blur and commit the value.
1240
+ *
1241
+ * @param {boolean} focused
1242
+ * @protected
1243
+ * @override
1244
+ */
1245
+ _setFocused(focused) {
1246
+ super._setFocused(focused);
1237
1247
 
1238
- // Fixes the problem with `focusout` happening when clicking on the scroll bar on Edge
1239
- if (event.relatedTarget === this._overlayElement) {
1240
- event.composedPath()[0].focus();
1241
- return;
1242
- }
1243
- if (!this.readonly && !this._closeOnBlurIsPrevented) {
1248
+ if (!focused && !this.readonly && !this._closeOnBlurIsPrevented) {
1244
1249
  // User's logic in `custom-value-set` event listener might cause input to blur,
1245
1250
  // which will result in attempting to commit the same custom value once again.
1246
1251
  if (!this.opened && this.allowCustomValue && this._inputElementValue === this._lastCustomValue) {
@@ -1252,6 +1257,32 @@ export const ComboBoxMixin = (subclass) =>
1252
1257
  }
1253
1258
  }
1254
1259
 
1260
+ /**
1261
+ * Override method inherited from `FocusMixin` to not remove focused
1262
+ * state when focus moves to the overlay.
1263
+ *
1264
+ * @param {FocusEvent} event
1265
+ * @return {boolean}
1266
+ * @protected
1267
+ * @override
1268
+ */
1269
+ _shouldRemoveFocus(event) {
1270
+ // VoiceOver on iOS fires `focusout` event when moving focus to the item in the dropdown.
1271
+ // Do not focus the input in this case, because it would break announcement for the item.
1272
+ if (event.relatedTarget && event.relatedTarget.localName === `${this._tagNamePrefix}-item`) {
1273
+ return false;
1274
+ }
1275
+
1276
+ // Do not blur when focus moves to the overlay
1277
+ // Also, fixes the problem with `focusout` happening when clicking on the scroll bar on Edge
1278
+ if (event.relatedTarget === this._overlayElement) {
1279
+ event.composedPath()[0].focus();
1280
+ return false;
1281
+ }
1282
+
1283
+ return true;
1284
+ }
1285
+
1255
1286
  /** @private */
1256
1287
  _onTouchend(event) {
1257
1288
  if (!this.clearElement || event.composedPath()[0] !== this.clearElement) {
@@ -3,13 +3,15 @@
3
3
  * Copyright (c) 2015 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { Overlay } from '@vaadin/overlay/src/vaadin-overlay.js';
6
+ import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
7
+ import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
8
+ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
7
9
  import { ComboBoxOverlayMixin } from './vaadin-combo-box-overlay-mixin.js';
8
10
 
9
11
  /**
10
12
  * An element used internally by `<vaadin-combo-box>`. Not intended to be used separately.
11
13
  */
12
- declare class ComboBoxOverlay extends ComboBoxOverlayMixin(Overlay) {}
14
+ declare class ComboBoxOverlay extends ComboBoxOverlayMixin(OverlayMixin(DirMixin(ThemableMixin(HTMLElement)))) {}
13
15
 
14
16
  declare global {
15
17
  interface HTMLElementTagNameMap {
@@ -3,54 +3,52 @@
3
3
  * Copyright (c) 2015 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { Overlay } from '@vaadin/overlay/src/vaadin-overlay.js';
7
- import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
6
+ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
7
+ import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
8
+ import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
9
+ import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
10
+ import { css, registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
8
11
  import { ComboBoxOverlayMixin } from './vaadin-combo-box-overlay-mixin.js';
9
12
 
10
- registerStyles(
11
- 'vaadin-combo-box-overlay',
12
- css`
13
- #overlay {
14
- width: var(--vaadin-combo-box-overlay-width, var(--_vaadin-combo-box-overlay-default-width, auto));
15
- }
13
+ const comboBoxOverlayStyles = css`
14
+ #overlay {
15
+ width: var(--vaadin-combo-box-overlay-width, var(--_vaadin-combo-box-overlay-default-width, auto));
16
+ }
16
17
 
17
- [part='content'] {
18
- display: flex;
19
- flex-direction: column;
20
- height: 100%;
21
- }
22
- `,
23
- { moduleId: 'vaadin-combo-box-overlay-styles' },
24
- );
18
+ [part='content'] {
19
+ display: flex;
20
+ flex-direction: column;
21
+ height: 100%;
22
+ }
23
+ `;
25
24
 
26
- let memoizedTemplate;
25
+ registerStyles('vaadin-combo-box-overlay', [overlayStyles, comboBoxOverlayStyles], {
26
+ moduleId: 'vaadin-combo-box-overlay-styles',
27
+ });
27
28
 
28
29
  /**
29
30
  * An element used internally by `<vaadin-combo-box>`. Not intended to be used separately.
30
31
  *
31
- * @extends Overlay
32
+ * @extends HTMLElement
32
33
  * @mixes ComboBoxOverlayMixin
34
+ * @mixes DirMixin
35
+ * @mixes OverlayMixin
36
+ * @mixes ThemableMixin
33
37
  * @private
34
38
  */
35
- export class ComboBoxOverlay extends ComboBoxOverlayMixin(Overlay) {
39
+ export class ComboBoxOverlay extends ComboBoxOverlayMixin(OverlayMixin(DirMixin(ThemableMixin(PolymerElement)))) {
36
40
  static get is() {
37
41
  return 'vaadin-combo-box-overlay';
38
42
  }
39
43
 
40
44
  static get template() {
41
- if (!memoizedTemplate) {
42
- memoizedTemplate = super.template.cloneNode(true);
43
-
44
- const overlay = memoizedTemplate.content.querySelector('[part~="overlay"]');
45
- overlay.removeAttribute('tabindex');
46
-
47
- const loader = document.createElement('div');
48
- loader.setAttribute('part', 'loader');
49
-
50
- overlay.insertBefore(loader, overlay.firstElementChild);
51
- }
52
-
53
- return memoizedTemplate;
45
+ return html`
46
+ <div id="backdrop" part="backdrop" hidden></div>
47
+ <div part="overlay" id="overlay">
48
+ <div part="loader"></div>
49
+ <div part="content" id="content"><slot></slot></div>
50
+ </div>
51
+ `;
54
52
  }
55
53
  }
56
54
 
@@ -254,40 +254,6 @@ class ComboBox extends ComboBoxDataProviderMixin(
254
254
  this._toggleElement = this.$.toggleButton;
255
255
  }
256
256
 
257
- /**
258
- * Override method inherited from `FocusMixin` to validate on blur.
259
- * @param {boolean} focused
260
- * @protected
261
- * @override
262
- */
263
- _setFocused(focused) {
264
- super._setFocused(focused);
265
-
266
- // Do not validate when focusout is caused by document
267
- // losing focus, which happens on browser tab switch.
268
- if (!focused && document.hasFocus()) {
269
- this.validate();
270
- }
271
- }
272
-
273
- /**
274
- * Override method inherited from `FocusMixin` to not remove focused
275
- * state when focus moves to the overlay.
276
- * @param {FocusEvent} event
277
- * @return {boolean}
278
- * @protected
279
- * @override
280
- */
281
- _shouldRemoveFocus(event) {
282
- // Do not blur when focus moves to the overlay
283
- if (event.relatedTarget === this._overlayElement) {
284
- event.composedPath()[0].focus();
285
- return false;
286
- }
287
-
288
- return true;
289
- }
290
-
291
257
  /**
292
258
  * Override the method from `InputControlMixin`
293
259
  * to stop event propagation to prevent `ComboBoxMixin`
@@ -1,7 +1,6 @@
1
1
  import '@vaadin/vaadin-lumo-styles/color.js';
2
2
  import '@vaadin/vaadin-lumo-styles/spacing.js';
3
3
  import '@vaadin/vaadin-lumo-styles/style.js';
4
- import '@vaadin/overlay/theme/lumo/vaadin-overlay.js';
5
4
  import { loader } from '@vaadin/vaadin-lumo-styles/mixins/loader.js';
6
5
  import { menuOverlayCore } from '@vaadin/vaadin-lumo-styles/mixins/menu-overlay.js';
7
6
  import { overlay } from '@vaadin/vaadin-lumo-styles/mixins/overlay.js';
@@ -1,5 +1,4 @@
1
1
  import '@vaadin/vaadin-material-styles/color.js';
2
- import '@vaadin/overlay/theme/material/vaadin-overlay.js';
3
2
  import { loader } from '@vaadin/vaadin-material-styles/mixins/loader.js';
4
3
  import { menuOverlay } from '@vaadin/vaadin-material-styles/mixins/menu-overlay.js';
5
4
  import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';