0
# Selection Components
1
2
Selection components provide advanced user interface controls for choosing from predefined options. These components support filtering, multi-selection, and custom value handling.
3
4
## Capabilities
5
6
### Select
7
8
Dropdown selection component for choosing from a list of predefined options.
9
10
```typescript { .api }
11
/**
12
* Dropdown select component for single selection
13
* Displays options in an overlay when opened
14
*/
15
interface Select extends HTMLElement {
16
/** Currently selected value */
17
value: string;
18
/** Array of selectable items */
19
items: SelectItem[];
20
/** Placeholder text when no selection */
21
placeholder: string;
22
/** Dropdown is currently open */
23
opened: boolean;
24
/** Field label */
25
label: string;
26
/** Field is required */
27
required: boolean;
28
/** Field is disabled */
29
disabled: boolean;
30
/** Field is read-only */
31
readonly: boolean;
32
/** Field has validation errors */
33
invalid: boolean;
34
/** Error message when invalid */
35
errorMessage: string;
36
37
/** Open the dropdown */
38
open(): void;
39
/** Close the dropdown */
40
close(): void;
41
/** Validate the selection */
42
validate(): boolean;
43
/** Focus the select component */
44
focus(): void;
45
}
46
47
/**
48
* Item configuration for Select component
49
*/
50
interface SelectItem {
51
/** Display text for the item */
52
label: string;
53
/** Value when item is selected */
54
value: string;
55
/** Item is disabled and cannot be selected */
56
disabled?: boolean;
57
/** Custom component name for rendering */
58
component?: string;
59
}
60
```
61
62
**Usage Examples:**
63
64
```typescript
65
import '@vaadin/select';
66
67
const countrySelect = document.createElement('vaadin-select');
68
countrySelect.label = 'Country';
69
countrySelect.placeholder = 'Choose country...';
70
71
countrySelect.items = [
72
{ label: 'United States', value: 'US' },
73
{ label: 'Canada', value: 'CA' },
74
{ label: 'United Kingdom', value: 'UK' },
75
{ label: 'Germany', value: 'DE', disabled: true }
76
];
77
78
// Handle selection
79
countrySelect.addEventListener('value-changed', (e) => {
80
console.log('Selected country:', e.detail.value);
81
});
82
```
83
84
### Combo Box
85
86
Advanced selection component with filtering, custom values, and large dataset support.
87
88
```typescript { .api }
89
/**
90
* Combo box with filtering and custom value support
91
* Supports large datasets with lazy loading
92
*/
93
interface ComboBox extends HTMLElement {
94
/** Currently selected value */
95
value: string;
96
/** Currently selected item object */
97
selectedItem: object | null;
98
/** Array of available items */
99
items: object[];
100
/** Property path for item labels */
101
itemLabelPath: string;
102
/** Property path for item values */
103
itemValuePath: string;
104
/** Currently filtered items */
105
filteredItems: object[];
106
/** Current filter text */
107
filter: string;
108
/** Loading indicator state */
109
loading: boolean;
110
/** Allow custom values not in items */
111
allowCustomValue: boolean;
112
/** Dropdown is currently open */
113
opened: boolean;
114
/** Component label */
115
label: string;
116
/** Placeholder text */
117
placeholder: string;
118
/** Component is required */
119
required: boolean;
120
/** Component is disabled */
121
disabled: boolean;
122
/** Component is read-only */
123
readonly: boolean;
124
/** Component has validation errors */
125
invalid: boolean;
126
/** Error message when invalid */
127
errorMessage: string;
128
129
/** Open the dropdown */
130
open(): void;
131
/** Close the dropdown */
132
close(): void;
133
/** Clear the current filter */
134
clearFilter(): void;
135
/** Validate the selection */
136
validate(): boolean;
137
/** Focus the component */
138
focus(): void;
139
/** Clear the selection */
140
clear(): void;
141
}
142
```
143
144
**Usage Examples:**
145
146
```typescript
147
import '@vaadin/combo-box';
148
149
// Simple string array
150
const colorCombo = document.createElement('vaadin-combo-box');
151
colorCombo.label = 'Color';
152
colorCombo.items = ['Red', 'Green', 'Blue', 'Yellow', 'Purple'];
153
colorCombo.allowCustomValue = true;
154
155
// Object array with custom properties
156
const userCombo = document.createElement('vaadin-combo-box');
157
userCombo.label = 'User';
158
userCombo.itemLabelPath = 'name';
159
userCombo.itemValuePath = 'id';
160
userCombo.items = [
161
{ id: '1', name: 'John Doe', email: 'john@example.com' },
162
{ id: '2', name: 'Jane Smith', email: 'jane@example.com' }
163
];
164
165
// Handle selection changes
166
userCombo.addEventListener('selected-item-changed', (e) => {
167
const user = e.detail.value;
168
console.log('Selected user:', user?.name, user?.email);
169
});
170
171
// Handle custom values
172
colorCombo.addEventListener('custom-value-set', (e) => {
173
const customColor = e.detail;
174
console.log('Custom color entered:', customColor);
175
// Add to items if desired
176
colorCombo.items = [...colorCombo.items, customColor];
177
});
178
```
179
180
### Multi-Select Combo Box
181
182
Combo box supporting multiple selections with token display.
183
184
```typescript { .api }
185
/**
186
* Multi-selection combo box with token display
187
* Allows selection of multiple items from a list
188
*/
189
interface MultiSelectComboBox extends HTMLElement {
190
/** Array of selected items */
191
selectedItems: object[];
192
/** Array of available items */
193
items: object[];
194
/** Property path for item labels */
195
itemLabelPath: string;
196
/** Property path for item values */
197
itemValuePath: string;
198
/** Current filter text */
199
filter: string;
200
/** Component label */
201
label: string;
202
/** Placeholder text */
203
placeholder: string;
204
/** Component is required */
205
required: boolean;
206
/** Component is disabled */
207
disabled: boolean;
208
/** Component is read-only */
209
readonly: boolean;
210
/** Component has validation errors */
211
invalid: boolean;
212
/** Error message when invalid */
213
errorMessage: string;
214
215
/** Select an item */
216
selectItem(item: object): void;
217
/** Deselect an item */
218
deselectItem(item: object): void;
219
/** Clear all selections */
220
clearSelection(): void;
221
/** Validate the selection */
222
validate(): boolean;
223
/** Focus the component */
224
focus(): void;
225
}
226
```
227
228
### List Box
229
230
Container for selectable items with keyboard navigation support.
231
232
```typescript { .api }
233
/**
234
* Selectable list container with keyboard navigation
235
* Manages selection state and focus handling
236
*/
237
interface ListBox extends HTMLElement {
238
/** Index of selected item (single selection) */
239
selected: number;
240
/** Array of selected indices (multiple selection) */
241
selectedValues: number[];
242
/** Enable multiple selection */
243
multiple: boolean;
244
/** Orientation of the list */
245
orientation: 'vertical' | 'horizontal';
246
247
/** Select item by index */
248
selectIndex(index: number): void;
249
/** Deselect item by index */
250
deselectIndex(index: number): void;
251
/** Focus the list box */
252
focus(): void;
253
}
254
```
255
256
### Item
257
258
Individual selectable item for use within ListBox or other containers.
259
260
```typescript { .api }
261
/**
262
* Individual selectable item component
263
* Used within ListBox and other selection containers
264
*/
265
interface Item extends HTMLElement {
266
/** Item is currently selected */
267
selected: boolean;
268
/** Item is disabled and cannot be selected */
269
disabled: boolean;
270
/** Item value */
271
value: string;
272
273
/** Focus this item */
274
focus(): void;
275
}
276
```
277
278
**Usage Examples:**
279
280
```typescript
281
import '@vaadin/list-box';
282
import '@vaadin/item';
283
284
const listBox = document.createElement('vaadin-list-box');
285
listBox.multiple = true;
286
287
// Add selectable items
288
const items = ['Dashboard', 'Users', 'Settings', 'Reports'];
289
items.forEach((text, index) => {
290
const item = document.createElement('vaadin-item');
291
item.textContent = text;
292
item.value = text.toLowerCase();
293
listBox.appendChild(item);
294
});
295
296
// Handle selection changes
297
listBox.addEventListener('selected-changed', (e) => {
298
console.log('Selected index:', e.detail.value);
299
});
300
```
301
302
## Advanced Selection Patterns
303
304
### Lazy Loading Combo Box
305
306
```typescript
307
// Combo box with lazy loading for large datasets
308
const setupLazyComboBox = (comboBox: ComboBox) => {
309
let cachedItems: object[] = [];
310
311
comboBox.addEventListener('filter-changed', async (e) => {
312
const filter = e.detail.value;
313
if (!filter) return;
314
315
comboBox.loading = true;
316
317
try {
318
const response = await fetch(`/api/search?q=${encodeURIComponent(filter)}`);
319
const results = await response.json();
320
321
cachedItems = [...cachedItems, ...results];
322
comboBox.items = cachedItems;
323
comboBox.filteredItems = results;
324
} catch (error) {
325
console.error('Failed to load items:', error);
326
} finally {
327
comboBox.loading = false;
328
}
329
});
330
};
331
```
332
333
### Custom Item Renderer
334
335
```typescript
336
// Custom rendering for complex items
337
const setupCustomRenderer = (comboBox: ComboBox) => {
338
comboBox.renderer = (root: HTMLElement, comboBox: ComboBox, model: any) => {
339
if (!root.firstElementChild) {
340
root.innerHTML = `
341
<div class="user-item">
342
<img class="avatar" />
343
<div class="details">
344
<div class="name"></div>
345
<div class="email"></div>
346
</div>
347
</div>
348
`;
349
}
350
351
const item = model.item;
352
const avatar = root.querySelector('.avatar') as HTMLImageElement;
353
const name = root.querySelector('.name') as HTMLElement;
354
const email = root.querySelector('.email') as HTMLElement;
355
356
avatar.src = item.avatar || '/default-avatar.png';
357
name.textContent = item.name;
358
email.textContent = item.email;
359
};
360
};
361
```
362
363
### Multi-Level Selection
364
365
```typescript
366
// Hierarchical selection with categories
367
const createCategorySelect = () => {
368
const select = document.createElement('vaadin-select');
369
370
const categories = {
371
'Electronics': ['Laptop', 'Phone', 'Tablet'],
372
'Clothing': ['Shirts', 'Pants', 'Shoes'],
373
'Books': ['Fiction', 'Non-fiction', 'Science']
374
};
375
376
const items: SelectItem[] = [];
377
378
Object.entries(categories).forEach(([category, subcategories]) => {
379
// Add category header
380
items.push({
381
label: category,
382
value: category,
383
component: 'category-header'
384
});
385
386
// Add subcategory items
387
subcategories.forEach(sub => {
388
items.push({
389
label: ` ${sub}`,
390
value: `${category}/${sub}`
391
});
392
});
393
});
394
395
select.items = items;
396
return select;
397
};
398
```
399
400
### Radio Group
401
402
Radio group component for single selection from multiple exclusive options.
403
404
```typescript { .api }
405
/**
406
* Radio group container for mutually exclusive selection
407
* Provides grouping and validation for radio buttons
408
*/
409
interface RadioGroup extends HTMLElement {
410
/** Currently selected value */
411
value: string;
412
/** Field label */
413
label: string;
414
/** Field is required */
415
required: boolean;
416
/** Field is disabled */
417
disabled: boolean;
418
/** Field is read-only */
419
readonly: boolean;
420
/** Field has validation errors */
421
invalid: boolean;
422
/** Error message when invalid */
423
errorMessage: string;
424
/** Helper text displayed below field */
425
helperText: string;
426
427
/** Validate the selection */
428
validate(): boolean;
429
/** Focus the radio group */
430
focus(): void;
431
}
432
433
/**
434
* Individual radio button within a radio group
435
* Only one radio button can be selected per group
436
*/
437
interface RadioButton extends HTMLElement {
438
/** Radio button value */
439
value: string;
440
/** Radio button label */
441
label: string;
442
/** Radio button is checked/selected */
443
checked: boolean;
444
/** Radio button is disabled */
445
disabled: boolean;
446
/** Radio button name (groups buttons) */
447
name: string;
448
449
/** Focus the radio button */
450
focus(): void;
451
/** Click/select the radio button */
452
click(): void;
453
}
454
```
455
456
**Usage Examples:**
457
458
```typescript
459
import '@vaadin/radio-group';
460
import '@vaadin/radio-group/vaadin-radio-button';
461
462
// Create radio group
463
const radioGroup = document.createElement('vaadin-radio-group');
464
radioGroup.label = 'Travel Class';
465
radioGroup.required = true;
466
467
// Add radio buttons
468
const options = [
469
{ value: 'economy', label: 'Economy' },
470
{ value: 'business', label: 'Business' },
471
{ value: 'first', label: 'First Class' }
472
];
473
474
options.forEach(option => {
475
const radio = document.createElement('vaadin-radio-button');
476
radio.value = option.value;
477
radio.label = option.label;
478
radioGroup.appendChild(radio);
479
});
480
481
// Listen for value changes
482
radioGroup.addEventListener('value-changed', (e) => {
483
console.log('Selected:', e.detail.value);
484
});
485
486
document.body.appendChild(radioGroup);
487
```