Skip to main content
Glama
select-usage.md11.8 kB
# Select Component Usage ## Overview The select component allows users to choose an option from a list. It provides both native HTML select and custom JavaScript-enhanced implementations with improved styling and functionality. ## JavaScript Requirements ### Required Scripts ```html <!-- Include Basecoat CSS and JavaScript --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/basecoat-css@0.3.1/dist/basecoat.cdn.min.css"> <script src="https://cdn.jsdelivr.net/npm/basecoat-css@0.3.1/dist/js/basecoat.min.js" defer></script> <script src="https://cdn.jsdelivr.net/npm/basecoat-css@0.3.1/dist/js/select.min.js" defer></script> ``` ## Native HTML Select ### Basic Native Select ```html <select class="select" name="options"> <option value="">Choose an option...</option> <option value="option1">Option 1</option> <option value="option2">Option 2</option> <option value="option3">Option 3</option> </select> ``` ### Native Select with Label ```html <div class="grid gap-2"> <label for="country" class="label">Country</label> <select class="select" id="country" name="country" required> <option value="">Select a country...</option> <option value="us">United States</option> <option value="ca">Canada</option> <option value="uk">United Kingdom</option> </select> </div> ``` ### Native Select with Option Groups ```html <select class="select" name="location"> <option value="">Choose location...</option> <optgroup label="North America"> <option value="us">United States</option> <option value="ca">Canada</option> </optgroup> <optgroup label="Europe"> <option value="uk">United Kingdom</option> <option value="de">Germany</option> <option value="fr">France</option> </optgroup> </select> ``` ## Custom JavaScript Select ### Basic Custom Select ```html <div class="select"> <button type="button" class="flex items-center justify-between w-full p-2 border rounded" aria-haspopup="listbox"> <span>Choose option...</span> <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> </svg> </button> <div data-popover class="w-full border rounded mt-1 bg-background shadow-lg" aria-hidden="true"> <div role="listbox" class="max-h-48 overflow-y-auto"> <div role="option" data-value="option1" class="p-2 hover:bg-muted cursor-pointer">Option 1</div> <div role="option" data-value="option2" class="p-2 hover:bg-muted cursor-pointer">Option 2</div> <div role="option" data-value="option3" class="p-2 hover:bg-muted cursor-pointer">Option 3</div> </div> </div> <input type="hidden" name="select-value" value=""> </div> ``` ### Custom Select with Icons ```html <div class="select"> <button type="button" class="flex items-center justify-between w-full p-2 border rounded" aria-haspopup="listbox"> <span class="flex items-center gap-2"> <span class="w-4 h-4">🌍</span> <span>Choose country...</span> </span> <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> </svg> </button> <div data-popover class="w-full border rounded mt-1 bg-background shadow-lg"> <div role="listbox" class="max-h-48 overflow-y-auto"> <div role="option" data-value="us" class="flex items-center gap-2 p-2 hover:bg-muted cursor-pointer"> <span>🇺🇸</span> <span>United States</span> </div> <div role="option" data-value="ca" class="flex items-center gap-2 p-2 hover:bg-muted cursor-pointer"> <span>🇨🇦</span> <span>Canada</span> </div> <div role="option" data-value="uk" class="flex items-center gap-2 p-2 hover:bg-muted cursor-pointer"> <span>🇬🇧</span> <span>United Kingdom</span> </div> </div> </div> <input type="hidden" name="country" value=""> </div> ``` ### Custom Select with Search (Combobox) ```html <div class="select"> <button type="button" class="flex items-center justify-between w-full p-2 border rounded" aria-haspopup="listbox"> <span>Select framework...</span> <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> </svg> </button> <div data-popover class="w-full border rounded mt-1 bg-background shadow-lg"> <header class="p-2 border-b"> <input type="text" class="input w-full" placeholder="Search frameworks..." aria-label="Search options"> </header> <div role="listbox" class="max-h-48 overflow-y-auto"> <div role="option" data-value="react" class="p-2 hover:bg-muted cursor-pointer">React</div> <div role="option" data-value="vue" class="p-2 hover:bg-muted cursor-pointer">Vue.js</div> <div role="option" data-value="angular" class="p-2 hover:bg-muted cursor-pointer">Angular</div> <div role="option" data-value="svelte" class="p-2 hover:bg-muted cursor-pointer">Svelte</div> </div> </div> <input type="hidden" name="selected-framework" value=""> </div> ``` ### Custom Select with Groups ```html <div class="select"> <button type="button" class="flex items-center justify-between w-full p-2 border rounded" aria-haspopup="listbox"> <span>Choose technology...</span> <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> </svg> </button> <div data-popover class="w-full border rounded mt-1 bg-background shadow-lg"> <div role="listbox" class="max-h-48 overflow-y-auto"> <div class="px-2 py-1 text-sm font-medium text-muted-foreground bg-muted">Frontend</div> <div role="option" data-value="react" class="p-2 hover:bg-muted cursor-pointer">React</div> <div role="option" data-value="vue" class="p-2 hover:bg-muted cursor-pointer">Vue.js</div> <div class="px-2 py-1 text-sm font-medium text-muted-foreground bg-muted">Backend</div> <div role="option" data-value="node" class="p-2 hover:bg-muted cursor-pointer">Node.js</div> <div role="option" data-value="python" class="p-2 hover:bg-muted cursor-pointer">Python</div> </div> </div> <input type="hidden" name="technology" value=""> </div> ``` ## Select States ### Disabled Select ```html <!-- Native disabled --> <select class="select" disabled> <option>Disabled select</option> </select> <!-- Custom disabled --> <div class="select"> <button type="button" class="flex items-center justify-between w-full p-2 border rounded opacity-50" disabled> <span>Disabled select</span> <svg class="w-4 h-4"><!-- chevron --></svg> </button> </div> ``` ### Required Select ```html <div class="grid gap-2"> <label for="required-select" class="label"> Country <span class="text-destructive">*</span> </label> <select class="select" id="required-select" required> <option value="">Select country...</option> <option value="us">United States</option> <option value="ca">Canada</option> </select> </div> ``` ### Invalid Select ```html <div class="grid gap-2"> <label for="invalid-select" class="label">Country</label> <select class="select" id="invalid-select" aria-invalid="true" required> <option value="">Select country...</option> <option value="us">United States</option> </select> <p class="text-destructive text-sm">Please select a country</p> </div> ``` ## JavaScript API ### Programmatic Control ```javascript // Initialize select after DOM is ready document.addEventListener('DOMContentLoaded', function() { const selectElement = document.querySelector('.select'); // Select option by value if (selectElement.selectByValue) { selectElement.selectByValue('option2'); } }); // Listen for select changes document.addEventListener('change', function(e) { if (e.target.matches('.select input[type="hidden"]')) { console.log('Selected value:', e.target.value); } }); // Listen for initialization document.addEventListener('basecoat:initialized', function(e) { if (e.target.matches('.select')) { console.log('Select component initialized'); } }); ``` ### Dynamic Options ```javascript function updateSelectOptions(selectElement, options) { const listbox = selectElement.querySelector('[role="listbox"]'); const hiddenInput = selectElement.querySelector('input[type="hidden"]'); // Clear existing options listbox.innerHTML = ''; // Add new options options.forEach(option => { const optionElement = document.createElement('div'); optionElement.setAttribute('role', 'option'); optionElement.setAttribute('data-value', option.value); optionElement.className = 'p-2 hover:bg-muted cursor-pointer'; optionElement.textContent = option.label; listbox.appendChild(optionElement); }); // Reset selection hiddenInput.value = ''; selectElement.querySelector('button span').textContent = 'Choose option...'; } ``` ## Accessibility Guidelines ### ARIA Attributes ```html <div class="select"> <button type="button" aria-haspopup="listbox" aria-expanded="false" aria-labelledby="select-label"> <span>Choose option...</span> </button> <div data-popover aria-hidden="true"> <div role="listbox" aria-labelledby="select-label" aria-activedescendant=""> <div role="option" id="option-1" data-value="option1" aria-selected="false"> Option 1 </div> </div> </div> </div> ``` ### Keyboard Navigation - **Enter/Space**: Open/close select - **Arrow Up/Down**: Navigate options - **Escape**: Close select - **Tab**: Move focus to next element ## Best Practices ### User Experience - Provide clear default/placeholder text - Use logical grouping for many options - Implement search for long lists (10+ items) - Show selected value clearly in the trigger button ### Accessibility - Always associate labels with select elements - Use semantic HTML and ARIA attributes - Ensure keyboard navigation works properly - Provide clear focus indicators ### Performance - Lazy load options for large datasets - Implement virtual scrolling for very long lists - Debounce search input to avoid excessive filtering - Cache frequently used option sets ### Form Integration ```html <form class="form grid gap-6"> <div class="grid gap-2"> <label for="category" class="label">Category</label> <select class="select" id="category" name="category" required> <option value="">Select category...</option> <option value="tech">Technology</option> <option value="design">Design</option> </select> </div> <div class="select"> <label class="label mb-2">Priority</label> <button type="button" class="flex items-center justify-between w-full p-2 border rounded"> <span>Choose priority...</span> <svg class="w-4 h-4"><!-- chevron --></svg> </button> <div data-popover class="w-full border rounded mt-1 bg-background shadow-lg"> <div role="listbox"> <div role="option" data-value="high" class="p-2 hover:bg-muted cursor-pointer">High</div> <div role="option" data-value="medium" class="p-2 hover:bg-muted cursor-pointer">Medium</div> <div role="option" data-value="low" class="p-2 hover:bg-muted cursor-pointer">Low</div> </div> </div> <input type="hidden" name="priority" value=""> </div> <button type="submit" class="btn">Submit</button> </form> ```

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/GustavoGomezPG/basecoat-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server