Skip to content

Instantly share code, notes, and snippets.

@followthemoney1
Last active November 10, 2025 16:09
Show Gist options
  • Select an option

  • Save followthemoney1/1189ddc208206598f9fb5f6ae9d06b80 to your computer and use it in GitHub Desktop.

Select an option

Save followthemoney1/1189ddc208206598f9fb5f6ae9d06b80 to your computer and use it in GitHub Desktop.
Good Flutter User Name Validation
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:recase/recase.dart';
/// Custom TextInputFormatter that converts input to title case
class TitleCaseTextInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
if (newValue.text.isEmpty || newValue.text.endsWith(' ')) {
return newValue;
}
final titleCase = newValue.text.titleCase;
return TextEditingValue(text: titleCase, selection: newValue.selection);
}
}
/// A shared stateless widget for full name text field input.
///
/// This widget enforces consistent validation and formatting across the app
/// for full name inputs. It automatically converts input to title case and
/// filters out potentially dangerous characters.
class FullNameTextField extends StatelessWidget {
const FullNameTextField({required this.controller, required this.onChanged, this.hintText = 'John Doe', super.key});
final TextEditingController controller;
final ValueChanged<String> onChanged;
final String? hintText;
@override
Widget build(BuildContext context) {
return TextField(
controller: controller,
hintText: hintText ?? context.loc.fullNamePlaceholder,
backgroundColor: const Color(0xFF000000),
borderRadius: BorderRadius.circular(BorderRadiusConstants.normal),
textStyle: context.textTheme.bodyMedium?.copyWith(color: Colors.white),
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(),
FormBuilderValidators.minLength(4, errorText: context.loc.fullNameMinLength),
]),
inputFormatters: [
// Remove any characters that are NOT valid in names
// Allows: Unicode letters (\p{L}), combining marks/diacritics (\p{M}), numbers (\p{N}),
// dots (.), apostrophes ('), hyphens (-), middle dot (·), glottal stop (ʔ), and spaces
FilteringTextInputFormatter.deny(RegExp(r"[^\p{L}\p{M}\p{N}.'ʼʔ·\- ]+", unicode: true)),
TitleCaseTextInputFormatter(),
],
maxLength: 35,
onChanged: onChanged,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment