Textarea
A multi-line text field that can grow with its content and count characters.
'use client';
import { Textarea } from '@akhatmirzo/ui';
export default function TextareaBasic() {
return (
<div className="w-full max-w-md">
<Textarea placeholder="Buyurtma haqida izoh qoldiring" aria-label="Izoh" />
</div>
);
}
Import
import { Textarea } from '@akhatmirzo/ui';When to use
- For free-form, multi-line text — comments, addresses, reviews, messages. For single-line
values, use
Input. - Always inside a
Field— the label, hint and error get wired up for you. - Use
autoResizefor chat and comment boxes: the field grows as you type and scrolls inside once it reachesmaxRows. - If there's a limit, pair
maxLengthwithshowCountso people can see how much room is left.
Auto-resize
With autoResize, the height follows the content between minRows and maxRows. Without
maxRows, it grows without limit. Manual resizing is turned off in this mode.
'use client';
import { Textarea } from '@akhatmirzo/ui';
export default function TextareaAutoResize() {
return (
<div className="w-full max-w-md">
<Textarea
autoResize
minRows={2}
maxRows={6}
placeholder="Yozib ko'ring — maydon matn bilan birga o'sadi"
aria-label="Xabar"
/>
</div>
);
}
Character count
showCount shows the number of characters below the field; with maxLength it reads "64 / 120".
The count turns red when you hit the limit.
'use client';
import { Textarea } from '@akhatmirzo/ui';
import { useState } from 'react';
export default function TextareaCount() {
const [bio, setBio] = useState(
'Frontend dasturchi, Toshkent. React va TypeScript bilan ishlayman.',
);
return (
<div className="w-full max-w-md">
<Textarea
showCount
maxLength={120}
value={bio}
onChange={(e) => setBio(e.target.value)}
aria-label="O'zingiz haqingizda"
/>
</div>
);
}
States and sizes
The same states as Input: invalid, disabled and readOnly. Sizes (sm, md, lg) change
the padding and font size; minRows controls the height.
'use client';
import { Textarea } from '@akhatmirzo/ui';
export default function TextareaStates() {
return (
<div className="grid w-full max-w-lg grid-cols-1 gap-3 sm:grid-cols-2">
<Textarea minRows={2} invalid defaultValue="Juda qisqa" aria-label="Xato" />
<Textarea minRows={2} disabled defaultValue="O'chirilgan" aria-label="O'chirilgan" />
<Textarea minRows={2} readOnly defaultValue="Faqat o'qish uchun" aria-label="Faqat o'qish" />
<Textarea minRows={2} size="sm" placeholder="Kichik o'lcham" aria-label="Kichik" />
</div>
);
}
With Field
Kuryer uchun qo'shimcha ma'lumot
'use client';
import { Field, Textarea } from '@akhatmirzo/ui';
export default function TextareaWithField() {
return (
<div className="w-full max-w-md">
<Field label="Izoh" required description="Kuryer uchun qo'shimcha ma'lumot">
<Textarea
autoResize
showCount
maxLength={300}
placeholder="Masalan: 3-podyezd, domofon ishlamaydi"
/>
</Field>
</div>
);
}
Props
Textarea accepts every other <textarea> attribute (name, placeholder, maxLength,
onChange ...), and ref points to the inner <textarea>. Use minRows instead of rows.
className goes to the outer container; use textareaClassName for the inner element.
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'sm' | 'md' | 'lg' | 'md' | Padding and font size |
invalid | boolean | — | Error state (automatic inside a Field with an error) |
autoResize | boolean | false | Height grows with the content (minRows .. maxRows) |
minRows | number | 3 | Initial (and minimum) number of rows |
maxRows | number | — | Maximum rows with autoResize; scrolls inside after that |
showCount | boolean | false | Character count; "120 / 500" with maxLength |
textareaClassName | string | — | Class for the inner <textarea> |
readOnly | boolean | false | Read-only |
Data attributes
Set on the outer container (data-slot="textarea"): data-size, data-invalid,
data-disabled and data-readonly. The counter element has data-slot="textarea-count".
Accessibility
- Native
<textarea>— focus withTab;Enterinserts a new line. - With Field,
id,aria-describedby,aria-invalidandaria-requiredare wired up automatically. - The counter is added to
aria-describedby, so screen readers mention the limit when the field gets focus.