@vaadin/combo-box 22.0.0-alpha9 → 22.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -28
- package/package.json +15 -15
- package/src/vaadin-combo-box-data-provider-mixin.d.ts +4 -9
- package/src/vaadin-combo-box-dropdown.js +5 -18
- package/src/vaadin-combo-box-item.js +11 -9
- package/src/vaadin-combo-box-light.d.ts +12 -6
- package/src/vaadin-combo-box-light.js +3 -3
- package/src/vaadin-combo-box-mixin.d.ts +17 -12
- package/src/vaadin-combo-box-mixin.js +18 -5
- package/src/vaadin-combo-box-overlay.js +12 -1
- package/src/vaadin-combo-box-scroller.js +13 -3
- package/src/vaadin-combo-box.d.ts +73 -69
- package/src/vaadin-combo-box.js +45 -64
- package/theme/lumo/vaadin-combo-box-dropdown-styles.js +2 -2
- package/theme/lumo/vaadin-combo-box-item-styles.js +4 -28
- package/theme/lumo/vaadin-combo-box-styles.js +1 -1
- package/theme/material/vaadin-combo-box-dropdown-styles.js +1 -1
- package/theme/material/vaadin-combo-box-item-styles.js +1 -18
- package/theme/material/vaadin-combo-box-styles.js +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @vaadin/combo-box
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
|
5
|
-
[API documentation ↗](https://vaadin.com/components/vaadin-combo-box/html-api)
|
|
3
|
+
A web component for choosing a value from a filterable list of options presented in an overlay.
|
|
6
4
|
|
|
7
|
-
[
|
|
5
|
+
[Documentation + Live Demo ↗](https://vaadin.com/docs/latest/ds/components/combo-box)
|
|
8
6
|
|
|
9
7
|
[](https://www.npmjs.com/package/@vaadin/combo-box)
|
|
10
|
-
[](https://vaadin.com/directory/component/vaadinvaadin-combo-box)
|
|
11
8
|
[](https://discord.gg/PHmkCKC)
|
|
12
9
|
|
|
13
10
|
```html
|
|
@@ -27,45 +24,44 @@
|
|
|
27
24
|
</script>
|
|
28
25
|
```
|
|
29
26
|
|
|
30
|
-
[<img src="https://raw.githubusercontent.com/vaadin/
|
|
27
|
+
[<img src="https://raw.githubusercontent.com/vaadin/web-components/master/packages/combo-box/screenshot.png" width="208" alt="Screenshot of vaadin-combo-box">](https://vaadin.com/docs/latest/ds/components/combo-box)
|
|
31
28
|
|
|
32
29
|
## Installation
|
|
33
30
|
|
|
34
|
-
Install
|
|
31
|
+
Install the component:
|
|
35
32
|
|
|
36
33
|
```sh
|
|
37
|
-
npm i @vaadin/combo-box
|
|
34
|
+
npm i @vaadin/combo-box
|
|
38
35
|
```
|
|
39
36
|
|
|
40
|
-
Once installed, import
|
|
37
|
+
Once installed, import the component in your application:
|
|
41
38
|
|
|
42
39
|
```js
|
|
43
|
-
import '@vaadin/combo-box
|
|
40
|
+
import '@vaadin/combo-box';
|
|
44
41
|
```
|
|
45
42
|
|
|
46
|
-
##
|
|
43
|
+
## Themes
|
|
47
44
|
|
|
48
|
-
Vaadin components
|
|
45
|
+
Vaadin components come with two built-in [themes](https://vaadin.com/docs/latest/ds/customization/using-themes), Lumo and Material.
|
|
46
|
+
The [main entrypoint](https://github.com/vaadin/web-components/blob/master/packages/combo-box/vaadin-combo-box.js) of the package uses the Lumo theme.
|
|
49
47
|
|
|
50
|
-
To use the Material theme, import the
|
|
48
|
+
To use the Material theme, import the component from the `theme/material` folder:
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
`theme/lumo/vaadin-combo-box.js`
|
|
57
|
-
`theme/lumo/vaadin-combo-box-light.js`
|
|
50
|
+
```js
|
|
51
|
+
import '@vaadin/combo-box/theme/material/vaadin-combo-box.js';
|
|
52
|
+
```
|
|
58
53
|
|
|
59
|
-
|
|
54
|
+
You can also import the Lumo version of the component explicitly:
|
|
60
55
|
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
```js
|
|
57
|
+
import '@vaadin/combo-box/theme/lumo/vaadin-combo-box.js';
|
|
58
|
+
```
|
|
63
59
|
|
|
64
|
-
-
|
|
65
|
-
`theme/lumo/vaadin-combo-box-light.js`
|
|
60
|
+
Finally, you can import the un-themed component from the `src` folder to get a minimal starting point:
|
|
66
61
|
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
```js
|
|
63
|
+
import '@vaadin/combo-box/src/vaadin-combo-box.js';
|
|
64
|
+
```
|
|
69
65
|
|
|
70
66
|
## Contributing
|
|
71
67
|
|
|
@@ -75,4 +71,5 @@ Read the [contributing guide](https://vaadin.com/docs/latest/guide/contributing/
|
|
|
75
71
|
|
|
76
72
|
Apache License 2.0
|
|
77
73
|
|
|
78
|
-
Vaadin collects development time
|
|
74
|
+
Vaadin collects usage statistics at development time to improve this product.
|
|
75
|
+
For details and to opt-out, see https://github.com/vaadin/vaadin-usage-statistics.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/combo-box",
|
|
3
|
-
"version": "22.0.0
|
|
3
|
+
"version": "22.0.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -31,26 +31,26 @@
|
|
|
31
31
|
"polymer"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
34
35
|
"@polymer/iron-resizable-behavior": "^3.0.0",
|
|
35
36
|
"@polymer/polymer": "^3.0.0",
|
|
36
|
-
"@vaadin/component-base": "22.0.0
|
|
37
|
-
"@vaadin/field-base": "22.0.0
|
|
38
|
-
"@vaadin/input-container": "22.0.0
|
|
39
|
-
"@vaadin/item": "22.0.0
|
|
40
|
-
"@vaadin/vaadin-lumo-styles": "22.0.0
|
|
41
|
-
"@vaadin/vaadin-material-styles": "22.0.0
|
|
42
|
-
"@vaadin/vaadin-overlay": "22.0.0
|
|
43
|
-
"@vaadin/vaadin-themable-mixin": "22.0.0
|
|
44
|
-
"@vaadin/virtual-list": "22.0.0-alpha9"
|
|
37
|
+
"@vaadin/component-base": "^22.0.0",
|
|
38
|
+
"@vaadin/field-base": "^22.0.0",
|
|
39
|
+
"@vaadin/input-container": "^22.0.0",
|
|
40
|
+
"@vaadin/item": "^22.0.0",
|
|
41
|
+
"@vaadin/vaadin-lumo-styles": "^22.0.0",
|
|
42
|
+
"@vaadin/vaadin-material-styles": "^22.0.0",
|
|
43
|
+
"@vaadin/vaadin-overlay": "^22.0.0",
|
|
44
|
+
"@vaadin/vaadin-themable-mixin": "^22.0.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@esm-bundle/chai": "^4.3.4",
|
|
48
|
-
"@vaadin/dialog": "22.0.0
|
|
49
|
-
"@vaadin/polymer-legacy-adapter": "22.0.0
|
|
50
|
-
"@vaadin/testing-helpers": "^0.3.
|
|
51
|
-
"@vaadin/text-field": "22.0.0
|
|
48
|
+
"@vaadin/dialog": "^22.0.0",
|
|
49
|
+
"@vaadin/polymer-legacy-adapter": "^22.0.0",
|
|
50
|
+
"@vaadin/testing-helpers": "^0.3.2",
|
|
51
|
+
"@vaadin/text-field": "^22.0.0",
|
|
52
52
|
"lit": "^2.0.0",
|
|
53
53
|
"sinon": "^9.2.0"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "b668e9b1a975227fbe34beb70d1cd5b03dce2348"
|
|
56
56
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
+
import { Constructor } from '@open-wc/dedupe-mixin';
|
|
6
7
|
|
|
7
8
|
export type ComboBoxDataProviderCallback<TItem> = (items: Array<TItem>, size: number) => void;
|
|
8
9
|
|
|
@@ -17,15 +18,11 @@ export type ComboBoxDataProvider<TItem> = (
|
|
|
17
18
|
callback: ComboBoxDataProviderCallback<TItem>
|
|
18
19
|
) => void;
|
|
19
20
|
|
|
20
|
-
declare function ComboBoxDataProviderMixin<TItem, T extends
|
|
21
|
+
export declare function ComboBoxDataProviderMixin<TItem, T extends Constructor<HTMLElement>>(
|
|
21
22
|
base: T
|
|
22
|
-
): T &
|
|
23
|
+
): T & Constructor<ComboBoxDataProviderMixinClass<TItem>>;
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
new (...args: any[]): ComboBoxDataProviderMixin<TItem>;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface ComboBoxDataProviderMixin<TItem> {
|
|
25
|
+
export declare class ComboBoxDataProviderMixinClass<TItem> {
|
|
29
26
|
/**
|
|
30
27
|
* Number of items fetched at a time from the dataprovider.
|
|
31
28
|
* @attr {number} page-size
|
|
@@ -57,5 +54,3 @@ interface ComboBoxDataProviderMixin<TItem> {
|
|
|
57
54
|
*/
|
|
58
55
|
clearCache(): void;
|
|
59
56
|
}
|
|
60
|
-
|
|
61
|
-
export { ComboBoxDataProviderMixin, ComboBoxDataProviderMixinConstructor };
|
|
@@ -3,21 +3,12 @@
|
|
|
3
3
|
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
|
|
7
|
-
import { mixinBehaviors } from '@polymer/polymer/lib/legacy/class.js';
|
|
8
|
-
import { IronResizableBehavior } from '@polymer/iron-resizable-behavior/iron-resizable-behavior.js';
|
|
9
6
|
import './vaadin-combo-box-item.js';
|
|
10
7
|
import './vaadin-combo-box-overlay.js';
|
|
11
8
|
import './vaadin-combo-box-scroller.js';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
document.createEvent('TouchEvent');
|
|
16
|
-
return true;
|
|
17
|
-
} catch (e) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
})();
|
|
9
|
+
import { IronResizableBehavior } from '@polymer/iron-resizable-behavior/iron-resizable-behavior.js';
|
|
10
|
+
import { mixinBehaviors } from '@polymer/polymer/lib/legacy/class.js';
|
|
11
|
+
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
21
12
|
|
|
22
13
|
/**
|
|
23
14
|
* Element for internal use only.
|
|
@@ -47,13 +38,9 @@ export class ComboBoxDropdown extends mixinBehaviors(IronResizableBehavior, Poly
|
|
|
47
38
|
static get properties() {
|
|
48
39
|
return {
|
|
49
40
|
/**
|
|
50
|
-
* True if the
|
|
41
|
+
* True if the combo-box has been activate by the user.
|
|
42
|
+
* The actual opened state depends on whether the dropdown has items.
|
|
51
43
|
*/
|
|
52
|
-
touchDevice: {
|
|
53
|
-
type: Boolean,
|
|
54
|
-
value: TOUCH_DEVICE
|
|
55
|
-
},
|
|
56
|
-
|
|
57
44
|
opened: Boolean,
|
|
58
45
|
|
|
59
46
|
/**
|
|
@@ -3,27 +3,28 @@
|
|
|
3
3
|
* Copyright (c) 2021 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 { 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
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* An item element used by the `<vaadin-combo-box>` dropdown.
|
|
12
12
|
*
|
|
13
13
|
* ### Styling
|
|
14
14
|
*
|
|
15
15
|
* The following shadow DOM parts are available for styling:
|
|
16
16
|
*
|
|
17
|
-
* Part name
|
|
18
|
-
*
|
|
19
|
-
* `
|
|
17
|
+
* Part name | Description
|
|
18
|
+
* ------------|--------------
|
|
19
|
+
* `checkmark` | The graphical checkmark shown for a selected item
|
|
20
|
+
* `content` | The element that wraps the item content
|
|
20
21
|
*
|
|
21
22
|
* The following state attributes are exposed for styling:
|
|
22
23
|
*
|
|
23
|
-
* Attribute | Description
|
|
24
|
-
*
|
|
25
|
-
* `selected`
|
|
26
|
-
* `focused`
|
|
24
|
+
* Attribute | Description
|
|
25
|
+
* -------------|-------------
|
|
26
|
+
* `selected` | Set when the item is selected
|
|
27
|
+
* `focused` | Set when the item is focused
|
|
27
28
|
*
|
|
28
29
|
* See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
|
|
29
30
|
*
|
|
@@ -43,6 +44,7 @@ export class ComboBoxItem extends ThemableMixin(DirMixin(PolymerElement)) {
|
|
|
43
44
|
display: none;
|
|
44
45
|
}
|
|
45
46
|
</style>
|
|
47
|
+
<span part="checkmark" aria-hidden="true"></span>
|
|
46
48
|
<div part="content">
|
|
47
49
|
<slot></slot>
|
|
48
50
|
</div>
|
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
* Copyright (c) 2021 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 {
|
|
8
|
-
import {
|
|
6
|
+
import { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js';
|
|
7
|
+
import { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
|
|
8
|
+
import { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
|
|
9
|
+
import { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
10
|
+
import { ComboBoxDataProviderMixinClass } from './vaadin-combo-box-data-provider-mixin.js';
|
|
11
|
+
import { ComboBoxMixinClass } from './vaadin-combo-box-mixin.js';
|
|
9
12
|
import { ComboBoxDefaultItem } from './vaadin-combo-box-mixin.js';
|
|
10
13
|
export {
|
|
11
14
|
ComboBoxDataProvider,
|
|
@@ -125,9 +128,12 @@ declare class ComboBoxLight<TItem = ComboBoxDefaultItem> extends HTMLElement {
|
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
interface ComboBoxLight<TItem = ComboBoxDefaultItem>
|
|
128
|
-
extends
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
extends ComboBoxDataProviderMixinClass<TItem>,
|
|
132
|
+
ComboBoxMixinClass<TItem>,
|
|
133
|
+
KeyboardMixinClass,
|
|
134
|
+
InputMixinClass,
|
|
135
|
+
DisabledMixinClass,
|
|
136
|
+
ThemableMixinClass {}
|
|
131
137
|
|
|
132
138
|
declare global {
|
|
133
139
|
interface HTMLElementTagNameMap {
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* Copyright (c) 2021 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 './vaadin-combo-box-dropdown.js';
|
|
7
7
|
import { dashToCamelCase } from '@polymer/polymer/lib/utils/case-map.js';
|
|
8
|
+
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
8
9
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
9
|
-
import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
|
|
10
10
|
import { ComboBoxDataProviderMixin } from './vaadin-combo-box-data-provider-mixin.js';
|
|
11
|
-
import './vaadin-combo-box-
|
|
11
|
+
import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* `<vaadin-combo-box-light>` is a customizable version of the `<vaadin-combo-box>` providing
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* Copyright (c) 2021 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 {
|
|
8
|
-
import {
|
|
6
|
+
import { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
|
+
import { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js';
|
|
8
|
+
import { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
|
|
9
|
+
import { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
|
|
9
10
|
import { ComboBox } from './vaadin-combo-box.js';
|
|
10
11
|
|
|
11
12
|
export type ComboBoxDefaultItem = any;
|
|
@@ -21,16 +22,22 @@ export type ComboBoxRenderer<TItem> = (
|
|
|
21
22
|
model: ComboBoxItemModel<TItem>
|
|
22
23
|
) => void;
|
|
23
24
|
|
|
24
|
-
declare function ComboBoxMixin<TItem, T extends
|
|
25
|
+
export declare function ComboBoxMixin<TItem, T extends Constructor<HTMLElement>>(
|
|
25
26
|
base: T
|
|
26
|
-
): T &
|
|
27
|
+
): T &
|
|
28
|
+
Constructor<ComboBoxMixinClass<TItem>> &
|
|
29
|
+
Constructor<DisabledMixinClass> &
|
|
30
|
+
Constructor<InputMixinClass> &
|
|
31
|
+
Constructor<KeyboardMixinClass>;
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
export declare class ComboBoxMixinClass<TItem> {
|
|
34
|
+
protected readonly _propertyForValue: string;
|
|
35
|
+
|
|
36
|
+
protected _inputElementValue: string | undefined;
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
protected _revertInputValue(): void;
|
|
39
|
+
|
|
40
|
+
protected _getItemElements(): HTMLElement[];
|
|
34
41
|
|
|
35
42
|
/**
|
|
36
43
|
* True if the dropdown is open, false otherwise.
|
|
@@ -173,5 +180,3 @@ interface ComboBoxMixin<TItem> extends DisabledMixin, InputMixin, KeyboardMixin
|
|
|
173
180
|
*/
|
|
174
181
|
checkValidity(): boolean;
|
|
175
182
|
}
|
|
176
|
-
|
|
177
|
-
export { ComboBoxMixin, ComboBoxMixinConstructor };
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
+
import { isTouch } from '@vaadin/component-base/src/browser-utils.js';
|
|
6
7
|
import { DisabledMixin } from '@vaadin/component-base/src/disabled-mixin.js';
|
|
7
8
|
import { KeyboardMixin } from '@vaadin/component-base/src/keyboard-mixin.js';
|
|
8
9
|
import { processTemplates } from '@vaadin/component-base/src/templates.js';
|
|
@@ -360,7 +361,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
360
361
|
this._openedWithFocusRing = this.hasAttribute('focus-ring');
|
|
361
362
|
// For touch devices, we don't want to popup virtual keyboard
|
|
362
363
|
// unless input element is explicitly focused by the user.
|
|
363
|
-
if (!this.hasAttribute('focused') && !
|
|
364
|
+
if (!this.hasAttribute('focused') && !isTouch) {
|
|
364
365
|
this.focus();
|
|
365
366
|
}
|
|
366
367
|
} else {
|
|
@@ -569,11 +570,14 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
569
570
|
_onEscape(e) {
|
|
570
571
|
if (this.autoOpenDisabled) {
|
|
571
572
|
// Auto-open is disabled
|
|
572
|
-
if (this.value !== this._inputElementValue) {
|
|
573
|
+
if (this.opened || (this.value !== this._inputElementValue && this._inputElementValue.length > 0)) {
|
|
574
|
+
// The overlay is open or
|
|
573
575
|
// The input value has changed but the change hasn't been committed, so cancel it.
|
|
576
|
+
e.stopPropagation();
|
|
574
577
|
this._focusedIndex = -1;
|
|
575
578
|
this.cancel();
|
|
576
|
-
} else if (this.clearButtonVisible && !this.opened) {
|
|
579
|
+
} else if (this.clearButtonVisible && !this.opened && !!this.value) {
|
|
580
|
+
e.stopPropagation();
|
|
577
581
|
// The clear button is visible and the overlay is closed, so clear the value.
|
|
578
582
|
this._clear();
|
|
579
583
|
}
|
|
@@ -591,7 +595,8 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
591
595
|
// No item is focused, cancel the change and close the overlay
|
|
592
596
|
this.cancel();
|
|
593
597
|
}
|
|
594
|
-
} else if (this.clearButtonVisible) {
|
|
598
|
+
} else if (this.clearButtonVisible && !!this.value) {
|
|
599
|
+
e.stopPropagation();
|
|
595
600
|
// The clear button is visible and the overlay is closed, so clear the value.
|
|
596
601
|
this._clear();
|
|
597
602
|
}
|
|
@@ -605,7 +610,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
605
610
|
toggleElement.addEventListener('mousedown', (e) => e.preventDefault());
|
|
606
611
|
// Unfocus previously focused element if focus is not inside combo box (on touch devices)
|
|
607
612
|
toggleElement.addEventListener('click', () => {
|
|
608
|
-
if (
|
|
613
|
+
if (isTouch && !this.hasAttribute('focused')) {
|
|
609
614
|
document.activeElement.blur();
|
|
610
615
|
}
|
|
611
616
|
});
|
|
@@ -930,6 +935,14 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
930
935
|
this.opened || this.autoOpenDisabled
|
|
931
936
|
? this.$.dropdown.indexOfLabel(this.filter)
|
|
932
937
|
: this._indexOfValue(this.value, this.filteredItems);
|
|
938
|
+
|
|
939
|
+
// see https://github.com/vaadin/web-components/issues/2615
|
|
940
|
+
if (this.selectedItem === null && this._focusedIndex >= 0) {
|
|
941
|
+
const filteredItem = this.filteredItems[this._focusedIndex];
|
|
942
|
+
if (this._getItemValue(filteredItem) === this.value) {
|
|
943
|
+
this._selectItemForValue(this.value);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
933
946
|
}
|
|
934
947
|
}
|
|
935
948
|
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { OverlayElement } from '@vaadin/vaadin-overlay/src/vaadin-overlay.js';
|
|
7
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
8
7
|
import { PositionMixin } from '@vaadin/vaadin-overlay/src/vaadin-overlay-position-mixin.js';
|
|
8
|
+
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
9
9
|
|
|
10
10
|
registerStyles(
|
|
11
11
|
'vaadin-combo-box-overlay',
|
|
@@ -23,6 +23,8 @@ registerStyles(
|
|
|
23
23
|
{ moduleId: 'vaadin-combo-box-overlay-styles' }
|
|
24
24
|
);
|
|
25
25
|
|
|
26
|
+
let memoizedTemplate;
|
|
27
|
+
|
|
26
28
|
/**
|
|
27
29
|
* An element used internally by `<vaadin-combo-box>`. Not intended to be used separately.
|
|
28
30
|
*
|
|
@@ -34,6 +36,15 @@ export class ComboBoxOverlay extends PositionMixin(OverlayElement) {
|
|
|
34
36
|
return 'vaadin-combo-box-overlay';
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
static get template() {
|
|
40
|
+
if (!memoizedTemplate) {
|
|
41
|
+
memoizedTemplate = super.template.cloneNode(true);
|
|
42
|
+
memoizedTemplate.content.querySelector('[part~="overlay"]').removeAttribute('tabindex');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return memoizedTemplate;
|
|
46
|
+
}
|
|
47
|
+
|
|
37
48
|
connectedCallback() {
|
|
38
49
|
super.connectedCallback();
|
|
39
50
|
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Copyright (c) 2021 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 { Virtualizer } from '@vaadin/
|
|
6
|
+
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
7
|
+
import { Virtualizer } from '@vaadin/component-base/src/virtualizer.js';
|
|
8
8
|
import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -81,7 +81,8 @@ export class ComboBoxScroller extends PolymerElement {
|
|
|
81
81
|
* calling `scrollIntoView` does not have any effect.
|
|
82
82
|
*/
|
|
83
83
|
opened: {
|
|
84
|
-
type: Boolean
|
|
84
|
+
type: Boolean,
|
|
85
|
+
observer: '__openedChanged'
|
|
85
86
|
},
|
|
86
87
|
|
|
87
88
|
/**
|
|
@@ -134,6 +135,12 @@ export class ComboBoxScroller extends PolymerElement {
|
|
|
134
135
|
this.__boundOnItemClick = this.__onItemClick.bind(this);
|
|
135
136
|
}
|
|
136
137
|
|
|
138
|
+
__openedChanged(opened) {
|
|
139
|
+
if (this.__virtualizer && opened) {
|
|
140
|
+
this.__virtualizer.update();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
137
144
|
/** @protected */
|
|
138
145
|
ready() {
|
|
139
146
|
super.ready();
|
|
@@ -226,6 +233,7 @@ export class ComboBoxScroller extends PolymerElement {
|
|
|
226
233
|
this.__virtualizer.flush();
|
|
227
234
|
// Ensure the total count of items is properly announced.
|
|
228
235
|
this.setAttribute('aria-setsize', items.length);
|
|
236
|
+
this.__virtualizer.update();
|
|
229
237
|
}
|
|
230
238
|
}
|
|
231
239
|
|
|
@@ -239,6 +247,7 @@ export class ComboBoxScroller extends PolymerElement {
|
|
|
239
247
|
/** @private */
|
|
240
248
|
__focusedIndexChanged(index) {
|
|
241
249
|
if (this.__virtualizer && index >= 0) {
|
|
250
|
+
this.__virtualizer.update();
|
|
242
251
|
this.scrollIntoView(index);
|
|
243
252
|
}
|
|
244
253
|
}
|
|
@@ -255,6 +264,7 @@ export class ComboBoxScroller extends PolymerElement {
|
|
|
255
264
|
return [...Array(count)].map(() => {
|
|
256
265
|
const item = document.createElement(`${this.__hostTagName}-item`);
|
|
257
266
|
item.addEventListener('click', this.__boundOnItemClick);
|
|
267
|
+
// Negative tabindex prevents the item content from being focused.
|
|
258
268
|
item.tabIndex = '-1';
|
|
259
269
|
item.style.width = '100%';
|
|
260
270
|
return item;
|
|
@@ -3,12 +3,23 @@
|
|
|
3
3
|
* Copyright (c) 2021 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 {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
6
|
+
import { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js';
|
|
7
|
+
import { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js';
|
|
8
|
+
import { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js';
|
|
9
|
+
import { FocusMixinClass } from '@vaadin/component-base/src/focus-mixin.js';
|
|
10
|
+
import { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
|
|
11
|
+
import { DelegateFocusMixinClass } from '@vaadin/field-base/src/delegate-focus-mixin.js';
|
|
12
|
+
import { DelegateStateMixinClass } from '@vaadin/field-base/src/delegate-state-mixin.js';
|
|
13
|
+
import { FieldMixinClass } from '@vaadin/field-base/src/field-mixin.js';
|
|
14
|
+
import { InputConstraintsMixinClass } from '@vaadin/field-base/src/input-constraints-mixin.js';
|
|
15
|
+
import { InputControlMixinClass } from '@vaadin/field-base/src/input-control-mixin.js';
|
|
16
|
+
import { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
|
|
17
|
+
import { LabelMixinClass } from '@vaadin/field-base/src/label-mixin.js';
|
|
18
|
+
import { PatternMixinClass } from '@vaadin/field-base/src/pattern-mixin.js';
|
|
19
|
+
import { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
|
|
20
|
+
import { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
21
|
+
import { ComboBoxDataProviderMixinClass } from './vaadin-combo-box-data-provider-mixin.js';
|
|
22
|
+
import { ComboBoxMixinClass } from './vaadin-combo-box-mixin.js';
|
|
12
23
|
import { ComboBoxDefaultItem } from './vaadin-combo-box-mixin.js';
|
|
13
24
|
export {
|
|
14
25
|
ComboBoxDataProvider,
|
|
@@ -62,77 +73,60 @@ export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap {
|
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
/**
|
|
65
|
-
* `<vaadin-combo-box>` is a
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* [`<vaadin-combo-box-light>`](#/elements/vaadin-combo-box-light) element.
|
|
69
|
-
*
|
|
70
|
-
* Items in the dropdown list must be provided as a list of `String` values.
|
|
71
|
-
* Defining the items is done using the `items` property, which can be assigned
|
|
72
|
-
* with data-binding, using an attribute or directly with the JavaScript property.
|
|
76
|
+
* `<vaadin-combo-box>` is a web component for choosing a value from a filterable list of options
|
|
77
|
+
* presented in a dropdown overlay. The options can be provided as a list of strings or objects
|
|
78
|
+
* by setting [`items`](#/elements/vaadin-combo-box#property-items) property on the element.
|
|
73
79
|
*
|
|
74
80
|
* ```html
|
|
75
|
-
* <vaadin-combo-box
|
|
76
|
-
* label="Fruit"
|
|
77
|
-
* items="[[data]]">
|
|
78
|
-
* </vaadin-combo-box>
|
|
81
|
+
* <vaadin-combo-box id="combo-box"></vaadin-combo-box>
|
|
79
82
|
* ```
|
|
80
83
|
*
|
|
81
84
|
* ```js
|
|
82
|
-
*
|
|
85
|
+
* document.querySelector('#combo-box').items = ['apple', 'orange', 'banana'];
|
|
83
86
|
* ```
|
|
84
87
|
*
|
|
85
88
|
* When the selected `value` is changed, a `value-changed` event is triggered.
|
|
86
89
|
*
|
|
87
90
|
* ### Item rendering
|
|
88
91
|
*
|
|
89
|
-
* `<vaadin-combo-box>`
|
|
90
|
-
*
|
|
92
|
+
* To customize the content of the `<vaadin-combo-box-item>` elements placed in the dropdown, use
|
|
93
|
+
* [`renderer`](#/elements/vaadin-combo-box#property-renderer) property which accepts a function.
|
|
94
|
+
* The renderer function is called with `root`, `comboBox`, and `model` as arguments.
|
|
91
95
|
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* content, users are able to check if there is already content in `root` for reusing it.
|
|
96
|
+
* Generate DOM content by using `model` object properties if needed, and append it to the `root`
|
|
97
|
+
* element. The `comboBox` reference is provided to access the combo-box element state. Do not
|
|
98
|
+
* set combo-box properties in a `renderer` function.
|
|
96
99
|
*
|
|
97
|
-
* ```html
|
|
98
|
-
* <vaadin-combo-box id="combo-box"></vaadin-combo-box>
|
|
99
|
-
* ```
|
|
100
100
|
* ```js
|
|
101
101
|
* const comboBox = document.querySelector('#combo-box');
|
|
102
102
|
* comboBox.items = [{'label': 'Hydrogen', 'value': 'H'}];
|
|
103
|
-
* comboBox.renderer =
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* '<b>' + model.item.value + '</b>';
|
|
103
|
+
* comboBox.renderer = (root, comboBox, model) => {
|
|
104
|
+
* const item = model.item;
|
|
105
|
+
* root.innerHTML = `${model.index}: ${item.label} <b>${item.value}</b>`;
|
|
107
106
|
* };
|
|
108
107
|
* ```
|
|
109
108
|
*
|
|
110
109
|
* Renderer is called on the opening of the combo-box and each time the related model is updated.
|
|
111
|
-
*
|
|
112
|
-
* in
|
|
113
|
-
*
|
|
110
|
+
* Before creating new content, it is recommended to check if there is already an existing DOM
|
|
111
|
+
* element in `root` from a previous renderer call for reusing it. Even though combo-box uses
|
|
112
|
+
* infinite scrolling, reducing DOM operations might improve performance.
|
|
114
113
|
*
|
|
115
114
|
* The following properties are available in the `model` argument:
|
|
116
115
|
*
|
|
117
|
-
* Property
|
|
118
|
-
*
|
|
119
|
-
* `index
|
|
120
|
-
* `item`
|
|
121
|
-
* `selected` | Boolean
|
|
122
|
-
* `focused`
|
|
116
|
+
* Property | Type | Description
|
|
117
|
+
* -----------|------------------|-------------
|
|
118
|
+
* `index` | Number | Index of the item in the `items` array
|
|
119
|
+
* `item` | String or Object | The item reference
|
|
120
|
+
* `selected` | Boolean | True when item is selected
|
|
121
|
+
* `focused` | Boolean | True when item is focused
|
|
123
122
|
*
|
|
124
123
|
* ### Lazy Loading with Function Data Provider
|
|
125
124
|
*
|
|
126
|
-
* In addition to assigning an array to the items property, you can alternatively
|
|
127
|
-
* provide the `<vaadin-combo-box>` data through the
|
|
125
|
+
* In addition to assigning an array to the items property, you can alternatively use the
|
|
128
126
|
* [`dataProvider`](#/elements/vaadin-combo-box#property-dataProvider) function property.
|
|
129
127
|
* The `<vaadin-combo-box>` calls this function lazily, only when it needs more data
|
|
130
128
|
* to be displayed.
|
|
131
129
|
*
|
|
132
|
-
* See the [`dataProvider`](#/elements/vaadin-combo-box#property-dataProvider) in
|
|
133
|
-
* the API reference below for the detailed data provider arguments description,
|
|
134
|
-
* and the “Lazy Loading“ example on “Basics” page in the demos.
|
|
135
|
-
*
|
|
136
130
|
* __Note that when using function data providers, the total number of items
|
|
137
131
|
* needs to be set manually. The total number of items can be returned
|
|
138
132
|
* in the second argument of the data provider callback:__
|
|
@@ -164,34 +158,33 @@ export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap {
|
|
|
164
158
|
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
165
159
|
* `--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
|
|
166
160
|
*
|
|
167
|
-
*
|
|
161
|
+
* `<vaadin-combo-box>` provides the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
|
|
162
|
+
* See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
|
|
163
|
+
*
|
|
164
|
+
* In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
|
|
168
165
|
*
|
|
169
|
-
* Part name
|
|
166
|
+
* Part name | Description
|
|
170
167
|
* ----------------|----------------
|
|
171
|
-
* `text-field` | The text field
|
|
172
168
|
* `toggle-button` | The toggle button
|
|
173
169
|
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* Attribute
|
|
177
|
-
*
|
|
178
|
-
* `opened`
|
|
179
|
-
* `disabled` | Set to a disabled combo box | :host
|
|
180
|
-
* `readonly` | Set to a read only combo box | :host
|
|
181
|
-
* `has-value` | Set when the element has a value | :host
|
|
182
|
-
* `invalid` | Set when the element is invalid | :host
|
|
183
|
-
* `focused` | Set when the element is focused | :host
|
|
184
|
-
* `focus-ring` | Set when the element is keyboard focused | :host
|
|
170
|
+
* In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
|
|
171
|
+
*
|
|
172
|
+
* Attribute | Description | Part name
|
|
173
|
+
* ----------|-------------|------------
|
|
174
|
+
* `opened` | Set when the combo box dropdown is open | :host
|
|
185
175
|
* `loading` | Set when new items are expected | :host
|
|
186
176
|
*
|
|
177
|
+
* If you want to replace the default `<input>` and its container with a custom implementation to get full control
|
|
178
|
+
* over the input field, consider using the [`<vaadin-combo-box-light>`](#/elements/vaadin-combo-box-light) element.
|
|
179
|
+
*
|
|
187
180
|
* ### Internal components
|
|
188
181
|
*
|
|
189
182
|
* In addition to `<vaadin-combo-box>` itself, the following internal
|
|
190
183
|
* components are themable:
|
|
191
184
|
*
|
|
192
185
|
* - `<vaadin-combo-box-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
|
|
193
|
-
* -
|
|
194
|
-
* - `<vaadin-
|
|
186
|
+
* - `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).
|
|
187
|
+
* - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
|
|
195
188
|
*
|
|
196
189
|
* Note: the `theme` attribute value set on `<vaadin-combo-box>` is
|
|
197
190
|
* propagated to the internal components listed above.
|
|
@@ -221,12 +214,23 @@ declare class ComboBox<TItem = ComboBoxDefaultItem> extends HTMLElement {
|
|
|
221
214
|
}
|
|
222
215
|
|
|
223
216
|
interface ComboBox<TItem = ComboBoxDefaultItem>
|
|
224
|
-
extends
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
217
|
+
extends ComboBoxDataProviderMixinClass<TItem>,
|
|
218
|
+
ComboBoxMixinClass<TItem>,
|
|
219
|
+
ValidateMixinClass,
|
|
220
|
+
PatternMixinClass,
|
|
221
|
+
LabelMixinClass,
|
|
222
|
+
KeyboardMixinClass,
|
|
223
|
+
InputMixinClass,
|
|
224
|
+
InputControlMixinClass,
|
|
225
|
+
InputConstraintsMixinClass,
|
|
226
|
+
FocusMixinClass,
|
|
227
|
+
FieldMixinClass,
|
|
228
|
+
DisabledMixinClass,
|
|
229
|
+
DelegateStateMixinClass,
|
|
230
|
+
DelegateFocusMixinClass,
|
|
231
|
+
ThemableMixinClass,
|
|
232
|
+
ElementMixinClass,
|
|
233
|
+
ControllerMixinClass {}
|
|
230
234
|
|
|
231
235
|
declare global {
|
|
232
236
|
interface HTMLElementTagNameMap {
|
package/src/vaadin-combo-box.js
CHANGED
|
@@ -3,94 +3,76 @@
|
|
|
3
3
|
* Copyright (c) 2021 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 '@vaadin/input-container/src/vaadin-input-container.js';
|
|
7
|
+
import './vaadin-combo-box-dropdown.js';
|
|
8
|
+
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
7
9
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
8
|
-
import { AriaLabelController } from '@vaadin/field-base/src/aria-label-controller.js';
|
|
9
|
-
import { InputController } from '@vaadin/field-base/src/input-controller.js';
|
|
10
10
|
import { InputControlMixin } from '@vaadin/field-base/src/input-control-mixin.js';
|
|
11
|
+
import { InputController } from '@vaadin/field-base/src/input-controller.js';
|
|
12
|
+
import { LabelledInputController } from '@vaadin/field-base/src/labelled-input-controller.js';
|
|
11
13
|
import { PatternMixin } from '@vaadin/field-base/src/pattern-mixin.js';
|
|
12
14
|
import { inputFieldShared } from '@vaadin/field-base/src/styles/input-field-shared-styles.js';
|
|
13
|
-
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
14
|
-
import { registerStyles } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
15
|
-
import '@vaadin/input-container/src/vaadin-input-container.js';
|
|
15
|
+
import { registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
16
16
|
import { ComboBoxDataProviderMixin } from './vaadin-combo-box-data-provider-mixin.js';
|
|
17
17
|
import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
|
|
18
|
-
import './vaadin-combo-box-dropdown.js';
|
|
19
18
|
|
|
20
19
|
registerStyles('vaadin-combo-box', inputFieldShared, { moduleId: 'vaadin-combo-box-styles' });
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
|
-
* `<vaadin-combo-box>` is a
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* [`<vaadin-combo-box-light>`](#/elements/vaadin-combo-box-light) element.
|
|
27
|
-
*
|
|
28
|
-
* Items in the dropdown list must be provided as a list of `String` values.
|
|
29
|
-
* Defining the items is done using the `items` property, which can be assigned
|
|
30
|
-
* with data-binding, using an attribute or directly with the JavaScript property.
|
|
22
|
+
* `<vaadin-combo-box>` is a web component for choosing a value from a filterable list of options
|
|
23
|
+
* presented in a dropdown overlay. The options can be provided as a list of strings or objects
|
|
24
|
+
* by setting [`items`](#/elements/vaadin-combo-box#property-items) property on the element.
|
|
31
25
|
*
|
|
32
26
|
* ```html
|
|
33
|
-
* <vaadin-combo-box
|
|
34
|
-
* label="Fruit"
|
|
35
|
-
* items="[[data]]">
|
|
36
|
-
* </vaadin-combo-box>
|
|
27
|
+
* <vaadin-combo-box id="combo-box"></vaadin-combo-box>
|
|
37
28
|
* ```
|
|
38
29
|
*
|
|
39
30
|
* ```js
|
|
40
|
-
*
|
|
31
|
+
* document.querySelector('#combo-box').items = ['apple', 'orange', 'banana'];
|
|
41
32
|
* ```
|
|
42
33
|
*
|
|
43
34
|
* When the selected `value` is changed, a `value-changed` event is triggered.
|
|
44
35
|
*
|
|
45
36
|
* ### Item rendering
|
|
46
37
|
*
|
|
47
|
-
* `<vaadin-combo-box>`
|
|
48
|
-
*
|
|
38
|
+
* To customize the content of the `<vaadin-combo-box-item>` elements placed in the dropdown, use
|
|
39
|
+
* [`renderer`](#/elements/vaadin-combo-box#property-renderer) property which accepts a function.
|
|
40
|
+
* The renderer function is called with `root`, `comboBox`, and `model` as arguments.
|
|
49
41
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* content, users are able to check if there is already content in `root` for reusing it.
|
|
42
|
+
* Generate DOM content by using `model` object properties if needed, and append it to the `root`
|
|
43
|
+
* element. The `comboBox` reference is provided to access the combo-box element state. Do not
|
|
44
|
+
* set combo-box properties in a `renderer` function.
|
|
54
45
|
*
|
|
55
|
-
* ```html
|
|
56
|
-
* <vaadin-combo-box id="combo-box"></vaadin-combo-box>
|
|
57
|
-
* ```
|
|
58
46
|
* ```js
|
|
59
47
|
* const comboBox = document.querySelector('#combo-box');
|
|
60
48
|
* comboBox.items = [{'label': 'Hydrogen', 'value': 'H'}];
|
|
61
|
-
* comboBox.renderer =
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* '<b>' + model.item.value + '</b>';
|
|
49
|
+
* comboBox.renderer = (root, comboBox, model) => {
|
|
50
|
+
* const item = model.item;
|
|
51
|
+
* root.innerHTML = `${model.index}: ${item.label} <b>${item.value}</b>`;
|
|
65
52
|
* };
|
|
66
53
|
* ```
|
|
67
54
|
*
|
|
68
55
|
* Renderer is called on the opening of the combo-box and each time the related model is updated.
|
|
69
|
-
*
|
|
70
|
-
* in
|
|
71
|
-
*
|
|
56
|
+
* Before creating new content, it is recommended to check if there is already an existing DOM
|
|
57
|
+
* element in `root` from a previous renderer call for reusing it. Even though combo-box uses
|
|
58
|
+
* infinite scrolling, reducing DOM operations might improve performance.
|
|
72
59
|
*
|
|
73
60
|
* The following properties are available in the `model` argument:
|
|
74
61
|
*
|
|
75
|
-
* Property
|
|
76
|
-
*
|
|
77
|
-
* `index
|
|
78
|
-
* `item`
|
|
79
|
-
* `selected` | Boolean
|
|
80
|
-
* `focused`
|
|
62
|
+
* Property | Type | Description
|
|
63
|
+
* -----------|------------------|-------------
|
|
64
|
+
* `index` | Number | Index of the item in the `items` array
|
|
65
|
+
* `item` | String or Object | The item reference
|
|
66
|
+
* `selected` | Boolean | True when item is selected
|
|
67
|
+
* `focused` | Boolean | True when item is focused
|
|
81
68
|
*
|
|
82
69
|
* ### Lazy Loading with Function Data Provider
|
|
83
70
|
*
|
|
84
|
-
* In addition to assigning an array to the items property, you can alternatively
|
|
85
|
-
* provide the `<vaadin-combo-box>` data through the
|
|
71
|
+
* In addition to assigning an array to the items property, you can alternatively use the
|
|
86
72
|
* [`dataProvider`](#/elements/vaadin-combo-box#property-dataProvider) function property.
|
|
87
73
|
* The `<vaadin-combo-box>` calls this function lazily, only when it needs more data
|
|
88
74
|
* to be displayed.
|
|
89
75
|
*
|
|
90
|
-
* See the [`dataProvider`](#/elements/vaadin-combo-box#property-dataProvider) in
|
|
91
|
-
* the API reference below for the detailed data provider arguments description,
|
|
92
|
-
* and the “Lazy Loading“ example on “Basics” page in the demos.
|
|
93
|
-
*
|
|
94
76
|
* __Note that when using function data providers, the total number of items
|
|
95
77
|
* needs to be set manually. The total number of items can be returned
|
|
96
78
|
* in the second argument of the data provider callback:__
|
|
@@ -122,34 +104,33 @@ registerStyles('vaadin-combo-box', inputFieldShared, { moduleId: 'vaadin-combo-b
|
|
|
122
104
|
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
123
105
|
* `--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
|
|
124
106
|
*
|
|
125
|
-
*
|
|
107
|
+
* `<vaadin-combo-box>` provides the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
|
|
108
|
+
* See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
|
|
109
|
+
*
|
|
110
|
+
* In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
|
|
126
111
|
*
|
|
127
|
-
* Part name
|
|
112
|
+
* Part name | Description
|
|
128
113
|
* ----------------|----------------
|
|
129
|
-
* `text-field` | The text field
|
|
130
114
|
* `toggle-button` | The toggle button
|
|
131
115
|
*
|
|
132
|
-
*
|
|
116
|
+
* In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
|
|
133
117
|
*
|
|
134
|
-
* Attribute
|
|
135
|
-
*
|
|
136
|
-
* `opened`
|
|
137
|
-
* `disabled` | Set to a disabled combo box | :host
|
|
138
|
-
* `readonly` | Set to a read only combo box | :host
|
|
139
|
-
* `has-value` | Set when the element has a value | :host
|
|
140
|
-
* `invalid` | Set when the element is invalid | :host
|
|
141
|
-
* `focused` | Set when the element is focused | :host
|
|
142
|
-
* `focus-ring` | Set when the element is keyboard focused | :host
|
|
118
|
+
* Attribute | Description | Part name
|
|
119
|
+
* ----------|-------------|------------
|
|
120
|
+
* `opened` | Set when the combo box dropdown is open | :host
|
|
143
121
|
* `loading` | Set when new items are expected | :host
|
|
144
122
|
*
|
|
123
|
+
* If you want to replace the default `<input>` and its container with a custom implementation to get full control
|
|
124
|
+
* over the input field, consider using the [`<vaadin-combo-box-light>`](#/elements/vaadin-combo-box-light) element.
|
|
125
|
+
*
|
|
145
126
|
* ### Internal components
|
|
146
127
|
*
|
|
147
128
|
* In addition to `<vaadin-combo-box>` itself, the following internal
|
|
148
129
|
* components are themable:
|
|
149
130
|
*
|
|
150
131
|
* - `<vaadin-combo-box-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
|
|
151
|
-
* -
|
|
152
|
-
* - `<vaadin-
|
|
132
|
+
* - `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).
|
|
133
|
+
* - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
|
|
153
134
|
*
|
|
154
135
|
* Note: the `theme` attribute value set on `<vaadin-combo-box>` is
|
|
155
136
|
* propagated to the internal components listed above.
|
|
@@ -261,7 +242,7 @@ class ComboBox extends ComboBoxDataProviderMixin(
|
|
|
261
242
|
this.ariaTarget = input;
|
|
262
243
|
})
|
|
263
244
|
);
|
|
264
|
-
this.addController(new
|
|
245
|
+
this.addController(new LabelledInputController(this.inputElement, this._labelNode));
|
|
265
246
|
this._positionTarget = this.shadowRoot.querySelector('[part="input-field"]');
|
|
266
247
|
this._toggleElement = this.$.toggleButton;
|
|
267
248
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
2
1
|
import '@vaadin/vaadin-lumo-styles/color.js';
|
|
3
2
|
import '@vaadin/vaadin-lumo-styles/spacing.js';
|
|
4
3
|
import '@vaadin/vaadin-lumo-styles/style.js';
|
|
5
|
-
import { overlay } from '@vaadin/vaadin-lumo-styles/mixins/overlay.js';
|
|
6
4
|
import '@vaadin/vaadin-overlay/theme/lumo/vaadin-overlay.js';
|
|
7
5
|
import { menuOverlayCore } from '@vaadin/vaadin-lumo-styles/mixins/menu-overlay.js';
|
|
6
|
+
import { overlay } from '@vaadin/vaadin-lumo-styles/mixins/overlay.js';
|
|
7
|
+
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
8
8
|
|
|
9
9
|
const comboBoxOverlay = css`
|
|
10
10
|
[part='content'] {
|
|
@@ -1,45 +1,21 @@
|
|
|
1
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
2
|
-
import { item } from '@vaadin/item/theme/lumo/vaadin-item-styles.js';
|
|
3
1
|
import '@vaadin/vaadin-lumo-styles/color.js';
|
|
4
2
|
import '@vaadin/vaadin-lumo-styles/spacing.js';
|
|
5
3
|
import '@vaadin/vaadin-lumo-styles/style.js';
|
|
4
|
+
import { item } from '@vaadin/item/theme/lumo/vaadin-item-styles.js';
|
|
5
|
+
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
6
6
|
|
|
7
|
-
/* TODO partly duplicated from vaadin-list-box styles. Should find a way to make it DRY */
|
|
8
7
|
const comboBoxItem = css`
|
|
9
8
|
:host {
|
|
10
|
-
cursor: default;
|
|
11
|
-
-webkit-tap-highlight-color: var(--lumo-primary-color-10pct);
|
|
12
|
-
padding-left: calc(var(--lumo-border-radius-m) / 4);
|
|
13
|
-
padding-right: calc(var(--lumo-space-l) + var(--lumo-border-radius-m) / 4);
|
|
14
9
|
transition: background-color 100ms;
|
|
15
|
-
border-radius: var(--lumo-border-radius-m);
|
|
16
10
|
overflow: hidden;
|
|
17
11
|
--_lumo-item-selected-icon-display: block;
|
|
18
12
|
}
|
|
19
13
|
|
|
20
|
-
|
|
21
|
-
background-color: var(--lumo-primary-color-10pct);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
:host([focused]:not([disabled])) {
|
|
25
|
-
box-shadow: inset 0 0 0 2px var(--lumo-primary-color-50pct);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
@media (pointer: coarse) {
|
|
29
|
-
:host(:hover) {
|
|
30
|
-
background-color: transparent;
|
|
31
|
-
}
|
|
32
|
-
|
|
14
|
+
@media (any-hover: hover) {
|
|
33
15
|
:host([focused]:not([disabled])) {
|
|
34
|
-
box-shadow:
|
|
16
|
+
box-shadow: inset 0 0 0 2px var(--lumo-primary-color-50pct);
|
|
35
17
|
}
|
|
36
18
|
}
|
|
37
|
-
|
|
38
|
-
/* RTL specific styles */
|
|
39
|
-
:host([dir='rtl']) {
|
|
40
|
-
padding-right: calc(var(--lumo-border-radius-m) / 4);
|
|
41
|
-
padding-left: calc(var(--lumo-space-l) + var(--lumo-border-radius-m) / 4);
|
|
42
|
-
}
|
|
43
19
|
`;
|
|
44
20
|
|
|
45
21
|
registerStyles('vaadin-combo-box-item', [item, comboBoxItem], {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
2
1
|
import '@vaadin/vaadin-lumo-styles/font-icons.js';
|
|
3
2
|
import { inputFieldShared } from '@vaadin/vaadin-lumo-styles/mixins/input-field-shared.js';
|
|
3
|
+
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
4
4
|
|
|
5
5
|
const comboBox = css`
|
|
6
6
|
:host {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
2
1
|
import '@vaadin/vaadin-material-styles/color.js';
|
|
3
2
|
import { menuOverlay } from '@vaadin/vaadin-material-styles/mixins/menu-overlay.js';
|
|
3
|
+
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
4
4
|
|
|
5
5
|
const comboBoxOverlay = css`
|
|
6
6
|
:host {
|
|
@@ -1,33 +1,16 @@
|
|
|
1
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
2
1
|
import '@vaadin/vaadin-material-styles/color.js';
|
|
3
2
|
import '@vaadin/vaadin-material-styles/font-icons.js';
|
|
4
3
|
import '@vaadin/vaadin-material-styles/typography.js';
|
|
5
4
|
import { item } from '@vaadin/item/theme/material/vaadin-item-styles.js';
|
|
5
|
+
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
6
6
|
|
|
7
7
|
const comboBoxItem = css`
|
|
8
8
|
:host {
|
|
9
9
|
cursor: pointer;
|
|
10
10
|
-webkit-tap-highlight-color: transparent;
|
|
11
11
|
padding: 4px 10px;
|
|
12
|
-
min-height: 36px;
|
|
13
|
-
font-size: var(--material-small-font-size);
|
|
14
12
|
--_material-item-selected-icon-display: block;
|
|
15
13
|
}
|
|
16
|
-
|
|
17
|
-
:host(:hover) {
|
|
18
|
-
background-color: var(--material-secondary-background-color);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
:host([focused]) {
|
|
22
|
-
background-color: var(--material-divider-color);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@media (pointer: coarse) {
|
|
26
|
-
:host(:hover),
|
|
27
|
-
:host([focused]) {
|
|
28
|
-
background-color: transparent;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
14
|
`;
|
|
32
15
|
|
|
33
16
|
registerStyles('vaadin-combo-box-item', [item, comboBoxItem], {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
2
1
|
import '@vaadin/vaadin-material-styles/color.js';
|
|
3
2
|
import '@vaadin/vaadin-material-styles/font-icons.js';
|
|
4
3
|
import { inputFieldShared } from '@vaadin/vaadin-material-styles/mixins/input-field-shared.js';
|
|
4
|
+
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
5
5
|
|
|
6
6
|
const comboBox = css`
|
|
7
7
|
:host {
|