Comprehensive collection of business-ready web components for modern web applications
Selection components provide advanced user interface controls for choosing from predefined options. These components support filtering, multi-selection, and custom value handling.
Dropdown selection component for choosing from a list of predefined options.
/**
* Dropdown select component for single selection
* Displays options in an overlay when opened
*/
interface Select extends HTMLElement {
/** Currently selected value */
value: string;
/** Array of selectable items */
items: SelectItem[];
/** Placeholder text when no selection */
placeholder: string;
/** Dropdown is currently open */
opened: boolean;
/** Field label */
label: string;
/** Field is required */
required: boolean;
/** Field is disabled */
disabled: boolean;
/** Field is read-only */
readonly: boolean;
/** Field has validation errors */
invalid: boolean;
/** Error message when invalid */
errorMessage: string;
/** Open the dropdown */
open(): void;
/** Close the dropdown */
close(): void;
/** Validate the selection */
validate(): boolean;
/** Focus the select component */
focus(): void;
}
/**
* Item configuration for Select component
*/
interface SelectItem {
/** Display text for the item */
label: string;
/** Value when item is selected */
value: string;
/** Item is disabled and cannot be selected */
disabled?: boolean;
/** Custom component name for rendering */
component?: string;
}Usage Examples:
import '@vaadin/select';
const countrySelect = document.createElement('vaadin-select');
countrySelect.label = 'Country';
countrySelect.placeholder = 'Choose country...';
countrySelect.items = [
{ label: 'United States', value: 'US' },
{ label: 'Canada', value: 'CA' },
{ label: 'United Kingdom', value: 'UK' },
{ label: 'Germany', value: 'DE', disabled: true }
];
// Handle selection
countrySelect.addEventListener('value-changed', (e) => {
console.log('Selected country:', e.detail.value);
});Advanced selection component with filtering, custom values, and large dataset support.
/**
* Combo box with filtering and custom value support
* Supports large datasets with lazy loading
*/
interface ComboBox extends HTMLElement {
/** Currently selected value */
value: string;
/** Currently selected item object */
selectedItem: object | null;
/** Array of available items */
items: object[];
/** Property path for item labels */
itemLabelPath: string;
/** Property path for item values */
itemValuePath: string;
/** Currently filtered items */
filteredItems: object[];
/** Current filter text */
filter: string;
/** Loading indicator state */
loading: boolean;
/** Allow custom values not in items */
allowCustomValue: boolean;
/** Dropdown is currently open */
opened: boolean;
/** Component label */
label: string;
/** Placeholder text */
placeholder: string;
/** Component is required */
required: boolean;
/** Component is disabled */
disabled: boolean;
/** Component is read-only */
readonly: boolean;
/** Component has validation errors */
invalid: boolean;
/** Error message when invalid */
errorMessage: string;
/** Open the dropdown */
open(): void;
/** Close the dropdown */
close(): void;
/** Clear the current filter */
clearFilter(): void;
/** Validate the selection */
validate(): boolean;
/** Focus the component */
focus(): void;
/** Clear the selection */
clear(): void;
}Usage Examples:
import '@vaadin/combo-box';
// Simple string array
const colorCombo = document.createElement('vaadin-combo-box');
colorCombo.label = 'Color';
colorCombo.items = ['Red', 'Green', 'Blue', 'Yellow', 'Purple'];
colorCombo.allowCustomValue = true;
// Object array with custom properties
const userCombo = document.createElement('vaadin-combo-box');
userCombo.label = 'User';
userCombo.itemLabelPath = 'name';
userCombo.itemValuePath = 'id';
userCombo.items = [
{ id: '1', name: 'John Doe', email: 'john@example.com' },
{ id: '2', name: 'Jane Smith', email: 'jane@example.com' }
];
// Handle selection changes
userCombo.addEventListener('selected-item-changed', (e) => {
const user = e.detail.value;
console.log('Selected user:', user?.name, user?.email);
});
// Handle custom values
colorCombo.addEventListener('custom-value-set', (e) => {
const customColor = e.detail;
console.log('Custom color entered:', customColor);
// Add to items if desired
colorCombo.items = [...colorCombo.items, customColor];
});Combo box supporting multiple selections with token display.
/**
* Multi-selection combo box with token display
* Allows selection of multiple items from a list
*/
interface MultiSelectComboBox extends HTMLElement {
/** Array of selected items */
selectedItems: object[];
/** Array of available items */
items: object[];
/** Property path for item labels */
itemLabelPath: string;
/** Property path for item values */
itemValuePath: string;
/** Current filter text */
filter: string;
/** Component label */
label: string;
/** Placeholder text */
placeholder: string;
/** Component is required */
required: boolean;
/** Component is disabled */
disabled: boolean;
/** Component is read-only */
readonly: boolean;
/** Component has validation errors */
invalid: boolean;
/** Error message when invalid */
errorMessage: string;
/** Select an item */
selectItem(item: object): void;
/** Deselect an item */
deselectItem(item: object): void;
/** Clear all selections */
clearSelection(): void;
/** Validate the selection */
validate(): boolean;
/** Focus the component */
focus(): void;
}Container for selectable items with keyboard navigation support.
/**
* Selectable list container with keyboard navigation
* Manages selection state and focus handling
*/
interface ListBox extends HTMLElement {
/** Index of selected item (single selection) */
selected: number;
/** Array of selected indices (multiple selection) */
selectedValues: number[];
/** Enable multiple selection */
multiple: boolean;
/** Orientation of the list */
orientation: 'vertical' | 'horizontal';
/** Select item by index */
selectIndex(index: number): void;
/** Deselect item by index */
deselectIndex(index: number): void;
/** Focus the list box */
focus(): void;
}Individual selectable item for use within ListBox or other containers.
/**
* Individual selectable item component
* Used within ListBox and other selection containers
*/
interface Item extends HTMLElement {
/** Item is currently selected */
selected: boolean;
/** Item is disabled and cannot be selected */
disabled: boolean;
/** Item value */
value: string;
/** Focus this item */
focus(): void;
}Usage Examples:
import '@vaadin/list-box';
import '@vaadin/item';
const listBox = document.createElement('vaadin-list-box');
listBox.multiple = true;
// Add selectable items
const items = ['Dashboard', 'Users', 'Settings', 'Reports'];
items.forEach((text, index) => {
const item = document.createElement('vaadin-item');
item.textContent = text;
item.value = text.toLowerCase();
listBox.appendChild(item);
});
// Handle selection changes
listBox.addEventListener('selected-changed', (e) => {
console.log('Selected index:', e.detail.value);
});// Combo box with lazy loading for large datasets
const setupLazyComboBox = (comboBox: ComboBox) => {
let cachedItems: object[] = [];
comboBox.addEventListener('filter-changed', async (e) => {
const filter = e.detail.value;
if (!filter) return;
comboBox.loading = true;
try {
const response = await fetch(`/api/search?q=${encodeURIComponent(filter)}`);
const results = await response.json();
cachedItems = [...cachedItems, ...results];
comboBox.items = cachedItems;
comboBox.filteredItems = results;
} catch (error) {
console.error('Failed to load items:', error);
} finally {
comboBox.loading = false;
}
});
};// Custom rendering for complex items
const setupCustomRenderer = (comboBox: ComboBox) => {
comboBox.renderer = (root: HTMLElement, comboBox: ComboBox, model: any) => {
if (!root.firstElementChild) {
root.innerHTML = `
<div class="user-item">
<img class="avatar" />
<div class="details">
<div class="name"></div>
<div class="email"></div>
</div>
</div>
`;
}
const item = model.item;
const avatar = root.querySelector('.avatar') as HTMLImageElement;
const name = root.querySelector('.name') as HTMLElement;
const email = root.querySelector('.email') as HTMLElement;
avatar.src = item.avatar || '/default-avatar.png';
name.textContent = item.name;
email.textContent = item.email;
};
};// Hierarchical selection with categories
const createCategorySelect = () => {
const select = document.createElement('vaadin-select');
const categories = {
'Electronics': ['Laptop', 'Phone', 'Tablet'],
'Clothing': ['Shirts', 'Pants', 'Shoes'],
'Books': ['Fiction', 'Non-fiction', 'Science']
};
const items: SelectItem[] = [];
Object.entries(categories).forEach(([category, subcategories]) => {
// Add category header
items.push({
label: category,
value: category,
component: 'category-header'
});
// Add subcategory items
subcategories.forEach(sub => {
items.push({
label: ` ${sub}`,
value: `${category}/${sub}`
});
});
});
select.items = items;
return select;
};Radio group component for single selection from multiple exclusive options.
/**
* Radio group container for mutually exclusive selection
* Provides grouping and validation for radio buttons
*/
interface RadioGroup extends HTMLElement {
/** Currently selected value */
value: string;
/** Field label */
label: string;
/** Field is required */
required: boolean;
/** Field is disabled */
disabled: boolean;
/** Field is read-only */
readonly: boolean;
/** Field has validation errors */
invalid: boolean;
/** Error message when invalid */
errorMessage: string;
/** Helper text displayed below field */
helperText: string;
/** Validate the selection */
validate(): boolean;
/** Focus the radio group */
focus(): void;
}
/**
* Individual radio button within a radio group
* Only one radio button can be selected per group
*/
interface RadioButton extends HTMLElement {
/** Radio button value */
value: string;
/** Radio button label */
label: string;
/** Radio button is checked/selected */
checked: boolean;
/** Radio button is disabled */
disabled: boolean;
/** Radio button name (groups buttons) */
name: string;
/** Focus the radio button */
focus(): void;
/** Click/select the radio button */
click(): void;
}Usage Examples:
import '@vaadin/radio-group';
import '@vaadin/radio-group/vaadin-radio-button';
// Create radio group
const radioGroup = document.createElement('vaadin-radio-group');
radioGroup.label = 'Travel Class';
radioGroup.required = true;
// Add radio buttons
const options = [
{ value: 'economy', label: 'Economy' },
{ value: 'business', label: 'Business' },
{ value: 'first', label: 'First Class' }
];
options.forEach(option => {
const radio = document.createElement('vaadin-radio-button');
radio.value = option.value;
radio.label = option.label;
radioGroup.appendChild(radio);
});
// Listen for value changes
radioGroup.addEventListener('value-changed', (e) => {
console.log('Selected:', e.detail.value);
});
document.body.appendChild(radioGroup);Install with Tessl CLI
npx tessl i tessl/npm-vaadin--vaadin