Textarea
Multi-line text input component with character counting, auto-resize, and real-time validation.
Key Features
- 3 Variants - Default, Filled, Outline
- 5 Sizes - xs, sm, base, lg, xl
- 3 Shapes - Square, Rounded, Pill
- All Colors - Semantic + any Tailwind color
- Character Counter - Live character count with maxlength tracking
- Auto-resize - Automatically grows/shrinks with content
- Real-time Validation - HTML5 Constraint Validation API with visual feedback
- Form Builder - Full Rails form integration (
f.rui_textarea) - Full Accessibility - ARIA attributes, proper labeling
- JavaScript API - Programmatic control with
data-actionattributes
Basic Usage
A simple multi-line text area with label and help text.
Share your thoughts and ideas
<%= rui_textarea(:content,
label: "Post Content",
placeholder: "Write your post content here...",
help_text: "Share your thoughts and ideas",
rows: 5,
color: :primary
) %>
Variants
Three visual styles to match your design system.
<%= rui_textarea(:text, variant: :default) %>
<%= rui_textarea(:text, variant: :filled) %>
<%= rui_textarea(:text, variant: :outline) %>
Sizes
Five size options with different text sizes and padding.
<%= rui_textarea(:text, size: :xs) %>
<%= rui_textarea(:text, size: :sm) %>
<%= rui_textarea(:text, size: :base) %>
<%= rui_textarea(:text, size: :lg) %>
<%= rui_textarea(:text, size: :xl) %>
Shapes
Three border radius options to match your design aesthetic.
<%= rui_textarea(:text, shape: :square) %>
<%= rui_textarea(:text, shape: :rounded) %>
<%= rui_textarea(:text, shape: :pill) %>
Colors
Semantic colors and Tailwind color support for focus rings and validation states.
Semantic Colors
<%= rui_textarea(:text, color: :primary) %>
<%= rui_textarea(:text, color: :success) %>
<%= rui_textarea(:text, color: :danger) %>
Tailwind Colors
Use any Tailwind color directly for custom focus ring colors.
Character Counter
Display live character count with show_count: true. Automatically shows "X / Y" format when maxlength is set.
Keep it concise
0 / 200 characters
Counter shows total characters
0 characters
<%# With maxlength - shows "X / 200" format %>
<%= rui_textarea(:bio,
label: "Bio",
maxlength: 200,
show_count: true,
help_text: "Keep it concise"
) %>
<%# Without maxlength - shows "X characters" %>
<%= rui_textarea(:notes,
show_count: true,
help_text: "Counter shows total characters"
) %>
Note: When both help_text and show_count are present, they appear on the same line (help text left, counter right).
Auto-resize
Automatically grows and shrinks with content using auto_resize: true. Respects rows as minimum height and optional max_rows.
Grows with content, shrinks when deleted
Limited to 8 rows maximum
<%# Basic auto-resize %>
<%= rui_textarea(:comment,
label: "Comment",
rows: 3,
auto_resize: true,
help_text: "Grows with content"
) %>
<%# With max_rows constraint %>
<%= rui_textarea(:feedback,
label: "Feedback",
rows: 3,
auto_resize: true,
max_rows: 8,
help_text: "Limited to 8 rows"
) %>
Auto-resize Behavior: When auto_resize: true, manual resize is automatically disabled (resize: :none). The textarea grows/shrinks dynamically based on content.
Resize Control
Control the user's ability to manually resize the textarea with the resize: parameter.
<%= rui_textarea(:text, resize: :none) %>
<%= rui_textarea(:text, resize: :vertical) %>
<%= rui_textarea(:text, resize: :horizontal) %>
<%= rui_textarea(:text, resize: :both) %>
Real-time Validation
Built-in validation using HTML5 Constraint Validation API with visual feedback.
Leave blank and click outside to see validation
Type less than 10 chars to see validation
0 / 100 characters
<%# Required validation %>
<%= rui_textarea(:feedback,
label: "Required Field",
required: true,
help_text: "This field is required"
) %>
<%# Length validation %>
<%= rui_textarea(:description,
label: "Description",
minlength: 10,
maxlength: 100,
show_count: true,
help_text: "Between 10 and 100 characters"
) %>
Validation Feedback: Border turns green when valid, red when invalid. Error messages display below the textarea automatically.
States
Disabled, readonly, and required states for different use cases.
Disabled state
Readonly state
Required state - shows asterisk in label
<%= rui_textarea(:text, disabled: true) %>
<%= rui_textarea(:text, readonly: true) %>
<%= rui_textarea(:text, required: true) %>
Form Builder Integration
Use with Rails form builder for automatic object binding and validation.
<%= form_with model: @post do |f| %>
<%# Basic textarea %>
<%= f.rui_textarea(:body,
label: "Post Content",
placeholder: "Write your post...",
rows: 8,
help_text: "Main content of your post"
) %>
<%# With character counter %>
<%= f.rui_textarea(:excerpt,
label: "Excerpt",
maxlength: 200,
show_count: true,
rows: 3,
help_text: "Brief summary"
) %>
<%# With auto-resize %>
<%= f.rui_textarea(:notes,
label: "Notes",
rows: 3,
auto_resize: true,
max_rows: 10,
help_text: "Grows with content"
) %>
<%= f.rui_button %>
<% end %>
| Rails Helper | rui_textarea Equivalent |
|---|---|
f.text_area |
f.rui_textarea(:method) |
Live Examples
See f.rui_textarea in action with real Rails forms and Turbo integration.
Accessibility
The Textarea component follows WAI-ARIA best practices for form controls.
ARIA Attributes
-
Help text and validation linked via
aria-describedby -
Error states include
aria-invalid="true" -
Required fields include
aria-required="true"
Keyboard Navigation
- Tab moves focus between textareas
- Focus states are clearly visible with ring styles
- Auto-resize maintains scrollable content access
Semantic HTML
-
Uses native
<textarea>element -
Labels use
forattribute linked to textareaid - Required indicator shows visual asterisk in label
Screen Reader Support
- Character count is announced when nearing limit
- Validation errors are announced on input
- Help text provides additional context when focused
JavaScript API
The textarea uses the textarea-validation Stimulus controller for real-time validation, character counting, and auto-resize.
Stimulus Actions
Trigger textarea behavior from any element:
| Action | Description |
|---|---|
textarea-validation#validate |
Validate the textarea and show visual feedback (green/red border) |
textarea-validation#updateCounter |
Update the character counter display |
textarea-validation#autoResize |
Resize the textarea based on content (when auto-resize enabled) |
Controller Values
Configure the controller behavior:
| Value | Type | Default | Description |
|---|---|---|---|
autoResize |
Boolean | false |
Enable auto-resize behavior |
minRows |
Number | 4 |
Minimum number of rows (from rows attribute) |
maxRows |
Number | — | Maximum rows before scrolling |
maxlength |
Number | — | Maximum character length for counter |
Programmatic Control
Control the textarea directly via Stimulus controller:
// Get the controller instance
const element = document.querySelector('[data-controller="textarea-validation"]')
const controller = this.application.getControllerForElementAndIdentifier(element, 'textarea-validation')
// Trigger validation programmatically
controller.validate()
// Update character counter
controller.updateCounter()
// Trigger auto-resize
controller.autoResize()
// Access validation state
const textarea = controller.textareaTarget
if (textarea.validity.valid) {
console.log('Textarea is valid')
} else {
console.log('Validation error:', textarea.validationMessage)
}
Note: The textarea validation uses the HTML5 Constraint Validation API (validity, validationMessage). This means validation constraints like required, minlength, and maxlength work automatically via HTML attributes.
API Reference
rui_textarea
Multi-line text input with auto-resize and character counter
| Parameter | Type | Default | Description |
|---|---|---|---|
| name_or_method* | Symbol/String | — | Positional first arg - name for standalone, method for form builder |
| value | String | — | Textarea content |
| placeholder | String | — | Placeholder text |
Appearance
Visual styling options
| Parameter | Type | Default | Description |
|---|---|---|---|
| variant | Symbol |
:default
|
Visual style
:default
:filled
:outline
|
| color | Symbol |
:default
|
Focus ring color - semantic or any Tailwind color |
| size | Symbol |
:base
|
Textarea size
:xs
:sm
:base
:lg
:xl
|
| shape | Symbol |
:rounded
|
Border radius
:square
:rounded
:pill
|
Sizing
Height and resize options
| Parameter | Type | Default | Description |
|---|---|---|---|
| rows | Integer |
3
|
Number of visible text lines |
| min_rows | Integer | — | Minimum rows for auto-resize |
| max_rows | Integer | — | Maximum rows for auto-resize |
| auto_resize | Boolean |
false
|
Auto-resize height based on content |
| resize | Symbol |
:vertical
|
Manual resize behavior
:none
:vertical
:horizontal
:both
|
Character Counter
Character count and limit options
| Parameter | Type | Default | Description |
|---|---|---|---|
| maxlength | Integer | — | Maximum character limit (enables counter) |
| show_counter | Boolean |
false
|
Show character counter without limit |
| counter_warning | Integer | — | Percentage at which counter turns warning color |
Labels & Text
Text options
| Parameter | Type | Default | Description |
|---|---|---|---|
| label | String | — | Label text displayed above textarea |
| help_text | String | — | Help text displayed below textarea |
States
State options
| Parameter | Type | Default | Description |
|---|---|---|---|
| required | Boolean |
false
|
Show required indicator (*) |
| disabled | Boolean |
false
|
Disable the textarea |
| readonly | Boolean |
false
|
Make textarea read-only |
Form Builder
Options when used with Rails form builder (f.rui_textarea)
| Parameter | Type | Default | Description |
|---|---|---|---|
| form | FormBuilder | — | Rails form builder instance |
| object | Object/Symbol | — | Object to bind textarea to |