import 'package:flutter/services.dart'; /// Formatage affichage prénom / nom (capitalisation par mot et segments après `-` ou `'`). String formatPersonNameCase(String raw) { final trimmed = raw.trim(); if (trimmed.isEmpty) { return trimmed; } final words = trimmed.split(RegExp(r'\s+')); return words.map(_capitalizeComposedWord).join(' '); } /// Variante saisie live : pas de majuscule tant que le mot n’a qu’une lettre ; /// dès la 2ᵉ lettre, capitalisation comme [formatPersonNameCase]. String formatPersonNameCaseTyping(String raw) { if (raw.isEmpty) return raw; final trailingMatch = RegExp(r'(\s*)$').firstMatch(raw); final trailing = trailingMatch?.group(1) ?? ''; final core = raw.substring(0, raw.length - trailing.length); if (core.isEmpty) return raw; final words = core.split(RegExp(r'\s+')); final formatted = words.map((w) { if (w.length < 2) return w; return _capitalizeComposedWord(w); }).join(' '); return formatted + trailing; } String _capitalizeComposedWord(String word) { if (word.isEmpty) { return word; } final lower = word.toLowerCase(); const separators = {'-', "'", '’'}; final buffer = StringBuffer(); var capitalizeNext = true; for (var i = 0; i < lower.length; i++) { final char = lower[i]; if (capitalizeNext && RegExp(r'[a-zà-öø-ÿ]').hasMatch(char)) { buffer.write(char.toUpperCase()); capitalizeNext = false; } else { buffer.write(char); capitalizeNext = separators.contains(char); } } return buffer.toString(); } /// Formateur de saisie prénom / nom (capitalisation progressive). class PersonNameInputFormatter extends TextInputFormatter { const PersonNameInputFormatter(); @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue, ) { final formatted = formatPersonNameCaseTyping(newValue.text); if (formatted == newValue.text) return newValue; final sel = newValue.selection; final offset = sel.isValid ? sel.baseOffset.clamp(0, formatted.length) : formatted.length; return TextEditingValue( text: formatted, selection: TextSelection.collapsed(offset: offset), ); } }