105 lines
3.0 KiB
Dart
105 lines
3.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:fancy_password_field/fancy_password_field.dart';
|
|
|
|
import 'package:pweb/config/constants.dart';
|
|
|
|
import 'package:pweb/generated/i18n/app_localizations.dart';
|
|
|
|
|
|
class PasswordField extends StatefulWidget {
|
|
final TextEditingController controller;
|
|
final ValueChanged<bool>? onValid;
|
|
final bool hasStrengthIndicator;
|
|
final String? labelText;
|
|
final Set<ValidationRule> rules;
|
|
final AutovalidateMode? autovalidateMode;
|
|
final Widget Function(Set<ValidationRule>, String)? validationRuleBuilder;
|
|
|
|
const PasswordField({
|
|
super.key,
|
|
required this.controller,
|
|
this.onValid,
|
|
this.validationRuleBuilder,
|
|
this.labelText,
|
|
this.hasStrengthIndicator = false,
|
|
this.autovalidateMode,
|
|
this.rules = const {},
|
|
});
|
|
|
|
@override
|
|
State<PasswordField> createState() => _PasswordFieldState();
|
|
}
|
|
|
|
class _PasswordFieldState extends State<PasswordField> {
|
|
bool _lastValidationResult = false;
|
|
|
|
void _onChanged(String value) {
|
|
bool isValid = widget.rules.every((rule) => rule.validate(value));
|
|
|
|
// Only trigger onValid if validation result has changed
|
|
if (isValid != _lastValidationResult) {
|
|
_lastValidationResult = isValid;
|
|
widget.onValid?.call(isValid);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return FancyPasswordField(
|
|
key: widget.key,
|
|
controller: widget.controller,
|
|
decoration: InputDecoration(
|
|
labelText: widget.labelText ?? AppLocalizations.of(context)!.password,
|
|
),
|
|
validationRules: widget.rules,
|
|
hasStrengthIndicator: widget.hasStrengthIndicator,
|
|
validationRuleBuilder: widget.validationRuleBuilder,
|
|
autovalidateMode: widget.autovalidateMode,
|
|
onChanged: _onChanged,
|
|
);
|
|
}
|
|
}
|
|
|
|
Widget defaulRulesPasswordField(
|
|
BuildContext context, {
|
|
required TextEditingController controller,
|
|
Key? key,
|
|
ValueChanged<bool>? onValid,
|
|
Widget Function(Set<ValidationRule>, String)? validationRuleBuilder,
|
|
String? labelText,
|
|
FocusNode? focusNode,
|
|
AutovalidateMode? autovalidateMode,
|
|
bool hasStrengthIndicator = false,
|
|
Set<ValidationRule> additionalRules = const {},
|
|
}) {
|
|
Set<ValidationRule> rules = {
|
|
DigitValidationRule(
|
|
customText: AppLocalizations.of(context)!.passwordValidationRuleDigit,
|
|
),
|
|
UppercaseValidationRule(
|
|
customText: AppLocalizations.of(context)!.passwordValidationRuleUpperCase,
|
|
),
|
|
LowercaseValidationRule(
|
|
customText: AppLocalizations.of(context)!.passwordValidationRuleLowerCase,
|
|
),
|
|
MinCharactersValidationRule(
|
|
Constants.minPasswordCharacters,
|
|
customText: AppLocalizations.of(context)!
|
|
.passwordValidationRuleMinCharacters(Constants.minPasswordCharacters),
|
|
),
|
|
...additionalRules,
|
|
};
|
|
|
|
return PasswordField(
|
|
key: key,
|
|
controller: controller,
|
|
onValid: onValid,
|
|
validationRuleBuilder: validationRuleBuilder,
|
|
hasStrengthIndicator: hasStrengthIndicator,
|
|
labelText: labelText,
|
|
autovalidateMode: autovalidateMode,
|
|
rules: rules,
|
|
);
|
|
}
|