Define options as <k-option> children. As the user types, options are filtered to match the input.
<k-combobox placeholder='Select a fruit...'>
<k-option value='apple'>Apple</k-option>
<k-option value='banana'>Banana</k-option>
<k-option value='cherry'>Cherry</k-option>
<k-option value='date'>Date</k-option>
<k-option value='elderberry'>Elderberry</k-option>
<k-option value='fig'>Fig</k-option>
<k-option value='grape'>Grape</k-option>
<k-option value='honeydew'>Honeydew</k-option>
<k-option value='kiwi'>Kiwi</k-option>
<k-option value='lemon'>Lemon</k-option>
</k-combobox>
Listen for the search event to fetch options from an external source when the user pauses typing. Use setOptions() to replace the <k-option> children programmatically. Set the searching attribute to show a loading spinner while results load.
<k-combobox id='dynamicCombobox' placeholder='Search users...' debounce-ms='400'></k-combobox>
const cb = document.querySelector('#dynamicCombobox');
cb.addEventListener('search', (e) => {
cb.searching = true;
fetch('/api/users?q=' + encodeURIComponent(e.detail.value)).then(r => r.json()).then(users => {
cb.setOptions(users.map(u => ({
label: u.email,
value: u.id
})));
cb.searching = false;
});
});
cb.addEventListener('select', (e) => {
console.log('Selected:', e.detail.label, e.detail.value);
});
The combobox is form-associated. Use the required attribute to prevent submitting when the field is empty.
<form id='requiredForm'>
<k-combobox name='fruit' required placeholder='Required field...'>
<k-option value='apple'>Apple</k-option>
<k-option value='banana'>Banana</k-option>
<k-option value='cherry'>Cherry</k-option>
</k-combobox>
<button type='submit' class='btn primary mt'>Submit</button>
</form>
Use require-match to only accept values that match an existing option. An empty value is still valid (the field is not required), but any typed text that does not match an option label will fail validation.
<form id='matchForm'>
<k-combobox name='color' require-match placeholder='Type or pick a color...'>
<k-option value='red'>Red</k-option>
<k-option value='green'>Green</k-option>
<k-option value='blue'>Blue</k-option>
</k-combobox>
<button type='submit' class='btn primary mt'>Submit</button>
</form>
Use max-visible to limit the number of options shown at once. A “more” indicator appears when additional matches exist.
<k-combobox placeholder='Shows 4 at a time...' max-visible='4'>
<k-option value='1'>Alpha</k-option>
<k-option value='2'>Bravo</k-option>
<k-option value='3'>Charlie</k-option>
<k-option value='4'>Delta</k-option>
<k-option value='5'>Echo</k-option>
<k-option value='6'>Foxtrot</k-option>
<k-option value='7'>Golf</k-option>
<k-option value='8'>Hotel</k-option>
</k-combobox>
Use no-results-message to customize the text shown when the user has typed something but no options match. Use empty-message to customize the text shown when the input is empty and no options are loaded yet (e.g. before a dynamic search has fetched results). They default to "No Matches" and "Type to search..." respectively.
<k-combobox placeholder='Start typing to search...' no-results-message='No users found. Try a different search.' empty-message='Start typing to find a user...'>
</k-combobox>
<script type='module' src='path/to/Combobox.js'></script>
Combobox.js automatically imports Option.js, so only one script tag is needed. k-spinner must be loaded separately if using the searching indicator.
The following components are required:
k-spinner — used for the searching indicator| Attribute | Property | Type | Default | Description |
|---|---|---|---|---|
value |
value |
String |
'' |
The current text input value. |
name |
name |
String |
'' |
Form field name, submitted with the form. |
placeholder |
placeholder |
String |
'' |
Placeholder text for the input field. |
opened |
opened |
Boolean |
false |
Whether the options dropdown is visible. |
searching |
searching |
Boolean |
false |
Shows a loading spinner in the dropdown. |
required |
required |
Boolean |
false |
Marks the field as required for form validation. |
require-match |
requireMatch |
Boolean |
false |
When set, only values matching an existing option are valid. |
disabled |
disabled |
Boolean |
false |
Disables the combobox. |
debounce-ms |
debounceMs |
Number |
300 |
Milliseconds to wait after typing before firing the search event. |
max-visible |
maxVisible |
Number |
8 |
Maximum number of options visible at once. |
no-results-message |
noResultsMessage |
String |
'No Matches' |
Text displayed when the user has typed something but no options match. |
empty-message |
emptyMessage |
String |
'Type to search...' |
Text displayed when the input is empty and no options are loaded (e.g. before an initial dynamic search fetch). |
| Element | Description |
|---|---|
<k-option value="...">Label</k-option> |
Defines a selectable option. The value attribute is the form value; the text content is the displayed label. If value is omitted, the text content is used as both. |
| Method | Description |
|---|---|
setOptions(options) |
Replaces all <k-option> children. Accepts an array of strings or {label, value} objects. Returns this. |
clear() |
Clears the input value and closes the dropdown. Returns this. |
Example:
combobox.setOptions(['Apple', 'Banana', {
label: 'alice@example.com',
value: 101
}]);
| Event | Detail | Description |
|---|---|---|
search |
{ value: String } |
Fired after the user stops typing for debounce-ms milliseconds. |
select |
{ value: *, label: String } |
Fired when the user selects an option from the list. |
change |
— | Fired after an option is selected. |
The combobox inherits kempo-css variables for colors, borders, spacing, and animation timing. No additional custom properties are defined.