@vaadin/combo-box 25.3.0 → 25.4.0-dev.55bb86e155
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/custom-elements.json +39 -1
- package/package.json +14 -14
- package/src/vaadin-combo-box-base-mixin.d.ts +2 -0
- package/src/vaadin-combo-box-base-mixin.js +22 -44
- package/src/vaadin-combo-box-focus-index-mixin.js +2 -2
- package/src/vaadin-combo-box-highlight-mixin.d.ts +18 -0
- package/src/vaadin-combo-box-highlight-mixin.js +109 -0
- package/src/vaadin-combo-box-items-mixin.js +20 -26
- package/src/vaadin-combo-box-mixin.js +4 -4
- package/src/vaadin-combo-box.d.ts +3 -0
- package/src/vaadin-combo-box.js +3 -0
- package/web-types.json +2 -2
- package/web-types.lit.json +2 -2
package/custom-elements.json
CHANGED
|
@@ -155,6 +155,10 @@
|
|
|
155
155
|
}
|
|
156
156
|
],
|
|
157
157
|
"mixins": [
|
|
158
|
+
{
|
|
159
|
+
"name": "ComboBoxHighlightMixin",
|
|
160
|
+
"module": "src/vaadin-combo-box-highlight-mixin.js"
|
|
161
|
+
},
|
|
158
162
|
{
|
|
159
163
|
"name": "KeyboardMixin",
|
|
160
164
|
"package": "@vaadin/a11y-base/src/keyboard-mixin.js"
|
|
@@ -306,6 +310,40 @@
|
|
|
306
310
|
}
|
|
307
311
|
]
|
|
308
312
|
},
|
|
313
|
+
{
|
|
314
|
+
"kind": "javascript-module",
|
|
315
|
+
"path": "src/vaadin-combo-box-highlight-mixin.js",
|
|
316
|
+
"declarations": [
|
|
317
|
+
{
|
|
318
|
+
"kind": "mixin",
|
|
319
|
+
"description": "A mixin that tracks which element of a combo box has the keyboard highlight\nwhile the DOM focus stays in the input. Only one element is highlighted at\na time.\n\nThe state is one of:\n\n- `{ type: 'none' }`: nothing is highlighted.\n- `{ type: 'item', index }`: the dropdown item at `index`.\n\nMixins applied on top can add more types by calling `_setHighlightState()`.",
|
|
320
|
+
"name": "ComboBoxHighlightMixin",
|
|
321
|
+
"members": [],
|
|
322
|
+
"attributes": [],
|
|
323
|
+
"parameters": [
|
|
324
|
+
{
|
|
325
|
+
"name": "superClass"
|
|
326
|
+
}
|
|
327
|
+
],
|
|
328
|
+
"mixins": [
|
|
329
|
+
{
|
|
330
|
+
"name": "dedupeMixin",
|
|
331
|
+
"package": "@open-wc/dedupe-mixin"
|
|
332
|
+
}
|
|
333
|
+
]
|
|
334
|
+
}
|
|
335
|
+
],
|
|
336
|
+
"exports": [
|
|
337
|
+
{
|
|
338
|
+
"kind": "js",
|
|
339
|
+
"name": "ComboBoxHighlightMixin",
|
|
340
|
+
"declaration": {
|
|
341
|
+
"name": "ComboBoxHighlightMixin",
|
|
342
|
+
"module": "src/vaadin-combo-box-highlight-mixin.js"
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
]
|
|
346
|
+
},
|
|
309
347
|
{
|
|
310
348
|
"kind": "javascript-module",
|
|
311
349
|
"path": "src/vaadin-combo-box-item-mixin.js",
|
|
@@ -1781,7 +1819,7 @@
|
|
|
1781
1819
|
"declarations": [
|
|
1782
1820
|
{
|
|
1783
1821
|
"kind": "class",
|
|
1784
|
-
"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`](#/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\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`](#/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`](#/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 shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------|----------------\n`label` | The label element\n`input-field` | The element that wraps prefix, value and buttons\n`field-button` | Set on both clear and toggle buttons\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n`overlay` | The overlay container\n`content` | The overlay content\n`loader` | The loading indicator shown while loading items\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------------|---------------------------------\n`disabled` | Set when the element is disabled\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`has-tooltip` | Set when the element has a slotted tooltip\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`readonly` | Set when the element is readonly\n`opened` | Set when the overlay is opened\n`loading` | Set when loading items from the data provider\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:--------------------------------------------------|\n| `--vaadin-combo-box-overlay-max-height` |\n| `--vaadin-combo-box-overlay-width` |\n| `--vaadin-field-default-width` |\n| `--vaadin-input-field-background` |\n| `--vaadin-input-field-border-color` |\n| `--vaadin-input-field-border-radius` |\n| `--vaadin-input-field-border-width` |\n| `--vaadin-input-field-bottom-end-radius` |\n| `--vaadin-input-field-bottom-start-radius` |\n| `--vaadin-input-field-button-text-color` |\n| `--vaadin-input-field-container-gap` |\n| `--vaadin-input-field-disabled-background` |\n| `--vaadin-input-field-disabled-text-color` |\n| `--vaadin-input-field-error-color` |\n| `--vaadin-input-field-error-font-size` |\n| `--vaadin-input-field-error-font-weight` |\n| `--vaadin-input-field-error-line-height` |\n| `--vaadin-input-field-gap` |\n| `--vaadin-input-field-helper-color` |\n| `--vaadin-input-field-helper-font-size` |\n| `--vaadin-input-field-helper-font-weight` |\n| `--vaadin-input-field-helper-line-height` |\n| `--vaadin-input-field-label-color` |\n| `--vaadin-input-field-label-font-size` |\n| `--vaadin-input-field-label-font-weight` |\n| `--vaadin-input-field-label-line-height` |\n| `--vaadin-input-field-padding` |\n| `--vaadin-input-field-placeholder-color` |\n| `--vaadin-input-field-required-indicator` |\n| `--vaadin-input-field-required-indicator-color` |\n| `--vaadin-input-field-top-end-radius` |\n| `--vaadin-input-field-top-start-radius` |\n| `--vaadin-input-field-value-color` |\n| `--vaadin-input-field-value-font-size` |\n| `--vaadin-input-field-value-font-weight` |\n| `--vaadin-input-field-value-line-height` |\n| `--vaadin-item-overlay-padding` |\n\n### Internal components\n\nIn addition to `<vaadin-combo-box>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
|
|
1822
|
+
"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`](#/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\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`](#/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`](#/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 shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------|----------------\n`label` | The label element\n`input-field` | The element that wraps prefix, value and buttons\n`field-button` | Set on both clear and toggle buttons\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n`overlay` | The overlay container\n`content` | The overlay content\n`loader` | The loading indicator shown while loading items\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------------|---------------------------------\n`disabled` | Set when the element is disabled\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`has-tooltip` | Set when the element has a slotted tooltip\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`readonly` | Set when the element is readonly\n`opened` | Set when the overlay is opened\n`loading` | Set when loading items from the data provider\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:--------------------------------------------------|\n| `--vaadin-combo-box-overlay-max-height` |\n| `--vaadin-combo-box-overlay-width` |\n| `--vaadin-field-default-width` |\n| `--vaadin-input-field-background` |\n| `--vaadin-input-field-border-color` |\n| `--vaadin-input-field-border-radius` |\n| `--vaadin-input-field-border-width` |\n| `--vaadin-input-field-bottom-end-radius` |\n| `--vaadin-input-field-bottom-start-radius` |\n| `--vaadin-input-field-button-text-color` |\n| `--vaadin-input-field-container-gap` |\n| `--vaadin-input-field-disabled-background` |\n| `--vaadin-input-field-disabled-text-color` |\n| `--vaadin-input-field-error-color` |\n| `--vaadin-input-field-error-font-size` |\n| `--vaadin-input-field-error-font-weight` |\n| `--vaadin-input-field-error-line-height` |\n| `--vaadin-input-field-gap` |\n| `--vaadin-input-field-helper-color` |\n| `--vaadin-input-field-helper-font-size` |\n| `--vaadin-input-field-helper-font-weight` |\n| `--vaadin-input-field-helper-line-height` |\n| `--vaadin-input-field-label-aside-gap` |\n| `--vaadin-input-field-label-aside-text-align` |\n| `--vaadin-input-field-label-aside-width` |\n| `--vaadin-input-field-label-color` |\n| `--vaadin-input-field-label-font-size` |\n| `--vaadin-input-field-label-font-weight` |\n| `--vaadin-input-field-label-line-height` |\n| `--vaadin-input-field-padding` |\n| `--vaadin-input-field-placeholder-color` |\n| `--vaadin-input-field-required-indicator` |\n| `--vaadin-input-field-required-indicator-color` |\n| `--vaadin-input-field-top-end-radius` |\n| `--vaadin-input-field-top-start-radius` |\n| `--vaadin-input-field-value-color` |\n| `--vaadin-input-field-value-font-size` |\n| `--vaadin-input-field-value-font-weight` |\n| `--vaadin-input-field-value-line-height` |\n| `--vaadin-item-overlay-padding` |\n\n### Internal components\n\nIn addition to `<vaadin-combo-box>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
|
|
1785
1823
|
"name": "ComboBox",
|
|
1786
1824
|
"members": [
|
|
1787
1825
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/combo-box",
|
|
3
|
-
"version": "25.
|
|
3
|
+
"version": "25.4.0-dev.55bb86e155",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -36,22 +36,22 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
39
|
-
"@vaadin/a11y-base": "
|
|
40
|
-
"@vaadin/component-base": "
|
|
41
|
-
"@vaadin/field-base": "
|
|
42
|
-
"@vaadin/input-container": "
|
|
43
|
-
"@vaadin/item": "
|
|
44
|
-
"@vaadin/lit-renderer": "
|
|
45
|
-
"@vaadin/overlay": "
|
|
46
|
-
"@vaadin/vaadin-themable-mixin": "
|
|
39
|
+
"@vaadin/a11y-base": "25.4.0-dev.55bb86e155",
|
|
40
|
+
"@vaadin/component-base": "25.4.0-dev.55bb86e155",
|
|
41
|
+
"@vaadin/field-base": "25.4.0-dev.55bb86e155",
|
|
42
|
+
"@vaadin/input-container": "25.4.0-dev.55bb86e155",
|
|
43
|
+
"@vaadin/item": "25.4.0-dev.55bb86e155",
|
|
44
|
+
"@vaadin/lit-renderer": "25.4.0-dev.55bb86e155",
|
|
45
|
+
"@vaadin/overlay": "25.4.0-dev.55bb86e155",
|
|
46
|
+
"@vaadin/vaadin-themable-mixin": "25.4.0-dev.55bb86e155",
|
|
47
47
|
"lit": "^3.0.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@vaadin/aura": "
|
|
51
|
-
"@vaadin/chai-plugins": "
|
|
52
|
-
"@vaadin/test-runner-commands": "
|
|
50
|
+
"@vaadin/aura": "25.4.0-dev.55bb86e155",
|
|
51
|
+
"@vaadin/chai-plugins": "25.4.0-dev.55bb86e155",
|
|
52
|
+
"@vaadin/test-runner-commands": "25.4.0-dev.55bb86e155",
|
|
53
53
|
"@vaadin/testing-helpers": "^2.0.0",
|
|
54
|
-
"@vaadin/vaadin-lumo-styles": "
|
|
54
|
+
"@vaadin/vaadin-lumo-styles": "25.4.0-dev.55bb86e155",
|
|
55
55
|
"sinon": "^22.0.0"
|
|
56
56
|
},
|
|
57
57
|
"customElements": "custom-elements.json",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"web-types.json",
|
|
60
60
|
"web-types.lit.json"
|
|
61
61
|
],
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "5db8e58fb088121b067290b0ed90d12d7d4084f2"
|
|
63
63
|
}
|
|
@@ -9,10 +9,12 @@ import type { FocusMixinClass } from '@vaadin/a11y-base/src/focus-mixin.js';
|
|
|
9
9
|
import type { KeyboardMixinClass } from '@vaadin/a11y-base/src/keyboard-mixin.js';
|
|
10
10
|
import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
|
|
11
11
|
import type { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
|
|
12
|
+
import type { ComboBoxHighlightMixinClass } from './vaadin-combo-box-highlight-mixin.js';
|
|
12
13
|
|
|
13
14
|
export declare function ComboBoxBaseMixin<T extends Constructor<HTMLElement>>(
|
|
14
15
|
base: T,
|
|
15
16
|
): Constructor<ComboBoxBaseMixinClass> &
|
|
17
|
+
Constructor<ComboBoxHighlightMixinClass> &
|
|
16
18
|
Constructor<DisabledMixinClass> &
|
|
17
19
|
Constructor<FocusMixinClass> &
|
|
18
20
|
Constructor<InputMixinClass> &
|
|
@@ -10,10 +10,13 @@ import { KeyboardMixin } from '@vaadin/a11y-base/src/keyboard-mixin.js';
|
|
|
10
10
|
import { isTouch } from '@vaadin/component-base/src/browser-utils.js';
|
|
11
11
|
import { setOrRemoveAttribute } from '@vaadin/component-base/src/dom-utils.js';
|
|
12
12
|
import { InputMixin } from '@vaadin/field-base/src/input-mixin.js';
|
|
13
|
+
import { ComboBoxHighlightMixin } from './vaadin-combo-box-highlight-mixin.js';
|
|
13
14
|
import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
|
|
14
15
|
|
|
15
16
|
export const ComboBoxBaseMixin = (superClass) =>
|
|
16
|
-
class ComboBoxMixinBaseClass extends
|
|
17
|
+
class ComboBoxMixinBaseClass extends ComboBoxHighlightMixin(
|
|
18
|
+
KeyboardMixin(InputMixin(DisabledMixin(FocusMixin(superClass)))),
|
|
19
|
+
) {
|
|
17
20
|
static get properties() {
|
|
18
21
|
return {
|
|
19
22
|
/**
|
|
@@ -46,16 +49,6 @@ export const ComboBoxBaseMixin = (superClass) =>
|
|
|
46
49
|
reflectToAttribute: true,
|
|
47
50
|
},
|
|
48
51
|
|
|
49
|
-
/**
|
|
50
|
-
* @protected
|
|
51
|
-
*/
|
|
52
|
-
_focusedIndex: {
|
|
53
|
-
type: Number,
|
|
54
|
-
observer: '_focusedIndexChanged',
|
|
55
|
-
value: -1,
|
|
56
|
-
sync: true,
|
|
57
|
-
},
|
|
58
|
-
|
|
59
52
|
/**
|
|
60
53
|
* @type {!HTMLElement | undefined}
|
|
61
54
|
* @protected
|
|
@@ -183,9 +176,13 @@ export const ComboBoxBaseMixin = (superClass) =>
|
|
|
183
176
|
|
|
184
177
|
// Update the scroller only once the overlay is actually opened, so that the
|
|
185
178
|
// virtualizer does not measure and render items while the overlay is hidden.
|
|
186
|
-
if (['_overlayOpened', '_dropdownItems', '
|
|
179
|
+
if (['_overlayOpened', '_dropdownItems', '_highlightState', '_theme'].some((prop) => props.has(prop))) {
|
|
187
180
|
this._updateScroller();
|
|
188
181
|
}
|
|
182
|
+
|
|
183
|
+
if (props.has('_highlightState')) {
|
|
184
|
+
this._updateActiveDescendant();
|
|
185
|
+
}
|
|
189
186
|
}
|
|
190
187
|
|
|
191
188
|
/** @protected */
|
|
@@ -284,7 +281,7 @@ export const ComboBoxBaseMixin = (superClass) =>
|
|
|
284
281
|
this._scroller.setProperties({
|
|
285
282
|
items: opened || isClosing ? this._dropdownItems : [],
|
|
286
283
|
opened,
|
|
287
|
-
focusedIndex: this.
|
|
284
|
+
focusedIndex: this._highlightedItemIndex,
|
|
288
285
|
theme: this._theme,
|
|
289
286
|
});
|
|
290
287
|
}
|
|
@@ -306,26 +303,19 @@ export const ComboBoxBaseMixin = (superClass) =>
|
|
|
306
303
|
}
|
|
307
304
|
}
|
|
308
305
|
|
|
309
|
-
/** @private */
|
|
310
|
-
_focusedIndexChanged(index, oldIndex) {
|
|
311
|
-
if (oldIndex === undefined) {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
this._updateActiveDescendant(index);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
306
|
/** @protected */
|
|
318
307
|
_isInputFocused() {
|
|
319
308
|
return this.inputElement && isElementFocused(this.inputElement);
|
|
320
309
|
}
|
|
321
310
|
|
|
322
|
-
/** @
|
|
323
|
-
_updateActiveDescendant(
|
|
311
|
+
/** @protected */
|
|
312
|
+
_updateActiveDescendant() {
|
|
324
313
|
const input = this.inputElement;
|
|
325
314
|
if (!input) {
|
|
326
315
|
return;
|
|
327
316
|
}
|
|
328
317
|
|
|
318
|
+
const index = this._highlightedItemIndex;
|
|
329
319
|
const item = this._getItemElements().find((el) => el.index === index);
|
|
330
320
|
setOrRemoveAttribute(input, 'aria-activedescendant', item?.id);
|
|
331
321
|
}
|
|
@@ -502,11 +492,8 @@ export const ComboBoxBaseMixin = (superClass) =>
|
|
|
502
492
|
/** @private */
|
|
503
493
|
_onArrowDown() {
|
|
504
494
|
if (this.opened) {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
this._focusedIndex = Math.min(items.length - 1, this._focusedIndex + 1);
|
|
508
|
-
this._prefillFocusedItemLabel();
|
|
509
|
-
}
|
|
495
|
+
this._highlightNextItem();
|
|
496
|
+
this._prefillFocusedItemLabel();
|
|
510
497
|
} else {
|
|
511
498
|
this.open();
|
|
512
499
|
}
|
|
@@ -515,15 +502,7 @@ export const ComboBoxBaseMixin = (superClass) =>
|
|
|
515
502
|
/** @private */
|
|
516
503
|
_onArrowUp() {
|
|
517
504
|
if (this.opened) {
|
|
518
|
-
|
|
519
|
-
this._focusedIndex = Math.max(0, this._focusedIndex - 1);
|
|
520
|
-
} else {
|
|
521
|
-
const items = this._dropdownItems;
|
|
522
|
-
if (items) {
|
|
523
|
-
this._focusedIndex = items.length - 1;
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
|
|
505
|
+
this._highlightPrevItem();
|
|
527
506
|
this._prefillFocusedItemLabel();
|
|
528
507
|
} else {
|
|
529
508
|
this.open();
|
|
@@ -532,9 +511,8 @@ export const ComboBoxBaseMixin = (superClass) =>
|
|
|
532
511
|
|
|
533
512
|
/** @private */
|
|
534
513
|
_prefillFocusedItemLabel() {
|
|
535
|
-
if (this.
|
|
536
|
-
|
|
537
|
-
this._inputElementValue = this._getItemLabel(focusedItem);
|
|
514
|
+
if (this._hasHighlightedItem) {
|
|
515
|
+
this._inputElementValue = this._getItemLabel(this._highlightedItem);
|
|
538
516
|
this._markAllSelectionRange();
|
|
539
517
|
}
|
|
540
518
|
}
|
|
@@ -633,16 +611,16 @@ export const ComboBoxBaseMixin = (superClass) =>
|
|
|
633
611
|
// The overlay is open or
|
|
634
612
|
// The input value has changed but the change hasn't been committed, so cancel it.
|
|
635
613
|
e.stopPropagation();
|
|
636
|
-
this.
|
|
614
|
+
this._clearItemHighlight();
|
|
637
615
|
this._onEscapeCancel();
|
|
638
616
|
} else if (this.opened) {
|
|
639
617
|
// Auto-open is enabled
|
|
640
618
|
// The overlay is open
|
|
641
619
|
e.stopPropagation();
|
|
642
620
|
|
|
643
|
-
if (this.
|
|
621
|
+
if (this._hasHighlightedItem) {
|
|
644
622
|
// An item is focused, revert the input to the filtered value
|
|
645
|
-
this.
|
|
623
|
+
this._clearItemHighlight();
|
|
646
624
|
this._revertInputValue();
|
|
647
625
|
} else {
|
|
648
626
|
// No item is focused, cancel the change and close the overlay
|
|
@@ -766,7 +744,7 @@ export const ComboBoxBaseMixin = (superClass) =>
|
|
|
766
744
|
}
|
|
767
745
|
|
|
768
746
|
if (this.opened) {
|
|
769
|
-
this.
|
|
747
|
+
this._highlightItem(e.detail.item);
|
|
770
748
|
this.close();
|
|
771
749
|
}
|
|
772
750
|
}
|
|
@@ -47,7 +47,7 @@ export const ComboBoxFocusIndexMixin = (superClass) =>
|
|
|
47
47
|
// wins. Rendering rows around `index` also lets placeholder rows fire
|
|
48
48
|
// `index-requested`, loading any missing pages via the data-provider
|
|
49
49
|
// chain.
|
|
50
|
-
this.
|
|
50
|
+
this._highlightItemAt(index);
|
|
51
51
|
this._scrollIntoView(index, true);
|
|
52
52
|
|
|
53
53
|
// A page-load may have kicked in during the scroll (placeholder
|
|
@@ -61,7 +61,7 @@ export const ComboBoxFocusIndexMixin = (superClass) =>
|
|
|
61
61
|
delete this.__pendingFocusIndex;
|
|
62
62
|
requestAnimationFrame(() => {
|
|
63
63
|
if (this.isConnected) {
|
|
64
|
-
this._updateActiveDescendant(
|
|
64
|
+
this._updateActiveDescendant();
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2015 - 2026 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
|
+
/**
|
|
9
|
+
* A mixin that tracks which element of a combo box has the keyboard highlight
|
|
10
|
+
* while the DOM focus stays in the input. Only one element is highlighted at
|
|
11
|
+
* a time.
|
|
12
|
+
*/
|
|
13
|
+
export declare function ComboBoxHighlightMixin<T extends Constructor<HTMLElement>>(
|
|
14
|
+
base: T,
|
|
15
|
+
): Constructor<ComboBoxHighlightMixinClass> & T;
|
|
16
|
+
|
|
17
|
+
// Nothing to declare, all state and methods are considered internal
|
|
18
|
+
export declare class ComboBoxHighlightMixinClass {}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2015 - 2026 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { dedupeMixin } from '@open-wc/dedupe-mixin';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A mixin that tracks which element of a combo box has the keyboard highlight
|
|
10
|
+
* while the DOM focus stays in the input. Only one element is highlighted at
|
|
11
|
+
* a time.
|
|
12
|
+
*
|
|
13
|
+
* The state is one of:
|
|
14
|
+
*
|
|
15
|
+
* - `{ type: 'none' }`: nothing is highlighted.
|
|
16
|
+
* - `{ type: 'item', index }`: the dropdown item at `index`.
|
|
17
|
+
*
|
|
18
|
+
* Mixins applied on top can add more types by calling `_setHighlightState()`.
|
|
19
|
+
*/
|
|
20
|
+
const ComboBoxHighlightMixinImplementation = (superClass) =>
|
|
21
|
+
class ComboBoxHighlightMixinClass extends superClass {
|
|
22
|
+
static get properties() {
|
|
23
|
+
return {
|
|
24
|
+
/**
|
|
25
|
+
* The element that currently has the keyboard highlight.
|
|
26
|
+
* @protected
|
|
27
|
+
*/
|
|
28
|
+
_highlightState: {
|
|
29
|
+
type: Object,
|
|
30
|
+
value: () => ({ type: 'none' }),
|
|
31
|
+
sync: true,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** @protected */
|
|
37
|
+
get _hasHighlightedItem() {
|
|
38
|
+
return this._highlightState.type === 'item';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** @protected */
|
|
42
|
+
get _highlightedItemIndex() {
|
|
43
|
+
return this._hasHighlightedItem ? this._highlightState.index : -1;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** @protected */
|
|
47
|
+
get _highlightedItem() {
|
|
48
|
+
return this._hasHighlightedItem ? this._dropdownItems?.[this._highlightState.index] : undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** @protected */
|
|
52
|
+
_highlightNextItem() {
|
|
53
|
+
const items = this._dropdownItems;
|
|
54
|
+
if (items) {
|
|
55
|
+
this._highlightItemAt(Math.min(items.length - 1, this._highlightedItemIndex + 1));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** @protected */
|
|
60
|
+
_highlightPrevItem() {
|
|
61
|
+
const items = this._dropdownItems;
|
|
62
|
+
if (items) {
|
|
63
|
+
this._highlightItemAt(
|
|
64
|
+
this._hasHighlightedItem ? Math.max(0, this._highlightState.index - 1) : items.length - 1,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** @protected */
|
|
70
|
+
_highlightItem(item) {
|
|
71
|
+
const items = this._dropdownItems;
|
|
72
|
+
this._highlightItemAt(items ? items.indexOf(item) : -1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** @protected */
|
|
76
|
+
_highlightItemAt(index) {
|
|
77
|
+
if (index > -1) {
|
|
78
|
+
this._setHighlightState({ type: 'item', index });
|
|
79
|
+
} else {
|
|
80
|
+
this._clearItemHighlight();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @protected
|
|
86
|
+
*/
|
|
87
|
+
_clearItemHighlight() {
|
|
88
|
+
if (this._hasHighlightedItem) {
|
|
89
|
+
this._clearHighlight();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** @protected */
|
|
94
|
+
_clearHighlight() {
|
|
95
|
+
this._setHighlightState({ type: 'none' });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @protected
|
|
100
|
+
*/
|
|
101
|
+
_setHighlightState(state) {
|
|
102
|
+
const oldState = this._highlightState;
|
|
103
|
+
if (state.type !== oldState.type || state.index !== oldState.index) {
|
|
104
|
+
this._highlightState = state;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export const ComboBoxHighlightMixin = dedupeMixin(ComboBoxHighlightMixinImplementation);
|
|
@@ -246,8 +246,8 @@ export const ComboBoxItemsMixin = (superClass) =>
|
|
|
246
246
|
_onOpened() {
|
|
247
247
|
super._onOpened();
|
|
248
248
|
|
|
249
|
-
if (this.filter && this.
|
|
250
|
-
this.
|
|
249
|
+
if (this.filter && !this._hasHighlightedItem) {
|
|
250
|
+
this._highlightItemAt(this.__getItemIndexByFilter(this._dropdownItems));
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
|
|
@@ -309,7 +309,7 @@ export const ComboBoxItemsMixin = (superClass) =>
|
|
|
309
309
|
// Scroll to the top of the list whenever the filter changes.
|
|
310
310
|
this._scrollIntoView(0);
|
|
311
311
|
|
|
312
|
-
this.
|
|
312
|
+
this._clearItemHighlight();
|
|
313
313
|
|
|
314
314
|
if (this.items) {
|
|
315
315
|
this.filteredItems = this._filterItems(this.items, filter);
|
|
@@ -348,37 +348,31 @@ export const ComboBoxItemsMixin = (superClass) =>
|
|
|
348
348
|
* @protected
|
|
349
349
|
*/
|
|
350
350
|
_setDropdownItems(newItems) {
|
|
351
|
-
const
|
|
351
|
+
const highlightedItem = this._highlightedItem;
|
|
352
352
|
this._dropdownItems = newItems;
|
|
353
353
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
354
|
+
this.__restoreItemHighlight(highlightedItem);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Highlights the given item again if it is still among the dropdown
|
|
359
|
+
* items, which keeps the highlight in place when more items are
|
|
360
|
+
* loading. Otherwise the item matching the filter is highlighted, or none.
|
|
361
|
+
* @private
|
|
362
|
+
*/
|
|
363
|
+
__restoreItemHighlight(item) {
|
|
364
|
+
const items = this._dropdownItems;
|
|
358
365
|
|
|
359
|
-
// When both the previously
|
|
366
|
+
// When both the previously highlighted entry and the new entry at the
|
|
360
367
|
// same index are placeholders (e.g. the Flow connector mid-scroll
|
|
361
|
-
// re-pushing `_setDropdownItems`), preserve
|
|
368
|
+
// re-pushing `_setDropdownItems`), preserve the highlight until
|
|
362
369
|
// a follow-up call lands a real item at that position.
|
|
363
|
-
if (
|
|
364
|
-
oldItems &&
|
|
365
|
-
oldItems[this._focusedIndex] instanceof ComboBoxPlaceholder &&
|
|
366
|
-
newItems[this._focusedIndex] instanceof ComboBoxPlaceholder
|
|
367
|
-
) {
|
|
370
|
+
if (item instanceof ComboBoxPlaceholder && items[this._highlightedItemIndex] instanceof ComboBoxPlaceholder) {
|
|
368
371
|
return;
|
|
369
372
|
}
|
|
370
373
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
// depending on the selected item or the filter query.
|
|
374
|
-
const focusedItemIndex = this.__getItemIndexByValue(newItems, this._getItemValue(focusedItem));
|
|
375
|
-
if (focusedItemIndex > -1) {
|
|
376
|
-
this._focusedIndex = focusedItemIndex;
|
|
377
|
-
} else {
|
|
378
|
-
// When the user filled in something that is different from the current value = filtering is enabled,
|
|
379
|
-
// set the focused index to the item that matches the filter query.
|
|
380
|
-
this._focusedIndex = this.__getItemIndexByFilter(newItems);
|
|
381
|
-
}
|
|
374
|
+
const index = this.__getItemIndexByValue(items, this._getItemValue(item));
|
|
375
|
+
this._highlightItemAt(index > -1 ? index : this.__getItemIndexByFilter(items));
|
|
382
376
|
}
|
|
383
377
|
|
|
384
378
|
/** @private */
|
|
@@ -146,7 +146,7 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
146
146
|
*/
|
|
147
147
|
_hasValidInputValue() {
|
|
148
148
|
const hasInvalidOption =
|
|
149
|
-
this.
|
|
149
|
+
!this._hasHighlightedItem &&
|
|
150
150
|
this._inputElementValue !== '' &&
|
|
151
151
|
this._getItemLabel(this.selectedItem) !== this._inputElementValue;
|
|
152
152
|
|
|
@@ -236,14 +236,14 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
236
236
|
* @override
|
|
237
237
|
*/
|
|
238
238
|
_commitValue() {
|
|
239
|
-
if (this.
|
|
240
|
-
const focusedItem = this.
|
|
239
|
+
if (this._hasHighlightedItem) {
|
|
240
|
+
const focusedItem = this._highlightedItem;
|
|
241
241
|
if (this.selectedItem !== focusedItem) {
|
|
242
242
|
this.selectedItem = focusedItem;
|
|
243
243
|
}
|
|
244
244
|
// Make sure input field is updated in case value doesn't change (i.e. FOO -> foo)
|
|
245
245
|
this._inputElementValue = this._getItemLabel(this.selectedItem);
|
|
246
|
-
this.
|
|
246
|
+
this._clearItemHighlight();
|
|
247
247
|
} else if (this._inputElementValue === '' || this._inputElementValue === undefined) {
|
|
248
248
|
this.selectedItem = null;
|
|
249
249
|
|
|
@@ -227,6 +227,9 @@ export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap {
|
|
|
227
227
|
* | `--vaadin-input-field-helper-font-size` |
|
|
228
228
|
* | `--vaadin-input-field-helper-font-weight` |
|
|
229
229
|
* | `--vaadin-input-field-helper-line-height` |
|
|
230
|
+
* | `--vaadin-input-field-label-aside-gap` |
|
|
231
|
+
* | `--vaadin-input-field-label-aside-text-align` |
|
|
232
|
+
* | `--vaadin-input-field-label-aside-width` |
|
|
230
233
|
* | `--vaadin-input-field-label-color` |
|
|
231
234
|
* | `--vaadin-input-field-label-font-size` |
|
|
232
235
|
* | `--vaadin-input-field-label-font-weight` |
|
package/src/vaadin-combo-box.js
CHANGED
|
@@ -159,6 +159,9 @@ import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
|
|
|
159
159
|
* | `--vaadin-input-field-helper-font-size` |
|
|
160
160
|
* | `--vaadin-input-field-helper-font-weight` |
|
|
161
161
|
* | `--vaadin-input-field-helper-line-height` |
|
|
162
|
+
* | `--vaadin-input-field-label-aside-gap` |
|
|
163
|
+
* | `--vaadin-input-field-label-aside-text-align` |
|
|
164
|
+
* | `--vaadin-input-field-label-aside-width` |
|
|
162
165
|
* | `--vaadin-input-field-label-color` |
|
|
163
166
|
* | `--vaadin-input-field-label-font-size` |
|
|
164
167
|
* | `--vaadin-input-field-label-font-weight` |
|
package/web-types.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/web-types",
|
|
3
3
|
"name": "@vaadin/combo-box",
|
|
4
|
-
"version": "25.
|
|
4
|
+
"version": "25.4.0-dev.55bb86e155",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"contributions": {
|
|
7
7
|
"html": {
|
|
8
8
|
"elements": [
|
|
9
9
|
{
|
|
10
10
|
"name": "vaadin-combo-box",
|
|
11
|
-
"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/25.
|
|
11
|
+
"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/25.4.0-dev.55bb86e155/#/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/25.4.0-dev.55bb86e155/#/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/25.4.0-dev.55bb86e155/#/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 shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------|----------------\n`label` | The label element\n`input-field` | The element that wraps prefix, value and buttons\n`field-button` | Set on both clear and toggle buttons\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n`overlay` | The overlay container\n`content` | The overlay content\n`loader` | The loading indicator shown while loading items\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------------|---------------------------------\n`disabled` | Set when the element is disabled\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`has-tooltip` | Set when the element has a slotted tooltip\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`readonly` | Set when the element is readonly\n`opened` | Set when the overlay is opened\n`loading` | Set when loading items from the data provider\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:--------------------------------------------------|\n| `--vaadin-combo-box-overlay-max-height` |\n| `--vaadin-combo-box-overlay-width` |\n| `--vaadin-field-default-width` |\n| `--vaadin-input-field-background` |\n| `--vaadin-input-field-border-color` |\n| `--vaadin-input-field-border-radius` |\n| `--vaadin-input-field-border-width` |\n| `--vaadin-input-field-bottom-end-radius` |\n| `--vaadin-input-field-bottom-start-radius` |\n| `--vaadin-input-field-button-text-color` |\n| `--vaadin-input-field-container-gap` |\n| `--vaadin-input-field-disabled-background` |\n| `--vaadin-input-field-disabled-text-color` |\n| `--vaadin-input-field-error-color` |\n| `--vaadin-input-field-error-font-size` |\n| `--vaadin-input-field-error-font-weight` |\n| `--vaadin-input-field-error-line-height` |\n| `--vaadin-input-field-gap` |\n| `--vaadin-input-field-helper-color` |\n| `--vaadin-input-field-helper-font-size` |\n| `--vaadin-input-field-helper-font-weight` |\n| `--vaadin-input-field-helper-line-height` |\n| `--vaadin-input-field-label-aside-gap` |\n| `--vaadin-input-field-label-aside-text-align` |\n| `--vaadin-input-field-label-aside-width` |\n| `--vaadin-input-field-label-color` |\n| `--vaadin-input-field-label-font-size` |\n| `--vaadin-input-field-label-font-weight` |\n| `--vaadin-input-field-label-line-height` |\n| `--vaadin-input-field-padding` |\n| `--vaadin-input-field-placeholder-color` |\n| `--vaadin-input-field-required-indicator` |\n| `--vaadin-input-field-required-indicator-color` |\n| `--vaadin-input-field-top-end-radius` |\n| `--vaadin-input-field-top-start-radius` |\n| `--vaadin-input-field-value-color` |\n| `--vaadin-input-field-value-font-size` |\n| `--vaadin-input-field-value-font-weight` |\n| `--vaadin-input-field-value-line-height` |\n| `--vaadin-item-overlay-padding` |\n\n### Internal components\n\nIn addition to `<vaadin-combo-box>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.4.0-dev.55bb86e155/#/elements/vaadin-item).\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
|
|
12
12
|
"attributes": [
|
|
13
13
|
{
|
|
14
14
|
"name": "accessible-description-ref",
|
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": "25.
|
|
4
|
+
"version": "25.4.0-dev.55bb86e155",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"framework": "lit",
|
|
7
7
|
"framework-config": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"elements": [
|
|
17
17
|
{
|
|
18
18
|
"name": "vaadin-combo-box",
|
|
19
|
-
"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/25.
|
|
19
|
+
"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/25.4.0-dev.55bb86e155/#/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/25.4.0-dev.55bb86e155/#/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/25.4.0-dev.55bb86e155/#/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 shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------|----------------\n`label` | The label element\n`input-field` | The element that wraps prefix, value and buttons\n`field-button` | Set on both clear and toggle buttons\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n`overlay` | The overlay container\n`content` | The overlay content\n`loader` | The loading indicator shown while loading items\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------------|---------------------------------\n`disabled` | Set when the element is disabled\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`has-tooltip` | Set when the element has a slotted tooltip\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`readonly` | Set when the element is readonly\n`opened` | Set when the overlay is opened\n`loading` | Set when loading items from the data provider\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:--------------------------------------------------|\n| `--vaadin-combo-box-overlay-max-height` |\n| `--vaadin-combo-box-overlay-width` |\n| `--vaadin-field-default-width` |\n| `--vaadin-input-field-background` |\n| `--vaadin-input-field-border-color` |\n| `--vaadin-input-field-border-radius` |\n| `--vaadin-input-field-border-width` |\n| `--vaadin-input-field-bottom-end-radius` |\n| `--vaadin-input-field-bottom-start-radius` |\n| `--vaadin-input-field-button-text-color` |\n| `--vaadin-input-field-container-gap` |\n| `--vaadin-input-field-disabled-background` |\n| `--vaadin-input-field-disabled-text-color` |\n| `--vaadin-input-field-error-color` |\n| `--vaadin-input-field-error-font-size` |\n| `--vaadin-input-field-error-font-weight` |\n| `--vaadin-input-field-error-line-height` |\n| `--vaadin-input-field-gap` |\n| `--vaadin-input-field-helper-color` |\n| `--vaadin-input-field-helper-font-size` |\n| `--vaadin-input-field-helper-font-weight` |\n| `--vaadin-input-field-helper-line-height` |\n| `--vaadin-input-field-label-aside-gap` |\n| `--vaadin-input-field-label-aside-text-align` |\n| `--vaadin-input-field-label-aside-width` |\n| `--vaadin-input-field-label-color` |\n| `--vaadin-input-field-label-font-size` |\n| `--vaadin-input-field-label-font-weight` |\n| `--vaadin-input-field-label-line-height` |\n| `--vaadin-input-field-padding` |\n| `--vaadin-input-field-placeholder-color` |\n| `--vaadin-input-field-required-indicator` |\n| `--vaadin-input-field-required-indicator-color` |\n| `--vaadin-input-field-top-end-radius` |\n| `--vaadin-input-field-top-start-radius` |\n| `--vaadin-input-field-value-color` |\n| `--vaadin-input-field-value-font-size` |\n| `--vaadin-input-field-value-font-weight` |\n| `--vaadin-input-field-value-line-height` |\n| `--vaadin-item-overlay-padding` |\n\n### Internal components\n\nIn addition to `<vaadin-combo-box>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.4.0-dev.55bb86e155/#/elements/vaadin-item).\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
|
|
20
20
|
"extension": true,
|
|
21
21
|
"attributes": [
|
|
22
22
|
{
|