petitspas/frontend/lib/utils/phone_utils.dart
Julien Martin cde676c4f9 feat: alignement master sur develop (squash)
- Dossiers unifiés #119, pending-families enrichi, validation admin (wizards)
- Front: modèles dossier_unifie / pending_family, NIR, auth
- Migrations dossier_famille, scripts de test API
- Résolution conflits: parents.*, docs tickets, auth_service, nir_utils

Made-with: Cursor
2026-03-26 00:20:47 +01:00

58 lines
2.1 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/services.dart';
/// Format français : 10 chiffres affichés par paires (ex. 06 12 34 56 78).
/// Ne garde que les chiffres (max 10).
String normalizePhone(String raw) {
final digits = raw.replaceAll(RegExp(r'\D'), '');
return digits.length > 10 ? digits.substring(0, 10) : digits;
}
/// Retourne le numéro formaté pour l'affichage (ex. "06 12 34 56 78").
/// Si [raw] est vide après normalisation, retourne [raw] tel quel (pour afficher "" etc.).
String formatPhoneForDisplay(String raw) {
if (raw.trim().isEmpty) return raw;
final normalized = normalizePhone(raw);
if (normalized.isEmpty) return raw;
final buffer = StringBuffer();
for (var i = 0; i < normalized.length; i++) {
if (i > 0 && i.isEven) buffer.write(' ');
buffer.write(normalized[i]);
}
return buffer.toString();
}
/// Formatter de saisie : uniquement chiffres, espaces automatiques toutes les 2 chiffres, max 10 chiffres.
class FrenchPhoneNumberFormatter extends TextInputFormatter {
const FrenchPhoneNumberFormatter();
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
final digits = newValue.text.replaceAll(RegExp(r'\D'), '');
final normalized = digits.length > 10 ? digits.substring(0, 10) : digits;
final buffer = StringBuffer();
for (var i = 0; i < normalized.length; i++) {
if (i > 0 && i.isEven) buffer.write(' ');
buffer.write(normalized[i]);
}
final formatted = buffer.toString();
// Conserver la position du curseur : compter les chiffres avant la sélection
final sel = newValue.selection;
final digitsBeforeCursor = newValue.text
.substring(0, sel.start.clamp(0, newValue.text.length))
.replaceAll(RegExp(r'\D'), '')
.length;
final newOffset = digitsBeforeCursor + (digitsBeforeCursor > 0 ? digitsBeforeCursor ~/ 2 : 0);
final clampedOffset = newOffset.clamp(0, formatted.length);
return TextEditingValue(
text: formatted,
selection: TextSelection.collapsed(offset: clampedOffset),
);
}
}