persian-number-input 4.3.4 → 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.
- package/README.fa.md +190 -240
- package/README.md +152 -230
- package/dist/components/PersianNumberInput.d.ts +1 -1
- package/dist/components/PersianNumberInput.d.ts.map +1 -1
- package/dist/components/PersianNumberInput.js +22 -17
- package/dist/components/PersianNumberInput.js.map +1 -1
- package/dist/components/PersianNumberInput.test.js +24 -6
- package/dist/components/PersianNumberInput.test.js.map +1 -1
- package/dist/hooks/useCursorManager.d.ts +4 -0
- package/dist/hooks/useCursorManager.d.ts.map +1 -0
- package/dist/hooks/useCursorManager.js +19 -0
- package/dist/hooks/useCursorManager.js.map +1 -0
- package/dist/hooks/useNumberFormatter.d.ts +18 -0
- package/dist/hooks/useNumberFormatter.d.ts.map +1 -0
- package/dist/hooks/useNumberFormatter.js +29 -0
- package/dist/hooks/useNumberFormatter.js.map +1 -0
- package/dist/hooks/useNumberValidation.d.ts +11 -0
- package/dist/hooks/useNumberValidation.d.ts.map +1 -0
- package/dist/hooks/useNumberValidation.js +22 -0
- package/dist/hooks/useNumberValidation.js.map +1 -0
- package/dist/hooks/useNumericInputEvents.d.ts +18 -0
- package/dist/hooks/useNumericInputEvents.d.ts.map +1 -0
- package/dist/hooks/useNumericInputEvents.js +39 -0
- package/dist/hooks/useNumericInputEvents.js.map +1 -0
- package/dist/hooks/usePersianNumberInput.d.ts +7 -2
- package/dist/hooks/usePersianNumberInput.d.ts.map +1 -1
- package/dist/hooks/usePersianNumberInput.js +66 -63
- package/dist/hooks/usePersianNumberInput.js.map +1 -1
- package/dist/test-utils.d.ts +7 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +27 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/utils/digitUtils.d.ts +4 -0
- package/dist/utils/digitUtils.d.ts.map +1 -1
- package/dist/utils/digitUtils.js +44 -17
- package/dist/utils/digitUtils.js.map +1 -1
- package/dist/utils/keyFilter.d.ts +16 -0
- package/dist/utils/keyFilter.d.ts.map +1 -0
- package/dist/utils/keyFilter.js +31 -0
- package/dist/utils/keyFilter.js.map +1 -0
- package/dist/utils/validation.d.ts +22 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +85 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +15 -4
package/README.fa.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
# ورودی
|
|
1
|
+
# ورودی عدد فارسی برای React — تبدیل خودکار ارقام فارسی، عربی و RTL
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
English | [فارسی](./README.fa.md)
|
|
4
|
+
|
|
5
|
+
یک کامپوننت React برای **ورودی اعداد فارسی و عربی** با تبدیل خودکار ارقام، جداکننده هزارگان، کنترل دقت اعشاری و پشتیبانی کامل از RTL. کاربر ارقام فارسی تایپ میکند، فرم شما عدد انگلیسی تمیز دریافت میکند — بدون هیچ تبدیل دستی.
|
|
4
6
|
|
|
5
7
|
[](https://www.npmjs.com/package/persian-number-input)
|
|
6
8
|
[](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
|
-
|
|
29
|
+
کاربر تایپ میکند: ۱۲۳۴۵۶۷
|
|
30
|
+
نمایش داده میشود: ۱,۲۳۴,۵۶۷
|
|
31
|
+
فرم دریافت میکند: "1234567"
|
|
22
32
|
```
|
|
23
33
|
|
|
24
|
-

|
|
25
|
-
|
|
26
34
|
---
|
|
27
35
|
|
|
28
36
|
## ✨ امکانات
|
|
29
37
|
|
|
30
|
-
- 🔢 **تبدیل خودکار ارقام**
|
|
31
|
-
- 🌍
|
|
32
|
-
- 📊
|
|
33
|
-
- 💰 **آماده برای ارز**
|
|
34
|
-
- ⚡
|
|
35
|
-
- 🎯 **
|
|
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={
|
|
107
|
+
initialValue={0}
|
|
105
108
|
locale="fa"
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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={
|
|
123
|
+
initialValue={1234.56}
|
|
122
124
|
locale="fa"
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
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 استاندارد
|
|
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
|
-
|
|
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
|
-
|
|
234
|
-
|
|
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
|
-
|
|
245
|
-
|
|
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
|
-
|
|
256
|
-
|
|
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="
|
|
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
|
-
|
|
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
|
-
|
|
357
|
-
|
|
358
|
-
import { PersianNumberInput } from "persian-number-input";
|
|
349
|
+
**مقدار برگشتی `onValueChange` چیه؟**
|
|
350
|
+
همیشه رشتهای از ارقام انگلیسی — مثلاً `"1234567"` — صرفنظر از اینکه چه localeای نمایش داده میشه.
|
|
359
351
|
|
|
360
|
-
|
|
361
|
-
|
|
352
|
+
**آیا با `input` داخل یک فرم native کار میکنه؟**
|
|
353
|
+
از `onValueChange` برای ذخیره مقدار در state استفاده کن، بعد موقع submit از state بخون. یا از React Hook Form با Controller استفاده کن (مثال بالا).
|
|
362
354
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
};
|
|
355
|
+
**تفاوت `locale="fa"` و `locale="ar"` چیه؟**
|
|
356
|
+
`fa` از ارقام فارسی (۰–۹) و جداکننده `٫` استفاده میکنه. `ar` از ارقام عربی شرقی (٠–٩). هر دو مقدار انگلیسی به `onValueChange` برمیگردونن.
|
|
366
357
|
|
|
367
|
-
|
|
368
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 ©
|
|
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
|
-
-
|
|
455
|
-
- 🐛 [گزارش
|
|
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 -->
|