Select
Native <select class="select"> is the default.
There is no wrapper. When you need a styled listbox, paste the markup
first. Copy src/components/ui/Place.svelte (see Popover)
and use .select-trigger plus a .menu popover
(data-match="anchor" matches the trigger width).
Native
<div class="field">
<label class="label" for="fruit">Fruit</label>
<select class="select" id="fruit">
<option value="">Select</option>
<option>Apple</option>
<option>Banana</option>
<option>Orange</option>
</select>
</div>Custom listbox
Markup
<button class="select-trigger" type="button" popovertarget="fruit-list" aria-haspopup="listbox" aria-expanded="false" data-placeholder="">Select a fruit</button>
<div id="fruit-list" popover class="menu" role="listbox" tabindex="-1" data-match="anchor">
<button class="menu-item select-option" type="button" role="option" aria-selected="false">
<span class="menu-check"></span> Apple
</button>
<button class="menu-item select-option" type="button" role="option" aria-selected="false">
<span class="menu-check"></span> Banana
</button>
</div>Imported
<script>
import { on_menu_toggle, menu_keydown } from './ui/Place.svelte';
let value = $state('');
const label = $derived(value || 'Select a fruit');
function pick(event, next) {
if (event.currentTarget.getAttribute('aria-disabled') === 'true')
return;
value = next;
event.currentTarget.closest('[popover]')?.hidePopover();
}
</script>
<button
class="select-trigger"
type="button"
popovertarget="fruit-list"
aria-haspopup="listbox"
aria-expanded="false"
data-placeholder={value ? undefined : ''}
>{label}</button>
<div id="fruit-list" popover class="menu" role="listbox" tabindex="-1" data-match="anchor" ontoggle={on_menu_toggle} onkeydown={menu_keydown}>
<button class="menu-item select-option" type="button" role="option" aria-selected={value === 'apple'} onclick={(event) => pick(event, 'apple')}>
<span class="menu-check"></span> Apple
</button>
<button class="menu-item select-option" type="button" role="option" aria-selected={value === 'banana'} onclick={(event) => pick(event, 'banana')}>
<span class="menu-check"></span> Banana
</button>
</div>