On this page
Listbox
A scrollable listbox driven by a SelectOption[] property. Supports single and multi-select, client-side filter, option groups, and full keyboard navigation.
uwc-listbox is a scrollable selection list driven by a
SelectOption[] property. It supports single and multi-select with checkboxes, search
filtering, option groups, and full keyboard navigation.
Import
All components
import '@uwc/components';
Selected component (Lit / Angular / Vue)
import { UwcListbox } from '@uwc/components/listbox';
customElements.define('uwc-listbox', UwcListbox);
React
import { UwcListbox } from '@uwc/components/react';
Usage
Lit
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('app-demo')
export class AppDemo extends LitElement {
options = [
{ label: 'New York', value: 'NY' },
{ label: 'London', value: 'LN' },
];
render() {
return html`<uwc-listbox .options=${this.options}></uwc-listbox>`;
}
}
React
import React from 'react';
import { UwcListbox } from '@uwc/components/react';
const options = [
{ label: 'New York', value: 'NY' },
{ label: 'London', value: 'LN' },
];
export default function App() {
return <UwcListbox options={options} />;
}
Angular
import { Component } from '@angular/core';
import '@uwc/listbox';
@Component({
selector: 'app-root',
standalone: true,
template: `<uwc-listbox [options]="options"></uwc-listbox>`,
})
export class AppComponent {
options = [
{ label: 'New York', value: 'NY' },
{ label: 'London', value: 'LN' },
];
}
Vue
import '@uwc/listbox';
export default {
data() {
return {
options: [
{ label: 'New York', value: 'NY' },
{ label: 'London', value: 'LN' },
],
};
},
template: `<uwc-listbox :options="options"></uwc-listbox>`,
};
Basic Usage
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('app-demo')
export class AppDemo extends LitElement {
options = [
{ label: 'New York', value: 'NY' },
{ label: 'Rome', value: 'RM' },
{ label: 'London', value: 'LN' },
{ label: 'Istanbul', value: 'IS' },
{ label: 'Paris', value: 'PA' },
];
render() {
return html`<uwc-listbox .options=${this.options} style="width:16rem"></uwc-listbox>`;
}
}
import React from 'react';
import { UwcListbox } from '@uwc/components/react';
export default function App() {
const options = [
{ label: 'New York', value: 'NY' },
{ label: 'Rome', value: 'RM' },
{ label: 'London', value: 'LN' },
{ label: 'Istanbul', value: 'IS' },
{ label: 'Paris', value: 'PA' },
];
return <UwcListbox options={options} style={{ width: '16rem' }} />;
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `<uwc-listbox [options]="options" style="width:16rem"></uwc-listbox>`
})
export class AppComponent {
options = [
{ label: 'New York', value: 'NY' },
{ label: 'Rome', value: 'RM' },
{ label: 'London', value: 'LN' },
{ label: 'Istanbul', value: 'IS' },
{ label: 'Paris', value: 'PA' },
];
}
export default {
data() {
return {
options: [
{ label: 'New York', value: 'NY' },
{ label: 'Rome', value: 'RM' },
{ label: 'London', value: 'LN' },
{ label: 'Istanbul', value: 'IS' },
{ label: 'Paris', value: 'PA' },
],
};
},
template: `<uwc-listbox :options="options" style="width:16rem"></uwc-listbox>`
};
Basic
Pass a SelectOption[] array to the options property. Listen to
uwc-change to receive the selected value.
import { LitElement, html, css } from 'lit';
import { customElement, state } from 'lit/decorators.js';
@customElement('listbox-basic-demo')
export class AppDemo extends LitElement {
static styles = css`
:host { display: block; }
p { margin: .75rem 0 0; font-size: .875rem; color: #374151; }
strong { color: #6366f1; }
`;
@state() value = null;
options = [
{ label: 'New York', value: 'NY' },
{ label: 'Rome', value: 'RM' },
{ label: 'London', value: 'LN' },
{ label: 'Istanbul', value: 'IS' },
{ label: 'Paris', value: 'PA' },
];
render() {
return html`
<uwc-listbox
.options=${this.options}
.value=${this.value}
style="width:16rem"
@uwc-change=${(e) => { this.value = e.detail.value; }}>
</uwc-listbox>
<p>Selected: <strong>${this.value ?? 'none'}</strong></p>
`;
}
}
import React, { useState } from 'react';
import { UwcListbox } from '@uwc/components/react';
export default function App() {
const [value, setValue] = useState(null);
const options = [
{ label: 'New York', value: 'NY' },
{ label: 'Rome', value: 'RM' },
{ label: 'London', value: 'LN' },
{ label: 'Istanbul', value: 'IS' },
{ label: 'Paris', value: 'PA' },
];
return (
<>
<UwcListbox
options={options}
value={value}
style={{ width: '16rem' }}
onUwcChange={(e) => setValue(e.detail.value)}
/>
<p style={{ marginTop: '.75rem', fontSize: '.875rem', color: '#374151' }}>
Selected: <strong style={{ color: '#6366f1' }}>{value ?? 'none'}</strong>
</p>
</>
);
}
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<uwc-listbox
[options]="options"
[value]="value()"
style="width:16rem"
(uwc-change)="value.set($event.detail.value)">
</uwc-listbox>
<p style="margin:.75rem 0 0;font-size:.875rem;color:#374151">
Selected: <strong style="color:#6366f1">{{ value() ?? 'none' }}</strong>
</p>
`
})
export class AppComponent {
readonly value = signal<string | null>(null);
options = [
{ label: 'New York', value: 'NY' },
{ label: 'Rome', value: 'RM' },
{ label: 'London', value: 'LN' },
{ label: 'Istanbul', value: 'IS' },
{ label: 'Paris', value: 'PA' },
];
}
export default {
data() {
return {
value: null,
options: [
{ label: 'New York', value: 'NY' },
{ label: 'Rome', value: 'RM' },
{ label: 'London', value: 'LN' },
{ label: 'Istanbul', value: 'IS' },
{ label: 'Paris', value: 'PA' },
],
};
},
template: `
<uwc-listbox
:options="options"
:value="value"
style="width:16rem"
@uwc-change="value = $event.detail.value">
</uwc-listbox>
<p style="margin:.75rem 0 0;font-size:.875rem;color:#374151">
Selected: <strong style="color:#6366f1">{{ value ?? 'none' }}</strong>
</p>
`
};
Multiple selection
Add multiple to enable checkbox-based multi-selection.
import { LitElement, html, css } from 'lit';
import { customElement, state } from 'lit/decorators.js';
@customElement('listbox-multi-demo')
export class AppDemo extends LitElement {
static styles = css`
:host { display: block; }
p { margin: .75rem 0 0; font-size: .875rem; color: #374151; }
`;
@state() value = [];
options = [
{ label: 'HTML', value: 'html' },
{ label: 'CSS', value: 'css' },
{ label: 'JavaScript', value: 'js' },
{ label: 'TypeScript', value: 'ts' },
{ label: 'React', value: 'react'},
{ label: 'Vue', value: 'vue' },
];
render() {
return html`
<uwc-listbox
.options=${this.options}
.value=${this.value}
multiple
style="width:16rem"
@uwc-change=${(e) => { this.value = e.detail.value; }}>
</uwc-listbox>
<p>Selected: <strong>${this.value.length ? this.value.join(', ') : 'none'}</strong></p>
`;
}
}
import React, { useState } from 'react';
import { UwcListbox } from '@uwc/components/react';
export default function App() {
const [value, setValue] = useState([]);
const options = [
{ label: 'HTML', value: 'html' },
{ label: 'CSS', value: 'css' },
{ label: 'JavaScript', value: 'js' },
{ label: 'TypeScript', value: 'ts' },
{ label: 'React', value: 'react'},
{ label: 'Vue', value: 'vue' },
];
return (
<>
<UwcListbox
options={options}
value={value}
multiple
style={{ width: '16rem' }}
onUwcChange={(e) => setValue(e.detail.value)}
/>
<p style={{ marginTop: '.75rem', fontSize: '.875rem', color: '#374151' }}>
Selected: <strong>{value.length ? value.join(', ') : 'none'}</strong>
</p>
</>
);
}
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<uwc-listbox
[options]="options"
[value]="value()"
multiple
style="width:16rem"
(uwc-change)="value.set($event.detail.value)">
</uwc-listbox>
<p style="margin:.75rem 0 0;font-size:.875rem;color:#374151">
Selected: <strong>{{ value().length ? value().join(', ') : 'none' }}</strong>
</p>
`
})
export class AppComponent {
readonly value = signal<string[]>([]);
options = [
{ label: 'HTML', value: 'html' },
{ label: 'CSS', value: 'css' },
{ label: 'JavaScript', value: 'js' },
{ label: 'TypeScript', value: 'ts' },
{ label: 'React', value: 'react'},
{ label: 'Vue', value: 'vue' },
];
}
export default {
data() {
return {
value: [],
options: [
{ label: 'HTML', value: 'html' },
{ label: 'CSS', value: 'css' },
{ label: 'JavaScript', value: 'js' },
{ label: 'TypeScript', value: 'ts' },
{ label: 'React', value: 'react'},
{ label: 'Vue', value: 'vue' },
],
};
},
template: `
<uwc-listbox
:options="options"
:value="value"
multiple
style="width:16rem"
@uwc-change="value = $event.detail.value">
</uwc-listbox>
<p style="margin:.75rem 0 0;font-size:.875rem;color:#374151">
Selected: <strong>{{ value.length ? value.join(', ') : 'none' }}</strong>
</p>
`
};
With filter
Add filter to show a search input at the top of the list.
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('listbox-filter-demo')
export class AppDemo extends LitElement {
options = [
{ label: 'United States', value: 'us' },
{ label: 'United Kingdom', value: 'uk' },
{ label: 'Canada', value: 'ca' },
{ label: 'Germany', value: 'de' },
{ label: 'France', value: 'fr' },
{ label: 'Japan', value: 'jp' },
{ label: 'Australia', value: 'au' },
];
render() {
return html`
<uwc-listbox
.options=${this.options}
filter
filter-placeholder="Search countries..."
style="width:16rem">
</uwc-listbox>
`;
}
}
import React from 'react';
import { UwcListbox } from '@uwc/components/react';
export default function App() {
const options = [
{ label: 'United States', value: 'us' },
{ label: 'United Kingdom', value: 'uk' },
{ label: 'Canada', value: 'ca' },
{ label: 'Germany', value: 'de' },
{ label: 'France', value: 'fr' },
{ label: 'Japan', value: 'jp' },
{ label: 'Australia', value: 'au' },
];
return (
<UwcListbox
options={options}
filter
filterPlaceholder="Search countries..."
style={{ width: '16rem' }}
/>
);
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<uwc-listbox
[options]="options"
filter
filter-placeholder="Search countries..."
style="width:16rem">
</uwc-listbox>
`
})
export class AppComponent {
options = [
{ label: 'United States', value: 'us' },
{ label: 'United Kingdom', value: 'uk' },
{ label: 'Canada', value: 'ca' },
{ label: 'Germany', value: 'de' },
{ label: 'France', value: 'fr' },
{ label: 'Japan', value: 'jp' },
{ label: 'Australia', value: 'au' },
];
}
export default {
data() {
return {
options: [
{ label: 'United States', value: 'us' },
{ label: 'United Kingdom', value: 'uk' },
{ label: 'Canada', value: 'ca' },
{ label: 'Germany', value: 'de' },
{ label: 'France', value: 'fr' },
{ label: 'Japan', value: 'jp' },
{ label: 'Australia', value: 'au' },
],
};
},
template: `
<uwc-listbox
:options="options"
filter
filter-placeholder="Search countries..."
style="width:16rem">
</uwc-listbox>
`
};
Option groups
Set the group field to render non-selectable section headers.
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('listbox-groups-demo')
export class AppDemo extends LitElement {
options = [
{ group: 'Fruits', label: 'Fruits', value: null },
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Cherry', value: 'cherry' },
{ group: 'Vegetables', label: 'Vegetables', value: null },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli'},
];
render() {
return html`
<uwc-listbox .options=${this.options} style="width:16rem"></uwc-listbox>
`;
}
}
import React from 'react';
import { UwcListbox } from '@uwc/components/react';
export default function App() {
const options = [
{ group: 'Fruits', label: 'Fruits', value: null },
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Cherry', value: 'cherry' },
{ group: 'Vegetables', label: 'Vegetables', value: null },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli'},
];
return <UwcListbox options={options} style={{ width: '16rem' }} />;
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<uwc-listbox [options]="options" style="width:16rem"></uwc-listbox>
`
})
export class AppComponent {
options = [
{ group: 'Fruits', label: 'Fruits', value: null },
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Cherry', value: 'cherry' },
{ group: 'Vegetables', label: 'Vegetables', value: null },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli'},
];
}
export default {
data() {
return {
options: [
{ group: 'Fruits', label: 'Fruits', value: null },
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Cherry', value: 'cherry' },
{ group: 'Vegetables', label: 'Vegetables', value: null },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Broccoli', value: 'broccoli'},
],
};
},
template: `
<uwc-listbox :options="options" style="width:16rem"></uwc-listbox>
`
};
Disabled items
Set disabled: true on individual options or set disabled on the component to
block all interaction.
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('listbox-disabled-demo')
export class AppDemo extends LitElement {
options = [
{ label: 'Available', value: 'a' },
{ label: 'Unavailable', value: 'b', disabled: true },
{ label: 'Available', value: 'c' },
{ label: 'Unavailable', value: 'd', disabled: true },
{ label: 'Available', value: 'e' },
];
render() {
return html`
<uwc-listbox .options=${this.options} style="width:16rem"></uwc-listbox>
`;
}
}
import React from 'react';
import { UwcListbox } from '@uwc/components/react';
export default function App() {
const options = [
{ label: 'Available', value: 'a' },
{ label: 'Unavailable', value: 'b', disabled: true },
{ label: 'Available', value: 'c' },
{ label: 'Unavailable', value: 'd', disabled: true },
{ label: 'Available', value: 'e' },
];
return <UwcListbox options={options} style={{ width: '16rem' }} />;
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<uwc-listbox [options]="options" style="width:16rem"></uwc-listbox>
`
})
export class AppComponent {
options = [
{ label: 'Available', value: 'a' },
{ label: 'Unavailable', value: 'b', disabled: true },
{ label: 'Available', value: 'c' },
{ label: 'Unavailable', value: 'd', disabled: true },
{ label: 'Available', value: 'e' },
];
}
export default {
data() {
return {
options: [
{ label: 'Available', value: 'a' },
{ label: 'Unavailable', value: 'b', disabled: true },
{ label: 'Available', value: 'c' },
{ label: 'Unavailable', value: 'd', disabled: true },
{ label: 'Available', value: 'e' },
],
};
},
template: `
<uwc-listbox :options="options" style="width:16rem"></uwc-listbox>
`
};
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
options |
— |
— |
JSON array of SelectOption objects. |
value |
— |
— |
Currently selected value (single) or JSON array (multiple). |
multiple |
— |
— |
Allow multiple selection (shows checkboxes). |
filter |
— |
— |
Show a search filter input. |
filter-placeholder |
— |
— |
Placeholder for filter input. |
filter-by |
— |
— |
Field to filter on. Default: label. |
list-style-height |
— |
— |
Max height of list. Default: 14rem. |
disabled |
— |
— |
Disable the listbox. |
invalid |
— |
— |
Mark as invalid. |
fluid |
— |
— |
Stretch to fill container. |
empty-message |
— |
— |
Text shown when no options match filter. Default: No results found. |
Properties
| Name | Type | Default | Description |
|---|---|---|---|
styles |
CSSResultGroup |
[styles] |
— |
options |
SelectOption[] |
[] |
Accepts a JSON string or will be set programmatically. |
value |
unknown |
null |
Single value or array of values (multiple). |
multiple |
boolean |
false |
— |
filter |
boolean |
false |
— |
filterPlaceholder |
string |
'Search...' |
— |
filterBy |
string |
'label' |
— |
listStyleHeight |
string |
'' |
— |
emptyMessage |
string |
'No results found' |
— |
disabled |
boolean |
false |
— |
invalid |
boolean |
false |
— |
fluid |
boolean |
false |
— |
Events
| Name | Type | Description |
|---|---|---|
uwc-change |
CustomEvent |
Fired on selection change. Detail: { value }. |
uwc-filter |
CustomEvent |
Fired on filter change. Detail: { query }. |
CSS Custom Properties
| Name | Default | Description |
|---|---|---|
--uwc-listbox-radius |
— |
Border radius. |
--uwc-listbox-border |
— |
Border shorthand. |
--uwc-listbox-bg |
— |
Background color. |
--uwc-listbox-item-height |
— |
Min item height. |
--uwc-listbox-font-size |
— |
Font size. |
--uwc-listbox-max-height |
— |
List scroll max height. Default: 14rem. |
CSS Parts
| Name | Description |
|---|---|
container |
The outer wrapper. |
list |
The <ul> list element. |
item |
Each option <li>. |