Select

Displays a list of options for the user to pick from—triggered by a button.

Requires JavaScript

Installation

Add the component to your project:

rails generate shadcn:component select

Usage

<%= render Shadcn::SelectComponent.new(name: "fruit", placeholder: "Select a fruit") do |select| %>
  <% select.with_item(value: "apple") { "Apple" } %>
  <% select.with_item(value: "banana") { "Banana" } %>
  <% select.with_item(value: "orange") { "Orange" } %>
<% end %>

Examples

With Groups

Organize options into labeled groups.

<%= render Shadcn::SelectComponent.new(name: "timezone", placeholder: "Select a timezone") do |select| %>
  <% select.with_group(label: "North America") do |group| %>
    <% group.with_item(value: "est") { "Eastern Time" } %>
    <% group.with_item(value: "cst") { "Central Time" } %>
    <% group.with_item(value: "mst") { "Mountain Time" } %>
    <% group.with_item(value: "pst") { "Pacific Time" } %>
  <% end %>
  <% select.with_group(label: "Europe") do |group| %>
    <% group.with_item(value: "gmt") { "Greenwich Mean Time" } %>
    <% group.with_item(value: "cet") { "Central European Time" } %>
  <% end %>
<% end %>

Preselected Value

Set an initial value with the value parameter.

<%= render Shadcn::SelectComponent.new(
  name: "fruit",
  value: "banana",
  placeholder: "Select a fruit"
) do |select| %>
  <% select.with_item(value: "apple") { "Apple" } %>
  <% select.with_item(value: "banana") { "Banana" } %>
  <% select.with_item(value: "orange") { "Orange" } %>
<% end %>

Disabled State

Disable the entire select component.

<%= render Shadcn::SelectComponent.new(name: "fruit", placeholder: "Select a fruit", disabled: true) do |select| %>
  <% select.with_item(value: "apple") { "Apple" } %>
  <% select.with_item(value: "banana") { "Banana" } %>
  <% select.with_item(value: "orange") { "Orange" } %>
<% end %>

Disabled Items

Disable specific items within the select.

<%= render Shadcn::SelectComponent.new(name: "fruit", placeholder: "Select a fruit") do |select| %>
  <% select.with_item(value: "apple") { "Apple" } %>
  <% select.with_item(value: "banana", disabled: true) { "Banana (out of stock)" } %>
  <% select.with_item(value: "orange") { "Orange" } %>
<% end %>

Form Integration

Use Select within forms with proper labels and validation.

<%= form_with url: "/submit", method: :post do |f| %>
  <div class="space-y-4">
    <%= render Shadcn::LabelComponent.new(for: "country") { "Country" } %>
    <%= render Shadcn::SelectComponent.new(
      name: "country",
      id: "country",
      placeholder: "Select your country",
      required: true
    ) do |select| %>
      <% select.with_item(value: "us") { "United States" } %>
      <% select.with_item(value: "uk") { "United Kingdom" } %>
      <% select.with_item(value: "ca") { "Canada" } %>
      <% select.with_item(value: "au") { "Australia" } %>
    <% end %>
    <%= render Shadcn::ButtonComponent.new(type: :submit) { "Submit" } %>
  </div>
<% end %>

API Reference

SelectComponent

API Reference

Prop Type Default Description
name String nil Form field name for the hidden input
id String nil Element ID for the hidden input
value String nil Currently selected value
placeholder String "Select..." Placeholder text shown when no value is selected
disabled Boolean false Whether the select is disabled
required Boolean false Whether the select is required for form validation

Slots

Slot Props Description
with_item value:, disabled: A selectable option (yields content)
with_group label: A group of options with an optional label (yields SelectGroupComponent)

SelectItemComponent

API Reference

Prop Type Default Description
value String required The value submitted when this option is selected
disabled Boolean false Whether this option is disabled

SelectGroupComponent

API Reference

Prop Type Default Description
label String nil Optional label for the group

The SelectGroupComponent also accepts with_item slots for items within the group.

Stimulus Controller

This component requires JavaScript. The Stimulus controller shadcn--select provides interactivity.

Manages select dropdown state, keyboard navigation, value selection, and accessibility.

Installation

Add to your config/importmap.rb:

pin "shadcn-rails", to: "shadcn/index.js"

Then in your app/javascript/controllers/index.js:

import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"

const application = Application.start()
registerShadcnControllers(application)

Or import just this controller:

import SelectController from "shadcn-rails/controllers/select_controller"

application.register("shadcn--select", SelectController)

Targets

Name Description
trigger The button that toggles the dropdown
content The dropdown content container
input The hidden input that stores the selected value
item Each selectable option in the dropdown
display The text display showing the current selection
checkIcon The checkmark icon for selected items

Values

Name Type Default Description
value String "" Currently selected value

Actions

Action Description
toggle Opens or closes the dropdown
open Opens the dropdown
close Closes the dropdown
select Selects an item from the dropdown
handleKeydown Handles keyboard navigation (Arrow keys, Enter, Escape, Home, End)

TypeScript

Type definitions are included. Import types as needed:

import type { SelectController } from "shadcn-rails"

Accessibility

  • Uses role="combobox" on the trigger for proper screen reader announcement
  • Uses role="listbox" for the dropdown content
  • Uses role="option" for each selectable item
  • Sets aria-expanded to indicate dropdown open/closed state
  • Sets aria-selected to indicate selected option
  • Supports full keyboard navigation:
    • Space or Enter to open/select
    • Arrow Down / Arrow Up to navigate options
    • Home / End to jump to first/last option
    • Escape to close dropdown
  • Disabled items are properly marked and skipped during keyboard navigation
  • Focus returns to trigger after selection or closing
  • Visual checkmark indicator for the selected option