Combobox
Custom searchable dropdown with icons, multi-select, and rich interactions. JavaScript-powered alternative to native Select.
Key Features
- Searchable - Filter options with real-time search
- Icons in Options - Display icons alongside option text
- Multi-Select - Select multiple values with checkmarks
- Custom Styling - Full control over appearance (not native picker)
- 5 Sizes - xs, sm, base, lg, xl
- 2 Variants - Default (bordered), Underline
- All Colors - Focus ring colors for all semantic colors
- Keyboard Navigation - Arrow keys, Enter, Escape
- Form Builder - Full Rails form integration (
f.rui_combobox) - Full Accessibility - ARIA attributes, screen reader support
- JavaScript API - Programmatic control with
data-actionattributes
Combobox vs Select
Choose the right component for your use case:
Use Select When
- Simple form selection needed
- Mobile-first (native picker preferred)
- No JavaScript overhead desired
- Basic text-only options
Use Combobox When
- Search/filter functionality needed
- Icons in options required
- Multi-select with visual feedback
- Custom styled dropdown wanted
Basic Usage
Simple combobox with an array of options.
<%= rui_combobox(:province,
collection: ["Ontario", "Quebec", "British Columbia", "Alberta", "Manitoba"],
label: "Province",
placeholder: "Select province...",
wrapper_class: "w-64"
) %>
<%= rui_combobox(:fruit,
collection: ["Apple", "Banana", "Orange", "Mango", "Strawberry"],
label: "Favourite Fruit",
color: :primary,
wrapper_class: "w-64"
) %>
Searchable
Enable search to filter options as you type. Great for long lists.
<%= rui_combobox(:city,
collection: ["Toronto", "Ottawa", "Mississauga", "Brampton", "Hamilton", "London", "Markham", "Vaughan", "Kitchener", "Windsor"],
label: "City in Ontario",
searchable: true,
placeholder: "Search cities..."
) %>
<%= rui_combobox(:saas_company,
collection: ["Shopify", "Slack", "Notion", "Figma", "Linear", "Vercel", "Stripe"],
label: "SaaS Company",
searchable: true,
placeholder: "Search companies..."
) %>
With Icons
Add icons to options using hash collection format.
<%= rui_combobox(:payment_method,
collection: [
{ text: "Credit Card", value: "credit_card", icon: :credit_card },
{ text: "PayPal", value: "paypal", icon: :wallet },
{ text: "Bank Transfer", value: "bank", icon: :building },
{ text: "Apple Pay", value: "apple_pay", icon: :smartphone }
],
label: "Payment Method",
placeholder: "Select payment..."
) %>
Multi-Select
Allow multiple selections with checkmarks. Shows "X selected" in trigger.
<%= rui_combobox(:programming_languages,
collection: ["Ruby", "Python", "JavaScript", "TypeScript", "Go", "Rust"],
label: "Programming Languages",
multiple: true,
searchable: true,
placeholder: "Select languages..."
) %>
<!-- With max selections limit -->
<%= rui_combobox(:grocery_items,
collection: grocery_items_with_icons,
label: "Shopping List (max 3)",
multiple: true,
max_selections: 3
) %>
Sizes
Five sizes matching other form components.
<%= rui_combobox(:field, collection: options, size: :xs) %>
<%= rui_combobox(:field, collection: options, size: :sm) %>
<%= rui_combobox(:field, collection: options, size: :base) %> <!-- Default -->
<%= rui_combobox(:field, collection: options, size: :lg) %>
<%= rui_combobox(:field, collection: options, size: :xl) %>
Variants
Two visual variants: default (bordered) and underline.
<%= rui_combobox(:genre, collection: genres, variant: :default) %>
<%= rui_combobox(:genre, collection: genres, variant: :underline) %>
Colors
Color affects the focus ring and border styling. Combobox supports all semantic colors and any Tailwind color.
Semantic Colors
Tailwind Colors
All Tailwind colors are supported with automatic dark mode variants.
<!-- Semantic colors -->
<%= rui_combobox(:field, collection: options, color: :zinc) %> <!-- Default -->
<%= rui_combobox(:field, collection: options, color: :primary) %>
<%= rui_combobox(:field, collection: options, color: :success) %>
<%= rui_combobox(:field, collection: options, color: :warning) %>
<%= rui_combobox(:field, collection: options, color: :danger) %>
<%= rui_combobox(:field, collection: options, color: :info) %>
<!-- Tailwind colors (all supported!) -->
<%= rui_combobox(:field, collection: options, color: :red) %>
<%= rui_combobox(:field, collection: options, color: :blue) %>
<%= rui_combobox(:field, collection: options, color: :purple) %>
<%= rui_combobox(:field, collection: options, color: :pink) %>
<%= rui_combobox(:field, collection: options, color: :amber) %>
Collections
Combobox supports multiple collection formats.
<!-- Array of strings (value = text) -->
<%= rui_combobox(:city, collection: ["Toronto", "Vancouver", "Montreal"]) %>
<!-- Array of [text, value] pairs -->
<%= rui_combobox(:country, collection: [
["United States", "US"],
["Canada", "CA"],
["United Kingdom", "UK"]
]) %>
<!-- Hash { text => value } -->
<%= rui_combobox(:priority, collection: {
"Low Priority" => "low",
"Medium Priority" => "medium",
"High Priority" => "high"
}) %>
<!-- Array of hashes with icons -->
<%= rui_combobox(:payment, collection: [
{ text: "Credit Card", value: "card", icon: :credit_card },
{ text: "PayPal", value: "paypal", icon: :wallet }
]) %>
<!-- ActiveRecord relation -->
<%= rui_combobox(:category_id,
collection: Category.all,
value_method: :id,
text_method: :name
) %>
States
Disabled, required, and with help text.
Choose your favourite comedy show
<!-- Disabled -->
<%= rui_combobox(:show, collection: comedy_shows, disabled: true) %>
<!-- Required -->
<%= rui_combobox(:show, collection: comedy_shows, required: true, label: "Required") %>
<!-- With help text -->
<%= rui_combobox(:show, collection: comedy_shows, help_text: "Choose your favourite") %>
Form Builder Integration
Use f.rui_combobox within Rails forms. The first parameter is the model's attribute (binds to form), while color: controls the visual styling.
Understanding the Parameters
- First parameter (e.g., :category_id) - The model attribute that gets bound to the form and stored in the database
- color: parameter - Controls the visual styling (border and focus ring colors). Supports all semantic and Tailwind colors
<%= form_with(model: @post) do |f| %>
<!-- Binds to @post.category_id attribute, styled with primary color -->
<%= f.rui_combobox(:category_id,
collection: Category.all,
label: "Category",
color: :primary,
searchable: true,
required: true
) %>
<!-- Binds to @post.tag_ids attribute, styled with success color -->
<%= f.rui_combobox(:tag_ids,
collection: Tag.all,
label: "Tags",
color: :success,
multiple: true,
help_text: "Select one or more tags"
) %>
<%= f.rui_button("Save Post") %>
<% end %>
Accessibility
The Combobox component follows WAI-ARIA best practices for combobox patterns.
ARIA Attributes
-
Input has
role="combobox"witharia-haspopup="listbox" -
aria-expandedindicates dropdown open/closed state -
aria-activedescendanttracks currently focused option -
Options use
role="option"witharia-selected
Keyboard Navigation
- Arrow Down/Up navigates through options
- Enter selects the focused option
- Escape closes the dropdown
- Home/End jumps to first/last option
- Type-ahead search filters options as you type
Semantic HTML
-
Uses
<input>for the combobox trigger -
Dropdown uses
role="listbox"for proper semantics -
Labels properly associated via
forattribute
Screen Reader Support
- Announces number of available options when dropdown opens
- Selected options are announced with their label
- Help text provides additional context when focused
JavaScript API
The Combobox component is composed of multiple Stimulus controllers working together for full functionality.
Combobox Controller
Handles selection, multi-select, and form integration:
| Action | Description |
|---|---|
combobox#select |
Handles option selection (single or multi-select) |
combobox#selectFocused |
Selects the currently focused option (Enter key) |
combobox#clearAll |
Clears all selections (multi-select only) |
combobox#onFilter |
Handles search filter results, shows/hides "no results" |
Menu Controller
Manages dropdown open/close and keyboard navigation:
| Action | Description |
|---|---|
menu#toggle |
Toggles dropdown open/closed |
menu#open |
Opens the dropdown |
menu#close |
Closes the dropdown |
menu#navigateDown |
Move focus to next option (Down arrow) |
menu#navigateUp |
Move focus to previous option (Up arrow) |
Search Controller
Provides real-time filtering of options:
| Action | Description |
|---|---|
search#filter |
Filters options based on search input (debounced) |
search#clear |
Clears the search input and shows all options |
Custom Events
Listen to these events for selection changes:
| Event | When | Detail |
|---|---|---|
combobox:change |
Selection changes | { values: [...] } |
menu:opened |
Dropdown opens | {} |
menu:closed |
Dropdown closes | {} |
search:filter |
Search filters options | { visibleCount, totalCount, term } |
<div data-controller="my-handler"
data-action="combobox:change->my-handler#onSelectionChange">
<%= rui_combobox(:category, options: ["A", "B", "C"]) %>
</div>
// my_handler_controller.js
onSelectionChange(event) {
const { values } = event.detail
console.log("Selected:", values)
}
Programmatic Control
Control the combobox from JavaScript:
// Get the controllers
const element = document.querySelector('[data-controller~="combobox"]')
const comboboxCtrl = application.getControllerForElementAndIdentifier(element, "combobox")
const menuCtrl = application.getControllerForElementAndIdentifier(element, "menu")
// Open/close dropdown
menuCtrl.open()
menuCtrl.close()
// Clear all selections
comboboxCtrl.clearAll()
// Get selected values
console.log(comboboxCtrl.selectedValues)
API Reference
rui_combobox
Custom searchable dropdown with icons, multi-select, and rich interactions
| Parameter | Type | Default | Description |
|---|---|---|---|
| method* | Symbol/String | — | Attribute name for form binding (positional) |
| collection* | Array/Hash/AR |
[]
|
Options collection - strings, [text, value] pairs, hashes, or AR relation |
| label | String | — | Label text above combobox |
| placeholder | String |
"Select an option"
|
Placeholder text when nothing selected |
| help_text | String | — | Help text below combobox |
Selection
Single and multi-select options
| Parameter | Type | Default | Description |
|---|---|---|---|
| multiple | Boolean |
false
|
Allow multiple selections with checkmarks |
| selected | String/Array | — | Pre-selected value(s) - auto-retrieved from object if bound |
| max_selections | Integer | — | Limit number of selections (multi-select only) |
| show_badges | Boolean |
true
|
Show individual badges in trigger (multi-select) |
Appearance
Visual styling options
| Parameter | Type | Default | Description |
|---|---|---|---|
| variant | Symbol |
:default
|
Visual variant
:default
:underline
|
| size | Symbol |
:base
|
Combobox size
:xs
:sm
:base
:lg
:xl
|
| color | Symbol |
:zinc
|
Focus ring color - semantic or Tailwind color |
| shape | Symbol |
:rounded
|
Border radius style
:square
:rounded
:pill
|
Behavior
Search and interaction options
| Parameter | Type | Default | Description |
|---|---|---|---|
| searchable | Boolean |
true
|
Enable search/filter functionality |
| clear_on_select | Boolean |
false
|
Clear search input after selecting |
| close_on_select | Boolean |
auto
|
Close dropdown after selection (single: true, multi: false) |
Collection Configuration
Options for processing collection items
| Parameter | Type | Default | Description |
|---|---|---|---|
| value_method | Symbol/String |
:id
|
Method to get value from collection items |
| text_method | Symbol/String |
:name
|
Method to get display text from collection items |
| icon_method | Symbol/String | — | Method to get icon name from collection items |
States
State options
| Parameter | Type | Default | Description |
|---|---|---|---|
| disabled | Boolean |
false
|
Disable the combobox |
| required | Boolean |
false
|
Show required indicator (*) |
Keyboard Navigation
Built-in keyboard support
| Parameter | Type | Default | Description |
|---|---|---|---|
| ↑ / ↓ | Key | — | Navigate through options |
| Enter | Key | — | Select highlighted option |
| Escape | Key | — | Close dropdown |
| Tab | Key | — | Close dropdown and move to next field |
Form Builder
Options when used with Rails form builder (f.rui_combobox)
| Parameter | Type | Default | Description |
|---|---|---|---|
| form | FormBuilder | — | Rails form builder instance (auto-set by f.rui_combobox) |
| object | Object/Symbol | — | Object to bind combobox to |
| name | String | — | Input name attribute (auto-generated from form/object/method) |
Slots
Content slots for customizing component parts
| Slot | Description |
|---|---|
| icon | Future enhancement - icon slot for options |