ورودی عدد بومی (NumberInputLocale)

ورودی عددی بومی‌ساز — ارقام فارسی، عربی یا لاتین را می‌پذیرد، ارقام فارسی را با قابلیت ss01 قلم نمایش می‌دهد و همیشه یک عدد جاوااسکریپتی تمیز به فرم تحویل می‌دهد.

معرفی

NumberInputLocale یک ورودی عددی است که ارقام تایپ‌شده با هر صفحه‌کلیدی (فارسی، عربی یا لاتین) را می‌پذیرد، آن‌ها را به رقم لاتین نرمال می‌کند و از طریق onValueChange همیشه یک number استاندارد جاوااسکریپت — یا null برای فیلد خالی — به فرم تحویل می‌دهد.

مقدار داخل input همیشه با ارقام لاتین نگهداری می‌شود؛ شکل فارسی ارقام را قابلیت ss01 قلم «یکان بخ» هنگام رندر می‌سازد. به این ترتیب کپی‌برداری، جست‌وجوی درون‌صفحه (Ctrl+F) و ارسال بومی فرم (name) همچنان یک عدد ماشین‌خوان تحویل می‌دهند، در حالی که کاربر ارقام فارسی می‌بیند.

چه زمانی استفاده کنیم:

  • هر فیلد عددی در فرم‌های فارسی/عربی که کاربر ممکن است با صفحه‌کلید بومی تایپ کند (بودجه کمپین تخفیف فصلی، سقف هزینه، تعداد پست)
  • وقتی نمایش باید ارقام بومی و جداکننده هزارگان داشته باشد اما مقدار ذخیره‌شده و ارسالی باید عدد خام بماند
  • فیلدهای دارای واحد (تومان، درصد، نفر) که واحد باید داخل خود ورودی دیده شود

چه زمانی استفاده نکنیم:

  • برای متن آزاد یا رشته‌هایی که فقط شبیه عدد هستند (شماره تلفن، کد پستی) — از Input استفاده کنید؛ صفر ابتدای این مقادیر نباید حذف شود
  • برای انتخاب بصری یک عدد در بازه بسته و کوچک — از Slider استفاده کنید
  • برای کد تأیید چندرقمی — از InputOTP استفاده کنید
تومان

مقدار عددی خروجی: 2500000

استفاده

import { NumberInputLocale } from '@partodata/ui'
const [budget, setBudget] = React.useState<number | null>(null)

<NumberInputLocale
  value={budget}
  onValueChange={setBudget}
  unit="تومان"
  min={0}
  allowNegative={false}
  placeholder="مبلغ را وارد کنید"
/>

رفتار نمایش دو مرحله‌ای است: تا وقتی فیلد فوکوس دارد، همان متن تایپ‌شده کاربر (بدون جداکننده هزارگان) نمایش داده می‌شود تا مکان‌نما هنگام ویرایش وسط عدد نپرد؛ با خروج فوکوس (blur) مقدار به بازه min و max محدود شده و با جداکننده هزارگان و تعداد اعشار مشخص‌شده بازنویسی می‌شود. onValueChange در حین تایپ نیز به‌صورت زنده صدا زده می‌شود تا اعتبارسنجی فرم عقب نماند.

حالت‌ها و انواع

زبان ارقام (locale)

سه مقدار fa، ar و en پشتیبانی می‌شود. ورودی کاربر با هر مجموعه رقمی پذیرفته و پیش از پارس به لاتین نرمال می‌شود. locale شکل ارقام را عوض نمی‌کند — مقدار input در هر سه حالت لاتین است و ظاهر فارسی از ss01 قلم می‌آید؛ این مقدار روی ریشه به‌صورت data-locale منتشر می‌شود تا کد مصرف‌کننده و CSS به آن دسترسی داشته باشند.

بازدید
نفر
%
<NumberInputLocale locale="fa" defaultValue={1250000} unit="بازدید" />
<NumberInputLocale locale="ar" defaultValue={1250000} unit="نفر" />
<NumberInputLocale locale="en" defaultValue={4.8} decimals={1} unit="%" />

واحد (unit) و پیشوند (prefix)

unit واحدی است که بعد از عدد خوانده می‌شود: «250,000 تومان». در فارسی و عربی سمت چپ عدد می‌نشیند و در انگلیسی سمت راست آن («250,000 USD»)، و عدد به سمت واحد چیده می‌شود تا این دو کنار هم خوانده شوند. prefix نمادی است که قبل از عدد خوانده می‌شود — علامت‌های پولی مثل «$» در انگلیسی. «تومان»، «ریال» و «٪» فارسی همیشه unit هستند، نه prefix. هر دو جزیره‌ی جهت‌دار جداگانه‌ای (bdi) به زبان فیلد هستند؛ خود عدد همیشه یک رشته‌ی چپ‌به‌راست می‌ماند تا علامت منفی و جداکننده‌ها جابه‌جا نشوند. فاصله‌ی متن تا واحد اندازه‌گیری می‌شود، پس واحد بلند هم روی ارقام نمی‌افتد.

تومان
$
USD

زمین بازی

زمین بازی
تومان
تنظیمات
محتوا
داده
0
ظاهر
کد این نمونه به‌صورت خودکار قابل تولید نیست — برای کد آماده‌ی copy/paste به بخش «استفاده» در بالای صفحه مراجعه کنید.
<NumberInputLocale unit="تومان" min={0} allowNegative={false} />
<NumberInputLocale locale="en" prefix="$" defaultValue={1250} decimals={2} />
<NumberInputLocale locale="en" unit="USD" defaultValue={250000} />

محدوده مجاز (min و max)

مقادیر min و max شامل خود کران هستند و فقط هنگام blur اعمال می‌شوند — وسط تایپ مقدار کاربر دستکاری نمی‌شود. اگر مقدار پس از blur تغییر کند، onValueChange یک بار دیگر با مقدار محدودشده فراخوانی می‌شود.

<NumberInputLocale min={0} max={100} decimals={1} unit="٪" />

اعشار و جداکننده هزارگان

پیش‌فرض ورودی عدد صحیح است (decimals={0}). با مقدار بزرگ‌تر، عدد حداکثر همان تعداد رقم اعشار را می‌پذیرد؛ مقدار مجاز هنگام blur صفرپر می‌شود. اعشار اضافی حذف، قطع یا گرد نمی‌شود: مقدار واقعی مرئی می‌ماند، aria-invalid فعال می‌شود و اعتبارسنجی بومی فرم آن را رد می‌کند. برای نمونه، 1.5 در حالت صحیح به 15 تبدیل نمی‌شود و 12.345 با decimals={2} به‌صورت 12.35 پنهان نمی‌شود. مقدار مجاز 0.29 با دو رقم اعشار معتبر است.

جداکنندهٔ اعشار فارسی/عربی ٫ به نقطه و جداکنندهٔ هزارگان ٬ به رشتهٔ خالی نرمال می‌شود؛ ورودی با ارقام فارسی یا عربی، همان مقدار عددی را به callback می‌فرستد. جداکننده هزارگان نمایشی به‌صورت پیش‌فرض فعال است و با thousandSeparator={false} خاموش می‌شود.

<NumberInputLocale decimals={2} thousandSeparator={false} />

اعشار اضافی مرئی می‌ماند و فرم را نامعتبر می‌کند.

عدد واقعی callback: تعداد 1.5، قیمت 12.345

onValueChange عدد واقعی را حتی در حالت precision نامعتبر به مصرف‌کننده می‌دهد؛ null به معنای پاک‌شدن فیلد است. پیش از ذخیره، اعتبار فرم و قواعد دامنهٔ محصول را بررسی کنید. ارسال بومی فرم مقدار نامعتبر را متوقف می‌کند؛ دکمهٔ بیرون فرم یا ارسال دستی باید checkValidity() یا reportValidity() فیلد و guard عددی مناسب را صریحاً بررسی کند.

اعداد منفی

به‌صورت پیش‌فرض علامت منفی پذیرفته می‌شود. با allowNegative={false} مقدار منفی مرئی و نامعتبر می‌ماند و callback همان عدد منفی را می‌فرستد؛ علامت منفی حذف نمی‌شود تا -5 به مبلغ دیگری مانند 5 تبدیل نشود. اگر min={0} هم داده شود، محدودسازی صریح هنگام blur طبق معمول مقدار را به 0 می‌رساند:

<NumberInputLocale allowNegative={false} min={0} />

کنترل‌شده و کنترل‌نشده

مانند سایر ورودی‌ها هر دو حالت پشتیبانی می‌شود: با value و onValueChange کنترل‌شده، و با defaultValue کنترل‌نشده. مقدار null در هر دو حالت به معنای فیلد خالی است.

// کنترل‌نشده — فقط مقدار اولیه
<NumberInputLocale defaultValue={5000} onValueChange={(next) => console.log(next)} />

راهنمای استفاده

بکنید

  • مقدار را همیشه به‌صورت number یا null نگه دارید و از onValueChange بخوانید — پارس و نرمال‌سازی ارقام کار خود کامپوننت است. - برای رد مقدار منفی از allowNegative={false} استفاده کنید؛ min={0} را تنها وقتی بدهید که محدودسازی مقدار به صفر در blur رفتار موردنظر فرم است. قواعد دامنهٔ محصول را پیش از ارسال جداگانه بررسی کنید. - واحد فیلد را با prop unit نشان دهید و همان واحد را در Label یا aria-label هم تکرار کنید تا برای صفحه‌خوان‌ها نیز روشن باشد. - برای فرم‌های چندزبانه، locale را از تنظیمات زبان کاربر بگیرید؛ شکل ارقام از قلم می‌آید، پس نیازی به تبدیل دستی رقم در کد مصرف‌کننده نیست.

نکنید

  • از این کامپوننت برای شماره تلفن، کد ملی یا کد پستی استفاده نکنید — این مقادیر رشته هستند و صفر ابتدایشان نباید حذف شود؛ از Input استفاده کنید. - مقدار نمایشی داخل فیلد را خودتان دوباره فرمت نکنید (مثلاً با افزودن جداکننده در onValueChange) — چرخه فرمت‌مجدد، مکان‌نمای کاربر را می‌پراند. - انتظار نداشته باشید min و max وسط تایپ اعمال شوند — محدودسازی عمداً به blur موکول شده تا ویرایش نیمه‌کاره خراب نشود؛ اعتبارسنجی لحظه‌ای فرم را جداگانه انجام دهید.
  • واحد را به‌صورت متن داخل placeholder یا بعد از فیلد تکرار نکنید وقتی unit تنظیم شده — دو بار نمایش واحد گیج‌کننده است.

Props

کامپوننت علاوه بر موارد زیر، همه ویژگی‌های بومی input (مانند id، placeholder، disabled، readOnly و صفات aria-*) را می‌پذیرد؛ فقط type، value، defaultValue، onChange و size بومی کنار گذاشته شده‌اند. ref نیز مستقیماً به المنت input می‌رسد.

Prop

Type

دسترسی‌پذیری

  • از یک input بومی با type="text" و inputMode="decimal" استفاده می‌کند — موبایل‌ها صفحه‌کلید عددی نشان می‌دهند بدون رفتارهای ناخواسته type="number" مرورگر.
  • جهت فیلد همیشه dir="ltr" با تراز انتهایی است تا عدد در فرم‌های RTL هم به شکل طبیعی خوانده شود.
  • کاربر با هر صفحه‌کلیدی (فارسی، عربی، لاتین) می‌تواند تایپ کند؛ نرمال‌سازی ارقام خودکار است و خطای «رقم نامعتبر» رخ نمی‌دهد.
  • پسوند unit یک عنصر تزئینی است و به‌صورت برنامه‌ای به فیلد متصل نیست — واحد را در Label متصل با htmlFor یا در aria-label هم ذکر کنید.
  • همه صفات بومی از جمله aria-invalid عبور داده می‌شوند. اعشار اضافی یا منفیِ نامجاز، خودکار aria-invalid و custom validity را فعال می‌کند؛ با اصلاح یا پاک‌کردن مقدار خطای داخلی پاک می‌شود و وضعیت خطای مصرف‌کننده همچنان حفظ می‌شود. استایل حالت خطا از Input پایه به ارث می‌رسد.
  • این کامپوننت spinbutton نیست: دکمه افزایش/کاهش و کلیدهای جهت‌نما برای تغییر مقدار ندارد؛ تعامل همان تایپ آزاد است.

تعامل با کیبورد

  • Tab: انتقال فوکوس به فیلد؛ با ورود فوکوس، جداکننده‌های هزارگان حذف می‌شوند تا ویرایش ساده‌تر شود - خروج فوکوس: محدودسازی به بازه مجاز و بازنویسی نمایش با جداکننده هزارگان - در حالت disabled فیلد از ترتیب فوکوس خارج می‌شود

کامپوننت‌های مرتبط

  • Input — اگر مقدار در واقع رشته است (شماره تلفن، کد پستی، متن آزاد) و نباید به عدد تبدیل شود
  • Input — اگر ورودی به واحد، آیکون یا دکمه کنارش نیاز دارد (startAdornment/endAdornment)
  • Slider — اگر انتخاب عدد در یک بازه بسته و کوچک است و بازخورد بصری مهم‌تر از تایپ دقیق است
  • InputOTP — اگر ورودی یک کد عددی چندرقمی با خانه‌های جدا است، نه یک مقدار عددی