Input OTPv1.0.1

فیلد کد تأیید پیامکی: هر رقم یک خانه، چسباندن کد از پیامک، حرکت خودکار بین خانه‌ها و پاک‌کردن با Backspace. کاربر می‌تواند ۱۲۳۴۵۶ فارسی تایپ کند و مقداری که به سرور می‌رسد همیشه لاتین است.

ری‌اکت ۱۹ و Next.js با پیاده‌سازی دسترس‌پذیری داخلی دیگویو ۳ با Composition API — هنوز برای این کامپوننت پورت نشدهSvelte ۵ با runes — هنوز برای این کامپوننت پورت نشدهانگولار با signals و دایرکتیوهای standalone — هنوز برای این کامپوننت پورت نشده

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

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

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

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

نصب

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

پکیج‌منیجر پیش‌فرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/input-otp.json
pnpm dlx digdesign@latest add https://docs.digdesign.ir/r/input-otp.json
yarn dlx digdesign@latest add https://docs.digdesign.ir/r/input-otp.json
bunx --bun digdesign@latest add https://docs.digdesign.ir/r/input-otp.json

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

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

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

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

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

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

استفاده

"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 پورت نشده است.

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

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

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

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

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

ترکیب اجزا

بدون هیچ وابستگی بیرونی است: هر خانه یک input واقعی و مستقل است، نه یک div که ظاهر ورودی را شبیه‌سازی می‌کند.

همین یعنی مکان‌نما، انتخاب متن و اتوفیل کد پیامک روی iOS/Android دقیقاً همان رفتار پیش‌فرض مرورگر را دارند، بدون نیاز به شبیه‌سازی دستی.

ریشه همیشه dir=ltr می‌گیرد چون کد از چپ به راست خوانده و وارد می‌شود، حتی وسط یک صفحهٔ راست‌به‌چپ.

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

دسترس‌پذیری

  • با autocomplete=one-time-code مرورگر و iOS کد پیامک را پیشنهاد می‌دهند؛ این را از ریشه برندارید.
  • inputMode=numeric صفحه‌کلید عددی موبایل را باز می‌کند.
  • ناوبری بین خانه‌ها با کلیدهای جهت‌دار است و Backspace روی خانهٔ خالی به خانهٔ قبلی برمی‌گردد.
  • برای کل گروه یک Label با htmlFor بگذارید و در حالت خطا invalid را روی Root بدهید تا هر شش خانه با هم قرمز شوند.
  • با autoSubmit فرم به‌محض کامل شدن کد ارسال می‌شود؛ اگر کاربر ممکن است اشتباه تایپ کند، بهتر است دکمهٔ تأیید صریح داشته باشید.

مرجع API

InputOTP

ویژگینوعپیش‌فرضتوضیح
value / onValueChangestring / (value: string) => void—حالت کنترل‌شده؛ مقدار همیشه رشته‌ای از ارقام لاتین است.
defaultValuestring—مقدار اولیه در حالت کنترل‌نشده.
sanitizeValue(value: string) => stringتبدیل ارقام فارسی و حذف غیرعددپاک‌سازی ورودی پیش از ثبت؛ برای کدهای حرفی‌عددی بازنویسی کنید.
validationType"alpha" | "numeric" | "alphanumeric" | "none""none"اعتبارسنجی هر نویسه پیش از پذیرفتنش؛ چون خودمان با sanitizeValue پاک‌سازی می‌کنیم روی none است.
type"text" | "password""text"مخفی کردن ارقام واردشده.
variant"separated" | "connected" | "filled""separated"separated خانه‌های جدا و گِرد با پس‌زمینهٔ خاکستری خنثی است، پرکاربردترین حالت، بدون سایه، برای هرجا از جمله روی Card/Surface. connected آن‌ها را در یک نوار کادردار و سایه‌دار به هم می‌چسباند. filled خانه‌های توپرِ خاکستری بدون کادر و سایه است.
invalidbooleanfalseخطا را روی همهٔ خانه‌ها یک‌جا می‌نشاند؛ نیازی به تکرار aria-invalid روی تک‌تک خانه‌ها نیست.
faDigitsbooleantrueنمایش ارقام به فارسی؛ مقدار ثبت‌شده همیشه لاتین می‌ماند (مثل faDigits در Input). پیش‌فرض روشن است و به کیبورد یا لوکیل کاربر بستگی ندارد؛ برای موارد خاص که کد باید عیناً لاتین دیده شود با faDigits={false} خاموشش کنید.
onComplete(value: string) => void—هر بار همهٔ خانه‌ها پر شوند صدا زده می‌شود، با تایپ، چسباندن یا اتوفیل، صرف‌نظر از autoSubmit.
autoSubmitbooleanfalseارسال خودکار نزدیک‌ترین فرم به‌محض پر شدن همهٔ خانه‌ها.
name / formstring—برای ارسال در فرم؛ کل کد در یک input مخفی قرار می‌گیرد.
disabled / readOnlybooleanfalseقفل کردن ورودی‌ها.

InputOTPSlot

ویژگینوعپیش‌فرضتوضیح
indexnumber—جای خانه در ترتیب؛ دادنش از پرش ظاهری بعد از هیدریشن جلوگیری می‌کند.
aria-invalidboolean—بازنویسی دستی خطا برای همین یک خانه؛ برای خطای کل کد از invalid روی Root استفاده کنید.
data-filled"true" | undefined—attribute فقط‌خواندنی؛ وقتی خانه رقم دارد true است، قلاب استایل‌دهی سفارشی با data-[filled=true]:.

InputOTPGroup / InputOTPSeparator

ویژگینوعپیش‌فرضتوضیح
InputOTPGroupReact.ComponentProps<"div">—در variant=separated (پیش‌فرض) هر خانه گوشهٔ خودش را دارد و با فاصله می‌نشیند؛ در connected خانه‌ها را می‌چسباند و فقط گوشه‌های اول و آخر منطقی گِرد می‌شوند.
InputOTPSeparatorReact.ComponentProps<"div">—خط تیرهٔ بین دو گروه؛ role=separator دارد و خوانده نمی‌شود.

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

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

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

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

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

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