@vaadin/combo-box 24.2.0-alpha1 → 24.2.0-alpha11
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 +14 -14
- package/src/lit/renderer-directives.d.ts +2 -2
- package/src/vaadin-combo-box-light.d.ts +10 -0
- package/src/vaadin-combo-box-light.js +4 -16
- package/src/vaadin-combo-box-mixin.d.ts +4 -0
- package/src/vaadin-combo-box-mixin.js +58 -44
- package/src/vaadin-combo-box-overlay.d.ts +4 -2
- package/src/vaadin-combo-box-overlay.js +30 -32
- package/src/vaadin-combo-box-scroller-mixin.js +2 -1
- package/src/vaadin-combo-box.d.ts +8 -0
- package/src/vaadin-combo-box.js +1 -32
- package/theme/lumo/vaadin-combo-box-overlay-styles.js +0 -1
- package/theme/material/vaadin-combo-box-overlay-styles.js +0 -1
- package/web-types.json +104 -52
- package/web-types.lit.json +52 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/combo-box",
|
|
3
|
-
"version": "24.2.0-
|
|
3
|
+
"version": "24.2.0-alpha11",
|
|
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-
|
|
42
|
-
"@vaadin/component-base": "24.2.0-
|
|
43
|
-
"@vaadin/field-base": "24.2.0-
|
|
44
|
-
"@vaadin/input-container": "24.2.0-
|
|
45
|
-
"@vaadin/item": "24.2.0-
|
|
46
|
-
"@vaadin/lit-renderer": "24.2.0-
|
|
47
|
-
"@vaadin/overlay": "24.2.0-
|
|
48
|
-
"@vaadin/vaadin-lumo-styles": "24.2.0-
|
|
49
|
-
"@vaadin/vaadin-material-styles": "24.2.0-
|
|
50
|
-
"@vaadin/vaadin-themable-mixin": "24.2.0-
|
|
41
|
+
"@vaadin/a11y-base": "24.2.0-alpha11",
|
|
42
|
+
"@vaadin/component-base": "24.2.0-alpha11",
|
|
43
|
+
"@vaadin/field-base": "24.2.0-alpha11",
|
|
44
|
+
"@vaadin/input-container": "24.2.0-alpha11",
|
|
45
|
+
"@vaadin/item": "24.2.0-alpha11",
|
|
46
|
+
"@vaadin/lit-renderer": "24.2.0-alpha11",
|
|
47
|
+
"@vaadin/overlay": "24.2.0-alpha11",
|
|
48
|
+
"@vaadin/vaadin-lumo-styles": "24.2.0-alpha11",
|
|
49
|
+
"@vaadin/vaadin-material-styles": "24.2.0-alpha11",
|
|
50
|
+
"@vaadin/vaadin-themable-mixin": "24.2.0-alpha11"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@esm-bundle/chai": "^4.3.4",
|
|
54
|
-
"@vaadin/testing-helpers": "^0.
|
|
55
|
-
"@vaadin/text-field": "24.2.0-
|
|
54
|
+
"@vaadin/testing-helpers": "^0.5.0",
|
|
55
|
+
"@vaadin/text-field": "24.2.0-alpha11",
|
|
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": "
|
|
63
|
+
"gitHead": "a958207d5f6a09ca0e2dcf9f62194b3f92c8766a"
|
|
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
|
-
) =>
|
|
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';
|
|
@@ -40,6 +41,11 @@ export type ComboBoxLightOpenedChangedEvent = CustomEvent<{ value: boolean }>;
|
|
|
40
41
|
*/
|
|
41
42
|
export type ComboBoxLightInvalidChangedEvent = CustomEvent<{ value: boolean }>;
|
|
42
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Fired when the `dirty` property changes.
|
|
46
|
+
*/
|
|
47
|
+
export type ComboBoxLightDirtyChangedEvent = CustomEvent<{ value: boolean }>;
|
|
48
|
+
|
|
43
49
|
/**
|
|
44
50
|
* Fired when the `value` property changes.
|
|
45
51
|
*/
|
|
@@ -71,6 +77,8 @@ export interface ComboBoxLightEventMap<TItem> extends HTMLElementEventMap {
|
|
|
71
77
|
|
|
72
78
|
'invalid-changed': ComboBoxLightInvalidChangedEvent;
|
|
73
79
|
|
|
80
|
+
'dirty-changed': ComboBoxLightDirtyChangedEvent;
|
|
81
|
+
|
|
74
82
|
'value-changed': ComboBoxLightValueChangedEvent;
|
|
75
83
|
|
|
76
84
|
'selected-item-changed': ComboBoxLightSelectedItemChangedEvent<TItem>;
|
|
@@ -121,6 +129,7 @@ export interface ComboBoxLightEventMap<TItem> extends HTMLElementEventMap {
|
|
|
121
129
|
* @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
|
|
122
130
|
* @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
|
|
123
131
|
* @fires {CustomEvent} selected-item-changed - Fired when the `selectedItem` property changes.
|
|
132
|
+
* @fires {CustomEvent} dirty-changed - Fired when the `dirty` property changes.
|
|
124
133
|
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
125
134
|
* @fires {CustomEvent} validated - Fired whenever the field is validated.
|
|
126
135
|
*/
|
|
@@ -152,6 +161,7 @@ interface ComboBoxLight<TItem = ComboBoxDefaultItem>
|
|
|
152
161
|
InputMixinClass,
|
|
153
162
|
DisabledMixinClass,
|
|
154
163
|
ThemableMixinClass,
|
|
164
|
+
FocusMixinClass,
|
|
155
165
|
ThemePropertyMixinClass,
|
|
156
166
|
ValidateMixinClass {}
|
|
157
167
|
|
|
@@ -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();
|
|
@@ -195,32 +195,20 @@ class ComboBoxLight extends ComboBoxDataProviderMixin(ComboBoxMixin(ValidateMixi
|
|
|
195
195
|
);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
/**
|
|
199
|
-
* @param {!Event} event
|
|
200
|
-
* @protected
|
|
201
|
-
*/
|
|
202
|
-
_onChange(event) {
|
|
203
|
-
super._onChange(event);
|
|
204
|
-
|
|
205
|
-
if (this._isClearButton(event)) {
|
|
206
|
-
this._onClearAction();
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
198
|
/**
|
|
211
199
|
* @protected
|
|
212
200
|
* @override
|
|
213
201
|
*/
|
|
214
|
-
|
|
202
|
+
_shouldRemoveFocus(event) {
|
|
215
203
|
const isBlurringControlButtons = event.target === this._toggleElement || event.target === this.clearElement;
|
|
216
204
|
const isFocusingInputElement = event.relatedTarget && event.relatedTarget === this._nativeInput;
|
|
217
205
|
|
|
218
206
|
// prevent closing the overlay when moving focus from clear or toggle buttons to the internal input
|
|
219
207
|
if (isBlurringControlButtons && isFocusingInputElement) {
|
|
220
|
-
return;
|
|
208
|
+
return false;
|
|
221
209
|
}
|
|
222
210
|
|
|
223
|
-
super.
|
|
211
|
+
return super._shouldRemoveFocus(event);
|
|
224
212
|
}
|
|
225
213
|
}
|
|
226
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,13 +4,16 @@
|
|
|
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';
|
|
10
11
|
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
11
12
|
import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
|
|
13
|
+
import { get } from '@vaadin/component-base/src/path-utils.js';
|
|
12
14
|
import { processTemplates } from '@vaadin/component-base/src/templates.js';
|
|
13
15
|
import { InputMixin } from '@vaadin/field-base/src/input-mixin.js';
|
|
16
|
+
import { ValidateMixin } from '@vaadin/field-base/src/validate-mixin.js';
|
|
14
17
|
import { VirtualKeyboardController } from '@vaadin/field-base/src/virtual-keyboard-controller.js';
|
|
15
18
|
import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
|
|
16
19
|
|
|
@@ -45,15 +48,17 @@ function findItemIndex(items, callback) {
|
|
|
45
48
|
/**
|
|
46
49
|
* @polymerMixin
|
|
47
50
|
* @mixes ControllerMixin
|
|
51
|
+
* @mixes ValidateMixin
|
|
48
52
|
* @mixes DisabledMixin
|
|
49
53
|
* @mixes InputMixin
|
|
50
54
|
* @mixes KeyboardMixin
|
|
55
|
+
* @mixes FocusMixin
|
|
51
56
|
* @mixes OverlayClassMixin
|
|
52
57
|
* @param {function(new:HTMLElement)} subclass
|
|
53
58
|
*/
|
|
54
59
|
export const ComboBoxMixin = (subclass) =>
|
|
55
60
|
class ComboBoxMixinClass extends OverlayClassMixin(
|
|
56
|
-
ControllerMixin(KeyboardMixin(InputMixin(DisabledMixin(subclass)))),
|
|
61
|
+
ControllerMixin(ValidateMixin(FocusMixin(KeyboardMixin(InputMixin(DisabledMixin(subclass)))))),
|
|
57
62
|
) {
|
|
58
63
|
static get properties() {
|
|
59
64
|
return {
|
|
@@ -253,7 +258,6 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
253
258
|
|
|
254
259
|
constructor() {
|
|
255
260
|
super();
|
|
256
|
-
this._boundOnFocusout = this._onFocusout.bind(this);
|
|
257
261
|
this._boundOverlaySelectedItemChanged = this._overlaySelectedItemChanged.bind(this);
|
|
258
262
|
this._boundOnClearButtonMouseDown = this.__onClearButtonMouseDown.bind(this);
|
|
259
263
|
this._boundOnClick = this._onClick.bind(this);
|
|
@@ -320,8 +324,6 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
320
324
|
this._initOverlay();
|
|
321
325
|
this._initScroller();
|
|
322
326
|
|
|
323
|
-
this.addEventListener('focusout', this._boundOnFocusout);
|
|
324
|
-
|
|
325
327
|
this._lastCommittedValue = this.value;
|
|
326
328
|
|
|
327
329
|
this.addEventListener('click', this._boundOnClick);
|
|
@@ -660,7 +662,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
660
662
|
|
|
661
663
|
/** @private */
|
|
662
664
|
_getItemLabel(item) {
|
|
663
|
-
let label = item && this.itemLabelPath ?
|
|
665
|
+
let label = item && this.itemLabelPath ? get(this.itemLabelPath, item) : undefined;
|
|
664
666
|
if (label === undefined || label === null) {
|
|
665
667
|
label = item ? item.toString() : '';
|
|
666
668
|
}
|
|
@@ -669,7 +671,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
669
671
|
|
|
670
672
|
/** @private */
|
|
671
673
|
_getItemValue(item) {
|
|
672
|
-
let value = item && this.itemValuePath ?
|
|
674
|
+
let value = item && this.itemValuePath ? get(this.itemValuePath, item) : undefined;
|
|
673
675
|
if (value === undefined) {
|
|
674
676
|
value = item ? item.toString() : '';
|
|
675
677
|
}
|
|
@@ -869,14 +871,6 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
869
871
|
|
|
870
872
|
/** @private */
|
|
871
873
|
_onOpened() {
|
|
872
|
-
// Defer scroll position adjustment to improve performance.
|
|
873
|
-
requestAnimationFrame(() => {
|
|
874
|
-
this._scrollIntoView(this._focusedIndex);
|
|
875
|
-
|
|
876
|
-
// Set attribute after the items are rendered when overlay is opened for the first time.
|
|
877
|
-
this._updateActiveDescendant(this._focusedIndex);
|
|
878
|
-
});
|
|
879
|
-
|
|
880
874
|
// _detectAndDispatchChange() should not consider value changes done before opening
|
|
881
875
|
this._lastCommittedValue = this.value;
|
|
882
876
|
}
|
|
@@ -897,6 +891,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
897
891
|
}
|
|
898
892
|
// Make sure input field is updated in case value doesn't change (i.e. FOO -> foo)
|
|
899
893
|
this._inputElementValue = this._getItemLabel(this.selectedItem);
|
|
894
|
+
this._focusedIndex = -1;
|
|
900
895
|
} else if (this._inputElementValue === '' || this._inputElementValue === undefined) {
|
|
901
896
|
this.selectedItem = null;
|
|
902
897
|
|
|
@@ -1056,10 +1051,6 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
1056
1051
|
this._toggleHasValue(true);
|
|
1057
1052
|
this._inputElementValue = this._getItemLabel(selectedItem);
|
|
1058
1053
|
}
|
|
1059
|
-
|
|
1060
|
-
if (this.filteredItems) {
|
|
1061
|
-
this._focusedIndex = this.filteredItems.indexOf(selectedItem);
|
|
1062
|
-
}
|
|
1063
1054
|
}
|
|
1064
1055
|
|
|
1065
1056
|
/**
|
|
@@ -1096,7 +1087,18 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
1096
1087
|
|
|
1097
1088
|
/** @private */
|
|
1098
1089
|
_detectAndDispatchChange() {
|
|
1099
|
-
|
|
1090
|
+
const isValueChanged = this.value !== this._lastCommittedValue;
|
|
1091
|
+
if (isValueChanged) {
|
|
1092
|
+
this.dirty = true;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
// Do not validate when focusout is caused by document
|
|
1096
|
+
// losing focus, which happens on browser tab switch.
|
|
1097
|
+
if (document.hasFocus()) {
|
|
1098
|
+
this.validate();
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
if (isValueChanged) {
|
|
1100
1102
|
this.dispatchEvent(new CustomEvent('change', { bubbles: true }));
|
|
1101
1103
|
this._lastCommittedValue = this.value;
|
|
1102
1104
|
}
|
|
@@ -1138,18 +1140,6 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
1138
1140
|
const focusedItemIndex = this.__getItemIndexByValue(filteredItems, this._getItemValue(focusedItem));
|
|
1139
1141
|
if (focusedItemIndex > -1) {
|
|
1140
1142
|
this._focusedIndex = focusedItemIndex;
|
|
1141
|
-
} else {
|
|
1142
|
-
this.__setInitialFocusedIndex();
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
/** @private */
|
|
1147
|
-
__setInitialFocusedIndex() {
|
|
1148
|
-
const inputValue = this._inputElementValue;
|
|
1149
|
-
if (inputValue === undefined || inputValue === this._getItemLabel(this.selectedItem)) {
|
|
1150
|
-
// When the input element value is the same as the current value or not defined,
|
|
1151
|
-
// set the focused index to the item that matches the value.
|
|
1152
|
-
this._focusedIndex = this.__getItemIndexByLabel(this.filteredItems, this._getItemLabel(this.selectedItem));
|
|
1153
1143
|
} else {
|
|
1154
1144
|
// When the user filled in something that is different from the current value = filtering is enabled,
|
|
1155
1145
|
// set the focused index to the item that matches the filter query.
|
|
@@ -1250,20 +1240,18 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
1250
1240
|
}
|
|
1251
1241
|
}
|
|
1252
1242
|
|
|
1253
|
-
/**
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1243
|
+
/**
|
|
1244
|
+
* Override method inherited from `FocusMixin`
|
|
1245
|
+
* to close the overlay on blur and commit the value.
|
|
1246
|
+
*
|
|
1247
|
+
* @param {boolean} focused
|
|
1248
|
+
* @protected
|
|
1249
|
+
* @override
|
|
1250
|
+
*/
|
|
1251
|
+
_setFocused(focused) {
|
|
1252
|
+
super._setFocused(focused);
|
|
1260
1253
|
|
|
1261
|
-
|
|
1262
|
-
if (event.relatedTarget === this._overlayElement) {
|
|
1263
|
-
event.composedPath()[0].focus();
|
|
1264
|
-
return;
|
|
1265
|
-
}
|
|
1266
|
-
if (!this.readonly && !this._closeOnBlurIsPrevented) {
|
|
1254
|
+
if (!focused && !this.readonly && !this._closeOnBlurIsPrevented) {
|
|
1267
1255
|
// User's logic in `custom-value-set` event listener might cause input to blur,
|
|
1268
1256
|
// which will result in attempting to commit the same custom value once again.
|
|
1269
1257
|
if (!this.opened && this.allowCustomValue && this._inputElementValue === this._lastCustomValue) {
|
|
@@ -1275,6 +1263,32 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
1275
1263
|
}
|
|
1276
1264
|
}
|
|
1277
1265
|
|
|
1266
|
+
/**
|
|
1267
|
+
* Override method inherited from `FocusMixin` to not remove focused
|
|
1268
|
+
* state when focus moves to the overlay.
|
|
1269
|
+
*
|
|
1270
|
+
* @param {FocusEvent} event
|
|
1271
|
+
* @return {boolean}
|
|
1272
|
+
* @protected
|
|
1273
|
+
* @override
|
|
1274
|
+
*/
|
|
1275
|
+
_shouldRemoveFocus(event) {
|
|
1276
|
+
// VoiceOver on iOS fires `focusout` event when moving focus to the item in the dropdown.
|
|
1277
|
+
// Do not focus the input in this case, because it would break announcement for the item.
|
|
1278
|
+
if (event.relatedTarget && event.relatedTarget.localName === `${this._tagNamePrefix}-item`) {
|
|
1279
|
+
return false;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
// Do not blur when focus moves to the overlay
|
|
1283
|
+
// Also, fixes the problem with `focusout` happening when clicking on the scroll bar on Edge
|
|
1284
|
+
if (event.relatedTarget === this._overlayElement) {
|
|
1285
|
+
event.composedPath()[0].focus();
|
|
1286
|
+
return false;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
return true;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1278
1292
|
/** @private */
|
|
1279
1293
|
_onTouchend(event) {
|
|
1280
1294
|
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 {
|
|
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(
|
|
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 {
|
|
7
|
-
import {
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
|
|
@@ -3,6 +3,7 @@
|
|
|
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 { get } from '@vaadin/component-base/src/path-utils.js';
|
|
6
7
|
import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
|
|
7
8
|
import { Virtualizer } from '@vaadin/component-base/src/virtualizer.js';
|
|
8
9
|
import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
|
|
@@ -202,7 +203,7 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
202
203
|
if (item instanceof ComboBoxPlaceholder) {
|
|
203
204
|
return false;
|
|
204
205
|
} else if (itemIdPath && item !== undefined && selectedItem !== undefined) {
|
|
205
|
-
return
|
|
206
|
+
return get(itemIdPath, item) === get(itemIdPath, selectedItem);
|
|
206
207
|
}
|
|
207
208
|
return item === selectedItem;
|
|
208
209
|
}
|
|
@@ -53,6 +53,11 @@ export type ComboBoxOpenedChangedEvent = CustomEvent<{ value: boolean }>;
|
|
|
53
53
|
*/
|
|
54
54
|
export type ComboBoxInvalidChangedEvent = CustomEvent<{ value: boolean }>;
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Fired when the `dirty` property changes.
|
|
58
|
+
*/
|
|
59
|
+
export type ComboBoxDirtyChangedEvent = CustomEvent<{ value: boolean }>;
|
|
60
|
+
|
|
56
61
|
/**
|
|
57
62
|
* Fired when the `value` property changes.
|
|
58
63
|
*/
|
|
@@ -84,6 +89,8 @@ export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap {
|
|
|
84
89
|
|
|
85
90
|
'invalid-changed': ComboBoxInvalidChangedEvent;
|
|
86
91
|
|
|
92
|
+
'dirty-changed': ComboBoxDirtyChangedEvent;
|
|
93
|
+
|
|
87
94
|
'value-changed': ComboBoxValueChangedEvent;
|
|
88
95
|
|
|
89
96
|
'selected-item-changed': ComboBoxSelectedItemChangedEvent<TItem>;
|
|
@@ -212,6 +219,7 @@ export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap {
|
|
|
212
219
|
* @fires {CustomEvent} filter-changed - Fired when the `filter` property changes.
|
|
213
220
|
* @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
|
|
214
221
|
* @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
|
|
222
|
+
* @fires {CustomEvent} dirty-changed - Fired when the `dirty` property changes.
|
|
215
223
|
* @fires {CustomEvent} selected-item-changed - Fired when the `selectedItem` property changes.
|
|
216
224
|
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
217
225
|
* @fires {CustomEvent} validated - Fired whenever the field is validated.
|
package/src/vaadin-combo-box.js
CHANGED
|
@@ -248,44 +248,13 @@ class ComboBox extends ComboBoxDataProviderMixin(
|
|
|
248
248
|
this._tooltipController = new TooltipController(this);
|
|
249
249
|
this.addController(this._tooltipController);
|
|
250
250
|
this._tooltipController.setPosition('top');
|
|
251
|
+
this._tooltipController.setAriaTarget(this.inputElement);
|
|
251
252
|
this._tooltipController.setShouldShow((target) => !target.opened);
|
|
252
253
|
|
|
253
254
|
this._positionTarget = this.shadowRoot.querySelector('[part="input-field"]');
|
|
254
255
|
this._toggleElement = this.$.toggleButton;
|
|
255
256
|
}
|
|
256
257
|
|
|
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
|
-
if (!focused) {
|
|
267
|
-
this.validate();
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Override method inherited from `FocusMixin` to not remove focused
|
|
273
|
-
* state when focus moves to the overlay.
|
|
274
|
-
* @param {FocusEvent} event
|
|
275
|
-
* @return {boolean}
|
|
276
|
-
* @protected
|
|
277
|
-
* @override
|
|
278
|
-
*/
|
|
279
|
-
_shouldRemoveFocus(event) {
|
|
280
|
-
// Do not blur when focus moves to the overlay
|
|
281
|
-
if (event.relatedTarget === this._overlayElement) {
|
|
282
|
-
event.composedPath()[0].focus();
|
|
283
|
-
return false;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return true;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
258
|
/**
|
|
290
259
|
* Override the method from `InputControlMixin`
|
|
291
260
|
* 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';
|
package/web-types.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/web-types",
|
|
3
3
|
"name": "@vaadin/combo-box",
|
|
4
|
-
"version": "24.2.0-
|
|
4
|
+
"version": "24.2.0-alpha11",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"contributions": {
|
|
7
7
|
"html": {
|
|
@@ -29,6 +29,28 @@
|
|
|
29
29
|
]
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
|
+
{
|
|
33
|
+
"name": "invalid",
|
|
34
|
+
"description": "Set to true when the field is invalid.",
|
|
35
|
+
"value": {
|
|
36
|
+
"type": [
|
|
37
|
+
"boolean",
|
|
38
|
+
"null",
|
|
39
|
+
"undefined"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "required",
|
|
45
|
+
"description": "Specifies that the user must fill in a value.",
|
|
46
|
+
"value": {
|
|
47
|
+
"type": [
|
|
48
|
+
"boolean",
|
|
49
|
+
"null",
|
|
50
|
+
"undefined"
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
},
|
|
32
54
|
{
|
|
33
55
|
"name": "disabled",
|
|
34
56
|
"description": "If true, the user cannot interact with this element.",
|
|
@@ -51,6 +73,17 @@
|
|
|
51
73
|
]
|
|
52
74
|
}
|
|
53
75
|
},
|
|
76
|
+
{
|
|
77
|
+
"name": "dirty",
|
|
78
|
+
"description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\nan `input` or `change` event. Additionally, the field can be manually\nmarked as dirty by setting the property to `true`.",
|
|
79
|
+
"value": {
|
|
80
|
+
"type": [
|
|
81
|
+
"boolean",
|
|
82
|
+
"null",
|
|
83
|
+
"undefined"
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
},
|
|
54
87
|
{
|
|
55
88
|
"name": "overlay-class",
|
|
56
89
|
"description": "A space-delimited list of CSS class names to set on the overlay element.\nThis property does not affect other CSS class names set manually via JS.\n\nNote, if the CSS class name was set with this property, clearing it will\nremove it from the overlay, even if the same class name was also added\nmanually, e.g. by using `classList.add()` in the `renderer` function.",
|
|
@@ -147,28 +180,6 @@
|
|
|
147
180
|
]
|
|
148
181
|
}
|
|
149
182
|
},
|
|
150
|
-
{
|
|
151
|
-
"name": "invalid",
|
|
152
|
-
"description": "Set to true when the field is invalid.",
|
|
153
|
-
"value": {
|
|
154
|
-
"type": [
|
|
155
|
-
"boolean",
|
|
156
|
-
"null",
|
|
157
|
-
"undefined"
|
|
158
|
-
]
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
"name": "required",
|
|
163
|
-
"description": "Specifies that the user must fill in a value.",
|
|
164
|
-
"value": {
|
|
165
|
-
"type": [
|
|
166
|
-
"boolean",
|
|
167
|
-
"null",
|
|
168
|
-
"undefined"
|
|
169
|
-
]
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
183
|
{
|
|
173
184
|
"name": "attr-for-value",
|
|
174
185
|
"description": "Name of the two-way data-bindable property representing the\nvalue of the custom input field.",
|
|
@@ -221,6 +232,28 @@
|
|
|
221
232
|
]
|
|
222
233
|
}
|
|
223
234
|
},
|
|
235
|
+
{
|
|
236
|
+
"name": "invalid",
|
|
237
|
+
"description": "Set to true when the field is invalid.",
|
|
238
|
+
"value": {
|
|
239
|
+
"type": [
|
|
240
|
+
"boolean",
|
|
241
|
+
"null",
|
|
242
|
+
"undefined"
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"name": "required",
|
|
248
|
+
"description": "Specifies that the user must fill in a value.",
|
|
249
|
+
"value": {
|
|
250
|
+
"type": [
|
|
251
|
+
"boolean",
|
|
252
|
+
"null",
|
|
253
|
+
"undefined"
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
},
|
|
224
257
|
{
|
|
225
258
|
"name": "disabled",
|
|
226
259
|
"description": "If true, the user cannot interact with this element.",
|
|
@@ -243,6 +276,17 @@
|
|
|
243
276
|
]
|
|
244
277
|
}
|
|
245
278
|
},
|
|
279
|
+
{
|
|
280
|
+
"name": "dirty",
|
|
281
|
+
"description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\nan `input` or `change` event. Additionally, the field can be manually\nmarked as dirty by setting the property to `true`.",
|
|
282
|
+
"value": {
|
|
283
|
+
"type": [
|
|
284
|
+
"boolean",
|
|
285
|
+
"null",
|
|
286
|
+
"undefined"
|
|
287
|
+
]
|
|
288
|
+
}
|
|
289
|
+
},
|
|
246
290
|
{
|
|
247
291
|
"name": "overlayClass",
|
|
248
292
|
"description": "A space-delimited list of CSS class names to set on the overlay element.\nThis property does not affect other CSS class names set manually via JS.\n\nNote, if the CSS class name was set with this property, clearing it will\nremove it from the overlay, even if the same class name was also added\nmanually, e.g. by using `classList.add()` in the `renderer` function.",
|
|
@@ -382,28 +426,6 @@
|
|
|
382
426
|
]
|
|
383
427
|
}
|
|
384
428
|
},
|
|
385
|
-
{
|
|
386
|
-
"name": "invalid",
|
|
387
|
-
"description": "Set to true when the field is invalid.",
|
|
388
|
-
"value": {
|
|
389
|
-
"type": [
|
|
390
|
-
"boolean",
|
|
391
|
-
"null",
|
|
392
|
-
"undefined"
|
|
393
|
-
]
|
|
394
|
-
}
|
|
395
|
-
},
|
|
396
|
-
{
|
|
397
|
-
"name": "required",
|
|
398
|
-
"description": "Specifies that the user must fill in a value.",
|
|
399
|
-
"value": {
|
|
400
|
-
"type": [
|
|
401
|
-
"boolean",
|
|
402
|
-
"null",
|
|
403
|
-
"undefined"
|
|
404
|
-
]
|
|
405
|
-
}
|
|
406
|
-
},
|
|
407
429
|
{
|
|
408
430
|
"name": "attrForValue",
|
|
409
431
|
"description": "Name of the two-way data-bindable property representing the\nvalue of the custom input field.",
|
|
@@ -415,6 +437,10 @@
|
|
|
415
437
|
}
|
|
416
438
|
],
|
|
417
439
|
"events": [
|
|
440
|
+
{
|
|
441
|
+
"name": "validated",
|
|
442
|
+
"description": "Fired whenever the field is validated."
|
|
443
|
+
},
|
|
418
444
|
{
|
|
419
445
|
"name": "change",
|
|
420
446
|
"description": "Fired when value changes.\nTo comply with https://developer.mozilla.org/en-US/docs/Web/Events/change"
|
|
@@ -440,8 +466,12 @@
|
|
|
440
466
|
"description": "Fired when the value changes."
|
|
441
467
|
},
|
|
442
468
|
{
|
|
443
|
-
"name": "
|
|
444
|
-
"description": "Fired
|
|
469
|
+
"name": "invalid-changed",
|
|
470
|
+
"description": "Fired when the `invalid` property changes."
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
"name": "dirty-changed",
|
|
474
|
+
"description": "Fired when the `dirty` property changes."
|
|
445
475
|
},
|
|
446
476
|
{
|
|
447
477
|
"name": "opened-changed",
|
|
@@ -450,17 +480,13 @@
|
|
|
450
480
|
{
|
|
451
481
|
"name": "filter-changed",
|
|
452
482
|
"description": "Fired when the `filter` property changes."
|
|
453
|
-
},
|
|
454
|
-
{
|
|
455
|
-
"name": "invalid-changed",
|
|
456
|
-
"description": "Fired when the `invalid` property changes."
|
|
457
483
|
}
|
|
458
484
|
]
|
|
459
485
|
}
|
|
460
486
|
},
|
|
461
487
|
{
|
|
462
488
|
"name": "vaadin-combo-box",
|
|
463
|
-
"description": "`<vaadin-combo-box>` is a web component for choosing a value from a filterable list of options\npresented in a dropdown overlay. The options can be provided as a list of strings or objects\nby setting [`items`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-
|
|
489
|
+
"description": "`<vaadin-combo-box>` is a web component for choosing a value from a filterable list of options\npresented in a dropdown overlay. The options can be provided as a list of strings or objects\nby setting [`items`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-combo-box#property-items) property on the element.\n\n```html\n<vaadin-combo-box id=\"combo-box\"></vaadin-combo-box>\n```\n```js\ndocument.querySelector('#combo-box').items = ['apple', 'orange', 'banana'];\n```\n\nWhen the selected `value` is changed, a `value-changed` event is triggered.\n\n### Item rendering\n\nTo customize the content of the `<vaadin-combo-box-item>` elements placed in the dropdown, use\n[`renderer`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-combo-box#property-renderer) property which accepts a function.\nThe renderer function is called with `root`, `comboBox`, and `model` as arguments.\n\nGenerate DOM content by using `model` object properties if needed, and append it to the `root`\nelement. The `comboBox` reference is provided to access the combo-box element state. Do not\nset combo-box properties in a `renderer` function.\n\n```js\nconst comboBox = document.querySelector('#combo-box');\ncomboBox.items = [{'label': 'Hydrogen', 'value': 'H'}];\ncomboBox.renderer = (root, comboBox, model) => {\n const item = model.item;\n root.innerHTML = `${model.index}: ${item.label} <b>${item.value}</b>`;\n};\n```\n\nRenderer is called on the opening of the combo-box and each time the related model is updated.\nBefore creating new content, it is recommended to check if there is already an existing DOM\nelement in `root` from a previous renderer call for reusing it. Even though combo-box uses\ninfinite scrolling, reducing DOM operations might improve performance.\n\nThe following properties are available in the `model` argument:\n\nProperty | Type | Description\n-----------|------------------|-------------\n`index` | Number | Index of the item in the `items` array\n`item` | String or Object | The item reference\n`selected` | Boolean | True when item is selected\n`focused` | Boolean | True when item is focused\n\n### Lazy Loading with Function Data Provider\n\nIn addition to assigning an array to the items property, you can alternatively use the\n[`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-combo-box#property-dataProvider) function property.\nThe `<vaadin-combo-box>` calls this function lazily, only when it needs more data\nto be displayed.\n\n__Note that when using function data providers, the total number of items\nneeds to be set manually. The total number of items can be returned\nin the second argument of the data provider callback:__\n\n```js\ncomboBox.dataProvider = async (params, callback) => {\n const API = 'https://demo.vaadin.com/demo-data/1.0/filtered-countries';\n const { filter, page, pageSize } = params;\n const index = page * pageSize;\n\n const res = await fetch(`${API}?index=${index}&count=${pageSize}&filter=${filter}`);\n if (res.ok) {\n const { result, size } = await res.json();\n callback(result, size);\n }\n};\n```\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n----------------------------------------|----------------------------|---------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n`--vaadin-combo-box-overlay-width` | Width of the overlay | `auto`\n`--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh`\n\n`<vaadin-combo-box>` provides the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.\nSee [`<vaadin-text-field>`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-text-field) for the styling documentation.\n\nIn addition to `<vaadin-text-field>` parts, the following parts are available for theming:\n\nPart name | Description\n----------------|----------------\n`toggle-button` | The toggle button\n\nIn addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:\n\nAttribute | Description | Part name\n----------|-------------|------------\n`opened` | Set when the combo box dropdown is open | :host\n`loading` | Set when new items are expected | :host\n\nIf you want to replace the default `<input>` and its container with a custom implementation to get full control\nover the input field, consider using the [`<vaadin-combo-box-light>`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-combo-box-light) element.\n\n### Internal components\n\nIn addition to `<vaadin-combo-box>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-combo-box-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-overlay).\n- `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-item).\n- [`<vaadin-input-container>`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-input-container) - an internal element wrapping the input.\n\nNote: the `theme` attribute value set on `<vaadin-combo-box>` is\npropagated to the internal components listed above.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
|
|
464
490
|
"attributes": [
|
|
465
491
|
{
|
|
466
492
|
"name": "disabled",
|
|
@@ -572,6 +598,17 @@
|
|
|
572
598
|
]
|
|
573
599
|
}
|
|
574
600
|
},
|
|
601
|
+
{
|
|
602
|
+
"name": "dirty",
|
|
603
|
+
"description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\nan `input` or `change` event. Additionally, the field can be manually\nmarked as dirty by setting the property to `true`.",
|
|
604
|
+
"value": {
|
|
605
|
+
"type": [
|
|
606
|
+
"boolean",
|
|
607
|
+
"null",
|
|
608
|
+
"undefined"
|
|
609
|
+
]
|
|
610
|
+
}
|
|
611
|
+
},
|
|
575
612
|
{
|
|
576
613
|
"name": "clear-button-visible",
|
|
577
614
|
"description": "Set to true to display the clear icon which clears the input.\n\nIt is up to the component to choose where to place the clear icon:\nin the Shadow DOM or in the light DOM. In any way, a reference to\nthe clear icon element should be provided via the `clearElement` getter.",
|
|
@@ -888,6 +925,17 @@
|
|
|
888
925
|
]
|
|
889
926
|
}
|
|
890
927
|
},
|
|
928
|
+
{
|
|
929
|
+
"name": "dirty",
|
|
930
|
+
"description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\nan `input` or `change` event. Additionally, the field can be manually\nmarked as dirty by setting the property to `true`.",
|
|
931
|
+
"value": {
|
|
932
|
+
"type": [
|
|
933
|
+
"boolean",
|
|
934
|
+
"null",
|
|
935
|
+
"undefined"
|
|
936
|
+
]
|
|
937
|
+
}
|
|
938
|
+
},
|
|
891
939
|
{
|
|
892
940
|
"name": "clearButtonVisible",
|
|
893
941
|
"description": "Set to true to display the clear icon which clears the input.\n\nIt is up to the component to choose where to place the clear icon:\nin the Shadow DOM or in the light DOM. In any way, a reference to\nthe clear icon element should be provided via the `clearElement` getter.",
|
|
@@ -1171,6 +1219,10 @@
|
|
|
1171
1219
|
"name": "invalid-changed",
|
|
1172
1220
|
"description": "Fired when the `invalid` property changes."
|
|
1173
1221
|
},
|
|
1222
|
+
{
|
|
1223
|
+
"name": "dirty-changed",
|
|
1224
|
+
"description": "Fired when the `dirty` property changes."
|
|
1225
|
+
},
|
|
1174
1226
|
{
|
|
1175
1227
|
"name": "opened-changed",
|
|
1176
1228
|
"description": "Fired when the `opened` property changes."
|
package/web-types.lit.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/web-types",
|
|
3
3
|
"name": "@vaadin/combo-box",
|
|
4
|
-
"version": "24.2.0-
|
|
4
|
+
"version": "24.2.0-alpha11",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"framework": "lit",
|
|
7
7
|
"framework-config": {
|
|
@@ -19,6 +19,20 @@
|
|
|
19
19
|
"description": "`<vaadin-combo-box-light>` is a customizable version of the `<vaadin-combo-box>` providing\nonly the dropdown functionality and leaving the input field definition to the user.\n\nThe element has the same API as `<vaadin-combo-box>`.\n\nTo create a custom input field, you need to add a child element which has a two-way\ndata-bindable property representing the input value. The property name is expected\nto be `value` by default. For example, you can use `<vaadin-text-field>` element:\n\n```html\n<vaadin-combo-box-light>\n <vaadin-text-field></vaadin-text-field>\n</vaadin-combo-box-light>\n```\n\nIf you are using custom input field that has other property for value,\nset `class=\"input\"` to enable corresponding logic, and use `attr-for-value`\nattribute to specify which property to use:\n\n```html\n<vaadin-combo-box-light attr-for-value=\"input-value\">\n <custom-input class=\"input\"></custom-input>\n</vaadin-combo-box-light>\n```\n\nYou can also pass custom toggle and clear buttons with corresponding classes:\n\n```html\n<vaadin-combo-box-light>\n <custom-input class=\"input\" attr-for-value=\"input-value\">\n <button slot=\"suffix\" class=\"clear-button\">Clear</button>\n <button slot=\"suffix\" class=\"toggle-button\">Toggle</button>\n </custom-input>\n</vaadin-combo-box-light>\n```",
|
|
20
20
|
"extension": true,
|
|
21
21
|
"attributes": [
|
|
22
|
+
{
|
|
23
|
+
"name": "?invalid",
|
|
24
|
+
"description": "Set to true when the field is invalid.",
|
|
25
|
+
"value": {
|
|
26
|
+
"kind": "expression"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "?required",
|
|
31
|
+
"description": "Specifies that the user must fill in a value.",
|
|
32
|
+
"value": {
|
|
33
|
+
"kind": "expression"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
22
36
|
{
|
|
23
37
|
"name": "?disabled",
|
|
24
38
|
"description": "If true, the user cannot interact with this element.",
|
|
@@ -26,6 +40,13 @@
|
|
|
26
40
|
"kind": "expression"
|
|
27
41
|
}
|
|
28
42
|
},
|
|
43
|
+
{
|
|
44
|
+
"name": "?dirty",
|
|
45
|
+
"description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\nan `input` or `change` event. Additionally, the field can be manually\nmarked as dirty by setting the property to `true`.",
|
|
46
|
+
"value": {
|
|
47
|
+
"kind": "expression"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
29
50
|
{
|
|
30
51
|
"name": "?opened",
|
|
31
52
|
"description": "True if the dropdown is open, false otherwise.",
|
|
@@ -61,20 +82,6 @@
|
|
|
61
82
|
"kind": "expression"
|
|
62
83
|
}
|
|
63
84
|
},
|
|
64
|
-
{
|
|
65
|
-
"name": "?invalid",
|
|
66
|
-
"description": "Set to true when the field is invalid.",
|
|
67
|
-
"value": {
|
|
68
|
-
"kind": "expression"
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"name": "?required",
|
|
73
|
-
"description": "Specifies that the user must fill in a value.",
|
|
74
|
-
"value": {
|
|
75
|
-
"kind": "expression"
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
85
|
{
|
|
79
86
|
"name": ".pageSize",
|
|
80
87
|
"description": "Number of items fetched at a time from the dataprovider.",
|
|
@@ -173,6 +180,13 @@
|
|
|
173
180
|
"kind": "expression"
|
|
174
181
|
}
|
|
175
182
|
},
|
|
183
|
+
{
|
|
184
|
+
"name": "@validated",
|
|
185
|
+
"description": "Fired whenever the field is validated.",
|
|
186
|
+
"value": {
|
|
187
|
+
"kind": "expression"
|
|
188
|
+
}
|
|
189
|
+
},
|
|
176
190
|
{
|
|
177
191
|
"name": "@change",
|
|
178
192
|
"description": "Fired when value changes.\nTo comply with https://developer.mozilla.org/en-US/docs/Web/Events/change",
|
|
@@ -216,29 +230,29 @@
|
|
|
216
230
|
}
|
|
217
231
|
},
|
|
218
232
|
{
|
|
219
|
-
"name": "@
|
|
220
|
-
"description": "Fired
|
|
233
|
+
"name": "@invalid-changed",
|
|
234
|
+
"description": "Fired when the `invalid` property changes.",
|
|
221
235
|
"value": {
|
|
222
236
|
"kind": "expression"
|
|
223
237
|
}
|
|
224
238
|
},
|
|
225
239
|
{
|
|
226
|
-
"name": "@
|
|
227
|
-
"description": "Fired when the `
|
|
240
|
+
"name": "@dirty-changed",
|
|
241
|
+
"description": "Fired when the `dirty` property changes.",
|
|
228
242
|
"value": {
|
|
229
243
|
"kind": "expression"
|
|
230
244
|
}
|
|
231
245
|
},
|
|
232
246
|
{
|
|
233
|
-
"name": "@
|
|
234
|
-
"description": "Fired when the `
|
|
247
|
+
"name": "@opened-changed",
|
|
248
|
+
"description": "Fired when the `opened` property changes.",
|
|
235
249
|
"value": {
|
|
236
250
|
"kind": "expression"
|
|
237
251
|
}
|
|
238
252
|
},
|
|
239
253
|
{
|
|
240
|
-
"name": "@
|
|
241
|
-
"description": "Fired when the `
|
|
254
|
+
"name": "@filter-changed",
|
|
255
|
+
"description": "Fired when the `filter` property changes.",
|
|
242
256
|
"value": {
|
|
243
257
|
"kind": "expression"
|
|
244
258
|
}
|
|
@@ -247,7 +261,7 @@
|
|
|
247
261
|
},
|
|
248
262
|
{
|
|
249
263
|
"name": "vaadin-combo-box",
|
|
250
|
-
"description": "`<vaadin-combo-box>` is a web component for choosing a value from a filterable list of options\npresented in a dropdown overlay. The options can be provided as a list of strings or objects\nby setting [`items`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-
|
|
264
|
+
"description": "`<vaadin-combo-box>` is a web component for choosing a value from a filterable list of options\npresented in a dropdown overlay. The options can be provided as a list of strings or objects\nby setting [`items`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-combo-box#property-items) property on the element.\n\n```html\n<vaadin-combo-box id=\"combo-box\"></vaadin-combo-box>\n```\n```js\ndocument.querySelector('#combo-box').items = ['apple', 'orange', 'banana'];\n```\n\nWhen the selected `value` is changed, a `value-changed` event is triggered.\n\n### Item rendering\n\nTo customize the content of the `<vaadin-combo-box-item>` elements placed in the dropdown, use\n[`renderer`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-combo-box#property-renderer) property which accepts a function.\nThe renderer function is called with `root`, `comboBox`, and `model` as arguments.\n\nGenerate DOM content by using `model` object properties if needed, and append it to the `root`\nelement. The `comboBox` reference is provided to access the combo-box element state. Do not\nset combo-box properties in a `renderer` function.\n\n```js\nconst comboBox = document.querySelector('#combo-box');\ncomboBox.items = [{'label': 'Hydrogen', 'value': 'H'}];\ncomboBox.renderer = (root, comboBox, model) => {\n const item = model.item;\n root.innerHTML = `${model.index}: ${item.label} <b>${item.value}</b>`;\n};\n```\n\nRenderer is called on the opening of the combo-box and each time the related model is updated.\nBefore creating new content, it is recommended to check if there is already an existing DOM\nelement in `root` from a previous renderer call for reusing it. Even though combo-box uses\ninfinite scrolling, reducing DOM operations might improve performance.\n\nThe following properties are available in the `model` argument:\n\nProperty | Type | Description\n-----------|------------------|-------------\n`index` | Number | Index of the item in the `items` array\n`item` | String or Object | The item reference\n`selected` | Boolean | True when item is selected\n`focused` | Boolean | True when item is focused\n\n### Lazy Loading with Function Data Provider\n\nIn addition to assigning an array to the items property, you can alternatively use the\n[`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-combo-box#property-dataProvider) function property.\nThe `<vaadin-combo-box>` calls this function lazily, only when it needs more data\nto be displayed.\n\n__Note that when using function data providers, the total number of items\nneeds to be set manually. The total number of items can be returned\nin the second argument of the data provider callback:__\n\n```js\ncomboBox.dataProvider = async (params, callback) => {\n const API = 'https://demo.vaadin.com/demo-data/1.0/filtered-countries';\n const { filter, page, pageSize } = params;\n const index = page * pageSize;\n\n const res = await fetch(`${API}?index=${index}&count=${pageSize}&filter=${filter}`);\n if (res.ok) {\n const { result, size } = await res.json();\n callback(result, size);\n }\n};\n```\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n----------------------------------------|----------------------------|---------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n`--vaadin-combo-box-overlay-width` | Width of the overlay | `auto`\n`--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh`\n\n`<vaadin-combo-box>` provides the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.\nSee [`<vaadin-text-field>`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-text-field) for the styling documentation.\n\nIn addition to `<vaadin-text-field>` parts, the following parts are available for theming:\n\nPart name | Description\n----------------|----------------\n`toggle-button` | The toggle button\n\nIn addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:\n\nAttribute | Description | Part name\n----------|-------------|------------\n`opened` | Set when the combo box dropdown is open | :host\n`loading` | Set when new items are expected | :host\n\nIf you want to replace the default `<input>` and its container with a custom implementation to get full control\nover the input field, consider using the [`<vaadin-combo-box-light>`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-combo-box-light) element.\n\n### Internal components\n\nIn addition to `<vaadin-combo-box>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-combo-box-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-overlay).\n- `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-item).\n- [`<vaadin-input-container>`](https://cdn.vaadin.com/vaadin-web-components/24.2.0-alpha11/#/elements/vaadin-input-container) - an internal element wrapping the input.\n\nNote: the `theme` attribute value set on `<vaadin-combo-box>` is\npropagated to the internal components listed above.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
|
|
251
265
|
"extension": true,
|
|
252
266
|
"attributes": [
|
|
253
267
|
{
|
|
@@ -278,6 +292,13 @@
|
|
|
278
292
|
"kind": "expression"
|
|
279
293
|
}
|
|
280
294
|
},
|
|
295
|
+
{
|
|
296
|
+
"name": "?dirty",
|
|
297
|
+
"description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\nan `input` or `change` event. Additionally, the field can be manually\nmarked as dirty by setting the property to `true`.",
|
|
298
|
+
"value": {
|
|
299
|
+
"kind": "expression"
|
|
300
|
+
}
|
|
301
|
+
},
|
|
281
302
|
{
|
|
282
303
|
"name": "?clearButtonVisible",
|
|
283
304
|
"description": "Set to true to display the clear icon which clears the input.\n\nIt is up to the component to choose where to place the clear icon:\nin the Shadow DOM or in the light DOM. In any way, a reference to\nthe clear icon element should be provided via the `clearElement` getter.",
|
|
@@ -551,6 +572,13 @@
|
|
|
551
572
|
"kind": "expression"
|
|
552
573
|
}
|
|
553
574
|
},
|
|
575
|
+
{
|
|
576
|
+
"name": "@dirty-changed",
|
|
577
|
+
"description": "Fired when the `dirty` property changes.",
|
|
578
|
+
"value": {
|
|
579
|
+
"kind": "expression"
|
|
580
|
+
}
|
|
581
|
+
},
|
|
554
582
|
{
|
|
555
583
|
"name": "@opened-changed",
|
|
556
584
|
"description": "Fired when the `opened` property changes.",
|