persian-number-input 4.3.2 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.fa.md +190 -240
  2. package/README.md +152 -230
  3. package/dist/components/PersianNumberInput.d.ts +1 -1
  4. package/dist/components/PersianNumberInput.d.ts.map +1 -1
  5. package/dist/components/PersianNumberInput.js +22 -17
  6. package/dist/components/PersianNumberInput.js.map +1 -1
  7. package/dist/components/PersianNumberInput.test.d.ts +2 -0
  8. package/dist/components/PersianNumberInput.test.d.ts.map +1 -0
  9. package/dist/components/PersianNumberInput.test.js +394 -0
  10. package/dist/components/PersianNumberInput.test.js.map +1 -0
  11. package/dist/hooks/useCursorManager.d.ts +4 -0
  12. package/dist/hooks/useCursorManager.d.ts.map +1 -0
  13. package/dist/hooks/useCursorManager.js +19 -0
  14. package/dist/hooks/useCursorManager.js.map +1 -0
  15. package/dist/hooks/useNumberFormatter.d.ts +18 -0
  16. package/dist/hooks/useNumberFormatter.d.ts.map +1 -0
  17. package/dist/hooks/useNumberFormatter.js +29 -0
  18. package/dist/hooks/useNumberFormatter.js.map +1 -0
  19. package/dist/hooks/useNumberValidation.d.ts +11 -0
  20. package/dist/hooks/useNumberValidation.d.ts.map +1 -0
  21. package/dist/hooks/useNumberValidation.js +22 -0
  22. package/dist/hooks/useNumberValidation.js.map +1 -0
  23. package/dist/hooks/useNumericInputEvents.d.ts +18 -0
  24. package/dist/hooks/useNumericInputEvents.d.ts.map +1 -0
  25. package/dist/hooks/useNumericInputEvents.js +39 -0
  26. package/dist/hooks/useNumericInputEvents.js.map +1 -0
  27. package/dist/hooks/usePersianNumberInput.d.ts +7 -2
  28. package/dist/hooks/usePersianNumberInput.d.ts.map +1 -1
  29. package/dist/hooks/usePersianNumberInput.js +66 -63
  30. package/dist/hooks/usePersianNumberInput.js.map +1 -1
  31. package/dist/test-utils.d.ts +7 -0
  32. package/dist/test-utils.d.ts.map +1 -0
  33. package/dist/test-utils.js +27 -0
  34. package/dist/test-utils.js.map +1 -0
  35. package/dist/utils/digitUtils.d.ts +4 -0
  36. package/dist/utils/digitUtils.d.ts.map +1 -1
  37. package/dist/utils/digitUtils.js +44 -17
  38. package/dist/utils/digitUtils.js.map +1 -1
  39. package/dist/utils/keyFilter.d.ts +16 -0
  40. package/dist/utils/keyFilter.d.ts.map +1 -0
  41. package/dist/utils/keyFilter.js +31 -0
  42. package/dist/utils/keyFilter.js.map +1 -0
  43. package/dist/utils/validation.d.ts +22 -0
  44. package/dist/utils/validation.d.ts.map +1 -0
  45. package/dist/utils/validation.js +85 -0
  46. package/dist/utils/validation.js.map +1 -0
  47. package/package.json +19 -7
package/README.fa.md CHANGED
@@ -1,6 +1,8 @@
1
- # ورودی اعداد فارسی و عربی
1
+ # ورودی عدد فارسی برای React — تبدیل خودکار ارقام فارسی، عربی و RTL
2
2
 
3
- یک کتابخانه React سبک و قدرتمند برای مدیریت ورودی اعداد فارسی و عربی با تبدیل خودکار ارقام، فرمت‌دهی و پشتیبانی از چند زبان.
3
+ English | [فارسی](./README.fa.md)
4
+
5
+ یک کامپوننت React برای **ورودی اعداد فارسی و عربی** با تبدیل خودکار ارقام، جداکننده هزارگان، کنترل دقت اعشاری و پشتیبانی کامل از RTL. کاربر ارقام فارسی تایپ می‌کند، فرم شما عدد انگلیسی تمیز دریافت می‌کند — بدون هیچ تبدیل دستی.
4
6
 
5
7
  [![نسخه npm](https://img.shields.io/npm/v/persian-number-input.svg)](https://www.npmjs.com/package/persian-number-input)
6
8
  [![دانلودهای npm](https://img.shields.io/npm/dm/persian-number-input.svg)](https://www.npmjs.com/package/persian-number-input)
@@ -9,34 +11,39 @@
9
11
 
10
12
  ## 🚀 [دموی آنلاین](https://persian-number-input.netlify.app/)
11
13
 
12
- کامپوننت را به صورت زنده تجربه کنید!
13
-
14
14
  ---
15
15
 
16
- ## 📊 حجم باندل
16
+ ## چرا این پکیج؟
17
+
18
+ ساختن فرم برای کاربران فارسی‌زبان چالش‌های واقعی داره:
17
19
 
18
- این کتابخانه فوق‌العاده سبک است:
20
+ - کاربر `۱۲۳۴` تایپ می‌کنه — API شما `1234` می‌خواد
21
+ - `<input type="number">` اصلاً ارقام فارسی یا عربی رو قبول نمی‌کنه
22
+ - وقتی جداکننده هزارگان اضافه میشه، cursor جهش می‌کنه
23
+ - جداکننده اعشاری در فارسی `٫` هست نه `.`
24
+ - ورودی‌های RTL نیاز به تنظیمات خاص دارن
25
+
26
+ این پکیج همه اینا رو خودکار حل می‌کنه:
19
27
 
20
28
  ```
21
- persian-number-input: تنها ~1KB (فشرده شده)
29
+ کاربر تایپ می‌کند: ۱۲۳۴۵۶۷
30
+ نمایش داده می‌شود: ۱,۲۳۴,۵۶۷
31
+ فرم دریافت می‌کند: "1234567"
22
32
  ```
23
33
 
24
- ![مقایسه حجم باندل](./public/size.png)
25
-
26
34
  ---
27
35
 
28
36
  ## ✨ امکانات
29
37
 
30
- - 🔢 **تبدیل خودکار ارقام** - تبدیل یکپارچه ارقام فارسی (۰-۹) و عربی (٠-٩) به انگلیسی و بالعکس
31
- - 🌍 **پشتیبانی چندزبانه** - پشتیبانی داخلی از فارسی (fa)، عربی (ar) و انگلیسی (en)
32
- - 📊 **فرمت‌دهی اعداد** - جداکننده هزارگان خودکار با کاراکترهای قابل تنظیم
33
- - 💰 **آماده برای ارز** - امکان افزودن پیشوند، پسوند و جداکننده اعشاری سفارشی
34
- - ⚡ **سبک و سریع** - حجم بسیار کم با صفر وابستگی (به جز decimal.js برای دقت)
35
- - 🎯 **Type-Safe** - پشتیبانی کامل TypeScript با تعاریف تایپ کامل
36
- - **قابل دسترس** - پیروی از بهترین شیوه‌های دسترسی‌پذیری
37
- - 🎨 **قابل سفارشی‌سازی** - گزینه‌های پیکربندی گسترده برای هر نیازی
38
- - 🔄 **فرمت‌دهی لحظه‌ای** - فرمت کردن اعداد همزمان با تایپ کاربر با حفظ موقعیت مکان‌نما
39
- - ✅ **اعتبارسنجی** - کنترل داخلی مقادیر min/max و دقت اعشاری
38
+ - 🔢 **تبدیل خودکار ارقام** فارسی (۰-۹) و عربی (٠-٩) به انگلیسی و برعکس
39
+ - 🌍 **چند زبانه** فارسی (`fa`)، عربی (`ar`)، انگلیسی (`en`)
40
+ - 📊 **جداکننده هزارگان** قابل تنظیم با هر کاراکتری
41
+ - 💰 **آماده برای ارز** پشتیبانی از پسوند (تومان، ریال، ر.س) و جداکننده اعشاری سفارشی
42
+ - ⚡ **فقط کیلوبایت** بدون هیچ dependency اضافه
43
+ - 🎯 **TypeScript** تعریف تایپ کامل
44
+ - 🔄 **حفظ موقعیت cursor** بدون جهش هنگام فرمت‌دهی
45
+ - **اعتبارسنجی min/max** کنترل بازه مجاز و دقت اعشاری
46
+ - **دسترس‌پذیر** رعایت استانداردهای WCAG
40
47
 
41
48
  ---
42
49
 
@@ -44,22 +51,18 @@ persian-number-input: تنها ~1KB (فشرده شده)
44
51
 
45
52
  ```bash
46
53
  npm install persian-number-input
47
- ```
48
-
49
- ```bash
54
+ # یا
50
55
  yarn add persian-number-input
51
- ```
52
-
53
- ```bash
56
+ # یا
54
57
  pnpm add persian-number-input
55
58
  ```
56
59
 
60
+ > **نیازمندی‌ها:** React 16.8 به بالا — سازگار با Next.js، Vite، و CRA.
61
+
57
62
  ---
58
63
 
59
64
  ## 🎯 شروع سریع
60
65
 
61
- ### استفاده ساده
62
-
63
66
  ```tsx
64
67
  import { PersianNumberInput } from "persian-number-input";
65
68
 
@@ -68,19 +71,19 @@ function App() {
68
71
  <PersianNumberInput
69
72
  initialValue={1234567}
70
73
  locale="fa"
71
- onValueChange={(value) => console.log(value)}
74
+ onValueChange={(value) => console.log(value)} // "1234567"
72
75
  />
73
76
  );
74
77
  }
75
78
  ```
76
79
 
77
- **خروجی:** `۱,۲۳۴,۵۶۷`
80
+ خروجی نمایشی: `۱,۲۳۴,۵۶۷`
78
81
 
79
82
  ---
80
83
 
81
- ## 📚 نمونه‌های کاربردی
84
+ ## 📚 مثال‌های کاربردی
82
85
 
83
- ### ورودی مبلغ (تومان ایران)
86
+ ### ورودی مبلغ تومان
84
87
 
85
88
  ```tsx
86
89
  <PersianNumberInput
@@ -93,46 +96,44 @@ function App() {
93
96
  />
94
97
  ```
95
98
 
96
- **خروجی:** `۵,۰۰۰,۰۰۰ تومان`
99
+ خروجی: `۵,۰۰۰,۰۰۰ تومان`
97
100
 
98
101
  ---
99
102
 
100
- ### اعداد اعشاری با جداکننده سفارشی
103
+ ### ورودی ریال با اعتبارسنجی
101
104
 
102
105
  ```tsx
103
106
  <PersianNumberInput
104
- initialValue={1234.56}
107
+ initialValue={0}
105
108
  locale="fa"
106
- maxDecimals={2}
107
- decimalChar="٫"
108
- separatorChar=","
109
+ min={0}
110
+ max={999999999}
111
+ suffix="ریال"
112
+ showZero={true}
109
113
  onValueChange={(value) => console.log(value)}
110
114
  />
111
115
  ```
112
116
 
113
- **خروجی:** `۱,۲۳۴٫۵۶`
114
-
115
117
  ---
116
118
 
117
- ### ورودی قیمت با اعتبارسنجی
119
+ ### عدد اعشاری با جداکننده فارسی
118
120
 
119
121
  ```tsx
120
122
  <PersianNumberInput
121
- initialValue={0}
123
+ initialValue={1234.56}
122
124
  locale="fa"
123
- min={0}
124
- max={999999999}
125
- suffix="ریال"
126
- showZero={true}
125
+ maxDecimals={2}
126
+ decimalChar="٫"
127
+ separatorChar=","
127
128
  onValueChange={(value) => console.log(value)}
128
129
  />
129
130
  ```
130
131
 
131
- **خروجی:** `۰ ریال`
132
+ خروجی: `۱,۲۳۴٫۵۶`
132
133
 
133
134
  ---
134
135
 
135
- ### زبان عربی
136
+ ### زبان عربی (ریال سعودی)
136
137
 
137
138
  ```tsx
138
139
  <PersianNumberInput
@@ -144,7 +145,39 @@ function App() {
144
145
  />
145
146
  ```
146
147
 
147
- **خروجی:** `٩٨٧,٦٥٤ ر.س`
148
+ خروجی: `٩٨٧,٦٥٤ ر.س`
149
+
150
+ ---
151
+
152
+ ### استفاده با React Hook Form
153
+
154
+ ```tsx
155
+ import { useForm, Controller } from "react-hook-form";
156
+ import { PersianNumberInput } from "persian-number-input";
157
+
158
+ function ProductForm() {
159
+ const { control, handleSubmit } = useForm();
160
+
161
+ return (
162
+ <form onSubmit={handleSubmit(console.log)}>
163
+ <Controller
164
+ name="price"
165
+ control={control}
166
+ rules={{ required: true }}
167
+ render={({ field }) => (
168
+ <PersianNumberInput
169
+ locale="fa"
170
+ suffix="تومان"
171
+ onValueChange={field.onChange}
172
+ initialValue={field.value}
173
+ />
174
+ )}
175
+ />
176
+ <button type="submit">ثبت</button>
177
+ </form>
178
+ );
179
+ }
180
+ ```
148
181
 
149
182
  ---
150
183
 
@@ -161,10 +194,7 @@ function CustomInput() {
161
194
  maxDecimals: 2,
162
195
  min: 0,
163
196
  max: 1000000,
164
- onValueChange: (val) => {
165
- console.log("مقدار خام:", val); // "1000"
166
- console.log("مقدار نمایشی:", value); // "۱,۰۰۰"
167
- },
197
+ onValueChange: (val) => console.log("مقدار انگلیسی:", val),
168
198
  });
169
199
 
170
200
  return (
@@ -173,7 +203,7 @@ function CustomInput() {
173
203
  value={value}
174
204
  onChange={onChange}
175
205
  onBlur={onBlur}
176
- className="custom-input"
206
+ dir="rtl"
177
207
  />
178
208
  );
179
209
  }
@@ -181,25 +211,66 @@ function CustomInput() {
181
211
 
182
212
  ---
183
213
 
214
+ ### ماشین‌حساب وام
215
+
216
+ ```tsx
217
+ import { useState } from "react";
218
+ import { PersianNumberInput } from "persian-number-input";
219
+
220
+ function LoanCalculator() {
221
+ const [principal, setPrincipal] = useState<string>();
222
+ const [rate, setRate] = useState<string>();
223
+ const [years, setYears] = useState<string>();
224
+
225
+ const calculateMonthlyPayment = () => {
226
+ if (!principal || !rate || !years) return 0;
227
+ const p = parseFloat(principal);
228
+ const r = parseFloat(rate) / 100 / 12;
229
+ const n = parseFloat(years) * 12;
230
+ return (p * r * Math.pow(1 + r, n)) / (Math.pow(1 + r, n) - 1);
231
+ };
232
+
233
+ return (
234
+ <div className="space-y-4">
235
+ <div>
236
+ <label>مبلغ وام:</label>
237
+ <PersianNumberInput locale="fa" suffix="تومان" onValueChange={setPrincipal} min={0} />
238
+ </div>
239
+ <div>
240
+ <label>نرخ سود (٪):</label>
241
+ <PersianNumberInput locale="fa" maxDecimals={2} onValueChange={setRate} min={0} max={100} />
242
+ </div>
243
+ <div>
244
+ <label>مدت زمان (سال):</label>
245
+ <PersianNumberInput locale="fa" onValueChange={setYears} min={1} max={30} />
246
+ </div>
247
+ <p>پرداخت ماهیانه: {calculateMonthlyPayment().toLocaleString("fa-IR")} تومان</p>
248
+ </div>
249
+ );
250
+ }
251
+ ```
252
+
253
+ ---
254
+
184
255
  ## 🛠️ مرجع API
185
256
 
186
- ### Props کامپوننت PersianNumberInput
257
+ ### Props کامپوننت `PersianNumberInput`
187
258
 
188
- | ویژگی | نوع | پیش‌فرض | توضیحات |
189
- | ---------------- | -------------------------------------- | ----------- | --------------------------------------------------------------- |
190
- | `initialValue` | `number \| string` | `undefined` | مقدار اولیه ورودی |
191
- | `locale` | `"fa" \| "ar" \| "en"` | `"fa"` | زبان برای تبدیل ارقام |
192
- | `separatorCount` | `number` | `3` | تعداد ارقام بین جداکننده‌ها |
193
- | `separatorChar` | `string` | `","` | کاراکتر جداکننده هزارگان |
194
- | `decimalChar` | `string` | خودکار | کاراکتر جداکننده اعشار |
195
- | `suffix` | `string` | `undefined` | متن پسوند (مثل واحد پول) |
196
- | `maxDecimals` | `number` | `undefined` | حداکثر رقم اعشار مجاز |
197
- | `min` | `number` | `undefined` | کمترین مقدار مجاز |
198
- | `max` | `number` | `undefined` | بیشترین مقدار مجاز |
199
- | `showZero` | `boolean` | `false` | نمایش صفر وقتی مقدار خالی است |
200
- | `onValueChange` | `(value: string \| undefined) => void` | `undefined` | تابع فراخوانی هنگام تغییر مقدار (ارقام انگلیسی خام برمی‌گرداند) |
259
+ | ویژگی | نوع | پیش‌فرض | توضیحات |
260
+ | ---------------- | -------------------------------------- | ----------- | ---------------------------------------------------------------- |
261
+ | `initialValue` | `number \| string` | `undefined` | مقدار اولیه ورودی |
262
+ | `locale` | `"fa" \| "ar" \| "en"` | `"fa"` | زبان فارسی، عربی یا انگلیسی |
263
+ | `separatorCount` | `number` | `3` | تعداد ارقام بین جداکننده‌ها (۳ = هزارگان) |
264
+ | `separatorChar` | `string` | `","` | کاراکتر جداکننده هزارگان |
265
+ | `decimalChar` | `string` | خودکار | جداکننده اعشار (`٫` برای fa، `.` برای en) |
266
+ | `suffix` | `string` | `undefined` | پسوند مثل `تومان`، `ریال` |
267
+ | `maxDecimals` | `number` | `undefined` | حداکثر رقم اعشار مجاز |
268
+ | `min` | `number` | `undefined` | کمترین مقدار مجاز |
269
+ | `max` | `number` | `undefined` | بیشترین مقدار مجاز |
270
+ | `showZero` | `boolean` | `false` | نمایش صفر وقتی ورودی خالی است |
271
+ | `onValueChange` | `(value: string \| undefined) => void` | `undefined` | callback هنگام تغییر همیشه ارقام انگلیسی برمی‌گرداند |
201
272
 
202
- تمام props استاندارد HTML input نیز پشتیبانی می‌شوند.
273
+ تمام props استاندارد `<input>` مثل `className`، `style`، `placeholder` و `disabled` هم پشتیبانی می‌شن.
203
274
 
204
275
  ---
205
276
 
@@ -207,252 +278,131 @@ function CustomInput() {
207
278
 
208
279
  #### `transformNumber(rawValue, options)`
209
280
 
210
- یک رشته عددی را بر اساس زبان و تنظیمات فرمت می‌کند.
281
+ فرمت‌دهی یک رشته عددی بر اساس زبان و تنظیمات:
211
282
 
212
283
  ```tsx
213
284
  import { transformNumber } from "persian-number-input";
214
285
 
215
- const formatted = transformNumber("1234567.89", {
286
+ transformNumber("1234567.89", {
216
287
  locale: "fa",
217
288
  separatorCount: 3,
218
289
  separatorChar: ",",
219
290
  maxDecimals: 2,
220
291
  suffix: "تومان",
221
292
  });
222
-
223
- console.log(formatted); // "۱,۲۳۴,۵۶۷٫۸۹ تومان"
293
+ // ← "۱,۲۳۴,۵۶۷٫۸۹ تومان"
224
294
  ```
225
295
 
226
296
  #### `toEnglishDigits(str, decimalChar?)`
227
297
 
228
- ارقام فارسی/عربی را به انگلیسی تبدیل می‌کند.
298
+ تبدیل ارقام فارسی یا عربی به انگلیسی:
229
299
 
230
300
  ```tsx
231
301
  import { toEnglishDigits } from "persian-number-input";
232
302
 
233
- console.log(toEnglishDigits("۱۲۳۴")); // "1234"
234
- console.log(toEnglishDigits("٩٨٧٦")); // "9876"
303
+ toEnglishDigits("۱۲۳۴"); // "1234"
304
+ toEnglishDigits("٩٨٧٦"); // "9876"
235
305
  ```
236
306
 
237
307
  #### `toLocalizedDigits(numStr, locale)`
238
308
 
239
- ارقام انگلیسی را به ارقام محلی تبدیل می‌کند.
309
+ تبدیل ارقام انگلیسی به زبان مقصد:
240
310
 
241
311
  ```tsx
242
312
  import { toLocalizedDigits } from "persian-number-input";
243
313
 
244
- console.log(toLocalizedDigits("1234", "fa")); // "۱۲۳۴"
245
- console.log(toLocalizedDigits("5678", "ar")); // "٥٦٧٨"
314
+ toLocalizedDigits("1234", "fa"); // "۱۲۳۴"
315
+ toLocalizedDigits("5678", "ar"); // "٥٦٧٨"
246
316
  ```
247
317
 
248
318
  #### `sanitizeNumericInput(value, maxDecimals?, decimalChar?)`
249
319
 
250
- ورودی عددی را پاکسازی و اعتبارسنجی می‌کند.
320
+ پاکسازی ورودی و اعمال محدودیت اعشار:
251
321
 
252
322
  ```tsx
253
323
  import { sanitizeNumericInput } from "persian-number-input";
254
324
 
255
- console.log(sanitizeNumericInput("۱۲۳abc۴۵۶", 2)); // "123456"
256
- console.log(sanitizeNumericInput("12.345.67", 2)); // "12.34"
325
+ sanitizeNumericInput("۱۲۳abc۴۵۶", 2); // "123456"
326
+ sanitizeNumericInput("12.345.67", 2); // "12.34"
257
327
  ```
258
328
 
259
329
  ---
260
330
 
261
331
  ## 🎨 استایل‌دهی
262
332
 
263
- کامپوننت تمام props استاندارد input را می‌پذیرد، از جمله `className` و `style`:
264
-
265
333
  ```tsx
266
334
  <PersianNumberInput
267
- initialValue={1000}
268
335
  locale="fa"
269
- className="custom-input"
270
- style={{
271
- padding: "12px",
272
- fontSize: "16px",
273
- border: "2px solid #4F46E5",
274
- borderRadius: "8px",
275
- textAlign: "right",
276
- }}
336
+ className="w-full px-4 py-3 text-lg border-2 border-indigo-500 rounded-lg text-right focus:outline-none focus:ring-2 focus:ring-indigo-600"
277
337
  />
278
338
  ```
279
339
 
280
- ### با Tailwind CSS
281
-
282
- ```tsx
283
- <PersianNumberInput
284
- initialValue={1000}
285
- locale="fa"
286
- className="w-full px-4 py-3 text-lg border-2 border-indigo-500 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-600 text-right"
287
- />
288
- ```
340
+ برای چیدمان RTL، `dir="rtl"` رو روی wrapper بذارید یا `style={{ textAlign: "right" }}` رو مستقیم پاس بدید.
289
341
 
290
342
  ---
291
343
 
292
- ## 🌟 مثال‌های پیشرفته
293
-
294
- ### ماشین حساب مالی
295
-
296
- ```tsx
297
- import { useState } from "react";
298
- import { PersianNumberInput } from "persian-number-input";
299
-
300
- function LoanCalculator() {
301
- const [principal, setPrincipal] = useState<string>();
302
- const [rate, setRate] = useState<string>();
303
- const [years, setYears] = useState<string>();
304
-
305
- const calculateMonthlyPayment = () => {
306
- if (!principal || !rate || !years) return 0;
307
- const p = parseFloat(principal);
308
- const r = parseFloat(rate) / 100 / 12;
309
- const n = parseFloat(years) * 12;
310
- return (p * r * Math.pow(1 + r, n)) / (Math.pow(1 + r, n) - 1);
311
- };
312
-
313
- return (
314
- <div className="space-y-4">
315
- <div>
316
- <label>مبلغ وام:</label>
317
- <PersianNumberInput
318
- locale="fa"
319
- suffix="تومان"
320
- onValueChange={setPrincipal}
321
- min={0}
322
- />
323
- </div>
324
- <div>
325
- <label>نرخ سود (٪):</label>
326
- <PersianNumberInput
327
- locale="fa"
328
- maxDecimals={2}
329
- onValueChange={setRate}
330
- min={0}
331
- max={100}
332
- />
333
- </div>
334
- <div>
335
- <label>مدت زمان (سال):</label>
336
- <PersianNumberInput
337
- locale="fa"
338
- onValueChange={setYears}
339
- min={1}
340
- max={30}
341
- />
342
- </div>
343
- <p>
344
- پرداخت ماهیانه: {calculateMonthlyPayment().toLocaleString("fa-IR")}{" "}
345
- تومان
346
- </p>
347
- </div>
348
- );
349
- }
350
- ```
351
-
352
- ---
344
+ ## سوالات متداول
353
345
 
354
- ### یکپارچگی با فرم
346
+ **آیا با Next.js و App Router کار می‌کنه؟**
347
+ بله. چون کامپوننت client-side هست، `"use client"` رو بالای فایلت بذار.
355
348
 
356
- ```tsx
357
- import { useForm, Controller } from "react-hook-form";
358
- import { PersianNumberInput } from "persian-number-input";
349
+ **مقدار برگشتی `onValueChange` چیه؟**
350
+ همیشه رشته‌ای از ارقام انگلیسی مثلاً `"1234567"` — صرف‌نظر از اینکه چه locale‌ای نمایش داده میشه.
359
351
 
360
- function ProductForm() {
361
- const { control, handleSubmit } = useForm();
352
+ **آیا با `input` داخل یک فرم native کار می‌کنه؟**
353
+ از `onValueChange` برای ذخیره مقدار در state استفاده کن، بعد موقع submit از state بخون. یا از React Hook Form با Controller استفاده کن (مثال بالا).
362
354
 
363
- const onSubmit = (data) => {
364
- console.log(data);
365
- };
355
+ **تفاوت `locale="fa"` و `locale="ar"` چیه؟**
356
+ `fa` از ارقام فارسی (۰–۹) و جداکننده `٫` استفاده می‌کنه. `ar` از ارقام عربی شرقی (٠–٩). هر دو مقدار انگلیسی به `onValueChange` برمی‌گردونن.
366
357
 
367
- return (
368
- <form onSubmit={handleSubmit(onSubmit)}>
369
- <Controller
370
- name="price"
371
- control={control}
372
- rules={{ required: true }}
373
- render={({ field }) => (
374
- <PersianNumberInput
375
- locale="fa"
376
- suffix="تومان"
377
- onValueChange={field.onChange}
378
- initialValue={field.value}
379
- />
380
- )}
381
- />
382
- <button type="submit">ثبت</button>
383
- </form>
384
- );
385
- }
386
- ```
358
+ **آیا محدودیت عددی وجود داره؟**
359
+ نه. پکیج از مقایسه عددی مبتنی بر رشته استفاده می‌کنه و اعداد خیلی بزرگ یا با دقت اعشاری بالا رو بدون خطای floating-point پردازش می‌کنه.
387
360
 
388
361
  ---
389
362
 
390
- ## 🔍 چرا ورودی اعداد فارسی؟
363
+ ## 🏆 مقایسه با بقیه
391
364
 
392
- ### مشکل
393
-
394
- کار با ارقام فارسی و عربی در برنامه‌های وب چالش‌برانگیز است:
395
-
396
- - کاربران با ارقام بومی خود تایپ می‌کنند، اما فرم‌ها ارقام انگلیسی انتظار دارند
397
- - فرمت‌دهی اعداد در زبان‌های مختلف متفاوت است
398
- - حفظ موقعیت مکان‌نما هنگام فرمت‌دهی پیچیده است
399
- - مدیریت دقت اعشاری نیاز به پیاده‌سازی دقیق دارد
400
-
401
- ### راه‌حل
402
-
403
- ورودی اعداد فارسی تمام این پیچیدگی‌ها را به صورت خودکار مدیریت می‌کند:
404
-
405
- ```tsx
406
- // کاربر تایپ می‌کند: ۱۲۳۴۵۶۷
407
- // کامپوننت نمایش می‌دهد: ۱,۲۳۴,۵۶۷
408
- // فرم دریافت می‌کند: "1234567"
409
- ```
365
+ | امکانات | persian-number-input | `<input>` معمولی | کتابخانه‌های دیگر |
366
+ | ------------------------------ | :------------------: | :--------------: | :---------------: |
367
+ | ورودی ارقام فارسی و عربی | ✅ | ❌ | ⚠️ ناقص |
368
+ | حفظ موقعیت cursor هنگام فرمت | ✅ | ❌ | ⚠️ اغلب باگ‌دار |
369
+ | چند locale (fa / ar / en) | ✅ | ❌ | ❌ |
370
+ | جداکننده هزارگان | ✅ | ❌ | ⚠️ محدود |
371
+ | کنترل دقت اعشاری | ✅ | ❌ | ⚠️ محدود |
372
+ | اعتبارسنجی min/max | ✅ | جزئی | ⚠️ متغیر |
373
+ | TypeScript | ✅ | ✅ | ⚠️ متغیر |
374
+ | حجم باندل | 🟢 ~۱ کیلوبایت | 🟢 native | 🔴 ۵–۳۰ کیلوبایت |
410
375
 
411
376
  ---
412
377
 
413
- ## 🏆 مقایسه
414
-
415
- | امکانات | ورودی اعداد فارسی | Input معمولی | کتابخانه‌های دیگر |
416
- | ------------------- | ----------------- | ------------ | ----------------- |
417
- | تبدیل خودکار ارقام | ✅ | ❌ | ⚠️ جزئی |
418
- | حفظ مکان‌نما | ✅ | ❌ | ⚠️ باگ‌دار |
419
- | پشتیبانی TypeScript | ✅ | ✅ | ⚠️ متغیر |
420
- | چند زبانه | ✅ | ❌ | ❌ |
421
- | حجم باندل | 🟢 کم | 🟢 - | 🔴 زیاد |
422
- | دقت اعشاری | ✅ | ❌ | ⚠️ محدود |
423
-
424
- ---
378
+ ## 🤝 مشارکت در توسعه
425
379
 
426
- ## 🤝 مشارکت
380
+ خوشحال میشم مشارکت کنید!
427
381
 
428
- مشارکت شما استقبال می‌شود! لطفاً از ارسال Pull Request دریغ نکنید.
382
+ 1. مخزن رو Fork کنید
383
+ 2. شاخه feature بسازید: `git checkout -b feature/your-feature`
384
+ 3. تغییرات رو commit کنید: `git commit -m 'Add your feature'`
385
+ 4. push کنید: `git push origin feature/your-feature`
386
+ 5. Pull Request باز کنید
429
387
 
430
- 1. مخزن را Fork کنید
431
- 2. شاخه ویژگی خود را ایجاد کنید (`git checkout -b feature/AmazingFeature`)
432
- 3. تغییرات خود را Commit کنید (`git commit -m 'Add some AmazingFeature'`)
433
- 4. به شاخه Push کنید (`git push origin feature/AmazingFeature`)
434
- 5. یک Pull Request باز کنید
388
+ برای تغییرات بزرگ، لطفاً اول یه issue باز کنید تا با هم بررسی کنیم.
435
389
 
436
390
  ---
437
391
 
438
392
  ## 📄 مجوز
439
393
 
440
- MIT © javad Sharifi
441
-
442
- ---
443
-
444
- ## 🙏 تشکرات
445
-
446
- - ساخته شده با TypeScript و React
447
- - استفاده از [decimal.js](https://github.com/MikeMcl/decimal.js/) برای محاسبات دقیق اعشاری
448
- - الهام‌گرفته از نیازهای توسعه‌دهندگان فارسی و عربی‌زبان
394
+ MIT © [Javad Sharifi](https://github.com/javadSharifi)
449
395
 
450
396
  ---
451
397
 
452
398
  ## 📞 پشتیبانی
453
399
 
454
- - 📧 telegram: [Javad Sharifi](https://t.me/Javad_sharifi98)
455
- - 🐛 [گزارش مشکلات](https://github.com/javadSharifi/persian-number-input/issues)
400
+ - 💬 تلگرام: [@Javad_sharifi98](https://t.me/Javad_sharifi98)
401
+ - 🐛 [گزارش مشکل](https://github.com/javadSharifi/persian-number-input/issues)
456
402
  - 💬 [بحث و گفتگو](https://github.com/javadSharifi/persian-number-input/discussions)
457
403
 
404
+ ---
405
+
458
406
  **ساخته شده با ❤️ برای جامعه توسعه‌دهندگان فارسی و عربی‌زبان**
407
+
408
+ <!-- کلیدواژه‌ها: ورودی عدد فارسی ریکت، تبدیل اعداد فارسی به انگلیسی، کامپوننت ورودی فارسی، ورودی RTL، جداکننده هزارگان فارسی، ورودی اعداد عربی، persian number input react، farsi digit input، arabic number react -->