You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A styled, accessible select input component that wraps a native <select> element inside shadow DOM. Options are provided as light DOM children and automatically synced into the internal select on slot change.
Tag
<x-selectname="country" placeholder="Choose a country"><optionvalue="us">United States</option><optionvalue="gb">United Kingdom</option><optionvalue="ca">Canada</option></x-select>
x-select-change-request — fires before the selection updates. Call preventDefault() to block the change (controlled mode).
select-change — fires after the selection has changed.
Slots
Slot
Description
(default)
<option> and <optgroup> elements. These are cloned into the internal <select> on slotchange.
CSS Custom Properties
Property
Default (light)
Default (dark)
--x-select-height-sm
2rem
—
--x-select-height-md
2.5rem
—
--x-select-height-lg
3rem
—
--x-select-radius
0.5rem
—
--x-select-font-size-sm
0.75rem
—
--x-select-font-size-md
0.875rem
—
--x-select-font-size-lg
1rem
—
--x-select-padding-inline
0.75rem
—
--x-select-bg
#ffffff
#1f2937
--x-select-bg-disabled
#f8fafc
#111827
--x-select-fg
#0f172a
#f1f5f9
--x-select-fg-disabled
#94a3b8
—
--x-select-placeholder-fg
#94a3b8
—
--x-select-border
#cbd5e1
#374151
--x-select-border-hover
#94a3b8
#4b5563
--x-select-border-focus
#3b82f6
#60a5fa
--x-select-chevron
#64748b
#94a3b8
--x-select-focus-ring
#93c5fd
—
--x-select-shadow
0 1px 2px rgba(15,23,42,0.06)
—
--x-select-transition-duration
140ms
—
CSS Parts
Part
Element
Description
wrapper
<div>
The styled container; receives size/disabled data attrs
select
<select>
The native select element
chevron
<span>
The dropdown arrow icon
Accessibility
The internal <select> uses native browser accessibility — keyboard navigation, screen reader announcements, and OS-level option pickers are provided for free.
When no name attribute is present, aria-label is set on the internal <select> using the placeholder text (or "select" as fallback).
Disabled state is communicated natively via <select disabled>.
Focus ring is applied via :focus-within on the wrapper using --x-select-focus-ring.
Theming
Dark mode is handled automatically via @media (prefers-color-scheme: dark) inside the component's shadow styles. Override any CSS custom property on the host to customize:
Transitions on the wrapper respect @media (prefers-reduced-motion: reduce) — all transitions are set to none when reduced motion is preferred.
Usage Examples
Basic
<x-selectname="role" placeholder="Select a role"><optionvalue="admin">Admin</option><optionvalue="editor">Editor</option><optionvalue="viewer">Viewer</option></x-select>
Consumer-controlled value
<x-selectid="my-select" name="plan" value="pro"><optionvalue="free">Free</option><optionvalue="pro">Pro</option><optionvalue="enterprise">Enterprise</option></x-select><script>constsel=document.getElementById('my-select');sel.addEventListener('select-change',e=>{// Consumer decides whether to persist the selectionsel.setAttribute('value',e.detail.value);console.log('Selected:',e.detail.value,e.detail.label);});</script>