persian-number-input 3.0.10 → 4.0.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.md CHANGED
@@ -4,34 +4,36 @@
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 for formatting and handling numbers in Persian, English, or other localized digit systems. Perfect for multilingual applications requiring numeric inputs with customizable formatting.
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
20
+ - Min/max value constraints for input validation
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
30
  npm install persian-number-input
28
31
  ```
29
32
 
30
- ![Size](./public/size.png)
31
33
 
32
34
  ### 💻 Usage Example
33
35
 
34
- Simple usage example:
36
+ Here’s a simple example demonstrating the component with min/max constraints and decimal support:
35
37
 
36
38
  ```jsx
37
39
  import React, { useState } from "react";
@@ -42,10 +44,17 @@ const App = () => {
42
44
 
43
45
  return (
44
46
  <PersianNumberInput
45
- initialValue="123456"
47
+ initialValue="123456.78"
46
48
  separatorCount={3}
47
- lang="fa"
48
- onChangeValue={(val) => setNumber(val)}
49
+ separatorChar=","
50
+ locale="fa"
51
+ maxDecimals={2}
52
+ min={0}
53
+ max={1000000}
54
+ showZero={true}
55
+ onValueChange={(val) => setNumber(val || "")}
56
+ placeholder="Enter a number"
57
+ className="numeric-input"
49
58
  />
50
59
  );
51
60
  };
@@ -56,82 +65,102 @@ export default App;
56
65
  ### 🔥 Output Example
57
66
 
58
67
  ```
59
- Input: 123456
60
- Displayed Output: ۱۲۳,۴۵۶
61
- English Output: 123456
68
+ Input: 123456.78
69
+ Displayed Output: ۱۲۳,۴۵۶٫۷۸
70
+ English Output: 123456.78
62
71
  ```
63
72
 
64
- ![Output Example](./public/output.png)
65
-
66
73
  ### 📚 Props Reference
67
74
 
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
- ---
75
+ | Name | Type | Default | Description |
76
+ | --- | --- | --- | --- |
77
+ | `initialValue` | \`string | number\` | `""` |
78
+ | `separatorCount` | `number` | `3` | Number of digits per group (e.g., 3 for thousands) |
79
+ | `separatorChar` | `string` | `","` | Character used for grouping digits (e.g., `,` or `.`) |
80
+ | `locale` | `string` | `"fa"` | Language for digit localization (e.g., `fa`, `en`) |
81
+ | `maxDecimals` | `number` | `0` | Maximum number of decimal places allowed |
82
+ | `showZero` | `boolean` | `false` | If `true`, displays `0` when the input is empty or zero |
83
+ | `min` | `number` | \- | Minimum allowed value (inclusive) |
84
+ | `max` | `number` | \- | Maximum allowed value (inclusive) |
85
+ | `onValueChange` | \`(value: string | undefined) =&gt; void\` | \- |
86
+ | `...rest` | `InputHTMLAttributes` | \- | Standard HTML input attributes (e.g., `className`, `placeholder`, `style`) |
87
+
88
+ ### 🌟 Why Use Persian Number Input?
89
+
90
+ - **Multilingual Support**: Seamlessly handle Persian, English, or other localized digits.
91
+ - **Customizable Formatting**: Control separators, decimals, and zero display.
92
+ - **Robust Validation**: Enforce min/max constraints for reliable inputs.
93
+ - **Developer-Friendly**: TypeScript support and a simple API for quick integration.
94
+ - **Lightweight**: Minimal bundle size for fast performance.
77
95
 
78
96
  ### ❓ FAQ (Frequently Asked Questions)
79
97
 
80
- **Does this package support React 19?**
81
- Yes, it fully supports React versions 16 through 19.
98
+ **Does this package support React 19?**\
99
+ Yes, it is fully compatible with React 16 through 19.
82
100
 
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.
101
+ **Can I use decimal numbers?**\
102
+ Yes, set `maxDecimals` to the desired number of decimal places (e.g., `maxDecimals={2}`).
85
103
 
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.
104
+ **How do I enforce minimum and maximum values?**\
105
+ Use the `min` and `max` props to restrict the input range (e.g., `min={0}` and `max={1000}`).
88
106
 
89
- ---
107
+ **How can I style the input?**\
108
+ Pass `className` or `style` props to customize the input’s appearance.
109
+
110
+ **What happens if the user enters an invalid number?**\
111
+ The component sanitizes inputs, ensuring only valid numbers are processed, and respects min/max constraints.
90
112
 
91
113
  ### 🌟 Support the Project
92
114
 
93
- If you find this package helpful, **please give it a star ⭐ on GitHub** to encourage further improvements.
115
+ If you find this package useful, **please give it a star ⭐ on GitHub** to support further development.
94
116
 
95
- 👉 **[GitHub Repository](https://github.com/javadSharifi/persian-number-input)**
117
+ 👉 **GitHub Repository**
96
118
 
97
119
  Thank you for your support! ❤️🚀
98
120
 
99
- ---
100
-
101
121
  ### 📈 SEO Keywords
102
122
 
103
- `Persian Number Input`, `React Persian input`, `localization`, `digit grouping`, `Persian digits`, `React numeric input`, `number formatter`
104
-
105
- ---
123
+ `Persian Number Input`, `React Persian input`, `React number formatting`, `localized numeric input`, `Persian digits`, `React numeric input`, `number formatter`, `TypeScript React component`, `multilingual input`
106
124
 
107
125
  ### 📄 License
108
126
 
109
- [MIT License](LICENSE)
127
+ MIT License
110
128
 
111
- © 2024 Your Name. All rights reserved.
129
+ © 2025 Javad Sharifi. All rights reserved.
112
130
 
113
- # persian-number-input
131
+ ---
114
132
 
115
- ## 🇮🇷 فارسی
133
+ ## فارسی
116
134
 
117
- کامپوننت React برای ورودی اعداد فارسی، انگلیسی و هندی با قابلیت جداکننده ارقام و محلی‌سازی کامل.
135
+ **کامپوننت ورودی اعداد فارسی** - یک کامپوننت قدرتمند React برای مدیریت و فرمت‌بندی اعداد به صورت فارسی، انگلیسی یا سایر سیستم‌های ارقام محلی. ایده‌آل برای برنامه‌های چندزبانه که نیاز به ورودی‌های عددی با فرمت سفارشی دارند.
118
136
 
119
137
  ✅ **امکانات کلیدی:**
120
138
 
121
- - پشتیبانی از اعداد فارسی، انگلیسی و هندی
122
- - قابلیت تعیین جداکننده ارقام دلخواه (هزارگان)
123
- - تبدیل خودکار اعداد محلی به اعداد انگلیسی
124
- - استفاده آسان و پشتیبانی از React نسخه‌های 16 تا 19
139
+ - پشتیبانی از ارقام فارسی، انگلیسی و سایر زبان‌ها (مانند هندی)
140
+ - قابلیت تنظیم جداکننده ارقام (مثل هزارگان)
141
+ - مدیریت اعداد اعشاری با دقت قابل تنظیم
142
+ - اعمال محدودیت‌های حداقل و حداکثر برای اعتبارسنجی
143
+ - تبدیل خودکار ارقام محلی به ارقام انگلیسی برای پردازش
144
+ - سبک و سازگار با React 16 تا 19
145
+ - پشتیبانی از TypeScript برای توسعه امن
125
146
 
126
147
  ### 🚀 نصب
127
148
 
149
+ پکیج را از طریق npm یا yarn نصب کنید:
150
+
128
151
  ```bash
129
152
  npm install persian-number-input
130
153
  ```
131
154
 
132
- ### 💻 روش استفاده
155
+ یا
133
156
 
134
- مثال ساده:
157
+ ```bash
158
+ yarn add persian-number-input
159
+ ```
160
+
161
+ ### 💻 مثال استفاده
162
+
163
+ مثالی ساده با پشتیبانی از اعشار و محدودیت‌های حداقل/حداکثر:
135
164
 
136
165
  ```jsx
137
166
  import React, { useState } from "react";
@@ -142,10 +171,17 @@ const App = () => {
142
171
 
143
172
  return (
144
173
  <PersianNumberInput
145
- initialValue="123456"
174
+ initialValue="123456.78"
146
175
  separatorCount={3}
147
- lang="fa"
148
- onChangeValue={(val) => setNumber(val)}
176
+ separatorChar=","
177
+ locale="fa"
178
+ maxDecimals={2}
179
+ min={0}
180
+ max={1000000}
181
+ showZero={true}
182
+ onValueChange={(val) => setNumber(val || "")}
183
+ placeholder="یک عدد وارد کنید"
184
+ className="numeric-input"
149
185
  />
150
186
  );
151
187
  };
@@ -156,29 +192,65 @@ export default App;
156
192
  ### 🔥 مثال خروجی
157
193
 
158
194
  ```
159
- ورودی: 123456
160
- خروجی نمایشی: ۱۲۳,۴۵۶
161
- خروجی انگلیسی: 123456
195
+ ورودی: 123456.78
196
+ خروجی نمایشی: ۱۲۳,۴۵۶٫۷۸
197
+ خروجی انگلیسی: 123456.78
162
198
  ```
163
199
 
164
- ![مثال خروجی ](./public/output.png)
200
+ ### 📚 مرجع مشخصات (Props)
165
201
 
166
- ### 📚 مشخصات Props
202
+ | نام | نوع | پیش‌فرض | توضیح |
203
+ | --- | --- | --- | --- |
204
+ | `initialValue` | \`string | number\` | `""` |
205
+ | `separatorCount` | `number` | `3` | تعداد ارقام در هر گروه (مثلاً ۳ برای هزارگان) |
206
+ | `separatorChar` | `string` | `","` | کاراکتر جداکننده گروه‌ها (مثلاً `,` یا `.`) |
207
+ | `locale` | `string` | `"fa"` | زبان برای محلی‌سازی ارقام (مثلاً `fa` یا `en`) |
208
+ | `maxDecimals` | `number` | `0` | حداکثر تعداد ارقام اعشاری مجاز |
209
+ | `showZero` | `boolean` | `false` | اگر `true` باشد، عدد `0` را در ورودی خالی یا صفر نمایش می‌دهد |
210
+ | `min` | `number` | \- | حداقل مقدار مجاز (شامل) |
211
+ | `max` | `number` | \- | حداکثر مقدار مجاز (شامل) |
212
+ | `onValueChange` | \`(value: string | undefined) =&gt; void\` | \- |
213
+ | `...rest` | `InputHTMLAttributes` | \- | ویژگی‌های استاندارد ورودی HTML (مثل `className`، `placeholder`، `style`) |
167
214
 
168
- | نام | نوع | پیشفرض | توضیح |
169
- | -------------- | ------------------------------- | ------ | -------------------------------- |
170
- | initialValue | string | "" | مقدار اولیه |
171
- | separatorCount | number | 0 | تعداد ارقام جداشده (مثلاً ۳ رقم) |
172
- | separatorChar | string | "," | کاراکتر جداکننده (مانند `,`) |
173
- | lang | 'fa' \| 'in' \| 'en' | "fa" | زبان نمایش ارقام |
174
- | onChangeValue | (englishNumber: string) => void | - | فراخوانی در تغییر مقدار |
215
+ ### 🌟 چرا از این کامپوننت استفاده کنیم؟
175
216
 
176
- ---
217
+ - **پشتیبانی چندزبانه**: مدیریت آسان ارقام فارسی، انگلیسی یا سایر زبان‌ها.
218
+ - **فرمت‌بندی انعطاف‌پذیر**: کنترل جداکننده‌ها، اعشار و نمایش صفر.
219
+ - **اعتبارسنجی قوی**: اعمال محدودیت‌های حداقل و حداکثر برای ورودی‌های مطمئن.
220
+ - **مناسب توسعه‌دهندگان**: پشتیبانی از TypeScript و API ساده برای ادغام سریع.
221
+ - **سبک و سریع**: حجم کم برای عملکرد بهینه.
222
+
223
+ ### ❓ سوالات متداول
224
+
225
+ **آیا این پکیج از React 19 پشتیبانی می‌کند؟**\
226
+ بله، کاملاً با React 16 تا 19 سازگار است.
227
+
228
+ **آیا می‌توان از اعداد اعشاری استفاده کرد؟**\
229
+ بله، با تنظیم `maxDecimals` می‌توانید تعداد ارقام اعشاری را مشخص کنید (مثلاً `maxDecimals={2}`).
230
+
231
+ **چگونه می‌توان حداقل و حداکثر مقدار را اعمال کرد؟**\
232
+ از پراپ‌های `min` و `max` استفاده کنید (مثلاً `min={0}` و `max={1000}`).
233
+
234
+ **چگونه ظاهر ورودی را سفارشی کنم؟**\
235
+ با پراپ‌های `className` یا `style` می‌توانید ظاهر ورودی را تغییر دهید.
236
+
237
+ **اگر کاربر عدد نامعتبری وارد کند چه می‌شود؟**\
238
+ کامپوننت ورودی‌ها را پاکسازی می‌کند و فقط اعداد معتبر را پردازش می‌کند، ضمن رعایت محدودیت‌های min/max.
177
239
 
178
240
  ### 🌟 حمایت از پروژه
179
241
 
180
- اگر این پکیج برای شما مفید بود، **لطفاً یک ستاره به مخزن GitHub بدهید ⭐**. این بهترین راه برای حمایت از پروژه و تشویق توسعه‌دهنده به بهبود آن است.
242
+ اگر این پکیج برای شما مفید بود، **لطفاً یک ستاره به مخزن GitHub بدهید** تا توسعه بیشتر آن را تشویق کنید.
243
+
244
+ 👉 **مخزن GitHub**
245
+
246
+ از حمایت شما سپاسگزاریم! ❤️🚀
247
+
248
+ ### 📈 کلمات کلیدی برای جستجو
249
+
250
+ `ورودی اعداد فارسی`, `کامپوننت React فارسی`, `فرمت‌بندی اعداد در React`, `ورودی عددی محلی‌سازی‌شده`, `ارقام فارسی`, `ورودی عددی React`, `فرمت‌کننده اعداد`, `کامپوننت TypeScript React`, `ورودی چندزبانه`
251
+
252
+ ### 📄 مجوز
181
253
 
182
- 👉 **[GitHub Repository](https://github.com/javadSharifi/persian-number-input)**
254
+ MIT License
183
255
 
184
- از حمایت شما متشکریم! ❤️🚀
256
+ © ۱۴۰۴ جواد شریفی. تمامی حقوق محفوظ است.
@@ -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,36 +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 PropTypes from 'prop-types'; // اضافه کردن PropTypes برای تایپ‌دهی در زمان اجرا
14
- import { toLocalizedDigits, groupDigits, convertToEnglishDigits } from '../utils/digitUtils';
15
- // استایل پایه برای input
16
- const baseInputStyle = {
17
- border: '1px solid #ccc',
18
- borderRadius: '4px',
19
- };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ const jsx_runtime_1 = require("react/jsx-runtime");
15
+ const usePersianNumberInput_1 = require("../hooks/usePersianNumberInput");
20
16
  const PersianNumberInput = (_a) => {
21
- var { initialValue = '', separatorCount = 0, separatorChar = ',', lang = 'fa', onChangeValue, style } = _a, rest = __rest(_a, ["initialValue", "separatorCount", "separatorChar", "lang", "onChangeValue", "style"]);
22
- const [value, setValue] = useState(() => convertToEnglishDigits(initialValue).replace(/\D/g, ''));
23
- const handleChange = useCallback((e) => {
24
- const input = convertToEnglishDigits(e.target.value).replace(/\D/g, '');
25
- setValue(input);
26
- if (onChangeValue)
27
- onChangeValue(input);
28
- }, [onChangeValue]);
29
- const formattedValue = groupDigits(value, separatorCount, separatorChar);
30
- const displayValue = lang === 'en' ? formattedValue : toLocalizedDigits(formattedValue, lang);
31
- const mergedStyle = Object.assign(Object.assign({}, baseInputStyle), style);
32
- return (React.createElement("input", Object.assign({ value: displayValue, onChange: handleChange, style: mergedStyle }, rest)));
33
- };
34
- // اضافه کردن PropTypes برای اطمینان از تطابق نوع
35
- PersianNumberInput.propTypes = {
36
- initialValue: PropTypes.string,
37
- separatorCount: PropTypes.number,
38
- separatorChar: PropTypes.string,
39
- lang: PropTypes.oneOf(['fa', 'in', 'en']),
40
- onChangeValue: PropTypes.func,
41
- style: PropTypes.object,
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 })));
42
45
  };
43
- export default PersianNumberInput;
46
+ exports.default = PersianNumberInput;
44
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,SAAS,MAAM,YAAY,CAAC,CAAE,kDAAkD;AACvF,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,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,MAAM,KAAK,GAAG,sBAAsB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxE,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,iDAAiD;AACjD,kBAAkB,CAAC,SAAS,GAAG;IAC3B,YAAY,EAAE,SAAS,CAAC,MAAM;IAC9B,cAAc,EAAE,SAAS,CAAC,MAAM;IAChC,aAAa,EAAE,SAAS,CAAC,MAAM;IAC/B,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACzC,aAAa,EAAE,SAAS,CAAC,IAAI;IAC7B,KAAK,EAAE,SAAS,CAAC,MAAM;CAC1B,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,41 +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
- export const toLocalizedDigits = (numStr, locale) => {
6
- const digits = digitsMap[locale];
7
- return numStr.replace(/\d/g, (digit) => digits[parseInt(digit)]);
13
+ /**
14
+ * نقشه جداکننده اعشار برای زبان‌های مختلف.
15
+ */
16
+ exports.decimalSeparatorMap = {
17
+ fa: "٫",
18
+ // en: ".", (پیش فرض نقطه است)
8
19
  };
9
- export const groupDigits = (numStr, separatorCount, separatorChar = ",") => {
10
- if (separatorCount && separatorCount > 0) {
11
- 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;
12
76
  }
13
- return numStr;
77
+ // Regex برای پیدا کردن محل درج جداکننده ها (از راست به چپ)
78
+ const regex = new RegExp(`\\B(?=(\\d{${separatorCount}})+(?!\\d))`, "g");
79
+ return numStr.replace(regex, separatorChar);
14
80
  };
15
- // بهینه‌سازی و استفاده از تابع برای تبدیل اعداد به انگلیسی
16
- export const convertToEnglishDigits = (str) => {
17
- const map = {
18
- "۰": "0",
19
- "۱": "1",
20
- "۲": "2",
21
- "۳": "3",
22
- "۴": "4",
23
- "۵": "5",
24
- "۶": "6",
25
- "۷": "7",
26
- "۸": "8",
27
- "۹": "9",
28
- "०": "0",
29
- "१": "1",
30
- "": "2",
31
- "": "3",
32
- "४": "4",
33
- "५": "5",
34
- "": "6",
35
- "": "7",
36
- "८": "8",
37
- "९": "9",
38
- };
39
- 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;
40
108
  };
109
+ exports.sanitizeNumericInput = sanitizeNumericInput;
41
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,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,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,2DAA2D;AAC3D,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.0.10",
3
+ "version": "4.0.0",
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",
@@ -47,6 +47,6 @@
47
47
  "typescript": "^5.8.3"
48
48
  },
49
49
  "dependencies": {
50
- "prop-types": "^15.8.1"
50
+ "decimal.js": "^10.5.0"
51
51
  }
52
52
  }