Native Select

A styled native HTML select element with optgroup support.

No JavaScript Required
native-select/default
<%= render(Shadcn::NativeSelectComponent.new(name: "framework")) do |select| %>
  <% select.with_option(value: "", disabled: true, selected: true) { "Select a framework" } %>
  <% select.with_option(value: "rails") { "Ruby on Rails" } %>
  <% select.with_option(value: "stimulus") { "Stimulus" } %>
  <% select.with_option(value: "turbo") { "Turbo" } %>
<% end %>

Installation

Add the component to your project:

rails generate shadcn:add native_select

Usage

<%= render(Shadcn::NativeSelectComponent.new(name: "framework")) do |select| %>
  <% select.with_option(value: "", disabled: true, selected: true) { "Select a framework" } %>
  <% select.with_option(value: "rails") { "Ruby on Rails" } %>
  <% select.with_option(value: "stimulus") { "Stimulus" } %>
  <% select.with_option(value: "turbo") { "Turbo" } %>
<% end %>

Examples

With Optgroups

<div class="max-w-sm">
  <%= render Shadcn::NativeSelectComponent.new(name: "car") do |select| %>
    <% select.with_optgroup(label: "Swedish Cars") do |group| %>
      <% group.with_option(value: "volvo") { "Volvo" } %>
      <% group.with_option(value: "saab") { "Saab" } %>
    <% end %>
    <% select.with_optgroup(label: "German Cars") do |group| %>
      <% group.with_option(value: "mercedes") { "Mercedes" } %>
      <% group.with_option(value: "audi") { "Audi" } %>
    <% end %>
  <% end %>
</div>

Disabled

<div class="max-w-sm">
  <%= render Shadcn::NativeSelectComponent.new(name: "status", disabled: true) do |select| %>
    <% select.with_option(value: "active", selected: true) { "Active" } %>
    <% select.with_option(value: "inactive") { "Inactive" } %>
  <% end %>
</div>

Required

<div class="max-w-sm">
  <%= render Shadcn::NativeSelectComponent.new(name: "priority", required: true) do |select| %>
    <% select.with_option(value: "", disabled: true, selected: true) { "Select priority" } %>
    <% select.with_option(value: "low") { "Low" } %>
    <% select.with_option(value: "medium") { "Medium" } %>
    <% select.with_option(value: "high") { "High" } %>
  <% end %>
</div>

In Form Field

Select the country where you reside.

<div class="max-w-sm">
  <%= render Shadcn::FieldComponent.new do |field| %>
    <% field.with_label { "Country" } %>
    <% field.with_control do %>
      <%= render Shadcn::NativeSelectComponent.new(name: "user[country]") do |select| %>
        <% select.with_option(value: "", disabled: true, selected: true) { "Select your country" } %>
        <% select.with_option(value: "us") { "United States" } %>
        <% select.with_option(value: "uk") { "United Kingdom" } %>
        <% select.with_option(value: "ca") { "Canada" } %>
      <% end %>
    <% end %>
    <% field.with_description { "Select the country where you reside." } %>
  <% end %>
</div>

Form Example

native-select/form_example
<%= render(Shadcn::NativeSelectComponent.new(name: "user[timezone]", id: "user_timezone")) do |select| %>
  <% select.with_option(value: "utc", selected: true) { "UTC" } %>
  <% select.with_option(value: "est") { "Eastern Time" } %>
  <% select.with_option(value: "pst") { "Pacific Time" } %>
<% end %>

API Reference

API Reference

Prop Type Default Description
name String nil Select name attribute for form submission
id String nil Select ID attribute
disabled Boolean false Whether the select is disabled
required Boolean false Whether the select is required
class_name String nil Additional CSS classes to apply

Slots

  • with_option - Option element (value:, disabled:, selected:)
  • with_optgroup - Option group (label:, disabled:) with nested options

Accessibility

  • Uses native <select> element for full accessibility support
  • Screen readers announce all options and their states correctly
  • Keyboard navigation works natively (arrow keys, type to search)
  • Consider using a placeholder option with disabled for initial state

Native vs Custom Select

Use Native Select when:

  • You need maximum accessibility and mobile support
  • You don't need custom styling for the dropdown
  • You want zero JavaScript overhead

Use the custom Select component when:

  • You need full control over dropdown styling
  • You want features like search/filtering
  • You need custom option rendering