zeba_academy_form_rules 0.0.1
zeba_academy_form_rules: ^0.0.1 copied to clipboard
Reusable synchronous form validation rules for Dart and Flutter applications.
zeba_academy_form_rules #
A lightweight, reusable, dependency-free form validation rules package for Dart and Flutter applications.
zeba_academy_form_rules provides composable validation rules for common form requirements such as required fields, email addresses, string length, numeric values, passwords, matching fields, and custom validation logic.
β¨ Features #
- β Required field validation
- π§ Email validation
- π Minimum length validation
- π Maximum length validation
- π’ Numeric validation
- π Configurable password validation
- π Matching field validation
- π§© Custom validation rules
- π§± Composable validation rules
- β Multiple validation errors
- π¬ Custom error messages
- β‘ Synchronous validation
- πͺΆ Lightweight and dependency-free
- π― Works with Flutter
TextFormField - π§ͺ Unit-test friendly
- π¦ Simple public API
π¦ Installation #
Add the package to your pubspec.yaml:
dependencies:
zeba_academy_form_rules: ^0.0.1
Then run:
flutter pub get
Or:
dart pub add zeba_academy_form_rules
π Getting Started #
Import the package:
import 'package:zeba_academy_form_rules/zeba_academy_form_rules.dart';
Create a validation rule:
const rule = RequiredRule();
final result = rule.validate('Hello');
print(result.isValid); // true
For invalid values:
const rule = RequiredRule();
final result = rule.validate('');
print(result.isValid); // false
print(result.firstError); // This field is required.
π§© Available Rules #
RequiredRule #
Validates that a string is not null, empty, or whitespace-only.
const rule = RequiredRule();
rule.isValid('Flutter'); // true
rule.isValid(''); // false
rule.isValid(' '); // false
Custom Error Message #
const rule = RequiredRule(
message: 'Please enter your name.',
);
π§ EmailRule #
Validates email addresses.
const rule = EmailRule();
rule.isValid('user@example.com'); // true
rule.isValid('invalid-email'); // false
Custom message:
const rule = EmailRule(
message: 'Please enter a valid email.',
);
EmailRule allows empty values so it can be composed with RequiredRule.
final validator = RuleValidator<String>(
[
RequiredRule(),
EmailRule(),
],
);
π MinLengthRule #
Validates the minimum number of characters.
const rule = MinLengthRule(8);
rule.isValid('Flutter'); // false
rule.isValid('Flutter!'); // true
Custom message:
const rule = MinLengthRule(
8,
message: 'Password must contain at least 8 characters.',
);
π MaxLengthRule #
Validates the maximum number of characters.
const rule = MaxLengthRule(20);
rule.isValid('Flutter'); // true
rule.isValid('This value is too long for the field'); // false
Custom message:
const rule = MaxLengthRule(
20,
message: 'Username cannot exceed 20 characters.',
);
π’ NumericRule #
Validates that a value contains only digits.
const rule = NumericRule();
rule.isValid('123456'); // true
rule.isValid('123abc'); // false
Custom message:
const rule = NumericRule(
message: 'Please enter numbers only.',
);
π PasswordRule #
Provides configurable password validation.
By default, it checks:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
const rule = PasswordRule();
final result = rule.validate('Password@123');
print(result.isValid); // true
Weak Password #
const rule = PasswordRule();
final result = rule.validate('abc');
print(result.isValid); // false
print(result.errors);
A password can return multiple validation errors.
Custom Password Requirements #
const rule = PasswordRule(
minLength: 10,
requireUppercase: true,
requireLowercase: true,
requireDigit: true,
requireSpecialCharacter: false,
);
This allows you to adapt the rule to different application requirements.
π MatchRule #
Validates that two values are equal.
This is useful for:
- Confirm password
- Confirm email
- Repeat phone number
- Confirmation fields
Example:
const rule = MatchRule<String>(
otherValue: 'Password@123',
message: 'Passwords do not match.',
);
rule.isValid('Password@123'); // true
rule.isValid('Password@456'); // false
π§© CustomRule #
Create your own validation logic without creating a new class.
final rule = CustomRule<String>(
validator: (value) {
return value != null && value.startsWith('Zeba');
},
message: 'Value must start with Zeba.',
);
rule.isValid('Zeba Academy'); // true
rule.isValid('Flutter'); // false
This makes the package extensible without requiring changes to the package itself.
π§± Combining Multiple Rules #
Use RuleValidator when a field requires multiple rules.
For example, username validation:
final usernameValidator = RuleValidator<String>(
[
RequiredRule(
message: 'Username is required.',
),
MinLengthRule(
3,
message: 'Username must contain at least 3 characters.',
),
MaxLengthRule(
20,
message: 'Username cannot exceed 20 characters.',
),
],
);
Validate:
final result = usernameValidator.validate('ab');
print(result.isValid); // false
print(result.errors);
First Error #
If you only need the first error:
final error = usernameValidator.error('ab');
print(error);
Check Validity #
final isValid = usernameValidator.isValid('sarvesh');
print(isValid);
π Multiple Validation Errors #
RuleValidator executes all supplied rules and collects their errors.
final validator = RuleValidator<String>(
[
RequiredRule(),
MinLengthRule(8),
MaxLengthRule(20),
],
);
final result = validator.validate('abc');
print(result.errors);
This makes it possible to display all applicable validation problems instead of stopping after the first rule.
π± Flutter Integration #
The package is framework-independent in its validation logic and can be used directly with Flutter forms.
Example:
final emailValidator = RuleValidator<String>(
[
RequiredRule(
message: 'Email is required.',
),
EmailRule(
message: 'Enter a valid email address.',
),
],
);
Use it with TextFormField:
TextFormField(
validator: (value) {
return emailValidator.error(value);
},
)
This keeps validation logic separate from the widget layer.
π Complete Login Form Example #
import 'package:flutter/material.dart';
import 'package:zeba_academy_form_rules/zeba_academy_form_rules.dart';
class LoginForm extends StatelessWidget {
LoginForm({super.key});
final emailValidator = RuleValidator<String>(
[
RequiredRule(
message: 'Email is required.',
),
EmailRule(
message: 'Enter a valid email address.',
),
],
);
final passwordValidator = RuleValidator<String>(
[
RequiredRule(
message: 'Password is required.',
),
PasswordRule(),
],
);
@override
Widget build(BuildContext context) {
return Form(
child: Column(
children: [
TextFormField(
keyboardType: TextInputType.emailAddress,
validator: emailValidator.error,
),
TextFormField(
obscureText: true,
validator: passwordValidator.error,
),
],
),
);
}
}
π± Registration Form Example #
final usernameValidator = RuleValidator<String>(
[
RequiredRule(
message: 'Username is required.',
),
MinLengthRule(
3,
message: 'Username must contain at least 3 characters.',
),
MaxLengthRule(
20,
message: 'Username cannot exceed 20 characters.',
),
],
);
final emailValidator = RuleValidator<String>(
[
RequiredRule(
message: 'Email is required.',
),
EmailRule(),
],
);
final passwordValidator = RuleValidator<String>(
[
RequiredRule(
message: 'Password is required.',
),
PasswordRule(),
],
);
π Phone Number Example #
final phoneValidator = RuleValidator<String>(
[
RequiredRule(
message: 'Phone number is required.',
),
NumericRule(
message: 'Phone number must contain only digits.',
),
MinLengthRule(
10,
message: 'Phone number must contain 10 digits.',
),
MaxLengthRule(
10,
message: 'Phone number must contain 10 digits.',
),
],
);
π Confirm Password Example #
final password = passwordController.text;
final confirmPasswordValidator = RuleValidator<String>(
[
RequiredRule(
message: 'Please confirm your password.',
),
MatchRule<String>(
otherValue: password,
message: 'Passwords do not match.',
),
],
);
Then:
TextFormField(
controller: confirmPasswordController,
obscureText: true,
validator: confirmPasswordValidator.error,
)
π¨ Custom Validation Example #
You can implement application-specific rules without modifying the package.
final usernameRule = CustomRule<String>(
validator: (value) {
if (value == null) {
return false;
}
return RegExp(r'^[a-zA-Z0-9_]+$').hasMatch(value);
},
message: 'Only letters, numbers and underscores are allowed.',
);
Combine it with built-in rules:
final validator = RuleValidator<String>(
[
RequiredRule(),
MinLengthRule(3),
MaxLengthRule(20),
usernameRule,
],
);
π§ͺ Testing #
The package is designed to be easily testable.
Run the test suite:
flutter test
Run static analysis:
flutter analyze
Format the source:
dart format lib test
Check package publishing:
flutter pub publish --dry-run
π Project Structure #
zeba_academy_form_rules/
β
βββ lib/
β βββ zeba_academy_form_rules.dart
β βββ src/
β βββ custom_rule.dart
β βββ email_rule.dart
β βββ form_rule.dart
β βββ length_rules.dart
β βββ match_rule.dart
β βββ numeric_rule.dart
β βββ password_rule.dart
β βββ required_rule.dart
β βββ rule_validator.dart
β βββ validation_result.dart
β
βββ test/
β βββ form_rule_test.dart
β βββ validation_result_test.dart
β
βββ CHANGELOG.md
βββ LICENSE
βββ README.md
βββ pubspec.yaml
π― Design Goals #
zeba_academy_form_rules is designed around a few simple principles:
Simple #
Validation should be easy to understand and use.
Reusable #
Rules should work across different screens and applications.
Composable #
Multiple rules can be combined for complex validation requirements.
Dependency-Free #
The package avoids unnecessary runtime dependencies.
Testable #
Every validation rule can be tested independently.
Flutter-Friendly #
The package integrates naturally with Flutter's Form and TextFormField.
π API Overview #
| Class | Purpose |
|---|---|
FormRule<T> |
Base validation rule |
ValidationResult |
Represents validation result and errors |
RequiredRule |
Required field validation |
EmailRule |
Email validation |
MinLengthRule |
Minimum string length |
MaxLengthRule |
Maximum string length |
NumericRule |
Numeric-only validation |
PasswordRule |
Configurable password validation |
MatchRule<T> |
Matching field validation |
CustomRule<T> |
Custom validation logic |
RuleValidator<T> |
Combines multiple rules |
π‘ Why Use This Package? #
Instead of writing validation logic repeatedly:
if (email.isEmpty) {
// ...
}
if (!email.contains('@')) {
// ...
}
if (password.length < 8) {
// ...
}
You can define reusable rules:
final emailValidator = RuleValidator<String>(
[
RequiredRule(),
EmailRule(),
],
);
And reuse them throughout your application.
π€ Contributing #
Contributions are welcome!
If you find a bug, have an improvement, or want to suggest a new validation rule:
- Fork the repository.
- Create a feature branch.
- Make your changes.
- Add or update tests.
- Run
dart format lib test. - Run
flutter analyze. - Run
flutter test. - Submit a pull request.
Please keep contributions focused, documented, and tested.
π License #
This project is licensed under the GNU General Public License v3.0 (GPL-3.0).
You should include the complete GPL-3.0 license text in the project's LICENSE file.
See the official GNU GPL documentation for more information.
π¨βπ» About Me #
β¨ Iβm Sufyan bin Uzayr, an open-source developer passionate about building and sharing meaningful projects.
You can learn more about me and my work at sufyanism.com or connect with me on LinkedIn.
π Zeba Academy #
Your all-in-one learning hub! #
π Explore courses and resources in coding, tech, and development at zeba.academy and code.zeba.academy.
Empower yourself with practical skills through curated tutorials, real-world projects, and hands-on experience. Level up your tech game today! π»β¨
Zeba Academy is a learning platform dedicated to coding, technology, and development.
β‘ Visit our main site: zeba.academy
β‘ Explore hands-on courses and resources at: code.zeba.academy
β‘ Check out our YouTube for more tutorials: zeba.academy
β‘ Follow us on Instagram: zeba.academy
β Support the Project #
If zeba_academy_form_rules helps you build better Flutter applications:
- β Star the repository
- π¦ Like the package on pub.flutter-io.cn
- π Report issues
- π‘ Suggest improvements
- π€ Contribute to the project
- π’ Share it with other Flutter developers
Every contribution helps improve the project and the wider Flutter community.
Thank you for visiting and supporting Zeba Academy! π
Happy coding! π