import React, { useEffect, useRef, useState } from 'react'; import { digitsOnly, parseUserNumber } from '../../lib/utils'; interface PriceInputProps { value: number | ''; onChange: (value: number) => void; placeholder?: string; className?: string; style?: React.CSSProperties; disabled?: boolean; min?: number; max?: number; /** نمایش ارقام لاتین با جداکنندهٔ کاما (پیش‌فرض: فارسی). */ latin?: boolean; /** واحد نمایشی داخل فیلد، مثلاً «تومان». */ suffix?: string; } function formatDisplay(num: number, latin: boolean): string { return new Intl.NumberFormat(latin ? 'en-US' : 'fa-IR').format(num); } /** مقدار prop را به متن نمایشی تبدیل می‌کند؛ صفر و خالی هر دو فیلد خالی هستند. */ function textFromValue(value: number | '', latin: boolean): string { const num = value === '' ? 0 : Number(value); return Number.isFinite(num) && num !== 0 ? formatDisplay(num, latin) : ''; } /** * ورودی مبلغ: ارقام فارسی/عربی، جداکننده و واحد چسبیده به عدد را می‌پذیرد (پیست * «۸۵,۰۰۰ تومان» ⇒ 85000) و همیشه یک عدد معتبر — هرگز NaN — به بالا می‌دهد. * * متن فیلد state مستقل است تا «۰ تایپ‌شده» از «خالی» تفکیک شود؛ محدودکردن به بازهٔ * min/max فقط روی blur اعمال می‌شود تا رقم اول تایپ به مرز نپرد. */ export default function PriceInput({ value, onChange, placeholder = '0', className, style, disabled, min = 0, max, latin = false, suffix, }: PriceInputProps) { const [text, setText] = useState(() => textFromValue(value, latin)); const textRef = useRef(text); textRef.current = text; // فقط وقتی مقدار از بیرون عوض شده باشد (reset فرم، بارگذاری داده) متن را بازنویسی کن. useEffect(() => { const shown = parseUserNumber(textRef.current) ?? 0; const incoming = value === '' ? 0 : Number(value); if (shown !== incoming) setText(textFromValue(value, latin)); }, [value, latin]); const handleChange = (e: React.ChangeEvent) => { const raw = digitsOnly(e.target.value); const num = parseUserNumber(raw) ?? 0; setText(raw === '' ? '' : formatDisplay(num, latin)); onChange(num); }; const handleBlur = () => { if (text === '') return; const num = parseUserNumber(text) ?? 0; const clamped = Math.min(max ?? Infinity, Math.max(min, num)); if (clamped !== num) { setText(formatDisplay(clamped, latin)); onChange(clamped); } }; const input = ( ); if (!suffix) return input; return ( {input} {suffix} ); }