~3.5 KB gzipped (JS + CSS) · Zero dependencies
A fully accessible custom select dropdown web component with keyboard navigation, theming via CSS custom properties.
🔍 Live Demo - See it in action!
npm install @magic-spells/select-dropdownimport '@magic-spells/select-dropdown'<link rel="stylesheet" href="https://unpkg.com/@magic-spells/select-dropdown/dist/select-dropdown.css" />
<script src="https://unpkg.com/@magic-spells/select-dropdown"></script><select-dropdown>
<select-trigger>
<span class="select-label-text">Pick a fruit</span>
</select-trigger>
<input type="hidden" name="fruit" />
<select-panel>
<select-option value="apple">Apple</select-option>
<select-option value="banana" selected>Banana</select-option>
<select-option value="cherry">Cherry</select-option>
</select-panel>
</select-dropdown>| Element | Description |
|---|---|
<select-dropdown> |
Root container |
<select-trigger> |
Clickable trigger button |
<select-panel> |
Options list container |
<select-option> |
Selectable option |
<select-divider> |
Visual separator between groups |
<select-label> |
Non-interactive group heading |
Use <select-label> and <select-divider> to organize options into groups. These elements are automatically skipped during keyboard navigation.
<select-panel>
<select-label>Fruits</select-label>
<select-option value="apple">Apple</select-option>
<select-option value="banana">Banana</select-option>
<select-divider></select-divider>
<select-label>Nuts</select-label>
<select-option value="almond">Almond</select-option>
</select-panel>dropdown.addEventListener('change', () => {
console.log(dropdown.value) // selected value
console.log(dropdown.selectedText) // selected label
})Programmatic updates use the same control API:
dropdown.value = 'banana'Option values come from the value attribute. If an option has no value, its trimmed text content is used.
Style with CSS custom properties:
select-dropdown {
--select-color-text: #333;
--select-color-background: #fff;
--select-color-border: #ddd;
--select-color-border-hover: #aaa;
--select-color-border-dark: #666;
--select-color-primary: #4299e1;
--select-color-hover: #f0f0f0;
--select-color-focus: #e6f7ff;
--select-color-selected: #e6f7ff;
}| Key | Action |
|---|---|
Tab |
Focus the dropdown |
Enter / Space |
Open dropdown or select option |
↑ ↓ |
Open dropdown or navigate options |
Home / End |
Jump to first/last option |
Escape |
Close dropdown |
| Any letter | Jump to matching option |
selectedon<select-option>— pre-select an optionvalueon<select-option>— the option's value
This project is licensed under the MIT License - see the LICENSE file for details.
Made by Cory Schulz