Skip to content

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, and FormData reporting.

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.

MikeTomLucy
html
<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

PropertyTypeDefaultDescription
labelstring''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
valuestring''Selected value. Setting it updates the closed-state label; ignored while disabled
defaultValuestring''Initial selected value, matched against option value
disabledbooleanfalseWhether the select is disabled
typestring''text renders a borderless, transparent trigger with no arrow icon; otherwise bordered
placementstring'bottom'Dropdown direction: top, bottom
showSearchbooleanfalseShow an inline search box that filters options by label
getPopupContainerIdstring''Element id to mount the dropdown into (defaults to document.body)
dropdownclassstring''Custom class applied to the dropdown panel
triggerstring'click'How the dropdown opens: click, hover, or click,hover (hover is ignored on mobile)
requiredbooleanfalseWhether a selection is required for the form to submit
sheetstring''CSS injected into the shadow DOM

Note: defaultValue and showSearch are reactive — changing them after the element has connected is re-processed (alongside value, disabled, and sheet) in attributeChangedCallback. Updating defaultValue re-applies the matching selection; toggling showSearch wires or unwires the inline search box.

Option Properties

Provide options via <r-option> child elements.

PropertyTypeDefaultDescription
valuestring''Option value; emitted as the select's value when chosen
disabledbooleanfalseMarks the option as non-selectable; the select skips it for both click and keyboard selection
sheetstring''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).

United StatesCanadaMexico
html
<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

MikeTomLucy
html
<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

MikeTomLucy
html
<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

MikeTomLucy
html
<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>

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.

MikeTomLucy
html
<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

MikeTomLucy
html
<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

MikeTomLucy
html
<!-- 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.

html
<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

html
<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.

html
<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>

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.

html
<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.

html
<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

SlotDescription
(default)Accepts <r-option> elements that define the selectable options

CSS Parts

PartDescription
selectRoot wrapper of the select
selectionThe trigger box (border, background, layout)
iconDropdown arrow icon
selection-itemElement showing the selected option's label
searchThe inline search input (visible with showSearch)
labelThe static label above the field (present when label set)

Best Practices

  • Many options: Enable showSearch so users can filter by label.
  • Trigger method: Match trigger to user expectations; hover is ignored on mobile, so keep click available.
  • Mount position: In scroll or overflow-clipped layouts, use getPopupContainerId to control where the dropdown mounts.
  • Custom styling: Use dropdownclass or the exposed ::part() names to restyle the trigger and dropdown.
  • Forms: Give the select a name so its value is captured by FormData inside a native <form>.

Released under the MIT License.