Textarea
An intelligent multiline text input component built on MUI TextField. Ideal for longer freeform content like comments, descriptions, feedback, messages, and notes. Supports standalone usage, seamless DashForm integration with automatic field binding, validation error gating, and reactive visibility.
Quick Start
Copy & Paste
For multiline input—feedback, comments, descriptions, and long-form content.
import { Textarea } from '@dashforge/ui';
<Textarea label="Description" name="description" />Examples
Multiline text input patterns for feedback, comments, and descriptions
Basic
Multiline input for descriptions and longer content
<Textarea label="Description" name="description" />
With Placeholder
Guide users with placeholder text for feedback or comments
<Textarea label="Feedback" name="feedback" placeholder="Share your thoughts..." />
Custom Rows
Expand height for bios, detailed feedback, or longer text
<Textarea
label="Bio"
name="bio"
minRows={5}
/>With Helper Text
Provide context for optional comments or notes
Enter any additional comments (optional)
<Textarea label="Comments" name="comments" helperText="Enter any additional comments (optional)" />
Error State
Validation errors for required or length-constrained text
Message is required and must be at least 10 characters
<Textarea label="Message" name="message" error helperText="Message is required and must be at least 10 characters" />
Disabled
Read-only multiline content like terms or policies
<Textarea label="Terms & Conditions" name="terms" defaultValue="By using this service, you agree to our terms..." disabled />
Dashforge Capabilities
Progressive adoption from controlled components to predictive forms
Use Textarea as a controlled component, integrate with React Hook Form, or leverage reactive capabilities. Choose the adoption level that fits your workflow.
Controlled
Available Now
Controlled multiline input with standard React patterns. No proprietary lock-in—use familiar value/onChange.
Standard value and onChange props
No proprietary lock-in
Easy incremental adoption
<Textarea
value={description}
onChange={(e) => setDescription(e.target.value)}
label="Product description"
/>React Hook Form Ready
Integration-Friendly
Long-form input validation with React Hook Form. Automatic error handling for feedback, comments, and multiline fields.
Works through DashForm bridge
Validation and error handling supported
Fits existing RHF workflows
<DashForm>
<Textarea
name="feedback"
label="Your feedback"
rules={{
required: 'Feedback is required',
minLength: { value: 10, message: 'Min 10 chars' }
}}
/>
</DashForm>Reactive Visibility
Available Now
Conditional rendering for description fields. Show large text areas only when needed—issue details, explanations, notes.
Conditional rendering via visibleWhen
Engine evaluates the predicate
Useful for conditional descriptions and notes
<Textarea
name="additionalNotes"
label="Additional notes"
visibleWhen={(engine) =>
engine.getNode('needsExplanation')?.value === true
}
/>Access Control (RBAC)
Control field visibility and interaction based on user permissions. Fields can be hidden, disabled, or readonly when users lack access.
Hide when unauthorized
<Textarea
name="comments"
access={{
resource: 'document.comments',
action: 'read',
onUnauthorized: 'hide',
}}
/>Disable when cannot edit
<Textarea
name="feedback"
access={{
resource: 'ticket.feedback',
action: 'update',
onUnauthorized: 'disable',
}}
/>Readonly for view-only
<Textarea
name="description"
access={{
resource: 'project.description',
action: 'update',
onUnauthorized: 'readonly',
}}
/>Combined with visibleWhen
<Textarea
name="otherDetails"
visibleWhen={(engine) =>
engine.getNode('category')?.value === 'other'
}
access={{
resource: 'form.otherDetails',
action: 'read',
onUnauthorized: 'hide',
}}
/>Note: When combining visibleWhen with RBAC, both conditions must be satisfied. The field shows only if UI logic returns true AND the user has required permissions.
Form Integration
Real-world scenarios with React Hook Form and dynamic visibility
Live scenarios showing DashForm integration and reactive visibility in real form contexts.
React Hook Form Integration
Try it: Enter feedback and submit the form
Textarea integrates with React Hook Form through DashForm. Fields self-register, errors display after blur, and validation follows RHF patterns. Try submitting with empty fields or less than 10 characters.
import { DashForm } from '@dashforge/forms';
import { Textarea } from '@dashforge/ui';
function FeedbackForm() {
const handleSubmit = (data: FormData) => {
console.log('Feedback:', data);
};
return (
<DashForm
defaultValues={{
feedback: '',
suggestions: '',
experience: ''
}}
onSubmit={handleSubmit}
mode="onBlur"
>
<Textarea
name="feedback"
label="Your feedback"
placeholder="Tell us what you think..."
rules={{
required: 'Feedback is required',
minLength: {
value: 10,
message: 'Please provide at least 10 characters'
}
}}
/>
<Textarea
name="suggestions"
label="Suggestions for improvement"
placeholder="What could we do better?"
minRows={5}
/>
<Textarea
name="experience"
label="Overall experience"
placeholder="Describe your experience..."
/>
<button type="submit">Submit Feedback</button>
</DashForm>
);
}
// Textarea automatically:
// - Registers with React Hook Form
// - Syncs value from form state
// - Returns string values on submit
// - Shows errors only after touched OR submit
// - Tracks touched state on blurWhy it matters
Drop Textarea into existing form architectures without rewriting validation or state management.
Reactive Conditional Visibility
Try it: Select "Report an issue" to see description textarea appear
Textarea supports conditional rendering through visibleWhen. Fields render based on engine state—query field values and make rendering decisions. Select "Report an issue" to see conditional textarea appear without manual state orchestration.
import { DashForm } from '@dashforge/forms';
import { Textarea, Select } from '@dashforge/ui';
function ContactForm() {
return (
<DashForm
defaultValues={{
contactReason: '',
message: '',
issueDescription: ''
}}
>
<Select
name="contactReason"
label="Reason for contact"
options={[
{ label: 'General inquiry', value: 'general' },
{ label: 'Report an issue', value: 'issue' },
{ label: 'Feature request', value: 'feature' }
]}
/>
<Textarea
name="message"
label="Message"
placeholder="Your message..."
/>
{/* Issue description: renders only when reporting an issue */}
<Textarea
name="issueDescription"
label="Issue description"
placeholder="Describe the issue in detail..."
minRows={5}
visibleWhen={(engine) => {
const reason = engine.getNode('contactReason')?.value;
return reason === 'issue';
}}
/>
</DashForm>
);
}
// The Engine API provides:
// - getNode(name): Access any field's state
// - Component re-renders on dependency changes
// - Component makes rendering decision (engine provides state)Why it matters
Build adaptive forms where textarea visibility responds to user input. Define the predicate—the component handles rendering.
API Reference
Complete props and type definitions
Explicit vs Auto-Bound Props: When inside DashForm, Textarea receives value, error, helperText, onChange, and onBlur automatically through field binding. Explicit props always take precedence over form-provided values.
| Prop | Type | Default | Description |
|---|---|---|---|
| name | string | - | Field name for form integration (required) |
| label | React.ReactNode | - | Label text displayed above the textarea |
| value | string | - | Controlled value of the textarea |
| onChange | (event) => void | - | Callback fired when the value changes |
| placeholder | string | - | Placeholder text shown when textarea is empty |
| minRows | number | 3 | Minimum number of rows to display. Textarea automatically expands as content grows. |
| error | boolean | false | If true, displays error state. Explicit error prop overrides form-provided error state. When inside DashForm without explicit prop, error is gated (shows only when touched OR submitted). |
| helperText | string | - | Helper text displayed below textarea. Explicit helperText prop overrides form-provided validation error message. When inside DashForm, validation errors display as helperText (gated by touched/submitted state). |
| disabled | boolean | false | If true, the textarea is disabled |
| rules | ValidationRules | - | Validation rules for DashForm integration. Format follows React Hook Form rules contract (required, minLength, maxLength, pattern, validate, etc.). Only used when inside DashForm—ignored in standalone mode. |
| visibleWhen | (engine: Engine) => boolean | - | Component-level conditional rendering predicate. Receives engine instance with access to all field state via getNode(name). When false, component renders null. Re-evaluates on dependency changes. Only works inside DashForm (requires engine). |
Under the hood
How Textarea behaves and why it works this way
Form integration
Automatically binds to form state inside DashForm. No Controller, no manual wiring. Works as a standard MUI TextField (multiline) when used standalone.
Behavior model
Always renders multiline with 3 rows by default (adjust via minRows for longer content like bios or feedback). Errors appear only after blur or submit. Preserves newlines in string values—critical for paragraphs, code snippets, and formatted text. Reacts to form state using visibleWhen.
Architecture
Built on MUI TextField with multiline={true}. Fully typed with TypeScript. Purpose-built for comments, feedback, descriptions, issue reports, and any long-form user input.