@vaadin/combo-box 25.2.0-beta2 → 25.2.0-rc1
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 +9 -1
- package/package.json +14 -14
- package/src/vaadin-combo-box-base-mixin.js +2 -2
- package/src/vaadin-combo-box-focus-index-mixin.js +7 -4
- package/src/vaadin-combo-box-scroller-mixin.d.ts +6 -3
- package/src/vaadin-combo-box-scroller-mixin.js +45 -14
- package/web-types.json +2 -2
- package/web-types.lit.json +2 -2
package/custom-elements.json
CHANGED
|
@@ -1599,9 +1599,17 @@
|
|
|
1599
1599
|
"type": {
|
|
1600
1600
|
"text": "number"
|
|
1601
1601
|
}
|
|
1602
|
+
},
|
|
1603
|
+
{
|
|
1604
|
+
"name": "alignToCenter",
|
|
1605
|
+
"default": "false",
|
|
1606
|
+
"optional": true,
|
|
1607
|
+
"type": {
|
|
1608
|
+
"text": "boolean"
|
|
1609
|
+
}
|
|
1602
1610
|
}
|
|
1603
1611
|
],
|
|
1604
|
-
"description": "Scrolls an item at given index into view
|
|
1612
|
+
"description": "Scrolls an item at given index into view. By default the item is made\nfully visible at the bottom of the viewport (the behavior wanted on\nArrow Down key press). When `alignToCenter` is `true`, the item is placed\nin the middle of the viewport instead, as close to center as the list\nallows near its start and end."
|
|
1605
1613
|
},
|
|
1606
1614
|
{
|
|
1607
1615
|
"kind": "field",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/combo-box",
|
|
3
|
-
"version": "25.2.0-
|
|
3
|
+
"version": "25.2.0-rc1",
|
|
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": "25.2.0-
|
|
40
|
-
"@vaadin/component-base": "25.2.0-
|
|
41
|
-
"@vaadin/field-base": "25.2.0-
|
|
42
|
-
"@vaadin/input-container": "25.2.0-
|
|
43
|
-
"@vaadin/item": "25.2.0-
|
|
44
|
-
"@vaadin/lit-renderer": "25.2.0-
|
|
45
|
-
"@vaadin/overlay": "25.2.0-
|
|
46
|
-
"@vaadin/vaadin-themable-mixin": "25.2.0-
|
|
39
|
+
"@vaadin/a11y-base": "25.2.0-rc1",
|
|
40
|
+
"@vaadin/component-base": "25.2.0-rc1",
|
|
41
|
+
"@vaadin/field-base": "25.2.0-rc1",
|
|
42
|
+
"@vaadin/input-container": "25.2.0-rc1",
|
|
43
|
+
"@vaadin/item": "25.2.0-rc1",
|
|
44
|
+
"@vaadin/lit-renderer": "25.2.0-rc1",
|
|
45
|
+
"@vaadin/overlay": "25.2.0-rc1",
|
|
46
|
+
"@vaadin/vaadin-themable-mixin": "25.2.0-rc1",
|
|
47
47
|
"lit": "^3.0.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@vaadin/aura": "25.2.0-
|
|
51
|
-
"@vaadin/chai-plugins": "25.2.0-
|
|
52
|
-
"@vaadin/test-runner-commands": "25.2.0-
|
|
50
|
+
"@vaadin/aura": "25.2.0-rc1",
|
|
51
|
+
"@vaadin/chai-plugins": "25.2.0-rc1",
|
|
52
|
+
"@vaadin/test-runner-commands": "25.2.0-rc1",
|
|
53
53
|
"@vaadin/testing-helpers": "^2.0.0",
|
|
54
|
-
"@vaadin/vaadin-lumo-styles": "25.2.0-
|
|
54
|
+
"@vaadin/vaadin-lumo-styles": "25.2.0-rc1",
|
|
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": "7c581b396dbb889f75c8073d6b4d25537a65b873"
|
|
63
63
|
}
|
|
@@ -696,11 +696,11 @@ export const ComboBoxBaseMixin = (superClass) =>
|
|
|
696
696
|
}
|
|
697
697
|
|
|
698
698
|
/** @protected */
|
|
699
|
-
_scrollIntoView(index) {
|
|
699
|
+
_scrollIntoView(index, alignToCenter = false) {
|
|
700
700
|
if (!this._scroller) {
|
|
701
701
|
return;
|
|
702
702
|
}
|
|
703
|
-
this._scroller.scrollIntoView(index);
|
|
703
|
+
this._scroller.scrollIntoView(index, alignToCenter);
|
|
704
704
|
}
|
|
705
705
|
|
|
706
706
|
/** @private */
|
|
@@ -36,11 +36,14 @@ export const ComboBoxFocusIndexMixin = (superClass) =>
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
|
|
39
|
+
// Set the focused row first: this synchronously runs the scroller's
|
|
40
|
+
// `__focusedIndexChanged` observer, which scrolls the row into view
|
|
41
|
+
// (bottom-aligned). Then scroll again to center it so the final position
|
|
42
|
+
// wins. Rendering rows around `index` also lets placeholder rows fire
|
|
43
|
+
// `index-requested`, loading any missing pages via the data-provider
|
|
44
|
+
// chain.
|
|
43
45
|
this._focusedIndex = index;
|
|
46
|
+
this._scrollIntoView(index, true);
|
|
44
47
|
|
|
45
48
|
// A page-load may have kicked in during the scroll (placeholder
|
|
46
49
|
// rows in the new viewport requested their pages). Re-fire after
|
|
@@ -70,10 +70,13 @@ export declare class ComboBoxScrollerMixinClass<TItem, TOwner> {
|
|
|
70
70
|
requestContentUpdate(): void;
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
|
-
* Scrolls an item at given index into view
|
|
74
|
-
*
|
|
73
|
+
* Scrolls an item at given index into view. By default the item is made
|
|
74
|
+
* fully visible at the bottom of the viewport (the behavior wanted on
|
|
75
|
+
* Arrow Down key press). When `alignToCenter` is `true`, the item is placed
|
|
76
|
+
* in the middle of the viewport instead, as close to center as the list
|
|
77
|
+
* allows near its start and end.
|
|
75
78
|
*/
|
|
76
|
-
scrollIntoView(index: number): void;
|
|
79
|
+
scrollIntoView(index: number, alignToCenter?: boolean): void;
|
|
77
80
|
|
|
78
81
|
protected _isItemSelected(item: TItem, selectedItem: TItem, itemIdPath: string | null | undefined): void;
|
|
79
82
|
|
|
@@ -166,29 +166,53 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
/**
|
|
169
|
-
* Scrolls an item at given index into view
|
|
170
|
-
*
|
|
169
|
+
* Scrolls an item at given index into view. By default the item is made
|
|
170
|
+
* fully visible at the bottom of the viewport (the behavior wanted on
|
|
171
|
+
* Arrow Down key press). When `alignToCenter` is `true`, the item is placed
|
|
172
|
+
* in the middle of the viewport instead, as close to center as the list
|
|
173
|
+
* allows near its start and end.
|
|
171
174
|
* @param {number} index
|
|
175
|
+
* @param {boolean} [alignToCenter=false]
|
|
172
176
|
*/
|
|
173
|
-
scrollIntoView(index) {
|
|
177
|
+
scrollIntoView(index, alignToCenter = false) {
|
|
174
178
|
if (!this.__virtualizer || !(this.opened && index >= 0)) {
|
|
175
179
|
return;
|
|
176
180
|
}
|
|
177
181
|
|
|
178
|
-
|
|
182
|
+
// If the target row is already fully visible, leave the scroll untouched.
|
|
183
|
+
// Re-running scrollToIndex would snap an unaligned scrollTop to a row
|
|
184
|
+
// boundary — a visible jump when only the focus ring should move (arrow
|
|
185
|
+
// navigation, clicks). Centering always repositions, so it skips this.
|
|
186
|
+
const renderedTarget = [...this.children].find((el) => !el.hidden && el.index === index);
|
|
187
|
+
if (!alignToCenter && renderedTarget) {
|
|
188
|
+
const targetRect = renderedTarget.getBoundingClientRect();
|
|
189
|
+
const scrollerRect = this.getBoundingClientRect();
|
|
190
|
+
if (
|
|
191
|
+
targetRect.top >= scrollerRect.top &&
|
|
192
|
+
targetRect.bottom + this._viewportTotalPaddingBottom <= scrollerRect.bottom
|
|
193
|
+
) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
179
197
|
|
|
198
|
+
// When centering, scrolling straight to the target index renders it (the
|
|
199
|
+
// native `scrollIntoView({ block: 'center' })` below then centers it), so
|
|
200
|
+
// no index recalculation is needed.
|
|
180
201
|
let targetIndex = index;
|
|
181
202
|
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
203
|
+
if (!alignToCenter) {
|
|
204
|
+
const visibleItemsCount = this._visibleItemsCount();
|
|
205
|
+
if (index > this.__virtualizer.lastVisibleIndex - 1) {
|
|
206
|
+
// Index is below the bottom, scrolling down. Make the item appear at the bottom.
|
|
207
|
+
// First scroll to target (will be at the top of the scroller) to make sure it's rendered.
|
|
208
|
+
this.__virtualizer.scrollToIndex(index);
|
|
209
|
+
// Then calculate the index for the following scroll (to get the target to bottom of the scroller).
|
|
210
|
+
targetIndex = index - visibleItemsCount + 1;
|
|
211
|
+
} else if (index > this.__virtualizer.firstVisibleIndex) {
|
|
212
|
+
// The item is already visible, scrolling is unnecessary per se. But we need to trigger iron-list to set
|
|
213
|
+
// the correct scrollTop on the scrollTarget. Scrolling to firstVisibleIndex.
|
|
214
|
+
targetIndex = this.__virtualizer.firstVisibleIndex;
|
|
215
|
+
}
|
|
192
216
|
}
|
|
193
217
|
this.__virtualizer.scrollToIndex(Math.max(0, targetIndex));
|
|
194
218
|
|
|
@@ -199,6 +223,13 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
199
223
|
if (!target) {
|
|
200
224
|
return;
|
|
201
225
|
}
|
|
226
|
+
if (alignToCenter) {
|
|
227
|
+
// Center the now-rendered row in the viewport. The browser clamps near
|
|
228
|
+
// the list start and end, placing the row as close to center as the
|
|
229
|
+
// list allows.
|
|
230
|
+
target.scrollIntoView({ block: 'center' });
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
202
233
|
const targetRect = target.getBoundingClientRect();
|
|
203
234
|
const scrollerRect = this.getBoundingClientRect();
|
|
204
235
|
const targetBottom = targetRect.bottom + this._viewportTotalPaddingBottom;
|
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.2.0-
|
|
4
|
+
"version": "25.2.0-rc1",
|
|
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.2.0-
|
|
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.2.0-rc1/#/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.2.0-rc1/#/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.2.0-rc1/#/elements/vaadin-combo-box#property-dataProvider) function property.\nThe `<vaadin-combo-box>` calls this function lazily, only when it needs more data\nto be displayed.\n\n__Note that when using function data providers, the total number of items\nneeds to be set manually. The total number of items can be returned\nin the second argument of the data provider callback:__\n\n```js\ncomboBox.dataProvider = async (params, callback) => {\n const API = 'https://demo.vaadin.com/demo-data/1.0/filtered-countries';\n const { filter, page, pageSize } = params;\n const index = page * pageSize;\n\n const res = await fetch(`${API}?index=${index}&count=${pageSize}&filter=${filter}`);\n if (res.ok) {\n const { result, size } = await res.json();\n callback(result, size);\n }\n};\n```\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n----------------------------------------|----------------------------|---------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n`--vaadin-combo-box-overlay-width` | Width of the overlay | `auto`\n`--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh`\n\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\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.2.0-rc1/#/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-name",
|
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.2.0-
|
|
4
|
+
"version": "25.2.0-rc1",
|
|
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.2.0-
|
|
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.2.0-rc1/#/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.2.0-rc1/#/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.2.0-rc1/#/elements/vaadin-combo-box#property-dataProvider) function property.\nThe `<vaadin-combo-box>` calls this function lazily, only when it needs more data\nto be displayed.\n\n__Note that when using function data providers, the total number of items\nneeds to be set manually. The total number of items can be returned\nin the second argument of the data provider callback:__\n\n```js\ncomboBox.dataProvider = async (params, callback) => {\n const API = 'https://demo.vaadin.com/demo-data/1.0/filtered-countries';\n const { filter, page, pageSize } = params;\n const index = page * pageSize;\n\n const res = await fetch(`${API}?index=${index}&count=${pageSize}&filter=${filter}`);\n if (res.ok) {\n const { result, size } = await res.json();\n callback(result, size);\n }\n};\n```\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n----------------------------------------|----------------------------|---------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n`--vaadin-combo-box-overlay-width` | Width of the overlay | `auto`\n`--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh`\n\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\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.2.0-rc1/#/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
|
{
|