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.

@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>