MiHCM
primitives/@mihcm/ui·v0.21.0·stable

Textarea

Multi-line text entry. Shares the variant + invalid model with Input.

In context

Comment composer, quarterly feedback with live character counter, support ticket with validation, and a long-form release notes draft.

Comment composer

Multi-line composer with identity + actions.

Yashi EL
@mentions supported

Quarterly feedback

Live character count tone shifts as the limit approaches.

280 character soft limit.93 left

Open ticket

Required textarea with validation.

Will be sent to engineering

Release notes draft

Quiet container surface for long-form composition.

Autosaved 18 seconds agoMarkdown supported

Basic with label

import { Textarea } from '@mihcm/ui/Textarea';
import { Label } from '@mihcm/ui/Label';
 
<div className="space-y-1.5">
  <Label htmlFor="bio">Bio</Label>
  <Textarea id="bio" placeholder="Tell us about yourself..." rows={4} />
</div>

With validation error

The invalid prop switches to destructive styling and sets aria-invalid.

This field is required.

import { Textarea } from '@mihcm/ui/Textarea';
import { Label } from '@mihcm/ui/Label';
 
<div className="space-y-1.5">
  <Label htmlFor="notes" tone="destructive">Notes</Label>
  <Textarea id="notes" invalid placeholder="Required field" />
  <p className="text-sm text-destructive">This field is required.</p>
</div>

Character count

0/200

import { useState } from 'react';
import { Textarea } from '@mihcm/ui/Textarea';
import { Label } from '@mihcm/ui/Label';
 
const [value, setValue] = useState('');
const max = 200;
 
<div className="space-y-1.5">
  <Label htmlFor="feedback">Feedback</Label>
  <Textarea
    id="feedback"
    value={value}
    onChange={(e) => setValue(e.target.value.slice(0, max))}
    rows={4}
  />
  <p className="text-xs text-muted-foreground text-right">
    {value.length}/{max}
  </p>
</div>