persian-number-input 4.1.0 → 4.3.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 +458 -0
- package/README.md +342 -270
- package/dist/components/PersianNumberInput.d.ts.map +1 -1
- package/dist/components/PersianNumberInput.js +2 -1
- package/dist/components/PersianNumberInput.js.map +1 -1
- package/dist/components/PersianNumberInput.test.d.ts +2 -0
- package/dist/components/PersianNumberInput.test.d.ts.map +1 -0
- package/dist/components/PersianNumberInput.test.js +37 -0
- package/dist/components/PersianNumberInput.test.js.map +1 -0
- package/dist/hooks/usePersianNumberInput.d.ts.map +1 -1
- package/dist/hooks/usePersianNumberInput.js +4 -1
- package/dist/hooks/usePersianNumberInput.js.map +1 -1
- package/dist/setupTests.d.ts +2 -0
- package/dist/setupTests.d.ts.map +1 -0
- package/dist/setupTests.js +4 -0
- package/dist/setupTests.js.map +1 -0
- package/dist/utils/transformNumber.d.ts +1 -0
- package/dist/utils/transformNumber.d.ts.map +1 -1
- package/dist/utils/transformNumber.js +12 -3
- package/dist/utils/transformNumber.js.map +1 -1
- package/package.json +14 -3
package/README.md
CHANGED
|
@@ -1,389 +1,461 @@
|
|
|
1
1
|
# Persian Number Input
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[فارسی](./README.fa.md) | English
|
|
4
|
+
A lightweight, powerful React library for handling Persian (Farsi) and Arabic number inputs with automatic digit conversion, formatting, and localization support.
|
|
4
5
|
|
|
6
|
+
[](https://www.npmjs.com/package/persian-number-input)
|
|
7
|
+
[](https://www.npmjs.com/package/persian-number-input)
|
|
8
|
+
[](https://bundlephobia.com/package/persian-number-input)
|
|
9
|
+
[](https://github.com/javadSharifi/persian-number-input/blob/main/LICENSE)
|
|
10
|
+
|
|
11
|
+
## 🚀 [Live Demo](https://persian-number-input.netlify.app/)
|
|
5
12
|
---
|
|
6
13
|
|
|
7
|
-
|
|
14
|
+
Experience the component in action with our interactive demo!
|
|
15
|
+
|
|
16
|
+
## 📊 Bundle Size
|
|
17
|
+
|
|
18
|
+
This library is extremely lightweight:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
persian-number-input: ~1KB (minified + gzipped)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
8
26
|
|
|
9
27
|
---
|
|
10
28
|
|
|
11
|
-
##
|
|
29
|
+
## ✨ Features
|
|
12
30
|
|
|
13
|
-
**
|
|
31
|
+
- 🔢 **Automatic Digit Conversion** - Seamlessly converts Persian (۰-۹) and Arabic (٠-٩) digits to English and vice versa
|
|
32
|
+
- 🌍 **Multi-locale Support** - Built-in support for Persian (fa), Arabic (ar), and English (en)
|
|
33
|
+
- 📊 **Number Formatting** - Automatic thousand separators with customizable characters
|
|
34
|
+
- 💰 **Currency Ready** - Add prefixes, suffixes, and custom decimal separators
|
|
35
|
+
- ⚡ **Lightweight** - Tiny bundle size with zero dependencies (except decimal.js for precision)
|
|
36
|
+
- 🎯 **Type-Safe** - Full TypeScript support with complete type definitions
|
|
37
|
+
- ♿ **Accessible** - Follows best practices for input accessibility
|
|
38
|
+
- 🎨 **Customizable** - Extensive configuration options for any use case
|
|
39
|
+
- 🔄 **Real-time Formatting** - Format numbers as users type with cursor position preservation
|
|
40
|
+
- ✅ **Validation** - Built-in min/max value validation and decimal precision control
|
|
14
41
|
|
|
15
|
-
|
|
42
|
+
---
|
|
16
43
|
|
|
17
|
-
|
|
18
|
-
- Customizable digit grouping (e.g., thousands separator)
|
|
19
|
-
- Handles decimal numbers with configurable precision using ``
|
|
20
|
-
- Min/max value constraints for input validation, including decimals
|
|
21
|
-
- Converts localized digits to standard English digits for processing
|
|
22
|
-
- Lightweight and compatible with React 16 to 19
|
|
23
|
-
- TypeScript support for robust development
|
|
44
|
+
## 📦 Installation
|
|
24
45
|
|
|
25
|
-
|
|
46
|
+
```bash
|
|
47
|
+
npm install persian-number-input
|
|
48
|
+
```
|
|
26
49
|
|
|
27
|
-
|
|
50
|
+
```bash
|
|
51
|
+
yarn add persian-number-input
|
|
52
|
+
```
|
|
28
53
|
|
|
29
54
|
```bash
|
|
30
|
-
|
|
55
|
+
pnpm add persian-number-input
|
|
31
56
|
```
|
|
32
57
|
|
|
33
|
-
|
|
58
|
+
---
|
|
34
59
|
|
|
35
|
-
|
|
60
|
+
## 🎯 Quick Start
|
|
36
61
|
|
|
37
|
-
|
|
62
|
+
### Basic Usage
|
|
38
63
|
|
|
39
|
-
```
|
|
40
|
-
import React, { useState } from "react";
|
|
64
|
+
```tsx
|
|
41
65
|
import { PersianNumberInput } from "persian-number-input";
|
|
42
66
|
|
|
43
|
-
|
|
44
|
-
const [number, setNumber] = useState("");
|
|
45
|
-
|
|
67
|
+
function App() {
|
|
46
68
|
return (
|
|
47
69
|
<PersianNumberInput
|
|
48
|
-
initialValue=
|
|
49
|
-
separatorCount={3}
|
|
50
|
-
separatorChar=","
|
|
70
|
+
initialValue={1234567}
|
|
51
71
|
locale="fa"
|
|
52
|
-
|
|
53
|
-
min={0.5}
|
|
54
|
-
max={1000000.999}
|
|
55
|
-
showZero={true}
|
|
56
|
-
onValueChange={(val) => setNumber(val || "")}
|
|
57
|
-
placeholder="Enter a number"
|
|
58
|
-
className="numeric-input"
|
|
72
|
+
onValueChange={(value) => console.log(value)}
|
|
59
73
|
/>
|
|
60
74
|
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export default App;
|
|
75
|
+
}
|
|
64
76
|
```
|
|
65
77
|
|
|
66
|
-
**Output
|
|
78
|
+
**Output:** `۱,۲۳۴,۵۶۷`
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 📚 Usage Examples
|
|
83
|
+
|
|
84
|
+
### Currency Input (Persian Toman)
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
<PersianNumberInput
|
|
88
|
+
initialValue={5000000}
|
|
89
|
+
locale="fa"
|
|
90
|
+
suffix="تومان"
|
|
91
|
+
separatorCount={3}
|
|
92
|
+
separatorChar=","
|
|
93
|
+
onValueChange={(value) => console.log(value)}
|
|
94
|
+
/>
|
|
67
95
|
```
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
96
|
+
|
|
97
|
+
**Output:** `۵,۰۰۰,۰۰۰ تومان`
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
### Decimal Numbers with Custom Separator
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
<PersianNumberInput
|
|
105
|
+
initialValue={1234.56}
|
|
106
|
+
locale="fa"
|
|
107
|
+
maxDecimals={2}
|
|
108
|
+
decimalChar="٫"
|
|
109
|
+
separatorChar=","
|
|
110
|
+
onValueChange={(value) => console.log(value)}
|
|
111
|
+
/>
|
|
71
112
|
```
|
|
72
113
|
|
|
73
|
-
|
|
114
|
+
**Output:** `۱,۲۳۴٫۵۶`
|
|
115
|
+
|
|
116
|
+
---
|
|
74
117
|
|
|
75
|
-
|
|
118
|
+
### Price Input with Validation
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
<PersianNumberInput
|
|
122
|
+
initialValue={0}
|
|
123
|
+
locale="fa"
|
|
124
|
+
min={0}
|
|
125
|
+
max={999999999}
|
|
126
|
+
suffix="ریال"
|
|
127
|
+
showZero={true}
|
|
128
|
+
onValueChange={(value) => console.log(value)}
|
|
129
|
+
/>
|
|
130
|
+
```
|
|
76
131
|
|
|
77
|
-
|
|
78
|
-
import React from "react";
|
|
79
|
-
import { usePersianNumberInput } from "persian-number-input";
|
|
132
|
+
**Output:** `۰ ریال`
|
|
80
133
|
|
|
81
|
-
|
|
82
|
-
const { value, onChange, rawValue } = usePersianNumberInput({
|
|
83
|
-
initialValue: "5000.25",
|
|
84
|
-
separatorCount: 3,
|
|
85
|
-
separatorChar: ",",
|
|
86
|
-
locale: "fa",
|
|
87
|
-
maxDecimals: 2,
|
|
88
|
-
min: 0.5,
|
|
89
|
-
max: 10000.999,
|
|
90
|
-
showZero: true,
|
|
91
|
-
});
|
|
134
|
+
---
|
|
92
135
|
|
|
93
|
-
|
|
94
|
-
<div>
|
|
95
|
-
<input
|
|
96
|
-
type="text"
|
|
97
|
-
inputMode="decimal"
|
|
98
|
-
value={value}
|
|
99
|
-
onChange={onChange}
|
|
100
|
-
placeholder="Enter a number"
|
|
101
|
-
/>
|
|
102
|
-
<p>Raw Value: {rawValue || "N/A"}</p>
|
|
103
|
-
</div>
|
|
104
|
-
);
|
|
105
|
-
};
|
|
136
|
+
### Arabic Locale
|
|
106
137
|
|
|
107
|
-
|
|
138
|
+
```tsx
|
|
139
|
+
<PersianNumberInput
|
|
140
|
+
initialValue={987654}
|
|
141
|
+
locale="ar"
|
|
142
|
+
separatorChar=","
|
|
143
|
+
suffix="ر.س"
|
|
144
|
+
onValueChange={(value) => console.log(value)}
|
|
145
|
+
/>
|
|
108
146
|
```
|
|
109
147
|
|
|
110
|
-
**
|
|
111
|
-
- The hook manages the input state and formatting, returning `value` (formatted for display) and `rawValue` (English digits).
|
|
112
|
-
- Use this for custom input components or non-standard form controls.
|
|
113
|
-
- **Output**:
|
|
114
|
-
```
|
|
115
|
-
Displayed Input:ავ۰٫۲۵
|
|
116
|
-
Raw Value: 5000.25
|
|
117
|
-
```
|
|
148
|
+
**Output:** `٩٨٧,٦٥٤ ر.س`
|
|
118
149
|
|
|
119
|
-
|
|
150
|
+
---
|
|
120
151
|
|
|
121
|
-
|
|
152
|
+
### Using the Hook (Advanced)
|
|
122
153
|
|
|
123
|
-
```
|
|
124
|
-
import {
|
|
154
|
+
```tsx
|
|
155
|
+
import { usePersianNumberInput } from "persian-number-input";
|
|
125
156
|
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
157
|
+
function CustomInput() {
|
|
158
|
+
const { value, onChange, onBlur, rawValue } = usePersianNumberInput({
|
|
159
|
+
initialValue: 1000,
|
|
160
|
+
locale: "fa",
|
|
161
|
+
separatorCount: 3,
|
|
162
|
+
maxDecimals: 2,
|
|
163
|
+
min: 0,
|
|
164
|
+
max: 1000000,
|
|
165
|
+
onValueChange: (val) => {
|
|
166
|
+
console.log("Raw value:", val); // "1000"
|
|
167
|
+
console.log("Displayed value:", value); // "۱,۰۰۰"
|
|
168
|
+
},
|
|
169
|
+
});
|
|
134
170
|
|
|
135
|
-
|
|
171
|
+
return (
|
|
172
|
+
<input
|
|
173
|
+
type="text"
|
|
174
|
+
value={value}
|
|
175
|
+
onChange={onChange}
|
|
176
|
+
onBlur={onBlur}
|
|
177
|
+
className="custom-input"
|
|
178
|
+
/>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
136
181
|
```
|
|
137
182
|
|
|
138
|
-
|
|
139
|
-
- Use `transformNumber` to format numbers for display in tables, labels, or other non-input contexts.
|
|
140
|
-
- Supports the same options as `PersianNumberInput` (`separatorCount`, `locale`, etc.).
|
|
141
|
-
- Returns a string with localized digits and formatting.
|
|
142
|
-
|
|
143
|
-
### 📚 Props Reference
|
|
183
|
+
---
|
|
144
184
|
|
|
145
|
-
|
|
146
|
-
| --- | --- | --- | --- |
|
|
147
|
-
| `initialValue` | `string | number` | `""` | Initial value of the input |
|
|
148
|
-
| `separatorCount` | `number` | `3` | Number of digits per group (e.g., 3 for thousands) |
|
|
149
|
-
| `separatorChar` | `string` | `","` | Character used for grouping digits (e.g., `,` or `.`) |
|
|
150
|
-
| `locale` | `string` | `"fa"` | Language for digit localization (e.g., `fa`, `en`) |
|
|
151
|
-
| `maxDecimals` | `number` | `0` | Maximum number of decimal places allowed |
|
|
152
|
-
| `showZero` | `boolean` | `false` | If `true`, displays `0` when the input is empty or zero |
|
|
153
|
-
| `min` | `number` | - | Minimum allowed value (supports decimals, e.g., `0.5`) |
|
|
154
|
-
| `max` | `number` | - | Maximum allowed value (supports decimals, e.g., `1000.201`) |
|
|
155
|
-
| `onValueChange` | `(value: string | undefined) => void` | - | Callback for value changes |
|
|
156
|
-
| `...rest` | `InputHTMLAttributes` | - | Standard HTML input attributes (e.g., `className`, `placeholder`, `style`) |
|
|
185
|
+
## 🛠️ API Reference
|
|
157
186
|
|
|
158
|
-
###
|
|
187
|
+
### PersianNumberInput Props
|
|
159
188
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
189
|
+
| Prop | Type | Default | Description |
|
|
190
|
+
| ---------------- | -------------------------------------- | ----------- | -------------------------------------------------------- |
|
|
191
|
+
| `initialValue` | `number \| string` | `undefined` | Initial value of the input |
|
|
192
|
+
| `locale` | `"fa" \| "ar" \| "en"` | `"fa"` | Locale for digit conversion |
|
|
193
|
+
| `separatorCount` | `number` | `3` | Number of digits between separators |
|
|
194
|
+
| `separatorChar` | `string` | `","` | Character used for thousand separator |
|
|
195
|
+
| `decimalChar` | `string` | Auto | Decimal separator character |
|
|
196
|
+
| `suffix` | `string` | `undefined` | Suffix text (e.g., currency symbol) |
|
|
197
|
+
| `maxDecimals` | `number` | `undefined` | Maximum decimal places allowed |
|
|
198
|
+
| `min` | `number` | `undefined` | Minimum allowed value |
|
|
199
|
+
| `max` | `number` | `undefined` | Maximum allowed value |
|
|
200
|
+
| `showZero` | `boolean` | `false` | Show zero when value is empty |
|
|
201
|
+
| `onValueChange` | `(value: string \| undefined) => void` | `undefined` | Callback when value changes (returns raw English digits) |
|
|
165
202
|
|
|
166
|
-
|
|
203
|
+
All standard HTML input props are also supported.
|
|
167
204
|
|
|
168
|
-
|
|
169
|
-
Yes, it is fully compatible with React 16 through 19.
|
|
205
|
+
---
|
|
170
206
|
|
|
171
|
-
|
|
172
|
-
Yes, set `maxDecimals` to the desired number of decimal places (e.g., `maxDecimals={2}`).
|
|
207
|
+
### Utility Functions
|
|
173
208
|
|
|
174
|
-
|
|
175
|
-
Use the `min` and `max` props, which support decimals (e.g., `min={0.5}`, `max={1000.201}`).
|
|
209
|
+
#### `transformNumber(rawValue, options)`
|
|
176
210
|
|
|
177
|
-
|
|
178
|
-
Pass `className` or `style` props to customize the input’s appearance.
|
|
211
|
+
Formats a number string according to locale and options.
|
|
179
212
|
|
|
180
|
-
|
|
181
|
-
|
|
213
|
+
```tsx
|
|
214
|
+
import { transformNumber } from "persian-number-input";
|
|
182
215
|
|
|
183
|
-
|
|
216
|
+
const formatted = transformNumber("1234567.89", {
|
|
217
|
+
locale: "fa",
|
|
218
|
+
separatorCount: 3,
|
|
219
|
+
separatorChar: ",",
|
|
220
|
+
maxDecimals: 2,
|
|
221
|
+
suffix: "تومان",
|
|
222
|
+
});
|
|
184
223
|
|
|
185
|
-
|
|
224
|
+
console.log(formatted); // "۱,۲۳۴,۵۶۷٫۸۹ تومان"
|
|
225
|
+
```
|
|
186
226
|
|
|
187
|
-
|
|
227
|
+
#### `toEnglishDigits(str, decimalChar?)`
|
|
188
228
|
|
|
189
|
-
|
|
229
|
+
Converts Persian/Arabic digits to English digits.
|
|
190
230
|
|
|
191
|
-
|
|
231
|
+
```tsx
|
|
232
|
+
import { toEnglishDigits } from "persian-number-input";
|
|
192
233
|
|
|
193
|
-
|
|
234
|
+
console.log(toEnglishDigits("۱۲۳۴")); // "1234"
|
|
235
|
+
console.log(toEnglishDigits("٩٨٧٦")); // "9876"
|
|
236
|
+
```
|
|
194
237
|
|
|
195
|
-
|
|
238
|
+
#### `toLocalizedDigits(numStr, locale)`
|
|
196
239
|
|
|
197
|
-
|
|
240
|
+
Converts English digits to localized digits.
|
|
198
241
|
|
|
199
|
-
|
|
242
|
+
```tsx
|
|
243
|
+
import { toLocalizedDigits } from "persian-number-input";
|
|
200
244
|
|
|
201
|
-
|
|
245
|
+
console.log(toLocalizedDigits("1234", "fa")); // "۱۲۳۴"
|
|
246
|
+
console.log(toLocalizedDigits("5678", "ar")); // "٥٦٧٨"
|
|
247
|
+
```
|
|
202
248
|
|
|
203
|
-
|
|
249
|
+
#### `sanitizeNumericInput(value, maxDecimals?, decimalChar?)`
|
|
204
250
|
|
|
205
|
-
|
|
251
|
+
Cleans and validates numeric input.
|
|
206
252
|
|
|
207
|
-
|
|
253
|
+
```tsx
|
|
254
|
+
import { sanitizeNumericInput } from "persian-number-input";
|
|
208
255
|
|
|
209
|
-
|
|
210
|
-
|
|
256
|
+
console.log(sanitizeNumericInput("۱۲۳abc۴۵۶", 2)); // "123456"
|
|
257
|
+
console.log(sanitizeNumericInput("12.345.67", 2)); // "12.34"
|
|
258
|
+
```
|
|
211
259
|
|
|
212
|
-
|
|
213
|
-
- تبدیل خودکار ارقام محلی به ارقام انگلیسی برای پردازش
|
|
214
|
-
- سبک و سازگار با React 16 تا 19
|
|
215
|
-
- پشتیبانی از TypeScript برای توسعه امن
|
|
260
|
+
---
|
|
216
261
|
|
|
217
|
-
|
|
262
|
+
## 🎨 Styling
|
|
263
|
+
|
|
264
|
+
The component accepts all standard input props, including `className` and `style`:
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
<PersianNumberInput
|
|
268
|
+
initialValue={1000}
|
|
269
|
+
locale="fa"
|
|
270
|
+
className="custom-input"
|
|
271
|
+
style={{
|
|
272
|
+
padding: "12px",
|
|
273
|
+
fontSize: "16px",
|
|
274
|
+
border: "2px solid #4F46E5",
|
|
275
|
+
borderRadius: "8px",
|
|
276
|
+
textAlign: "right",
|
|
277
|
+
}}
|
|
278
|
+
/>
|
|
279
|
+
```
|
|
218
280
|
|
|
219
|
-
|
|
281
|
+
### With Tailwind CSS
|
|
220
282
|
|
|
221
|
-
```
|
|
222
|
-
|
|
283
|
+
```tsx
|
|
284
|
+
<PersianNumberInput
|
|
285
|
+
initialValue={1000}
|
|
286
|
+
locale="fa"
|
|
287
|
+
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"
|
|
288
|
+
/>
|
|
223
289
|
```
|
|
224
290
|
|
|
225
|
-
|
|
291
|
+
---
|
|
226
292
|
|
|
227
|
-
|
|
293
|
+
## 🌟 Advanced Examples
|
|
228
294
|
|
|
229
|
-
|
|
295
|
+
### Financial Calculator
|
|
230
296
|
|
|
231
|
-
```
|
|
232
|
-
import
|
|
297
|
+
```tsx
|
|
298
|
+
import { useState } from "react";
|
|
233
299
|
import { PersianNumberInput } from "persian-number-input";
|
|
234
300
|
|
|
235
|
-
|
|
236
|
-
const [
|
|
301
|
+
function LoanCalculator() {
|
|
302
|
+
const [principal, setPrincipal] = useState<string>();
|
|
303
|
+
const [rate, setRate] = useState<string>();
|
|
304
|
+
const [years, setYears] = useState<string>();
|
|
305
|
+
|
|
306
|
+
const calculateMonthlyPayment = () => {
|
|
307
|
+
if (!principal || !rate || !years) return 0;
|
|
308
|
+
const p = parseFloat(principal);
|
|
309
|
+
const r = parseFloat(rate) / 100 / 12;
|
|
310
|
+
const n = parseFloat(years) * 12;
|
|
311
|
+
return (p * r * Math.pow(1 + r, n)) / (Math.pow(1 + r, n) - 1);
|
|
312
|
+
};
|
|
237
313
|
|
|
238
314
|
return (
|
|
239
|
-
<
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
315
|
+
<div className="space-y-4">
|
|
316
|
+
<div>
|
|
317
|
+
<label>مبلغ وام:</label>
|
|
318
|
+
<PersianNumberInput
|
|
319
|
+
locale="fa"
|
|
320
|
+
suffix="تومان"
|
|
321
|
+
onValueChange={setPrincipal}
|
|
322
|
+
min={0}
|
|
323
|
+
/>
|
|
324
|
+
</div>
|
|
325
|
+
<div>
|
|
326
|
+
<label>نرخ سود (٪):</label>
|
|
327
|
+
<PersianNumberInput
|
|
328
|
+
locale="fa"
|
|
329
|
+
maxDecimals={2}
|
|
330
|
+
onValueChange={setRate}
|
|
331
|
+
min={0}
|
|
332
|
+
max={100}
|
|
333
|
+
/>
|
|
334
|
+
</div>
|
|
335
|
+
<div>
|
|
336
|
+
<label>مدت زمان (سال):</label>
|
|
337
|
+
<PersianNumberInput
|
|
338
|
+
locale="fa"
|
|
339
|
+
onValueChange={setYears}
|
|
340
|
+
min={1}
|
|
341
|
+
max={30}
|
|
342
|
+
/>
|
|
343
|
+
</div>
|
|
344
|
+
<p>
|
|
345
|
+
پرداخت ماهیانه: {calculateMonthlyPayment().toLocaleString("fa-IR")}{" "}
|
|
346
|
+
تومان
|
|
347
|
+
</p>
|
|
348
|
+
</div>
|
|
252
349
|
);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
export default App;
|
|
350
|
+
}
|
|
256
351
|
```
|
|
257
352
|
|
|
258
|
-
|
|
259
|
-
```
|
|
260
|
-
ورودی: 123456.78
|
|
261
|
-
خروجی نمایشی: ۱۲۳,۴۵۶٫۷۸
|
|
262
|
-
خروجی انگلیسی: 123456.78
|
|
263
|
-
```
|
|
353
|
+
---
|
|
264
354
|
|
|
265
|
-
|
|
355
|
+
### Form Integration
|
|
266
356
|
|
|
267
|
-
|
|
357
|
+
```tsx
|
|
358
|
+
import { useForm, Controller } from "react-hook-form";
|
|
359
|
+
import { PersianNumberInput } from "persian-number-input";
|
|
268
360
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
import { usePersianNumberInput } from "persian-number-input";
|
|
361
|
+
function ProductForm() {
|
|
362
|
+
const { control, handleSubmit } = useForm();
|
|
272
363
|
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
separatorCount: 3,
|
|
277
|
-
separatorChar: ",",
|
|
278
|
-
locale: "fa",
|
|
279
|
-
maxDecimals: 2,
|
|
280
|
-
min: 0.5,
|
|
281
|
-
max: 10000.999,
|
|
282
|
-
showZero: true,
|
|
283
|
-
});
|
|
364
|
+
const onSubmit = (data) => {
|
|
365
|
+
console.log(data);
|
|
366
|
+
};
|
|
284
367
|
|
|
285
368
|
return (
|
|
286
|
-
<
|
|
287
|
-
<
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
369
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
|
370
|
+
<Controller
|
|
371
|
+
name="price"
|
|
372
|
+
control={control}
|
|
373
|
+
rules={{ required: true }}
|
|
374
|
+
render={({ field }) => (
|
|
375
|
+
<PersianNumberInput
|
|
376
|
+
locale="fa"
|
|
377
|
+
suffix="تومان"
|
|
378
|
+
onValueChange={field.onChange}
|
|
379
|
+
initialValue={field.value}
|
|
380
|
+
/>
|
|
381
|
+
)}
|
|
293
382
|
/>
|
|
294
|
-
<
|
|
295
|
-
</
|
|
383
|
+
<button type="submit">ثبت</button>
|
|
384
|
+
</form>
|
|
296
385
|
);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
export default CustomInput;
|
|
386
|
+
}
|
|
300
387
|
```
|
|
301
388
|
|
|
302
|
-
|
|
303
|
-
- این هوک وضعیت ورودی و فرمتبندی را مدیریت میکند و `value` (برای نمایش) و `rawValue` (ارقام انگلیسی) را برمیگرداند.
|
|
304
|
-
- برای کامپوننتهای ورودی سفارشی یا فرمهای غیراستاندارد مناسب است.
|
|
305
|
-
- **خروجی**:
|
|
306
|
-
```
|
|
307
|
-
ورودی نمایشی: ۵,۰۰۰٫۲۵
|
|
308
|
-
مقدار خام: 5000.25
|
|
309
|
-
```
|
|
389
|
+
---
|
|
310
390
|
|
|
311
|
-
|
|
391
|
+
## 🔍 Why Persian Number Input?
|
|
312
392
|
|
|
313
|
-
|
|
393
|
+
### The Problem
|
|
314
394
|
|
|
315
|
-
|
|
316
|
-
import { transformNumber } from "persian-number-input";
|
|
395
|
+
Working with Persian and Arabic numerals in web applications is challenging:
|
|
317
396
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
locale: "fa",
|
|
323
|
-
maxDecimals: 2,
|
|
324
|
-
showZero: true,
|
|
325
|
-
});
|
|
397
|
+
- Users type in their native digits, but forms expect English digits
|
|
398
|
+
- Number formatting varies across locales
|
|
399
|
+
- Maintaining cursor position during formatting is complex
|
|
400
|
+
- Decimal precision handling requires careful implementation
|
|
326
401
|
|
|
327
|
-
|
|
328
|
-
```
|
|
402
|
+
### The Solution
|
|
329
403
|
|
|
330
|
-
|
|
331
|
-
- از `transformNumber` برای فرمتبندی اعداد در جداول، برچسبها یا سایر موارد غیرورودی استفاده کنید.
|
|
332
|
-
- همان گزینههای `PersianNumberInput` (مانند `separatorCount` و `locale`) را پشتیبانی میکند.
|
|
333
|
-
- یک رشته با ارقام محلی و فرمتبندی مناسب برمیگرداند.
|
|
404
|
+
Persian Number Input handles all these complexities automatically:
|
|
334
405
|
|
|
335
|
-
|
|
406
|
+
```tsx
|
|
407
|
+
// User types: ۱۲۳۴۵۶۷
|
|
408
|
+
// Component displays: ۱,۲۳۴,۵۶۷
|
|
409
|
+
// Form receives: "1234567"
|
|
410
|
+
```
|
|
336
411
|
|
|
337
|
-
|
|
338
|
-
| --- | --- | --- | --- |
|
|
339
|
-
| `initialValue` | `string | number` | `""` | مقدار اولیه ورودی |
|
|
340
|
-
| `separatorCount` | `number` | `3` | تعداد ارقام در هر گروه (مثلاً ۳ برای هزارگان) |
|
|
341
|
-
| `separatorChar` | `string` | `","` | کاراکتر جداکننده گروهها (مثلاً `,` یا `.`) |
|
|
342
|
-
| `locale` | `string` | `"fa"` | زبان برای محلیسازی ارقام (مثلاً `fa` یا `en`) |
|
|
343
|
-
| `maxDecimals` | `number` | `0` | حداکثر تعداد ارقام اعشاری مجاز |
|
|
344
|
-
| `showZero` | `boolean` | `false` | اگر `true` باشد، عدد `0` را در ورودی خالی یا صفر نمایش میدهد |
|
|
345
|
-
| `min` | `number` | - | حداقل مقدار مجاز (پشتیبانی از اعشار، مثلاً `0.5`) |
|
|
346
|
-
| `max` | `number` | - | حداکثر مقدار مجاز (پشتیبانی از اعشار، مثلاً `1000.201`) |
|
|
347
|
-
| `onValueChange` | `(value: string | undefined) => void` | - | فراخوانی در تغییر مقدار |
|
|
348
|
-
| `...rest` | `InputHTMLAttributes` | - | ویژگیهای استاندارد ورودی HTML (مثل `className`، `placeholder`، `style`) |
|
|
412
|
+
---
|
|
349
413
|
|
|
350
|
-
|
|
414
|
+
## 🏆 Comparison
|
|
351
415
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
416
|
+
| Feature | Persian Number Input | Native Input | Other Libraries |
|
|
417
|
+
| --------------------- | -------------------- | ------------ | --------------- |
|
|
418
|
+
| Auto digit conversion | ✅ | ❌ | ⚠️ Partial |
|
|
419
|
+
| Cursor preservation | ✅ | ❌ | ⚠️ Buggy |
|
|
420
|
+
| TypeScript support | ✅ | ✅ | ⚠️ Varies |
|
|
421
|
+
| Multi-locale | ✅ | ❌ | ❌ |
|
|
422
|
+
| Bundle size | 🟢 Small | 🟢 N/A | 🔴 Large |
|
|
423
|
+
| Decimal precision | ✅ | ❌ | ⚠️ Limited |
|
|
357
424
|
|
|
358
|
-
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## 🤝 Contributing
|
|
359
428
|
|
|
360
|
-
|
|
361
|
-
بله، کاملاً با React 16 تا 19 سازگار است.
|
|
429
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
362
430
|
|
|
363
|
-
|
|
364
|
-
|
|
431
|
+
1. Fork the repository
|
|
432
|
+
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
433
|
+
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
434
|
+
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
435
|
+
5. Open a Pull Request
|
|
365
436
|
|
|
366
|
-
|
|
367
|
-
از پراپهای `min` و `max` استفاده کنید که از اعشار پشتیبانی میکنند (مثلاً `min={0.5}` و `max={1000.201}`).
|
|
437
|
+
---
|
|
368
438
|
|
|
369
|
-
|
|
370
|
-
با پراپهای `className` یا `style` میتوانید ظاهر ورودی را تغییر دهید.
|
|
439
|
+
## 📄 License
|
|
371
440
|
|
|
372
|
-
|
|
373
|
-
کامپوننت ورودیها را پاکسازی میکند و فقط اعداد معتبر را پردازش میکند، ضمن رعایت محدودیتهای min/max.
|
|
441
|
+
MIT © [Your Name]
|
|
374
442
|
|
|
375
|
-
|
|
443
|
+
---
|
|
376
444
|
|
|
377
|
-
|
|
445
|
+
## 🙏 Acknowledgments
|
|
378
446
|
|
|
379
|
-
|
|
447
|
+
- Built with TypeScript and React
|
|
448
|
+
- Uses [decimal.js](https://github.com/MikeMcl/decimal.js/) for precise decimal calculations
|
|
449
|
+
- Inspired by the needs of Persian and Arabic speaking developers
|
|
380
450
|
|
|
381
|
-
|
|
451
|
+
---
|
|
382
452
|
|
|
383
|
-
|
|
453
|
+
## 📞 Support
|
|
384
454
|
|
|
385
|
-
|
|
455
|
+
- 📧 Email: your.email@example.com
|
|
456
|
+
- 🐛 [Issue Tracker](https://github.com/javadSharifi/persian-number-input/issues)
|
|
457
|
+
- 💬 [Discussions](https://github.com/javadSharifi/persian-number-input/discussions)
|
|
386
458
|
|
|
387
|
-
|
|
459
|
+
---
|
|
388
460
|
|
|
389
|
-
|
|
461
|
+
**Made with ❤️ for the Persian and Arabic developer community**
|