@vaadin/select 22.0.0-alpha9 → 22.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,17 +1,14 @@
1
- # <vaadin-select>
1
+ # @vaadin/select
2
2
 
3
- [Live Demo ↗](https://vaadin.com/components/vaadin-select/html-examples)
4
- |
5
- [API documentation ↗](https://vaadin.com/components/vaadin-select/html-api)
3
+ A web component for selecting a single value from a list of options presented in an overlay.
6
4
 
7
- [<vaadin-select>](https://vaadin.com/components/vaadin-select) is a Web Component similar to a native browser select element, part of the [Vaadin components](https://vaadin.com/components).
5
+ [Documentation + Live Demo ](https://vaadin.com/docs/latest/ds/components/select)
8
6
 
9
7
  [![npm version](https://badgen.net/npm/v/@vaadin/vaadin-select)](https://www.npmjs.com/package/@vaadin/vaadin-select)
10
- [![Published on Vaadin Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0.svg)](https://vaadin.com/directory/component/vaadinvaadin-select)
11
8
  [![Discord](https://img.shields.io/discord/732335336448852018?label=discord)](https://discord.gg/PHmkCKC)
12
9
 
13
10
  ```html
14
- <vaadin-select></vaadin-select>
11
+ <vaadin-select label="Sort by"></vaadin-select>
15
12
  <script>
16
13
  document.querySelector('vaadin-select').renderer = (root) => {
17
14
  if (root.firstElementChild) {
@@ -19,55 +16,58 @@
19
16
  }
20
17
 
21
18
  // Note that innerHTML is only used for demo purposes here!
22
- // Prefer using a templating library instead.
19
+ // Consider using Lit or another template library instead.
23
20
  root.innerHTML = `
24
21
  <vaadin-list-box>
25
- <vaadin-item>Option one</vaadin-item>
26
- <vaadin-item>Option two</vaadin-item>
27
- <vaadin-item>Option three</vaadin-item>
28
- <hr>
29
- <vaadin-item disabled>Option four</vaadin-item>
22
+ <vaadin-item value="recent">Most recent first</vaadin-item>
23
+ <vaadin-item value="rating-desc">Rating: high to low</vaadin-item>
24
+ <vaadin-item value="rating-asc">Rating: low to high</vaadin-item>
25
+ <vaadin-item value="price-desc">Price: high to low</vaadin-item>
26
+ <vaadin-item value="price-asc">Price: low to high</vaadin-item>
30
27
  </vaadin-list-box>
31
28
  `;
32
29
  };
33
30
  </script>
34
31
  ```
35
32
 
36
- [<img src="https://raw.githubusercontent.com/vaadin/vaadin-select/master/screenshot.gif" width="220" alt="Screenshot of vaadin-select">](https://vaadin.com/components/vaadin-select)
33
+ [<img src="https://raw.githubusercontent.com/vaadin/web-components/master/packages/select/screenshot.png" width="231" alt="Screenshot of vaadin-select">](https://vaadin.com/docs/latest/ds/components/select)
37
34
 
38
35
  ## Installation
39
36
 
40
- Install `vaadin-select`:
37
+ Install the component:
41
38
 
42
39
  ```sh
43
- npm i @vaadin/vaadin-select --save
40
+ npm i @vaadin/select
44
41
  ```
45
42
 
46
- Once installed, import it in your application:
43
+ Once installed, import the component in your application:
47
44
 
48
45
  ```js
49
- import '@vaadin/vaadin-select/vaadin-select.js';
46
+ import '@vaadin/select';
50
47
  ```
51
48
 
52
- ## Getting started
49
+ ## Themes
53
50
 
54
- Vaadin components use the Lumo theme by default.
51
+ Vaadin components come with two built-in [themes](https://vaadin.com/docs/latest/ds/customization/using-themes), Lumo and Material.
52
+ The [main entrypoint](https://github.com/vaadin/web-components/blob/master/packages/select/vaadin-select.js) of the package uses the Lumo theme.
55
53
 
56
- To use the Material theme, import the correspondent file from the `theme/material` folder.
54
+ To use the Material theme, import the component from the `theme/material` folder:
57
55
 
58
- ## Entry points
59
-
60
- - The component with the Lumo theme:
61
-
62
- `theme/lumo/vaadin-select.js`
56
+ ```js
57
+ import '@vaadin/select/theme/material/vaadin-select.js';
58
+ ```
63
59
 
64
- - The component with the Material theme:
60
+ You can also import the Lumo version of the component explicitly:
65
61
 
66
- - `theme/material/vaadin-select.js`
62
+ ```js
63
+ import '@vaadin/select/theme/lumo/vaadin-select.js';
64
+ ```
67
65
 
68
- - Alias for `theme/lumo/vaadin-select.js`:
66
+ Finally, you can import the un-themed component from the `src` folder to get a minimal starting point:
69
67
 
70
- - `vaadin-select.js`
68
+ ```js
69
+ import '@vaadin/select/src/vaadin-select.js';
70
+ ```
71
71
 
72
72
  ## Contributing
73
73
 
@@ -77,4 +77,5 @@ Read the [contributing guide](https://vaadin.com/docs/latest/guide/contributing/
77
77
 
78
78
  Apache License 2.0
79
79
 
80
- Vaadin collects development time usage statistics to improve this product. For details and to opt-out, see https://github.com/vaadin/vaadin-usage-statistics.
80
+ Vaadin collects usage statistics at development time to improve this product.
81
+ For details and to opt-out, see https://github.com/vaadin/vaadin-usage-statistics.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/select",
3
- "version": "22.0.0-alpha9",
3
+ "version": "22.0.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -34,24 +34,24 @@
34
34
  "dependencies": {
35
35
  "@polymer/iron-media-query": "^3.0.0",
36
36
  "@polymer/polymer": "^3.2.0",
37
- "@vaadin/button": "22.0.0-alpha9",
38
- "@vaadin/component-base": "22.0.0-alpha9",
39
- "@vaadin/field-base": "22.0.0-alpha9",
40
- "@vaadin/input-container": "22.0.0-alpha9",
41
- "@vaadin/item": "22.0.0-alpha9",
42
- "@vaadin/list-box": "22.0.0-alpha9",
43
- "@vaadin/vaadin-list-mixin": "22.0.0-alpha9",
44
- "@vaadin/vaadin-lumo-styles": "22.0.0-alpha9",
45
- "@vaadin/vaadin-material-styles": "22.0.0-alpha9",
46
- "@vaadin/vaadin-overlay": "22.0.0-alpha9",
47
- "@vaadin/vaadin-themable-mixin": "22.0.0-alpha9"
37
+ "@vaadin/button": "^22.0.0",
38
+ "@vaadin/component-base": "^22.0.0",
39
+ "@vaadin/field-base": "^22.0.0",
40
+ "@vaadin/input-container": "^22.0.0",
41
+ "@vaadin/item": "^22.0.0",
42
+ "@vaadin/list-box": "^22.0.0",
43
+ "@vaadin/vaadin-list-mixin": "^22.0.0",
44
+ "@vaadin/vaadin-lumo-styles": "^22.0.0",
45
+ "@vaadin/vaadin-material-styles": "^22.0.0",
46
+ "@vaadin/vaadin-overlay": "^22.0.0",
47
+ "@vaadin/vaadin-themable-mixin": "^22.0.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@esm-bundle/chai": "^4.3.4",
51
- "@vaadin/polymer-legacy-adapter": "22.0.0-alpha9",
52
- "@vaadin/testing-helpers": "^0.3.0",
51
+ "@vaadin/polymer-legacy-adapter": "^22.0.0",
52
+ "@vaadin/testing-helpers": "^0.3.2",
53
53
  "lit": "^2.0.0",
54
54
  "sinon": "^9.2.0"
55
55
  },
56
- "gitHead": "6e8c899dc65918f97e3c0acb2076122c4b2ef274"
56
+ "gitHead": "b668e9b1a975227fbe34beb70d1cd5b03dce2348"
57
57
  }
@@ -4,8 +4,8 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { OverlayElement } from '@vaadin/vaadin-overlay/src/vaadin-overlay.js';
7
- import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
8
7
  import { PositionMixin } from '@vaadin/vaadin-overlay/src/vaadin-overlay-position-mixin.js';
8
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
9
9
 
10
10
  registerStyles(
11
11
  'vaadin-select-overlay',
@@ -4,7 +4,7 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { Button } from '@vaadin/button/src/vaadin-button.js';
7
- import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
7
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
8
8
 
9
9
  registerStyles(
10
10
  'vaadin-select-value-button',
@@ -92,23 +92,25 @@ export interface SelectEventMap extends HTMLElementEventMap, SelectCustomEventMa
92
92
  * `--vaadin-field-default-width` | Default width of the field | :host | `12em`
93
93
  * `--vaadin-select-text-field-width` | Effective width of the field | `vaadin-select-overlay` |
94
94
  *
95
- * The following shadow DOM parts are available for styling:
95
+ * `<vaadin-select>` provides mostly the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
96
+ * See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
96
97
  *
97
- * Part name | Description
98
+ *
99
+ * In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
100
+ *
101
+ * Part name | Description
98
102
  * ----------------|----------------
99
103
  * `toggle-button` | The toggle button
100
104
  *
101
- * The following state attributes are available for styling:
105
+ * In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
102
106
  *
103
- * Attribute | Description | Part name
104
- * -------------|-------------|------------
105
- * `opened` | Set when the select is open | :host
106
- * `invalid` | Set when the element is invalid | :host
107
- * `focused` | Set when the element is focused | :host
108
- * `focus-ring` | Set when the element is keyboard focused | :host
109
- * `readonly` | Set when the select is read only | :host
107
+ * Attribute | Description | Part name
108
+ * ----------|-----------------------------|-----------
109
+ * `opened` | Set when the select is open | :host
110
110
  *
111
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
111
+ * There are two exceptions in terms of styling compared to `<vaadin-text-field>`:
112
+ * - the `clear-button` shadow DOM part does not exist in `<vaadin-select>`.
113
+ * - the `input-prevented` state attribute is not supported by `<vaadin-select>`.
112
114
  *
113
115
  * ### Internal components
114
116
  *
@@ -116,10 +118,14 @@ export interface SelectEventMap extends HTMLElementEventMap, SelectCustomEventMa
116
118
  * components are themable:
117
119
  *
118
120
  * - `<vaadin-select-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
121
+ * - `<vaadin-select-value-button>` - has the same API as [`<vaadin-button>`](#/elements/vaadin-button).
122
+ * - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the button.
119
123
  *
120
124
  * Note: the `theme` attribute value set on `<vaadin-select>` is
121
125
  * propagated to the internal components listed above.
122
126
  *
127
+ * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
128
+ *
123
129
  * @fires {Event} change - Fired when the user commits a value change.
124
130
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
125
131
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
@@ -3,8 +3,11 @@
3
3
  * Copyright (c) 2021 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
7
6
  import '@polymer/iron-media-query/iron-media-query.js';
7
+ import '@vaadin/input-container/src/vaadin-input-container.js';
8
+ import './vaadin-select-overlay.js';
9
+ import './vaadin-select-value-button.js';
10
+ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
8
11
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
9
12
  import { SlotMixin } from '@vaadin/component-base/src/slot-mixin.js';
10
13
  import { processTemplates } from '@vaadin/component-base/src/templates.js';
@@ -12,11 +15,7 @@ import { DelegateFocusMixin } from '@vaadin/field-base/src/delegate-focus-mixin.
12
15
  import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
13
16
  import { fieldShared } from '@vaadin/field-base/src/styles/field-shared-styles.js';
14
17
  import { inputFieldContainer } from '@vaadin/field-base/src/styles/input-field-container-styles.js';
15
- import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
16
- import { registerStyles } from '@vaadin/vaadin-themable-mixin/register-styles.js';
17
- import '@vaadin/input-container/src/vaadin-input-container.js';
18
- import './vaadin-select-overlay.js';
19
- import './vaadin-select-value-button.js';
18
+ import { registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
20
19
 
21
20
  registerStyles('vaadin-select', [fieldShared, inputFieldContainer], { moduleId: 'vaadin-select-styles' });
22
21
 
@@ -68,23 +67,25 @@ registerStyles('vaadin-select', [fieldShared, inputFieldContainer], { moduleId:
68
67
  * `--vaadin-field-default-width` | Default width of the field | :host | `12em`
69
68
  * `--vaadin-select-text-field-width` | Effective width of the field | `vaadin-select-overlay` |
70
69
  *
71
- * The following shadow DOM parts are available for styling:
70
+ * `<vaadin-select>` provides mostly the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
71
+ * See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
72
+ *
72
73
  *
73
- * Part name | Description
74
+ * In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
75
+ *
76
+ * Part name | Description
74
77
  * ----------------|----------------
75
78
  * `toggle-button` | The toggle button
76
79
  *
77
- * The following state attributes are available for styling:
80
+ * In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
78
81
  *
79
- * Attribute | Description | Part name
80
- * -------------|-------------|------------
81
- * `opened` | Set when the select is open | :host
82
- * `invalid` | Set when the element is invalid | :host
83
- * `focused` | Set when the element is focused | :host
84
- * `focus-ring` | Set when the element is keyboard focused | :host
85
- * `readonly` | Set when the select is read only | :host
82
+ * Attribute | Description | Part name
83
+ * ----------|-----------------------------|-----------
84
+ * `opened` | Set when the select is open | :host
86
85
  *
87
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
86
+ * There are two exceptions in terms of styling compared to `<vaadin-text-field>`:
87
+ * - the `clear-button` shadow DOM part does not exist in `<vaadin-select>`.
88
+ * - the `input-prevented` state attribute is not supported by `<vaadin-select>`.
88
89
  *
89
90
  * ### Internal components
90
91
  *
@@ -92,10 +93,14 @@ registerStyles('vaadin-select', [fieldShared, inputFieldContainer], { moduleId:
92
93
  * components are themable:
93
94
  *
94
95
  * - `<vaadin-select-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
96
+ * - `<vaadin-select-value-button>` - has the same API as [`<vaadin-button>`](#/elements/vaadin-button).
97
+ * - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the button.
95
98
  *
96
99
  * Note: the `theme` attribute value set on `<vaadin-select>` is
97
100
  * propagated to the internal components listed above.
98
101
  *
102
+ * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
103
+ *
99
104
  * @fires {Event} change - Fired when the user commits a value change.
100
105
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
101
106
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
@@ -123,7 +128,7 @@ class Select extends DelegateFocusMixin(FieldMixin(SlotMixin(ElementMixin(Themab
123
128
  </style>
124
129
 
125
130
  <div class="vaadin-select-container">
126
- <div part="label">
131
+ <div part="label" on-click="_onClick">
127
132
  <slot name="label"></slot>
128
133
  <span part="required-indicator" aria-hidden="true" on-click="focus"></span>
129
134
  </div>
@@ -338,8 +343,15 @@ class Select extends DelegateFocusMixin(FieldMixin(SlotMixin(ElementMixin(Themab
338
343
  * It is not guaranteed that the update happens immediately (synchronously) after it is requested.
339
344
  */
340
345
  requestContentUpdate() {
346
+ if (!this._overlayElement) {
347
+ return;
348
+ }
349
+
341
350
  this._overlayElement.requestContentUpdate();
342
351
 
352
+ // Ensure menu element is set
353
+ this._assignMenuElement();
354
+
343
355
  if (this._menuElement && this._menuElement.items) {
344
356
  this._updateSelectedItem(this.value, this._menuElement.items);
345
357
  }
@@ -362,18 +374,19 @@ class Select extends DelegateFocusMixin(FieldMixin(SlotMixin(ElementMixin(Themab
362
374
 
363
375
  /** @private */
364
376
  _assignMenuElement() {
365
- this._menuElement = Array.from(this._overlayElement.content.children).find(
366
- (element) => element.localName !== 'style'
367
- );
377
+ const menuElement = this.__getMenuElement();
368
378
 
369
- if (this._menuElement) {
370
- this._menuElement.addEventListener('items-changed', () => {
371
- this._items = this._menuElement.items;
379
+ if (menuElement && menuElement !== this.__lastMenuElement) {
380
+ this._menuElement = menuElement;
381
+ menuElement.addEventListener('items-changed', () => {
382
+ this._items = menuElement.items;
372
383
  this._items.forEach((item) => item.setAttribute('role', 'option'));
373
384
  });
374
- this._menuElement.addEventListener('selected-changed', () => this.__updateValueButton());
375
- this._menuElement.addEventListener('keydown', (e) => this._onKeyDownInside(e));
376
- this._menuElement.addEventListener(
385
+ menuElement.addEventListener('selected-changed', () => this.__updateValueButton());
386
+ // Use capture phase to make it possible for `<vaadin-grid-pro-edit-select>`
387
+ // to override and handle the keydown event before the value change happens.
388
+ menuElement.addEventListener('keydown', (e) => this._onKeyDownInside(e), true);
389
+ menuElement.addEventListener(
377
390
  'click',
378
391
  () => {
379
392
  this.__userInteraction = true;
@@ -382,10 +395,19 @@ class Select extends DelegateFocusMixin(FieldMixin(SlotMixin(ElementMixin(Themab
382
395
  true
383
396
  );
384
397
 
385
- this._menuElement.setAttribute('role', 'listbox');
398
+ menuElement.setAttribute('role', 'listbox');
399
+
400
+ // Store the menu element reference
401
+ this.__lastMenuElement = menuElement;
386
402
  }
387
403
  }
388
404
 
405
+ /** @private */
406
+ __getMenuElement() {
407
+ const content = this._overlayElement && this._overlayElement.content;
408
+ return content ? Array.from(content.children).find((el) => el.localName !== 'style') : null;
409
+ }
410
+
389
411
  /** @private */
390
412
  _valueChanged(value, oldValue) {
391
413
  this.toggleAttribute('has-value', Boolean(value));
@@ -397,12 +419,13 @@ class Select extends DelegateFocusMixin(FieldMixin(SlotMixin(ElementMixin(Themab
397
419
  this.validate();
398
420
  }
399
421
 
400
- /** @private */
401
- _onClick(e) {
402
- const isHelperClick = Array.from(e.composedPath()).some((node) => {
403
- return node.nodeType === Node.ELEMENT_NODE && node.getAttribute('slot') === 'helper';
404
- });
405
- this.opened = !this.readonly && !isHelperClick;
422
+ /**
423
+ * Opens the overlay if the field is not read-only.
424
+ *
425
+ * @private
426
+ */
427
+ _onClick() {
428
+ this.opened = !this.readonly;
406
429
  }
407
430
 
408
431
  /**
@@ -414,13 +437,16 @@ class Select extends DelegateFocusMixin(FieldMixin(SlotMixin(ElementMixin(Themab
414
437
  if (/^(Enter|SpaceBar|\s|ArrowDown|Down|ArrowUp|Up)$/.test(e.key)) {
415
438
  e.preventDefault();
416
439
  this.opened = true;
417
- } else if (/[a-zA-Z0-9]/.test(e.key) && e.key.length === 1) {
440
+ } else if (/[\p{L}\p{Nd}]/u.test(e.key) && e.key.length === 1) {
418
441
  const selected = this._menuElement.selected;
419
442
  const currentIdx = selected !== undefined ? selected : -1;
420
443
  const newIdx = this._menuElement._searchKey(currentIdx, e.key);
421
444
  if (newIdx >= 0) {
422
445
  this.__userInteraction = true;
423
- this._updateSelectedItem(this._items[newIdx].value, this._items);
446
+
447
+ // Announce the value selected with the first letter shortcut
448
+ this._updateAriaLive(true);
449
+ this._menuElement.selected = newIdx;
424
450
  }
425
451
  }
426
452
  }
@@ -439,6 +465,9 @@ class Select extends DelegateFocusMixin(FieldMixin(SlotMixin(ElementMixin(Themab
439
465
  /** @private */
440
466
  _openedChanged(opened, wasOpened) {
441
467
  if (opened) {
468
+ // Avoid multiple announcements when a value gets selected from the dropdown
469
+ this._updateAriaLive(false);
470
+
442
471
  if (!this._overlayElement || !this._menuElement || !this.focusElement || this.disabled || this.readonly) {
443
472
  this.opened = false;
444
473
  return;
@@ -460,13 +489,9 @@ class Select extends DelegateFocusMixin(FieldMixin(SlotMixin(ElementMixin(Themab
460
489
 
461
490
  this._menuElement.focus();
462
491
  } else if (wasOpened) {
463
- if (this._phone) {
464
- this._setFocused(false);
465
- } else {
466
- this.focus();
467
- if (this._openedWithFocusRing) {
468
- this.setAttribute('focus-ring', '');
469
- }
492
+ this.focus();
493
+ if (this._openedWithFocusRing) {
494
+ this.setAttribute('focus-ring', '');
470
495
  }
471
496
  this.validate();
472
497
  }
@@ -486,6 +511,17 @@ class Select extends DelegateFocusMixin(FieldMixin(SlotMixin(ElementMixin(Themab
486
511
  }
487
512
  }
488
513
 
514
+ /** @private */
515
+ _updateAriaLive(ariaLive) {
516
+ if (this._valueButton) {
517
+ if (ariaLive) {
518
+ this._valueButton.setAttribute('aria-live', 'polite');
519
+ } else {
520
+ this._valueButton.removeAttribute('aria-live');
521
+ }
522
+ }
523
+ }
524
+
489
525
  /** @private */
490
526
  __attachSelectedItem(selected) {
491
527
  let labelItem;
@@ -532,10 +568,13 @@ class Select extends DelegateFocusMixin(FieldMixin(SlotMixin(ElementMixin(Themab
532
568
 
533
569
  const selected = this._items[this._menuElement.selected];
534
570
 
571
+ this._valueButton.removeAttribute('placeholder');
572
+
535
573
  if (!selected) {
536
574
  if (this.placeholder) {
537
575
  const item = this.__createItem(this.placeholder);
538
576
  this.__appendItem(item);
577
+ this._valueButton.setAttribute('placeholder', '');
539
578
  }
540
579
  } else {
541
580
  this.__attachSelectedItem(selected);
@@ -3,33 +3,37 @@
3
3
  * Copyright (c) 2021 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
7
6
  import '@vaadin/vaadin-lumo-styles/sizing.js';
8
7
  import '@vaadin/vaadin-lumo-styles/style.js';
9
8
  import '@vaadin/vaadin-lumo-styles/font-icons.js';
10
- import { menuOverlay } from '@vaadin/vaadin-lumo-styles/mixins/menu-overlay.js';
11
9
  import { inputFieldShared } from '@vaadin/vaadin-lumo-styles/mixins/input-field-shared.js';
10
+ import { menuOverlay } from '@vaadin/vaadin-lumo-styles/mixins/menu-overlay.js';
11
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
12
12
 
13
13
  const select = css`
14
14
  :host(:not([theme*='align'])) ::slotted([slot='value']) {
15
15
  text-align: start;
16
16
  }
17
17
 
18
+ [part='input-field'] {
19
+ cursor: var(--lumo-clickable-cursor);
20
+ }
21
+
18
22
  [part='input-field'] ::slotted([slot='value']) {
19
23
  font-weight: 500;
20
24
  }
21
25
 
26
+ [part='input-field'] ::slotted([slot='value']:not([placeholder])) {
27
+ color: var(--lumo-body-text-color);
28
+ }
29
+
22
30
  /* placeholder styles */
23
- :host(:not([has-value])) [part='input-field'] ::slotted([slot='value']) {
31
+ [part='input-field'] ::slotted([slot='value'][placeholder]) {
24
32
  color: inherit;
25
33
  transition: opacity 0.175s 0.1s;
26
34
  opacity: 0.5;
27
35
  }
28
36
 
29
- :host([has-value]) [part='input-field'] ::slotted([slot='value']) {
30
- color: var(--lumo-body-text-color);
31
- }
32
-
33
37
  [part='toggle-button']::before {
34
38
  content: var(--lumo-icons-dropdown);
35
39
  }
@@ -62,6 +66,10 @@ registerStyles(
62
66
  :host([focus-ring]) {
63
67
  box-shadow: none;
64
68
  }
69
+
70
+ ::slotted(vaadin-item:hover) {
71
+ background-color: transparent;
72
+ }
65
73
  `,
66
74
  { moduleId: 'lumo-select-value-button' }
67
75
  );
@@ -3,10 +3,10 @@
3
3
  * Copyright (c) 2021 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
7
6
  import '@vaadin/vaadin-material-styles/font-icons.js';
8
- import { menuOverlay } from '@vaadin/vaadin-material-styles/mixins/menu-overlay.js';
9
7
  import { inputFieldShared } from '@vaadin/vaadin-material-styles/mixins/input-field-shared.js';
8
+ import { menuOverlay } from '@vaadin/vaadin-material-styles/mixins/menu-overlay.js';
9
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
10
10
 
11
11
  const select = css`
12
12
  :host {
@@ -15,13 +15,13 @@ const select = css`
15
15
  }
16
16
 
17
17
  /* placeholder styles */
18
- :host(:not([has-value])) [part='input-field'] ::slotted([slot='value']) {
18
+ :host [part='input-field'] ::slotted([slot='value'][placeholder]) {
19
19
  color: var(--material-disabled-text-color);
20
20
  transition: opacity 0.175s 0.1s;
21
21
  opacity: 1;
22
22
  }
23
23
 
24
- :host([has-value]) [part='input-field'] ::slotted([slot='value']) {
24
+ :host [part='input-field'] ::slotted([slot='value']) {
25
25
  color: var(--material-body-text-color);
26
26
  }
27
27
 
@@ -53,6 +53,15 @@ registerStyles(
53
53
  :host::after {
54
54
  display: none;
55
55
  }
56
+
57
+ ::slotted(vaadin-item) {
58
+ font: inherit;
59
+ padding: 4px 0;
60
+ }
61
+
62
+ ::slotted(vaadin-item:hover) {
63
+ background-color: transparent;
64
+ }
56
65
  `,
57
66
  { moduleId: 'material-select-value-button' }
58
67
  );