TextField

یک فیلد کامل فرم: برچسب، ورودی، توضیح و پیام خطا در یک کامپوننت، با اتصال خودکار id و aria-describedby. هم به‌صورت میان‌بر (همه چیز با props) و هم به‌صورت ترکیبی (اجزا را خودتان بچینید) کار می‌کند.

ری‌اکت ۱۹ و Next.js با پیاده‌سازی دسترس‌پذیری داخلی دیگویو ۳ با Composition API و Reka UISvelte ۵ با runes و Bits UIانگولار با signals و Angular CDK

این کامپوننت فعلاً برای ۱ فریم‌ورک از ۴ فریم‌ورک آماده است.

هیچ‌وقت ایمیلتان را با کسی به اشتراک نمی‌گذاریم.

این نمونه هنوز برای Vue پورت نشده است؛ آنچه می‌بینید نسخهٔ ری‌اکت است.

این نمونه هنوز برای Svelte پورت نشده است؛ آنچه می‌بینید نسخهٔ ری‌اکت است.

این نمونه هنوز برای Angular پورت نشده است؛ آنچه می‌بینید نسخهٔ ری‌اکت است.

نصب

با CLI اختصاصی dig-ui کامپوننت را از رجیستری دیگ نصب کنید؛ وابستگی‌ها و فایل‌ها خودکار اضافه می‌شوند.

نصب سریع با لینک سخت و دیسک مشترکپکیج‌منیجر پیش‌فرض Node.jsYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
pnpm dlx dig-ui@latest add https://design-system-tau-green.vercel.app/r/text-field.json
npx dig-ui@latest add https://design-system-tau-green.vercel.app/r/text-field.json
yarn dlx dig-ui@latest add https://design-system-tau-green.vercel.app/r/text-field.json
bunx --bun dig-ui@latest add https://design-system-tau-green.vercel.app/r/text-field.json

این کامپوننت هنوز برای Vue پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک روی Reka UI در دست کار است.

این کامپوننت هنوز برای Svelte پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک روی Bits UI در دست کار است.

این کامپوننت هنوز برای Angular پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک روی Angular CDK در دست کار است.

استفاده

import { TextField } from "@/components/ui/text-field"

// میان‌بر: همه چیز با props
<TextField
  label="ایمیل"
  type="email"
  description="برای بازیابی رمز لازم است."
  errorMessage="قالب ایمیل درست نیست."
  invalid={hasError}
  required
/>

// ترکیبی: اجزا را خودتان بچینید
import {
  TextField,
  TextFieldLabel,
  TextFieldInput,
  TextFieldDescription,
  TextFieldError,
} from "@/components/ui/text-field"

<TextField invalid={hasError} required>
  <TextFieldLabel>ایمیل</TextFieldLabel>
  <TextFieldInput type="email" />
  <TextFieldDescription>برای بازیابی رمز لازم است.</TextFieldDescription>
  <TextFieldError>قالب ایمیل درست نیست.</TextFieldError>
</TextField>

این کامپوننت هنوز برای Vue پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک روی Reka UI در دست کار است.

این کامپوننت هنوز برای Svelte پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک روی Bits UI در دست کار است.

این کامپوننت هنوز برای Angular پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک روی Angular CDK در دست کار است.

ترکیب اجزا

ریشهٔ TextField یک context می‌سازد که id ورودی، id توضیح و id خطا را نگه می‌دارد. به همین دلیل TextFieldLabel خودش htmlFor می‌گیرد و TextFieldInput خودش aria-describedby، aria-invalid و required را برمی‌دارد؛ شما هیچ idای دستی نمی‌نویسید.

وقتی فیلد نامعتبر است، پیام خطا جای توضیح را می‌گیرد، نه اینکه زیرش اضافه شود.

برچسب شناور (labelPlacement="inside") هم کاملاً CSS است: کادر Input کلاس peer می‌گیرد و برچسب با peer-focus-within و peer-data-[filled=true] بالا و پایین می‌رود. پر بودن فیلد را خودِ Input با data-filled اعلام می‌کند، پس هیچ state ری‌اکتی و هیچ اندازه‌گیری در کار نیست.

  • در حالت ترکیبی، TextFieldInput باید در DOM قبل از TextFieldLabel بیاید تا انتخابگر هم‌نیا کار کند.
  • برای فیلد چندخطی به‌جای TextFieldInput از TextFieldTextarea استفاده کنید؛ فقط برچسب شناور را پشتیبانی نمی‌کند.
  • اگر مقدار را کنترل‌شده بدهید، پراپ validate هم هست: تابعی که با هر تغییر مقدار صدا زده می‌شود و رشته برگرداندن یعنی نامعتبر، دیگر لازم نیست invalid و errorMessage را دستی هماهنگ نگه دارید.

TextField فعلاً فقط برای ری‌اکت پورت شده است.

دسترس‌پذیری

  • برچسب با htmlFor به id ورودی وصل می‌شود؛ id را خودتان ندهید مگر اینکه لازم باشد (useId تولیدش می‌کند).
  • aria-describedby فقط به عنصری اشاره می‌کند که واقعاً رندر شده، اگر توضیح ندهید، اصلاً گذاشته نمی‌شود.
  • پیام خطا role="alert" دارد تا صفحه‌خوان بلافاصله بخواندش.
  • فیلد اجباری علاوه بر ستارهٔ بصری، ویژگی required را روی تگ بومی می‌گذارد تا اعتبارسنجی مرورگر و صفحه‌خوان هر دو بفهمند.
  • در حالت برچسب شناور، placeholder تا لحظهٔ فوکوس پنهان می‌ماند تا با برچسب هم‌پوشانی نکند.

مرجع API

TextField

هر propای که اینجا نیست مستقیم به Input منتقل می‌شود (type، placeholder، variant، color، size، clearable، startContent و…).

ویژگینوعپیش‌فرضتوضیح
labelReact.ReactNodeبرچسب فیلد در حالت میان‌بر؛ در حالت ترکیبی به‌جایش TextFieldLabel بگذارید.
labelPlacement"outside" | "outside-top" | "outside-left" | "inside""outside"جایگاه برچسب. outside و outside-top هر دو بالای فیلد؛ inside برچسب شناور داخل کادر.
descriptionReact.ReactNodeمتن راهنما زیر فیلد؛ وقتی خطا نمایش داده می‌شود پنهان می‌شود.
errorMessageReact.ReactNodeپیام خطا؛ فقط وقتی invalid روشن باشد دیده می‌شود.
invalidbooleanfalseفیلد نامعتبر است: aria-invalid روی ورودی، برچسب قرمز و نمایش پیام خطا.
validate(value: string) => string | string[] | true | null | undefinedاعتبارسنجی زنده روی مقدار کنترل‌شده؛ رشته برگردانید یعنی نامعتبر (همان errorMessage می‌شود)، true/null/undefined یعنی معتبر. فقط با value کنترل‌شده اجرا می‌شود.
requiredbooleanfalseستارهٔ قرمز کنار برچسب و ویژگی required روی تگ بومی input.
disabledbooleanfalseکل فیلد غیرفعال می‌شود.
readOnlybooleanfalseمقدار قابل انتخاب و کپی است ولی تغییر نمی‌کند.
fullWidthbooleantrueفیلد تمام عرض ظرفش را می‌گیرد.
classNamestringکلاس ظرف بیرونی.
inputClassNamestringکلاس خودِ تگ input در حالت میان‌بر.
childrenReact.ReactNodeاگر بدهید، حالت ترکیبی فعال می‌شود و propهای میان‌بر (label، description، errorMessage) رندر نمی‌شوند.

TextFieldLabel

روی کامپوننت Label سوار است و htmlFor را خودش از context می‌گیرد.

ویژگینوعپیش‌فرضتوضیح
...propsReact.ComponentProps<typeof Label>همهٔ propهای Label؛ htmlFor خودکار پر می‌شود ولی می‌توانید بازنویسی کنید.

TextFieldInput

همان Input است با id، aria-invalid، aria-describedby، required، disabled و readOnly از context.

ویژگینوعپیش‌فرضتوضیح
...propsInputPropsهمهٔ propهای Input؛ propهای صریح شما بر مقادیر context اولویت دارند.

TextFieldTextarea

همان Textarea است با id، aria-invalid، aria-describedby، required، disabled و readOnly از context؛ برای فیلد چندخطی به‌جای TextFieldInput به‌کار می‌رود. برچسب شناور را پشتیبانی نمی‌کند.

ویژگینوعپیش‌فرضتوضیح
...propsReact.ComponentProps<typeof Textarea>همهٔ propهای Textarea (از جمله rows)؛ propهای صریح شما بر مقادیر context اولویت دارند.

TextFieldDescription

وقتی پیام خطا نمایش داده می‌شود، خودش را رندر نمی‌کند.

ویژگینوعپیش‌فرضتوضیح
...propsReact.ComponentProps<"p">id از context می‌آید تا aria-describedby درست بماند.

TextFieldError

فقط وقتی invalid روشن باشد رندر می‌شود و role="alert" دارد.

ویژگینوعپیش‌فرضتوضیح
...propsReact.ComponentProps<"p">id از context می‌آید تا aria-describedby درست بماند.

Data Attributes

روی ظرف بیرونی می‌نشینند.

ویژگینوعپیش‌فرضتوضیح
data-slot"text-field"اجزا به‌ترتیب text-field-label، input (یا textarea با TextFieldTextarea)، text-field-description و text-field-error دارند.
data-invalid / data-required / data-disabled / data-readonly"true" | undefinedبازتاب propهای متناظر برای استایل‌دهی از بیرون.

این کامپوننت هنوز برای Vue پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک روی Reka UI در دست کار است.

این کامپوننت هنوز برای Svelte پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک روی Bits UI در دست کار است.

این کامپوننت هنوز برای Angular پورت نشده است.

نسخهٔ ری‌اکت آماده است؛ پورت این فریم‌ورک روی Angular CDK در دست کار است.