Textarea
Ô chữ nhiều dòng, cho mô tả, bình luận hoặc tin nhắn. Hộp field của Input: cùng nền sunken, viền control, chữ 14px (16px trên cảm ứng) và các trạng thái, với góc container vẫn hữu hạn ở preset pill. Một dòng cộng padding khớp chiều cao Input cùng size.
Xem trước
import { Field, FieldControl, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Textarea } from "@/components/ui/textarea"
<Field className="w-full max-w-md">
<FieldLabel>Mô tả</FieldLabel>
<FieldControl>
<Textarea placeholder="Dự án này về điều gì?" />
</FieldControl>
<FieldDescription>Hiển thị trên thẻ dự án.</FieldDescription>
</Field>Cách dùng
Khi nào dùng
- Chữ trên nhiều dòng: một mô tả, một bình luận, một tin nhắn cho nhóm.
- Một value người dùng dán vào, chẳng hạn danh sách địa chỉ, mỗi địa chỉ một dòng.
Khi nào không dùng
- Một dòng, chẳng hạn tên, email hoặc tìm kiếm. Dùng Input.
- Chọn từ các lựa chọn đã biết. Dùng Select.
Biến thể
size
Padding và chiều cao tối thiểu, khớp Input cùng size. Dùng size của các field khác trong form.
import { Field, FieldControl, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Textarea } from "@/components/ui/textarea"
<Field className="w-full max-w-md">
<FieldLabel>Mô tả</FieldLabel>
<FieldControl>
<Textarea size="sm" placeholder="Dự án này về điều gì?" />
</FieldControl>
<FieldDescription>Hiển thị trên thẻ dự án.</FieldDescription>
</Field>
<Field className="w-full max-w-md">
<FieldLabel>Mô tả</FieldLabel>
<FieldControl>
<Textarea placeholder="Dự án này về điều gì?" />
</FieldControl>
<FieldDescription>Hiển thị trên thẻ dự án.</FieldDescription>
</Field>
<Field className="w-full max-w-md">
<FieldLabel>Mô tả</FieldLabel>
<FieldControl>
<Textarea size="lg" placeholder="Dự án này về điều gì?" />
</FieldControl>
<FieldDescription>Hiển thị trên thẻ dự án.</FieldDescription>
</Field>
<Field className="w-full max-w-md">
<FieldLabel>Mô tả</FieldLabel>
<FieldControl>
<Textarea size="xl" placeholder="Dự án này về điều gì?" />
</FieldControl>
<FieldDescription>Hiển thị trên thẻ dự án.</FieldDescription>
</Field>resize
Hướng người dùng có thể kéo góc. vertical giữ chiều rộng của form; none cho hộp cố định, chẳng hạn ô soạn chat.
import { Field, FieldControl, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Textarea } from "@/components/ui/textarea"
<Field className="w-full max-w-md">
<FieldLabel>Mô tả</FieldLabel>
<FieldControl>
<Textarea resize="none" placeholder="Dự án này về điều gì?" />
</FieldControl>
<FieldDescription>Hiển thị trên thẻ dự án.</FieldDescription>
</Field>
<Field className="w-full max-w-md">
<FieldLabel>Mô tả</FieldLabel>
<FieldControl>
<Textarea placeholder="Dự án này về điều gì?" />
</FieldControl>
<FieldDescription>Hiển thị trên thẻ dự án.</FieldDescription>
</Field>
<Field className="w-full max-w-md">
<FieldLabel>Mô tả</FieldLabel>
<FieldControl>
<Textarea resize="both" placeholder="Dự án này về điều gì?" />
</FieldControl>
<FieldDescription>Hiển thị trên thẻ dự án.</FieldDescription>
</Field>Ví dụ
Mặc định
import { Field, FieldControl, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Textarea } from "@/components/ui/textarea"
<Field className="w-full max-w-md">
<FieldLabel>Mô tả</FieldLabel>
<FieldControl>
<Textarea placeholder="Dự án này về điều gì?" />
</FieldControl>
<FieldDescription>Hiển thị trên thẻ dự án.</FieldDescription>
</Field>Có lỗi
Chữ lỗi đánh dấu textarea là invalid và được đọc sau tên.
import { Field, FieldControl, FieldError, FieldLabel } from "@/components/ui/field"
import { Textarea } from "@/components/ui/textarea"
<Field className="w-full max-w-md" required>
<FieldLabel requiredText="Bắt buộc">Lý do rời đi</FieldLabel>
<FieldControl>
<Textarea rows={4} />
</FieldControl>
<FieldError>Cho chúng tôi biết trong một hoặc hai câu.</FieldError>
</Field>Chỉ đọc
Focus và sao chép được, nhưng không sửa được.
import { Field, FieldControl, FieldLabel } from "@/components/ui/field"
import { Textarea } from "@/components/ui/textarea"
<Field className="w-full max-w-md">
<FieldLabel>Dữ liệu webhook</FieldLabel>
<FieldControl>
<Textarea readOnly rows={4} defaultValue="event: project.created" />
</FieldControl>
</Field>Vô hiệu
import { Field, FieldControl, FieldLabel } from "@/components/ui/field"
import { Textarea } from "@/components/ui/textarea"
<Field className="w-full max-w-md" disabled>
<FieldLabel>Ghi chú</FieldLabel>
<FieldControl>
<Textarea defaultValue="Archived projects can't be edited." />
</FieldControl>
</Field>Có bộ đếm ký tự
maxLength đặt giới hạn; showCount hiện nó bên trong field.
import { Textarea } from "@/components/ui/textarea"
<div className="flex w-full max-w-sm flex-col gap-xs">
<label htmlFor="bio" className="text-sm text-text-primary">Bio</label>
<Textarea id="bio" maxLength={160} showCount defaultValue="Product designer building Werewolf." />
</div>Nên và không nên
Nên
- Đặt trong một Field, để có label nhìn thấy và description cùng lỗi được nối.
- Đặt rows theo lượng chữ bạn chờ, để hộp cho thấy nên viết bao nhiêu.
- Dùng cùng size với các field khác trong form.
Không nên
- Đừng dùng cho một dòng, chẳng hạn tên hoặc email; dùng Input.
- Đừng dùng placeholder thay cho label.
- Đừng để Enter submit form; người ta chờ một dòng mới.
Props
| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
|---|---|---|---|---|
| size | enum | sm | md | lg | xl | md | Padding và chiều cao tối thiểu, khớp Input cùng size. Dùng size của các field khác trong form. |
| resize | enum | none | vertical | both | vertical | Hướng người dùng có thể kéo góc. vertical giữ chiều rộng của form; none cho hộp cố định, chẳng hạn ô soạn chat. |
| rows | number | - | 3 | Số dòng nhìn thấy trước khi chữ cuộn. Chọn theo lượng chữ bạn chờ: 3 cho một bình luận, 6 hoặc hơn cho một mô tả. |
| disabled | boolean | - | false | Không focus hoặc sửa được. Ưu tiên readOnly cho value mà người dùng vẫn nên đọc và sao chép. |
| readOnly | boolean | - | false | Focus, cuộn và sao chép được, nhưng không sửa được. Cùng kiểu với textarea có thể sửa. |
| maxLength | number | - | - | Giới hạn gốc về số ký tự. Với showCount, bộ đếm hiện 34 / 160. |
| showCount | boolean | - | false | Hiện số ký tự đã gõ ở góc dưới cuối field, trên tổng maxLength khi có. Textarea được mô tả bởi bộ đếm; trình đọc màn hình chỉ nghe số ký tự còn lại khi gần giới hạn, sau khi ngừng gõ. |
| countLabel | function | - | - | Câu trình đọc màn hình nghe khi gần giới hạn, nhận số ký tự còn lại. Mặc định là "12 characters left"; truyền một hàm đã dịch trên trang ngôn ngữ khác. |
Cấu tạo
| Phần | Mô tả |
|---|---|
| root | Phần tử textarea: nền sunken, viền control, radius-container, chữ 14px với leading của body (16px trên cảm ứng, để iOS không zoom). Không bao giờ ngắn hơn size-element-* của size đó. |
| placeholder | Chữ gợi ý khi value trống. Tô bằng text-secondary, nên đạt 4.5:1 trên nền sunken. |
| group | Hộp field khi có showCount: một wrapper cùng nền, border, radius và padding với textarea, hiện focus, kiểu disabled và viền danger của nó thông qua :has(). className nằm ở đây. |
| count | Bộ đếm ký tự ở góc dưới cuối group, chữ mono xs text-tertiary với chữ số đều. |
Khả năng truy cập
Role: textbox
| Phím | Hành động |
|---|---|
| Tab | Chuyển focus vào và ra khỏi textarea; bên trong, Tab không bị bắt. |
| Enter | Xuống dòng mới. Không bao giờ submit form. |
- Đặt tên bằng label nhìn thấy. Trong Field, FieldLabel trỏ tới textarea và FieldControl nối description cùng lỗi.
- Placeholder là gợi ý, không phải label: nó biến mất ngay khi người dùng gõ.
- aria-invalid hiện viền danger; đi cùng chữ lỗi, vì chỉ viền thì dựa vào màu. FieldError làm cả hai.
- Textarea là phần tử replaced, nên không có vùng nhấn ::before. Nó không bao giờ ngắn hơn một control cùng size.
- Chữ disabled vẫn cuộn được, nên không mất phần nào của value dài khỏi tầm nhìn.
Cài đặt
npx werewolf-ui add textareaChạy npx werewolf-ui init một lần trong app trước khi thêm component. Init cài token, thêm CSS import và luật cho agent. Add cài component này cùng các dependency và giữ nguyên theme của bạn. Xem Cài đặt để biết yêu cầu và cách cài qua registry.