persian-number-input 3.1.0 → 4.0.1

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.md CHANGED
@@ -4,34 +4,37 @@
4
4
 
5
5
  ---
6
6
 
7
- [English 🇺🇸](#-english)| [فارسی 🇮🇷](#-فارسی)
7
+ English 🇺🇸 | فارسی 🇮🇷
8
8
 
9
9
  ---
10
10
 
11
- ## 🇺🇸 English
11
+ ## English
12
12
 
13
- Persian Number Input - React Component for Persian, English & Indic Number Formatting
14
-
15
- Easily input, format, and convert numbers in Persian, English, or Indic digits with customizable digit separators. Lightweight, React-compatible, and fully localized for React versions 16 to 19.
13
+ **Persian Number Input** - A powerful React component and utility for formatting and handling numbers in Persian, English, or other localized digit systems. Perfect for multilingual applications requiring numeric inputs with customizable formatting, including decimal support.
16
14
 
17
15
  ✅ **Key Features:**
18
16
 
19
- - Support for Persian, English, and Indic digit localization
20
- - Customizable digit grouping separators (e.g., commas)
21
- - Automatically converts localized digits to standard English digits
22
- - Simple, easy-to-integrate React API
17
+ - Supports Persian, English, and other digit localization (e.g., Indic)
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
23
24
 
24
25
  ### 🚀 Installation
25
26
 
27
+ Install the package via npm or yarn:
28
+
26
29
  ```bash
27
- npm install persian-number-input
30
+ npm install persian-number-input
28
31
  ```
29
32
 
30
- ![Size](./public/size.png)
33
+ ### 💻 Usage Examples
31
34
 
32
- ### 💻 Usage Example
35
+ #### 1. Using `PersianNumberInput` Component
33
36
 
34
- Simple usage example:
37
+ This component is ideal for form inputs requiring localized number formatting.
35
38
 
36
39
  ```jsx
37
40
  import React, { useState } from "react";
@@ -42,10 +45,17 @@ const App = () => {
42
45
 
43
46
  return (
44
47
  <PersianNumberInput
45
- initialValue="123456"
48
+ initialValue="123456.78"
46
49
  separatorCount={3}
47
- lang="fa"
48
- onChangeValue={(val) => setNumber(val)}
50
+ separatorChar=","
51
+ locale="fa"
52
+ maxDecimals={2}
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"
49
59
  />
50
60
  );
51
61
  };
@@ -53,85 +63,170 @@ const App = () => {
53
63
  export default App;
54
64
  ```
55
65
 
56
- ### 🔥 Output Example
66
+ **Output**:
67
+ ```
68
+ Input: 123456.78
69
+ Displayed Output: ۱۲۳,۴۵۶٫۷۸
70
+ English Output: 123456.78
71
+ ```
72
+
73
+ #### 2. Using `usePersianNumberInput` Hook
74
+
75
+ The `usePersianNumberInput` hook provides fine-grained control for custom input handling.
76
+
77
+ ```jsx
78
+ import React from "react";
79
+ import { usePersianNumberInput } from "persian-number-input";
80
+
81
+ const CustomInput = () => {
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
+ });
57
92
 
93
+ return (
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
+ };
106
+
107
+ export default CustomInput;
58
108
  ```
59
- Input: 123456
60
- Displayed Output: ۱۲۳,۴۵۶
61
- English Output: 123456
109
+
110
+ **Explanation**:
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
+ ```
118
+
119
+ #### 3. Using `transformNumber` Utility
120
+
121
+ The `transformNumber` function formats numbers without requiring a React component, ideal for display-only scenarios.
122
+
123
+ ```javascript
124
+ import { transformNumber } from "persian-number-input";
125
+
126
+ const number = 123456.789;
127
+ const formatted = transformNumber(number, {
128
+ separatorCount: 3,
129
+ separatorChar: ",",
130
+ locale: "fa",
131
+ maxDecimals: 2,
132
+ showZero: true,
133
+ });
134
+
135
+ console.log(formatted); // Output: ۱۲۳,۴۵۶٫۷۹
62
136
  ```
63
137
 
64
- ![Output Example](./public/output.png)
138
+ **Explanation**:
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.
65
142
 
66
143
  ### 📚 Props Reference
67
144
 
68
- | Name | Type | Default | Description |
69
- | -------------- | ------------------------------- | ------- | ------------------------------------ |
70
- | initialValue | string | "" | Initial input value |
71
- | separatorCount | number | 0 | Number of digits per group (e.g., 3) |
72
- | separatorChar | string | "," | Digit grouping character |
73
- | lang | 'fa' \| 'in' \| 'en' | "fa" | Digit localization language |
74
- | onChangeValue | (englishNumber: string) => void | - | Callback function on value change |
75
-
76
- ---
145
+ | Name | Type | Default | Description |
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`) |
157
+
158
+ ### 🌟 Why Use Persian Number Input?
159
+
160
+ - **Multilingual Support**: Seamlessly handle Persian, English, or other localized digits.
161
+ - **Customizable Formatting**: Control separators, decimals, and zero display.
162
+ - **Robust Validation**: Enforce min/max constraints with decimal precision using ``.
163
+ - **Developer-Friendly**: TypeScript support and a simple API for quick integration.
164
+ - **Lightweight**: Optimized for performance with minimal dependencies.
77
165
 
78
166
  ### ❓ FAQ (Frequently Asked Questions)
79
167
 
80
168
  **Does this package support React 19?**
81
- Yes, it fully supports React versions 16 through 19.
169
+ Yes, it is fully compatible with React 16 through 19.
82
170
 
83
- **What is the best use-case scenario for this component?**
84
- Ideal for multilingual web applications, forms, and any interface requiring localized numeric inputs.
171
+ **Can I use decimal numbers?**
172
+ Yes, set `maxDecimals` to the desired number of decimal places (e.g., `maxDecimals={2}`).
85
173
 
86
- **How can I customize the styles of this component?**
87
- You can pass custom classes or inline styles directly to the component to match your design requirements.
174
+ **How do I enforce minimum and maximum values?**
175
+ Use the `min` and `max` props, which support decimals (e.g., `min={0.5}`, `max={1000.201}`).
88
176
 
89
- ---
177
+ **How can I style the input?**
178
+ Pass `className` or `style` props to customize the input’s appearance.
179
+
180
+ **What happens if the user enters an invalid number?**
181
+ The component sanitizes inputs, ensuring only valid numbers are processed, and respects min/max constraints.
90
182
 
91
183
  ### 🌟 Support the Project
92
184
 
93
- If you find this package helpful, **please give it a star ⭐ on GitHub** to encourage further improvements.
185
+ If you find this package useful, **please give it a star ⭐ on GitHub** to support further development.
94
186
 
95
187
  👉 **[GitHub Repository](https://github.com/javadSharifi/persian-number-input)**
96
188
 
97
189
  Thank you for your support! ❤️🚀
98
190
 
99
- ---
100
-
101
191
  ### 📈 SEO Keywords
102
192
 
103
- `Persian Number Input`, `React Persian input`, `localization`, `digit grouping`, `Persian digits`, `React numeric input`, `number formatter`
104
-
105
- ---
193
+ `Persian Number Input`, `React Persian input`, `React number formatting`, `localized numeric input`, `Persian digits`, `React numeric input`, `number formatter`, `TypeScript React component`, `multilingual input`, `React number formatting hook`, `Persian number utility`
106
194
 
107
195
  ### 📄 License
108
196
 
109
- [MIT License](LICENSE)
197
+ MIT License
110
198
 
111
- © 2024 Your Name. All rights reserved.
199
+ © 2025 Javad Sharifi. All rights reserved.
112
200
 
113
- # persian-number-input
201
+ ---
114
202
 
115
- ## 🇮🇷 فارسی
203
+ ## فارسی
116
204
 
117
- کامپوننت React برای ورودی اعداد فارسی، انگلیسی و هندی با قابلیت جداکننده ارقام و محلی‌سازی کامل.
205
+ **کامپوننت ورودی اعداد فارسی** - یک کامپوننت و ابزار قدرتمند React برای مدیریت و فرمت‌بندی اعداد به صورت فارسی، انگلیسی یا سایر سیستم‌های ارقام محلی. ایده‌آل برای برنامه‌های چندزبانه که نیاز به ورودی‌های عددی با فرمت سفارشی و پشتیبانی از اعشار دارند.
118
206
 
119
207
  ✅ **امکانات کلیدی:**
120
208
 
121
- - پشتیبانی از اعداد فارسی، انگلیسی و هندی
122
- - قابلیت تعیین جداکننده ارقام دلخواه (هزارگان)
123
- - تبدیل خودکار اعداد محلی به اعداد انگلیسی
124
- - استفاده آسان و پشتیبانی از React نسخه‌های 16 تا 19
209
+ - پشتیبانی از ارقام فارسی، انگلیسی و سایر زبان‌ها (مانند هندی)
210
+ - قابلیت تنظیم جداکننده ارقام (مثل هزارگان)
211
+
212
+ - اعمال محدودیت‌های حداقل و حداکثر با پشتیبانی از اعشار
213
+ - تبدیل خودکار ارقام محلی به ارقام انگلیسی برای پردازش
214
+ - سبک و سازگار با React 16 تا 19
215
+ - پشتیبانی از TypeScript برای توسعه امن
125
216
 
126
217
  ### 🚀 نصب
127
218
 
219
+ پکیج را از طریق npm یا yarn نصب کنید:
220
+
128
221
  ```bash
129
- npm install persian-number-input
222
+ npm install persian-number-input
130
223
  ```
131
224
 
132
- ### 💻 روش استفاده
225
+ ### 💻 مثال‌های استفاده
226
+
227
+ #### ۱. استفاده از کامپوننت `PersianNumberInput`
133
228
 
134
- مثال ساده:
229
+ این کامپوننت برای ورودی‌های فرم با فرمت‌بندی محلی مناسب است.
135
230
 
136
231
  ```jsx
137
232
  import React, { useState } from "react";
@@ -142,10 +237,17 @@ const App = () => {
142
237
 
143
238
  return (
144
239
  <PersianNumberInput
145
- initialValue="123456"
240
+ initialValue="123456.78"
146
241
  separatorCount={3}
147
- lang="fa"
148
- onChangeValue={(val) => setNumber(val)}
242
+ separatorChar=","
243
+ locale="fa"
244
+ maxDecimals={2}
245
+ min={0.5}
246
+ max={1000000.999}
247
+ showZero={true}
248
+ onValueChange={(val) => setNumber(val || "")}
249
+ placeholder="یک عدد وارد کنید"
250
+ className="numeric-input"
149
251
  />
150
252
  );
151
253
  };
@@ -153,32 +255,135 @@ const App = () => {
153
255
  export default App;
154
256
  ```
155
257
 
156
- ### 🔥 مثال خروجی
258
+ **خروجی**:
259
+ ```
260
+ ورودی: 123456.78
261
+ خروجی نمایشی: ۱۲۳,۴۵۶٫۷۸
262
+ خروجی انگلیسی: 123456.78
263
+ ```
264
+
265
+ #### ۲. استفاده از هوک `usePersianNumberInput`
266
+
267
+ هوک `usePersianNumberInput` برای کنترل دقیق ورودی‌های سفارشی استفاده می‌شود.
157
268
 
269
+ ```jsx
270
+ import React from "react";
271
+ import { usePersianNumberInput } from "persian-number-input";
272
+
273
+ const CustomInput = () => {
274
+ const { value, onChange, rawValue } = usePersianNumberInput({
275
+ initialValue: "5000.25",
276
+ separatorCount: 3,
277
+ separatorChar: ",",
278
+ locale: "fa",
279
+ maxDecimals: 2,
280
+ min: 0.5,
281
+ max: 10000.999,
282
+ showZero: true,
283
+ });
284
+
285
+ return (
286
+ <div>
287
+ <input
288
+ type="text"
289
+ inputMode="decimal"
290
+ value={value}
291
+ onChange={onChange}
292
+ placeholder="یک عدد وارد کنید"
293
+ />
294
+ <p>مقدار خام: {rawValue || "بدون مقدار"}</p>
295
+ </div>
296
+ );
297
+ };
298
+
299
+ export default CustomInput;
158
300
  ```
159
- ورودی: 123456
160
- خروجی نمایشی: ۱۲۳,۴۵۶
161
- خروجی انگلیسی: 123456
301
+
302
+ **توضیح**:
303
+ - این هوک وضعیت ورودی و فرمت‌بندی را مدیریت می‌کند و `value` (برای نمایش) و `rawValue` (ارقام انگلیسی) را برمی‌گرداند.
304
+ - برای کامپوننت‌های ورودی سفارشی یا فرم‌های غیراستاندارد مناسب است.
305
+ - **خروجی**:
306
+ ```
307
+ ورودی نمایشی: ۵,۰۰۰٫۲۵
308
+ مقدار خام: 5000.25
309
+ ```
310
+
311
+ #### ۳. استفاده از ابزار `transformNumber`
312
+
313
+ تابع `transformNumber` برای فرمت‌بندی اعداد بدون نیاز به کامپوننت React مناسب است.
314
+
315
+ ```javascript
316
+ import { transformNumber } from "persian-number-input";
317
+
318
+ const number = 123456.789;
319
+ const formatted = transformNumber(number, {
320
+ separatorCount: 3,
321
+ separatorChar: ",",
322
+ locale: "fa",
323
+ maxDecimals: 2,
324
+ showZero: true,
325
+ });
326
+
327
+ console.log(formatted); // خروجی: ۱۲۳,۴۵۶٫۷۹
162
328
  ```
163
329
 
164
- ![مثال خروجی ](./public/output.png)
330
+ **توضیح**:
331
+ - از `transformNumber` برای فرمت‌بندی اعداد در جداول، برچسب‌ها یا سایر موارد غیرورودی استفاده کنید.
332
+ - همان گزینه‌های `PersianNumberInput` (مانند `separatorCount` و `locale`) را پشتیبانی می‌کند.
333
+ - یک رشته با ارقام محلی و فرمت‌بندی مناسب برمی‌گرداند.
165
334
 
166
- ### 📚 مشخصات Props
335
+ ### 📚 مرجع مشخصات (Props)
167
336
 
168
- | نام | نوع | پیشفرض | توضیح |
169
- | -------------- | ------------------------------- | ------ | -------------------------------- |
170
- | initialValue | string | "" | مقدار اولیه |
171
- | separatorCount | number | 0 | تعداد ارقام جداشده (مثلاً ۳ رقم) |
172
- | separatorChar | string | "," | کاراکتر جداکننده (مانند `,`) |
173
- | lang | 'fa' \| 'in' \| 'en' | "fa" | زبان نمایش ارقام |
174
- | onChangeValue | (englishNumber: string) => void | - | فراخوانی در تغییر مقدار |
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`) |
175
349
 
176
- ---
350
+ ### 🌟 چرا از این کامپوننت استفاده کنیم؟
351
+
352
+ - **پشتیبانی چندزبانه**: مدیریت آسان ارقام فارسی، انگلیسی یا سایر زبان‌ها.
353
+ - **فرمت‌بندی انعطاف‌پذیر**: کنترل جداکننده‌ها، اعشار و نمایش صفر.
354
+ - **اعتبارسنجی قوی**: اعمال محدودیت‌های حداقل و حداکثر با دقت اعشاری با ``.
355
+ - **مناسب توسعه‌دهندگان**: پشتیبانی از TypeScript و API ساده برای ادغام سریع.
356
+ - **سبک و سریع**: بهینه‌شده برای عملکرد با حداقل وابستگی‌ها.
357
+
358
+ ### ❓ سوالات متداول
359
+
360
+ **آیا این پکیج از React 19 پشتیبانی می‌کند؟**
361
+ بله، کاملاً با React 16 تا 19 سازگار است.
362
+
363
+ **آیا می‌توان از اعداد اعشاری استفاده کرد؟**
364
+ بله، با تنظیم `maxDecimals` می‌توانید تعداد ارقام اعشاری را مشخص کنید (مثلاً `maxDecimals={2}`).
365
+
366
+ **چگونه می‌توان حداقل و حداکثر مقدار را اعمال کرد؟**
367
+ از پراپ‌های `min` و `max` استفاده کنید که از اعشار پشتیبانی می‌کنند (مثلاً `min={0.5}` و `max={1000.201}`).
368
+
369
+ **چگونه ظاهر ورودی را سفارشی کنم؟**
370
+ با پراپ‌های `className` یا `style` می‌توانید ظاهر ورودی را تغییر دهید.
371
+
372
+ **اگر کاربر عدد نامعتبری وارد کند چه می‌شود؟**
373
+ کامپوننت ورودی‌ها را پاکسازی می‌کند و فقط اعداد معتبر را پردازش می‌کند، ضمن رعایت محدودیت‌های min/max.
177
374
 
178
375
  ### 🌟 حمایت از پروژه
179
376
 
180
- اگر این پکیج برای شما مفید بود، **لطفاً یک ستاره به مخزن GitHub بدهید ⭐**. این بهترین راه برای حمایت از پروژه و تشویق توسعه‌دهنده به بهبود آن است.
377
+ اگر این پکیج برای شما مفید بود، **لطفاً یک ستاره به مخزن GitHub بدهید** تا توسعه بیشتر آن را تشویق کنید.
181
378
 
182
- 👉 **[GitHub Repository](https://github.com/javadSharifi/persian-number-input)**
379
+ 👉 **[مخزن GitHub](https://github.com/javadSharifi/persian-number-input)**
380
+
381
+ از حمایت شما سپاسگزاریم! ❤️🚀
382
+
383
+ ### 📈 کلمات کلیدی برای جستجو
384
+
385
+ `ورودی اعداد فارسی`, `کامپوننت React فارسی`, `فرمت‌بندی اعداد در React`, `ورودی عددی محلی‌سازی‌شده`, `ارقام فارسی`, `ورودی عددی React`, `فرمت‌کننده اعداد`, `کامپوننت TypeScript React`, `ورودی چندزبانه`, `هوک فرمت‌بندی اعداد`, `ابزار اعداد فارسی`
386
+
387
+ ### 📄 مجوز
183
388
 
184
- از حمایت شما متشکریم! ❤️🚀
389
+ MIT License
@@ -1,12 +1,11 @@
1
1
  import React from 'react';
2
- interface PersianNumberInputCustomProps {
3
- initialValue?: string;
4
- separatorCount?: number;
5
- separatorChar?: string;
6
- lang?: 'fa' | 'in' | 'en';
7
- onChangeValue?: (englishNumber: string) => void;
2
+ import type { TransformNumberOptions } from '../utils/transformNumber';
3
+ interface PersianNumberInputProps extends TransformNumberOptions, Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value'> {
4
+ onValueChange?: (value: string | undefined) => void;
5
+ initialValue?: number | string;
6
+ min?: number;
7
+ max?: number;
8
8
  }
9
- type AllowedInputProps = Pick<React.InputHTMLAttributes<HTMLInputElement>, 'className' | 'style' | 'placeholder' | 'disabled' | 'readOnly' | 'id' | 'name' | 'autoComplete' | 'autoFocus' | 'maxLength' | 'minLength' | 'required' | 'title' | 'dir' | 'onClick' | 'onKeyDown' | 'onKeyUp' | 'onKeyPress' | 'onFocus' | 'onBlur' | 'onMouseDown' | 'onMouseUp' | 'onMouseEnter' | 'onMouseLeave' | 'onTouchStart' | 'onTouchEnd' | 'onPaste'>;
10
- export type PersianNumberInputProps = PersianNumberInputCustomProps & AllowedInputProps;
11
9
  declare const PersianNumberInput: React.FC<PersianNumberInputProps>;
12
10
  export default PersianNumberInput;
11
+ //# sourceMappingURL=PersianNumberInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PersianNumberInput.d.ts","sourceRoot":"","sources":["../../src/components/PersianNumberInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGvE,UAAU,uBACN,SAAQ,sBAAsB,EAC9B,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAEvE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACpD,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAiDzD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  var __rest = (this && this.__rest) || function (s, e) {
2
3
  var t = {};
3
4
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -9,29 +10,38 @@ var __rest = (this && this.__rest) || function (s, e) {
9
10
  }
10
11
  return t;
11
12
  };
12
- import React, { useCallback, useState } from 'react';
13
- import { toLocalizedDigits, groupDigits, convertToEnglishDigits } from '../utils/digitUtils';
14
- // استایل پایه برای input
15
- const baseInputStyle = {
16
- border: '1px solid #ccc',
17
- borderRadius: '4px',
18
- };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ const jsx_runtime_1 = require("react/jsx-runtime");
15
+ const usePersianNumberInput_1 = require("../hooks/usePersianNumberInput");
19
16
  const PersianNumberInput = (_a) => {
20
- var { initialValue = '', separatorCount = 0, separatorChar = ',', lang = 'fa', onChangeValue, style } = _a, rest = __rest(_a, ["initialValue", "separatorCount", "separatorChar", "lang", "onChangeValue", "style"]);
21
- // تابع برای اعتبارسنجی ورودی و جلوگیری از کاراکترهای غیرمجاز
22
- const sanitizeInput = (input) => input.replace(/[^\d,]/g, '');
23
- const [value, setValue] = useState(() => convertToEnglishDigits(initialValue).replace(/\D/g, ''));
24
- const handleChange = useCallback((e) => {
25
- // فیلتر کردن ورودی‌های غیرمجاز
26
- const input = sanitizeInput(convertToEnglishDigits(e.target.value));
27
- setValue(input);
28
- if (onChangeValue)
29
- onChangeValue(input);
30
- }, [onChangeValue]);
31
- const formattedValue = groupDigits(value, separatorCount, separatorChar);
32
- const displayValue = lang === 'en' ? formattedValue : toLocalizedDigits(formattedValue, lang);
33
- const mergedStyle = Object.assign(Object.assign({}, baseInputStyle), style);
34
- return (React.createElement("input", Object.assign({ value: displayValue, onChange: handleChange, style: mergedStyle }, rest)));
17
+ var {
18
+ // جدا کردن آپشن های هوک از بقیه پراپ های input
19
+ initialValue, separatorCount, separatorChar, locale, maxDecimals, showZero, onValueChange, min, max } = _a,
20
+ // بقیه پراپ ها (مثل className, style, placeholder, id و ...) به input اصلی منتقل می شوند
21
+ restInputProps = __rest(_a, ["initialValue", "separatorCount", "separatorChar", "locale", "maxDecimals", "showZero", "onValueChange", "min", "max"]);
22
+ // اعتبارسنجی پراپ‌ها
23
+ if (maxDecimals !== undefined && maxDecimals < 0) {
24
+ console.warn('maxDecimals باید غیرمنفی باشد');
25
+ maxDecimals = 0;
26
+ }
27
+ if (min !== undefined && max !== undefined && min > max) {
28
+ console.warn('min نباید بزرگ‌تر از max باشد');
29
+ }
30
+ const { value: formattedValue, onChange, rawValue, // می توانید rawValue را هم برگردانید اگر لازم است
31
+ } = (0, usePersianNumberInput_1.usePersianNumberInput)({
32
+ initialValue,
33
+ separatorCount,
34
+ separatorChar,
35
+ locale,
36
+ maxDecimals,
37
+ showZero,
38
+ onValueChange,
39
+ min,
40
+ max
41
+ });
42
+ return ((0, jsx_runtime_1.jsx)("input", Object.assign({ type: "text" // یا "tel" هم گاهی استفاده می شود
43
+ , inputMode: "decimal", dir: "ltr" // معمولا برای اعداد بهتر است
44
+ }, restInputProps, { value: formattedValue, onChange: onChange })));
35
45
  };
36
- export default PersianNumberInput;
46
+ exports.default = PersianNumberInput;
37
47
  //# sourceMappingURL=PersianNumberInput.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PersianNumberInput.js","sourceRoot":"","sources":["../../src/components/PersianNumberInput.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AA0C7F,yBAAyB;AACzB,MAAM,cAAc,GAAwB;IACxC,MAAM,EAAE,gBAAgB;IACxB,YAAY,EAAE,KAAK;CACtB,CAAC;AAIF,MAAM,kBAAkB,GAAsC,CAAC,EAQ9D,EAAE,EAAE;QAR0D,EAC3D,YAAY,GAAG,EAAE,EACjB,cAAc,GAAG,CAAC,EAClB,aAAa,GAAG,GAAG,EACnB,IAAI,GAAG,IAAI,EACX,aAAa,EACb,KAAK,OAER,EADM,IAAI,cAPoD,qFAQ9D,CADU;IAEP,6DAA6D;IAC7D,MAAM,aAAa,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAEtE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IAElG,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAsC,EAAE,EAAE;QACxE,+BAA+B;QAC/B,MAAM,KAAK,GAAG,aAAa,CAAC,sBAAsB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChB,IAAI,aAAa;YAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC;IACzE,MAAM,YAAY,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IAE9F,MAAM,WAAW,mCAAQ,cAAc,GAAK,KAAK,CAAE,CAAC;IAEpD,OAAO,CACH,6CACI,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,YAAY,EACtB,KAAK,EAAE,WAAW,IACd,IAAI,EACV,CACL,CAAC;AACN,CAAC,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"PersianNumberInput.js","sourceRoot":"","sources":["../../src/components/PersianNumberInput.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;AACA,0EAAuE;AAcvE,MAAM,kBAAkB,GAAsC,CAAC,EAa9D,EAAE,EAAE;QAb0D;IAC3D,+CAA+C;IAC/C,YAAY,EACZ,cAAc,EACd,aAAa,EACb,MAAM,EACN,WAAW,EACX,QAAQ,EACR,aAAa,EACb,GAAG,EACH,GAAG,OAGN;IAFG,yFAAyF;IACtF,cAAc,cAZ0C,uHAa9D,CADoB;IAEjB,qBAAqB;IACrB,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QAC9C,WAAW,GAAG,CAAC,CAAC;IACpB,CAAC;IACD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,EACF,KAAK,EAAE,cAAc,EACrB,QAAQ,EACR,QAAQ,EAAE,kDAAkD;MAC/D,GAAG,IAAA,6CAAqB,EAAC;QACtB,YAAY;QACZ,cAAc;QACd,aAAa;QACb,MAAM;QACN,WAAW;QACX,QAAQ;QACR,aAAa;QACb,GAAG;QACH,GAAG;KACN,CAAC,CAAC;IAEH,OAAO,CACH,gDACI,IAAI,EAAC,MAAM,CAAC,kCAAkC;UAC9C,SAAS,EAAC,SAAS,EACnB,GAAG,EAAC,KAAK,CAAC,6BAA6B;QACnC,cAAc,IAClB,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,QAAQ,IACpB,CACL,CAAC;AACN,CAAC,CAAC;AAEF,kBAAe,kBAAkB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { TransformNumberOptions } from '../utils/transformNumber';
3
+ interface UsePersianNumberInputProps extends TransformNumberOptions {
4
+ initialValue?: number | string;
5
+ onValueChange?: (value: string | undefined) => void;
6
+ min?: number;
7
+ max?: number;
8
+ }
9
+ interface UsePersianNumberInputReturn {
10
+ /** مقدار فرمت شده برای نمایش در input. */
11
+ value: string;
12
+ /** تابع onChange برای اتصال به input. */
13
+ onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
14
+ /** تابع برای تنظیم مقدار به صورت برنامه نویسی (مقدار عددی تمیز). */
15
+ setValue: (newValue: number | string | undefined) => void;
16
+ /** مقدار عددی خام (رشته انگلیسی تمیز شده) */
17
+ rawValue: string | undefined;
18
+ }
19
+ export declare const usePersianNumberInput: ({ initialValue, separatorCount, separatorChar, locale, maxDecimals, showZero, onValueChange, min, max, }?: UsePersianNumberInputProps) => UsePersianNumberInputReturn;
20
+ export {};
21
+ //# sourceMappingURL=usePersianNumberInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePersianNumberInput.d.ts","sourceRoot":"","sources":["../../src/hooks/usePersianNumberInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAE9D,OAAO,EAAmB,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGnF,UAAU,0BAA2B,SAAQ,sBAAsB;IACjE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,2BAA2B;IACnC,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC/D,oEAAoE;IACpE,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC1D,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAWD,eAAO,MAAM,qBAAqB,GAAI,2GAUnC,0BAA+B,KAAG,2BAqIpC,CAAC"}
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.usePersianNumberInput = void 0;
7
+ const react_1 = require("react");
8
+ const decimal_js_1 = __importDefault(require("decimal.js"));
9
+ const transformNumber_1 = require("../utils/transformNumber");
10
+ const digitUtils_1 = require("../utils/digitUtils");
11
+ // تابع کمکی برای گرد کردن مقدار به تعداد اعشار مشخص
12
+ const roundToDecimals = (value, maxDecimals) => {
13
+ if (!value || !value.includes('.'))
14
+ return value; // اگر اعشاری نیست یا خالی است، همان را برگردان
15
+ const [integerPart, fractionalPart] = value.split('.');
16
+ if (maxDecimals === 0)
17
+ return integerPart; // اگر اعشار مجاز نیست، فقط بخش صحیح
18
+ const trimmedFractional = fractionalPart.slice(0, maxDecimals);
19
+ return trimmedFractional ? `${integerPart}.${trimmedFractional}` : integerPart;
20
+ };
21
+ const usePersianNumberInput = ({ initialValue, separatorCount = 3, separatorChar = ',', locale = 'fa', maxDecimals = 0, showZero = false, onValueChange, min, max, } = {}) => {
22
+ // State داخلی برای نگه داشتن مقدار عددی *تمیز شده* (ارقام انگلیسی، بدون جداکننده)
23
+ const [rawValue, setRawValue] = (0, react_1.useState)(() => {
24
+ if (initialValue === null || initialValue === undefined)
25
+ return undefined;
26
+ // مقدار اولیه را پاکسازی کن
27
+ let sanitized = (0, digitUtils_1.sanitizeNumericInput)(String(initialValue));
28
+ // اگر مقدار اولیه 0 بود و showZero false بود، مقدار خام را undefined بگذار
29
+ if (parseFloat(sanitized) === 0 &&
30
+ !showZero &&
31
+ initialValue !== 0 &&
32
+ initialValue !== '0') {
33
+ return undefined;
34
+ }
35
+ // گرد کردن به تعداد اعشار مجاز
36
+ sanitized = roundToDecimals(sanitized, maxDecimals);
37
+ // بررسی min و max برای مقدار اولیه
38
+ if (sanitized) {
39
+ try {
40
+ const numericValue = new decimal_js_1.default(sanitized);
41
+ if ((min !== undefined && numericValue.lt(min)) ||
42
+ (max !== undefined && numericValue.gt(max))) {
43
+ return undefined; // اگر مقدار اولیه خارج از محدوده است، undefined برگردان
44
+ }
45
+ }
46
+ catch (error) {
47
+ console.warn(`Invalid initial value: ${sanitized}`, error);
48
+ return undefined; // در صورت خطا، مقدار نامعتبر را رد کن
49
+ }
50
+ }
51
+ return sanitized || undefined; // اگر پاکسازی نتیجه خالی داد، undefined بگذار
52
+ });
53
+ // استفاده از useMemo برای بهینه سازی
54
+ const displayValue = (0, react_1.useMemo)(() => {
55
+ const options = { separatorCount, separatorChar, locale, maxDecimals, showZero };
56
+ // اگر rawValue تعریف نشده باشد، "" برگردان
57
+ if (rawValue === undefined) {
58
+ return showZero ? (0, transformNumber_1.transformNumber)('0', options) : '';
59
+ }
60
+ return (0, transformNumber_1.transformNumber)(rawValue, options);
61
+ }, [rawValue, separatorCount, separatorChar, locale, maxDecimals, showZero]);
62
+ const handleChange = (0, react_1.useCallback)((event) => {
63
+ const inputValue = event.target.value;
64
+ let sanitizedValue = (0, digitUtils_1.sanitizeNumericInput)(inputValue); // پاکسازی ورودی کاربر
65
+ // اگر مقدار پاکسازی شده با مقدار خام فعلی متفاوت بود، آپدیت کن
66
+ if (sanitizedValue !== rawValue) {
67
+ // گرد کردن به تعداد اعشار مجاز
68
+ sanitizedValue = roundToDecimals(sanitizedValue, maxDecimals);
69
+ // بررسی min و max
70
+ let valueToSet = sanitizedValue;
71
+ if (sanitizedValue) {
72
+ try {
73
+ const numericValue = new decimal_js_1.default(sanitizedValue);
74
+ if ((min !== undefined && numericValue.lt(min)) ||
75
+ (max !== undefined && numericValue.gt(max))) {
76
+ return; // اگر مقدار خارج از محدوده است، تغییر را اعمال نکن
77
+ }
78
+ }
79
+ catch (error) {
80
+ console.warn(`Invalid input value: ${sanitizedValue}`, error);
81
+ return; // در صورت خطا، مقدار نامعتبر را رد کن
82
+ }
83
+ }
84
+ // اگر مقدار پاکسازی شده 0 بود و showZero=false، مقدار خام را undefined بگذار
85
+ valueToSet =
86
+ parseFloat(sanitizedValue) === 0 &&
87
+ !showZero &&
88
+ sanitizedValue !== '0.'
89
+ ? undefined
90
+ : sanitizedValue;
91
+ setRawValue(valueToSet);
92
+ if (onValueChange) {
93
+ onValueChange(valueToSet); // اطلاع رسانی مقدار عددی تمیز شده
94
+ }
95
+ }
96
+ }, [rawValue, onValueChange, showZero, min, max, maxDecimals]);
97
+ const handleSetValue = (0, react_1.useCallback)((newValue) => {
98
+ if (newValue === null || newValue === undefined) {
99
+ setRawValue(undefined);
100
+ if (onValueChange)
101
+ onValueChange(undefined);
102
+ return;
103
+ }
104
+ let sanitizedValue = (0, digitUtils_1.sanitizeNumericInput)(String(newValue));
105
+ // گرد کردن به تعداد اعشار مجاز
106
+ sanitizedValue = roundToDecimals(sanitizedValue, maxDecimals);
107
+ // بررسی min و max
108
+ if (sanitizedValue) {
109
+ try {
110
+ const numericValue = new decimal_js_1.default(sanitizedValue);
111
+ if ((min !== undefined && numericValue.lt(min)) ||
112
+ (max !== undefined && numericValue.gt(max))) {
113
+ return; // اگر مقدار خارج از محدوده است، تغییر را اعمال نکن
114
+ }
115
+ }
116
+ catch (error) {
117
+ console.warn(`Invalid set value: ${sanitizedValue}`, error);
118
+ return; // در صورت خطا، مقدار نامعتبر را رد کن
119
+ }
120
+ }
121
+ const valueToSet = parseFloat(sanitizedValue) === 0 &&
122
+ !showZero &&
123
+ sanitizedValue !== '0.'
124
+ ? undefined
125
+ : sanitizedValue;
126
+ setRawValue(valueToSet);
127
+ if (onValueChange) {
128
+ onValueChange(valueToSet);
129
+ }
130
+ }, [onValueChange, showZero, min, max, maxDecimals]);
131
+ return {
132
+ value: displayValue, // مقدار قالب بندی شده برای input
133
+ onChange: handleChange, // تابع برای اتصال به input.onChange
134
+ setValue: handleSetValue, // تابع برای تنظیم مقدار برنامه ای
135
+ rawValue: rawValue, // مقدار عددی خام (رشته انگلیسی)
136
+ };
137
+ };
138
+ exports.usePersianNumberInput = usePersianNumberInput;
139
+ //# sourceMappingURL=usePersianNumberInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePersianNumberInput.js","sourceRoot":"","sources":["../../src/hooks/usePersianNumberInput.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1 +1,6 @@
1
+ export { usePersianNumberInput } from "./hooks/usePersianNumberInput";
1
2
  export { default as PersianNumberInput } from "./components/PersianNumberInput";
3
+ export { transformNumber } from "./utils/transformNumber";
4
+ export type { TransformNumberOptions } from "./utils/transformNumber";
5
+ export * from "./utils/digitUtils";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,28 @@
1
- export { default as PersianNumberInput } from "./components/PersianNumberInput";
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.transformNumber = exports.PersianNumberInput = exports.usePersianNumberInput = void 0;
21
+ var usePersianNumberInput_1 = require("./hooks/usePersianNumberInput");
22
+ Object.defineProperty(exports, "usePersianNumberInput", { enumerable: true, get: function () { return usePersianNumberInput_1.usePersianNumberInput; } });
23
+ var PersianNumberInput_1 = require("./components/PersianNumberInput");
24
+ Object.defineProperty(exports, "PersianNumberInput", { enumerable: true, get: function () { return __importDefault(PersianNumberInput_1).default; } });
25
+ var transformNumber_1 = require("./utils/transformNumber");
26
+ Object.defineProperty(exports, "transformNumber", { enumerable: true, get: function () { return transformNumber_1.transformNumber; } });
27
+ __exportStar(require("./utils/digitUtils"), exports);
2
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,uEAAsE;AAA7D,8HAAA,qBAAqB,OAAA;AAC9B,sEAAgF;AAAvE,yIAAA,OAAO,OAAsB;AACtC,2DAA0D;AAAjD,kHAAA,eAAe,OAAA;AAExB,qDAAmC"}
@@ -1,6 +1,48 @@
1
+ /**
2
+ * نقشه ارقام محلی برای زبان‌های مختلف.
3
+ */
1
4
  export declare const digitsMap: {
2
- [key: string]: string[];
5
+ [key: string]: ReadonlyArray<string>;
3
6
  };
4
- export declare const toLocalizedDigits: (numStr: string, locale: "fa" | "in") => string;
5
- export declare const groupDigits: (numStr: string, separatorCount: number, separatorChar?: string) => string;
7
+ /**
8
+ * نقشه جداکننده اعشار برای زبان‌های مختلف.
9
+ */
10
+ export declare const decimalSeparatorMap: {
11
+ [key: string]: string;
12
+ };
13
+ /**
14
+ * تبدیل رشته حاوی ارقام محلی (مانند فارسی) به رشته با ارقام انگلیسی (0-9).
15
+ * @param str رشته ورودی
16
+ * @returns رشته با ارقام انگلیسی
17
+ */
6
18
  export declare const convertToEnglishDigits: (str: string) => string;
19
+ /**
20
+ * تبدیل رشته حاوی ارقام انگلیسی (0-9) به رشته با ارقام محلی.
21
+ * @param numStr رشته با ارقام انگلیسی
22
+ * @param locale کد زبان ('fa', 'in', ...)
23
+ * @returns رشته با ارقام محلی
24
+ */
25
+ export declare const toLocalizedDigits: (numStr: string, locale: keyof typeof digitsMap) => string;
26
+ /**
27
+ * جایگزینی جداکننده اعشار انگلیسی (.) با جداکننده محلی.
28
+ * @param numStr رشته با ارقام و جداکننده انگلیسی
29
+ * @param locale کد زبان
30
+ * @returns رشته با جداکننده اعشار محلی
31
+ */
32
+ export declare const localizeDecimalSeparator: (numStr: string, locale: keyof typeof decimalSeparatorMap) => string;
33
+ /**
34
+ * گروه‌بندی ارقام قسمت صحیح یک عدد با استفاده از جداکننده.
35
+ * @param numStr قسمت صحیح عدد (فقط ارقام انگلیسی)
36
+ * @param separatorCount تعداد ارقام در هر گروه (مثلا 3 برای هزارگان)
37
+ * @param separatorChar کاراکتر جداکننده (پیش فرض ',')
38
+ * @returns رشته گروه‌بندی شده
39
+ */
40
+ export declare const groupDigits: (numStr: string, separatorCount: number, separatorChar?: string) => string;
41
+ /**
42
+ * پاکسازی ورودی کاربر برای نگه داشتن فقط کاراکترهای عددی معتبر (ارقام، یک نقطه، یک علامت منفی در ابتدا).
43
+ * ابتدا ارقام محلی را به انگلیسی تبدیل می کند.
44
+ * @param value مقدار ورودی کاربر
45
+ * @returns رشته عددی پاکسازی شده با ارقام انگلیسی
46
+ */
47
+ export declare const sanitizeNumericInput: (value: string) => string;
48
+ //# sourceMappingURL=digitUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digitUtils.d.ts","sourceRoot":"","sources":["../../src/utils/digitUtils.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;CAI7D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAGxD,CAAC;AAaF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,KAAK,MAAM,KAAG,MAGpD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,EAAE,QAAQ,MAAM,OAAO,SAAS,KAAG,MAIlF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GAAI,QAAQ,MAAM,EAAE,QAAQ,MAAM,OAAO,mBAAmB,KAAG,MAInG,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,MAAM,EACd,gBAAgB,MAAM,EACtB,sBAAmB,KAClB,MAOF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,KAAG,MAyBpD,CAAC"}
@@ -1,43 +1,110 @@
1
- export const digitsMap = {
1
+ "use strict";
2
+ // utils/digitUtils.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.sanitizeNumericInput = exports.groupDigits = exports.localizeDecimalSeparator = exports.toLocalizedDigits = exports.convertToEnglishDigits = exports.decimalSeparatorMap = exports.digitsMap = void 0;
5
+ /**
6
+ * نقشه ارقام محلی برای زبان‌های مختلف.
7
+ */
8
+ exports.digitsMap = {
2
9
  fa: ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"],
3
- in: ["०", "१", "२", "३", "४", "५", "६", "७", "८", "९"],
10
+ // می توانید زبان های دیگر را اضافه کنید
11
+ // in: ["०", "१", "२", "३", "४", "५", "६", "७", "८", "९"],
4
12
  };
5
- // تبدیل اعداد به اعداد محلی با استفاده از نقشه
6
- export const toLocalizedDigits = (numStr, locale) => {
7
- const digits = digitsMap[locale];
8
- return numStr.replace(/\d/g, (digit) => digits[parseInt(digit)]);
13
+ /**
14
+ * نقشه جداکننده اعشار برای زبان‌های مختلف.
15
+ */
16
+ exports.decimalSeparatorMap = {
17
+ fa: "٫",
18
+ // en: ".", (پیش فرض نقطه است)
9
19
  };
10
- // گروه‌بندی اعداد با استفاده از جداکننده
11
- export const groupDigits = (numStr, separatorCount, separatorChar = ",") => {
12
- if (separatorCount && separatorCount > 0) {
13
- return numStr.replace(new RegExp(`\\B(?=(\\d{${separatorCount}})+(?!\\d))`, "g"), separatorChar);
20
+ const allLocalizedDigits = Object.values(exports.digitsMap).flat().join("");
21
+ const conversionMap = {};
22
+ for (const locale in exports.digitsMap) {
23
+ exports.digitsMap[locale].forEach((digit, index) => {
24
+ conversionMap[digit] = index.toString();
25
+ });
26
+ }
27
+ // Regex بهینه شده برای پیدا کردن تمام ارقام محلی
28
+ const localizedDigitsRegex = new RegExp(`[${allLocalizedDigits}]`, "g");
29
+ /**
30
+ * تبدیل رشته حاوی ارقام محلی (مانند فارسی) به رشته با ارقام انگلیسی (0-9).
31
+ * @param str رشته ورودی
32
+ * @returns رشته با ارقام انگلیسی
33
+ */
34
+ const convertToEnglishDigits = (str) => {
35
+ if (!str)
36
+ return "";
37
+ return str.replace(localizedDigitsRegex, (char) => conversionMap[char] || char);
38
+ };
39
+ exports.convertToEnglishDigits = convertToEnglishDigits;
40
+ /**
41
+ * تبدیل رشته حاوی ارقام انگلیسی (0-9) به رشته با ارقام محلی.
42
+ * @param numStr رشته با ارقام انگلیسی
43
+ * @param locale کد زبان ('fa', 'in', ...)
44
+ * @returns رشته با ارقام محلی
45
+ */
46
+ const toLocalizedDigits = (numStr, locale) => {
47
+ if (!numStr || !exports.digitsMap[locale])
48
+ return numStr;
49
+ const localeDigits = exports.digitsMap[locale];
50
+ return numStr.replace(/\d/g, (digit) => localeDigits[parseInt(digit)]);
51
+ };
52
+ exports.toLocalizedDigits = toLocalizedDigits;
53
+ /**
54
+ * جایگزینی جداکننده اعشار انگلیسی (.) با جداکننده محلی.
55
+ * @param numStr رشته با ارقام و جداکننده انگلیسی
56
+ * @param locale کد زبان
57
+ * @returns رشته با جداکننده اعشار محلی
58
+ */
59
+ const localizeDecimalSeparator = (numStr, locale) => {
60
+ const separator = exports.decimalSeparatorMap[locale];
61
+ if (!separator)
62
+ return numStr; // اگر جداکننده محلی تعریف نشده، همان نقطه را برگردان
63
+ return numStr.replace(".", separator);
64
+ };
65
+ exports.localizeDecimalSeparator = localizeDecimalSeparator;
66
+ /**
67
+ * گروه‌بندی ارقام قسمت صحیح یک عدد با استفاده از جداکننده.
68
+ * @param numStr قسمت صحیح عدد (فقط ارقام انگلیسی)
69
+ * @param separatorCount تعداد ارقام در هر گروه (مثلا 3 برای هزارگان)
70
+ * @param separatorChar کاراکتر جداکننده (پیش فرض ',')
71
+ * @returns رشته گروه‌بندی شده
72
+ */
73
+ const groupDigits = (numStr, separatorCount, separatorChar = ",") => {
74
+ if (!numStr || separatorCount <= 0) {
75
+ return numStr;
14
76
  }
15
- return numStr;
77
+ // Regex برای پیدا کردن محل درج جداکننده ها (از راست به چپ)
78
+ const regex = new RegExp(`\\B(?=(\\d{${separatorCount}})+(?!\\d))`, "g");
79
+ return numStr.replace(regex, separatorChar);
16
80
  };
17
- // تبدیل اعداد محلی به اعداد انگلیسی
18
- export const convertToEnglishDigits = (str) => {
19
- const map = {
20
- "۰": "0",
21
- "۱": "1",
22
- "۲": "2",
23
- "۳": "3",
24
- "۴": "4",
25
- "۵": "5",
26
- "۶": "6",
27
- "۷": "7",
28
- "۸": "8",
29
- "۹": "9",
30
- "०": "0",
31
- "१": "1",
32
- "": "2",
33
- "": "3",
34
- "४": "4",
35
- "५": "5",
36
- "": "6",
37
- "": "7",
38
- "८": "8",
39
- "९": "9",
40
- };
41
- return str.replace(/[۰-۹०-९]/g, (char) => map[char]);
81
+ exports.groupDigits = groupDigits;
82
+ /**
83
+ * پاکسازی ورودی کاربر برای نگه داشتن فقط کاراکترهای عددی معتبر (ارقام، یک نقطه، یک علامت منفی در ابتدا).
84
+ * ابتدا ارقام محلی را به انگلیسی تبدیل می کند.
85
+ * @param value مقدار ورودی کاربر
86
+ * @returns رشته عددی پاکسازی شده با ارقام انگلیسی
87
+ */
88
+ const sanitizeNumericInput = (value) => {
89
+ if (value === null || value === undefined)
90
+ return "";
91
+ // 1. تبدیل همه ارقام به انگلیسی
92
+ let cleaned = (0, exports.convertToEnglishDigits)(String(value));
93
+ // 2. حذف همه چیز به جز ارقام، نقطه و علامت منفی
94
+ cleaned = cleaned.replace(/[^-0-9.]/g, "");
95
+ // 3. مدیریت علامت منفی: فقط یکی در ابتدا مجاز است
96
+ const negativeSign = cleaned.startsWith("-") ? "-" : "";
97
+ cleaned = cleaned.replace(/-/g, ""); // حذف همه منفی ها
98
+ // 4. مدیریت نقطه اعشار: فقط یکی مجاز است
99
+ const parts = cleaned.split(".");
100
+ let integerPart = parts[0] || ""; // بخش صحیح
101
+ let fractionalPart = parts.slice(1).join(""); // فقط اولین بخش اعشاری را نگه دار
102
+ // 5. بازسازی رشته تمیز شده
103
+ let sanitized = negativeSign + integerPart;
104
+ if (parts.length > 1) { // اگر نقطه ای وجود داشت
105
+ sanitized += "." + fractionalPart;
106
+ }
107
+ return sanitized;
42
108
  };
109
+ exports.sanitizeNumericInput = sanitizeNumericInput;
43
110
  //# sourceMappingURL=digitUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"digitUtils.js","sourceRoot":"","sources":["../../src/utils/digitUtils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAgC;IACpD,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACtD,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CACvD,CAAC;AAEF,+CAA+C;AAC/C,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAc,EAAE,MAAmB,EAAE,EAAE;IACvE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,CAAC;AAEF,yCAAyC;AACzC,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,MAAc,EACd,cAAsB,EACtB,aAAa,GAAG,GAAG,EACnB,EAAE;IACF,IAAI,cAAc,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACzC,OAAO,MAAM,CAAC,OAAO,CACnB,IAAI,MAAM,CAAC,cAAc,cAAc,aAAa,EAAE,GAAG,CAAC,EAC1D,aAAa,CACd,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,oCAAoC;AACpC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAW,EAAE,EAAE;IACpD,MAAM,GAAG,GAA8B;QACrC,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG;KACT,CAAC;IACF,OAAO,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC"}
1
+ {"version":3,"file":"digitUtils.js","sourceRoot":"","sources":["../../src/utils/digitUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export interface TransformNumberOptions {
2
+ /** تعداد ارقام در هر گروه برای جداسازی (مثلا 3). 0 یا کمتر یعنی بدون جداسازی. */
3
+ separatorCount?: number;
4
+ /** کاراکتر جداکننده گروه ها (پیش فرض ','). */
5
+ separatorChar?: string;
6
+ /** کد زبان برای نمایش ارقام ('fa', 'en', ...). پیش فرض 'fa'. */
7
+ locale?: 'fa' | 'en' | string;
8
+ /** حداکثر تعداد ارقام اعشار مجاز. 0 یعنی بدون اعشار. */
9
+ maxDecimals?: number;
10
+ /** اگر true باشد، حتی اگر مقدار ورودی 0 باشد، آن را نمایش بده. پیش فرض false */
11
+ showZero?: boolean;
12
+ }
13
+ /**
14
+ * یک عدد یا رشته عددی را به فرمت محلی و گروه بندی شده تبدیل می کند.
15
+ *
16
+ * @param input عدد یا رشته ورودی. می تواند شامل ارقام محلی یا انگلیسی باشد.
17
+ * @param options تنظیمات قالب بندی.
18
+ * @returns رشته قالب بندی شده یا رشته خالی اگر ورودی نامعتبر یا صفر (و showZero=false) باشد.
19
+ */
20
+ export declare const transformNumber: (input: number | string | null | undefined, options?: TransformNumberOptions) => string;
21
+ //# sourceMappingURL=transformNumber.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformNumber.d.ts","sourceRoot":"","sources":["../../src/utils/transformNumber.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,sBAAsB;IACrC,iFAAiF;IACjF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAC9B,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,OAAO,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,UAAU,sBAAsB,KAC/B,MA6EF,CAAC"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformNumber = void 0;
4
+ // utils/transformNumber.ts
5
+ const digitUtils_1 = require("./digitUtils");
6
+ /**
7
+ * یک عدد یا رشته عددی را به فرمت محلی و گروه بندی شده تبدیل می کند.
8
+ *
9
+ * @param input عدد یا رشته ورودی. می تواند شامل ارقام محلی یا انگلیسی باشد.
10
+ * @param options تنظیمات قالب بندی.
11
+ * @returns رشته قالب بندی شده یا رشته خالی اگر ورودی نامعتبر یا صفر (و showZero=false) باشد.
12
+ */
13
+ const transformNumber = (input, options) => {
14
+ const { separatorCount = 3, // پیش فرض 3 برای هزارگان
15
+ separatorChar = ',', locale = 'fa', maxDecimals = 0, showZero = false, // به طور پیش فرض صفر نمایش داده نشود مگر اینکه صریحا خواسته شود
16
+ } = options || {};
17
+ if (input === null || input === undefined || input === "") {
18
+ return showZero ? (0, digitUtils_1.toLocalizedDigits)("0", locale) : ""; // اگر ورودی خالی است و showZero=false، خالی برگردان
19
+ }
20
+ // 1. تبدیل ورودی به رشته و سپس به ارقام انگلیسی و پاکسازی اولیه
21
+ // توجه: در استفاده با input، بهتر است sanitizeNumericInput روی مقدار input *قبل* از پاس دادن به این تابع اجرا شود.
22
+ // اما برای اطمینان، اینجا هم یک تبدیل اولیه انجام می دهیم.
23
+ let str = (0, digitUtils_1.convertToEnglishDigits)(String(input));
24
+ // 2. بررسی اولیه برای معتبر بودن فرمت عددی (اختیاری اما مفید)
25
+ // این regex اجازه یک منفی در ابتدا و یک نقطه اعشار را می دهد.
26
+ if (!/^-?\d*(\.\d*)?$/.test(str)) {
27
+ // اگر فرمت پایه عددی نیست (بعد از تبدیل به انگلیسی)، یا خالی برگردان یا خود ورودی اصلی
28
+ // تصمیم: فعلا خالی بر میگردانیم یا صفر اگر showZero فعال باشد
29
+ console.warn(`Invalid numeric string after conversion: "${str}" from input: "${input}"`);
30
+ return showZero ? (0, digitUtils_1.toLocalizedDigits)("0", locale) : "";
31
+ }
32
+ // تبدیل رشته خالی یا فقط "-" به صفر اگر showZero فعال باشد
33
+ if ((str === "" || str === "-") && showZero) {
34
+ str = "0";
35
+ }
36
+ else if (str === "" || str === "-") {
37
+ return ""; // اگر ورودی فقط "-" بود یا خالی شد، خالی برگردان
38
+ }
39
+ // اگر ورودی فقط "." بود
40
+ if (str === ".") {
41
+ return showZero ? (0, digitUtils_1.toLocalizedDigits)("0", locale) : "۰"; // یا شاید "۰." ؟ تصمیم با شماست. نمایش صفر منطقی تر است.
42
+ }
43
+ // 3. محدود کردن تعداد ارقام اعشار
44
+ let [integerPart, fractionalPart] = str.split('.');
45
+ integerPart = integerPart || "0"; // اگر ورودی مثل ".5" بود
46
+ if (fractionalPart !== undefined) {
47
+ if (maxDecimals > 0) {
48
+ fractionalPart = fractionalPart.slice(0, maxDecimals);
49
+ // اگر بعد از بریدن، قسمت اعشاری خالی شد، آن را حذف کن
50
+ str = fractionalPart ? `${integerPart}.${fractionalPart}` : integerPart;
51
+ }
52
+ else {
53
+ // اگر maxDecimals صفر است، قسمت اعشار را حذف کن
54
+ str = integerPart;
55
+ }
56
+ }
57
+ else {
58
+ str = integerPart; // قسمت اعشاری وجود نداشت
59
+ }
60
+ // 4. جداسازی ارقام قسمت صحیح
61
+ // دوباره استخراج بخش صحیح و اعشاری چون ممکن است در مرحله 3 تغییر کرده باشد
62
+ [integerPart, fractionalPart] = str.split('.');
63
+ integerPart = integerPart || "0"; // اطمینان مجدد برای حالت "."
64
+ const groupedInt = (0, digitUtils_1.groupDigits)(integerPart, separatorCount, separatorChar);
65
+ // 5. ترکیب مجدد قسمت صحیح و اعشاری (اگر وجود دارد)
66
+ let finalStr = fractionalPart !== undefined ? `${groupedInt}.${fractionalPart}` : groupedInt;
67
+ // 6. محلی سازی (اگر locale انگلیسی نیست)
68
+ if (locale && locale !== 'en') {
69
+ // 6.1 جایگزینی جداکننده اعشار انگلیسی با محلی (قبل از تبدیل ارقام)
70
+ finalStr = (0, digitUtils_1.localizeDecimalSeparator)(finalStr, locale);
71
+ // 6.2 تبدیل ارقام انگلیسی به محلی
72
+ finalStr = (0, digitUtils_1.toLocalizedDigits)(finalStr, locale); // cast لازم است چون locale ممکن است string باشد
73
+ }
74
+ return finalStr;
75
+ };
76
+ exports.transformNumber = transformNumber;
77
+ //# sourceMappingURL=transformNumber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformNumber.js","sourceRoot":"","sources":["../../src/utils/transformNumber.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "persian-number-input",
3
- "version": "3.1.0",
3
+ "version": "4.0.1",
4
4
  "description": "React component for Persian, Indic, or English localized number input with customizable digit grouping",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -45,5 +45,8 @@
45
45
  "jest": "^29.7.0",
46
46
  "ts-jest": "^29.3.2",
47
47
  "typescript": "^5.8.3"
48
+ },
49
+ "dependencies": {
50
+ "decimal.js": "^10.5.0"
48
51
  }
49
52
  }