persian-number-input 4.0.6 → 4.0.8
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/dist/hooks/usePersianNumberInput.d.ts +0 -6
- package/dist/hooks/usePersianNumberInput.d.ts.map +1 -1
- package/dist/hooks/usePersianNumberInput.js +75 -77
- package/dist/hooks/usePersianNumberInput.js.map +1 -1
- package/dist/utils/transformNumber.d.ts +6 -9
- package/dist/utils/transformNumber.d.ts.map +1 -1
- package/dist/utils/transformNumber.js +75 -52
- package/dist/utils/transformNumber.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,19 +5,13 @@ interface UsePersianNumberInputProps extends Omit<TransformNumberOptions, 'maxDe
|
|
|
5
5
|
onValueChange?: (value: string | undefined) => void;
|
|
6
6
|
min?: number;
|
|
7
7
|
max?: number;
|
|
8
|
-
/** حداکثر تعداد ارقام اعشار مجاز. undefined یعنی نامحدود. */
|
|
9
8
|
maxDecimals?: number;
|
|
10
|
-
/** کاراکتری که کاربر برای وارد کردن اعشار استفاده میکند (مثلا '.' یا '/') */
|
|
11
9
|
inputDecimalSeparator?: string;
|
|
12
10
|
}
|
|
13
11
|
interface UsePersianNumberInputReturn {
|
|
14
|
-
/** مقدار فرمت شده برای نمایش در input */
|
|
15
12
|
value: string;
|
|
16
|
-
/** هندلر onChange برای input */
|
|
17
13
|
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
18
|
-
/** تابعی برای تنظیم مقدار به صورت برنامهنویسی */
|
|
19
14
|
setValue: (newValue: number | string | undefined) => void;
|
|
20
|
-
/** مقدار عددی خام (رشته انگلیسی بدون جداکننده گروه) */
|
|
21
15
|
rawValue: string | undefined;
|
|
22
16
|
}
|
|
23
17
|
export declare const usePersianNumberInput: ({ initialValue, separatorCount, separatorChar, locale, showZero, onValueChange, min, max, maxDecimals, inputDecimalSeparator, }?: UsePersianNumberInputProps) => UsePersianNumberInputReturn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePersianNumberInput.d.ts","sourceRoot":"","sources":["../../src/hooks/usePersianNumberInput.ts"],"names":[],"mappings":"AACA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAEzE,OAAO,EAAmB,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"usePersianNumberInput.d.ts","sourceRoot":"","sources":["../../src/hooks/usePersianNumberInput.ts"],"names":[],"mappings":"AACA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAEzE,OAAO,EAAmB,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAMnF,UAAU,0BAA2B,SAAQ,IAAI,CAAC,sBAAsB,EAAE,aAAa,CAAC;IACtF,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;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,UAAU,2BAA2B;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC/D,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC1D,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED,eAAO,MAAM,qBAAqB,GAAI,kIAWnC,0BAA+B,KAAG,2BA0HpC,CAAC"}
|
|
@@ -6,113 +6,111 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.usePersianNumberInput = void 0;
|
|
7
7
|
// hooks/usePersianNumberInput.ts
|
|
8
8
|
const react_1 = require("react");
|
|
9
|
-
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
9
|
+
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
10
10
|
const transformNumber_1 = require("../utils/transformNumber");
|
|
11
|
-
const digitUtils_1 = require("../utils/digitUtils");
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} = {}) => {
|
|
15
|
-
|
|
11
|
+
const digitUtils_1 = require("../utils/digitUtils");
|
|
12
|
+
// ۱. تعریف سیگنال منحصر به فرد برای خطای محدوده
|
|
13
|
+
const INVALID_RANGE_SIGNAL = Symbol("INVALID_RANGE");
|
|
14
|
+
const usePersianNumberInput = ({ initialValue, separatorCount = 3, separatorChar = ',', locale = 'fa', showZero = false, onValueChange, min, max, maxDecimals, inputDecimalSeparator = '.', } = {}) => {
|
|
15
|
+
// اسم تابع برای وضوح بیشتر تغییر کرد
|
|
16
|
+
const getSanitizedRoundedAndCheckedValue = (0, react_1.useCallback)((val) => {
|
|
17
|
+
// ۲. نوع خروجی تابع تغییر کرد
|
|
16
18
|
if (val === null || val === undefined)
|
|
17
19
|
return undefined;
|
|
18
20
|
let sanitized = (0, digitUtils_1.sanitizeNumericInput)(String(val), inputDecimalSeparator);
|
|
19
|
-
// اجازه به مقادیر بینابینی
|
|
21
|
+
// اجازه عبور موقت به مقادیر بینابینی
|
|
20
22
|
if (sanitized === '-' || sanitized === '.' || sanitized === '-.') {
|
|
21
|
-
//
|
|
22
|
-
// ولی اگر صفر نباید نشان داده شود، بعدا undefined میشوند
|
|
23
|
+
// در انتها بررسی showZero برای اینها انجام میشود
|
|
23
24
|
}
|
|
24
|
-
else if (sanitized) {
|
|
25
|
+
else if (sanitized) { // اگر رشته خالی یا فقط بینابینی نیست
|
|
25
26
|
try {
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// اگر خارج از محدوده است، مقدار قبلی را برگردان یا خالی کن؟
|
|
33
|
-
// فعلا خالی برمیگردانیم تا از تنظیم مقدار نامعتبر جلوگیری شود
|
|
34
|
-
console.warn(`Value ${sanitized} is out of range [${min}, ${max}]`);
|
|
35
|
-
return undefined; // یا شاید مقدار قبلی؟ rawValue?
|
|
36
|
-
}
|
|
27
|
+
// تبدیل به Decimal فقط برای بررسی محدوده
|
|
28
|
+
const numericValue = new decimal_js_1.default(sanitized);
|
|
29
|
+
// ۳. بررسی محدوده و برگرداندن سیگنال در صورت خطا
|
|
30
|
+
if (min !== undefined && numericValue.lt(min)) {
|
|
31
|
+
console.warn(`Value ${sanitized} is less than min ${min}. Input ignored.`);
|
|
32
|
+
return INVALID_RANGE_SIGNAL; // <<< برگرداندن سیگنال
|
|
37
33
|
}
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
if (max !== undefined && numericValue.gt(max)) {
|
|
35
|
+
console.warn(`Value ${sanitized} exceeds max ${max}. Input ignored.`);
|
|
36
|
+
return INVALID_RANGE_SIGNAL; // <<< برگرداندن سیگنال
|
|
37
|
+
}
|
|
38
|
+
// اگر در محدوده بود، گرد کردن را اعمال کن
|
|
40
39
|
sanitized = (0, digitUtils_1.roundToDecimals)(sanitized, maxDecimals);
|
|
41
40
|
}
|
|
42
41
|
catch (error) {
|
|
43
|
-
console.warn(`
|
|
44
|
-
|
|
45
|
-
if (sanitized !== '-')
|
|
46
|
-
return undefined;
|
|
47
|
-
// در غیر اینصورت، خود '-' یا '.' را موقتا نگه دار
|
|
42
|
+
console.warn(`Error processing sanitized value: ${sanitized}`, error);
|
|
43
|
+
return undefined; // خطای پردازش به معنی نامعتبر بودن است
|
|
48
44
|
}
|
|
49
45
|
}
|
|
50
46
|
else {
|
|
51
|
-
// اگر
|
|
52
|
-
return undefined;
|
|
53
|
-
}
|
|
54
|
-
// مدیریت showZero
|
|
55
|
-
// توجه: parseFloat('.') یا parseFloat('-.' ) برابر NaN است
|
|
56
|
-
// parseFloat('-') برابر NaN است
|
|
57
|
-
const numericRepresentation = parseFloat(sanitized);
|
|
58
|
-
if (!showZero && numericRepresentation === 0 && sanitized !== '0.' && sanitized !== '-0.') {
|
|
59
|
-
// اگر مقدار صفر است و نباید نمایش داده شود
|
|
60
|
-
// مگر اینکه کاربر در حال تایپ اعشار صفر باشد (مثل 0.)
|
|
47
|
+
// اگر sanitizeNumericInput رشته خالی برگرداند
|
|
61
48
|
return undefined;
|
|
62
49
|
}
|
|
63
|
-
//
|
|
64
|
-
if (!showZero
|
|
65
|
-
|
|
50
|
+
// مدیریت showZero برای مقدار نهایی (بعد از بررسی محدوده و گرد کردن)
|
|
51
|
+
if (!showZero) {
|
|
52
|
+
// مقادیر بینابینی را حذف کن اگر showZero=false
|
|
53
|
+
if (sanitized === '-' || sanitized === '.' || sanitized === '-.') {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
// مقادیر صفر را حذف کن (مگر اینکه نقطه انتهایی داشته باشد)
|
|
58
|
+
if (sanitized && new decimal_js_1.default(sanitized).isZero() && !sanitized.endsWith('.')) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch ( /* نادیده گرفتن خطا */_a) { /* نادیده گرفتن خطا */ }
|
|
66
63
|
}
|
|
67
|
-
|
|
64
|
+
// در نهایت، اگر رشته خالی شده، undefined برگردان
|
|
65
|
+
return sanitized === '' ? undefined : sanitized;
|
|
68
66
|
}, [inputDecimalSeparator, min, max, maxDecimals, showZero]);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
// ۵. مدیریت سیگنال در مقدار اولیه
|
|
68
|
+
const [rawValue, setRawValue] = (0, react_1.useState)(() => {
|
|
69
|
+
const initialProcessed = getSanitizedRoundedAndCheckedValue(initialValue);
|
|
70
|
+
// اگر مقدار اولیه خارج از محدوده بود، با undefined شروع کن
|
|
71
|
+
return initialProcessed === INVALID_RANGE_SIGNAL ? undefined : initialProcessed;
|
|
72
|
+
});
|
|
73
|
+
// useEffect برای initialValue ممکن است نیاز به بازبینی داشته باشد
|
|
74
74
|
const displayValue = (0, react_1.useMemo)(() => {
|
|
75
|
-
const options = { separatorCount, separatorChar, locale, showZero, maxDecimals
|
|
76
|
-
if (rawValue === undefined || rawValue === '' || rawValue === '-') {
|
|
77
|
-
// اگر خام undefined یا خالی یا فقط منفی است
|
|
78
|
-
// transformNumber خودش showZero را هندل میکند
|
|
79
|
-
return (0, transformNumber_1.transformNumber)(rawValue, options);
|
|
80
|
-
}
|
|
81
|
-
// اگر rawValue فقط نقطه است (مثلا '.') یا '-.'
|
|
82
|
-
if (rawValue === '.' || rawValue === '-.') {
|
|
83
|
-
// نمایش مناسب بده (مثلا ۰٫ یا -۰٫)
|
|
84
|
-
const base = rawValue.startsWith('-') ? '-0' : '0';
|
|
85
|
-
// transformNumber خودش به درستی نقطه را محلی میکند
|
|
86
|
-
return (0, transformNumber_1.transformNumber)(`${base}.`, options);
|
|
87
|
-
}
|
|
75
|
+
const options = { separatorCount, separatorChar, locale, showZero, maxDecimals };
|
|
88
76
|
return (0, transformNumber_1.transformNumber)(rawValue, options);
|
|
89
77
|
}, [rawValue, separatorCount, separatorChar, locale, showZero, maxDecimals]);
|
|
78
|
+
// ۴. اصلاح handleChange برای پردازش سیگنال
|
|
90
79
|
const handleChange = (0, react_1.useCallback)((event) => {
|
|
91
80
|
const inputValue = event.target.value;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
//
|
|
95
|
-
if (
|
|
96
|
-
|
|
81
|
+
// دریافت مقدار پردازش شده یا سیگنال خطا
|
|
82
|
+
const processedValue = getSanitizedRoundedAndCheckedValue(inputValue);
|
|
83
|
+
// اگر سیگنال خطا دریافت شد، هیچ کاری نکن (مقدار قبلی حفظ میشود)
|
|
84
|
+
if (processedValue === INVALID_RANGE_SIGNAL) {
|
|
85
|
+
// اینجا میتوانید بازخورد بصری به کاربر بدهید (مثلا لرزش input)
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// اگر مقدار معتبر بود (رشته یا undefined) و با مقدار فعلی فرق داشت
|
|
89
|
+
if (processedValue !== rawValue) {
|
|
90
|
+
setRawValue(processedValue);
|
|
97
91
|
if (onValueChange) {
|
|
98
|
-
onValueChange(
|
|
92
|
+
onValueChange(processedValue);
|
|
99
93
|
}
|
|
100
94
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// مگر اینکه منطق getSanitizedAndRoundedValue تغییر کرده باشد.
|
|
105
|
-
// برای اطمینان، شاید لازم باشد state نمایش را جداگانه مدیریت کرد؟ فعلا نه.
|
|
106
|
-
}, [rawValue, getSanitizedAndRoundedValue, onValueChange]);
|
|
95
|
+
}, [rawValue, getSanitizedRoundedAndCheckedValue, onValueChange] // تابع پردازشگر به وابستگیها اضافه شد
|
|
96
|
+
);
|
|
97
|
+
// ۴. اصلاح handleSetValue برای پردازش سیگنال
|
|
107
98
|
const handleSetValue = (0, react_1.useCallback)((newValue) => {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
99
|
+
const processedValue = getSanitizedRoundedAndCheckedValue(newValue);
|
|
100
|
+
// اگر مقدار جدید خارج از محدوده است، درخواست را نادیده بگیر
|
|
101
|
+
if (processedValue === INVALID_RANGE_SIGNAL) {
|
|
102
|
+
console.warn(`setValue ignored: Value ${newValue} is out of range [${min}, ${max}].`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// اگر مقدار معتبر و متفاوت بود، تنظیم کن
|
|
106
|
+
if (processedValue !== rawValue) {
|
|
107
|
+
setRawValue(processedValue);
|
|
111
108
|
if (onValueChange) {
|
|
112
|
-
onValueChange(
|
|
109
|
+
onValueChange(processedValue);
|
|
113
110
|
}
|
|
114
111
|
}
|
|
115
|
-
}, [rawValue,
|
|
112
|
+
}, [rawValue, min, max, getSanitizedRoundedAndCheckedValue, onValueChange] // min/max هم برای پیام هشدار اضافه شد
|
|
113
|
+
);
|
|
116
114
|
return { value: displayValue, onChange: handleChange, setValue: handleSetValue, rawValue };
|
|
117
115
|
};
|
|
118
116
|
exports.usePersianNumberInput = usePersianNumberInput;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePersianNumberInput.js","sourceRoot":"","sources":["../../src/hooks/usePersianNumberInput.ts"],"names":[],"mappings":";;;;;;AAAA,iCAAiC;AACjC,iCAAyE;AACzE,4DAAiC
|
|
1
|
+
{"version":3,"file":"usePersianNumberInput.js","sourceRoot":"","sources":["../../src/hooks/usePersianNumberInput.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
export interface TransformNumberOptions {
|
|
2
|
-
/** تعداد ارقام در هر گروه برای جداسازی (مثلا 3). 0 یا کمتر یعنی بدون جداسازی. */
|
|
3
2
|
separatorCount?: number;
|
|
4
|
-
/** کاراکتر جداکننده گروه ها (پیش فرض ','). */
|
|
5
3
|
separatorChar?: string;
|
|
6
|
-
/** کد زبان برای نمایش ارقام ('fa', 'en', ...). پیش فرض 'fa'. */
|
|
7
4
|
locale?: 'fa' | 'en' | string;
|
|
8
|
-
/** حداکثر تعداد ارقام اعشار مجاز. 0 یعنی بدون اعشار. */
|
|
9
5
|
maxDecimals?: number;
|
|
10
|
-
/** اگر true باشد، حتی اگر مقدار ورودی 0 باشد، آن را نمایش بده. پیش فرض false */
|
|
11
6
|
showZero?: boolean;
|
|
12
7
|
}
|
|
13
8
|
/**
|
|
14
|
-
*
|
|
9
|
+
* رشته عددی خام (انگلیسی، با نقطه استاندارد) را به فرمت نمایشی تبدیل میکند.
|
|
10
|
+
* فرض میشود ورودی از rawValue هوک آمده و قبلا sanitize و round شده است.
|
|
15
11
|
*
|
|
16
|
-
* @param
|
|
12
|
+
* @param rawValue رشته عددی خام (مثلا "1234.5", "15.", "-0.1", "-", ".") یا undefined.
|
|
17
13
|
* @param options تنظیمات قالب بندی.
|
|
18
|
-
* @returns رشته قالب بندی شده
|
|
14
|
+
* @returns رشته قالب بندی شده برای نمایش.
|
|
19
15
|
*/
|
|
20
|
-
export declare const transformNumber: (
|
|
16
|
+
export declare const transformNumber: (rawValue: string | undefined, // تغییر ورودی به string | undefined برای وضوح
|
|
17
|
+
options?: TransformNumberOptions) => string;
|
|
21
18
|
//# sourceMappingURL=transformNumber.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformNumber.d.ts","sourceRoot":"","sources":["../../src/utils/transformNumber.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transformNumber.d.ts","sourceRoot":"","sources":["../../src/utils/transformNumber.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,GAAG,SAAS,EAAE,8CAA8C;AAC5E,UAAU,sBAAsB,KAC/B,MA8FF,CAAC"}
|
|
@@ -1,75 +1,98 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.transformNumber = void 0;
|
|
4
7
|
// utils/transformNumber.ts
|
|
5
8
|
const digitUtils_1 = require("./digitUtils");
|
|
9
|
+
const decimal_js_1 = __importDefault(require("decimal.js")); // برای بررسی دقیق صفر
|
|
6
10
|
/**
|
|
7
|
-
*
|
|
11
|
+
* رشته عددی خام (انگلیسی، با نقطه استاندارد) را به فرمت نمایشی تبدیل میکند.
|
|
12
|
+
* فرض میشود ورودی از rawValue هوک آمده و قبلا sanitize و round شده است.
|
|
8
13
|
*
|
|
9
|
-
* @param
|
|
14
|
+
* @param rawValue رشته عددی خام (مثلا "1234.5", "15.", "-0.1", "-", ".") یا undefined.
|
|
10
15
|
* @param options تنظیمات قالب بندی.
|
|
11
|
-
* @returns رشته قالب بندی شده
|
|
16
|
+
* @returns رشته قالب بندی شده برای نمایش.
|
|
12
17
|
*/
|
|
13
|
-
const transformNumber = (
|
|
14
|
-
|
|
15
|
-
separatorChar = ',', locale = 'fa', maxDecimals
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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}"`);
|
|
18
|
+
const transformNumber = (rawValue, // تغییر ورودی به string | undefined برای وضوح
|
|
19
|
+
options) => {
|
|
20
|
+
const { separatorCount = 3, separatorChar = ',', locale = 'fa', maxDecimals, // ممکن است برای نمایش لازم باشد (اگرچه round در هوک انجام شده)
|
|
21
|
+
showZero = false, } = options || {};
|
|
22
|
+
// 1. مدیریت ورودیهای null/undefined/empty
|
|
23
|
+
if (rawValue === null || rawValue === undefined || rawValue === "") {
|
|
24
|
+
// نکته: تبدیل صفر به لوکال '۰' در صورت نیاز
|
|
30
25
|
return showZero ? (0, digitUtils_1.toLocalizedDigits)("0", locale) : "";
|
|
31
26
|
}
|
|
32
|
-
//
|
|
33
|
-
if (
|
|
34
|
-
|
|
27
|
+
// 2. مدیریت حالتهای خاص که ممکن است rawValue باشند
|
|
28
|
+
if (rawValue === "-") {
|
|
29
|
+
// اگر فقط منفی است، و showZero فعال است، شاید بهتر باشد "-0" نمایش دهیم؟
|
|
30
|
+
// فعلا خود "-" را برمیگردانیم یا اگر showZero=false خالی؟ سازگاری مهم است.
|
|
31
|
+
// اجازه دهید نمایش "-" را بدهیم.
|
|
32
|
+
return "-"; // یا بر اساس showZero تصمیم بگیرید
|
|
35
33
|
}
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
if (rawValue === ".") {
|
|
35
|
+
// نمایش "۰٫" یا فقط "٫" ؟ نمایش "۰٫" خواناتر است.
|
|
36
|
+
const display = showZero ? "0." : ".";
|
|
37
|
+
const localizedDisplay = (0, digitUtils_1.localizeDecimalSeparator)(display, locale);
|
|
38
|
+
return (0, digitUtils_1.toLocalizedDigits)(localizedDisplay, locale);
|
|
38
39
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
if (rawValue === "-.") {
|
|
41
|
+
const display = showZero ? "-0." : "-.";
|
|
42
|
+
const localizedDisplay = (0, digitUtils_1.localizeDecimalSeparator)(display, locale);
|
|
43
|
+
return (0, digitUtils_1.toLocalizedDigits)(localizedDisplay, locale);
|
|
44
|
+
}
|
|
45
|
+
// 3. اطمینان از معتبر بودن فرمت (اختیاری، چون rawValue باید معتبر باشد)
|
|
46
|
+
// این regex نقطه انتهایی را هم قبول میکند
|
|
47
|
+
if (!/^-?\d*(\.\d*)?$/.test(rawValue)) {
|
|
48
|
+
console.warn(`Invalid rawValue passed to transformNumber: "${rawValue}"`);
|
|
49
|
+
return showZero ? (0, digitUtils_1.toLocalizedDigits)("0", locale) : "";
|
|
42
50
|
}
|
|
43
|
-
//
|
|
44
|
-
let
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
fractionalPart = fractionalPart.slice(0, maxDecimals);
|
|
49
|
-
// اگر بعد از بریدن، قسمت اعشاری خالی شد، آن را حذف کن
|
|
50
|
-
str = fractionalPart ? `${integerPart}.${fractionalPart}` : integerPart;
|
|
51
|
+
// 4. بررسی صفر بودن مقدار (با دقت Decimal.js)
|
|
52
|
+
let isEffectivelyZero = false;
|
|
53
|
+
try {
|
|
54
|
+
if (rawValue !== '-' && rawValue !== '.' && rawValue !== '-.') { // از Decimal با این مقادیر جلوگیری کن
|
|
55
|
+
isEffectivelyZero = new decimal_js_1.default(rawValue).isZero();
|
|
51
56
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
}
|
|
58
|
+
catch ( /* خطا در تبدیل به Decimal نادیده گرفته شود */_a) { /* خطا در تبدیل به Decimal نادیده گرفته شود */ }
|
|
59
|
+
if (isEffectivelyZero && !showZero) {
|
|
60
|
+
// اگر مقدار صفر است و نباید نمایش داده شود
|
|
61
|
+
// مگر اینکه کاربر در حال تایپ نقطه بعد از صفر باشد (مثل '0.')
|
|
62
|
+
if (!rawValue.endsWith('.')) {
|
|
63
|
+
return "";
|
|
55
64
|
}
|
|
56
65
|
}
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
// 5. جدا کردن قسمت صحیح و اعشاری
|
|
67
|
+
// rawValue باید از قبل round شده باشد، پس نیازی به roundToDecimals مجدد نیست.
|
|
68
|
+
let [integerPart, fractionalPart] = rawValue.split('.');
|
|
69
|
+
// بررسی وجود نقطه انتهایی (وقتی fractionalPart بعد از split کردن undefined است ولی نقطه در رشته بود)
|
|
70
|
+
const hasTrailingDot = rawValue.endsWith('.') && fractionalPart === undefined;
|
|
71
|
+
// رسیدگی به حالتهایی مثل ".5" که integerPart خالی است
|
|
72
|
+
if (integerPart === "" || integerPart === "-") {
|
|
73
|
+
// اگر فقط "-" بود یا خالی، با صفر جایگزین کن (اگر قرار است چیزی نمایش داده شود)
|
|
74
|
+
integerPart = rawValue.startsWith('-') ? "-0" : "0";
|
|
75
|
+
}
|
|
76
|
+
// 6. گروهبندی ارقام قسمت صحیح
|
|
77
|
+
const sign = integerPart.startsWith('-') ? '-' : '';
|
|
78
|
+
const absIntPart = integerPart.startsWith('-') ? integerPart.substring(1) : integerPart;
|
|
79
|
+
const groupedAbsInt = (0, digitUtils_1.groupDigits)(absIntPart, separatorCount, separatorChar);
|
|
80
|
+
const groupedInt = sign + groupedAbsInt;
|
|
81
|
+
// 7. بازسازی رشته نهایی (با در نظر گرفتن نقطه انتهایی)
|
|
82
|
+
let finalStr = groupedInt;
|
|
83
|
+
if (fractionalPart !== undefined) { // اگر قسمت اعشاری وجود دارد
|
|
84
|
+
finalStr = `${groupedInt}.${fractionalPart}`;
|
|
85
|
+
}
|
|
86
|
+
else if (hasTrailingDot) { // ****** این قسمت اصلاح شده ******
|
|
87
|
+
// اگر قسمت اعشاری وجود ندارد ولی رشته اصلی با نقطه تمام شده بود
|
|
88
|
+
finalStr = `${groupedInt}.`;
|
|
59
89
|
}
|
|
60
|
-
//
|
|
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 انگلیسی نیست)
|
|
90
|
+
// 8. محلی سازی (ارقام و جداکننده اعشار)
|
|
68
91
|
if (locale && locale !== 'en') {
|
|
69
|
-
//
|
|
92
|
+
// اول جداکننده نقطه را به محلی تبدیل کن
|
|
70
93
|
finalStr = (0, digitUtils_1.localizeDecimalSeparator)(finalStr, locale);
|
|
71
|
-
//
|
|
72
|
-
finalStr = (0, digitUtils_1.toLocalizedDigits)(finalStr, locale);
|
|
94
|
+
// سپس ارقام انگلیسی را به محلی تبدیل کن
|
|
95
|
+
finalStr = (0, digitUtils_1.toLocalizedDigits)(finalStr, locale);
|
|
73
96
|
}
|
|
74
97
|
return finalStr;
|
|
75
98
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformNumber.js","sourceRoot":"","sources":["../../src/utils/transformNumber.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transformNumber.js","sourceRoot":"","sources":["../../src/utils/transformNumber.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED