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

Basic Usage

A simple multi-line text area with label and help text.

Share your thoughts and ideas

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

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

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

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

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

Character Counter
<%# 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

Auto-resize
<%# 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.

Resize Control
<%= 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

Validation
<%# 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

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

Interactive Examples

Visit the Posts section to see textarea components in real forms with character counters, auto-resize, and validation.

New Post Edit Post

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 for attribute linked to textarea id
  • 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)
Using Stimulus Actions

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:

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

Related Components