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-action attributes

Basic Usage

Simple text input with label and help text.

We'll never share your email

Basic Usage
<%= 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.

Input Types
<%= 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.

Default Variant
<%= rui_input(name: :username, variant: :default, label: "Username") %>

Filled

Input with filled background and transparent border.

Filled Variant
<%= rui_input(name: :username, variant: :filled, label: "Username") %>

Outline

Transparent background with visible border.

Outline Variant
<%= rui_input(name: :username, variant: :outline, label: "Username") %>

Sizes

Five size options from extra small to extra large.

Sizes
<%= 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.

Shapes
<%= 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

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

Password Toggle
<%= 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

Prefix Icon
<%= rui_input(name: :search, type: :search, label: "Search") do |input| %>
  <% input.with_prefix do %>
    <svg ...>...</svg>
  <% end %>
<% end %>

With Text

https://
USD
Text Prefix/Suffix
<%# 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

Pattern & Length Validation
<%= 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

Number Validation
<%= 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.

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 itself
  • wrapper_class: - Applied to the outer container
  • label_class: - Applied to the label element
  • prefix_class: - Applied to the prefix container
  • suffix_class: - Applied to the suffix container
  • container_class: - Applied to the input container (when has prefix/suffix)
  • help_text_class: - Applied to the help text

Input & Wrapper Examples

Input & Wrapper Styling
<%# 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

Label & Help Text 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

$
Prefix & Suffix Styling
<%# 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.

$
USD

All 7 class overrides applied

All 7 Class Overrides
<%= 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 Builder Usage
<%= 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 for attribute linked to input id
  • 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
Using Stimulus Actions
<%# 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:

Programmatic Control
// 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.

Related Components