The trigger renders its own up/down chevron, and the search field inside the popover carries a focus ring like any other form control.
Usage
<%= render "components/combobox", placeholder: "Select..." do |combobox_id| %>
<%= render "components/combobox/trigger", for_id: combobox_id, placeholder: "Select..." %>
<%= render "components/combobox/content", id: combobox_id do %>
<%= render "components/combobox/input", placeholder: "Search..." %>
<%= render "components/combobox/list" do %>
<%= render "components/combobox/option", value: "one" do %>Option One<% end %>
<%= render "components/combobox/option", value: "two" do %>Option Two<% end %>
<% end %>
<%= render "components/combobox/empty" %>
<% end %>
<% end %>
Examples
With Selection
<%= render "components/combobox/option", value: "active", selected: true do %>Active<% end %>
<%= render "components/combobox/option", value: "archived", disabled: true do %>Archived<% end %>
With Groups
<%= render "components/combobox/list" do %>
<%= render "components/combobox/group" do %>
<%= render "components/combobox/label", text: "Backend" %>
<%= render "components/combobox/option", value: "ruby" do %>Ruby<% end %>
<% end %>
<%= render "components/combobox/separator" %>
<%= render "components/combobox/group" do %>
<%= render "components/combobox/label", text: "Frontend" %>
<%= render "components/combobox/option", value: "js" do %>JavaScript<% end %>
<% end %>
<% end %>
API Reference
Combobox
| Parameter |
Type |
Default |
Description |
| id |
String |
nil |
Custom ID; defaults to a deterministic id derived from the input name |
| name |
String |
nil |
Form input name |
| value |
String |
nil |
Pre-selected value |
| placeholder |
String |
"Select..." |
Placeholder text |
| css_classes |
String |
"" |
Additional CSS classes |
| html_options |
Hash |
{} |
Additional HTML attributes |
Combobox Trigger
| Parameter |
Type |
Default |
Description |
| for_id |
String |
required |
ID of content popover |
| placeholder |
String |
"Select..." |
Placeholder text |
| variant |
Symbol |
:outline |
Button variant |
| size |
Symbol |
:default |
Button size |
| css_classes |
String |
"" |
Additional CSS classes |
| html_options |
Hash |
{} |
Additional HTML attributes |
Combobox Content
| Parameter |
Type |
Default |
Description |
| id |
String |
required |
Popover ID |
| align |
Symbol |
:start |
:start, :center, :end |
| width |
Symbol |
:default |
:sm, :default, :md, :lg, :full |
| css_classes |
String |
"" |
Additional CSS classes |
| html_options |
Hash |
{} |
Additional HTML attributes |
Combobox Input
| Parameter |
Type |
Default |
Description |
| placeholder |
String |
"Search..." |
Search placeholder |
| css_classes |
String |
"" |
Additional CSS classes |
| html_options |
Hash |
{} |
Additional HTML attributes |
Combobox Option
| Parameter |
Type |
Default |
Description |
| value |
String |
required |
Option value |
| selected |
Boolean |
false |
Whether selected |
| disabled |
Boolean |
false |
Whether disabled |
| css_classes |
String |
"" |
Additional CSS classes |
| html_options |
Hash |
{} |
Additional HTML attributes |
Combobox Empty
| Parameter |
Type |
Default |
Description |
| text |
String |
"No results found." |
Empty state message |
| content |
String |
nil |
Captured HTML via capture, or use block |
| css_classes |
String |
"" |
Additional CSS classes |
| html_options |
Hash |
{} |
Additional HTML attributes |
Combobox Group
| Parameter |
Type |
Default |
Description |
| css_classes |
String |
"" |
Additional CSS classes |
| html_options |
Hash |
{} |
Additional HTML attributes |
Combobox Label
| Parameter |
Type |
Default |
Description |
| text |
String |
nil |
Label text |
| content |
String |
nil |
HTML content via capture, or use block |
| css_classes |
String |
"" |
Additional CSS classes |
| html_options |
Hash |
{} |
Additional HTML attributes |
Combobox List
| Parameter |
Type |
Default |
Description |
| css_classes |
String |
"" |
Additional CSS classes |
| html_options |
Hash |
{} |
Additional HTML attributes |
Builder Helper
The combobox helper wires the trigger and content ids together for you:
<%= combobox placeholder: "Select framework...", name: "framework" do |cb| %>
<% cb.trigger %>
<% cb.content do %>
<% cb.input placeholder: "Search..." %>
<% cb.list do %>
<% cb.group do %>
<% cb.label "Frontend" %>
<% cb.option value: "react" do %>React<% end %>
<% cb.option value: "vue" do %>Vue<% end %>
<% end %>
<% cb.separator %>
<% cb.option value: "rails" do %>Rails<% end %>
<% end %>
<% cb.empty %>
<% end %>
<% end %>
For flat option lists, combobox_simple renders everything from data:
<%= combobox_simple placeholder: "Select framework...",
name: "framework",
options: [
{ value: "nextjs", label: "Next.js" },
{ value: "remix", label: "Remix" }
] %>