Input

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

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

کد، دستور نصب و مرجع API این صفحه با فریم‌ورک انتخابی عوض می‌شود.

پیش‌نمایش با نسخهٔ ری‌اکت رندر شده است؛ پورت Vue دقیقاً همین کلاس‌های Tailwind را دارد، پس خروجی بصری یکسان است.

پیش‌نمایش با نسخهٔ ری‌اکت رندر شده است؛ پورت Svelte دقیقاً همین کلاس‌های Tailwind را دارد، پس خروجی بصری یکسان است.

پیش‌نمایش با نسخهٔ ری‌اکت رندر شده است؛ پورت Angular دقیقاً همین کلاس‌های Tailwind را دارد، پس خروجی بصری یکسان است.

نصب

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

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

Vue هنوز CLI اختصاصی دیگ ندارد. فایل رجیستری برای ابزارهای خودتان در دسترس است، ولی برای نصب از تب «دستی» استفاده کنید.

curl -O https://design-system-tau-green.vercel.app/r/vue/input.json

Svelte هنوز CLI اختصاصی دیگ ندارد. فایل رجیستری برای ابزارهای خودتان در دسترس است، ولی برای نصب از تب «دستی» استفاده کنید.

curl -O https://design-system-tau-green.vercel.app/r/svelte/input.json

Angular هنوز CLI اختصاصی دیگ ندارد. فایل رجیستری برای ابزارهای خودتان در دسترس است، ولی برای نصب از تب «دستی» استفاده کنید.

curl -O https://design-system-tau-green.vercel.app/r/angular/input.json

استفاده

import { Input } from "@/components/ui/input"

<Input type="text" placeholder="نام و نام خانوادگی" />

// با واریانت، رنگ و اندازه
<Input variant="bordered" color="primary" size="lg" placeholder="عنوان" />
<script setup lang="ts">
import { ref } from "vue"
import Input from "@/components/ui/Input.vue"

const fullName = ref("")
</script>

<template>
  <Input v-model="fullName" type="text" placeholder="نام و نام خانوادگی" />
</template>
<script lang="ts">
  import Input from "$lib/components/ui/input.svelte";

  let fullName = $state("");
</script>

<Input bind:value={fullName} type="text" placeholder="نام و نام خانوادگی" />
import { Component } from "@angular/core"
import { FormsModule } from "@angular/forms"
import { DigInput } from "@/components/ui/input"

@Component({
  selector: "app-demo",
  standalone: true,
  imports: [DigInput, FormsModule],
  template: `
    <input digInput type="text" placeholder="نام و نام خانوادگی"
           [(ngModel)]="fullName" />
  `,
})
export class DemoComponent {
  fullName = ""
}

ترکیب اجزا

Input ساختار دو لایه دارد: یک کادر (data-slot input-root) که حاشیه، پس‌زمینه، ارتفاع و گردی گوشه را دارد، و داخلش تگ بومی input که خودش بی‌رنگ و بی‌حاشیه است.

محتوای ابتدا/انتها و دکمهٔ پاک‌کردن هم‌ردیفِ input در همان کادر flex می‌نشینند، پس هر عرضی داشته باشند - آیکون، کلمهٔ «تومان» یا یک دکمهٔ کامل - فضای واقعی می‌گیرند و روی متن نمی‌افتند. به همین دلیل className روی کادر می‌نشیند و inputClassName روی خود تگ input.

رنگ هم با یک متغیر CSS به اسم --field منتقل می‌شود: محور color فقط همین متغیر را ست می‌کند و محور variant تصمیم می‌گیرد رنگ روی حاشیه بنشیند، روی زیرخط، یا به‌صورت پس‌زمینهٔ رقیق.

برای برچسب، توضیح و پیام خطا از TextField استفاده کنید.

توجه: همهٔ حالت‌های این صفحه فعلاً فقط در نسخهٔ ری‌اکت هستند؛ پورت Vue/Svelte/Angular همچنان همان ورودی پایه است و در دست به‌روزرسانی.

دسترس‌پذیری

  • همیشه با Label و id متصل کنید؛ placeholder جایگزین برچسب نیست. TextField این اتصال را خودکار انجام می‌دهد.
  • جهت پیش‌فرض rtl است تا مکان‌نما از راست شروع کند و placeholder فارسی درست بشکند؛ فیلدهای ذاتاً لاتین (عدد، ایمیل، نشانی، شمارهٔ تماس) خودکار ltr می‌شوند و با prop dir می‌توانید هر کدام را بازنویسی کنید.
  • فیلدهای عددی ارقام را فارسی نشان می‌دهند ولی مقدار لاتین می‌فرستند، پس کاربر با هر کیبوردی تایپ کند در اعتبارسنجی سرور خطا نمی‌گیرد.
  • برای نمایش خطا aria-invalid و aria-describedby بدهید؛ استایل خطا خودکار اعمال می‌شود و بر رنگ واریانت اولویت دارد.
  • دکمهٔ پاک‌کردن aria-label دارد و از ترتیب Tab بیرون است (tabIndex=-1)، چون همان کار را می‌شود با انتخاب متن و Delete انجام داد؛ صفحه‌خوان همچنان آن را می‌بیند.
  • در ورودی فایل، دکمهٔ بومی مرورگر پنهان و با دکمهٔ فارسی جایگزین می‌شود؛ خود تگ input نامرئی روی کل کادر می‌ماند، پس فوکوس صفحه‌کلید و باز شدن پنجرهٔ انتخاب فایل دست‌نخورده است.
  • در انگولار دایرکتیو روی تگ بومی می‌نشیند، پس ngModel و formControlName و اعتبارسنجی فرم بدون هیچ پلی کار می‌کنند.

مرجع API

Input

همهٔ ویژگی‌های استاندارد تگ input هم پشتیبانی می‌شود. فقط size و color از نوع props نیتیو کنار گذاشته شده‌اند چون محور واریانت‌اند.

ویژگینوعپیش‌فرضتوضیح
variant"default" | "bordered" | "faded" | "flat" | "underlined""default"حالت بصری فیلد.
color"default" | "primary" | "success" | "warning" | "destructive""default"رنگ معنایی، مستقل از واریانت. default یعنی همان ظاهر خنثای دیگ.
size"sm" | "default" | "lg""default"ارتفاع و padding و اندازهٔ متن فیلد.
radius"none" | "sm" | "md" | "lg" | "full"شعاع گوشه؛ اگر ندهید rounded-md پیش‌فرض به‌کار می‌رود (و در underlined گوشه صاف است).
fullWidthbooleantrueفیلد تمام عرض ظرفش را می‌گیرد.
typestring"text"نوع ورودی HTML (text، email، password، number و…).
dir"rtl" | "ltr" | "auto""rtl" (یا "ltr" برای فیلدهای لاتین)جهت فیلد. پیش‌فرض rtl است تا مکان‌نما از راست شروع کند؛ برای عدد، ایمیل، نشانی و شمارهٔ تماس خودکار ltr می‌شود. روی کل کادر می‌نشیند، پس محتوای ابتدا هم هم‌جهت متن قرار می‌گیرد.
faDigitsbooleanخودکار برای فیلدهای عددیارقام را فارسی نشان می‌دهد و مقدار لاتین بیرون می‌دهد (در فرم با یک input مخفی). برای type="number"، type="tel" و inputMode عددی پیش‌فرض روشن است.
groupDigitsbooleaninputMode === "decimal"ارقام را سه‌تا سه‌تا با جداکنندهٔ هزارگان (٬) گروه‌بندی می‌کند، بدون توجه به بزرگی عدد؛ مقداری که به فرم می‌رود همچنان بدون جداکننده است. برای کد ملی و شمارهٔ کارت پیش‌فرض خاموش است.
hidePlaceholderOnFocusbooleantrueبا فوکوس (کلیک یا Tab) متن راهنما محو می‌شود و اگر کاربر بدون تایپ بیرون برود دوباره برمی‌گردد. برای فیلدی که باید راهنما حین تایپ هم بماند، false بدهید.
startContentReact.ReactNodeمحتوای ابتدای فیلد؛ در ردیف flex فضای واقعی می‌گیرد، پس روی متن نمی‌افتد.
endContentReact.ReactNodeمحتوای انتهای فیلد (واحد پول، دکمهٔ جستجو، دکمهٔ نمایش رمز و…).
startContentSpacing / endContentSpacing"default" | "tight" | "flush""default"فاصلهٔ محتوای کناری تا لبه: default همان padding فیلد، tight چند پیکسل برای دکمهٔ کوچک، و flush چسبیده به لبه با تمام ارتفاع فیلد.
fileButtonLabel / filePlaceholderstring"انتخاب فایل" / "فایلی انتخاب نشده"متن دکمهٔ فارسیِ انتخاب فایل و متن جای‌خالی؛ فقط در type="file".
clearablebooleanfalseدکمهٔ پاک‌کردن در انتهای فیلد. جایش همیشه رزرو است و فقط وقتی فیلد مقدار دارد دیده می‌شود.
onClear() => voidبعد از کلیک روی دکمهٔ پاک‌کردن صدا زده می‌شود.
onValueChange(value: string) => voidمثل onChange ولی مستقیم رشتهٔ مقدار را می‌دهد؛ هر دو با هم کار می‌کنند.
clearButtonLabelstring"پاک‌کردن"aria-label دکمهٔ پاک‌کردن.
classNamestringروی کادر بیرونی می‌نشیند (همان‌جا که حاشیه، پس‌زمینه، ارتفاع و گردی گوشه است) و با cn بر کلاس‌های واریانت اولویت دارد.
inputClassNamestringکلاس خودِ تگ input داخل کادر.

Data Attributes

روی تگ input می‌نشینند تا بتوانید بدون props استایل بدهید یا در تست انتخابشان کنید.

ویژگینوعپیش‌فرضتوضیح
data-slot"input-root" | "input" | …کادر بیرونی input-root است و تگ input داخلش input؛ اجزای دیگر input-start، input-end، input-clear و input-file.
data-variant / data-color / data-sizestringمقدار فعلی هر محور واریانت.
data-filled"true" | "false"آیا فیلد مقدار دارد؛ در هر دو حالت controlled و uncontrolled درست است.
data-disabled / data-readonly / data-required"true" | undefinedبازتاب propهای نیتیو متناظر.

inputVariants

اگر می‌خواهید همین کلاس‌ها را روی عنصر دیگری بگذارید (مثلاً یک textarea یا یک div شبیه فیلد).

ویژگینوعپیش‌فرضتوضیح
inputVariants({ variant, color, size, radius, fullWidth })(options?) => stringimport { inputVariants } from "@/components/ui/input"

Input.vue

پورت ویو فعلاً ورودی پایه است؛ محورهای واریانت و دکمهٔ پاک‌کردن هنوز اضافه نشده‌اند.

ویژگینوعپیش‌فرضتوضیح
v-modelstring | numberپیوند دوطرفه با useVModel؛ اگر ندهید، ورودی uncontrolled می‌ماند.
default-valuestring | numberمقدار اولیه وقتی v-model نمی‌دهید.
classHTMLAttributes['class']با cn ادغام می‌شود و بر کلاس‌های پایه اولویت دارد.
…attrsInputHTMLAttributestype، placeholder، disabled و بقیه به‌صورت fallthrough به تگ input می‌رسند.

input.svelte

پورت اسولت فعلاً ورودی پایه است؛ محورهای واریانت و دکمهٔ پاک‌کردن هنوز اضافه نشده‌اند.

ویژگینوعپیش‌فرضتوضیح
valuestring | number | nullقابل bind است: bind:value={email}.
refHTMLInputElement | nullnullقابل bind برای دسترسی مستقیم به عنصر.
classstringبا cn ادغام می‌شود و بر کلاس‌های پایه اولویت دارد.
...restPropsHTMLInputAttributesبقیهٔ ویژگی‌های input مستقیماً منتقل می‌شوند.

DigInput

دایرکتیو standalone روی تگ بومی input. پورت انگولار فعلاً ورودی پایه است؛ محورهای واریانت و دکمهٔ پاک‌کردن هنوز اضافه نشده‌اند.

ویژگینوعپیش‌فرضتوضیح
digInputDirectiveسلکتور دایرکتیو؛ روی تگ بومی input بگذارید تا استایل اعمال شود.
dir"auto" | "rtl" | "ltr""auto"جهت متن؛ پیش‌فرض auto است و بر اساس اولین نویسه تعیین می‌شود.
classstring""کلاس‌های شما با cn به کلاس‌های پایه اضافه و در تعارض‌ها برنده می‌شوند.