Checkbox
Versatile checkbox component for single selections, collections, and toggle switches.
Key Features
- 5 Variants - Checkbox, Switch, Card, Pill, Button
- Icon Support - Add icons with
with_iconslot - Single & Collections - Single checkbox or multiple from arrays/ActiveRecord
- Select All - Built-in select all with indeterminate state
- Smart Labels - Auto-derives label from model attribute name in form mode
- Unique IDs - Includes record ID for safe use in lists and repeated forms
- Auto-Submit - CSP-safe form submission on change via Stimulus
- Input HTML - Pass attributes directly to the
<input>element - Strikethrough - Line-through + muted color on check for todo/task lists
- Label Class - Custom CSS classes on the label element
- Form Builder - Full Rails form integration (
f.rui_checkbox) - 5 Sizes - xs, sm, base, lg, xl
- 2 Shapes - Square or rounded corners
- All Colors - Semantic + any Tailwind color
- Full Accessibility - ARIA attributes, keyboard navigation
- JavaScript API - Programmatic control with
data-actionattributes
Basic Usage
Simple checkbox with label and optional help text. Use the positional first argument for clean, Rails-like syntax.
<%= rui_checkbox(:terms_accepted, label: "I accept the terms and conditions") %>
<%= rui_checkbox(:newsletter,
label: "Subscribe to newsletter",
help_text: "We'll send you weekly updates"
) %>
We'll send you weekly updates
Colors
Supports all Tailwind colors via ColorBuilderHelper - semantic colors plus any Tailwind color.
Semantic Colors
<%= rui_checkbox(object: :demo, method: :opt1, label: "Primary", color: :primary, checked: true) %>
<%= rui_checkbox(object: :demo, method: :opt2, label: "Success", color: :success, checked: true) %>
<%= rui_checkbox(object: :demo, method: :opt3, label: "Warning", color: :warning, checked: true) %>
<%= rui_checkbox(object: :demo, method: :opt4, label: "Danger", color: :danger, checked: true) %>
Tailwind Colors
Use any Tailwind color directly - indigo, pink, violet, teal, and more!
<%= rui_checkbox(object: :demo, method: :opt1, label: "Indigo", color: :indigo, checked: true) %>
<%= rui_checkbox(object: :demo, method: :opt2, label: "Pink", color: :pink, checked: true) %>
<%= rui_checkbox(object: :demo, method: :opt3, label: "Violet", color: :violet, checked: true) %>
<%= rui_checkbox(object: :demo, method: :opt4, label: "Teal", color: :teal, checked: true) %>
Tip: Colors are generated dynamically using ColorBuilderHelper. This ensures consistency across all components and supports any color from the Tailwind palette.
Sizes
Five size options from extra small to extra large.
<%= rui_checkbox(object: :demo, method: :xs, label: "Extra Small", size: :xs, checked: true) %>
<%= rui_checkbox(object: :demo, method: :sm, label: "Small", size: :sm, checked: true) %>
<%= rui_checkbox(object: :demo, method: :base, label: "Base (default)", size: :base, checked: true) %>
<%= rui_checkbox(object: :demo, method: :lg, label: "Large", size: :lg, checked: true) %>
<%= rui_checkbox(object: :demo, method: :xl, label: "Extra Large", size: :xl, checked: true) %>
Shapes
Square or rounded corner styles for checkbox inputs.
<%= rui_checkbox(object: :demo, method: :rounded, label: "Rounded (default)", shape: :rounded) %>
<%= rui_checkbox(object: :demo, method: :square, label: "Square", shape: :square) %>
Note: The shape option only applies to the checkbox variant. Switch variant is always fully rounded.
Switch Variant
Toggle switch style for on/off settings.
<%= rui_checkbox(
object: :settings,
method: :dark_mode,
label: "Enable Dark Mode",
variant: :switch,
color: :primary
) %>
<%= rui_checkbox(
object: :settings,
method: :notifications,
label: "Push Notifications",
variant: :switch,
color: :success,
checked: true
) %>
Switch Sizes
Card Variant
Bordered cards with full-width click targets. Perfect for feature selection, pricing plans, or subscription preferences.
<%= rui_checkbox(
object: :subscription,
method: :newsletter,
label: "Newsletter",
description: "Get the latest updates and offers.",
variant: :card,
color: :primary,
checked: true
) do |cb|
cb.with_icon(:newspaper)
end %>
Subscription Preferences
Simple Cards (Without Icons)
Card Sizes
Pill Variant
Compact, tag-like selections. Perfect for filters, categories, or tags.
<div class="flex flex-wrap gap-2">
<%= rui_checkbox(variant: :pill, label: "Ruby", color: :red, checked: true) %>
<%= rui_checkbox(variant: :pill, label: "Rails", color: :rose) %>
<%= rui_checkbox(variant: :pill, label: "JavaScript", color: :yellow) %>
<%= rui_checkbox(variant: :pill, label: "TypeScript", color: :blue) %>
</div>
Pill Sizes
Collections
Render multiple checkboxes from an array or ActiveRecord collection.
<%= rui_checkbox(
object: @user,
method: :category_ids,
collection: Category.all,
label: "Select Categories",
help_text: "Choose one or more categories"
) %>
<%= rui_checkbox(
object: @user,
method: :role_ids,
collection: Role.all,
value_method: :id,
text_method: :name,
label: "Assign Roles"
) %>
Choose one or more categories
Horizontal Layout
<%= rui_checkbox(
object: @user,
method: :interests,
collection: Interest.all,
layout: :horizontal,
label: "Select Interests"
) %>
Select All
Enable a "Select All" checkbox for collections with automatic indeterminate state.
<%= rui_checkbox(
object: @user,
method: :permission_ids,
collection: Permission.all,
select_all: true,
label: "Assign Permissions"
) %>
Click 'Select All' or choose individual permissions
Indeterminate State: When some (but not all) items are checked, the "Select All" checkbox shows an indeterminate state (a dash instead of checkmark).
Descriptions
Add descriptions to individual checkboxes or collection items.
<%= rui_checkbox(
object: :user,
method: :marketing,
label: "Marketing Emails",
description: "Receive promotional offers and product updates"
) %>
<%= rui_checkbox(
object: @user,
method: :plan_id,
collection: Plan.all,
text_method: :name,
description_method: :description,
label: "Select Plan"
) %>
Receive promotional offers and product updates
Get notified about account security events
States
Disabled and required states for checkboxes.
<%= rui_checkbox(object: :user, method: :locked, label: "Locked option", disabled: true) %>
<%= rui_checkbox(object: :user, method: :terms, label: "I agree to terms", required: true) %>
Smart Labels
In form mode, the checkbox automatically derives a label from the model attribute name when no explicit label is provided.
<%= form_with model: @user do |f| %>
<%= f.rui_checkbox(:terms_accepted) %>
<%= f.rui_checkbox(:terms_accepted, label: "I agree to the Terms of Service") %>
<%= f.rui_checkbox(:featured, label: false) %>
<% end %>
Label resolution priority:
Explicit label → label: false (suppresses) → human_attribute_name (ActiveRecord) → humanize (fallback) → "Checkbox" (standalone default).
Unique IDs
When the checkbox is bound to a persisted object (one with an id), the record ID is included in the generated id and for attributes. This prevents ID collisions when rendering multiple checkboxes for different records on the same page.
<%= form_with model: @user do |f| %>
<%= f.rui_checkbox(:completed, label: "Done") %>
<% end %>
<%= form_with model: @user do |f| %>
<%= f.rui_checkbox(:category_ids, collection: Category.all) %>
<% end %>
| Mode | Generated ID |
|---|---|
| Form with persisted object (id: 42) | user_42_completed |
| Form with new object (no id) | user_completed |
| Collection item (id: 42, value: 1) | user_42_category_ids_1 |
| Standalone | terms |
Strikethrough
Enable strikethrough: true to add a line-through and muted color to the label when checked. Perfect for todo lists, task trackers, and shopping lists.
<%= rui_checkbox(object: :todo, method: :completed,
label: "Buy groceries",
strikethrough: true,
checked: true
) %>
<%= rui_checkbox(object: :todo, method: :laundry,
label: "Do laundry",
strikethrough: true
) %>
How it works: Uses pure CSS group-has-[:checked] — when the checkbox inside the .group wrapper is checked, the label gets line-through and a muted color. The color change is animated with transition-all duration-300. No JavaScript required.
Label Class
Use label_class: to append custom CSS classes to the label element. Works alongside all other label features.
<%= rui_checkbox(object: :demo, method: :custom,
label: "Custom styled label",
label_class: "text-lg italic"
) %>
<%= rui_checkbox(object: :todo, method: :task,
label: "Important task",
strikethrough: true,
label_class: "font-bold"
) %>
Auto-Submit
Enable auto_submit: true to automatically submit the parent form when the checkbox changes. Uses a CSP-safe Stimulus data-action instead of inline JavaScript.
<%= form_with model: @todo, url: todo_path(@todo), method: :patch do |f| %>
<%= f.rui_checkbox(:completed, auto_submit: true) %>
<% end %>
<%= form_with model: @settings do |f| %>
<%= f.rui_checkbox(:notifications, variant: :switch, auto_submit: true) %>
<% end %>
How it works: Adds data-controller="checkbox" to the wrapper and data-action="change->checkbox#submitForm" to the input.
The Stimulus controller calls form.requestSubmit() on the closest parent form. If no form exists, it does nothing gracefully.
Input HTML
Pass attributes directly to the underlying <input> element using the input_html option. Useful for adding custom data attributes, Stimulus actions, or CSS classes to the input itself (not the wrapper).
<%= rui_checkbox(:terms, label: "I agree",
input_html: { data: { turbo: false } }
) %>
<%= f.rui_checkbox(:completed,
auto_submit: true,
input_html: { data: { action: "change->analytics#track" } }
) %>
<%= rui_checkbox(:dark_mode, label: "Dark Mode",
input_html: { class: "custom-toggle" }
) %>
Merge behavior: data-action and data-controller values are space-concatenated with internal Stimulus values (not overwritten). class is appended. All other attributes overwrite.
Rails-Compatible API
rui_checkbox accepts standard Rails positional argument patterns for collection checkboxes in addition to the keyword API.
<!-- Simple array -->
<%= f.rui_checkbox(:category_ids, ["Tech", "Design", "Business"]) %>
<!-- Array of [text, value] pairs -->
<%= f.rui_checkbox(:category_ids, [["Tech", 1], ["Design", 2], ["Business", 3]]) %>
<!-- ActiveRecord collection with value and text methods -->
<%= f.rui_checkbox(:category_ids, Category.all, :id, :name) %>
<!-- With additional options -->
<%= f.rui_checkbox(:category_ids, Category.all, :id, :name, label: "Categories") %>
<%= rui_checkbox(:category_ids, Category.all, :id, :name, label: "Categories") %>
Priority rule: When both positional choices and the collection: keyword are provided, the collection: keyword always wins. Single checkboxes (no collection) are unaffected.
Form Builder Integration
Use with Rails form builder for automatic object binding and validation.
<%= form_with model: @user do |f| %>
<%= f.rui_checkbox(:terms_accepted) %>
<%= f.rui_checkbox(:newsletter, label: "Subscribe to updates", color: :primary) %>
<%= f.rui_checkbox(:completed, auto_submit: true) %>
<%= f.submit "Sign Up" %>
<% end %>
Note: When using f.rui_checkbox, the checked state is automatically detected from the form object, labels are derived from the model attribute name, and IDs include the record ID for uniqueness.
Rails Integration
rui_checkbox provides a styled alternative to Rails ActionView checkbox helpers with additional features like variants, colors, and collections with select all.
Comparison with Rails Helpers
Here's how rui_checkbox compares to standard Rails helpers:
| Rails Helper | rui_checkbox Equivalent |
|---|---|
f.check_box |
f.rui_checkbox(:method) |
check_box(:obj, :method) |
rui_checkbox(object: :obj, method: :method) |
check_box_tag(:name) |
rui_checkbox(name: :name) |
f.collection_check_boxes |
f.rui_checkbox(:method, collection: items) |
Single Boolean Field
For boolean attributes on a model:
<%= f.rui_checkbox(:featured,
label: "Featured Post",
description: "Display prominently on homepage",
color: :primary
) %>
Collection Checkboxes
For has_many associations or array selections:
<%= f.rui_checkbox(:category_ids,
collection: Category.all,
value_method: :id,
text_method: :name,
select_all: true,
label: "Categories",
color: :primary
) %>
Real-World Example: Post Form
See the checkbox component in action on the New Post and Posts pages.
<%= form_with model: @post do |f| %>
<%= f.rui_checkbox(:featured,
description: "Display this post prominently",
color: :primary
) %>
<%= f.rui_checkbox(:notify_subscribers,
variant: :switch,
color: :success,
auto_submit: true
) %>
<%= f.rui_checkbox(:allow_comments,
help_text: "Visitors can comment on this post",
color: :info
) %>
<%= f.rui_button(color: :success) %>
<% end %>
Pro Tip: rui_checkbox automatically generates the hidden field that Rails uses for unchecked checkboxes, ensuring proper form submission with boolean values.
Accessibility
The Checkbox component follows WAI-ARIA best practices for form controls.
ARIA Attributes
-
Help text linked via
aria-describedbyfor context -
Required fields include
aria-required="true" -
Error states include
aria-invalid="true" -
Checkbox groups use
role="group"witharia-labelledby
Keyboard Navigation
- Tab moves focus between checkboxes
- Space toggles the checkbox state
- Focus states are clearly visible with ring styles
Semantic HTML
-
Uses native
<input type="checkbox">elements -
Labels use
forattribute linked to inputid(unique per record) -
Indeterminate state properly communicates partial selection via
indeterminateproperty -
Auto-submit uses CSP-safe Stimulus
data-actioninstead of inline JavaScript
Screen Reader Support
- Checkbox state is announced as "checked", "not checked", or "mixed" (indeterminate)
- Error messages are announced when validation fails
- Help text provides additional context when focused
JavaScript API
The Checkbox component provides two Stimulus controllers for interactive features.
Checkbox Controller
Handles Select All functionality, indeterminate state, and auto-submit:
| Action | Description |
|---|---|
checkbox#toggleAll |
Toggles all item checkboxes based on select-all state |
checkbox#updateSelectAll |
Updates select-all checkbox state (checked/indeterminate/unchecked) |
checkbox#submitForm |
Submits the closest parent form (used by auto_submit: true). Does nothing if no form exists. |
<div data-controller="checkbox">
<input type="checkbox"
data-checkbox-target="selectAll"
data-action="change->checkbox#toggleAll">
<label>Select All</label>
<input type="checkbox"
data-checkbox-target="item"
data-action="change->checkbox#updateSelectAll">
<input type="checkbox"
data-checkbox-target="item"
data-action="change->checkbox#updateSelectAll">
</div>
Checkbox Switch Controller
Handles the switch/toggle visual animation:
| Action | Description |
|---|---|
checkbox-switch#updateThumbPosition |
Updates thumb position based on checked state |
Programmatic Control
Control checkboxes from JavaScript:
// Get the checkbox controller (for select-all functionality)
const container = document.querySelector('[data-controller="checkbox"]')
const checkboxController = application.getControllerForElementAndIdentifier(
container,
"checkbox"
)
// Update select-all state after programmatic changes
checkboxController.updateSelectAllState()
// Toggle all items programmatically
const selectAll = container.querySelector('[data-checkbox-target="selectAll"]')
selectAll.checked = true
selectAll.dispatchEvent(new Event("change"))
API Reference
rui_checkbox
Versatile checkbox with 5 variants (checkbox, switch, card, pill, button), collections, select all, smart labels, unique IDs, and auto-submit
| Parameter | Type | Default | Description |
|---|---|---|---|
| name_or_method | Symbol/String | — | Positional first arg - name for standalone, method for form builder |
| label | String/false | — | Label text for single checkbox or legend for collection. Pass false to suppress label. |
| description | String | — | Description text displayed below label |
| help_text | String | — | Help text displayed below checkbox/group |
Appearance
Visual styling options
| Parameter | Type | Default | Description |
|---|---|---|---|
| variant | Symbol |
:checkbox
|
Visual variant style
:checkbox
:switch
:card
:pill
:button
|
| color | Symbol |
:primary
|
Checked state color - semantic or any Tailwind color |
| size | Symbol |
:base
|
Checkbox size
:xs
:sm
:base
:lg
:xl
|
| shape | Symbol |
:rounded
|
Corner style (checkbox variant only)
:square
:rounded
|
| layout | Symbol |
:vertical
|
Layout for collections
:vertical
:horizontal
|
States
Checkbox state options
| Parameter | Type | Default | Description |
|---|---|---|---|
| checked | Boolean | — | Explicit checked state (overrides object value) |
| disabled | Boolean |
false
|
Disable the checkbox |
| required | Boolean |
false
|
Show required indicator (*) |
Behavior
Interactive behavior options
| Parameter | Type | Default | Description |
|---|---|---|---|
| auto_submit | Boolean |
false
|
Auto-submit the parent form when checkbox changes (CSP-safe via Stimulus) |
| strikethrough | Boolean |
false
|
Adds line-through + muted color to label when checked. Pure CSS via group-has-[:checked]. Checkbox variant only. |
| label_class | String | — | Custom CSS classes appended to the label element |
| input_html | Hash |
{}
|
Additional HTML attributes passed directly to the <input> element. Stimulus data-action and data-controller values are space-concatenated with internal ones. |
Values
Checked/unchecked value configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
| value | String |
"1"
|
Value when checkbox is checked |
| unchecked_value | String |
"0"
|
Value sent when unchecked (hidden field) |
Collections
Options for rendering multiple checkboxes from a collection
| Parameter | Type | Default | Description |
|---|---|---|---|
| collection | Array/ActiveRecord | — | Collection for multiple checkboxes |
| value_method | Symbol |
:id
|
Method to get value from collection items |
| text_method | Symbol |
:name
|
Method to get label text from collection items |
| description_method | Symbol | — | Method to get description from collection items |
| select_all | Boolean |
false
|
Show 'Select All' checkbox with indeterminate state |
Form Builder
Options when used with Rails form builder (f.rui_checkbox)
| Parameter | Type | Default | Description |
|---|---|---|---|
| form | FormBuilder | — | Rails form builder instance (auto-set by f.rui_checkbox) |
| object | Object/Symbol | — | Object to bind checkbox to |
| method | Symbol | — | Attribute name on the object (keyword alternative to positional) |
| name | String | — | Input name attribute (keyword alternative to positional) |
Slots
Content slots for customizing component parts
| Slot | Description |
|---|---|
| icon | Icon slot for button/pill/card variants via checkbox.with_icon(:name) |
JavaScript & Namespacing
Checkbox ships a Stimulus controller registered under the identifier checkbox.
If you set config.stimulus_namespace = "rui"
(
see guide
),
every emitted Stimulus attribute is prefixed: the identifier becomes rui--checkbox.
💡 Working with your own Stimulus controllers? Read Stimulus Namespace to keep the gem's controllers from colliding with yours.
JS registration (app/javascript/controllers/index.js)
import CheckboxController from "./rapid_rails_ui/checkbox_controller"
application.register("checkbox", CheckboxController)
import CheckboxController from "./rapid_rails_ui/checkbox_controller"
application.register("rui--checkbox", CheckboxController)
Custom trigger button
<button data-action="checkbox#open">Trigger</button>
<button data-action="rui--checkbox#open">Trigger</button>
<button data-action="<%= stimulus_action("<%= controller_id %>", "click->#open") %>">Trigger</button>