Input
Flexible text input component with multiple types, variants, and built-in validation.
Key Features
- 7 Input Types - text, email, password, number, tel, url, search
- 3 Variants - Default, Filled, Outline
- Password Toggle - Automatic show/hide for password inputs
- Prefix/Suffix Slots - Add icons or text before/after input
- Validation - Pattern, maxlength, minlength, min, max, step
- Form Builder - Full Rails form integration (
f.rui_input) - 5 Sizes - xs, sm, base, lg, xl
- 3 Shapes - Square, rounded, pill
- All Colors - Semantic + any Tailwind color for focus ring
- Full Accessibility - ARIA attributes, keyboard navigation
- JavaScript API - Programmatic control with
data-actionattributes
Basic Usage
Simple text input with label and help text.
We'll never share your email
<%= rui_input(name: :username, label: "Username") %>
<%= rui_input(
name: :email,
type: :email,
label: "Email Address",
help_text: "We'll never share your email"
) %>
Input Types
Seven input types for different data formats and validation.
<%= rui_input(name: :username, type: :text, label: "Text") %>
<%= rui_input(name: :email, type: :email, label: "Email") %>
<%= rui_input(name: :password, type: :password, label: "Password") %>
<%= rui_input(name: :quantity, type: :number, label: "Number") %>
<%= rui_input(name: :phone, type: :tel, label: "Phone") %>
<%= rui_input(name: :website, type: :url, label: "Website") %>
<%= rui_input(name: :query, type: :search, label: "Search") %>
Variants
Three visual variants for different design contexts.
Default
Standard bordered input with white background.
<%= rui_input(name: :username, variant: :default, label: "Username") %>
Filled
Input with filled background and transparent border.
<%= rui_input(name: :username, variant: :filled, label: "Username") %>
Outline
Transparent background with visible border.
<%= rui_input(name: :username, variant: :outline, label: "Username") %>
Sizes
Five size options from extra small to extra large.
<%= rui_input(name: :field, size: :xs, label: "Extra Small") %>
<%= rui_input(name: :field, size: :sm, label: "Small") %>
<%= rui_input(name: :field, size: :base, label: "Base (default)") %>
<%= rui_input(name: :field, size: :lg, label: "Large") %>
<%= rui_input(name: :field, size: :xl, label: "Extra Large") %>
Shapes
Three shape options for border radius.
<%= rui_input(name: :field, shape: :square, label: "Square") %>
<%= rui_input(name: :field, shape: :rounded, label: "Rounded") %>
<%= rui_input(name: :field, shape: :pill, label: "Pill") %>
Colors
Focus ring colors using semantic and Tailwind colors.
Semantic Colors
<%= rui_input(name: :field, color: :primary, label: "Primary") %>
<%= rui_input(name: :field, color: :success, label: "Success") %>
<%= rui_input(name: :field, color: :danger, label: "Danger") %>
Tailwind Colors
Use any Tailwind color for the focus ring!
Tip: Colors are generated dynamically using ColorBuilderHelper, supporting the entire Tailwind color palette.
Password Toggle
Password inputs automatically include a show/hide toggle button using Stimulus.
Click the eye icon to toggle visibility
<%= rui_input(
name: :password,
type: :password,
label: "Password",
placeholder: "Enter your password"
) %>
Automatic: The password toggle is automatically added to type: :password inputs. The eye icon swaps to eye-off when password is visible. Uses Stimulus controller for smooth interaction.
Prefix & Suffix
Add icons or text before or after the input using slots.
With Icons
<%= rui_input(name: :search, type: :search, label: "Search") do |input| %>
<% input.with_prefix do %>
<svg ...>...</svg>
<% end %>
<% end %>
With Text
<%# Use type: :text with pattern when prefix shows protocol %>
<%= rui_input(
name: :website,
type: :text,
label: "Website",
pattern: "[a-zA-Z0-9][a-zA-Z0-9\-]*\.[a-zA-Z]{2,}",
title: "Enter a valid domain (e.g., example.com)"
) do |input| %>
<% input.with_prefix do %>
<span class="text-xs font-medium">https://</span>
<% end %>
<% end %>
<%= rui_input(name: :price, type: :number, step: "0.01", min: 0, label: "Price") do |input| %>
<% input.with_suffix do %>
<span class="text-xs font-medium">USD</span>
<% end %>
<% end %>
Note: Password inputs with type: :password use the suffix slot automatically for the toggle button. If you provide a suffix slot on a password input, the toggle button won't be added.
Validation
HTML5 validation attributes for client-side validation.
Pattern & Length
3-20 characters, alphanumeric and underscores only
5-digit US ZIP code
<%= rui_input(
name: :username,
pattern: "[a-zA-Z0-9_]+",
minlength: 3,
maxlength: 20,
label: "Username"
) %>
Number Constraints
Must be between 18 and 120
In increments of 5 (0, 5, 10... 100)
Accepts decimal values
<%= rui_input(
name: :age,
type: :number,
min: 18,
max: 120,
label: "Age"
) %>
<%= rui_input(
name: :price,
type: :number,
min: 0,
step: "0.01",
label: "Price"
) %>
States
Required, disabled, readonly, and error states.
<%= rui_input(name: :field, required: true, label: "Required") %>
<%= rui_input(name: :field, disabled: true, label: "Disabled") %>
<%= rui_input(name: :field, readonly: true, label: "Readonly") %>
Custom Styling
Override or extend styles using class override attributes. RapidRailsUI uses tailwind_merge to intelligently merge custom classes - conflicting classes are properly overridden, not just appended.
Available Class Overrides
class:- Applied to the input element itselfwrapper_class:- Applied to the outer containerlabel_class:- Applied to the label elementprefix_class:- Applied to the prefix containersuffix_class:- Applied to the suffix containercontainer_class:- Applied to the input container (when has prefix/suffix)help_text_class:- Applied to the help text
Input & Wrapper Examples
<%# wrapper_class - controls the outer container (layout, width) %>
<%= rui_input(name: :field, wrapper_class: "w-64") %>
<%= rui_input(name: :field, wrapper_class: "max-w-xs") %>
<%# class - styles the input element itself %>
<%= rui_input(name: :field, class: "border-purple-500 focus:ring-purple-500") %>
<%# Both together %>
<%= rui_input(
name: :field,
wrapper_class: "w-80",
class: "bg-amber-50 border-amber-300"
) %>
Label & Help Text Examples
This help text has custom styling
<%# Custom label styling %>
<%= rui_input(
name: :field,
label: "Custom Label",
label_class: "text-indigo-600 font-bold"
) %>
<%# Custom help text styling %>
<%= rui_input(
name: :field,
help_text: "Custom styled help",
help_text_class: "text-indigo-500 font-medium"
) %>
Prefix & Suffix Examples
<%# Custom prefix background %>
<%= rui_input(name: :price, prefix_class: "bg-indigo-100 rounded-l-lg") do |input| %>
<% input.with_prefix do %>$<% end %>
<% end %>
<%# Custom suffix color %>
<%= rui_input(name: :email, suffix_class: "text-emerald-500") do |input| %>
<% input.with_suffix do %>
<svg ...>...</svg>
<% end %>
<% end %>
Combined Styling Example (All 7 Overrides)
This example demonstrates ALL 7 class override options working together.
All 7 class overrides applied
<%= rui_input(
name: :price,
label: "Fully Customized Input",
help_text: "All 7 class overrides applied",
placeholder: "0.00",
type: :number,
# 1. wrapper_class - outer container (layout, width)
wrapper_class: "max-w-md",
# 2. class - input element itself
class: "border-violet-300 focus:ring-violet-500",
# 3. label_class - label element
label_class: "text-violet-700 font-semibold",
# 4. help_text_class - help text below input
help_text_class: "text-violet-500 italic",
# 5. container_class - input container (with prefix/suffix)
container_class: "bg-violet-50 rounded-lg",
# 6. prefix_class - prefix container
prefix_class: "bg-violet-100 text-violet-600",
# 7. suffix_class - suffix container
suffix_class: "bg-violet-100 text-violet-600"
) do |input| %>
<% input.with_prefix do %>
<span class="text-sm font-bold">$</span>
<% end %>
<% input.with_suffix do %>
<span class="text-xs font-medium">USD</span>
<% end %>
<% end %>
Smart Merging: Thanks to tailwind_merge, your custom classes properly override defaults. For example, border-purple-500 will replace the default border-zinc-300, not just be appended.
Form Builder Integration
Use with Rails form builder for automatic object binding and validation.
<%= form_with model: @user do |f| %>
<%= f.rui_input(:username,
label: "Username",
placeholder: "Enter username",
required: true
) %>
<%= f.rui_input(:email,
type: :email,
label: "Email Address",
autocomplete: "email"
) %>
<%= f.rui_input(:password,
type: :password,
label: "Password",
minlength: 8,
help_text: "At least 8 characters"
) %>
<%= f.rui_input(:age,
type: :number,
label: "Age",
min: 18,
max: 120
) %>
<%= f.rui_input(:website,
type: :url,
label: "Website",
placeholder: "https://example.com"
) %>
<%= f.rui_button("Sign Up") %>
<% end %>
Note: When using f.rui_input, the component automatically reads values from the model and displays validation errors below the input.
Error Display
Errors from Rails validations are automatically displayed. Try typing an invalid email to see real-time validation.
Type an invalid email to see error, valid email to see success
Automatic Error Handling: When used with f.rui_input, Rails model errors are automatically detected and displayed with red border and error message.
Real-World Example: Post Form
See the input component in action on the New Post and Posts pages.
Accessibility
The Input component follows WAI-ARIA best practices for form controls.
ARIA Attributes
-
Help text and errors linked via
aria-describedby -
Required fields include
aria-required="true" -
Error states include
aria-invalid="true" -
Error messages displayed with
role="alert" -
Password toggle has
aria-label="Toggle password visibility"
Keyboard Navigation
- Tab moves focus between inputs
- Focus states are clearly visible with ring styles
- Password toggle button is keyboard accessible
Semantic HTML
-
Uses native
<input>elements with appropriate types -
Labels use
forattribute linked to inputid - Input types match content (email, tel, url, password)
Screen Reader Support
- Input type and constraints are announced
- Error messages are announced when validation fails
- Help text provides additional context when focused
JavaScript API
The Input component uses a validation controller for real-time validation feedback.
Stimulus Actions
Use these actions via data-action attributes:
| Action | Description |
|---|---|
input-validation#validate |
Validates input and shows feedback (called on input/blur) |
input-validation#togglePassword |
Toggles password visibility (show/hide) |
input-validation#formatPhoneNumber |
Formats phone as (XXX) XXX-XXXX |
input-validation#formatUrl |
Auto-adds https:// prefix on blur |
<%# Real-time validation is automatic for rui_input %>
<%= rui_input(
name: :email,
type: :email,
label: "Email",
required: true
) %>
<%# Password toggle is automatic for type: :password %>
<%= rui_input(
name: :password,
type: :password,
label: "Password"
) %>
<%# Phone formatting is automatic for type: :tel %>
<%= rui_input(
name: :phone,
type: :tel,
label: "Phone"
) %>
Programmatic Control
Control input validation from JavaScript:
// Get the input validation controller
const inputElement = document.querySelector('[data-controller="input-validation"]')
const validationCtrl = application.getControllerForElementAndIdentifier(
inputElement,
"input-validation"
)
// Trigger validation manually
validationCtrl.validate()
// Clear validation state
validationCtrl.clearValidation()
// Toggle password visibility
validationCtrl.togglePassword()
// Access the input directly
const input = validationCtrl.inputTarget
input.value = "new value"
validationCtrl.validate()
API Reference
rui_input
Text-based form input with validation, prefix/suffix slots, and password toggle
| Parameter | Type | Default | Description |
|---|---|---|---|
| name* | Symbol/String | — | Input name attribute (required for standalone) |
| type | Symbol |
:text
|
Input type
:text
:email
:password
:number
:tel
:url
:search
|
| value | String | — | Input value (auto-retrieved from object if bound) |
| placeholder | String | — | Placeholder text |
| label | String | — | Label text displayed above input |
| help_text | String | — | Help text displayed below input |
| required | Boolean |
false
|
Show required indicator (*) and set aria-required |
| disabled | Boolean |
false
|
Disable the input |
| readonly | Boolean |
false
|
Make input read-only |
Appearance
Visual styling options
| Parameter | Type | Default | Description |
|---|---|---|---|
| variant | Symbol |
:default
|
Visual style variant
:default
:filled
:outline
|
| color | Symbol |
:default
|
Focus ring color (semantic or any Tailwind color)
:default
:primary
:secondary
:success
:warning
:danger
:info
|
| size | Symbol |
:base
|
Input size
:xs
:sm
:base
:lg
:xl
|
| shape | Symbol |
:rounded
|
Border radius style
:square
:rounded
:pill
|
Validation
HTML5 validation attributes
| Parameter | Type | Default | Description |
|---|---|---|---|
| pattern | String | — | Regex pattern for validation |
| minlength | Integer | — | Minimum character length |
| maxlength | Integer | — | Maximum character length |
| min | Numeric | — | Minimum value (number inputs only) |
| max | Numeric | — | Maximum value (number inputs only) |
| step | Numeric/String | — | Step increment (number inputs, use 'any' for decimals) |
Behavior
Input behavior and accessibility hints
| Parameter | Type | Default | Description |
|---|---|---|---|
| autocomplete | String/Symbol | — | Browser autocomplete hint (e.g., 'email', 'username', 'off') |
| inputmode | String/Symbol | — | Virtual keyboard hint (e.g., 'numeric', 'email', 'tel') |
| list | String | — | ID of datalist element for autocomplete suggestions |
Custom Styling
Override default styles with custom Tailwind classes. Uses tailwind_merge for intelligent class merging.
| Parameter | Type | Default | Description |
|---|---|---|---|
| class | String | — | Custom classes for the input element (overrides defaults) |
| wrapper_class | String | — | Custom classes for the outer container |
| label_class | String | — | Custom classes for the label element |
| help_text_class | String | — | Custom classes for the help text |
| prefix_class | String | — | Custom classes for the prefix container |
| suffix_class | String | — | Custom classes for the suffix container |
| container_class | String | — | Custom classes for input container (when has prefix/suffix) |
Form Builder
Options when used with Rails form builder (f.rui_input)
| Parameter | Type | Default | Description |
|---|---|---|---|
| form | FormBuilder | — | Rails form builder instance (auto-set by f.rui_input) |
| object | Object/Symbol | — | Object to bind input to |
| method | Symbol | — | Attribute name on the object |
Slots
Content slots for customizing component parts
| Slot | Description |
|---|---|
| prefix | Leading content (icon or text). Positioned inside the input on the left. |
| suffix | Trailing content (icon or text). Note: Password inputs use this slot for the toggle button automatically. |