Chuyển tới nội dung

Pro đang mở bán trước. Cài đặt mở từ tháng 1/2027. Xem Pro

Component

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.

  • npm: 1 trực tiếp, 2 tổng
  • registry: 2 trực tiếp, 2 tổng

Xem trước

Hiển thị trên thẻ dự án.

Props

  • size
  • resize
  • rows
  • disabled
  • maxLength
  • showCount
  • label
  • placeholder
  • error
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.

  • Hiển thị trên thẻ dự án.

    sm

  • Hiển thị trên thẻ dự án.

    mdmặc định

  • Hiển thị trên thẻ dự án.

    lg

  • Hiển thị trên thẻ dự án.

    xl

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.

  • Hiển thị trên thẻ dự án.

    none

  • Hiển thị trên thẻ dự án.

    verticalmặc định

  • Hiển thị trên thẻ dự án.

    both

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

Hiển thị trên thẻ dự án.

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.

Cho chúng tôi biết trong một hoặc hai câu.

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.

35 / 160
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ênKiểuGiá trịMặc địnhMô tả
sizeenumsm | md | lg | xlmdPadding 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.
resizeenumnone | vertical | bothverticalHướ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.
rowsnumber-3Số 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ả.
disabledboolean-falseKhô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.
readOnlyboolean-falseFocus, 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.
maxLengthnumber--Giới hạn gốc về số ký tự. Với showCount, bộ đếm hiện 34 / 160.
showCountboolean-falseHiệ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õ.
countLabelfunction--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ầnMô tả
rootPhầ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 đó.
placeholderChữ gợi ý khi value trống. Tô bằng text-secondary, nên đạt 4.5:1 trên nền sunken.
groupHộ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.
countBộ đế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ímHành động
TabChuyển focus vào và ra khỏi textarea; bên trong, Tab không bị bắt.
EnterXuố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 textarea

Chạ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.