Changelog

Track the evolution of RapidRails UI with detailed release notes for every version.

Stay Updated: Follow releases on GitHub or watch the repository for notifications.

v0.25.0

Latest

Released on January 1, 2026

Dialog Component & Unified Color Validation

Major release introducing the Dialog component and comprehensive color validation improvements across all components.

🎨 New: Dialog Component

Native HTML <dialog> element with rich overlay functionality.

  • Modal mode for focused tasks (centered overlay)
  • Drawer mode for edge-positioned panels (right, left, top, bottom)
  • Native browser focus trapping and Escape key handling
  • Turbo Frame integration for dynamic content loading
  • CSS-only animations using @starting-style
  • Multiple size and position variants (sm, md, lg, xl, 2xl, full)
  • Full dark mode support
  • Auto-close on successful form submission
  • View helper: rui_dialog(title: "...", position: :center)
<%# Basic modal dialog %>
<%= rui_dialog(id: "edit-user", title: "Edit Profile") do %>
  <%= render "users/form", user: @user %>
<% end %>

<%# Drawer from right %>
<%= rui_dialog(id: "sidebar", mode: :drawer, position: :right) do %>
  <%= render "navigation/sidebar" %>
<% end %>

<%# With trigger button %>
<%= rui_dialog(id: "confirm", title: "Confirm Action") do |dialog| %>
  <% dialog.with_trigger { rui_button("Open", color: :primary) } %>
  Are you sure you want to continue?
<% end %>

🔒 Security Fixes

  • ColorBuilderHelper - Fixed unvalidated color fallback in resolve_color method
  • Invalid colors now safely default to "zinc" instead of returning unvalidated user input
  • Prevents potential CSS class injection via malformed color parameters
  • Added ColorValidationHelper as single source of truth for all color validation

🎨 New Semantic Colors

  • :default → maps to zinc (neutral, safe default)
  • :muted → maps to gray (for muted text/backgrounds)
  • :white → maps to neutral (light/white-like alternative)

🐛 Fixed

  • Color Validation - Unified across all 12+ components using ColorValidationHelper
  • Tailwind Safelist - Added missing shade 200 for soft variant hover states
  • Link Component - Default variant changed from :no_underline to :hover_underline (better UX)
  • Alert Component - Fixed color override logic when custom color is nil

Breaking Change: Link component default variant changed from :no_underline to :hover_underline. Users needing old behavior can explicitly specify variant: :no_underline.

v0.24.4

Released on December 26, 2025

ButtonTo Component Fix

Fixed

  • ButtonTo Form Wrapper - Fixed form wrapper not rendering due to ERB template referencing undefined local variable url instead of instance variable @url
  • Form now properly wraps button with correct action and method attributes
  • Fixes DELETE/PATCH/PUT requests that were failing due to missing form tag
  • CSRF token and _method hidden inputs are now inside a valid form tag

v0.24.3

Released on December 26, 2025

Dropdown Keyboard Navigation & Placement Fixes

Fixed critical dropdown component issues with keyboard navigation and placement positioning in production environments.

Fixed

  • Dropdown Keyboard Navigation - Fixed arrow key navigation that was skipping items due to complex CSS selectors
  • Simplified _getNavigableItems() selector to use explicit element type matching instead of complex :not() pseudo-selectors
  • Added explicit JavaScript filtering for disabled and hidden items (more reliable than CSS)
  • Placement Positioning - Fixed top, bottom, left, right placement classes not showing in production
  • Added focus-visible states to safelist for proper keyboard navigation visual feedback
  • Added Home/End key support for jumping to first/last menu items

New Features

  • Claude Code Skills - Created reusable diagnostic skills for Tailwind CSS issues:
    • /tailwind-safelist-audit - Diagnoses Tailwind CSS safelist issues with interview-based methodology
    • /color-safelist-sync - Synchronizes dynamic color generation with Tailwind safelist

v0.24.2

Released on December 24, 2025

Test Assertion Updates

Updated test assertions to match actual component rendering output after component refactoring.

Fixed

  • Dropdown Stimulus Controller Tests - Updated assertions to verify dual-controller setup (menu keyboard)
  • Avatar Fallback Icon Test - Updated to check for inline SVG rendering instead of references
  • SocialButton Color Tests - Updated assertions for inline style format
  • All 1393 tests passing - workflow publishing automated

v0.24.1

Released on December 24, 2025

Icon Component Refactoring

Refactored Icon component color logic to use ColorBuilderHelper for consistency across all components.

Fixed

  • Icon Component Color Logic - Refactored to use ColorBuilderHelper for consistency
  • Removed hardcoded color mappings - now dynamically supports all 22+ Tailwind colors
  • Automatically generates intelligent color shades via ColorBuilderHelper
  • All colors now have automatic dark mode variants
  • Enhanced documentation with comprehensive color examples

v0.24.0

Released on December 24, 2025

Component Fixes & Enhancements

Major fixes and improvements across multiple components with improved production compatibility and positioning.

SocialButton Component

  • Fixed ERB template constant resolution for Styles namespace
  • Fixed component.rb Styles method references to use fully qualified namespace
  • Added error handling for missing platform icons
  • Fixed icon mappings for social button platforms
  • Added cursor-pointer and focus rings to buttons

Avatar Component

  • Added sizing classes to Tailwind safelist (w-32, h-32, w-14, h-14, w-28, h-28)
  • Refactored borders from ring classes to standard border classes
  • Improved styling consistency

Dropdown Component

  • Added keyboard navigation support (Enter key selection)
  • Improved menu item accessibility
  • Fixed Stimulus controller naming conflicts

Tooltip & Popover Components

  • Improved positioning alignment and arrow placement
  • Fixed positioning calculations for edge cases
  • Updated to use inline CSS styles for production compatibility
  • Fixed Stimulus static values access with proper 'Value' suffix

Checkbox Component

  • Fixed checkmark rendering using peer-checked selector
  • Fixed icon positioning within checkboxes
  • Proper SVG rendering via IconProvider

Switch Component

  • Implemented animation using Stimulus controller
  • Added checkbox_switch_controller to installer generator

Select Component

  • Replaced arbitrary Tailwind classes with standard classes
  • Fixed chevron rendering for production

New Features

  • Docker License Validation Skip - New RAPID_RAILS_UI_SKIP_LICENSE_VALIDATION environment variable for CI/CD pipelines

v0.23.0

Released on December 21, 2025

Test Infrastructure Overhaul

Complete restructuring of component tests following Fizzy/Basecamp patterns for improved maintainability and organization.

New Test Helper Modules

  • LucideTestHelper - Mock for lucide-rails icons
  • ComponentTestHelper - Common assertions (render_html, assert_includes_class, etc.)
  • MockObjectsHelper - Factory methods for test fixtures
  • SharedExamples - Automatic variant testing patterns

Component Tests Restructured

All 19 component test files reorganized into focused modules:

  • Each component has dedicated folder with specific test files (basic, styling, accessibility, etc.)
  • 118 focused test files replacing 19 monolithic files
  • Components: accordion, alert, avatar, badge, checkbox, clipboard, combobox, date, image, link, popover, radio_button, select, text, text_fmt, textarea, tooltip, upload

test_helper.rb Refactored

  • Auto-discovery of components via Dir.glob
  • Optional VCR/WebMock configuration for HTTP mocking
  • Parallel test execution support

Bug Fixes

  • Fixed ViewComponent ActiveSupport::Configurable deprecation warning for Rails 8.1+
  • Silenced test suite warnings for cleaner output

Test Results

1393 runs, 2537 assertions, 0 failures, 0 errors

v0.22.0

Licensing

Released on December 21, 2025

New: Licensing System

Production license validation with tier support for Starter, Pro, and Agency tiers.

License Key Format

  • 7-segment format: RRUI-TIER-CUSTOMER-SEATS-DOMAINS-DATE-CHECKSUM
  • Tier codes: STR (Starter), PRO (Pro), AGY (Agency)
  • Seats & Domains: Configurable limits with :unlimited support
  • Legacy support: 4-segment keys still work (default to Starter tier)

Tier Module

  • RapidRailsUI.pro? / RapidRailsUI.starter? - Check gem tier
  • RapidRailsUI.component_available?(:dropdown) - Check component availability
  • RapidRailsUI.pro_exclusive?(:accordion) - Check if Pro-only
  • RapidRailsUI::INCLUDED_COMPONENTS - All 24 components
  • RapidRailsUI::PRO_EXCLUSIVE_COMPONENTS - 8 Pro-only components

TierGate Concern

Runtime access control for Pro-exclusive components:

  • Auto-skip: Disabled in development/test environments
  • Applied to: Accordion, Alert, Combobox, Date, Dropdown, Popover, Select, Upload
  • Error: TierAccessDenied with component name and current tier

Domain Normalization

  • Subdomains are FREE: staging.myapp.com → myapp.com (counts as 1 domain)
  • Multi-part TLDs: .co.uk, .com.au, .co.nz handled correctly
  • Examples: api.myapp.co.uk → myapp.co.uk

Tests Added

  • 98 new tests for licensing system
  • TierTest (28), TierGateTest (9), ActivationClientTest (30), LicenseTest (31)

Documentation

  • INSTALLATION.md: Domain counting section, troubleshooting table
  • LICENSE.txt: Domain counting examples, clearer tier descriptions
  • README.md: Commercial terms, tier comparison table

Bug Fix

  • Accordion Component - Various improvements and fixes

v0.21.0

Popover

Released on December 19, 2025

New: Popover Component (rui_popover)

Rich, interactive content on hover or click. Unlike Tooltip (text-only), Popover supports complex layouts with headers, bodies, footers, and interactive elements like buttons and links.

Structured Slots

  • with_trigger - The element that activates the popover (required)
  • with_header - Header section (optional)
  • with_body - Main content section (optional)
  • with_footer - Footer section, great for action buttons (optional)
  • with_custom_content - Flexible alternative to structured slots

Position & Width

  • Positions: top, right, bottom (default), left
  • Widths: sm (200px), base (280px), lg (320px), xl (400px)
  • Custom max-width: max_width: "350px" for precise control

Colors & Styling

  • default - Light background with subtle border
  • dark - Dark background for contrast
  • Tailwind colors - primary, success, warning, danger, blue, etc. (colored border)
  • Arrow - Optional arrow pointing to trigger (arrow: true)

Trigger Modes

  • hover (default) - Show on mouseenter, hide on mouseleave
  • click - Toggle on click, dismiss on click-outside or Escape
  • Delays: delay: 200 (show delay), hide_delay: 100 (hide delay)

Accessibility

  • role="dialog" on popover content
  • aria-describedby, aria-expanded, aria-haspopup on trigger
  • aria-hidden on popover when closed
  • Focusable trigger with tabindex="0"
  • Focus events (focusin/focusout) for keyboard users
  • Escape key dismissal for click mode

Usage Examples

<%# Basic popover with structured slots %>
<%= rui_popover do |p| %>
  <% p.with_trigger do %>
    <%= link_to "@username", "#" %>
  <% end %>
  <% p.with_header do %>
    <strong>User Name</strong>
  <% end %>
  <% p.with_body do %>
    <p>Bio text here...</p>
  <% end %>
  <% p.with_footer do %>
    <%= rui_button("Follow", size: :sm) %>
  <% end %>
<% end %>

<%# Click triggered with custom width %>
<%= rui_popover(trigger: :click, width: :lg) do |p| %>
  <% p.with_trigger do %>Click me<% end %>
  <% p.with_body do %>Click outside to close<% end %>
<% end %>

<%# With arrow and position %>
<%= rui_popover(position: :right, arrow: true, color: :primary) do |p| %>
  <% p.with_trigger { rui_icon(:info) } %>
  <% p.with_body { "Information panel" } %>
<% end %>

Bug Fix

  • Popover Styles - Fixed nil color handling in validate_color method

v0.20.0

TailwindMerge

Released on December 18, 2025

New: TailwindMerge Helper

Intelligent Tailwind CSS class merging that resolves conflicts when users customize component styles.

  • Added tailwind_merge gem dependency for class conflict resolution
  • Created TailwindMergeHelper module with tw_merge method
  • Later classes override earlier conflicting classes (e.g., tw_merge("p-4", "p-6") returns "p-6")
  • Enables users to customize component styles via class parameters
  • Comprehensive test coverage (13 tests)

New: Input Class Override Support

Customize internal element styles with new class parameters:

  • label_class - Custom label styling
  • prefix_class - Custom prefix container styling
  • suffix_class - Custom suffix container styling
  • help_text_class - Custom help text styling
  • container_class - Input container styling
  • All use tw_merge for intelligent class conflict resolution

Bug Fix

  • Button - Icon-only buttons no longer show "Button" text fallback

v0.19.0

Tooltip

Released on December 18, 2025

New: Tooltip Component (rui_tooltip)

Contextual information on hover or focus. Display supplementary hints, labels, or explanations.

Positions & Sizes

  • Positions: top (default), right, bottom, left
  • Sizes: sm, base, lg

Colors

  • dark (default) - Dark background for contrast
  • light - Light background
  • Semantic: primary, success, warning, danger, info

Features

  • CSS arrow pointing to trigger element (uses border technique)
  • Arrow can be disabled with arrow: false
  • Two trigger modes: hover (default) and click
  • Configurable show delay via delay parameter (milliseconds)
  • Configurable hide delay via hide_delay parameter (prevents flickering)
  • Max-width support for long text with wrapping (max_width parameter)
  • Screen reader description via description parameter

Accessibility

  • role="tooltip" on tooltip content
  • aria-describedby and aria-hidden attributes
  • Focusable trigger with focus events
  • Smooth 150ms fade animation
  • Full dark mode support
  • 48 comprehensive tests

Usage Example

<%= rui_tooltip(text: "This is helpful information", position: :top) do %>
  <%= rui_button("Hover me", variant: :outline) %>
<% end %>

<%= rui_tooltip(text: "Click to copy", trigger: :click, color: :primary) do %>
  <%= rui_icon(:copy) %>
<% end %>

New: Shared Popup Controller

Reusable Stimulus controller for hover/focus popups. Powers Tooltip and Popover components.

  • Configurable show delay and hide delay for smooth UX
  • Hover and click trigger modes
  • Smooth opacity transitions
  • ARIA attribute management
  • Click-outside dismissal for click triggers
  • Escape key handling
  • Dispatches cancelable events: popup:show, popup:shown, popup:hide, popup:hidden

v0.18.0

Combobox

Released on December 18, 2025

New: Combobox Component (rui_combobox, f.rui_combobox)

Searchable dropdown with custom styling and JavaScript interactivity. A powerful alternative to Select with enhanced UX features.

Selection Modes

  • Single select - Choose one option from the list
  • Multi-select - Choose multiple options with badge display (show_badges: true) or summary ("X items selected")
  • Max selections - Limit multi-select with max_selections parameter

Search & Navigation

  • Real-time search input for filtering options
  • Keyboard navigation (Arrow keys, Enter, Escape, Tab)
  • Icon support in options via icon_method parameter

Styling Options

  • Sizes: xs, sm, base, lg, xl (matches Select trigger styling)
  • Colors: Semantic + Tailwind colors for focus ring and borders
  • Shapes: square, rounded, pill
  • Variants: :default (bordered) and :underline

Form Integration

  • Collection support: Array, Hash, ActiveRecord::Relation
  • Form builder: f.rui_combobox(:method, collection: items, multiple: true)
  • View helper: rui_combobox(:name, collection: items)
  • Auto-detects selected value(s) from model
  • Auto-displays errors from model.errors

Behavior Options

  • searchable - Enable/disable search input
  • clear_on_select - Clear search after selection
  • close_on_select - Close dropdown after selection

Usage Example

<%# Single select with search %>
<%= rui_combobox(:country, collection: Country.all, label: "Select Country") %>

<%# Multi-select with badges %>
<%= f.rui_combobox(:tags, collection: Tag.all, multiple: true, show_badges: true) %>

<%# With icons in options %>
<%= rui_combobox(:category, collection: categories, icon_method: :icon_name) %>

v0.17.0

Select

Released on December 18, 2025

New: Select Component (rui_select, f.rui_select)

Native HTML <select> element with ViewComponent + Tailwind styling. A lightweight, JavaScript-free alternative to Dropdown for form submissions.

Styling Options

  • Variants: :default (bordered) and :underline (bottom border only)
  • Sizes: xs, sm, base, lg, xl (matches Dropdown sizing)
  • Colors: Semantic + Tailwind colors for focus ring
  • Shapes: square, rounded, pill

Features

  • Collection support: Array, Hash, ActiveRecord::Relation
  • Optgroup support for grouped options (nested hash format)
  • Multiple selection with rows parameter
  • Prompt and blank option support
  • Auto-detects selected value from model
  • Auto-displays errors from model.errors

Form Integration

  • Form builder: f.rui_select(:method, collection: items)
  • View helper: rui_select(:name, collection: items)
  • Full accessibility (native browser support)
  • Native mobile OS picker

Usage Example

<%# Basic select %>
<%= rui_select(:status, collection: Post.statuses, label: "Status") %>

<%# With optgroups %>
<%= f.rui_select(:category, collection: {
  "Fruits" => [["Apple", 1], ["Banana", 2]],
  "Vegetables" => [["Carrot", 3], ["Broccoli", 4]]
}) %>

<%# Multiple selection %>
<%= rui_select(:tags, collection: tags, multiple: true, rows: 5) %>

v0.16.1

Security

Released on December 17, 2025

Security

  • Avatar XSS Protection - Block potentially unsafe src attributes (javascript:, data:, vbscript: URIs)

Changed

  • JS Controller Reorganization - All Stimulus controllers moved to rapid_rails_ui/ namespace for better organization
  • Badge Component - Added memoization for improved performance
  • Component Cleanup - Minor documentation and code improvements across accordion, link components

Removed

  • Deprecated controller locations (old badge_controller.js paths)

v0.16.0

Dropdown

Released on December 17, 2025

New: Dropdown Component (rui_dropdown, f.rui_dropdown)

Versatile menu system for navigation and form selection with comprehensive features.

Two Modes

  • Action Dropdowns - Navigation menus, context menus, user menus
  • Selection Dropdowns - Form integration with hidden inputs for single/multi-select

Variants & Styles

  • Variants: solid, outline, ghost, soft
  • Colors: zinc, primary, success, warning, danger, info
  • Sizes: xs, sm, base, lg, xl
  • Shapes: square, rounded, pill

Rich Slot System

  • Items - Standard menu items with icons, descriptions, danger styling
  • Headers - Section headers for grouping
  • Dividers - Visual separators
  • Checkbox Items - Multi-select with checkmarks
  • Radio Items - Single-select with radio indicators
  • Toggle Items - Switch-style toggles
  • User Headers - User profile display with avatar
  • Avatar Items - Items with user avatars
  • Submenus - Nested menu panels
  • Search - Filter items as you type
  • Footer - Action buttons at bottom

Features

  • Keyboard Navigation - Arrow keys, Escape, Enter
  • Full ARIA Accessibility - role="menu", aria-expanded, etc.
  • Collection Support - Hash, Array, ActiveRecord::Relation
  • Form Builder Integration - f.rui_dropdown(:field, collection: [...])
  • Placement Options - top, right, bottom, left
  • Trigger Options - click, hover
  • Avatar Trigger - User menu with avatar display
  • Icon-Only Mode - Compact action menus

Usage Examples

<%# Action dropdown (navigation) %>
<%= rui_dropdown(text: "Options") do |dropdown| %>
  <% dropdown.with_header(text: "Actions") %>
  <% dropdown.with_item(text: "Edit", href: edit_path, icon: :edit) %>
  <% dropdown.with_divider %>
  <% dropdown.with_item(text: "Delete", href: delete_path, icon: :trash_2, danger: true) %>
<% end %>

<%# Selection dropdown (form) %>
<%= rui_dropdown(:status, collection: Post.statuses, label: "Status") %>

<%# Form builder %>
<%= form_with(model: @post) do |f| %>
  <%= f.rui_dropdown(:category_id, collection: Category.all, label: "Category") %>
<% end %>

<%# With search and checkbox items %>
<%= rui_dropdown(text: "Filter") do |dropdown| %>
  <% dropdown.with_search(placeholder: "Search...") %>
  <% dropdown.with_checkbox_item(text: "Draft", value: "draft") %>
  <% dropdown.with_checkbox_item(text: "Published", value: "published") %>
<% end %>

Architecture Improvements

  • New JS controller organization under rapid_rails_ui/ namespace
  • Shared controllers: keyboard, search, switch
  • Component JS config extracted to YAML for easier maintenance

v0.15.0

API Update

Released on December 14, 2025

Form Component API Modernization

Checkbox, RadioButton, and Date components now support the positional first argument pattern (like Textarea and Input), making standalone usage cleaner.

New Syntax (recommended)

<%# Checkbox - positional syntax %>
<%= rui_checkbox(:newsletter, label: "Subscribe") %>
<%= rui_checkbox(:terms, label: "I accept", required: true) %>
<%= rui_checkbox(:category_ids, collection: Category.all, label: "Categories") %>

<%# RadioButton - positional syntax %>
<%= rui_radio_button(:status, collection: Post.statuses, label: "Status") %>
<%= rui_radio_button(:priority, collection: priorities, variant: :card) %>

<%# Date - positional syntax %>
<%= rui_date(:birthday, label: "Birthday") %>
<%= rui_date(:event_date, variant: :picker, label: "Event Date") %>

<%# Form builder - unchanged (already clean) %>
<%= f.rui_checkbox(:terms, label: "I agree") %>
<%= f.rui_radio_button(:status, collection: statuses) %>
<%= f.rui_date(:start_date) %>

Backward Compatible

Old keyword-only syntax still works:

<%= rui_checkbox(object: :user, method: :terms, label: "I agree") %>
<%= rui_radio_button(object: @post, method: :status, collection: statuses) %>
<%= rui_date(name: :birthday, label: "Birthday") %>

Why This Change?

  • Cleaner, more Rails-like syntax for standalone usage
  • Consistent API across all form components (Textarea, Input, Checkbox, RadioButton, Date)
  • Form builder usage was already clean - this brings standalone up to par

v0.14.0

Upload

Released on December 13, 2025

New: Upload Component (rui_upload, f.rui_upload)

New file upload component with two modes: styled file input and drag & drop dropzone.

Two Modes

  • Default - Styled native file input (consistent with Input component)
  • Dropzone - Drag & drop area with visual feedback (dropzone: true)

Usage

<%# Basic file upload %>
<%= rui_upload(:avatar, label: "Profile Picture", accept: [:image]) %>

<%# Dropzone with multiple files %>
<%= rui_upload(:documents,
  label: "Documents",
  dropzone: true,
  multiple: true,
  accept: [:pdf, :document],
  max_files: 5,
  max_file_size: 10.megabytes
) %>

<%# Form builder %>
<%= f.rui_upload(:attachments, dropzone: true, multiple: true) %>

Features

  • File type restrictions - Accept symbols (:image, :pdf, :document, :video, :audio, :spreadsheet, :archive)
  • Size validation - Client-side max file size check (max_file_size)
  • Count limits - Limit number of files (max_files)
  • File preview - Image thumbnails or file icons with names and sizes
  • Remove files - Remove files from preview before upload
  • Real-time validation - Instant feedback for violations
  • 3 variants - default, filled, outline
  • 5 sizes - xs, sm, base (default), lg, xl
  • Dark mode - Complete dark mode support
  • Accessibility - Full ARIA support, keyboard navigation

View Upload Documentation →

v0.13.0

Textarea

Released on December 13, 2025

New: Textarea Component (rui_textarea, f.rui_textarea)

New multi-line text input component with character counting, auto-resize, and real-time validation.

Positional Argument Support

Cleaner syntax with positional first argument:

<%# Standalone - positional (recommended) %>
<%= rui_textarea(:notes, label: "Notes", rows: 4) %>

<%# Form builder %>
<%= f.rui_textarea(:body, label: "Content", rows: 8) %>

Variants

  • default - White background with border
  • filled - Gray background, no visible border
  • outline - Transparent background with border

Features

  • Character counter - Live count with "X / max" format (show_count: true)
  • Auto-resize - Grows/shrinks with content (auto_resize: true, max_rows)
  • Real-time validation - Visual feedback (green/red borders)
  • Resize control - :none, :vertical, :horizontal, :both
  • Wrap control - :soft, :hard, :off
  • 5 sizes - xs, sm, base (default), lg, xl
  • 3 shapes - square, rounded (default), pill (uses rounded-2xl)
  • All colors - Semantic + Tailwind colors for focus rings

View Textarea Documentation →

Fixed: Input & Textarea Stimulus Actions

Fixed Stimulus data-action attributes being HTML-encoded, which broke validation, password toggle, auto-resize, and character counter functionality.

  • Root cause - Rails tag helper escapes > to &gt; in attributes
  • Solution - Added .html_safe to action strings to preserve -> arrow syntax

v0.12.0

Input

Released on December 12, 2025

New: Input Component (rui_input, f.rui_input)

New text-based input component for form fields with real-time validation and rich customization options.

Input Types

  • text (default) - Standard text input
  • email - Email with browser validation
  • password - Obscured text with automatic show/hide toggle
  • number - Numeric input with min/max/step support
  • tel - Phone number (mobile keypad on touch devices)
  • url - URL with browser validation
  • search - Search with native clear button

Variants

  • default - White background with border
  • filled - Gray background, no visible border
  • outline - Transparent background with border

Features

  • Label with optional required indicator (*)
  • Help text below input
  • Real-time validation with visual feedback (Stimulus controller)
  • Password show/hide toggle (automatic for password inputs)
  • Prefix and suffix slots for icons or text
  • 5 sizes (xs, sm, base, lg, xl)
  • 3 shapes (square, rounded, pill)
  • All semantic colors + Tailwind colors for focus ring with colored backgrounds
  • Validation attributes: pattern, maxlength, minlength, min, max, step
  • Autocomplete & inputmode support for better UX
  • Dark mode support

Accessibility

  • Label association via for attribute
  • aria-describedby for help text and validation messages
  • aria-required and aria-invalid states
  • Password toggle has aria-label
  • Validation messages use role="alert"
<%# Basic usage %>
<%= rui_input(name: :email, type: :email, label: "Email Address") %>

<%# Form builder integration %>
<%= form_with model: @user do |f| %>
  <%= f.rui_input(:username, label: "Username", required: true) %>
  <%= f.rui_input(:email, type: :email, label: "Email") %>
  <%= f.rui_input(:password, type: :password, label: "Password") %>
<% end %>

<%# With prefix/suffix %>
<%= rui_input(name: :website, label: "Website") do |input| %>
  <% input.with_prefix do %>
    <span>https://</span>
  <% end %>
<% end %>

Bug Fixes

  • Fixed FormHelper#model_value to check respond_to? before calling method on form object
  • f.rui_input(:any_field) now works even if model doesn't have that attribute

View Input Documentation →

v0.11.1

Radio Button

Released on December 11, 2025

New: Radio Button Component (rui_radio_button, f.rui_radio_button)

New radio button component for single-selection form inputs with multiple variants.

Variants

  • radio (default) - Standard circular radio button
  • card - Bordered card with full-width click target
  • pill - Compact, tag-like rounded selections
  • button - Toolbar-style segmented controls

Features

  • Collection rendering from arrays, hashes, or ActiveRecord
  • Form builder integration (f.rui_radio_button)
  • Description support for each option
  • Required field indicator with asterisk
  • Help text and error message display
  • Vertical and horizontal layouts
  • 5 sizes (xs, sm, base, lg, xl)
  • All semantic colors + Tailwind colors
  • Dark mode support

Accessibility

  • role="radiogroup" on wrapper
  • aria-labelledby pointing to legend
  • aria-describedby for help text
  • aria-required and aria-invalid states
  • Proper label/input associations
<%# Basic usage with enum %>
<%= rui_radio_button(
  object: @post,
  method: :status,
  collection: Post.statuses,
  label: "Post Status"
) %>

<%# Form builder with card variant %>
<%= form_with model: @post do |f| %>
  <%= f.rui_radio_button :priority,
    collection: [["Low", 1], ["Medium", 2], ["High", 3]],
    variant: :card,
    label: "Priority Level"
  %>
<% end %>

<%# Button variant (segmented control) %>
<%= f.rui_radio_button :view_mode,
  collection: [["List", "list"], ["Grid", "grid"]],
  variant: :button,
  layout: :horizontal
%>

Critical Bug Fix: Radio Button Styling

  • Fixed radio buttons displaying as filled circles when unchecked
  • Implemented MDN-recommended border-only styling approach
  • Unchecked radios now correctly display as hollow circles
  • Checked radios fill with color using thick borders (no background)
  • Added dedicated build_radio method in ColorBuilderHelper

View Radio Button Documentation →

v0.11.0

Image

Released on December 10, 2025

New: Image Component (rui_image)

Semantic HTML image component for displaying content images with captions, links, and visual effects.

Core Features

  • Semantic HTML: Uses <figure> and <figcaption> when caption is present
  • Performance: Built-in lazy loading, async decoding, fetchpriority
  • Responsive: srcset, sizes, width/height for layout shift prevention
  • Sizes: auto, full, xs-xl3
  • Shapes: default, rounded, circle, square
  • Aspect ratios: auto, square, video, portrait, landscape, wide, ultrawide
  • Object fit: cover, contain, fill, none, scale_down
  • Visual effects: grayscale, blur, sepia, zoom, shine, overlay
  • Link wrapping: Make images clickable with url parameter
  • Security: crossorigin and referrerpolicy support

Picture Element Support

  • New sources parameter for <picture> element
  • Art Direction: Different images for different viewports using media queries
  • Format Fallback: AVIF/WebP with automatic JPEG/PNG fallback
  • Dark Mode: Different images based on prefers-color-scheme
  • Retina/High DPI: Density descriptors (1x, 2x, 3x) support

Social Media Platform Sizes

  • Built-in presets for 2025 social media dimensions
  • Instagram: :ig_post, :ig_story, :ig_reel
  • Facebook: :fb_post, :fb_story, :fb_cover
  • X/Twitter: :x_post, :x_header
  • LinkedIn: :linkedin_post, :linkedin_cover
  • Plus: Pinterest, TikTok, YouTube presets
<%# Basic image (positional src argument) %>
<%= rui_image("photo.jpg", alt: "A beautiful sunset") %>

<%# With caption (uses figure/figcaption) %>
<%= rui_image("landscape.jpg", alt: "Mountain vista", caption: "View from the summit") %>

<%# Picture element with format fallback %>
<%= rui_image("photo.jpg", alt: "Photo", sources: [
  { srcset: "photo.avif", type: "image/avif" },
  { srcset: "photo.webp", type: "image/webp" }
]) %>

<%# Social media size %>
<%= rui_image("campaign.jpg", alt: "Campaign", size: :ig_post) %>

Clipboard Component - Enhanced Code Variant

  • Updated :code variant with Flowbite-style design for code blocks
  • Minimal transparent button with icon + "Copy" text
  • Success state turns green (emerald-400) with check icon + "Copied!"

View Clipboard Documentation →

v0.10.0

Clipboard

Released on December 10, 2025

New: Clipboard Component (rui_clipboard)

Copy text to clipboard with visual feedback and success states.

Variants

  • default: Standard button with icon and text
  • minimal: Subtle, text-only button
  • github: Icon-only button (GitHub style)
  • toolbar: GitHub PR-style with label + icon
  • code: Flowbite-style for code blocks

Features

  • Positional argument support: rui_clipboard("element-id")
  • Tooltip support with success state
  • Auto-detects input.value or element.textContent
  • Success feedback with icon swap for 2 seconds
  • All semantic colors and sizes (xs-xl)
  • Clean Stimulus controller (modern Clipboard API)
<%# Basic usage %>
<%= rui_clipboard("code-block", text: "Copy Code") %>

<%# GitHub style (icon only) %>
<%= rui_clipboard("sha", variant: :github, tooltip: "Copy SHA") %>

<%# Code block style %>
<%= rui_clipboard("code-example", variant: :code) %>

View Date Component Documentation →

v0.9.1

Released on December 8, 2025

Date Component Improvements

  • Improved datetime time picker to match standalone time picker style with scrollable list UI
  • Removed max-w-sm constraint from calendar dropdown for better flexibility
  • Increased cell spacing (gap-1) in calendar for less crowded appearance
  • Implemented <dialog> element for semantic HTML (following Flux UI pattern)
  • Calendar now stays open when clicking date range presets for better UX

Checkbox Component

  • Added 11 new comprehensive tests covering icon slot (6 tests) and error state (5 tests)
  • Total test coverage: 711 tests, 1260 assertions

Bug Fixes

  • Fixed datetime picker time selection UI to use consistent scrollable list interface
  • Fixed calendar dropdown width constraint that was limiting larger date ranges
  • Fixed calendar closing unexpectedly when selecting presets in range mode

View Checkbox Component Documentation →

v0.9.0

Checkbox

Released on December 3, 2025

New: Checkbox Component (rui_checkbox, f.rui_checkbox)

New checkbox component with support for single checkboxes, collections, and switch variants.

Variants

  • checkbox (default) - Standard checkbox with checkmark
  • switch - Toggle switch with smooth animations
  • card - Bordered card with full-width click target
  • pill - Compact, tag-like rounded selections
  • button - Toolbar-style toggle controls

Features

  • Single checkbox with label and description
  • Collection checkboxes from arrays or ActiveRecord relations
  • Select all functionality with indeterminate state
  • Form builder integration (f.rui_checkbox)
  • Required field indicator with asterisk
  • Help text and error message display
  • Vertical and horizontal layouts
  • 5 sizes (xs, sm, base, lg, xl)
  • 2 shapes (square, rounded)
  • All semantic colors + Tailwind colors
  • Stimulus controller for select all interactivity
  • Dark mode support

Accessibility

  • Proper label association with for attribute
  • aria-describedby for help text
  • aria-required for required fields
  • aria-invalid for validation errors
  • role="group" with aria-labelledby for collections
  • Keyboard navigation support
<%# Single checkbox %>
<%= rui_checkbox(name: "terms", label: "I agree to terms") %>

<%# Switch variant %>
<%= rui_checkbox(name: "notifications", label: "Enable notifications", variant: :switch) %>

<%# Collection with form builder %>
<%= form_with model: @user do |f| %>
  <%= f.rui_checkbox :interests, collection: ["Sports", "Music", "Art"] %>
<% end %>

<%# With select all %>
<%= rui_checkbox(name: "categories[]", collection: @categories, select_all: true) %>

View Checkbox Component Documentation →

v0.8.0

Alert

Released on December 2, 2025

New: Alert Component (rui_alert, rui_alert_turbo)

New contextual feedback message component for user notifications.

Types & Variants

  • Types: default, info, success, warning, danger, error, primary
  • Variants: solid, soft, outline
  • Sizes: xs, sm, base, lg, xl
  • Shapes: square, rounded, pill

Features

  • Dismissible alerts with close button
  • Auto-dismiss with synchronized countdown timer and progress bar
  • Pause/resume on hover for auto-dismiss alerts
  • Undo action support with automatic countdown (for soft-delete patterns)
  • Countdown buffer for better UX (shows 3s when actual is 5s)
  • Clickable alerts with Turbo navigation support
  • Single or multiple messages support
  • Border accent positions (left, top, bottom, all)
  • Custom icon slot (default icons per type)
  • Action buttons slot
  • Enter/exit animations
  • Full accessibility with ARIA attributes
<%# Basic usage %>
<%= rui_alert(:success, title: "Success!") do %>
  Your changes have been saved.
<% end %>

<%# Dismissible with auto-dismiss %>
<%= rui_alert(:info, dismissible: true, auto_dismiss: true) do %>
  This will disappear in 5 seconds. Hover to pause.
<% end %>

<%# Undo action (great for delete operations) %>
<%= rui_alert(:warning, title: "Post deleted", undo_url: undo_post_path(@post)) do %>
  Click undo to restore.
<% end %>

<%# In Turbo Stream responses %>
<%= turbo_stream.prepend "flash" do %>
  <%= rui_alert_turbo(:success, messages: "Saved!") %>
<% end %>

View Alert Component Documentation →

v0.7.0

Accordion

Released on December 1, 2025

New: Accordion Component (rui_accordion)

New collapsible content sections component with smooth animations.

Variants & Options

  • Variants: default, bordered, separated, flush, ghost
  • Sizes: xs, sm, base, lg, xl
  • Shapes: none, rounded, square, pill
  • Colors: All semantic colors (zinc, primary, success, warning, danger, info)

Features

  • Multiple collapsible items with headers and content
  • Single or multiple open items (exclusive mode)
  • Smooth expand/collapse animations
  • Icon support in headers (leading and trailing positions)
  • Subtitle support for additional context
  • Custom expand/collapse icons (plus/minus swap)
  • Chevron position control (left or right)
  • Dividers between items
  • Always-open (non-collapsible) items
  • Turbo Frame support for lazy loading content
  • Keyboard navigation support
  • Full accessibility with ARIA attributes
<%# Basic usage %>
<%= rui_accordion do |accordion| %>
  <% accordion.with_item(title: "Section 1") do %>
    Content for section 1
  <% end %>
  <% accordion.with_item(title: "Section 2") do %>
    Content for section 2
  <% end %>
<% end %>

<%# With icons and expanded item %>
<%= rui_accordion(color: :primary, variant: :bordered) do |accordion| %>
  <% accordion.with_item(title: "Settings", icon: :settings, expanded: true) do %>
    Settings content
  <% end %>
<% end %>

<%# Multiple items can be open %>
<%= rui_accordion(exclusive: false) do |accordion| %>
  <% accordion.with_item(title: "Item 1") { "Content 1" } %>
  <% accordion.with_item(title: "Item 2") { "Content 2" } %>
<% end %>

View Accordion Component Documentation →

v0.6.0

Avatar

Released on November 30, 2025

New: Avatar Component (rui_avatar)

New versatile avatar component for displaying user profile images, initials, or placeholder icons.

Content Types

  • Image display with automatic fallback to initials or icon
  • Auto-generated initials from full names ("John Doe" → "JD")
  • Custom initials override
  • Fallback user icon when no image or name provided

Social Media Platform Sizes

  • Instagram: :ig_profile, :ig_story, :ig_post, :ig_comment
  • X/Twitter: :x_profile, :x_tweet, :x_reply
  • LinkedIn: :linkedin_profile, :linkedin_post, :linkedin_message
  • Discord: :discord_avatar, :discord_profile, :discord_server
  • GitHub: :github_avatar, :github_profile, :github_contrib
  • Plus: Facebook, YouTube, Slack, Twitch, TikTok, WhatsApp, Telegram, Dribbble, Behance, Pinterest

Features

  • Shapes: Circle (default), rounded, square
  • Ring Styles: White, gray, black, primary, success, warning, danger, Instagram story/live
  • Status Indicators: Online, offline, busy, away, dnd, streaming, idle, invisible
  • Clickable avatars with link to user profiles
  • Avatar groups with proper z-index stacking
  • Full accessibility with ARIA roles and labels
<%# Basic usage %>
<%= rui_avatar(src: user.avatar_url, alt: user.name) %>
<%= rui_avatar(name: "John Doe") %>

<%# Platform-specific sizes %>
<%= rui_avatar(src: url, size: :ig_story, ring: :ig_story) %>
<%= rui_avatar(src: url, size: :discord_avatar, status: :online) %>

<%# Avatar group %>
<div class="flex">
  <%= rui_avatar(src: url1, ring: :white, group_position: 1) %>
  <%= rui_avatar(src: url2, ring: :white, group_position: 2) %>
  <%= rui_avatar(src: url3, ring: :white, group_position: 3) %>
</div>

View Avatar Component Documentation →

v0.5.0

Text & TextFmt

Released on November 26, 2025

New: Text Component (rui_text)

Comprehensive typography component for headings, paragraphs, and inline text.

  • Full semantic HTML support (h1-h6, p, span, div, section, article, blockquote)
  • Complete typography control (size, weight, color, alignment, font family)
  • Visual variants (solid, outline, ghost, soft, link, strong, subtle)
  • Icon support with leading/trailing positions
  • 5 beautiful gradient styles: sunset, ocean, forest, sunrise, aurora
  • Blockquote support with citations
  • Prose mode for long-form content
  • Responsive headings that scale on larger screens

New: TextFmt Component (rui_text_fmt)

Rails text formatting helpers wrapped in typography component.

  • Text truncation with smart ellipsis
  • Text highlighting for search terms
  • HTML sanitization for user-generated content
  • Number formatting (currency, percentage, human-readable, phone)
  • Time formatting ("X ago" style timestamps)
  • Pluralization with count support
  • Auto-linkify URLs and emails
  • Default fallback for nil/empty values

View Text Component Documentation →

v0.4.0

Badge

Released on November 23, 2025

New: Badge Component (rui_badge)

  • Full Stimulus controller integration for dismissible badges
  • Pulsing animation support
  • Counter display
  • Icon support (leading/trailing positions)
  • Close button functionality
  • All variants (solid, outline, ghost, soft)
  • All sizes and shapes

Link Component Navigation Variant

  • New :nav variant for sidebar and navigation menus
  • Automatic current page detection (no manual checks required)
  • Color-themed navigation support
  • Block-level rendering with appropriate padding
<%# Clean, automatic navigation links %>
<%= rui_link(docs_button_path, "Button", variant: :nav) %>
<%= rui_link(docs_link_path, "Link", variant: :nav, color: :sky) %>

Bug Fixes

  • License re-activation when license key changes (renewals)
  • Icon component default size changed to :sm

View Badge Component Documentation →

v0.3.0

Link

Released on November 20, 2025

New: Link Component (rui_link)

Styled link elements with Rails link_to syntax and features.

  • Conditional rendering support (if:, unless:, unless_current:)
  • Full Turbo integration (frames, streams, methods, prefetch)
  • External link security (automatic target="_blank")
  • Icon slot support with color inheritance/override
  • Active state highlighting for navigation
  • Text truncation with automatic tooltips
  • Email links (mail_to compatibility): subject, body, cc, bcc, reply_to
  • Phone links (phone_to compatibility): country_code
  • SMS links (sms_to compatibility): body, country_code
  • Underline variants (hover, animated, none)
<%# Basic link %>
<%= rui_link("/posts", "View Posts", color: :primary) %>

<%# Conditional rendering %>
<%= rui_link("/admin", "Admin Panel", if: admin?) %>

<%# External link with security %>
<%= rui_link("https://github.com", "GitHub", external: true) %>

<%# Email with all options %>
<%= rui_link(email: "contact@example.com", subject: "Inquiry", text: "Contact Sales") %>

Icon Color Override

Icons now automatically inherit parent component color by default with ability to override.

View Link Component Documentation →

v0.2.0

Icon & Social

Released on November 19, 2025

New: Icon Component (rui_icon)

  • Lucide icon integration with 1500+ icons
  • Size options: xs, sm, base, lg, xl, xl2-xl6
  • Color customization with full Tailwind palette
  • Position support: leading/trailing for flex layouts
  • Standalone vs inherited color modes
  • ARIA labels with auto-generation

New: Social Button Component (rui_social_button)

  • Pre-styled buttons for 18+ platforms
  • Auth: Google, GitHub, Facebook, Apple, Twitter/X, LinkedIn, Discord
  • Payments: PayPal, Stripe, Apple Pay
  • Official brand colors and styling
  • Icon-only mode with accessibility
  • Full width option
<%= rui_icon(:heart, size: :lg, color: :danger) %>
<%= rui_social_button(:google, path: "/auth/google") %>
<%= rui_social_button(:paypal, "Pay with PayPal", path: checkout_path, method: :post) %>

Enhanced: Button with Icon Slot

  • Added with_icon slot support
  • Multiple icons (leading + trailing)
  • Icon-only button mode

View Social Button Component Documentation →

v0.1.0

Initial Release

Released on November 18, 2025

Button Component (rui_button)

  • Auto-detects button type (type="button" standalone, type="submit" in forms)
  • Auto-generates labels in forms ("Create Post" / "Update Post")
  • FormBuilder integration (f.rui_button)
  • Multiple submit buttons with name and value attributes
  • HTML5 form attributes: formaction, formtarget, form_id, formnovalidate
  • Block content support for custom layouts
  • Variants: solid, outline, ghost, soft
  • Sizes: xs, sm, base, md, lg, xl
  • Shapes: square, rounded, pill, circle
  • Full color palette support (semantic + Tailwind)
  • Loading and disabled states with ARIA

ButtonTo Component (rui_button_to)

  • Creates <form><button></form> wrapper automatically
  • HTTP method spoofing (POST, PATCH, PUT, DELETE)
  • CSRF token protection (automatic)
  • Hidden params support
  • Turbo/AJAX support
  • Shares all styling options with Button

Core Features

  • ViewComponent-based architecture
  • Pure Tailwind CSS (no custom CSS)
  • Zero JavaScript dependencies
  • Dark mode support
  • Turbo/Stimulus compatible
  • WCAG AA accessible

View Button Component Documentation →