"use client"; import { useEffect, useState } from "react"; /** عددِ گروه‌بندی‌شده با جداکننده‌ی هزارگان (مثلِ 12,500). */ export function fmtNum(n: number | null | undefined): string { const v = Number(n ?? 0); return Number.isFinite(v) ? v.toLocaleString("en-US") : "0"; } /** * ورودیِ عددی با جداکننده‌ی هزارگان که با کیبورد هم قابلِ تایپ است. * برخلافِ که جداکننده را نمی‌پذیرد، این یک ورودیِ متنی است * که هنگامِ تایپ زنده گروه‌بندی می‌کند و مقدارِ عددی را به onChange می‌دهد. */ export default function NumberInput({ value, onChange, allowNegative = false, className = "inp", style, disabled, }: { value: number; onChange: (n: number) => void; allowNegative?: boolean; className?: string; style?: React.CSSProperties; disabled?: boolean; }) { const show = (n: number) => n.toLocaleString("en-US"); const [text, setText] = useState(show(value)); // اگر مقدار از بیرون عوض شد (مثلاً ریست فرم)، متن را هم‌گام کن. useEffect(() => { const cur = parseInt(text.replace(/[^\d-]/g, "") || "0", 10) || 0; if (cur !== value) setText(show(value)); // eslint-disable-next-line react-hooks/exhaustive-deps }, [value]); return ( { let raw = e.target.value.replace(/[^\d-]/g, ""); if (!allowNegative) raw = raw.replace(/-/g, ""); raw = raw.replace(/(?!^)-/g, ""); // فقط منفیِ ابتدایی const n = raw === "" || raw === "-" ? 0 : parseInt(raw, 10); const grouped = raw === "" ? "" : raw === "-" ? "-" : (n || 0).toLocaleString("en-US"); setText(grouped); onChange(Number.isNaN(n) ? 0 : n); }} /> ); }