@vaadin/select 25.0.0-alpha1 → 25.0.0-alpha11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +16 -19
- package/src/lit/renderer-directives.d.ts +1 -1
- package/src/lit/renderer-directives.js +1 -1
- package/src/styles/vaadin-select-base-styles.js +38 -0
- package/src/{vaadin-select-overlay-core-styles.js → styles/vaadin-select-overlay-base-styles.js} +3 -5
- package/src/styles/vaadin-select-value-button-base-styles.js +30 -0
- package/src/vaadin-select-base-mixin.d.ts +1 -2
- package/src/vaadin-select-base-mixin.js +38 -31
- package/src/vaadin-select-item.js +3 -2
- package/src/vaadin-select-list-box.js +3 -2
- package/src/vaadin-select-overlay-mixin.js +31 -12
- package/src/vaadin-select-overlay.js +5 -4
- package/src/vaadin-select-value-button.js +3 -2
- package/src/vaadin-select.d.ts +17 -18
- package/src/vaadin-select.js +23 -19
- package/vaadin-select.js +1 -1
- package/web-types.json +3 -3
- package/web-types.lit.json +3 -3
- package/src/vaadin-select-base-styles.js +0 -36
- package/src/vaadin-select-core-styles.d.ts +0 -8
- package/src/vaadin-select-core-styles.js +0 -16
- package/src/vaadin-select-overlay-base-styles.js +0 -23
- package/src/vaadin-select-value-button-base-styles.js +0 -32
- package/src/vaadin-select-value-button-core-styles.js +0 -49
- package/theme/lumo/vaadin-select-styles.d.ts +0 -9
- package/theme/lumo/vaadin-select-styles.js +0 -135
- package/theme/lumo/vaadin-select.d.ts +0 -7
- package/theme/lumo/vaadin-select.js +0 -7
- /package/src/{vaadin-select-base-styles.d.ts → styles/vaadin-select-base-styles.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/select",
|
|
3
|
-
"version": "25.0.0-
|
|
3
|
+
"version": "25.0.0-alpha11",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -23,9 +23,6 @@
|
|
|
23
23
|
"lit.d.ts",
|
|
24
24
|
"lit.js",
|
|
25
25
|
"src",
|
|
26
|
-
"!src/*-base-styles.d.ts",
|
|
27
|
-
"!src/*-base-styles.js",
|
|
28
|
-
"theme",
|
|
29
26
|
"vaadin-*.d.ts",
|
|
30
27
|
"vaadin-*.js",
|
|
31
28
|
"web-types.json",
|
|
@@ -39,28 +36,28 @@
|
|
|
39
36
|
],
|
|
40
37
|
"dependencies": {
|
|
41
38
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
42
|
-
"@vaadin/a11y-base": "25.0.0-
|
|
43
|
-
"@vaadin/button": "25.0.0-
|
|
44
|
-
"@vaadin/component-base": "25.0.0-
|
|
45
|
-
"@vaadin/field-base": "25.0.0-
|
|
46
|
-
"@vaadin/input-container": "25.0.0-
|
|
47
|
-
"@vaadin/item": "25.0.0-
|
|
48
|
-
"@vaadin/list-box": "25.0.0-
|
|
49
|
-
"@vaadin/lit-renderer": "25.0.0-
|
|
50
|
-
"@vaadin/overlay": "25.0.0-
|
|
51
|
-
"@vaadin/vaadin-
|
|
52
|
-
"@vaadin/vaadin-themable-mixin": "25.0.0-alpha1",
|
|
39
|
+
"@vaadin/a11y-base": "25.0.0-alpha11",
|
|
40
|
+
"@vaadin/button": "25.0.0-alpha11",
|
|
41
|
+
"@vaadin/component-base": "25.0.0-alpha11",
|
|
42
|
+
"@vaadin/field-base": "25.0.0-alpha11",
|
|
43
|
+
"@vaadin/input-container": "25.0.0-alpha11",
|
|
44
|
+
"@vaadin/item": "25.0.0-alpha11",
|
|
45
|
+
"@vaadin/list-box": "25.0.0-alpha11",
|
|
46
|
+
"@vaadin/lit-renderer": "25.0.0-alpha11",
|
|
47
|
+
"@vaadin/overlay": "25.0.0-alpha11",
|
|
48
|
+
"@vaadin/vaadin-themable-mixin": "25.0.0-alpha11",
|
|
53
49
|
"lit": "^3.0.0"
|
|
54
50
|
},
|
|
55
51
|
"devDependencies": {
|
|
56
|
-
"@vaadin/chai-plugins": "25.0.0-
|
|
57
|
-
"@vaadin/test-runner-commands": "25.0.0-
|
|
58
|
-
"@vaadin/testing-helpers": "^
|
|
52
|
+
"@vaadin/chai-plugins": "25.0.0-alpha11",
|
|
53
|
+
"@vaadin/test-runner-commands": "25.0.0-alpha11",
|
|
54
|
+
"@vaadin/testing-helpers": "^2.0.0",
|
|
55
|
+
"@vaadin/vaadin-lumo-styles": "25.0.0-alpha11",
|
|
59
56
|
"sinon": "^18.0.0"
|
|
60
57
|
},
|
|
61
58
|
"web-types": [
|
|
62
59
|
"web-types.json",
|
|
63
60
|
"web-types.lit.json"
|
|
64
61
|
],
|
|
65
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "abfd315ba5a7484a613e0768635a4e8fe945a44b"
|
|
66
63
|
}
|
|
@@ -28,7 +28,7 @@ export class SelectRendererDirective extends LitRendererDirective<Select, Select
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* A Lit directive for populating the content of the `<vaadin-select
|
|
31
|
+
* A Lit directive for populating the content of the `<vaadin-select>` element.
|
|
32
32
|
*
|
|
33
33
|
* The directive accepts a renderer callback returning a Lit template and assigns it to the select
|
|
34
34
|
* via the `renderer` property. The renderer is called once to populate the content when assigned
|
|
@@ -32,7 +32,7 @@ export class SelectRendererDirective extends LitRendererDirective {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
* A Lit directive for populating the content of the `<vaadin-select
|
|
35
|
+
* A Lit directive for populating the content of the `<vaadin-select>` element.
|
|
36
36
|
*
|
|
37
37
|
* The directive accepts a renderer callback returning a Lit template and assigns it to the select
|
|
38
38
|
* via the `renderer` property. The renderer is called once to populate the content when assigned
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 2025 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import '@vaadin/component-base/src/styles/style-props.js';
|
|
7
|
+
import { css } from 'lit';
|
|
8
|
+
|
|
9
|
+
export const selectStyles = css`
|
|
10
|
+
:host {
|
|
11
|
+
position: relative;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
::slotted([slot='value']) {
|
|
15
|
+
flex: 1;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
::slotted(div[slot='overlay']) {
|
|
19
|
+
display: contents;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
:host(:not([focus-ring])) [part='input-field'] {
|
|
23
|
+
outline: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
:host([readonly]:not([focus-ring])) [part='input-field'] {
|
|
27
|
+
--vaadin-input-field-border-color: inherit;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[part='input-field'],
|
|
31
|
+
:host(:not([readonly])) ::slotted([slot='value']) {
|
|
32
|
+
cursor: var(--vaadin-clickable-cursor);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
[part='toggle-button']::before {
|
|
36
|
+
mask-image: var(--_vaadin-icon-chevron-down);
|
|
37
|
+
}
|
|
38
|
+
`;
|
package/src/{vaadin-select-overlay-core-styles.js → styles/vaadin-select-overlay-base-styles.js}
RENAMED
|
@@ -12,12 +12,10 @@ export const selectOverlayStyles = css`
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
:host(:not([phone])) [part='overlay'] {
|
|
15
|
-
min-width: var(--vaadin-select-overlay-width, var(--
|
|
15
|
+
min-width: var(--vaadin-select-overlay-width, var(--_vaadin-select-overlay-default-width));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
outline: 3px solid;
|
|
21
|
-
}
|
|
18
|
+
[part='content'] {
|
|
19
|
+
padding: var(--vaadin-item-overlay-padding, 4px);
|
|
22
20
|
}
|
|
23
21
|
`;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 2025 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { css } from 'lit';
|
|
7
|
+
|
|
8
|
+
export const valueButton = css`
|
|
9
|
+
:host {
|
|
10
|
+
min-height: 1lh;
|
|
11
|
+
outline: none;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
white-space: nowrap;
|
|
14
|
+
width: 100%;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
::slotted(*) {
|
|
18
|
+
padding: 0;
|
|
19
|
+
cursor: inherit;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.vaadin-button-container,
|
|
23
|
+
[part='label'] {
|
|
24
|
+
display: contents;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:host([disabled]) {
|
|
28
|
+
pointer-events: none;
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
@@ -64,8 +64,7 @@ export declare class SelectBaseMixinClass {
|
|
|
64
64
|
* Custom function for rendering the content of the `<vaadin-select>`.
|
|
65
65
|
* Receives two arguments:
|
|
66
66
|
*
|
|
67
|
-
* - `root` The
|
|
68
|
-
* DOM element. Append your content to it.
|
|
67
|
+
* - `root` The internal container DOM element. Append your content to it.
|
|
69
68
|
* - `select` The reference to the `<vaadin-select>` element.
|
|
70
69
|
*/
|
|
71
70
|
renderer: SelectRenderer | undefined;
|
|
@@ -63,6 +63,7 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
63
63
|
type: Boolean,
|
|
64
64
|
value: false,
|
|
65
65
|
notify: true,
|
|
66
|
+
observer: '_openedChanged',
|
|
66
67
|
reflectToAttribute: true,
|
|
67
68
|
sync: true,
|
|
68
69
|
},
|
|
@@ -71,8 +72,7 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
71
72
|
* Custom function for rendering the content of the `<vaadin-select>`.
|
|
72
73
|
* Receives two arguments:
|
|
73
74
|
*
|
|
74
|
-
* - `root` The
|
|
75
|
-
* DOM element. Append your content to it.
|
|
75
|
+
* - `root` The internal container DOM element. Append your content to it.
|
|
76
76
|
* - `select` The reference to the `<vaadin-select>` element.
|
|
77
77
|
* @type {!SelectRenderer | undefined}
|
|
78
78
|
*/
|
|
@@ -160,11 +160,7 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
static get observers() {
|
|
163
|
-
return [
|
|
164
|
-
'_updateAriaExpanded(opened, focusElement)',
|
|
165
|
-
'_updateSelectedItem(value, _items, placeholder)',
|
|
166
|
-
'_openedChanged(opened, _overlayElement)',
|
|
167
|
-
];
|
|
163
|
+
return ['_updateAriaExpanded(opened, focusElement)', '_updateSelectedItem(value, _items, placeholder)'];
|
|
168
164
|
}
|
|
169
165
|
|
|
170
166
|
constructor() {
|
|
@@ -207,6 +203,15 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
207
203
|
this.addController(this._tooltipController);
|
|
208
204
|
}
|
|
209
205
|
|
|
206
|
+
/** @protected */
|
|
207
|
+
updated(props) {
|
|
208
|
+
super.updated(props);
|
|
209
|
+
|
|
210
|
+
if (props.has('_phone')) {
|
|
211
|
+
this.toggleAttribute('phone', this._phone);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
210
215
|
/**
|
|
211
216
|
* Requests an update for the content of the select.
|
|
212
217
|
* While performing the update, it invokes the renderer passed in the `renderer` property.
|
|
@@ -219,10 +224,6 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
219
224
|
}
|
|
220
225
|
|
|
221
226
|
this._overlayElement.requestContentUpdate();
|
|
222
|
-
|
|
223
|
-
if (this._menuElement && this._menuElement.items) {
|
|
224
|
-
this._updateSelectedItem(this.value, this._menuElement.items);
|
|
225
|
-
}
|
|
226
227
|
}
|
|
227
228
|
|
|
228
229
|
/**
|
|
@@ -283,6 +284,12 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
283
284
|
// Store the menu element reference
|
|
284
285
|
this.__lastMenuElement = menuElement;
|
|
285
286
|
}
|
|
287
|
+
|
|
288
|
+
// When the renderer was re-assigned so that menu element is preserved
|
|
289
|
+
// but its items have changed, make sure selected property is updated.
|
|
290
|
+
if (this._menuElement && this._menuElement.items) {
|
|
291
|
+
this._updateSelectedItem(this.value, this._menuElement.items);
|
|
292
|
+
}
|
|
286
293
|
}
|
|
287
294
|
|
|
288
295
|
/** @private */
|
|
@@ -326,6 +333,12 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
326
333
|
// Prevent mousedown event to avoid blur and preserve focused state
|
|
327
334
|
// while opening, and to restore focus-ring attribute on closing.
|
|
328
335
|
event.preventDefault();
|
|
336
|
+
|
|
337
|
+
// Clicking the `vaadin-input-container` focuses the value button
|
|
338
|
+
// but clicking the toggle button does not, so we handle it here.
|
|
339
|
+
if (!this.opened) {
|
|
340
|
+
this.focusElement.focus();
|
|
341
|
+
}
|
|
329
342
|
}
|
|
330
343
|
|
|
331
344
|
/**
|
|
@@ -358,17 +371,21 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
358
371
|
* @protected
|
|
359
372
|
*/
|
|
360
373
|
_onKeyDownInside(e) {
|
|
361
|
-
if (
|
|
374
|
+
if (e.key === 'Tab') {
|
|
375
|
+
// Temporarily set tabindex to prevent moving focus
|
|
376
|
+
// to the value button element on item Shift + Tab
|
|
377
|
+
this.focusElement.setAttribute('tabindex', '-1');
|
|
378
|
+
this._overlayElement.restoreFocusOnClose = false;
|
|
362
379
|
this.opened = false;
|
|
380
|
+
setTimeout(() => {
|
|
381
|
+
this.focusElement.setAttribute('tabindex', '0');
|
|
382
|
+
this._overlayElement.restoreFocusOnClose = true;
|
|
383
|
+
});
|
|
363
384
|
}
|
|
364
385
|
}
|
|
365
386
|
|
|
366
387
|
/** @private */
|
|
367
|
-
_openedChanged(opened,
|
|
368
|
-
if (!overlayElement) {
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
|
|
388
|
+
_openedChanged(opened, oldOpened) {
|
|
372
389
|
if (opened) {
|
|
373
390
|
if (this.disabled || this.readonly) {
|
|
374
391
|
// Disallow programmatic opening when disabled or readonly
|
|
@@ -379,8 +396,6 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
379
396
|
// Avoid multiple announcements when a value gets selected from the dropdown
|
|
380
397
|
this._updateAriaLive(false);
|
|
381
398
|
|
|
382
|
-
overlayElement.style.setProperty('--vaadin-select-text-field-width', `${this._inputContainer.offsetWidth}px`);
|
|
383
|
-
|
|
384
399
|
// Preserve focus-ring to restore it later
|
|
385
400
|
const hasFocusRing = this.hasAttribute('focus-ring');
|
|
386
401
|
this._openedWithFocusRing = hasFocusRing;
|
|
@@ -389,7 +404,7 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
389
404
|
if (hasFocusRing) {
|
|
390
405
|
this.removeAttribute('focus-ring');
|
|
391
406
|
}
|
|
392
|
-
} else if (
|
|
407
|
+
} else if (oldOpened) {
|
|
393
408
|
if (this._openedWithFocusRing) {
|
|
394
409
|
this.setAttribute('focus-ring', '');
|
|
395
410
|
}
|
|
@@ -401,8 +416,6 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
401
416
|
this._requestValidation();
|
|
402
417
|
}
|
|
403
418
|
}
|
|
404
|
-
|
|
405
|
-
this.__oldOpened = opened;
|
|
406
419
|
}
|
|
407
420
|
|
|
408
421
|
/** @private */
|
|
@@ -590,8 +603,8 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
590
603
|
* @protected
|
|
591
604
|
* @override
|
|
592
605
|
*/
|
|
593
|
-
_shouldRemoveFocus() {
|
|
594
|
-
return !this.
|
|
606
|
+
_shouldRemoveFocus(event) {
|
|
607
|
+
return !this.contains(event.relatedTarget);
|
|
595
608
|
}
|
|
596
609
|
|
|
597
610
|
/**
|
|
@@ -644,13 +657,7 @@ export const SelectBaseMixin = (superClass) =>
|
|
|
644
657
|
}
|
|
645
658
|
|
|
646
659
|
/** @private */
|
|
647
|
-
|
|
648
|
-
// Wait for the update complete to guarantee that value-changed is fired
|
|
649
|
-
// before validated and change events when using the Lit version of the component.
|
|
650
|
-
if (this.updateComplete) {
|
|
651
|
-
await this.updateComplete;
|
|
652
|
-
}
|
|
653
|
-
|
|
660
|
+
__dispatchChange() {
|
|
654
661
|
this._requestValidation();
|
|
655
662
|
this.dispatchEvent(new CustomEvent('change', { bubbles: true }));
|
|
656
663
|
this.__dispatchChangePending = false;
|
|
@@ -7,8 +7,9 @@ import { html, LitElement } from 'lit';
|
|
|
7
7
|
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
8
8
|
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
9
9
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
10
|
-
import { itemStyles } from '@vaadin/item/src/vaadin-item-
|
|
10
|
+
import { itemStyles } from '@vaadin/item/src/styles/vaadin-item-base-styles.js';
|
|
11
11
|
import { ItemMixin } from '@vaadin/item/src/vaadin-item-mixin.js';
|
|
12
|
+
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
|
|
12
13
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -21,7 +22,7 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
21
22
|
* @mixes ThemableMixin
|
|
22
23
|
* @protected
|
|
23
24
|
*/
|
|
24
|
-
class SelectItem extends ItemMixin(ThemableMixin(DirMixin(PolylitMixin(LitElement)))) {
|
|
25
|
+
class SelectItem extends ItemMixin(ThemableMixin(DirMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
|
|
25
26
|
static get is() {
|
|
26
27
|
return 'vaadin-select-item';
|
|
27
28
|
}
|
|
@@ -8,7 +8,8 @@ import { ListMixin } from '@vaadin/a11y-base/src/list-mixin.js';
|
|
|
8
8
|
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
9
9
|
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
10
10
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
11
|
-
import { listBoxStyles } from '@vaadin/list-box/src/vaadin-list-box-
|
|
11
|
+
import { listBoxStyles } from '@vaadin/list-box/src/styles/vaadin-list-box-base-styles.js';
|
|
12
|
+
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
|
|
12
13
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -21,7 +22,7 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
21
22
|
* @mixes ThemableMixin
|
|
22
23
|
* @protected
|
|
23
24
|
*/
|
|
24
|
-
class SelectListBox extends ListMixin(ThemableMixin(DirMixin(PolylitMixin(LitElement)))) {
|
|
25
|
+
class SelectListBox extends ListMixin(ThemableMixin(DirMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
|
|
25
26
|
static get is() {
|
|
26
27
|
return 'vaadin-select-list-box';
|
|
27
28
|
}
|
|
@@ -16,7 +16,7 @@ import { PositionMixin } from '@vaadin/overlay/src/vaadin-overlay-position-mixin
|
|
|
16
16
|
export const SelectOverlayMixin = (superClass) =>
|
|
17
17
|
class SelectOverlayMixin extends PositionMixin(OverlayMixin(DirMixin(superClass))) {
|
|
18
18
|
static get observers() {
|
|
19
|
-
return ['_updateOverlayWidth(opened,
|
|
19
|
+
return ['_updateOverlayWidth(opened, positionTarget)'];
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/** @protected */
|
|
@@ -26,6 +26,21 @@ export const SelectOverlayMixin = (superClass) =>
|
|
|
26
26
|
this.restoreFocusOnClose = true;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* @override
|
|
31
|
+
* @protected
|
|
32
|
+
*/
|
|
33
|
+
get _contentRoot() {
|
|
34
|
+
if (!this.__savedRoot) {
|
|
35
|
+
const root = document.createElement('div');
|
|
36
|
+
root.setAttribute('slot', 'overlay');
|
|
37
|
+
this.owner.appendChild(root);
|
|
38
|
+
this.__savedRoot = root;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return this.__savedRoot;
|
|
42
|
+
}
|
|
43
|
+
|
|
29
44
|
/**
|
|
30
45
|
* Override method inherited from `Overlay` to always close on outside click,
|
|
31
46
|
* in order to avoid problem when using inside of the modeless dialog.
|
|
@@ -38,22 +53,26 @@ export const SelectOverlayMixin = (superClass) =>
|
|
|
38
53
|
return true;
|
|
39
54
|
}
|
|
40
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @protected
|
|
58
|
+
* @override
|
|
59
|
+
*/
|
|
60
|
+
_mouseDownListener(event) {
|
|
61
|
+
super._mouseDownListener(event);
|
|
62
|
+
|
|
63
|
+
// Prevent global mousedown event to avoid losing focus on outside click
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
}
|
|
66
|
+
|
|
41
67
|
/** @protected */
|
|
42
68
|
_getMenuElement() {
|
|
43
|
-
return Array.from(this.children).find((el) => el.localName !== 'style');
|
|
69
|
+
return Array.from(this._contentRoot.children).find((el) => el.localName !== 'style');
|
|
44
70
|
}
|
|
45
71
|
|
|
46
72
|
/** @private */
|
|
47
|
-
_updateOverlayWidth(opened,
|
|
48
|
-
if (opened &&
|
|
49
|
-
|
|
50
|
-
const customWidth = getComputedStyle(owner).getPropertyValue(widthProperty);
|
|
51
|
-
|
|
52
|
-
if (customWidth === '') {
|
|
53
|
-
this.style.removeProperty(widthProperty);
|
|
54
|
-
} else {
|
|
55
|
-
this.style.setProperty(widthProperty, customWidth);
|
|
56
|
-
}
|
|
73
|
+
_updateOverlayWidth(opened, positionTarget) {
|
|
74
|
+
if (opened && positionTarget) {
|
|
75
|
+
this.style.setProperty('--_vaadin-select-overlay-default-width', `${positionTarget.offsetWidth}px`);
|
|
57
76
|
}
|
|
58
77
|
}
|
|
59
78
|
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
import { html, LitElement } from 'lit';
|
|
7
7
|
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
8
8
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
9
|
-
import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
|
|
9
|
+
import { overlayStyles } from '@vaadin/overlay/src/styles/vaadin-overlay-base-styles.js';
|
|
10
|
+
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
|
|
10
11
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
11
|
-
import { selectOverlayStyles } from './vaadin-select-overlay-
|
|
12
|
+
import { selectOverlayStyles } from './styles/vaadin-select-overlay-base-styles.js';
|
|
12
13
|
import { SelectOverlayMixin } from './vaadin-select-overlay-mixin.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -20,7 +21,7 @@ import { SelectOverlayMixin } from './vaadin-select-overlay-mixin.js';
|
|
|
20
21
|
* @mixes ThemableMixin
|
|
21
22
|
* @private
|
|
22
23
|
*/
|
|
23
|
-
export class SelectOverlay extends SelectOverlayMixin(ThemableMixin(PolylitMixin(LitElement))) {
|
|
24
|
+
export class SelectOverlay extends SelectOverlayMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement)))) {
|
|
24
25
|
static get is() {
|
|
25
26
|
return 'vaadin-select-overlay';
|
|
26
27
|
}
|
|
@@ -33,7 +34,7 @@ export class SelectOverlay extends SelectOverlayMixin(ThemableMixin(PolylitMixin
|
|
|
33
34
|
render() {
|
|
34
35
|
return html`
|
|
35
36
|
<div id="backdrop" part="backdrop" ?hidden="${!this.withBackdrop}"></div>
|
|
36
|
-
<div part="overlay" id="overlay"
|
|
37
|
+
<div part="overlay" id="overlay">
|
|
37
38
|
<div part="content" id="content">
|
|
38
39
|
<slot></slot>
|
|
39
40
|
</div>
|
|
@@ -7,8 +7,9 @@ import { html, LitElement } from 'lit';
|
|
|
7
7
|
import { ButtonMixin } from '@vaadin/button/src/vaadin-button-mixin.js';
|
|
8
8
|
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
9
9
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
10
|
+
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
|
|
10
11
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
11
|
-
import { valueButton } from './vaadin-select-value-button-
|
|
12
|
+
import { valueButton } from './styles/vaadin-select-value-button-base-styles.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* An element used internally by `<vaadin-select>`. Not intended to be used separately.
|
|
@@ -19,7 +20,7 @@ import { valueButton } from './vaadin-select-value-button-core-styles.js';
|
|
|
19
20
|
* @mixes ThemableMixin
|
|
20
21
|
* @protected
|
|
21
22
|
*/
|
|
22
|
-
class SelectValueButton extends ButtonMixin(ThemableMixin(PolylitMixin(LitElement))) {
|
|
23
|
+
class SelectValueButton extends ButtonMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement)))) {
|
|
23
24
|
static get is() {
|
|
24
25
|
return 'vaadin-select-value-button';
|
|
25
26
|
}
|
package/src/vaadin-select.d.ts
CHANGED
|
@@ -26,8 +26,7 @@ export type SelectChangeEvent = Event & {
|
|
|
26
26
|
* Function for rendering the content of the `<vaadin-select>`.
|
|
27
27
|
* Receives two arguments:
|
|
28
28
|
*
|
|
29
|
-
* - `root` The
|
|
30
|
-
* DOM element. Append your content to it.
|
|
29
|
+
* - `root` The internal container DOM element. Append your content to it.
|
|
31
30
|
* - `select` The reference to the `<vaadin-select>` element.
|
|
32
31
|
*/
|
|
33
32
|
export type SelectRenderer = (root: HTMLElement, select: Select) => void;
|
|
@@ -126,11 +125,10 @@ export interface SelectEventMap extends HTMLElementEventMap, SelectCustomEventMa
|
|
|
126
125
|
*
|
|
127
126
|
* The following custom properties are available for styling:
|
|
128
127
|
*
|
|
129
|
-
* Custom property
|
|
130
|
-
*
|
|
131
|
-
* `--vaadin-field-default-width`
|
|
132
|
-
* `--vaadin-select-
|
|
133
|
-
* `--vaadin-select-overlay-width` | Width of the overlay | `vaadin-select-overlay` |
|
|
128
|
+
* Custom property | Description | Default
|
|
129
|
+
* ---------------------------------|-----------------------------|--------
|
|
130
|
+
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
131
|
+
* `--vaadin-select-overlay-width` | Width of the overlay |
|
|
134
132
|
*
|
|
135
133
|
* `<vaadin-select>` provides mostly the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
|
|
136
134
|
* See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
|
|
@@ -138,15 +136,19 @@ export interface SelectEventMap extends HTMLElementEventMap, SelectCustomEventMa
|
|
|
138
136
|
*
|
|
139
137
|
* In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
|
|
140
138
|
*
|
|
141
|
-
* Part name
|
|
142
|
-
*
|
|
143
|
-
* `toggle-button`
|
|
139
|
+
* Part name | Description
|
|
140
|
+
* -----------------|----------------
|
|
141
|
+
* `toggle-button` | The toggle button
|
|
142
|
+
* `backdrop` | Backdrop of the overlay
|
|
143
|
+
* `overlay` | The overlay container
|
|
144
|
+
* `content` | The overlay content
|
|
144
145
|
*
|
|
145
146
|
* In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
|
|
146
147
|
*
|
|
147
|
-
* Attribute | Description
|
|
148
|
-
*
|
|
149
|
-
* `opened` | Set when the select is open
|
|
148
|
+
* Attribute | Description
|
|
149
|
+
* ----------|-----------------------------
|
|
150
|
+
* `opened` | Set when the select is open
|
|
151
|
+
* `phone` | Set when the overlay is shown in phone mode
|
|
150
152
|
*
|
|
151
153
|
* There are two exceptions in terms of styling compared to `<vaadin-text-field>`:
|
|
152
154
|
* - the `clear-button` shadow DOM part does not exist in `<vaadin-select>`.
|
|
@@ -157,12 +159,9 @@ export interface SelectEventMap extends HTMLElementEventMap, SelectCustomEventMa
|
|
|
157
159
|
* In addition to `<vaadin-select>` itself, the following internal
|
|
158
160
|
* components are themable:
|
|
159
161
|
*
|
|
160
|
-
* - `<vaadin-select-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
|
|
161
162
|
* - `<vaadin-select-value-button>` - has the same API as [`<vaadin-button>`](#/elements/vaadin-button).
|
|
162
|
-
* - [`<vaadin-
|
|
163
|
-
*
|
|
164
|
-
* Note: the `theme` attribute value set on `<vaadin-select>` is
|
|
165
|
-
* propagated to the internal components listed above.
|
|
163
|
+
* - `<vaadin-select-list-box>` - has the same API as [`<vaadin-list-box>`](#/elements/vaadin-list-box).
|
|
164
|
+
* - `<vaadin-select-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).
|
|
166
165
|
*
|
|
167
166
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
168
167
|
*
|
package/src/vaadin-select.js
CHANGED
|
@@ -15,9 +15,10 @@ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
|
15
15
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
16
16
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
17
17
|
import { inputFieldShared } from '@vaadin/field-base/src/styles/input-field-shared-styles.js';
|
|
18
|
+
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
|
|
18
19
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
20
|
+
import { selectStyles } from './styles/vaadin-select-base-styles.js';
|
|
19
21
|
import { SelectBaseMixin } from './vaadin-select-base-mixin.js';
|
|
20
|
-
import { selectStyles } from './vaadin-select-core-styles.js';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* `<vaadin-select>` is a Web Component for selecting values from a list of items.
|
|
@@ -79,11 +80,10 @@ import { selectStyles } from './vaadin-select-core-styles.js';
|
|
|
79
80
|
*
|
|
80
81
|
* The following custom properties are available for styling:
|
|
81
82
|
*
|
|
82
|
-
* Custom property
|
|
83
|
-
*
|
|
84
|
-
* `--vaadin-field-default-width`
|
|
85
|
-
* `--vaadin-select-
|
|
86
|
-
* `--vaadin-select-overlay-width` | Width of the overlay | `vaadin-select-overlay` |
|
|
83
|
+
* Custom property | Description | Default
|
|
84
|
+
* ---------------------------------|-----------------------------|--------
|
|
85
|
+
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
86
|
+
* `--vaadin-select-overlay-width` | Width of the overlay |
|
|
87
87
|
*
|
|
88
88
|
* `<vaadin-select>` provides mostly the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
|
|
89
89
|
* See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
|
|
@@ -91,15 +91,19 @@ import { selectStyles } from './vaadin-select-core-styles.js';
|
|
|
91
91
|
*
|
|
92
92
|
* In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
|
|
93
93
|
*
|
|
94
|
-
* Part name
|
|
95
|
-
*
|
|
96
|
-
* `toggle-button`
|
|
94
|
+
* Part name | Description
|
|
95
|
+
* -----------------|----------------
|
|
96
|
+
* `toggle-button` | The toggle button
|
|
97
|
+
* `backdrop` | Backdrop of the overlay
|
|
98
|
+
* `overlay` | The overlay container
|
|
99
|
+
* `content` | The overlay content
|
|
97
100
|
*
|
|
98
101
|
* In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
|
|
99
102
|
*
|
|
100
|
-
* Attribute | Description
|
|
101
|
-
*
|
|
102
|
-
* `opened` | Set when the select is open
|
|
103
|
+
* Attribute | Description
|
|
104
|
+
* ----------|-----------------------------
|
|
105
|
+
* `opened` | Set when the select is open
|
|
106
|
+
* `phone` | Set when the overlay is shown in phone mode
|
|
103
107
|
*
|
|
104
108
|
* There are two exceptions in terms of styling compared to `<vaadin-text-field>`:
|
|
105
109
|
* - the `clear-button` shadow DOM part does not exist in `<vaadin-select>`.
|
|
@@ -110,12 +114,9 @@ import { selectStyles } from './vaadin-select-core-styles.js';
|
|
|
110
114
|
* In addition to `<vaadin-select>` itself, the following internal
|
|
111
115
|
* components are themable:
|
|
112
116
|
*
|
|
113
|
-
* - `<vaadin-select-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
|
|
114
117
|
* - `<vaadin-select-value-button>` - has the same API as [`<vaadin-button>`](#/elements/vaadin-button).
|
|
115
|
-
* - [`<vaadin-
|
|
116
|
-
*
|
|
117
|
-
* Note: the `theme` attribute value set on `<vaadin-select>` is
|
|
118
|
-
* propagated to the internal components listed above.
|
|
118
|
+
* - `<vaadin-select-list-box>` - has the same API as [`<vaadin-list-box>`](#/elements/vaadin-list-box).
|
|
119
|
+
* - `<vaadin-select-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).
|
|
119
120
|
*
|
|
120
121
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
121
122
|
*
|
|
@@ -131,7 +132,7 @@ import { selectStyles } from './vaadin-select-core-styles.js';
|
|
|
131
132
|
* @mixes SelectBaseMixin
|
|
132
133
|
* @mixes ThemableMixin
|
|
133
134
|
*/
|
|
134
|
-
class Select extends SelectBaseMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement)))) {
|
|
135
|
+
class Select extends SelectBaseMixin(ElementMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
|
|
135
136
|
static get is() {
|
|
136
137
|
return 'vaadin-select';
|
|
137
138
|
}
|
|
@@ -181,9 +182,12 @@ class Select extends SelectBaseMixin(ElementMixin(ThemableMixin(PolylitMixin(Lit
|
|
|
181
182
|
?phone="${this._phone}"
|
|
182
183
|
theme="${ifDefined(this._theme)}"
|
|
183
184
|
?no-vertical-overlap="${this.noVerticalOverlap}"
|
|
185
|
+
exportparts="backdrop, overlay, content"
|
|
184
186
|
@opened-changed="${this._onOpenedChanged}"
|
|
185
187
|
@vaadin-overlay-open="${this._onOverlayOpen}"
|
|
186
|
-
|
|
188
|
+
>
|
|
189
|
+
<slot name="overlay"></slot>
|
|
190
|
+
</vaadin-select-overlay>
|
|
187
191
|
|
|
188
192
|
<slot name="tooltip"></slot>
|
|
189
193
|
<div class="sr-only">
|
package/vaadin-select.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import './
|
|
1
|
+
import './src/vaadin-select.js';
|
|
2
2
|
export * from './src/vaadin-select.js';
|
package/web-types.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/web-types",
|
|
3
3
|
"name": "@vaadin/select",
|
|
4
|
-
"version": "25.0.0-
|
|
4
|
+
"version": "25.0.0-alpha11",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"contributions": {
|
|
7
7
|
"html": {
|
|
8
8
|
"elements": [
|
|
9
9
|
{
|
|
10
10
|
"name": "vaadin-select",
|
|
11
|
-
"description": "`<vaadin-select>` is a Web Component for selecting values from a list of items.\n\n### Items\n\nUse the `items` property to define possible options for the select:\n\n```html\n<vaadin-select id=\"select\"></vaadin-select>\n```\n```js\nconst select = document.querySelector('#select');\nselect.items = [\n { label: 'Most recent first', value: 'recent' },\n { component: 'hr' },\n { label: 'Rating: low to high', value: 'rating-asc', className: 'asc' },\n { label: 'Rating: high to low', value: 'rating-desc', className: 'desc' },\n { component: 'hr' },\n { label: 'Price: low to high', value: 'price-asc', disabled: true },\n { label: 'Price: high to low', value: 'price-desc', disabled: true }\n];\n```\n\n### Rendering\n\nAlternatively, the content of the select can be populated by using the renderer callback function.\n\nThe renderer function provides `root`, `select` arguments.\nGenerate DOM content, append it to the `root` element and control the state\nof the host element by accessing `select`.\n\n```js\nconst select = document.querySelector('#select');\nselect.renderer = function(root, select) {\n const listBox = document.createElement('vaadin-list-box');\n // append 3 <vaadin-item> elements\n ['Jose', 'Manolo', 'Pedro'].forEach(function(name) {\n const item = document.createElement('vaadin-item');\n item.textContent = name;\n item.setAttribute('label', name)\n listBox.appendChild(item);\n });\n\n // update the content\n root.appendChild(listBox);\n};\n```\n\nRenderer is called on initialization of new select and on its opening.\nDOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n* Hint: By setting the `label` property of inner vaadin-items you will\nbe able to change the visual representation of the selected value in the input part.\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property
|
|
11
|
+
"description": "`<vaadin-select>` is a Web Component for selecting values from a list of items.\n\n### Items\n\nUse the `items` property to define possible options for the select:\n\n```html\n<vaadin-select id=\"select\"></vaadin-select>\n```\n```js\nconst select = document.querySelector('#select');\nselect.items = [\n { label: 'Most recent first', value: 'recent' },\n { component: 'hr' },\n { label: 'Rating: low to high', value: 'rating-asc', className: 'asc' },\n { label: 'Rating: high to low', value: 'rating-desc', className: 'desc' },\n { component: 'hr' },\n { label: 'Price: low to high', value: 'price-asc', disabled: true },\n { label: 'Price: high to low', value: 'price-desc', disabled: true }\n];\n```\n\n### Rendering\n\nAlternatively, the content of the select can be populated by using the renderer callback function.\n\nThe renderer function provides `root`, `select` arguments.\nGenerate DOM content, append it to the `root` element and control the state\nof the host element by accessing `select`.\n\n```js\nconst select = document.querySelector('#select');\nselect.renderer = function(root, select) {\n const listBox = document.createElement('vaadin-list-box');\n // append 3 <vaadin-item> elements\n ['Jose', 'Manolo', 'Pedro'].forEach(function(name) {\n const item = document.createElement('vaadin-item');\n item.textContent = name;\n item.setAttribute('label', name)\n listBox.appendChild(item);\n });\n\n // update the content\n root.appendChild(listBox);\n};\n```\n\nRenderer is called on initialization of new select and on its opening.\nDOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n* Hint: By setting the `label` property of inner vaadin-items you will\nbe able to change the visual representation of the selected value in the input part.\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-select-overlay-width` | Width of the overlay |\n\n`<vaadin-select>` provides mostly the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.\nSee [`<vaadin-text-field>`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha11/#/elements/vaadin-text-field) for the styling documentation.\n\n\nIn addition to `<vaadin-text-field>` parts, the following parts are available for theming:\n\nPart name | Description\n-----------------|----------------\n`toggle-button` | The toggle button\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\nIn addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:\n\nAttribute | Description\n----------|-----------------------------\n`opened` | Set when the select is open\n`phone` | Set when the overlay is shown in phone mode\n\nThere are two exceptions in terms of styling compared to `<vaadin-text-field>`:\n- the `clear-button` shadow DOM part does not exist in `<vaadin-select>`.\n- the `input-prevented` state attribute is not supported by `<vaadin-select>`.\n\n### Internal components\n\nIn addition to `<vaadin-select>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-select-value-button>` - has the same API as [`<vaadin-button>`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha11/#/elements/vaadin-button).\n- `<vaadin-select-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha11/#/elements/vaadin-list-box).\n- `<vaadin-select-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha11/#/elements/vaadin-item).\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
|
|
12
12
|
"attributes": [
|
|
13
13
|
{
|
|
14
14
|
"name": "disabled",
|
|
@@ -346,7 +346,7 @@
|
|
|
346
346
|
},
|
|
347
347
|
{
|
|
348
348
|
"name": "renderer",
|
|
349
|
-
"description": "Custom function for rendering the content of the `<vaadin-select>`.\nReceives two arguments:\n\n- `root` The
|
|
349
|
+
"description": "Custom function for rendering the content of the `<vaadin-select>`.\nReceives two arguments:\n\n- `root` The internal container DOM element. Append your content to it.\n- `select` The reference to the `<vaadin-select>` element.",
|
|
350
350
|
"value": {
|
|
351
351
|
"type": [
|
|
352
352
|
"SelectRenderer",
|
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/select",
|
|
4
|
-
"version": "25.0.0-
|
|
4
|
+
"version": "25.0.0-alpha11",
|
|
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-select",
|
|
19
|
-
"description": "`<vaadin-select>` is a Web Component for selecting values from a list of items.\n\n### Items\n\nUse the `items` property to define possible options for the select:\n\n```html\n<vaadin-select id=\"select\"></vaadin-select>\n```\n```js\nconst select = document.querySelector('#select');\nselect.items = [\n { label: 'Most recent first', value: 'recent' },\n { component: 'hr' },\n { label: 'Rating: low to high', value: 'rating-asc', className: 'asc' },\n { label: 'Rating: high to low', value: 'rating-desc', className: 'desc' },\n { component: 'hr' },\n { label: 'Price: low to high', value: 'price-asc', disabled: true },\n { label: 'Price: high to low', value: 'price-desc', disabled: true }\n];\n```\n\n### Rendering\n\nAlternatively, the content of the select can be populated by using the renderer callback function.\n\nThe renderer function provides `root`, `select` arguments.\nGenerate DOM content, append it to the `root` element and control the state\nof the host element by accessing `select`.\n\n```js\nconst select = document.querySelector('#select');\nselect.renderer = function(root, select) {\n const listBox = document.createElement('vaadin-list-box');\n // append 3 <vaadin-item> elements\n ['Jose', 'Manolo', 'Pedro'].forEach(function(name) {\n const item = document.createElement('vaadin-item');\n item.textContent = name;\n item.setAttribute('label', name)\n listBox.appendChild(item);\n });\n\n // update the content\n root.appendChild(listBox);\n};\n```\n\nRenderer is called on initialization of new select and on its opening.\nDOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n* Hint: By setting the `label` property of inner vaadin-items you will\nbe able to change the visual representation of the selected value in the input part.\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property
|
|
19
|
+
"description": "`<vaadin-select>` is a Web Component for selecting values from a list of items.\n\n### Items\n\nUse the `items` property to define possible options for the select:\n\n```html\n<vaadin-select id=\"select\"></vaadin-select>\n```\n```js\nconst select = document.querySelector('#select');\nselect.items = [\n { label: 'Most recent first', value: 'recent' },\n { component: 'hr' },\n { label: 'Rating: low to high', value: 'rating-asc', className: 'asc' },\n { label: 'Rating: high to low', value: 'rating-desc', className: 'desc' },\n { component: 'hr' },\n { label: 'Price: low to high', value: 'price-asc', disabled: true },\n { label: 'Price: high to low', value: 'price-desc', disabled: true }\n];\n```\n\n### Rendering\n\nAlternatively, the content of the select can be populated by using the renderer callback function.\n\nThe renderer function provides `root`, `select` arguments.\nGenerate DOM content, append it to the `root` element and control the state\nof the host element by accessing `select`.\n\n```js\nconst select = document.querySelector('#select');\nselect.renderer = function(root, select) {\n const listBox = document.createElement('vaadin-list-box');\n // append 3 <vaadin-item> elements\n ['Jose', 'Manolo', 'Pedro'].forEach(function(name) {\n const item = document.createElement('vaadin-item');\n item.textContent = name;\n item.setAttribute('label', name)\n listBox.appendChild(item);\n });\n\n // update the content\n root.appendChild(listBox);\n};\n```\n\nRenderer is called on initialization of new select and on its opening.\nDOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n* Hint: By setting the `label` property of inner vaadin-items you will\nbe able to change the visual representation of the selected value in the input part.\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-select-overlay-width` | Width of the overlay |\n\n`<vaadin-select>` provides mostly the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.\nSee [`<vaadin-text-field>`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha11/#/elements/vaadin-text-field) for the styling documentation.\n\n\nIn addition to `<vaadin-text-field>` parts, the following parts are available for theming:\n\nPart name | Description\n-----------------|----------------\n`toggle-button` | The toggle button\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\nIn addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:\n\nAttribute | Description\n----------|-----------------------------\n`opened` | Set when the select is open\n`phone` | Set when the overlay is shown in phone mode\n\nThere are two exceptions in terms of styling compared to `<vaadin-text-field>`:\n- the `clear-button` shadow DOM part does not exist in `<vaadin-select>`.\n- the `input-prevented` state attribute is not supported by `<vaadin-select>`.\n\n### Internal components\n\nIn addition to `<vaadin-select>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-select-value-button>` - has the same API as [`<vaadin-button>`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha11/#/elements/vaadin-button).\n- `<vaadin-select-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha11/#/elements/vaadin-list-box).\n- `<vaadin-select-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha11/#/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
|
{
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
"name": ".renderer",
|
|
129
|
-
"description": "Custom function for rendering the content of the `<vaadin-select>`.\nReceives two arguments:\n\n- `root` The
|
|
129
|
+
"description": "Custom function for rendering the content of the `<vaadin-select>`.\nReceives two arguments:\n\n- `root` The internal container DOM element. Append your content to it.\n- `select` The reference to the `<vaadin-select>` element.",
|
|
130
130
|
"value": {
|
|
131
131
|
"kind": "expression"
|
|
132
132
|
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2017 - 2025 Vaadin Ltd.
|
|
4
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
-
*/
|
|
6
|
-
import '@vaadin/component-base/src/style-props.js';
|
|
7
|
-
import { css } from 'lit';
|
|
8
|
-
|
|
9
|
-
export const selectStyles = css`
|
|
10
|
-
@layer base {
|
|
11
|
-
:host {
|
|
12
|
-
position: relative;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
::slotted([slot='value']) {
|
|
16
|
-
flex: 1;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
:host(:not([focus-ring])) [part='input-field'] {
|
|
20
|
-
outline: none;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
:host([readonly]:not([focus-ring])) [part='input-field'] {
|
|
24
|
-
--vaadin-input-field-border-color: inherit;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
[part='input-field'],
|
|
28
|
-
:host(:not([readonly])) ::slotted([slot='value']) {
|
|
29
|
-
cursor: var(--vaadin-clickable-cursor);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
[part='toggle-button']::before {
|
|
33
|
-
mask-image: var(--_vaadin-icon-chevron-down);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
`;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2017 - 2025 Vaadin Ltd.
|
|
4
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
-
*/
|
|
6
|
-
import { css } from 'lit';
|
|
7
|
-
|
|
8
|
-
export const selectStyles = css`
|
|
9
|
-
:host {
|
|
10
|
-
position: relative;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
::slotted([slot='value']) {
|
|
14
|
-
flex-grow: 1;
|
|
15
|
-
}
|
|
16
|
-
`;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2017 - 2025 Vaadin Ltd.
|
|
4
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
-
*/
|
|
6
|
-
import { css } from 'lit';
|
|
7
|
-
|
|
8
|
-
export const selectOverlayStyles = css`
|
|
9
|
-
@layer base {
|
|
10
|
-
:host {
|
|
11
|
-
align-items: flex-start;
|
|
12
|
-
justify-content: flex-start;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
:host(:not([phone])) [part='overlay'] {
|
|
16
|
-
min-width: var(--vaadin-select-overlay-width, var(--vaadin-select-text-field-width));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
[part='content'] {
|
|
20
|
-
padding: var(--vaadin-item-overlay-padding, 4px);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
`;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2017 - 2025 Vaadin Ltd.
|
|
4
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
-
*/
|
|
6
|
-
import { css } from 'lit';
|
|
7
|
-
|
|
8
|
-
export const valueButton = css`
|
|
9
|
-
@layer base {
|
|
10
|
-
:host {
|
|
11
|
-
min-height: 1lh;
|
|
12
|
-
outline: none;
|
|
13
|
-
overflow: hidden;
|
|
14
|
-
white-space: nowrap;
|
|
15
|
-
width: 100%;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
::slotted(*) {
|
|
19
|
-
padding: 0;
|
|
20
|
-
cursor: inherit;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.vaadin-button-container,
|
|
24
|
-
[part='label'] {
|
|
25
|
-
display: contents;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
:host([disabled]) {
|
|
29
|
-
pointer-events: none;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
`;
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2017 - 2025 Vaadin Ltd.
|
|
4
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
-
*/
|
|
6
|
-
import { css } from 'lit';
|
|
7
|
-
|
|
8
|
-
export const valueButton = css`
|
|
9
|
-
:host {
|
|
10
|
-
display: inline-block;
|
|
11
|
-
position: relative;
|
|
12
|
-
outline: none;
|
|
13
|
-
white-space: nowrap;
|
|
14
|
-
-webkit-user-select: none;
|
|
15
|
-
user-select: none;
|
|
16
|
-
min-width: 0;
|
|
17
|
-
width: 0;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
::slotted(*) {
|
|
21
|
-
padding-left: 0;
|
|
22
|
-
padding-right: 0;
|
|
23
|
-
flex: auto;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/* placeholder styles */
|
|
27
|
-
::slotted(*:not([selected])) {
|
|
28
|
-
line-height: 1;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.vaadin-button-container {
|
|
32
|
-
display: inline-flex;
|
|
33
|
-
align-items: center;
|
|
34
|
-
justify-content: center;
|
|
35
|
-
text-align: inherit;
|
|
36
|
-
width: 100%;
|
|
37
|
-
height: 100%;
|
|
38
|
-
min-height: inherit;
|
|
39
|
-
text-shadow: inherit;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
[part='label'] {
|
|
43
|
-
white-space: nowrap;
|
|
44
|
-
overflow: hidden;
|
|
45
|
-
text-overflow: ellipsis;
|
|
46
|
-
width: 100%;
|
|
47
|
-
line-height: inherit;
|
|
48
|
-
}
|
|
49
|
-
`;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2017 - 2025 Vaadin Ltd.
|
|
4
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
-
*/
|
|
6
|
-
import '@vaadin/input-container/theme/lumo/vaadin-input-container-styles.js';
|
|
7
|
-
import '@vaadin/vaadin-lumo-styles/sizing.js';
|
|
8
|
-
import '@vaadin/vaadin-lumo-styles/style.js';
|
|
9
|
-
import '@vaadin/vaadin-lumo-styles/font-icons.js';
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2017 - 2025 Vaadin Ltd.
|
|
4
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
-
*/
|
|
6
|
-
import '@vaadin/input-container/theme/lumo/vaadin-input-container-styles.js';
|
|
7
|
-
import '@vaadin/vaadin-lumo-styles/sizing.js';
|
|
8
|
-
import '@vaadin/vaadin-lumo-styles/style.js';
|
|
9
|
-
import '@vaadin/vaadin-lumo-styles/font-icons.js';
|
|
10
|
-
import { item } from '@vaadin/item/theme/lumo/vaadin-item-styles.js';
|
|
11
|
-
import { listBox } from '@vaadin/list-box/theme/lumo/vaadin-list-box-styles.js';
|
|
12
|
-
import { inputFieldShared } from '@vaadin/vaadin-lumo-styles/mixins/input-field-shared.js';
|
|
13
|
-
import { menuOverlay } from '@vaadin/vaadin-lumo-styles/mixins/menu-overlay.js';
|
|
14
|
-
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
15
|
-
|
|
16
|
-
registerStyles('vaadin-select-item', item, { moduleId: 'lumo-select-item' });
|
|
17
|
-
|
|
18
|
-
registerStyles('vaadin-select-list-box', listBox, { moduleId: 'lumo-select-list-box' });
|
|
19
|
-
|
|
20
|
-
const select = css`
|
|
21
|
-
:host {
|
|
22
|
-
/* Disable pointer focus-ring for select, not supported yet */
|
|
23
|
-
--lumo-input-field-pointer-focus-visible: 0;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
:host(:not([theme*='align'])) ::slotted([slot='value']) {
|
|
27
|
-
text-align: start;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
[part='input-field'] {
|
|
31
|
-
cursor: var(--lumo-clickable-cursor);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
[part='input-field'] ::slotted([slot='value']) {
|
|
35
|
-
font-weight: var(--vaadin-input-field-value-font-weight, 500);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
[part='input-field'] ::slotted([slot='value']:not([placeholder])) {
|
|
39
|
-
color: var(--vaadin-input-field-value-color, var(--lumo-body-text-color));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
:host([readonly]) [part='input-field'] ::slotted([slot='value']:not([placeholder])) {
|
|
43
|
-
color: var(--lumo-secondary-text-color);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/* placeholder styles */
|
|
47
|
-
[part='input-field'] ::slotted([slot='value'][placeholder]) {
|
|
48
|
-
color: var(--vaadin-input-field-placeholder-color, var(--lumo-secondary-text-color));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
:host(:is([readonly], [disabled])) ::slotted([slot='value'][placeholder]) {
|
|
52
|
-
opacity: 0;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
[part='toggle-button']::before {
|
|
56
|
-
content: var(--lumo-icons-dropdown);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/* Highlight the toggle button when hovering over the entire component */
|
|
60
|
-
:host(:hover:not([readonly]):not([disabled])) [part='toggle-button'] {
|
|
61
|
-
color: var(--lumo-contrast-80pct);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
:host([theme~='small']) [part='input-field'] ::slotted([slot='value']) {
|
|
65
|
-
--_lumo-selected-item-height: var(--lumo-size-s);
|
|
66
|
-
--_lumo-selected-item-padding: 0;
|
|
67
|
-
}
|
|
68
|
-
`;
|
|
69
|
-
|
|
70
|
-
registerStyles('vaadin-select', [inputFieldShared, select], { moduleId: 'lumo-select' });
|
|
71
|
-
|
|
72
|
-
registerStyles(
|
|
73
|
-
'vaadin-select-value-button',
|
|
74
|
-
css`
|
|
75
|
-
:host {
|
|
76
|
-
font-family: var(--lumo-font-family);
|
|
77
|
-
font-size: var(--vaadin-input-field-value-font-size, var(--lumo-font-size-m));
|
|
78
|
-
padding: 0 0.25em;
|
|
79
|
-
--_lumo-selected-item-height: var(--lumo-size-m);
|
|
80
|
-
--_lumo-selected-item-padding: 0.5em;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
::slotted(*) {
|
|
84
|
-
min-height: var(--_lumo-selected-item-height);
|
|
85
|
-
padding-top: var(--_lumo-selected-item-padding);
|
|
86
|
-
padding-bottom: var(--_lumo-selected-item-padding);
|
|
87
|
-
font-size: inherit;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
::slotted(*:hover) {
|
|
91
|
-
background-color: transparent;
|
|
92
|
-
}
|
|
93
|
-
`,
|
|
94
|
-
{ moduleId: 'lumo-select-value-button' },
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
const selectOverlay = css`
|
|
98
|
-
:host {
|
|
99
|
-
--_lumo-item-selected-icon-display: block;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/* Small viewport adjustment */
|
|
103
|
-
:host([phone]) {
|
|
104
|
-
/* stylelint-disable declaration-block-no-redundant-longhand-properties */
|
|
105
|
-
top: 0 !important;
|
|
106
|
-
right: 0 !important;
|
|
107
|
-
bottom: var(--vaadin-overlay-viewport-bottom, 0) !important;
|
|
108
|
-
left: 0 !important;
|
|
109
|
-
/* stylelint-enable declaration-block-no-redundant-longhand-properties */
|
|
110
|
-
align-items: stretch;
|
|
111
|
-
justify-content: flex-end;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
:host([no-vertical-overlap][top-aligned]) [part='overlay'] {
|
|
115
|
-
margin-block-start: var(--lumo-space-xs);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
:host([no-vertical-overlap][bottom-aligned]) [part='overlay'] {
|
|
119
|
-
margin-block-end: var(--lumo-space-xs);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
:host([theme~='align-left']) {
|
|
123
|
-
text-align: left;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
:host([theme~='align-right']) {
|
|
127
|
-
text-align: right;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
:host([theme~='align-center']) {
|
|
131
|
-
text-align: center;
|
|
132
|
-
}
|
|
133
|
-
`;
|
|
134
|
-
|
|
135
|
-
registerStyles('vaadin-select-overlay', [menuOverlay, selectOverlay], { moduleId: 'lumo-select-overlay' });
|
|
File without changes
|