@vaadin/combo-box 24.0.0-alpha8 → 24.0.0-beta1
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 +13 -13
- package/src/vaadin-combo-box-data-provider-mixin.js +4 -6
- package/src/vaadin-combo-box-item-mixin.d.ts +65 -0
- package/src/vaadin-combo-box-item-mixin.js +127 -0
- package/src/vaadin-combo-box-item.d.ts +45 -0
- package/src/vaadin-combo-box-item.js +3 -114
- package/src/vaadin-combo-box-light.js +24 -24
- package/src/vaadin-combo-box-mixin.d.ts +6 -12
- package/src/vaadin-combo-box-mixin.js +35 -25
- package/src/vaadin-combo-box-overlay-mixin.d.ts +11 -0
- package/src/vaadin-combo-box-overlay-mixin.js +60 -0
- package/src/vaadin-combo-box-overlay.d.ts +20 -0
- package/src/vaadin-combo-box-overlay.js +12 -45
- package/src/vaadin-combo-box-scroller-mixin.d.ts +82 -0
- package/src/vaadin-combo-box-scroller-mixin.js +361 -0
- package/src/vaadin-combo-box-scroller.d.ts +19 -0
- package/src/vaadin-combo-box-scroller.js +5 -345
- package/src/vaadin-combo-box.d.ts +13 -15
- package/src/vaadin-combo-box.js +12 -16
- package/theme/lumo/vaadin-combo-box-item-styles.js +2 -0
- package/theme/lumo/vaadin-combo-box-light.js +1 -1
- package/theme/lumo/{vaadin-combo-box-dropdown-styles.js → vaadin-combo-box-overlay-styles.js} +21 -13
- package/theme/lumo/vaadin-combo-box.js +1 -1
- package/theme/material/vaadin-combo-box-item-styles.js +2 -0
- package/theme/material/vaadin-combo-box-light.js +1 -1
- package/theme/material/{vaadin-combo-box-dropdown-styles.js → vaadin-combo-box-overlay-styles.js} +20 -9
- package/theme/material/vaadin-combo-box.js +1 -1
- package/web-types.json +90 -2
- package/web-types.lit.json +30 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/combo-box",
|
|
3
|
-
"version": "24.0.0-
|
|
3
|
+
"version": "24.0.0-beta1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -38,20 +38,20 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
40
40
|
"@polymer/polymer": "^3.0.0",
|
|
41
|
-
"@vaadin/component-base": "24.0.0-
|
|
42
|
-
"@vaadin/field-base": "24.0.0-
|
|
43
|
-
"@vaadin/input-container": "24.0.0-
|
|
44
|
-
"@vaadin/item": "24.0.0-
|
|
45
|
-
"@vaadin/lit-renderer": "24.0.0-
|
|
46
|
-
"@vaadin/overlay": "24.0.0-
|
|
47
|
-
"@vaadin/vaadin-lumo-styles": "24.0.0-
|
|
48
|
-
"@vaadin/vaadin-material-styles": "24.0.0-
|
|
49
|
-
"@vaadin/vaadin-themable-mixin": "24.0.0-
|
|
41
|
+
"@vaadin/component-base": "24.0.0-beta1",
|
|
42
|
+
"@vaadin/field-base": "24.0.0-beta1",
|
|
43
|
+
"@vaadin/input-container": "24.0.0-beta1",
|
|
44
|
+
"@vaadin/item": "24.0.0-beta1",
|
|
45
|
+
"@vaadin/lit-renderer": "24.0.0-beta1",
|
|
46
|
+
"@vaadin/overlay": "24.0.0-beta1",
|
|
47
|
+
"@vaadin/vaadin-lumo-styles": "24.0.0-beta1",
|
|
48
|
+
"@vaadin/vaadin-material-styles": "24.0.0-beta1",
|
|
49
|
+
"@vaadin/vaadin-themable-mixin": "24.0.0-beta1"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@esm-bundle/chai": "^4.3.4",
|
|
53
|
-
"@vaadin/testing-helpers": "^0.
|
|
54
|
-
"@vaadin/text-field": "24.0.0-
|
|
53
|
+
"@vaadin/testing-helpers": "^0.4.0",
|
|
54
|
+
"@vaadin/text-field": "24.0.0-beta1",
|
|
55
55
|
"lit": "^2.0.0",
|
|
56
56
|
"sinon": "^13.0.2"
|
|
57
57
|
},
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"web-types.json",
|
|
60
60
|
"web-types.lit.json"
|
|
61
61
|
],
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "c5b48921a62482746df8e46994b37e1490fec27e"
|
|
63
63
|
}
|
|
@@ -311,13 +311,11 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
311
311
|
_flushPendingRequests(size) {
|
|
312
312
|
if (this._pendingRequests) {
|
|
313
313
|
const lastPage = Math.ceil(size / this.pageSize);
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if (page >= lastPage) {
|
|
318
|
-
this._pendingRequests[page]([], size);
|
|
314
|
+
Object.entries(this._pendingRequests).forEach(([page, callback]) => {
|
|
315
|
+
if (parseInt(page) >= lastPage) {
|
|
316
|
+
callback([], size);
|
|
319
317
|
}
|
|
320
|
-
}
|
|
318
|
+
});
|
|
321
319
|
}
|
|
322
320
|
}
|
|
323
321
|
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2015 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
|
+
|
|
8
|
+
export type ComboBoxDefaultItem = any;
|
|
9
|
+
|
|
10
|
+
export interface ComboBoxItemModel<TItem> {
|
|
11
|
+
index: number;
|
|
12
|
+
item: TItem;
|
|
13
|
+
selected: boolean;
|
|
14
|
+
focused: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type ComboBoxItemRenderer<TItem, TOwner> = (
|
|
18
|
+
root: HTMLElement,
|
|
19
|
+
owner: TOwner,
|
|
20
|
+
model: ComboBoxItemModel<TItem>,
|
|
21
|
+
) => void;
|
|
22
|
+
|
|
23
|
+
export declare function ComboBoxItemMixin<TItem, TOwner, T extends Constructor<HTMLElement>>(
|
|
24
|
+
base: T,
|
|
25
|
+
): Constructor<ComboBoxItemMixinClass<TItem, TOwner>> & T;
|
|
26
|
+
|
|
27
|
+
export declare class ComboBoxItemMixinClass<TItem, TOwner> {
|
|
28
|
+
/**
|
|
29
|
+
* The item to render.
|
|
30
|
+
*/
|
|
31
|
+
index: number;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The item to render.
|
|
35
|
+
*/
|
|
36
|
+
item: TItem;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The text to render in the item.
|
|
40
|
+
*/
|
|
41
|
+
label: string;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* True when item is selected.
|
|
45
|
+
*/
|
|
46
|
+
selected: boolean;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* True when item is focused.
|
|
50
|
+
*/
|
|
51
|
+
focused: boolean;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Custom function for rendering the item content.
|
|
55
|
+
*/
|
|
56
|
+
renderer: ComboBoxItemRenderer<TItem, TOwner>;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Requests an update for the content of the item.
|
|
60
|
+
* While performing the update, it invokes the renderer passed in the `renderer` property.
|
|
61
|
+
*
|
|
62
|
+
* It is not guaranteed that the update happens immediately (synchronously) after it is requested.
|
|
63
|
+
*/
|
|
64
|
+
requestContentUpdate(): void;
|
|
65
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2015 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @polymerMixin
|
|
9
|
+
*/
|
|
10
|
+
export const ComboBoxItemMixin = (superClass) =>
|
|
11
|
+
class ComboBoxItemMixinClass extends superClass {
|
|
12
|
+
static get properties() {
|
|
13
|
+
return {
|
|
14
|
+
/**
|
|
15
|
+
* The index of the item.
|
|
16
|
+
*/
|
|
17
|
+
index: {
|
|
18
|
+
type: Number,
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The item to render.
|
|
23
|
+
*/
|
|
24
|
+
item: {
|
|
25
|
+
type: Object,
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The text to render in the item.
|
|
30
|
+
*/
|
|
31
|
+
label: {
|
|
32
|
+
type: String,
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* True when item is selected.
|
|
37
|
+
*/
|
|
38
|
+
selected: {
|
|
39
|
+
type: Boolean,
|
|
40
|
+
value: false,
|
|
41
|
+
reflectToAttribute: true,
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* True when item is focused.
|
|
46
|
+
*/
|
|
47
|
+
focused: {
|
|
48
|
+
type: Boolean,
|
|
49
|
+
value: false,
|
|
50
|
+
reflectToAttribute: true,
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Custom function for rendering the item content.
|
|
55
|
+
*/
|
|
56
|
+
renderer: {
|
|
57
|
+
type: Function,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static get observers() {
|
|
63
|
+
return ['__rendererOrItemChanged(renderer, index, item.*, selected, focused)', '__updateLabel(label, renderer)'];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** @protected */
|
|
67
|
+
connectedCallback() {
|
|
68
|
+
super.connectedCallback();
|
|
69
|
+
|
|
70
|
+
this._owner = this.parentNode.owner;
|
|
71
|
+
|
|
72
|
+
const hostDir = this._owner.getAttribute('dir');
|
|
73
|
+
if (hostDir) {
|
|
74
|
+
this.setAttribute('dir', hostDir);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Requests an update for the content of the item.
|
|
80
|
+
* While performing the update, it invokes the renderer passed in the `renderer` property.
|
|
81
|
+
*
|
|
82
|
+
* It is not guaranteed that the update happens immediately (synchronously) after it is requested.
|
|
83
|
+
*/
|
|
84
|
+
requestContentUpdate() {
|
|
85
|
+
if (!this.renderer) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const model = {
|
|
90
|
+
index: this.index,
|
|
91
|
+
item: this.item,
|
|
92
|
+
focused: this.focused,
|
|
93
|
+
selected: this.selected,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
this.renderer(this, this._owner, model);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** @private */
|
|
100
|
+
__rendererOrItemChanged(renderer, index, item) {
|
|
101
|
+
if (item === undefined || index === undefined) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (this._oldRenderer !== renderer) {
|
|
106
|
+
this.innerHTML = '';
|
|
107
|
+
// Whenever a Lit-based renderer is used, it assigns a Lit part to the node it was rendered into.
|
|
108
|
+
// When clearing the rendered content, this part needs to be manually disposed of.
|
|
109
|
+
// Otherwise, using a Lit-based renderer on the same node will throw an exception or render nothing afterward.
|
|
110
|
+
delete this._$litPart$;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (renderer) {
|
|
114
|
+
this._oldRenderer = renderer;
|
|
115
|
+
this.requestContentUpdate();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** @private */
|
|
120
|
+
__updateLabel(label, renderer) {
|
|
121
|
+
if (renderer) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.textContent = label;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2015 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { DirMixinClass } from '@vaadin/component-base/src/dir-mixin.js';
|
|
7
|
+
import type { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
8
|
+
import type { ComboBox } from './vaadin-combo-box.js';
|
|
9
|
+
import type { ComboBoxDefaultItem, ComboBoxItemMixinClass } from './vaadin-combo-box-item-mixin.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* An item element used by the `<vaadin-combo-box>` dropdown.
|
|
13
|
+
*
|
|
14
|
+
* ### Styling
|
|
15
|
+
*
|
|
16
|
+
* The following shadow DOM parts are available for styling:
|
|
17
|
+
*
|
|
18
|
+
* Part name | Description
|
|
19
|
+
* ------------|--------------
|
|
20
|
+
* `checkmark` | The graphical checkmark shown for a selected item
|
|
21
|
+
* `content` | The element that wraps the item content
|
|
22
|
+
*
|
|
23
|
+
* The following state attributes are exposed for styling:
|
|
24
|
+
*
|
|
25
|
+
* Attribute | Description
|
|
26
|
+
* -------------|-------------
|
|
27
|
+
* `selected` | Set when the item is selected
|
|
28
|
+
* `focused` | Set when the item is focused
|
|
29
|
+
*
|
|
30
|
+
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
31
|
+
*/
|
|
32
|
+
declare class ComboBoxItem extends HTMLElement {}
|
|
33
|
+
|
|
34
|
+
interface ComboBoxItem<TItem = ComboBoxDefaultItem>
|
|
35
|
+
extends ComboBoxItemMixinClass<TItem, ComboBox>,
|
|
36
|
+
DirMixinClass,
|
|
37
|
+
ThemableMixinClass {}
|
|
38
|
+
|
|
39
|
+
declare global {
|
|
40
|
+
interface HTMLElementTagNameMap {
|
|
41
|
+
'vaadin-combo-box-item': ComboBoxItem;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { ComboBoxItem };
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
7
7
|
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
8
8
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
9
|
+
import { ComboBoxItemMixin } from './vaadin-combo-box-item-mixin.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* An item element used by the `<vaadin-combo-box>` dropdown.
|
|
@@ -28,11 +29,12 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
28
29
|
*
|
|
29
30
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
30
31
|
*
|
|
32
|
+
* @mixes ComboBoxItemMixin
|
|
31
33
|
* @mixes ThemableMixin
|
|
32
34
|
* @mixes DirMixin
|
|
33
35
|
* @private
|
|
34
36
|
*/
|
|
35
|
-
export class ComboBoxItem extends ThemableMixin(DirMixin(PolymerElement)) {
|
|
37
|
+
export class ComboBoxItem extends ComboBoxItemMixin(ThemableMixin(DirMixin(PolymerElement))) {
|
|
36
38
|
static get template() {
|
|
37
39
|
return html`
|
|
38
40
|
<style>
|
|
@@ -54,119 +56,6 @@ export class ComboBoxItem extends ThemableMixin(DirMixin(PolymerElement)) {
|
|
|
54
56
|
static get is() {
|
|
55
57
|
return 'vaadin-combo-box-item';
|
|
56
58
|
}
|
|
57
|
-
|
|
58
|
-
static get properties() {
|
|
59
|
-
return {
|
|
60
|
-
/**
|
|
61
|
-
* The index of the item
|
|
62
|
-
*/
|
|
63
|
-
index: Number,
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* The item to render
|
|
67
|
-
* @type {(String|Object)}
|
|
68
|
-
*/
|
|
69
|
-
item: Object,
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* The text label corresponding to the item
|
|
73
|
-
*/
|
|
74
|
-
label: String,
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* True when item is selected
|
|
78
|
-
*/
|
|
79
|
-
selected: {
|
|
80
|
-
type: Boolean,
|
|
81
|
-
value: false,
|
|
82
|
-
reflectToAttribute: true,
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* True when item is focused
|
|
87
|
-
*/
|
|
88
|
-
focused: {
|
|
89
|
-
type: Boolean,
|
|
90
|
-
value: false,
|
|
91
|
-
reflectToAttribute: true,
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Custom function for rendering the content of the `<vaadin-combo-box-item>` propagated from the combo box element.
|
|
96
|
-
*/
|
|
97
|
-
renderer: Function,
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Saved instance of a custom renderer function.
|
|
101
|
-
*/
|
|
102
|
-
_oldRenderer: Function,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
static get observers() {
|
|
107
|
-
return ['__rendererOrItemChanged(renderer, index, item.*, selected, focused)', '__updateLabel(label, renderer)'];
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
connectedCallback() {
|
|
111
|
-
super.connectedCallback();
|
|
112
|
-
|
|
113
|
-
this._comboBox = this.parentNode.comboBox;
|
|
114
|
-
|
|
115
|
-
const hostDir = this._comboBox.getAttribute('dir');
|
|
116
|
-
if (hostDir) {
|
|
117
|
-
this.setAttribute('dir', hostDir);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Requests an update for the content of the item.
|
|
123
|
-
* While performing the update, it invokes the renderer passed in the `renderer` property.
|
|
124
|
-
*
|
|
125
|
-
* It is not guaranteed that the update happens immediately (synchronously) after it is requested.
|
|
126
|
-
*/
|
|
127
|
-
requestContentUpdate() {
|
|
128
|
-
if (!this.renderer) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const model = {
|
|
133
|
-
index: this.index,
|
|
134
|
-
item: this.item,
|
|
135
|
-
focused: this.focused,
|
|
136
|
-
selected: this.selected,
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
this.renderer(this, this._comboBox, model);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/** @private */
|
|
143
|
-
__rendererOrItemChanged(renderer, index, item) {
|
|
144
|
-
if (item === undefined || index === undefined) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (this._oldRenderer !== renderer) {
|
|
149
|
-
this.innerHTML = '';
|
|
150
|
-
// Whenever a Lit-based renderer is used, it assigns a Lit part to the node it was rendered into.
|
|
151
|
-
// When clearing the rendered content, this part needs to be manually disposed of.
|
|
152
|
-
// Otherwise, using a Lit-based renderer on the same node will throw an exception or render nothing afterward.
|
|
153
|
-
delete this._$litPart$;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (renderer) {
|
|
157
|
-
this._oldRenderer = renderer;
|
|
158
|
-
this.requestContentUpdate();
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/** @private */
|
|
163
|
-
__updateLabel(label, renderer) {
|
|
164
|
-
if (renderer) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
this.textContent = label;
|
|
169
|
-
}
|
|
170
59
|
}
|
|
171
60
|
|
|
172
61
|
customElements.define(ComboBoxItem.is, ComboBoxItem);
|
|
@@ -117,30 +117,6 @@ class ComboBoxLight extends ComboBoxDataProviderMixin(ComboBoxMixin(ValidateMixi
|
|
|
117
117
|
return this.querySelector('.clear-button');
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
/** @protected */
|
|
121
|
-
ready() {
|
|
122
|
-
super.ready();
|
|
123
|
-
|
|
124
|
-
this._toggleElement = this.querySelector('.toggle-button');
|
|
125
|
-
|
|
126
|
-
// Wait until the slotted input DOM is ready
|
|
127
|
-
afterNextRender(this, () => {
|
|
128
|
-
this._setInputElement(this.querySelector('vaadin-text-field,.input'));
|
|
129
|
-
this._revertInputValue();
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Returns true if the current input value satisfies all constraints (if any).
|
|
135
|
-
* @return {boolean}
|
|
136
|
-
*/
|
|
137
|
-
checkValidity() {
|
|
138
|
-
if (this.inputElement.validate) {
|
|
139
|
-
return this.inputElement.validate();
|
|
140
|
-
}
|
|
141
|
-
return super.checkValidity();
|
|
142
|
-
}
|
|
143
|
-
|
|
144
120
|
/**
|
|
145
121
|
* @return {string}
|
|
146
122
|
* @protected
|
|
@@ -181,6 +157,30 @@ class ComboBoxLight extends ComboBoxDataProviderMixin(ComboBoxMixin(ValidateMixi
|
|
|
181
157
|
return undefined;
|
|
182
158
|
}
|
|
183
159
|
|
|
160
|
+
/** @protected */
|
|
161
|
+
ready() {
|
|
162
|
+
super.ready();
|
|
163
|
+
|
|
164
|
+
this._toggleElement = this.querySelector('.toggle-button');
|
|
165
|
+
|
|
166
|
+
// Wait until the slotted input DOM is ready
|
|
167
|
+
afterNextRender(this, () => {
|
|
168
|
+
this._setInputElement(this.querySelector('vaadin-text-field,.input'));
|
|
169
|
+
this._revertInputValue();
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Returns true if the current input value satisfies all constraints (if any).
|
|
175
|
+
* @return {boolean}
|
|
176
|
+
*/
|
|
177
|
+
checkValidity() {
|
|
178
|
+
if (this.inputElement.validate) {
|
|
179
|
+
return this.inputElement.validate();
|
|
180
|
+
}
|
|
181
|
+
return super.checkValidity();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
184
|
/** @protected */
|
|
185
185
|
_isClearButton(event) {
|
|
186
186
|
return (
|
|
@@ -6,21 +6,14 @@
|
|
|
6
6
|
import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
7
|
import type { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js';
|
|
8
8
|
import type { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
|
|
9
|
+
import type { OverlayClassMixinClass } from '@vaadin/component-base/src/overlay-class-mixin.js';
|
|
9
10
|
import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
|
|
10
11
|
import type { ComboBox } from './vaadin-combo-box.js';
|
|
12
|
+
import type { ComboBoxDefaultItem, ComboBoxItemModel, ComboBoxItemRenderer } from './vaadin-combo-box-item-mixin.js';
|
|
11
13
|
|
|
12
|
-
export type ComboBoxDefaultItem
|
|
14
|
+
export type { ComboBoxDefaultItem, ComboBoxItemModel };
|
|
13
15
|
|
|
14
|
-
export
|
|
15
|
-
index: number;
|
|
16
|
-
item: TItem;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type ComboBoxRenderer<TItem> = (
|
|
20
|
-
root: HTMLElement,
|
|
21
|
-
comboBox: ComboBox<TItem>,
|
|
22
|
-
model: ComboBoxItemModel<TItem>,
|
|
23
|
-
) => void;
|
|
16
|
+
export type ComboBoxRenderer<TItem> = ComboBoxItemRenderer<TItem, ComboBox<TItem>>;
|
|
24
17
|
|
|
25
18
|
export declare function ComboBoxMixin<TItem, T extends Constructor<HTMLElement>>(
|
|
26
19
|
base: T,
|
|
@@ -28,6 +21,7 @@ export declare function ComboBoxMixin<TItem, T extends Constructor<HTMLElement>>
|
|
|
28
21
|
Constructor<DisabledMixinClass> &
|
|
29
22
|
Constructor<InputMixinClass> &
|
|
30
23
|
Constructor<KeyboardMixinClass> &
|
|
24
|
+
Constructor<OverlayClassMixinClass> &
|
|
31
25
|
T;
|
|
32
26
|
|
|
33
27
|
export declare class ComboBoxMixinClass<TItem> {
|
|
@@ -85,7 +79,7 @@ export declare class ComboBoxMixinClass<TItem> {
|
|
|
85
79
|
/**
|
|
86
80
|
* The `String` value for the selected item of the combo box.
|
|
87
81
|
*
|
|
88
|
-
* When there
|
|
82
|
+
* When there is no item selected, the value is an empty string.
|
|
89
83
|
*
|
|
90
84
|
* Use `selectedItem` property to get the raw selected item from
|
|
91
85
|
* the `items` array.
|
|
@@ -8,6 +8,7 @@ import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js'
|
|
|
8
8
|
import { DisabledMixin } from '@vaadin/component-base/src/disabled-mixin.js';
|
|
9
9
|
import { isElementFocused } from '@vaadin/component-base/src/focus-utils.js';
|
|
10
10
|
import { KeyboardMixin } from '@vaadin/component-base/src/keyboard-mixin.js';
|
|
11
|
+
import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
|
|
11
12
|
import { processTemplates } from '@vaadin/component-base/src/templates.js';
|
|
12
13
|
import { InputMixin } from '@vaadin/field-base/src/input-mixin.js';
|
|
13
14
|
import { VirtualKeyboardController } from '@vaadin/field-base/src/virtual-keyboard-controller.js';
|
|
@@ -43,10 +44,17 @@ function findItemIndex(items, callback) {
|
|
|
43
44
|
|
|
44
45
|
/**
|
|
45
46
|
* @polymerMixin
|
|
47
|
+
* @mixes ControllerMixin
|
|
48
|
+
* @mixes DisabledMixin
|
|
49
|
+
* @mixes InputMixin
|
|
50
|
+
* @mixes KeyboardMixin
|
|
51
|
+
* @mixes OverlayClassMixin
|
|
46
52
|
* @param {function(new:HTMLElement)} subclass
|
|
47
53
|
*/
|
|
48
54
|
export const ComboBoxMixin = (subclass) =>
|
|
49
|
-
class
|
|
55
|
+
class ComboBoxMixinClass extends OverlayClassMixin(
|
|
56
|
+
ControllerMixin(KeyboardMixin(InputMixin(DisabledMixin(subclass)))),
|
|
57
|
+
) {
|
|
50
58
|
static get properties() {
|
|
51
59
|
return {
|
|
52
60
|
/**
|
|
@@ -262,6 +270,24 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
262
270
|
return 'vaadin-combo-box';
|
|
263
271
|
}
|
|
264
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Get a reference to the native `<input>` element.
|
|
275
|
+
* Override to provide a custom input.
|
|
276
|
+
* @protected
|
|
277
|
+
* @return {HTMLInputElement | undefined}
|
|
278
|
+
*/
|
|
279
|
+
get _nativeInput() {
|
|
280
|
+
return this.inputElement;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* @return {string}
|
|
285
|
+
* @protected
|
|
286
|
+
*/
|
|
287
|
+
get _propertyForValue() {
|
|
288
|
+
return 'value';
|
|
289
|
+
}
|
|
290
|
+
|
|
265
291
|
/**
|
|
266
292
|
* @return {string | undefined}
|
|
267
293
|
* @protected
|
|
@@ -280,16 +306,6 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
280
306
|
}
|
|
281
307
|
}
|
|
282
308
|
|
|
283
|
-
/**
|
|
284
|
-
* Get a reference to the native `<input>` element.
|
|
285
|
-
* Override to provide a custom input.
|
|
286
|
-
* @protected
|
|
287
|
-
* @return {HTMLInputElement | undefined}
|
|
288
|
-
*/
|
|
289
|
-
get _nativeInput() {
|
|
290
|
-
return this.inputElement;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
309
|
/**
|
|
294
310
|
* Override method inherited from `InputMixin`
|
|
295
311
|
* to customize the input element.
|
|
@@ -339,7 +355,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
339
355
|
|
|
340
356
|
const bringToFrontListener = () => {
|
|
341
357
|
requestAnimationFrame(() => {
|
|
342
|
-
this
|
|
358
|
+
this._overlayElement.bringToFront();
|
|
343
359
|
});
|
|
344
360
|
};
|
|
345
361
|
|
|
@@ -430,6 +446,8 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
430
446
|
overlay.addEventListener('opened-changed', (e) => {
|
|
431
447
|
this._overlayOpened = e.detail.value;
|
|
432
448
|
});
|
|
449
|
+
|
|
450
|
+
this._overlayElement = overlay;
|
|
433
451
|
}
|
|
434
452
|
|
|
435
453
|
/**
|
|
@@ -441,7 +459,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
441
459
|
_initScroller(host) {
|
|
442
460
|
const scrollerTag = `${this._tagNamePrefix}-scroller`;
|
|
443
461
|
|
|
444
|
-
const overlay = this
|
|
462
|
+
const overlay = this._overlayElement;
|
|
445
463
|
|
|
446
464
|
overlay.renderer = (root) => {
|
|
447
465
|
if (!root.firstChild) {
|
|
@@ -454,7 +472,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
454
472
|
|
|
455
473
|
const scroller = overlay.querySelector(scrollerTag);
|
|
456
474
|
|
|
457
|
-
scroller.
|
|
475
|
+
scroller.owner = host || this;
|
|
458
476
|
scroller.getItemLabel = this._getItemLabel.bind(this);
|
|
459
477
|
scroller.addEventListener('selection-changed', this._boundOverlaySelectedItemChanged);
|
|
460
478
|
|
|
@@ -547,7 +565,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
547
565
|
this.focus();
|
|
548
566
|
}
|
|
549
567
|
|
|
550
|
-
this
|
|
568
|
+
this._overlayElement.restoreFocusOnClose = true;
|
|
551
569
|
} else {
|
|
552
570
|
this._onClosed();
|
|
553
571
|
if (this._openedWithFocusRing && this._isInputFocused()) {
|
|
@@ -646,7 +664,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
646
664
|
super._onKeyDown(e);
|
|
647
665
|
|
|
648
666
|
if (e.key === 'Tab') {
|
|
649
|
-
this
|
|
667
|
+
this._overlayElement.restoreFocusOnClose = false;
|
|
650
668
|
} else if (e.key === 'ArrowDown') {
|
|
651
669
|
this._onArrowDown();
|
|
652
670
|
|
|
@@ -944,14 +962,6 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
944
962
|
this.filter = '';
|
|
945
963
|
}
|
|
946
964
|
|
|
947
|
-
/**
|
|
948
|
-
* @return {string}
|
|
949
|
-
* @protected
|
|
950
|
-
*/
|
|
951
|
-
get _propertyForValue() {
|
|
952
|
-
return 'value';
|
|
953
|
-
}
|
|
954
|
-
|
|
955
965
|
/**
|
|
956
966
|
* Override an event listener from `InputMixin`.
|
|
957
967
|
* @param {!Event} event
|
|
@@ -1271,7 +1281,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
1271
1281
|
}
|
|
1272
1282
|
|
|
1273
1283
|
// Fixes the problem with `focusout` happening when clicking on the scroll bar on Edge
|
|
1274
|
-
if (event.relatedTarget === this
|
|
1284
|
+
if (event.relatedTarget === this._overlayElement) {
|
|
1275
1285
|
event.composedPath()[0].focus();
|
|
1276
1286
|
return;
|
|
1277
1287
|
}
|