- Formulaire infos perso : ordre de tabulation explicite, Checkbox Material pour le consentement photo, formatage nom/prénom/ville à la perte de focus et à la soumission (name_format_utils). - Carte enfant : cadre photo, croix, ombres, consentement ; formatage prénom/nom enfant ; normalisation avant passage étape 4. - Asset photo_frame.png ; HoverReliefWidget clipBehavior. - Ajustements payload / modèle / étapes inscription liés au parcours. Made-with: Cursor
33 lines
897 B
Dart
33 lines
897 B
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(' ');
|
||
}
|
||
|
||
String _capitalizeComposedWord(String word) {
|
||
if (word.isEmpty) {
|
||
return word;
|
||
}
|
||
final lower = word.toLowerCase();
|
||
const separators = <String>{'-', "'", '’'};
|
||
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();
|
||
}
|