Select
Dropdown selector for choosing a single value from a list of options, with optional search and form participation.
Use when you need a single-value dropdown selector built from
<r-option>children, with optional search and native form participation —<r-select>handles opening, filtering, andFormDatareporting.
Quick Start
Basic Usage
Options are supplied as slotted <r-option> children. Each option's value attribute is its value and its text content is the displayed label.
<r-select style="width: 120px; height: 40px" defaultValue="185">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>API Reference
Properties
| Property | Type | Default | Description |
|---|---|---|---|
label | string | '' | Static caption above the field — same pattern as r-input's label, so a labeled select lines up with a labeled input in a form |
value | string | '' | Selected value. Setting it updates the closed-state label; ignored while disabled |
defaultValue | string | '' | Initial selected value, matched against option value |
disabled | boolean | false | Whether the select is disabled |
type | string | '' | text renders a borderless, transparent trigger with no arrow icon; otherwise bordered |
placement | string | 'bottom' | Dropdown direction: top, bottom |
showSearch | boolean | false | Show an inline search box that filters options by label |
getPopupContainerId | string | '' | Element id to mount the dropdown into (defaults to document.body) |
dropdownclass | string | '' | Custom class applied to the dropdown panel |
trigger | string | 'click' | How the dropdown opens: click, hover, or click,hover (hover is ignored on mobile) |
required | boolean | false | Whether a selection is required for the form to submit |
sheet | string | '' | CSS injected into the shadow DOM |
Note:
defaultValueandshowSearchare reactive — changing them after the element has connected is re-processed (alongsidevalue,disabled, andsheet) inattributeChangedCallback. UpdatingdefaultValuere-applies the matching selection; togglingshowSearchwires or unwires the inline search box.
Option Properties
Provide options via <r-option> child elements.
| Property | Type | Default | Description |
|---|---|---|---|
value | string | '' | Option value; emitted as the select's value when chosen |
disabled | boolean | false | Marks the option as non-selectable; the select skips it for both click and keyboard selection |
sheet | string | '' | CSS injected into the option's shadow DOM |
Duplicate option labels or values log a console.warn.
Label label
A static caption rendered above the field — always visible, never overlaps adjacent content. Uses the same tokens and layout as r-input's label, so a labeled select and a labeled input placed side by side in a form line up (same height, same top edge).
<r-select label="Country" defaultValue="185">
<r-option value="185">United States</r-option>
<r-option value="186">Canada</r-option>
<r-option value="187">Mexico</r-option>
</r-select>Default Value defaultValue
<r-select style="width: 120px; height: 40px" defaultValue="185">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>Disabled State disabled
<r-select style="width: 120px; height: 40px" disabled defaultValue="185">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>Text Type type
<r-select style="width: 120px; height: 40px" type="text" defaultValue="185">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>Dropdown Direction placement
placement is a preference, not a guarantee: when the trigger is near a viewport edge and the preferred side lacks room, the dropdown automatically flips to the other side and shifts horizontally to stay on-screen. This only applies to the default body-level mount — with getPopupContainerId set, choose a placement that fits the container.
<r-select style="width: 120px; height: 40px" defaultValue="185" placement="top">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>Search Function showSearch
<r-select style="width: 120px; height: 40px" showSearch="true">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>Trigger Method trigger
<!-- Click trigger (default) -->
<r-select trigger="click">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>
<!-- Hover trigger (ignored on mobile) -->
<r-select trigger="hover">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>
<!-- Both click and hover -->
<r-select trigger="click,hover">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>Container Mount getPopupContainerId
The dropdown is portaled to document.body by default. Pass the id of another element to mount it there instead.
<r-select getPopupContainerId="my-container">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>Custom Dropdown Class dropdownclass
<r-select dropdownclass="custom-dropdown">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>Events
change
Fired when an option is selected. event.detail is { value, label }, where value is the chosen option's value and label is its displayed text. Selecting the initial defaultValue does not fire change.
<r-select id="picker">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>
<script>
document.getElementById('picker').addEventListener('change', (e) => {
console.log(e.detail.value, e.detail.label); // e.g. "186" "Tom"
});
</script>search
Fired only when showSearch is enabled, as the user types in the search box (throttled). event.detail is { value }, the current search text. The component also filters the visible options by label internally.
<r-select showSearch="true" id="searchable">
<r-option value="185">Mike</r-option>
<r-option value="186">Tom</r-option>
<r-option value="187">Lucy</r-option>
</r-select>
<script>
document.getElementById('searchable').addEventListener('search', (e) => {
console.log(e.detail.value);
});
</script>Form Association
r-select is a form-associated custom element (static formAssociated = true). It relays its selected value through ElementInternals, so it is collected by new FormData(form) under the select's name, when it's a real descendant of a native <form>. The form value is seeded from any initial selection on connect and kept in sync as the value changes.
Reset: a native form.reset() restores defaultValue's selection if one is set, otherwise clears the selection entirely — via formResetCallback().
Validation: required makes an empty selection invalid via ElementInternals.setValidity(), visible to form.checkValidity()/form.reportValidity(); a disabled select never blocks validation. checkValidity(), reportValidity(), validity, and validationMessage are exposed on the element, same as a native field.
<form>
<r-select name="country" required>
<r-option value="us">United States</r-option>
<r-option value="ca">Canada</r-option>
</r-select>
<button type="submit">Submit</button>
</form>Slots
| Slot | Description |
|---|---|
| (default) | Accepts <r-option> elements that define the selectable options |
CSS Parts
| Part | Description |
|---|---|
select | Root wrapper of the select |
selection | The trigger box (border, background, layout) |
icon | Dropdown arrow icon |
selection-item | Element showing the selected option's label |
search | The inline search input (visible with showSearch) |
label | The static label above the field (present when label set) |
Best Practices
- Many options: Enable
showSearchso users can filter by label. - Trigger method: Match
triggerto user expectations;hoveris ignored on mobile, so keepclickavailable. - Mount position: In scroll or overflow-clipped layouts, use
getPopupContainerIdto control where the dropdown mounts. - Custom styling: Use
dropdownclassor the exposed::part()names to restyle the trigger and dropdown. - Forms: Give the select a
nameso its value is captured byFormDatainside a native<form>.