feat(form): new utility package for forms and bloc
This commit is contained in:
parent
c5ba545a74
commit
27d60c9aa3
90
packages/wyatt_form_bloc/lib/src/cubit/form_cubit.dart
Normal file
90
packages/wyatt_form_bloc/lib/src/cubit/form_cubit.dart
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/utils/set_operations.dart';
|
||||||
|
|
||||||
|
part 'form_state.dart';
|
||||||
|
|
||||||
|
class FormCubit extends Cubit<FormState> {
|
||||||
|
final Future<bool> Function(FormState state)? _onSubmit;
|
||||||
|
|
||||||
|
FormCubit({
|
||||||
|
required FormData entries,
|
||||||
|
Future<bool> Function(FormState state)? onSubmit,
|
||||||
|
}) : _onSubmit = onSubmit,
|
||||||
|
super(FormState(data: entries));
|
||||||
|
|
||||||
|
void dataChanged<T>(String field, FormInput dirtyValue) {
|
||||||
|
final _form = state.data.clone();
|
||||||
|
|
||||||
|
if (_form.contains(field)) {
|
||||||
|
_form.update(field, dirtyValue);
|
||||||
|
} else {
|
||||||
|
throw Exception('Form field $field not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
data: _form,
|
||||||
|
status: FormValidator.validate(_form.inputs<dynamic>()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateFormData(
|
||||||
|
FormData data, {
|
||||||
|
SetOperation operation = SetOperation.replace,
|
||||||
|
}) {
|
||||||
|
FormData _form = data;
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case SetOperation.replace:
|
||||||
|
_form = data;
|
||||||
|
break;
|
||||||
|
case SetOperation.difference:
|
||||||
|
_form = state.data.difference(data);
|
||||||
|
break;
|
||||||
|
case SetOperation.intersection:
|
||||||
|
_form = state.data.intersection(data);
|
||||||
|
break;
|
||||||
|
case SetOperation.union:
|
||||||
|
_form = state.data.union(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
data: _form,
|
||||||
|
status: FormValidator.validate(_form.inputs<dynamic>()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> submitForm() async {
|
||||||
|
unawaited(
|
||||||
|
_onSubmit?.call(state).then((bool reemit) {
|
||||||
|
if (reemit) {
|
||||||
|
emit(state);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
63
packages/wyatt_form_bloc/lib/src/cubit/form_state.dart
Normal file
63
packages/wyatt_form_bloc/lib/src/cubit/form_state.dart
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
part of 'form_cubit.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class FormState {
|
||||||
|
final FormStatus status;
|
||||||
|
final FormData data;
|
||||||
|
final String? errorMessage;
|
||||||
|
|
||||||
|
const FormState({
|
||||||
|
required this.data,
|
||||||
|
this.status = FormStatus.pure,
|
||||||
|
this.errorMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
FormState copyWith({
|
||||||
|
FormStatus? status,
|
||||||
|
FormData? data,
|
||||||
|
String? errorMessage,
|
||||||
|
}) {
|
||||||
|
return FormState(
|
||||||
|
status: status ?? this.status,
|
||||||
|
data: data ?? this.data,
|
||||||
|
errorMessage: errorMessage ?? this.errorMessage,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is FormState &&
|
||||||
|
other.status == status &&
|
||||||
|
other.data == data &&
|
||||||
|
other.errorMessage == errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return status.hashCode ^ data.hashCode ^ errorMessage.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'FormState(status: $status, data: $data, '
|
||||||
|
'errorMessage: $errorMessage)';
|
||||||
|
}
|
||||||
|
}
|
22
packages/wyatt_form_bloc/lib/src/form/form.dart
Normal file
22
packages/wyatt_form_bloc/lib/src/form/form.dart
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export 'form_data.dart';
|
||||||
|
export 'form_entry.dart';
|
||||||
|
export 'form_input.dart';
|
||||||
|
export 'form_input_status.dart';
|
||||||
|
export 'form_status.dart';
|
||||||
|
export 'form_validator.dart';
|
137
packages/wyatt_form_bloc/lib/src/form/form_data.dart
Normal file
137
packages/wyatt_form_bloc/lib/src/form/form_data.dart
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/utils/list_equals.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/validators/validators.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class FormData {
|
||||||
|
const FormData(this._entries);
|
||||||
|
|
||||||
|
FormData.empty() : this(<FormEntry>[]);
|
||||||
|
|
||||||
|
final List<FormEntry> _entries;
|
||||||
|
|
||||||
|
List<FormEntry> get entries => _entries;
|
||||||
|
|
||||||
|
List<FormInput<T, ValidationError>> inputs<T>() {
|
||||||
|
return _entries
|
||||||
|
.map((FormEntry entry) => entry.input as FormInput<T, ValidationError>)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
FormInput<T, ValidationError> input<T>(String field) {
|
||||||
|
if (contains(field)) {
|
||||||
|
return _entries
|
||||||
|
.firstWhere((FormEntry entry) => entry.field == field)
|
||||||
|
.input as FormInput<T, ValidationError>;
|
||||||
|
} else {
|
||||||
|
throw Exception('Field $field does not exist in form');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(String field) {
|
||||||
|
return _entries.any((FormEntry entry) => entry.field == field);
|
||||||
|
}
|
||||||
|
|
||||||
|
FormData intersection(FormData other) {
|
||||||
|
final List<FormEntry> entries = <FormEntry>[];
|
||||||
|
|
||||||
|
for (final FormEntry entry in _entries) {
|
||||||
|
if (other.contains(entry.field)) {
|
||||||
|
entries.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FormData(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
FormData difference(FormData other) {
|
||||||
|
final List<FormEntry> entries = <FormEntry>[];
|
||||||
|
|
||||||
|
for (final FormEntry otherEntry in other._entries) {
|
||||||
|
if (!contains(otherEntry.field)) {
|
||||||
|
entries.add(otherEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final FormEntry entry in _entries) {
|
||||||
|
if (!other.contains(entry.field)) {
|
||||||
|
entries.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FormData(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
FormData union(FormData other) {
|
||||||
|
final List<FormEntry> entries = <FormEntry>[];
|
||||||
|
|
||||||
|
for (final FormEntry entry in _entries) {
|
||||||
|
entries.add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final FormEntry otherEntry in other._entries) {
|
||||||
|
if (!contains(otherEntry.field)) {
|
||||||
|
entries.add(otherEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FormData(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(String field, FormInput input) {
|
||||||
|
if (contains(field)) {
|
||||||
|
final index = _entries.indexOf(
|
||||||
|
_entries.firstWhere((FormEntry entry) => entry.field == field),
|
||||||
|
);
|
||||||
|
_entries[index] = _entries[index].copyWith(input: input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormData clone() {
|
||||||
|
return FormData(
|
||||||
|
_entries
|
||||||
|
.map((FormEntry entry) => entry.clone())
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
final map = <String, dynamic>{};
|
||||||
|
for (final entry in _entries) {
|
||||||
|
if (entry.export) {
|
||||||
|
map[entry.fieldName ?? entry.field] = entry.input.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is FormData && listEquals(other._entries, _entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => _entries.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'FormData(entries: $_entries)';
|
||||||
|
}
|
76
packages/wyatt_form_bloc/lib/src/form/form_entry.dart
Normal file
76
packages/wyatt_form_bloc/lib/src/form/form_entry.dart
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class FormEntry {
|
||||||
|
const FormEntry(this.field, this.input, {this.export = true, this.fieldName});
|
||||||
|
|
||||||
|
final String field;
|
||||||
|
final FormInput input;
|
||||||
|
final bool export;
|
||||||
|
final String? fieldName;
|
||||||
|
|
||||||
|
FormEntry copyWith({
|
||||||
|
String? field,
|
||||||
|
FormInput? input,
|
||||||
|
bool? export,
|
||||||
|
String? fieldName,
|
||||||
|
}) {
|
||||||
|
return FormEntry(
|
||||||
|
field ?? this.field,
|
||||||
|
input ?? this.input,
|
||||||
|
export: export ?? this.export,
|
||||||
|
fieldName: fieldName ?? this.fieldName,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
FormEntry clone() {
|
||||||
|
return FormEntry(
|
||||||
|
field,
|
||||||
|
input,
|
||||||
|
export: export,
|
||||||
|
fieldName: fieldName,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is FormEntry &&
|
||||||
|
other.field == field &&
|
||||||
|
other.input == input &&
|
||||||
|
other.export == export &&
|
||||||
|
other.fieldName == fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return field.hashCode ^
|
||||||
|
input.hashCode ^
|
||||||
|
export.hashCode ^
|
||||||
|
fieldName.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'FormEntry(field: $field, input: $input, '
|
||||||
|
'export: $export, fieldName: $fieldName)';
|
||||||
|
}
|
||||||
|
}
|
111
packages/wyatt_form_bloc/lib/src/form/form_input.dart
Normal file
111
packages/wyatt_form_bloc/lib/src/form/form_input.dart
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
|
||||||
|
/// {@template form_input}
|
||||||
|
/// A [FormInput] represents the value of a single form input field.
|
||||||
|
/// It contains information about the [FormInputStatus], [value], as well
|
||||||
|
/// as validation status.
|
||||||
|
///
|
||||||
|
/// [FormInput] should be extended to define custom [FormInput] instances.
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// enum FirstNameError { empty }
|
||||||
|
/// class FirstName extends FormInput<String, FirstNameError> {
|
||||||
|
/// const FirstName.pure({String value = ''}) : super.pure(value);
|
||||||
|
/// const FirstName.dirty({String value = ''}) : super.dirty(value);
|
||||||
|
///
|
||||||
|
/// @override
|
||||||
|
/// FirstNameError? validator(String value) {
|
||||||
|
/// return value.isEmpty ? FirstNameError.empty : null;
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// {@endtemplate}
|
||||||
|
@immutable
|
||||||
|
abstract class FormInput<T, E> {
|
||||||
|
const FormInput._(this.value, [this.pure = true]);
|
||||||
|
|
||||||
|
/// Constructor which create a `pure` [FormInput] with a given value.
|
||||||
|
const FormInput.pure(T value) : this._(value);
|
||||||
|
|
||||||
|
/// Constructor which create a `dirty` [FormInput] with a given value.
|
||||||
|
const FormInput.dirty(T value) : this._(value, false);
|
||||||
|
|
||||||
|
/// The value of the given [FormInput].
|
||||||
|
/// For example, if you have a `FormInput` for `FirstName`,
|
||||||
|
/// the value could be 'Joe'.
|
||||||
|
final T value;
|
||||||
|
|
||||||
|
/// If the [FormInput] is pure (has been touched/modified).
|
||||||
|
/// Typically when the `FormInput` is initially created,
|
||||||
|
/// it is created using the `FormInput.pure` constructor to
|
||||||
|
/// signify that the user has not modified it.
|
||||||
|
///
|
||||||
|
/// For subsequent changes (in response to user input), the
|
||||||
|
/// `FormInput.dirty` constructor should be used to signify that
|
||||||
|
/// the `FormInput` has been manipulated.
|
||||||
|
final bool pure;
|
||||||
|
|
||||||
|
/// The [FormInputStatus] which can be one of the following:
|
||||||
|
/// * [FormInputStatus.pure]
|
||||||
|
/// - if the input has not been modified.
|
||||||
|
/// * [FormInputStatus.invalid]
|
||||||
|
/// - if the input has been modified and validation failed.
|
||||||
|
/// * [FormInputStatus.valid]
|
||||||
|
/// - if the input has been modified and validation succeeded.
|
||||||
|
FormInputStatus get status => pure
|
||||||
|
? FormInputStatus.pure
|
||||||
|
: valid
|
||||||
|
? FormInputStatus.valid
|
||||||
|
: FormInputStatus.invalid;
|
||||||
|
|
||||||
|
/// Returns a validation error if the [FormInput] is invalid.
|
||||||
|
/// Returns `null` if the [FormInput] is valid.
|
||||||
|
E? get error => validator(value);
|
||||||
|
|
||||||
|
/// Whether the [FormInput] value is valid according to the
|
||||||
|
/// overridden `validator`.
|
||||||
|
///
|
||||||
|
/// Returns `true` if `validator` returns `null` for the
|
||||||
|
/// current [FormInput] value and `false` otherwise.
|
||||||
|
bool get valid => validator(value) == null;
|
||||||
|
|
||||||
|
/// Whether the [FormInput] value is not valid.
|
||||||
|
/// A value is invalid when the overridden `validator`
|
||||||
|
/// returns an error (non-null value).
|
||||||
|
bool get invalid => status == FormInputStatus.invalid;
|
||||||
|
|
||||||
|
/// A function that must return a validation error if the provided
|
||||||
|
/// [value] is invalid and `null` otherwise.
|
||||||
|
E? validator(T value);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => value.hashCode ^ pure.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (other.runtimeType != runtimeType) return false;
|
||||||
|
return other is FormInput<T, E> &&
|
||||||
|
other.value == value &&
|
||||||
|
other.pure == pure;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => '$runtimeType($value, $pure)';
|
||||||
|
}
|
27
packages/wyatt_form_bloc/lib/src/form/form_input_status.dart
Normal file
27
packages/wyatt_form_bloc/lib/src/form/form_input_status.dart
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/// Enum representing the status of a form input at any given point in time.
|
||||||
|
enum FormInputStatus {
|
||||||
|
/// The form input has not been touched.
|
||||||
|
pure,
|
||||||
|
|
||||||
|
/// The form input is valid.
|
||||||
|
valid,
|
||||||
|
|
||||||
|
/// The form input is not valid.
|
||||||
|
invalid,
|
||||||
|
}
|
79
packages/wyatt_form_bloc/lib/src/form/form_status.dart
Normal file
79
packages/wyatt_form_bloc/lib/src/form/form_status.dart
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/// Enum representing the status of a form at any given point in time.
|
||||||
|
enum FormStatus {
|
||||||
|
/// The form has not been touched.
|
||||||
|
pure,
|
||||||
|
|
||||||
|
/// The form has been completely validated.
|
||||||
|
valid,
|
||||||
|
|
||||||
|
/// The form contains one or more invalid inputs.
|
||||||
|
invalid,
|
||||||
|
|
||||||
|
/// The form is in the process of being submitted.
|
||||||
|
submissionInProgress,
|
||||||
|
|
||||||
|
/// The form has been submitted successfully.
|
||||||
|
submissionSuccess,
|
||||||
|
|
||||||
|
/// The form submission failed.
|
||||||
|
submissionFailure,
|
||||||
|
|
||||||
|
/// The form submission has been canceled.
|
||||||
|
submissionCanceled
|
||||||
|
}
|
||||||
|
|
||||||
|
const Set<FormStatus> _validatedFormStatuses = <FormStatus>{
|
||||||
|
FormStatus.valid,
|
||||||
|
FormStatus.submissionInProgress,
|
||||||
|
FormStatus.submissionSuccess,
|
||||||
|
FormStatus.submissionFailure,
|
||||||
|
FormStatus.submissionCanceled,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Useful extensions on [FormStatus]
|
||||||
|
extension FormStatusX on FormStatus {
|
||||||
|
/// Indicates whether the form is untouched.
|
||||||
|
bool get isPure => this == FormStatus.pure;
|
||||||
|
|
||||||
|
/// Indicates whether the form is completely validated.
|
||||||
|
bool get isValid => this == FormStatus.valid;
|
||||||
|
|
||||||
|
/// Indicates whether the form has been validated successfully.
|
||||||
|
/// This means the [FormStatus] is either:
|
||||||
|
/// * `FormStatus.valid`
|
||||||
|
/// * `FormStatus.submissionInProgress`
|
||||||
|
/// * `FormStatus.submissionSuccess`
|
||||||
|
/// * `FormStatus.submissionFailure`
|
||||||
|
bool get isValidated => _validatedFormStatuses.contains(this);
|
||||||
|
|
||||||
|
/// Indicates whether the form contains one or more invalid inputs.
|
||||||
|
bool get isInvalid => this == FormStatus.invalid;
|
||||||
|
|
||||||
|
/// Indicates whether the form is in the process of being submitted.
|
||||||
|
bool get isSubmissionInProgress => this == FormStatus.submissionInProgress;
|
||||||
|
|
||||||
|
/// Indicates whether the form has been submitted successfully.
|
||||||
|
bool get isSubmissionSuccess => this == FormStatus.submissionSuccess;
|
||||||
|
|
||||||
|
/// Indicates whether the form submission failed.
|
||||||
|
bool get isSubmissionFailure => this == FormStatus.submissionFailure;
|
||||||
|
|
||||||
|
/// Indicates whether the form submission has been canceled.
|
||||||
|
bool get isSubmissionCanceled => this == FormStatus.submissionCanceled;
|
||||||
|
}
|
30
packages/wyatt_form_bloc/lib/src/form/form_validator.dart
Normal file
30
packages/wyatt_form_bloc/lib/src/form/form_validator.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
|
||||||
|
/// Class which contains methods that help manipulate and manage
|
||||||
|
/// [FormStatus] and [FormInputStatus] instances.
|
||||||
|
class FormValidator {
|
||||||
|
/// Returns a [FormStatus] given a list of [FormInput].
|
||||||
|
static FormStatus validate(List<FormInput> inputs) {
|
||||||
|
return inputs.every((FormInput element) => element.pure)
|
||||||
|
? FormStatus.pure
|
||||||
|
: inputs.any((FormInput input) => input.valid == false)
|
||||||
|
? FormStatus.invalid
|
||||||
|
: FormStatus.valid;
|
||||||
|
}
|
||||||
|
}
|
19
packages/wyatt_form_bloc/lib/src/src.dart
Normal file
19
packages/wyatt_form_bloc/lib/src/src.dart
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export 'form/form.dart';
|
||||||
|
export 'utils/set_operations.dart';
|
||||||
|
export 'validators/validators.dart';
|
25
packages/wyatt_form_bloc/lib/src/utils/list_equals.dart
Normal file
25
packages/wyatt_form_bloc/lib/src/utils/list_equals.dart
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
bool listEquals<T>(List<T>? a, List<T>? b) {
|
||||||
|
if (a == null) return b == null;
|
||||||
|
if (b == null || a.length != b.length) return false;
|
||||||
|
if (identical(a, b)) return true;
|
||||||
|
for (int index = 0; index < a.length; index += 1) {
|
||||||
|
if (a[index] != b[index]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
17
packages/wyatt_form_bloc/lib/src/utils/set_operations.dart
Normal file
17
packages/wyatt_form_bloc/lib/src/utils/set_operations.dart
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
enum SetOperation { replace, intersection, difference, union }
|
35
packages/wyatt_form_bloc/lib/src/validators/boolean.dart
Normal file
35
packages/wyatt_form_bloc/lib/src/validators/boolean.dart
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/validators/validators.dart';
|
||||||
|
|
||||||
|
/// {@template boolean}
|
||||||
|
/// Form input for a bool input
|
||||||
|
/// {@endtemplate}
|
||||||
|
class Boolean extends FormInput<bool, ValidationError> {
|
||||||
|
/// {@macro boolean}
|
||||||
|
const Boolean.pure({bool? defaultValue = false})
|
||||||
|
: super.pure(defaultValue ?? false);
|
||||||
|
|
||||||
|
/// {@macro boolean}
|
||||||
|
const Boolean.dirty({bool value = false}) : super.dirty(value);
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValidationError? validator(bool? value) {
|
||||||
|
return value != null ? null : ValidationError.invalid;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/validators/validators.dart';
|
||||||
|
|
||||||
|
/// {@template confirmed_password}
|
||||||
|
/// Form input for a confirmed password input.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class ConfirmedPassword
|
||||||
|
extends FormInput<String, ValidationError> {
|
||||||
|
/// {@macro confirmed_password}
|
||||||
|
const ConfirmedPassword.pure({this.password = ''}) : super.pure('');
|
||||||
|
|
||||||
|
/// {@macro confirmed_password}
|
||||||
|
const ConfirmedPassword.dirty({required this.password, String value = ''})
|
||||||
|
: super.dirty(value);
|
||||||
|
|
||||||
|
/// The original password.
|
||||||
|
final String password;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValidationError? validator(String? value) {
|
||||||
|
return password == value ? null : ValidationError.invalid;
|
||||||
|
}
|
||||||
|
}
|
40
packages/wyatt_form_bloc/lib/src/validators/email.dart
Normal file
40
packages/wyatt_form_bloc/lib/src/validators/email.dart
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/validators/validators.dart';
|
||||||
|
|
||||||
|
/// {@template email}
|
||||||
|
/// Form input for an email input.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class Email extends FormInput<String, ValidationError> {
|
||||||
|
/// {@macro email}
|
||||||
|
const Email.pure() : super.pure('');
|
||||||
|
|
||||||
|
/// {@macro email}
|
||||||
|
const Email.dirty([String value = '']) : super.dirty(value);
|
||||||
|
|
||||||
|
static final RegExp _emailRegExp = RegExp(
|
||||||
|
r'^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValidationError? validator(String? value) {
|
||||||
|
return _emailRegExp.hasMatch(value ?? '')
|
||||||
|
? null
|
||||||
|
: ValidationError.invalid;
|
||||||
|
}
|
||||||
|
}
|
38
packages/wyatt_form_bloc/lib/src/validators/iban.dart
Normal file
38
packages/wyatt_form_bloc/lib/src/validators/iban.dart
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/validators/validators.dart';
|
||||||
|
|
||||||
|
/// {@template iban}
|
||||||
|
/// Form input for an IBAN input.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class Iban extends FormInput<String, ValidationError> {
|
||||||
|
/// {@macro iban}
|
||||||
|
const Iban.pure() : super.pure('');
|
||||||
|
|
||||||
|
/// {@macro iban}
|
||||||
|
const Iban.dirty([String value = '']) : super.dirty(value);
|
||||||
|
|
||||||
|
static final RegExp _regExp = RegExp(
|
||||||
|
r'^(?:((?:IT|SM)\d{2}[A-Z]{1}\d{22})|(NL\d{2}[A-Z]{4}\d{10})|(LV\d{2}[A-Z]{4}\d{13})|((?:BG|GB|IE)\d{2}[A-Z]{4}\d{14})|(GI\d{2}[A-Z]{4}\d{15})|(RO\d{2}[A-Z]{4}\d{16})|(MT\d{2}[A-Z]{4}\d{23})|(NO\d{13})|((?:DK|FI)\d{16})|((?:SI)\d{17})|((?:AT|EE|LU|LT)\d{18})|((?:HR|LI|CH)\d{19})|((?:DE|VA)\d{20})|((?:AD|CZ|ES|MD|SK|SE)\d{22})|(PT\d{23})|((?:IS)\d{24})|((?:BE)\d{14})|((?:FR|MC|GR)\d{25})|((?:PL|HU|CY)\d{26}))$',
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValidationError? validator(String? value) {
|
||||||
|
return _regExp.hasMatch(value ?? '') ? null : ValidationError.invalid;
|
||||||
|
}
|
||||||
|
}
|
36
packages/wyatt_form_bloc/lib/src/validators/name.dart
Normal file
36
packages/wyatt_form_bloc/lib/src/validators/name.dart
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/validators/validators.dart';
|
||||||
|
|
||||||
|
/// {@template name}
|
||||||
|
/// Form input for a name input.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class Name extends FormInput<String, ValidationError> {
|
||||||
|
/// {@macro name}
|
||||||
|
const Name.pure() : super.pure('');
|
||||||
|
|
||||||
|
/// {@macro name}
|
||||||
|
const Name.dirty([String value = '']) : super.dirty(value);
|
||||||
|
|
||||||
|
static final RegExp _nameRegExp = RegExp(r"^([ \u00c0-\u01ffa-zA-Z'\-])+$");
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValidationError? validator(String? value) {
|
||||||
|
return _nameRegExp.hasMatch(value ?? '') ? null : ValidationError.invalid;
|
||||||
|
}
|
||||||
|
}
|
39
packages/wyatt_form_bloc/lib/src/validators/password.dart
Normal file
39
packages/wyatt_form_bloc/lib/src/validators/password.dart
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/validators/validators.dart';
|
||||||
|
|
||||||
|
/// {@template password}
|
||||||
|
/// Form input for a password input.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class Password extends FormInput<String, ValidationError> {
|
||||||
|
/// {@macro password}
|
||||||
|
const Password.pure() : super.pure('');
|
||||||
|
|
||||||
|
/// {@macro password}
|
||||||
|
const Password.dirty([String value = '']) : super.dirty(value);
|
||||||
|
|
||||||
|
static final RegExp _passwordRegExp =
|
||||||
|
RegExp(r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$');
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValidationError? validator(String? value) {
|
||||||
|
return _passwordRegExp.hasMatch(value ?? '')
|
||||||
|
? null
|
||||||
|
: ValidationError.invalid;
|
||||||
|
}
|
||||||
|
}
|
37
packages/wyatt_form_bloc/lib/src/validators/phone.dart
Normal file
37
packages/wyatt_form_bloc/lib/src/validators/phone.dart
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/validators/validators.dart';
|
||||||
|
|
||||||
|
/// {@template phone}
|
||||||
|
/// Form input for a phone input.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class Phone extends FormInput<String, ValidationError> {
|
||||||
|
/// {@macro phone}
|
||||||
|
const Phone.pure() : super.pure('');
|
||||||
|
|
||||||
|
/// {@macro phone}
|
||||||
|
const Phone.dirty([String value = '']) : super.dirty(value);
|
||||||
|
|
||||||
|
static final RegExp _phoneRegExp =
|
||||||
|
RegExp(r'^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$');
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValidationError? validator(String? value) {
|
||||||
|
return _phoneRegExp.hasMatch(value ?? '') ? null : ValidationError.invalid;
|
||||||
|
}
|
||||||
|
}
|
36
packages/wyatt_form_bloc/lib/src/validators/siren.dart
Normal file
36
packages/wyatt_form_bloc/lib/src/validators/siren.dart
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/validators/validators.dart';
|
||||||
|
|
||||||
|
/// {@template siren}
|
||||||
|
/// Form input for a SIREN input.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class Siren extends FormInput<String, ValidationError> {
|
||||||
|
/// {@macro siren}
|
||||||
|
const Siren.pure() : super.pure('');
|
||||||
|
|
||||||
|
/// {@macro siren}
|
||||||
|
const Siren.dirty([String value = '']) : super.dirty(value);
|
||||||
|
|
||||||
|
static final RegExp _regExp = RegExp(r'(\d{9}|\d{3}[ ]\d{3}[ ]\d{3})$');
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValidationError? validator(String? value) {
|
||||||
|
return _regExp.hasMatch(value ?? '') ? null : ValidationError.invalid;
|
||||||
|
}
|
||||||
|
}
|
36
packages/wyatt_form_bloc/lib/src/validators/text_string.dart
Normal file
36
packages/wyatt_form_bloc/lib/src/validators/text_string.dart
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||||
|
import 'package:wyatt_form_bloc/src/validators/validators.dart';
|
||||||
|
|
||||||
|
/// {@template text_string}
|
||||||
|
/// Form input for a text input
|
||||||
|
/// {@endtemplate}
|
||||||
|
class TextString extends FormInput<String, ValidationError> {
|
||||||
|
/// {@macro text_string}
|
||||||
|
const TextString.pure() : super.pure('');
|
||||||
|
|
||||||
|
/// {@macro text_string}
|
||||||
|
const TextString.dirty([String value = '']) : super.dirty(value);
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValidationError? validator(String? value) {
|
||||||
|
return (value?.isNotEmpty ?? false)
|
||||||
|
? null
|
||||||
|
: ValidationError.invalid;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
enum ValidationError {
|
||||||
|
/// Generic invalid error.
|
||||||
|
invalid
|
||||||
|
}
|
26
packages/wyatt_form_bloc/lib/src/validators/validators.dart
Normal file
26
packages/wyatt_form_bloc/lib/src/validators/validators.dart
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export 'boolean.dart';
|
||||||
|
export 'confirmed_password.dart';
|
||||||
|
export 'email.dart';
|
||||||
|
export 'iban.dart';
|
||||||
|
export 'name.dart';
|
||||||
|
export 'password.dart';
|
||||||
|
export 'phone.dart';
|
||||||
|
export 'siren.dart';
|
||||||
|
export 'text_string.dart';
|
||||||
|
export 'validation_error.dart';
|
20
packages/wyatt_form_bloc/lib/wyatt_form_bloc.dart
Normal file
20
packages/wyatt_form_bloc/lib/wyatt_form_bloc.dart
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/// A form library for BLoC.
|
||||||
|
library wyatt_form_bloc;
|
||||||
|
|
||||||
|
export 'src/src.dart';
|
Loading…
x
Reference in New Issue
Block a user