@vaadin/select 23.2.0-dev.8a7678b70 → 23.3.0-alpha1

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
@@ -2,7 +2,7 @@
2
2
 
3
3
  A web component for selecting a single value from a list of options presented in an overlay.
4
4
 
5
- [Documentation + Live Demo ↗](https://vaadin.com/docs/latest/ds/components/select)
5
+ [Documentation + Live Demo ↗](https://vaadin.com/docs/latest/components/select)
6
6
 
7
7
  [![npm version](https://badgen.net/npm/v/@vaadin/vaadin-select)](https://www.npmjs.com/package/@vaadin/vaadin-select)
8
8
  [![Discord](https://img.shields.io/discord/732335336448852018?label=discord)](https://discord.gg/PHmkCKC)
@@ -30,7 +30,7 @@ A web component for selecting a single value from a list of options presented in
30
30
  </script>
31
31
  ```
32
32
 
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)
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/components/select)
34
34
 
35
35
  ## Installation
36
36
 
@@ -48,7 +48,7 @@ import '@vaadin/select';
48
48
 
49
49
  ## Themes
50
50
 
51
- Vaadin components come with two built-in [themes](https://vaadin.com/docs/latest/ds/customization/using-themes), Lumo and Material.
51
+ Vaadin components come with two built-in [themes](https://vaadin.com/docs/latest/styling), Lumo and Material.
52
52
  The [main entrypoint](https://github.com/vaadin/web-components/blob/master/packages/select/vaadin-select.js) of the package uses the Lumo theme.
53
53
 
54
54
  To use the Material theme, import the component from the `theme/material` folder:
@@ -71,7 +71,7 @@ import '@vaadin/select/src/vaadin-select.js';
71
71
 
72
72
  ## Contributing
73
73
 
74
- Read the [contributing guide](https://vaadin.com/docs/latest/guide/contributing/overview) to learn about our development process, how to propose bugfixes and improvements, and how to test your changes to Vaadin components.
74
+ Read the [contributing guide](https://vaadin.com/docs/latest/contributing/overview) to learn about our development process, how to propose bugfixes and improvements, and how to test your changes to Vaadin components.
75
75
 
76
76
  ## License
77
77
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/select",
3
- "version": "23.2.0-dev.8a7678b70",
3
+ "version": "23.3.0-alpha1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -14,7 +14,7 @@
14
14
  "author": "Vaadin Ltd",
15
15
  "homepage": "https://vaadin.com/components",
16
16
  "bugs": {
17
- "url": "https://github.com/vaadin/vaadin-select/issues"
17
+ "url": "https://github.com/vaadin/web-components/issues"
18
18
  },
19
19
  "main": "vaadin-select.js",
20
20
  "module": "vaadin-select.js",
@@ -25,7 +25,9 @@
25
25
  "src",
26
26
  "theme",
27
27
  "vaadin-*.d.ts",
28
- "vaadin-*.js"
28
+ "vaadin-*.js",
29
+ "web-types.json",
30
+ "web-types.lit.json"
29
31
  ],
30
32
  "keywords": [
31
33
  "Vaadin",
@@ -36,25 +38,29 @@
36
38
  ],
37
39
  "dependencies": {
38
40
  "@polymer/polymer": "^3.2.0",
39
- "@vaadin/button": "23.2.0-dev.8a7678b70",
40
- "@vaadin/component-base": "23.2.0-dev.8a7678b70",
41
- "@vaadin/field-base": "23.2.0-dev.8a7678b70",
42
- "@vaadin/input-container": "23.2.0-dev.8a7678b70",
43
- "@vaadin/item": "23.2.0-dev.8a7678b70",
44
- "@vaadin/list-box": "23.2.0-dev.8a7678b70",
45
- "@vaadin/lit-renderer": "23.2.0-dev.8a7678b70",
46
- "@vaadin/vaadin-list-mixin": "23.2.0-dev.8a7678b70",
47
- "@vaadin/vaadin-lumo-styles": "23.2.0-dev.8a7678b70",
48
- "@vaadin/vaadin-material-styles": "23.2.0-dev.8a7678b70",
49
- "@vaadin/vaadin-overlay": "23.2.0-dev.8a7678b70",
50
- "@vaadin/vaadin-themable-mixin": "23.2.0-dev.8a7678b70"
41
+ "@vaadin/button": "23.3.0-alpha1",
42
+ "@vaadin/component-base": "23.3.0-alpha1",
43
+ "@vaadin/field-base": "23.3.0-alpha1",
44
+ "@vaadin/input-container": "23.3.0-alpha1",
45
+ "@vaadin/item": "23.3.0-alpha1",
46
+ "@vaadin/list-box": "23.3.0-alpha1",
47
+ "@vaadin/lit-renderer": "23.3.0-alpha1",
48
+ "@vaadin/vaadin-list-mixin": "23.3.0-alpha1",
49
+ "@vaadin/vaadin-lumo-styles": "23.3.0-alpha1",
50
+ "@vaadin/vaadin-material-styles": "23.3.0-alpha1",
51
+ "@vaadin/vaadin-overlay": "23.3.0-alpha1",
52
+ "@vaadin/vaadin-themable-mixin": "23.3.0-alpha1"
51
53
  },
52
54
  "devDependencies": {
53
55
  "@esm-bundle/chai": "^4.3.4",
54
- "@vaadin/polymer-legacy-adapter": "23.2.0-dev.8a7678b70",
56
+ "@vaadin/polymer-legacy-adapter": "23.3.0-alpha1",
55
57
  "@vaadin/testing-helpers": "^0.3.2",
56
58
  "lit": "^2.0.0",
57
59
  "sinon": "^13.0.2"
58
60
  },
59
- "gitHead": "85b403f96d8282f262322b56c0ff4289f843d02a"
61
+ "web-types": [
62
+ "web-types.json",
63
+ "web-types.lit.json"
64
+ ],
65
+ "gitHead": "beabc527d4b1274eb798ff701d406fed45cfe638"
60
66
  }
@@ -3,10 +3,10 @@
3
3
  * Copyright (c) 2017 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { TemplateResult } from 'lit';
7
- import { DirectiveResult } from 'lit/directive.js';
6
+ import type { TemplateResult } from 'lit';
7
+ import type { DirectiveResult } from 'lit/directive.js';
8
8
  import { LitRendererDirective } from '@vaadin/lit-renderer';
9
- import { Select } from '../vaadin-select.js';
9
+ import type { Select } from '../vaadin-select.js';
10
10
 
11
11
  export type SelectLitRenderer = (select: Select) => TemplateResult;
12
12
 
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
7
7
  import { DelegateFocusMixin } from '@vaadin/field-base/src/delegate-focus-mixin.js';
8
+ import { DelegateStateMixin } from '@vaadin/field-base/src/delegate-state-mixin.js';
8
9
  import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
9
10
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
10
11
 
@@ -47,12 +48,19 @@ export type SelectInvalidChangedEvent = CustomEvent<{ value: boolean }>;
47
48
  */
48
49
  export type SelectValueChangedEvent = CustomEvent<{ value: string }>;
49
50
 
51
+ /**
52
+ * Fired whenever the field is validated.
53
+ */
54
+ export type SelectValidatedEvent = CustomEvent<{ valid: boolean }>;
55
+
50
56
  export interface SelectCustomEventMap {
51
57
  'opened-changed': SelectOpenedChangedEvent;
52
58
 
53
59
  'invalid-changed': SelectInvalidChangedEvent;
54
60
 
55
61
  'value-changed': SelectValueChangedEvent;
62
+
63
+ validated: SelectValidatedEvent;
56
64
  }
57
65
 
58
66
  export interface SelectEventMap extends HTMLElementEventMap, SelectCustomEventMap {
@@ -156,14 +164,17 @@ export interface SelectEventMap extends HTMLElementEventMap, SelectCustomEventMa
156
164
  * Note: the `theme` attribute value set on `<vaadin-select>` is
157
165
  * propagated to the internal components listed above.
158
166
  *
159
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
167
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
160
168
  *
161
169
  * @fires {Event} change - Fired when the user commits a value change.
162
170
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
163
171
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
164
172
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
173
+ * @fires {CustomEvent} validated - Fired whenever the field is validated.
165
174
  */
166
- declare class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(HTMLElement)))) {
175
+ declare class Select extends DelegateFocusMixin(
176
+ DelegateStateMixin(FieldMixin(ElementMixin(ThemableMixin(HTMLElement)))),
177
+ ) {
167
178
  /**
168
179
  * An array containing items that will be rendered as the options of the select.
169
180
  *
@@ -244,23 +255,16 @@ declare class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(Themable
244
255
  */
245
256
  requestContentUpdate(): void;
246
257
 
247
- /**
248
- * Returns true if `value` is valid, and sets the `invalid` flag appropriately.
249
- *
250
- * @returns True if the value is valid and sets the `invalid` flag appropriately
251
- */
252
- validate(): boolean;
253
-
254
258
  addEventListener<K extends keyof SelectEventMap>(
255
259
  type: K,
256
260
  listener: (this: Select, ev: SelectEventMap[K]) => void,
257
- options?: boolean | AddEventListenerOptions,
261
+ options?: AddEventListenerOptions | boolean,
258
262
  ): void;
259
263
 
260
264
  removeEventListener<K extends keyof SelectEventMap>(
261
265
  type: K,
262
266
  listener: (this: Select, ev: SelectEventMap[K]) => void,
263
- options?: boolean | EventListenerOptions,
267
+ options?: EventListenerOptions | boolean,
264
268
  ): void;
265
269
  }
266
270
 
@@ -13,8 +13,10 @@ import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
13
13
  import { MediaQueryController } from '@vaadin/component-base/src/media-query-controller.js';
14
14
  import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
15
15
  import { processTemplates } from '@vaadin/component-base/src/templates.js';
16
+ import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
16
17
  import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
17
18
  import { DelegateFocusMixin } from '@vaadin/field-base/src/delegate-focus-mixin.js';
19
+ import { DelegateStateMixin } from '@vaadin/field-base/src/delegate-state-mixin.js';
18
20
  import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
19
21
  import { fieldShared } from '@vaadin/field-base/src/styles/field-shared-styles.js';
20
22
  import { inputFieldContainer } from '@vaadin/field-base/src/styles/input-field-container-styles.js';
@@ -119,20 +121,22 @@ registerStyles('vaadin-select', [fieldShared, inputFieldContainer], { moduleId:
119
121
  * Note: the `theme` attribute value set on `<vaadin-select>` is
120
122
  * propagated to the internal components listed above.
121
123
  *
122
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
124
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
123
125
  *
124
126
  * @fires {Event} change - Fired when the user commits a value change.
125
127
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
126
128
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
127
129
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
130
+ * @fires {CustomEvent} validated - Fired whenever the field is validated.
128
131
  *
129
132
  * @extends HTMLElement
130
133
  * @mixes ElementMixin
131
134
  * @mixes ThemableMixin
132
135
  * @mixes FieldMixin
133
136
  * @mixes DelegateFocusMixin
137
+ * @mixes DelegateStateMixin
134
138
  */
135
- class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(PolymerElement)))) {
139
+ class Select extends DelegateFocusMixin(DelegateStateMixin(FieldMixin(ElementMixin(ThemableMixin(PolymerElement))))) {
136
140
  static get is() {
137
141
  return 'vaadin-select';
138
142
  }
@@ -161,7 +165,7 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
161
165
  >
162
166
  <slot name="prefix" slot="prefix"></slot>
163
167
  <slot name="value"></slot>
164
- <div part="toggle-button" slot="suffix" aria-hidden="true"></div>
168
+ <div part="toggle-button" slot="suffix" aria-hidden="true" on-mousedown="_onToggleMouseDown"></div>
165
169
  </vaadin-input-container>
166
170
 
167
171
  <div part="helper-text">
@@ -180,6 +184,8 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
180
184
  phone$="[[_phone]]"
181
185
  theme$="[[_theme]]"
182
186
  ></vaadin-select-overlay>
187
+
188
+ <slot name="tooltip"></slot>
183
189
  `;
184
190
  }
185
191
 
@@ -302,10 +308,13 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
302
308
  };
303
309
  }
304
310
 
311
+ static get delegateAttrs() {
312
+ return [...super.delegateAttrs, 'invalid'];
313
+ }
314
+
305
315
  static get observers() {
306
316
  return [
307
317
  '_updateAriaExpanded(opened)',
308
- '_updateAriaRequired(required)',
309
318
  '_updateSelectedItem(value, _items, placeholder)',
310
319
  '_rendererChanged(renderer, _overlayElement)',
311
320
  ];
@@ -346,11 +355,11 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
346
355
  (host, btn) => {
347
356
  this._setFocusElement(btn);
348
357
  this.ariaTarget = btn;
358
+ this.stateTarget = btn;
349
359
 
350
360
  btn.setAttribute('aria-haspopup', 'listbox');
351
361
  btn.setAttribute('aria-labelledby', `${this._labelId} ${this._fieldId}`);
352
362
 
353
- this._updateAriaRequired(host.required);
354
363
  this._updateAriaExpanded(host.opened);
355
364
 
356
365
  btn.addEventListener('keydown', this._boundOnKeyDown);
@@ -365,6 +374,9 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
365
374
  );
366
375
 
367
376
  processTemplates(this);
377
+
378
+ this._tooltipController = new TooltipController(this);
379
+ this.addController(this._tooltipController);
368
380
  }
369
381
 
370
382
  /**
@@ -385,6 +397,21 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
385
397
  }
386
398
  }
387
399
 
400
+ /**
401
+ * Override an observer from `FieldMixin`
402
+ * to validate when required is removed.
403
+ *
404
+ * @protected
405
+ * @override
406
+ */
407
+ _requiredChanged(required) {
408
+ super._requiredChanged(required);
409
+
410
+ if (required === false) {
411
+ this.validate();
412
+ }
413
+ }
414
+
388
415
  /**
389
416
  * @param {SelectRenderer | undefined | null} renderer
390
417
  * @param {SelectOverlay | undefined} overlay
@@ -458,11 +485,10 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
458
485
  _valueChanged(value, oldValue) {
459
486
  this.toggleAttribute('has-value', Boolean(value));
460
487
 
461
- // Skip validation for the initial empty string value
462
- if (value === '' && oldValue === undefined) {
463
- return;
488
+ // Validate only if `value` changes after initialization.
489
+ if (oldValue !== undefined) {
490
+ this.validate();
464
491
  }
465
- this.validate();
466
492
  }
467
493
 
468
494
  /**
@@ -478,6 +504,13 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
478
504
  this.opened = !this.readonly;
479
505
  }
480
506
 
507
+ /** @private */
508
+ _onToggleMouseDown(event) {
509
+ // Prevent mousedown event to avoid blur and preserve focused state
510
+ // while opening, and to restore focus-ring attribute on closing.
511
+ event.preventDefault();
512
+ }
513
+
481
514
  /**
482
515
  * @param {!KeyboardEvent} e
483
516
  * @protected
@@ -554,13 +587,6 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
554
587
  }
555
588
  }
556
589
 
557
- /** @private */
558
- _updateAriaRequired(required) {
559
- if (this._valueButton) {
560
- this._valueButton.setAttribute('aria-required', required ? 'true' : 'false');
561
- }
562
- }
563
-
564
590
  /** @private */
565
591
  _updateAriaLive(ariaLive) {
566
592
  if (this._valueButton) {
@@ -659,8 +685,9 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
659
685
  /** @private */
660
686
  _updateSelectedItem(value, items) {
661
687
  if (items) {
688
+ const valueAsString = value == null ? value : value.toString();
662
689
  this._menuElement.selected = items.reduce((prev, item, idx) => {
663
- return prev === undefined && item.value === value ? idx : prev;
690
+ return prev === undefined && item.value === valueAsString ? idx : prev;
664
691
  }, undefined);
665
692
  if (!this._selectedChanging) {
666
693
  this._valueChanging = true;
@@ -696,12 +723,12 @@ class Select extends DelegateFocusMixin(FieldMixin(ElementMixin(ThemableMixin(Po
696
723
  }
697
724
 
698
725
  /**
699
- * Returns true if `value` is valid, and sets the `invalid` flag appropriately.
726
+ * Returns true if the current value satisfies all constraints (if any)
700
727
  *
701
- * @return {boolean} True if the value is valid and sets the `invalid` flag appropriately
728
+ * @return {boolean}
702
729
  */
703
- validate() {
704
- return !(this.invalid = !(this.disabled || !this.required || this.value));
730
+ checkValidity() {
731
+ return !this.required || this.readonly || !!this.value;
705
732
  }
706
733
 
707
734
  /**
package/web-types.json ADDED
@@ -0,0 +1,326 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/web-types",
3
+ "name": "@vaadin/select",
4
+ "version": "23.3.0-alpha1",
5
+ "description-markup": "markdown",
6
+ "contributions": {
7
+ "html": {
8
+ "elements": [
9
+ {
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' },\n { label: 'Rating: high to low', value: 'rating-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 | Target element | Default\n-----------------------------------|------------------------------|----------------------------------\n`--vaadin-field-default-width` | Default width of the field | :host | `12em`\n`--vaadin-select-text-field-width` | Effective width of the field | `vaadin-select-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/23.3.0-alpha1/#/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\nIn addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:\n\nAttribute | Description | Part name\n----------|-----------------------------|-----------\n`opened` | Set when the select is open | :host\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-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha1/#/elements/vaadin-overlay).\n- `<vaadin-select-value-button>` - has the same API as [`<vaadin-button>`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha1/#/elements/vaadin-button).\n- [`<vaadin-input-container>`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha1/#/elements/vaadin-input-container) - an internal element wrapping the button.\n\nNote: the `theme` attribute value set on `<vaadin-select>` is\npropagated to the internal components listed above.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
12
+ "attributes": [
13
+ {
14
+ "name": "label",
15
+ "description": "The label text for the input node.\nWhen no light dom defined via [slot=label], this value will be used.",
16
+ "value": {
17
+ "type": [
18
+ "string",
19
+ "null",
20
+ "undefined"
21
+ ]
22
+ }
23
+ },
24
+ {
25
+ "name": "invalid",
26
+ "description": "Set to true when the field is invalid.",
27
+ "value": {
28
+ "type": [
29
+ "boolean",
30
+ "null",
31
+ "undefined"
32
+ ]
33
+ }
34
+ },
35
+ {
36
+ "name": "required",
37
+ "description": "Specifies that the user must fill in a value.",
38
+ "value": {
39
+ "type": [
40
+ "boolean",
41
+ "null",
42
+ "undefined"
43
+ ]
44
+ }
45
+ },
46
+ {
47
+ "name": "error-message",
48
+ "description": "Error to show when the field is invalid.",
49
+ "value": {
50
+ "type": [
51
+ "string",
52
+ "null",
53
+ "undefined"
54
+ ]
55
+ }
56
+ },
57
+ {
58
+ "name": "helper-text",
59
+ "description": "String used for the helper text.",
60
+ "value": {
61
+ "type": [
62
+ "string",
63
+ "null",
64
+ "undefined"
65
+ ]
66
+ }
67
+ },
68
+ {
69
+ "name": "disabled",
70
+ "description": "If true, the user cannot interact with this element.",
71
+ "value": {
72
+ "type": [
73
+ "boolean",
74
+ "null",
75
+ "undefined"
76
+ ]
77
+ }
78
+ },
79
+ {
80
+ "name": "autofocus",
81
+ "description": "Specify that this control should have input focus when the page loads.",
82
+ "value": {
83
+ "type": [
84
+ "boolean",
85
+ "null",
86
+ "undefined"
87
+ ]
88
+ }
89
+ },
90
+ {
91
+ "name": "opened",
92
+ "description": "Set when the select is open",
93
+ "value": {
94
+ "type": [
95
+ "boolean"
96
+ ]
97
+ }
98
+ },
99
+ {
100
+ "name": "value",
101
+ "description": "It stores the the `value` property of the selected item, providing the\nvalue for iron-form.\nWhen there’s an item selected, it's the value of that item, otherwise\nit's an empty string.\nOn change or initialization, the component finds the item which matches the\nvalue and displays it.\nIf no value is provided to the component, it selects the first item without\nvalue or empty value.\nHint: If you do not want to select any item by default, you can either set all\nthe values of inner vaadin-items, or set the vaadin-select value to\nan inexistent value in the items list.",
102
+ "value": {
103
+ "type": [
104
+ "string"
105
+ ]
106
+ }
107
+ },
108
+ {
109
+ "name": "name",
110
+ "description": "The name of this element.",
111
+ "value": {
112
+ "type": [
113
+ "string",
114
+ "null",
115
+ "undefined"
116
+ ]
117
+ }
118
+ },
119
+ {
120
+ "name": "placeholder",
121
+ "description": "A hint to the user of what can be entered in the control.\nThe placeholder will be displayed in the case that there\nis no item selected, or the selected item has an empty\nstring label, or the selected item has no label and it's\nDOM content is empty.",
122
+ "value": {
123
+ "type": [
124
+ "string",
125
+ "null",
126
+ "undefined"
127
+ ]
128
+ }
129
+ },
130
+ {
131
+ "name": "readonly",
132
+ "description": "When present, it specifies that the element is read-only.",
133
+ "value": {
134
+ "type": [
135
+ "boolean"
136
+ ]
137
+ }
138
+ },
139
+ {
140
+ "name": "theme",
141
+ "description": "The theme variants to apply to the component.",
142
+ "value": {
143
+ "type": [
144
+ "string",
145
+ "null",
146
+ "undefined"
147
+ ]
148
+ }
149
+ }
150
+ ],
151
+ "js": {
152
+ "properties": [
153
+ {
154
+ "name": "label",
155
+ "description": "The label text for the input node.\nWhen no light dom defined via [slot=label], this value will be used.",
156
+ "value": {
157
+ "type": [
158
+ "string",
159
+ "null",
160
+ "undefined"
161
+ ]
162
+ }
163
+ },
164
+ {
165
+ "name": "invalid",
166
+ "description": "Set to true when the field is invalid.",
167
+ "value": {
168
+ "type": [
169
+ "boolean",
170
+ "null",
171
+ "undefined"
172
+ ]
173
+ }
174
+ },
175
+ {
176
+ "name": "required",
177
+ "description": "Specifies that the user must fill in a value.",
178
+ "value": {
179
+ "type": [
180
+ "boolean",
181
+ "null",
182
+ "undefined"
183
+ ]
184
+ }
185
+ },
186
+ {
187
+ "name": "errorMessage",
188
+ "description": "Error to show when the field is invalid.",
189
+ "value": {
190
+ "type": [
191
+ "string",
192
+ "null",
193
+ "undefined"
194
+ ]
195
+ }
196
+ },
197
+ {
198
+ "name": "helperText",
199
+ "description": "String used for the helper text.",
200
+ "value": {
201
+ "type": [
202
+ "string",
203
+ "null",
204
+ "undefined"
205
+ ]
206
+ }
207
+ },
208
+ {
209
+ "name": "disabled",
210
+ "description": "If true, the user cannot interact with this element.",
211
+ "value": {
212
+ "type": [
213
+ "boolean",
214
+ "null",
215
+ "undefined"
216
+ ]
217
+ }
218
+ },
219
+ {
220
+ "name": "autofocus",
221
+ "description": "Specify that this control should have input focus when the page loads.",
222
+ "value": {
223
+ "type": [
224
+ "boolean",
225
+ "null",
226
+ "undefined"
227
+ ]
228
+ }
229
+ },
230
+ {
231
+ "name": "items",
232
+ "description": "An array containing items that will be rendered as the options of the select.\n\n#### Example\n```js\nselect.items = [\n { label: 'Most recent first', value: 'recent' },\n { component: 'hr' },\n { label: 'Rating: low to high', value: 'rating-asc' },\n { label: 'Rating: high to low', value: 'rating-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\nNote: each item is rendered by default as the internal `<vaadin-select-item>` that is an extension of `<vaadin-item>`.\nTo render the item with a custom component, provide a tag name by the `component` property.",
233
+ "value": {
234
+ "type": [
235
+ "Array.<SelectItem>"
236
+ ]
237
+ }
238
+ },
239
+ {
240
+ "name": "opened",
241
+ "description": "Set when the select is open",
242
+ "value": {
243
+ "type": [
244
+ "boolean"
245
+ ]
246
+ }
247
+ },
248
+ {
249
+ "name": "renderer",
250
+ "description": "Custom function for rendering the content of the `<vaadin-select>`.\nReceives two arguments:\n\n- `root` The `<vaadin-select-overlay>` internal container\n DOM element. Append your content to it.\n- `select` The reference to the `<vaadin-select>` element.",
251
+ "value": {
252
+ "type": [
253
+ "SelectRenderer",
254
+ "undefined"
255
+ ]
256
+ }
257
+ },
258
+ {
259
+ "name": "value",
260
+ "description": "It stores the the `value` property of the selected item, providing the\nvalue for iron-form.\nWhen there’s an item selected, it's the value of that item, otherwise\nit's an empty string.\nOn change or initialization, the component finds the item which matches the\nvalue and displays it.\nIf no value is provided to the component, it selects the first item without\nvalue or empty value.\nHint: If you do not want to select any item by default, you can either set all\nthe values of inner vaadin-items, or set the vaadin-select value to\nan inexistent value in the items list.",
261
+ "value": {
262
+ "type": [
263
+ "string"
264
+ ]
265
+ }
266
+ },
267
+ {
268
+ "name": "name",
269
+ "description": "The name of this element.",
270
+ "value": {
271
+ "type": [
272
+ "string",
273
+ "null",
274
+ "undefined"
275
+ ]
276
+ }
277
+ },
278
+ {
279
+ "name": "placeholder",
280
+ "description": "A hint to the user of what can be entered in the control.\nThe placeholder will be displayed in the case that there\nis no item selected, or the selected item has an empty\nstring label, or the selected item has no label and it's\nDOM content is empty.",
281
+ "value": {
282
+ "type": [
283
+ "string",
284
+ "null",
285
+ "undefined"
286
+ ]
287
+ }
288
+ },
289
+ {
290
+ "name": "readonly",
291
+ "description": "When present, it specifies that the element is read-only.",
292
+ "value": {
293
+ "type": [
294
+ "boolean"
295
+ ]
296
+ }
297
+ }
298
+ ],
299
+ "events": [
300
+ {
301
+ "name": "validated",
302
+ "description": "Fired whenever the field is validated."
303
+ },
304
+ {
305
+ "name": "change",
306
+ "description": "Fired when the user commits a value change."
307
+ },
308
+ {
309
+ "name": "opened-changed",
310
+ "description": "Fired when the `opened` property changes."
311
+ },
312
+ {
313
+ "name": "value-changed",
314
+ "description": "Fired when the `value` property changes."
315
+ },
316
+ {
317
+ "name": "invalid-changed",
318
+ "description": "Fired when the `invalid` property changes."
319
+ }
320
+ ]
321
+ }
322
+ }
323
+ ]
324
+ }
325
+ }
326
+ }
@@ -0,0 +1,160 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/web-types",
3
+ "name": "@vaadin/select",
4
+ "version": "23.3.0-alpha1",
5
+ "description-markup": "markdown",
6
+ "framework": "lit",
7
+ "framework-config": {
8
+ "enable-when": {
9
+ "node-packages": [
10
+ "lit"
11
+ ]
12
+ }
13
+ },
14
+ "contributions": {
15
+ "html": {
16
+ "elements": [
17
+ {
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' },\n { label: 'Rating: high to low', value: 'rating-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 | Target element | Default\n-----------------------------------|------------------------------|----------------------------------\n`--vaadin-field-default-width` | Default width of the field | :host | `12em`\n`--vaadin-select-text-field-width` | Effective width of the field | `vaadin-select-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/23.3.0-alpha1/#/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\nIn addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:\n\nAttribute | Description | Part name\n----------|-----------------------------|-----------\n`opened` | Set when the select is open | :host\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-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha1/#/elements/vaadin-overlay).\n- `<vaadin-select-value-button>` - has the same API as [`<vaadin-button>`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha1/#/elements/vaadin-button).\n- [`<vaadin-input-container>`](https://cdn.vaadin.com/vaadin-web-components/23.3.0-alpha1/#/elements/vaadin-input-container) - an internal element wrapping the button.\n\nNote: the `theme` attribute value set on `<vaadin-select>` is\npropagated to the internal components listed above.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
20
+ "extension": true,
21
+ "attributes": [
22
+ {
23
+ "name": "?invalid",
24
+ "description": "Set to true when the field is invalid.",
25
+ "value": {
26
+ "kind": "expression"
27
+ }
28
+ },
29
+ {
30
+ "name": "?required",
31
+ "description": "Specifies that the user must fill in a value.",
32
+ "value": {
33
+ "kind": "expression"
34
+ }
35
+ },
36
+ {
37
+ "name": "?disabled",
38
+ "description": "If true, the user cannot interact with this element.",
39
+ "value": {
40
+ "kind": "expression"
41
+ }
42
+ },
43
+ {
44
+ "name": "?autofocus",
45
+ "description": "Specify that this control should have input focus when the page loads.",
46
+ "value": {
47
+ "kind": "expression"
48
+ }
49
+ },
50
+ {
51
+ "name": "?opened",
52
+ "description": "Set when the select is open",
53
+ "value": {
54
+ "kind": "expression"
55
+ }
56
+ },
57
+ {
58
+ "name": "?readonly",
59
+ "description": "When present, it specifies that the element is read-only.",
60
+ "value": {
61
+ "kind": "expression"
62
+ }
63
+ },
64
+ {
65
+ "name": ".label",
66
+ "description": "The label text for the input node.\nWhen no light dom defined via [slot=label], this value will be used.",
67
+ "value": {
68
+ "kind": "expression"
69
+ }
70
+ },
71
+ {
72
+ "name": ".errorMessage",
73
+ "description": "Error to show when the field is invalid.",
74
+ "value": {
75
+ "kind": "expression"
76
+ }
77
+ },
78
+ {
79
+ "name": ".helperText",
80
+ "description": "String used for the helper text.",
81
+ "value": {
82
+ "kind": "expression"
83
+ }
84
+ },
85
+ {
86
+ "name": ".items",
87
+ "description": "An array containing items that will be rendered as the options of the select.\n\n#### Example\n```js\nselect.items = [\n { label: 'Most recent first', value: 'recent' },\n { component: 'hr' },\n { label: 'Rating: low to high', value: 'rating-asc' },\n { label: 'Rating: high to low', value: 'rating-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\nNote: each item is rendered by default as the internal `<vaadin-select-item>` that is an extension of `<vaadin-item>`.\nTo render the item with a custom component, provide a tag name by the `component` property.",
88
+ "value": {
89
+ "kind": "expression"
90
+ }
91
+ },
92
+ {
93
+ "name": ".renderer",
94
+ "description": "Custom function for rendering the content of the `<vaadin-select>`.\nReceives two arguments:\n\n- `root` The `<vaadin-select-overlay>` internal container\n DOM element. Append your content to it.\n- `select` The reference to the `<vaadin-select>` element.",
95
+ "value": {
96
+ "kind": "expression"
97
+ }
98
+ },
99
+ {
100
+ "name": ".value",
101
+ "description": "It stores the the `value` property of the selected item, providing the\nvalue for iron-form.\nWhen there’s an item selected, it's the value of that item, otherwise\nit's an empty string.\nOn change or initialization, the component finds the item which matches the\nvalue and displays it.\nIf no value is provided to the component, it selects the first item without\nvalue or empty value.\nHint: If you do not want to select any item by default, you can either set all\nthe values of inner vaadin-items, or set the vaadin-select value to\nan inexistent value in the items list.",
102
+ "value": {
103
+ "kind": "expression"
104
+ }
105
+ },
106
+ {
107
+ "name": ".name",
108
+ "description": "The name of this element.",
109
+ "value": {
110
+ "kind": "expression"
111
+ }
112
+ },
113
+ {
114
+ "name": ".placeholder",
115
+ "description": "A hint to the user of what can be entered in the control.\nThe placeholder will be displayed in the case that there\nis no item selected, or the selected item has an empty\nstring label, or the selected item has no label and it's\nDOM content is empty.",
116
+ "value": {
117
+ "kind": "expression"
118
+ }
119
+ },
120
+ {
121
+ "name": "@validated",
122
+ "description": "Fired whenever the field is validated.",
123
+ "value": {
124
+ "kind": "expression"
125
+ }
126
+ },
127
+ {
128
+ "name": "@change",
129
+ "description": "Fired when the user commits a value change.",
130
+ "value": {
131
+ "kind": "expression"
132
+ }
133
+ },
134
+ {
135
+ "name": "@opened-changed",
136
+ "description": "Fired when the `opened` property changes.",
137
+ "value": {
138
+ "kind": "expression"
139
+ }
140
+ },
141
+ {
142
+ "name": "@value-changed",
143
+ "description": "Fired when the `value` property changes.",
144
+ "value": {
145
+ "kind": "expression"
146
+ }
147
+ },
148
+ {
149
+ "name": "@invalid-changed",
150
+ "description": "Fired when the `invalid` property changes.",
151
+ "value": {
152
+ "kind": "expression"
153
+ }
154
+ }
155
+ ]
156
+ }
157
+ ]
158
+ }
159
+ }
160
+ }