Input OTP
فیلد کد تأیید پیامکی: هر رقم یک خانه، چسباندن کد از پیامک، حرکت خودکار بین خانهها و پاککردن با Backspace. کاربر میتواند ۱۲۳۴۵۶ فارسی تایپ کند و مقداری که به سرور میرسد همیشه لاتین است.
این کامپوننت فعلاً برای ۱ فریمورک از ۴ فریمورک آماده است.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
نصب
با CLI اختصاصی dig-ui کامپوننت را از رجیستری دیگ نصب کنید؛ وابستگیها و فایلها خودکار اضافه میشوند.
pnpm dlx dig-ui@latest add https://design-system-tau-green.vercel.app/r/input-otp.jsonnpx dig-ui@latest add https://design-system-tau-green.vercel.app/r/input-otp.jsonyarn dlx dig-ui@latest add https://design-system-tau-green.vercel.app/r/input-otp.jsonbunx --bun dig-ui@latest add https://design-system-tau-green.vercel.app/r/input-otp.jsonاین کامپوننت هنوز برای Vue پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک روی Reka UI در دست کار است.
این کامپوننت هنوز برای Svelte پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک روی Bits UI در دست کار است.
این کامپوننت هنوز برای Angular پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک روی Angular CDK در دست کار است.
استفاده
"use client"
import * as React from "react"
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
} from "@/components/ui/input-otp"
const [code, setCode] = React.useState("")
<InputOTP value={code} onValueChange={setCode}>
<InputOTPGroup>
{[0, 1, 2, 3, 4, 5].map((index) => (
<InputOTPSlot key={index} index={index} />
))}
</InputOTPGroup>
</InputOTP>این کامپوننت هنوز برای Vue پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک روی Reka UI در دست کار است.
این کامپوننت هنوز برای Svelte پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک روی Bits UI در دست کار است.
این کامپوننت هنوز برای Angular پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک روی Angular CDK در دست کار است.
ترکیب اجزا
دسترسپذیری
- با autocomplete=one-time-code مرورگر و iOS کد پیامک را پیشنهاد میدهند؛ این را از ریشه برندارید.
- inputMode=numeric صفحهکلید عددی موبایل را باز میکند.
- ناوبری بین خانهها با کلیدهای جهتدار است و Backspace روی خانهٔ خالی به خانهٔ قبلی برمیگردد.
- برای کل گروه یک Label با htmlFor بگذارید و در حالت خطا invalid را روی Root بدهید تا هر شش خانه با هم قرمز شوند.
- با autoSubmit فرم بهمحض کامل شدن کد ارسال میشود؛ اگر کاربر ممکن است اشتباه تایپ کند، بهتر است دکمهٔ تأیید صریح داشته باشید.
مرجع API
InputOTP
| ویژگی | نوع | پیشفرض | توضیح |
|---|---|---|---|
| value / onValueChange | string / (value: string) => void | — | حالت کنترلشده؛ مقدار همیشه رشتهای از ارقام لاتین است. |
| defaultValue | string | — | مقدار اولیه در حالت کنترلنشده. |
| sanitizeValue | (value: string) => string | تبدیل ارقام فارسی و حذف غیرعدد | پاکسازی ورودی پیش از ثبت؛ برای کدهای حرفیعددی بازنویسی کنید. |
| validationType | "alpha" | "numeric" | "alphanumeric" | "none" | "none" | اعتبارسنجی هر نویسه پیش از پذیرفتنش؛ چون خودمان با sanitizeValue پاکسازی میکنیم روی none است. |
| type | "text" | "password" | "text" | مخفی کردن ارقام واردشده. |
| variant | "separated" | "connected" | "separated" | separated خانههای جدا و گِرد با پسزمینهٔ خاکستری خنثی است، پرکاربردترین حالت، بدون سایه، برای هرجا از جمله روی Card/Surface. connected آنها را در یک نوار کادردار و سایهدار به هم میچسباند. |
| invalid | boolean | false | خطا را روی همهٔ خانهها یکجا مینشاند؛ نیازی به تکرار aria-invalid روی تکتک خانهها نیست. |
| faDigits | boolean | true | نمایش ارقام به فارسی؛ مقدار ثبتشده همیشه لاتین میماند (مثل faDigits در Input). پیشفرض روشن است و به کیبورد یا لوکیل کاربر بستگی ندارد؛ برای موارد خاص که کد باید عیناً لاتین دیده شود با faDigits={false} خاموشش کنید. |
| onComplete | (value: string) => void | — | هر بار همهٔ خانهها پر شوند صدا زده میشود، با تایپ، چسباندن یا اتوفیل، صرفنظر از autoSubmit. |
| autoSubmit | boolean | false | ارسال خودکار نزدیکترین فرم بهمحض پر شدن همهٔ خانهها. |
| name / form | string | — | برای ارسال در فرم؛ کل کد در یک input مخفی قرار میگیرد. |
| disabled / readOnly | boolean | false | قفل کردن ورودیها. |
InputOTPSlot
| ویژگی | نوع | پیشفرض | توضیح |
|---|---|---|---|
| index | number | — | جای خانه در ترتیب؛ دادنش از پرش ظاهری بعد از هیدریشن جلوگیری میکند. |
| aria-invalid | boolean | — | بازنویسی دستی خطا برای همین یک خانه؛ برای خطای کل کد از invalid روی Root استفاده کنید. |
| data-filled | "true" | undefined | — | attribute فقطخواندنی؛ وقتی خانه رقم دارد true است، قلاب استایلدهی سفارشی با data-[filled=true]:. |
InputOTPGroup / InputOTPSeparator
| ویژگی | نوع | پیشفرض | توضیح |
|---|---|---|---|
| InputOTPGroup | React.ComponentProps<"div"> | — | در variant=separated (پیشفرض) هر خانه گوشهٔ خودش را دارد و با فاصله مینشیند؛ در connected خانهها را میچسباند و فقط گوشههای اول و آخر منطقی گِرد میشوند. |
| InputOTPSeparator | React.ComponentProps<"div"> | — | خط تیرهٔ بین دو گروه؛ role=separator دارد و خوانده نمیشود. |
این کامپوننت هنوز برای Vue پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک روی Reka UI در دست کار است.
این کامپوننت هنوز برای Svelte پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک روی Bits UI در دست کار است.
این کامپوننت هنوز برای Angular پورت نشده است.
نسخهٔ ریاکت آماده است؛ پورت این فریمورک روی Angular CDK در دست کار است.
نمونهها
With Separator
کدهای ششرقمی معمولاً دو گروه سهتایی میشوند تا خواندنشان راحتتر باشد.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
SMS Autofill
هر خانه از قبل autocomplete="one-time-code" دارد، پس مرورگر روی iOS و اندروید (WebOTP) بهمحض رسیدن پیامک کد را پیشنهاد یا خودکار پر میکند، بدون هیچ کد اضافه. چون این رفتار فقط با پیامک واقعی روی HTTPS دیده میشود، این دکمه رسیدن پیامک را شبیهسازی میکند تا پرشدن یکجای خانهها را همینجا ببینید.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
Four Digits
طول کد را تعداد خانهها تعیین میکند؛ برای کد چهاررقمی چهار خانه بگذارید.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
Latin Digits
پیشفرض همیشه فارسی نشان میدهد، صرفنظر از کیبورد یا لوکیل کاربر؛ مقداری که ثبت و ارسال میشود همیشه لاتین میماند. برای موارد خاص، مثلاً کدی که عمداً میخواهید عیناً لاتین دیده شود، با faDigits={false} نمایش را هم لاتین کنید.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
Error State
invalid را روی Root بگذارید تا کادر و حلقهٔ فوکوس همهٔ خانهها با هم قرمز شود.
کد واردشده درست نیست.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
Connected Variant
variant="connected" خانهها را در یک نوار کادردار و سایهدار به هم میچسباند؛ برای وقتی به ظاهر متصل و سنتیتر نیاز دارید. چون سایه دارد، اگر داخل یک Card/Surface سایهدار قرارش دهید دو سایه روی هم تلنبار میشود، variant پیشفرض (separated) برای آنجا مناسبتر است.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
On Complete
onComplete بهمحض پر شدن همهٔ خانهها صدا زده میشود، با تایپ یا چسباندن، بدون نیاز به فرم؛ مناسب بررسی خودکار کد با یک فراخوانی API.
برای تست، کد ۱۲۳۴۵۶ را وارد کنید.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
Disabled and Password
با type="password" ارقام مخفی میشوند و با disabled کل فیلد قفل میشود.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
In a Form
با name کل کد در یک input مخفی ارسال میشود و autoSubmit فرم را بهمحض کامل شدن میفرستد.
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
در حال بررسی (Loading)
بعد از تکمیل کد، خانهها را تا رسیدن پاسخ قفل کنید؛ وگرنه کاربر کد را وسط بررسی پاک میکند یا دوباره میفرستد. وضعیت را با aria-live بگویید تا صفحهخوان هم بفهمد.
کد ۶ رقمی را وارد کنید
این نمونه هنوز برای Vue پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Svelte پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
این نمونه هنوز برای Angular پورت نشده است؛ آنچه میبینید نسخهٔ ریاکت است.
کدام نمونه برای کدام موقعیت
| نمونه | کجا به کار میآید |
|---|---|
| With Separator | کدهای ششرقمی معمولاً دو گروه سهتایی میشوند تا خواندنشان راحتتر باشد. |
| SMS Autofill | هر خانه از قبل autocomplete="one-time-code" دارد، پس مرورگر روی iOS و اندروید (WebOTP) بهمحض رسیدن پیامک کد را پیشنهاد یا خودکار پر میکند، بدون هیچ کد اضافه |
| Four Digits | طول کد را تعداد خانهها تعیین میکند؛ برای کد چهاررقمی چهار خانه بگذارید. |
| Latin Digits | پیشفرض همیشه فارسی نشان میدهد، صرفنظر از کیبورد یا لوکیل کاربر؛ مقداری که ثبت و ارسال میشود همیشه لاتین میماند |
| Error State | invalid را روی Root بگذارید تا کادر و حلقهٔ فوکوس همهٔ خانهها با هم قرمز شود. |
| Connected Variant | variant="connected" خانهها را در یک نوار کادردار و سایهدار به هم میچسباند؛ برای وقتی به ظاهر متصل و سنتیتر نیاز دارید |
| On Complete | onComplete بهمحض پر شدن همهٔ خانهها صدا زده میشود، با تایپ یا چسباندن، بدون نیاز به فرم؛ مناسب بررسی خودکار کد با یک فراخوانی API. |
| Disabled and Password | با type="password" ارقام مخفی میشوند و با disabled کل فیلد قفل میشود. |
| In a Form | با name کل کد در یک input مخفی ارسال میشود و autoSubmit فرم را بهمحض کامل شدن میفرستد. |
| در حال بررسی (Loading) | کدی که با تکمیل شش رقم، خودکار به سرور بررسی میشود |
دستورالعمل استفاده
تعداد خانهها برابر طول واقعی کد
انجام بده
دقیقاً به تعداد ارقام کدی که میفرستید خانه بگذارید؛ کاربر با یک نگاه میفهمد چند رقم باید وارد کند و کد از پیامک هم کامل جا میشود.
انجام نده
خانههای اضافه یا کمتر از طول کد، هم کاربر را سردرگم میکند و هم چسباندن کد از پیامک را میشکند.
خطا روی همهٔ خانهها
کد واردشده درست نیست.
انجام بده
با invalid روی Root همهٔ خانهها یکجا قرمز میشوند؛ پیام را هم با aria-describedby وصل کنید. کد یک مقدار واحد است، نه شش مقدار جدا.
انجام نده
قرمز کردن یک خانه یا نمایش خطا بدون متن، نه محل مشکل را روشن میکند و نه برای کاربر صفحهخوان قابل فهم است.
گروهبندی برای کدهای بلند
انجام بده
کد ششرقمی را با یک جداکننده به دو گروه سهتایی بشکنید؛ خواندن و بازبینی ارقام برای کاربر سادهتر میشود.
انجام نده
شش خانهٔ چسبیده بدون گروهبندی، مرور و مقایسهٔ کد با پیامک را کندتر میکند.