hesabixArc/hesabixUI/hesabix_ui/lib/utils/number_formatters.dart
2025-10-02 03:21:43 +03:30

62 lines
2.1 KiB
Dart

import 'package:flutter/services.dart';
String formatWithThousands(dynamic value, {int? decimalPlaces}) {
if (value == null) return '-';
num? n;
if (value is num) {
n = value;
} else if (value is String) {
n = num.tryParse(value);
}
if (n == null) return value.toString();
// Determine effective decimal digits
int effectiveDecimalDigits = decimalPlaces ?? (n is int ? 0 : 2);
if (decimalPlaces != null && decimalPlaces > 0) {
final fixed = n.toStringAsFixed(decimalPlaces);
final parts = fixed.split('.');
if (parts.length == 2) {
final fractional = parts[1];
final isAllZeros = fractional.replaceAll('0', '').isEmpty;
if (isAllZeros) {
effectiveDecimalDigits = 0;
}
}
}
final parts = n.toStringAsFixed(effectiveDecimalDigits).split('.');
final intPart = parts[0];
final decPart = parts.length > 1 ? parts[1] : null;
final reg = RegExp(r'\B(?=(\d{3})+(?!\d))');
final grouped = intPart.replaceAllMapped(reg, (m) => ',');
return decPart == null || decPart.isEmpty ? grouped : '$grouped.$decPart';
}
class ThousandsSeparatorInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
final text = newValue.text;
if (text.isEmpty) return newValue;
final selectionIndexFromTheRight = text.length - newValue.selection.end;
String cleaned = text.replaceAll(',', '');
// Keep decimal part
String integerPart = cleaned;
String decimalPart = '';
final dotIndex = cleaned.indexOf('.');
if (dotIndex >= 0) {
integerPart = cleaned.substring(0, dotIndex);
decimalPart = cleaned.substring(dotIndex); // includes '.'
}
final reg = RegExp(r'\B(?=(\d{3})+(?!\d))');
final formattedInt = integerPart.replaceAllMapped(reg, (m) => ',');
final formatted = formattedInt + decimalPart;
final newSelectionIndex = formatted.length - selectionIndexFromTheRight;
return TextEditingValue(
text: formatted,
selection: TextSelection.collapsed(offset: newSelectionIndex.clamp(0, formatted.length)),
);
}
}