A zero-dependency replacement for <select>
with search, tags and groups — the native element stays in the DOM, so your
forms never notice. Everything below is live.
<script src="https://cdn.jsdelivr.net/gh/vanilla-ui-kit/components/select/select.js"></script>
Progressive enhancement of a native select — keyboard, typeahead and theming included.
new Select('#fruit')
Case- and diacritic-insensitive filter (try “zur”), plus a ✕ to reset.
new Select('#city', {
searchable: true,
clearable: true
})
Removable chips in the control, checkmarks in the list. Backspace removes the last tag.
new Select('#toppings', {
searchable: true,
maxItems: 3
})
<optgroup> becomes labelled groups; disabled
options are skipped by the keyboard.
<optgroup label="Strings">… <option disabled>Harp</option>
No native select needed — any container plus options;
a hidden field carries name for forms.
new Select('#size', {
name: 'size',
options: ['S', 'M', 'L', 'XL'],
onChange: v => show(v)
})
The hidden native select submits as usual — no JS on the read side.
<form> <select name="plan">…</select> <select name="addons" multiple>…</select> </form>
Just data attributes — activated on load.
<select data-vsel data-vsel-searchable data-vsel-placeholder="Search countries…">
Toggles the native disabled too, so submit semantics
stay native.
sel.disable() / sel.enable()