Compare commits
	
		
			No commits in common. "f031b3cbf5e1dad303b493112d262254ad6d586c" and "79fdd3c83751d0507512504bfc8a3e13a8e2c750" have entirely different histories.
		
	
	
		
			f031b3cbf5
			...
			79fdd3c837
		
	
		
@ -16,16 +16,16 @@
 | 
				
			|||||||
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
-->
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Flutter - Form BLoC
 | 
					# Dart - Form BLoC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p align="left">
 | 
					<p align="left">
 | 
				
			||||||
  <a href="https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis">
 | 
					  <a href="https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis">
 | 
				
			||||||
    <img src="https://img.shields.io/badge/Style-Wyatt%20Analysis-blue.svg?style=flat-square" alt="Style: Wyatt Analysis" />
 | 
					    <img src="https://img.shields.io/badge/Style-Wyatt%20Analysis-blue.svg?style=flat-square" alt="Style: Wyatt Analysis" />
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
  <img src="https://img.shields.io/badge/SDK-Flutter-blue?style=flat-square" alt="SDK: Flutter" />
 | 
					  <img src="https://img.shields.io/badge/SDK-Dart%20%7C%20Flutter-blue?style=flat-square" alt="SDK: Dart & Flutter" />
 | 
				
			||||||
</p>
 | 
					</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Form Bloc for Flutter.
 | 
					Form Bloc for Dart & Flutter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Features
 | 
					## Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
include: package:wyatt_analysis/analysis_options.flutter.yaml
 | 
					include: package:wyatt_analysis/analysis_options.yaml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
analyzer:
 | 
					analyzer:
 | 
				
			||||||
  exclude: "!example/**"
 | 
					  exclude: "!example/**"
 | 
				
			||||||
@ -21,6 +21,6 @@
 | 
				
			|||||||
  <key>CFBundleVersion</key>
 | 
					  <key>CFBundleVersion</key>
 | 
				
			||||||
  <string>1.0</string>
 | 
					  <string>1.0</string>
 | 
				
			||||||
  <key>MinimumOSVersion</key>
 | 
					  <key>MinimumOSVersion</key>
 | 
				
			||||||
  <string>11.0</string>
 | 
					  <string>9.0</string>
 | 
				
			||||||
</dict>
 | 
					</dict>
 | 
				
			||||||
</plist>
 | 
					</plist>
 | 
				
			||||||
 | 
				
			|||||||
@ -272,7 +272,7 @@
 | 
				
			|||||||
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 | 
									GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 | 
				
			||||||
				GCC_WARN_UNUSED_FUNCTION = YES;
 | 
									GCC_WARN_UNUSED_FUNCTION = YES;
 | 
				
			||||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
									GCC_WARN_UNUSED_VARIABLE = YES;
 | 
				
			||||||
				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 | 
									IPHONEOS_DEPLOYMENT_TARGET = 9.0;
 | 
				
			||||||
				MTL_ENABLE_DEBUG_INFO = NO;
 | 
									MTL_ENABLE_DEBUG_INFO = NO;
 | 
				
			||||||
				SDKROOT = iphoneos;
 | 
									SDKROOT = iphoneos;
 | 
				
			||||||
				SUPPORTED_PLATFORMS = iphoneos;
 | 
									SUPPORTED_PLATFORMS = iphoneos;
 | 
				
			||||||
@ -349,7 +349,7 @@
 | 
				
			|||||||
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 | 
									GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 | 
				
			||||||
				GCC_WARN_UNUSED_FUNCTION = YES;
 | 
									GCC_WARN_UNUSED_FUNCTION = YES;
 | 
				
			||||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
									GCC_WARN_UNUSED_VARIABLE = YES;
 | 
				
			||||||
				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 | 
									IPHONEOS_DEPLOYMENT_TARGET = 9.0;
 | 
				
			||||||
				MTL_ENABLE_DEBUG_INFO = YES;
 | 
									MTL_ENABLE_DEBUG_INFO = YES;
 | 
				
			||||||
				ONLY_ACTIVE_ARCH = YES;
 | 
									ONLY_ACTIVE_ARCH = YES;
 | 
				
			||||||
				SDKROOT = iphoneos;
 | 
									SDKROOT = iphoneos;
 | 
				
			||||||
@ -398,7 +398,7 @@
 | 
				
			|||||||
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 | 
									GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 | 
				
			||||||
				GCC_WARN_UNUSED_FUNCTION = YES;
 | 
									GCC_WARN_UNUSED_FUNCTION = YES;
 | 
				
			||||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
									GCC_WARN_UNUSED_VARIABLE = YES;
 | 
				
			||||||
				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 | 
									IPHONEOS_DEPLOYMENT_TARGET = 9.0;
 | 
				
			||||||
				MTL_ENABLE_DEBUG_INFO = NO;
 | 
									MTL_ENABLE_DEBUG_INFO = NO;
 | 
				
			||||||
				SDKROOT = iphoneos;
 | 
									SDKROOT = iphoneos;
 | 
				
			||||||
				SUPPORTED_PLATFORMS = iphoneos;
 | 
									SUPPORTED_PLATFORMS = iphoneos;
 | 
				
			||||||
 | 
				
			|||||||
@ -43,7 +43,5 @@
 | 
				
			|||||||
	</array>
 | 
						</array>
 | 
				
			||||||
	<key>UIViewControllerBasedStatusBarAppearance</key>
 | 
						<key>UIViewControllerBasedStatusBarAppearance</key>
 | 
				
			||||||
	<false/>
 | 
						<false/>
 | 
				
			||||||
	<key>CADisableMinimumFrameDurationOnPhone</key>
 | 
					 | 
				
			||||||
	<true/>
 | 
					 | 
				
			||||||
</dict>
 | 
					</dict>
 | 
				
			||||||
</plist>
 | 
					</plist>
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ import 'package:flutter/material.dart';
 | 
				
			|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
import 'package:form_bloc_example/app/metadata.dart';
 | 
					import 'package:form_bloc_example/app/metadata.dart';
 | 
				
			||||||
import 'package:form_bloc_example/constants.dart';
 | 
					import 'package:form_bloc_example/constants.dart';
 | 
				
			||||||
import 'package:form_bloc_example/simple_custom_form_cubit/simple_custom_form_cubit.dart';
 | 
					import 'package:form_bloc_example/cubit/custom_form_cubit.dart';
 | 
				
			||||||
import 'package:form_bloc_example/sign_up/sign_up_page.dart';
 | 
					import 'package:form_bloc_example/sign_up/sign_up_page.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
					import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -29,60 +29,43 @@ class App extends StatelessWidget {
 | 
				
			|||||||
  const App({Key? key}) : super(key: key);
 | 
					  const App({Key? key}) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static List<FormInput> getNormalEntries() {
 | 
					  static List<FormInput> getNormalEntries() {
 | 
				
			||||||
    return [
 | 
					    return const [
 | 
				
			||||||
      FormInput(formFieldName, const Name.pure('Test'),
 | 
					      FormInput(formFieldName, Name.pure(), metadata: FormInputMetadata<Metadata>(extra: blue)),
 | 
				
			||||||
          metadata: const FormInputMetadata<Metadata>(extra: blue)),
 | 
					      FormInput(formFieldEmail, Email.pure(), metadata: FormInputMetadata<Metadata>(extra: blue)),
 | 
				
			||||||
      FormInput(formFieldEmail, const Email.pure(),
 | 
					      FormInput(formFieldPhone, Phone.pure(), metadata: FormInputMetadata<Metadata>(extra: red)),
 | 
				
			||||||
          metadata: const FormInputMetadata<Metadata>(extra: blue)),
 | 
					 | 
				
			||||||
      FormInput(
 | 
					      FormInput(
 | 
				
			||||||
          formFieldList, const ListOption<String>.pure(choices: ['c1', 'c2', 'c3'],defaultValue: 'c3')),
 | 
					          formFieldList, ListOption<String>.pure(defaultValue: ['checkbox3'])),
 | 
				
			||||||
      FormInput(formFieldRadio, const TextString.pure()),
 | 
					      FormInput(formFieldRadio, TextString.pure()),
 | 
				
			||||||
      FormInput(formFieldPro, const Boolean.pure(),
 | 
					      FormInput(formFieldPro, Boolean.pure(),
 | 
				
			||||||
          metadata: const FormInputMetadata<Metadata>(name: 'business')),
 | 
					          metadata: FormInputMetadata<Metadata>(name: 'business')),
 | 
				
			||||||
      FormInput(formFieldHidden, const Boolean.pure(),
 | 
					      FormInput(formFieldHidden, Boolean.pure(),
 | 
				
			||||||
          metadata:
 | 
					          metadata: FormInputMetadata<Metadata>(export: false, extra: blue)),
 | 
				
			||||||
              const FormInputMetadata<Metadata>(export: false, extra: blue)),
 | 
					 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static List<FormInput> getBusinessEntries() {
 | 
					  static List<FormInput> getBusinessEntries() {
 | 
				
			||||||
    final entries = [
 | 
					    const entries = [
 | 
				
			||||||
      FormInput(formFieldPhone, const Phone.pure(),
 | 
					      FormInput(formFieldSiren, Siren.pure()),
 | 
				
			||||||
          metadata: const FormInputMetadata<Metadata>(extra: red)),
 | 
					      FormInput(formFieldIban, Iban.pure()),
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
    return getNormalEntries() + entries;
 | 
					    return getNormalEntries() + entries;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static WyattForm getNormalFormData() {
 | 
					  static FormData getNormalFormData() {
 | 
				
			||||||
    return WyattFormImpl(getNormalEntries(), name: formSignUp);
 | 
					    return FormData(getNormalEntries());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static WyattForm getProFormData() {
 | 
					  static FormData getProFormData() {
 | 
				
			||||||
    return WyattFormImpl(getBusinessEntries(), name: formSignUp);
 | 
					    return FormData(getBusinessEntries());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    FormRepository formRepository = FormRepositoryImpl()
 | 
					    FormDataCubit formCubit = CustomFormCubit(inputs: getNormalFormData());
 | 
				
			||||||
      ..registerForm(getNormalFormData());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // FormRepository formRepository = FormRepositoryImpl()
 | 
					    return BlocProvider(
 | 
				
			||||||
    //   ..registerForm(WyattFormImpl([
 | 
					      create: (context) => formCubit,
 | 
				
			||||||
    //     FormInput(formFieldName, const Name.pure('Test'),
 | 
					      child: const WidgetTree(),
 | 
				
			||||||
    //         metadata: const FormInputMetadata<Metadata>(extra: blue)),
 | 
					 | 
				
			||||||
    //   ], name: formSignUp));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SimpleCustomFormCubit formCubit = SimpleCustomFormCubit(
 | 
					 | 
				
			||||||
      formRepository,
 | 
					 | 
				
			||||||
      formSignUp,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return RepositoryProvider<FormRepository>.value(
 | 
					 | 
				
			||||||
      value: formRepository,
 | 
					 | 
				
			||||||
      child: BlocProvider<SimpleCustomFormCubit>(
 | 
					 | 
				
			||||||
        create: (context) => formCubit,
 | 
					 | 
				
			||||||
        child: const WidgetTree(),
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -28,5 +28,7 @@ class Metadata {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  String toString() => 'Metadata(category: $category)';
 | 
					  String toString() {
 | 
				
			||||||
 | 
					    return category.toString();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -14,11 +14,11 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const String formSignUp = 'signUp';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const String formFieldName = 'name';
 | 
					const String formFieldName = 'name';
 | 
				
			||||||
const String formFieldPhone = 'phone';
 | 
					const String formFieldPhone = 'phone';
 | 
				
			||||||
const String formFieldEmail = 'email';
 | 
					const String formFieldEmail = 'email';
 | 
				
			||||||
 | 
					const String formFieldSiren = 'siren';
 | 
				
			||||||
 | 
					const String formFieldIban = 'iban';
 | 
				
			||||||
const String formFieldList = 'list';
 | 
					const String formFieldList = 'list';
 | 
				
			||||||
const String formFieldRadio = 'radio';
 | 
					const String formFieldRadio = 'radio';
 | 
				
			||||||
const String formFieldHidden = 'hidden';
 | 
					const String formFieldHidden = 'hidden';
 | 
				
			||||||
 | 
				
			|||||||
@ -18,13 +18,12 @@ import 'dart:developer';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
					import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SimpleCustomFormCubit extends FormDataCubitImpl {
 | 
					class CustomFormCubit extends FormDataCubit {
 | 
				
			||||||
  SimpleCustomFormCubit(super._formRepository, super._formName) : super();
 | 
					  CustomFormCubit({required FormData inputs}) : super(inputs: inputs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Future<void> submit() {
 | 
					  Future<void> submitForm() {
 | 
				
			||||||
    final value = FormJsonEncoder().encode(state.form);
 | 
					    log(state.data.toMap().toString());
 | 
				
			||||||
    log(value);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Future.value();
 | 
					    return Future.value();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -14,34 +14,39 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'dart:developer';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
import 'package:form_bloc_example/app/app.dart';
 | 
					import 'package:form_bloc_example/app/app.dart';
 | 
				
			||||||
import 'package:form_bloc_example/app/metadata.dart';
 | 
					import 'package:form_bloc_example/app/metadata.dart';
 | 
				
			||||||
import 'package:form_bloc_example/constants.dart';
 | 
					import 'package:form_bloc_example/constants.dart';
 | 
				
			||||||
import 'package:form_bloc_example/simple_custom_form_cubit/simple_custom_form_cubit.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
					import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Color computeColor(Metadata? meta) {
 | 
					class CategoryIndicator extends StatelessWidget {
 | 
				
			||||||
  switch (meta?.category) {
 | 
					  const CategoryIndicator(
 | 
				
			||||||
    case Category.perso:
 | 
					      {Key? key, required this.field, required this.builder})
 | 
				
			||||||
      return Colors.blue;
 | 
					      : super(key: key);
 | 
				
			||||||
    case Category.business:
 | 
					
 | 
				
			||||||
      return Colors.red;
 | 
					  final String field;
 | 
				
			||||||
    case null:
 | 
					  final Function(BuildContext context, FormDataState state) builder;
 | 
				
			||||||
      return Colors.green;
 | 
					
 | 
				
			||||||
  }
 | 
					  Color computeColor(Metadata meta) {
 | 
				
			||||||
}
 | 
					    switch (meta.category) {
 | 
				
			||||||
 | 
					      case Category.perso:
 | 
				
			||||||
 | 
					        return Colors.blue;
 | 
				
			||||||
 | 
					      case Category.business:
 | 
				
			||||||
 | 
					        return Colors.red;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _NameInput extends StatelessWidget {
 | 
					 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return InputBuilderTextController<SimpleCustomFormCubit, String?, Metadata>(
 | 
					    return BlocBuilder<FormDataCubit, FormDataState>(
 | 
				
			||||||
      field: formFieldName,
 | 
					      builder: ((context, state) {
 | 
				
			||||||
      builder:
 | 
					        final meta = state.data.metadataOf(field).extra as Metadata;
 | 
				
			||||||
          (context, cubit, state, field, inputValid, controller, metadata) {
 | 
					 | 
				
			||||||
        final meta = state.form.metadataOf<Metadata>(field).extra;
 | 
					 | 
				
			||||||
        final color = computeColor(meta);
 | 
					        final color = computeColor(meta);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return Row(
 | 
					        return Row(
 | 
				
			||||||
          children: [
 | 
					          children: [
 | 
				
			||||||
            Container(
 | 
					            Container(
 | 
				
			||||||
@ -52,25 +57,58 @@ class _NameInput extends StatelessWidget {
 | 
				
			|||||||
                borderRadius: BorderRadius.circular(8),
 | 
					                borderRadius: BorderRadius.circular(8),
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            const SizedBox(
 | 
					            const SizedBox(width: 20,),
 | 
				
			||||||
              width: 20,
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            SizedBox(
 | 
					            SizedBox(
 | 
				
			||||||
              width: MediaQuery.of(context).size.width - 45,
 | 
					              width: MediaQuery.of(context).size.width - 45,
 | 
				
			||||||
              child: TextField(
 | 
					              child: builder(context, state),
 | 
				
			||||||
                controller: controller,
 | 
					 | 
				
			||||||
                onChanged: (value) =>
 | 
					 | 
				
			||||||
                    cubit.dataChanged(field, Name.dirty(value)),
 | 
					 | 
				
			||||||
                keyboardType: TextInputType.name,
 | 
					 | 
				
			||||||
                decoration: InputDecoration(
 | 
					 | 
				
			||||||
                  labelText: 'name',
 | 
					 | 
				
			||||||
                  helperText: '',
 | 
					 | 
				
			||||||
                  errorText: !inputValid ? 'invalid name' : null,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _NameInput extends StatelessWidget {
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return CategoryIndicator(
 | 
				
			||||||
 | 
					        field: formFieldName,
 | 
				
			||||||
 | 
					        builder: (context, state) {
 | 
				
			||||||
 | 
					          return TextField(
 | 
				
			||||||
 | 
					            onChanged: (name) => context
 | 
				
			||||||
 | 
					                .read<FormDataCubit>()
 | 
				
			||||||
 | 
					                .dataChanged(formFieldName, Name.dirty(name)),
 | 
				
			||||||
 | 
					            keyboardType: TextInputType.name,
 | 
				
			||||||
 | 
					            decoration: InputDecoration(
 | 
				
			||||||
 | 
					              labelText: 'name',
 | 
				
			||||||
 | 
					              helperText: '',
 | 
				
			||||||
 | 
					              errorText:
 | 
				
			||||||
 | 
					                  state.data.isNotValid(formFieldName) ? 'invalid name' : null,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _EmailInput extends StatelessWidget {
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return CategoryIndicator(
 | 
				
			||||||
 | 
					        field: formFieldEmail,
 | 
				
			||||||
 | 
					      builder: (context, state) {
 | 
				
			||||||
 | 
					        return TextField(
 | 
				
			||||||
 | 
					          onChanged: (email) => context
 | 
				
			||||||
 | 
					              .read<FormDataCubit>()
 | 
				
			||||||
 | 
					              .dataChanged(formFieldEmail, Email.dirty(email)),
 | 
				
			||||||
 | 
					          keyboardType: TextInputType.emailAddress,
 | 
				
			||||||
 | 
					          decoration: InputDecoration(
 | 
				
			||||||
 | 
					            labelText: 'email',
 | 
				
			||||||
 | 
					            helperText: '',
 | 
				
			||||||
 | 
					            errorText:
 | 
				
			||||||
 | 
					                state.data.isNotValid(formFieldEmail) ? 'invalid email' : null,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -79,58 +117,67 @@ class _NameInput extends StatelessWidget {
 | 
				
			|||||||
class _PhoneInput extends StatelessWidget {
 | 
					class _PhoneInput extends StatelessWidget {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return InputBuilderMetadata<SimpleCustomFormCubit, Metadata>(
 | 
					    return CategoryIndicator(
 | 
				
			||||||
      field: formFieldPhone,
 | 
					        field: formFieldPhone,
 | 
				
			||||||
      builder: (context, cubit, state, field, inputValid, metadata) {
 | 
					      builder: (context, state) {
 | 
				
			||||||
        final meta = state.form.metadataOf<Metadata>(field).extra;
 | 
					        return TextField(
 | 
				
			||||||
        final color = computeColor(meta);
 | 
					          onChanged: (phone) => context
 | 
				
			||||||
        return Row(
 | 
					              .read<FormDataCubit>()
 | 
				
			||||||
          children: [
 | 
					              .dataChanged(formFieldPhone, Phone.dirty(phone)),
 | 
				
			||||||
            Container(
 | 
					          keyboardType: TextInputType.phone,
 | 
				
			||||||
              height: 8,
 | 
					          decoration: InputDecoration(
 | 
				
			||||||
              width: 8,
 | 
					            labelText: 'phone',
 | 
				
			||||||
              decoration: BoxDecoration(
 | 
					            helperText: '',
 | 
				
			||||||
                color: color,
 | 
					            errorText:
 | 
				
			||||||
                borderRadius: BorderRadius.circular(8),
 | 
					                state.data.isNotValid(formFieldPhone) ? 'invalid phone' : null,
 | 
				
			||||||
              ),
 | 
					          ),
 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            const SizedBox(
 | 
					 | 
				
			||||||
              width: 20,
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            SizedBox(
 | 
					 | 
				
			||||||
              width: MediaQuery.of(context).size.width - 45,
 | 
					 | 
				
			||||||
              child: TextField(
 | 
					 | 
				
			||||||
                onChanged: (value) =>
 | 
					 | 
				
			||||||
                    cubit.dataChanged(field, Phone.dirty(value)),
 | 
					 | 
				
			||||||
                keyboardType: TextInputType.phone,
 | 
					 | 
				
			||||||
                decoration: InputDecoration(
 | 
					 | 
				
			||||||
                  labelText: 'phone',
 | 
					 | 
				
			||||||
                  helperText: '',
 | 
					 | 
				
			||||||
                  errorText: !inputValid ? 'invalid phone' : null,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
          ],
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _EmailInput extends StatelessWidget {
 | 
					class _SirenInput extends StatelessWidget {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return InputBuilder<SimpleCustomFormCubit>(
 | 
					    return CategoryIndicator(
 | 
				
			||||||
      field: formFieldEmail,
 | 
					        field: formFieldName,
 | 
				
			||||||
      builder: (context, cubit, state, field, inputValid) => TextField(
 | 
					      builder: (context, state) {
 | 
				
			||||||
        onChanged: (value) => cubit.dataChanged(field, Email.dirty(value)),
 | 
					        return TextField(
 | 
				
			||||||
        keyboardType: TextInputType.emailAddress,
 | 
					          onChanged: (siren) => context
 | 
				
			||||||
        decoration: InputDecoration(
 | 
					              .read<FormDataCubit>()
 | 
				
			||||||
          labelText: 'email',
 | 
					              .dataChanged(formFieldSiren, Siren.dirty(siren)),
 | 
				
			||||||
          helperText: '',
 | 
					          keyboardType: TextInputType.number,
 | 
				
			||||||
          errorText: !inputValid ? 'invalid email' : null,
 | 
					          decoration: InputDecoration(
 | 
				
			||||||
        ),
 | 
					            labelText: 'siren',
 | 
				
			||||||
      ),
 | 
					            helperText: '',
 | 
				
			||||||
 | 
					            errorText:
 | 
				
			||||||
 | 
					                state.data.isNotValid(formFieldSiren) ? 'invalid SIREN' : null,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _IbanInput extends StatelessWidget {
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return BlocBuilder<FormDataCubit, FormDataState>(
 | 
				
			||||||
 | 
					      builder: (context, state) {
 | 
				
			||||||
 | 
					        return TextField(
 | 
				
			||||||
 | 
					          onChanged: (iban) => context
 | 
				
			||||||
 | 
					              .read<FormDataCubit>()
 | 
				
			||||||
 | 
					              .dataChanged(formFieldIban, Iban.dirty(iban)),
 | 
				
			||||||
 | 
					          keyboardType: TextInputType.text,
 | 
				
			||||||
 | 
					          decoration: InputDecoration(
 | 
				
			||||||
 | 
					            labelText: 'iban',
 | 
				
			||||||
 | 
					            helperText: '',
 | 
				
			||||||
 | 
					            errorText:
 | 
				
			||||||
 | 
					                state.data.isNotValid(formFieldIban) ? 'invalid IBAN' : null,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -138,11 +185,11 @@ class _EmailInput extends StatelessWidget {
 | 
				
			|||||||
class _CheckListInput extends StatelessWidget {
 | 
					class _CheckListInput extends StatelessWidget {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return InputBuilder<SimpleCustomFormCubit>(
 | 
					    return BlocBuilder<FormDataCubit, FormDataState>(
 | 
				
			||||||
      field: formFieldList,
 | 
					      builder: (context, state) {
 | 
				
			||||||
      builder: (context, cubit, state, field, inputValid) {
 | 
					        final input =
 | 
				
			||||||
        final input = state.form.validatorOf<ListOption<String>>(field);
 | 
					            state.data.validatorOf<ListOption<String>>(formFieldList);
 | 
				
			||||||
        final choices = ['c1', 'c2', 'c3'];
 | 
					        final options = input.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return Column(
 | 
					        return Column(
 | 
				
			||||||
          mainAxisSize: MainAxisSize.min,
 | 
					          mainAxisSize: MainAxisSize.min,
 | 
				
			||||||
@ -150,34 +197,34 @@ class _CheckListInput extends StatelessWidget {
 | 
				
			|||||||
            ListTile(
 | 
					            ListTile(
 | 
				
			||||||
              title: const Text('Checkbox1'),
 | 
					              title: const Text('Checkbox1'),
 | 
				
			||||||
              trailing: Checkbox(
 | 
					              trailing: Checkbox(
 | 
				
			||||||
                  value: input.value == choices[0],
 | 
					                  value: options.contains('checkbox1'),
 | 
				
			||||||
                  onChanged: (_) {
 | 
					                  onChanged: (_) {
 | 
				
			||||||
                    cubit.dataChanged(
 | 
					                    context.read<FormDataCubit>().dataChanged(
 | 
				
			||||||
                      field,
 | 
					                          formFieldList,
 | 
				
			||||||
                      ListOption.dirty(choices: choices, value: choices[0]),
 | 
					                          input.select('checkbox1'),
 | 
				
			||||||
                    );
 | 
					                        );
 | 
				
			||||||
                  }),
 | 
					                  }),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            ListTile(
 | 
					            ListTile(
 | 
				
			||||||
              title: const Text('Checkbox2'),
 | 
					              title: const Text('Checkbox2'),
 | 
				
			||||||
              trailing: Checkbox(
 | 
					              trailing: Checkbox(
 | 
				
			||||||
                  value: input.value == choices[1],
 | 
					                  value: options.contains('checkbox2'),
 | 
				
			||||||
                  onChanged: (_) {
 | 
					                  onChanged: (_) {
 | 
				
			||||||
                    cubit.dataChanged(
 | 
					                    context.read<FormDataCubit>().dataChanged(
 | 
				
			||||||
                      field,
 | 
					                          formFieldList,
 | 
				
			||||||
                      ListOption.dirty(choices: choices, value: choices[1]),
 | 
					                          input.select('checkbox2'),
 | 
				
			||||||
                    );
 | 
					                        );
 | 
				
			||||||
                  }),
 | 
					                  }),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            ListTile(
 | 
					            ListTile(
 | 
				
			||||||
              title: const Text('Checkbox3 (default)'),
 | 
					              title: const Text('Checkbox3 (default)'),
 | 
				
			||||||
              trailing: Checkbox(
 | 
					              trailing: Checkbox(
 | 
				
			||||||
                  value: input.value == choices[2],
 | 
					                  value: options.contains('checkbox3'),
 | 
				
			||||||
                  onChanged: (_) {
 | 
					                  onChanged: (_) {
 | 
				
			||||||
                    cubit.dataChanged(
 | 
					                    context.read<FormDataCubit>().dataChanged(
 | 
				
			||||||
                      field,
 | 
					                          formFieldList,
 | 
				
			||||||
                      ListOption.dirty(choices: choices, value: choices[2]),
 | 
					                          input.select('checkbox3'),
 | 
				
			||||||
                    );
 | 
					                        );
 | 
				
			||||||
                  }),
 | 
					                  }),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
@ -190,10 +237,9 @@ class _CheckListInput extends StatelessWidget {
 | 
				
			|||||||
class _RadioListInput extends StatelessWidget {
 | 
					class _RadioListInput extends StatelessWidget {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return InputBuilder<SimpleCustomFormCubit>(
 | 
					    return BlocBuilder<FormDataCubit, FormDataState>(
 | 
				
			||||||
      field: formFieldRadio,
 | 
					      builder: (context, state) {
 | 
				
			||||||
      builder: ((context, cubit, state, field, inputValid) {
 | 
					        final input = state.data.validatorOf<TextString>(formFieldRadio);
 | 
				
			||||||
        final input = state.form.validatorOf<TextString>(field);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return Column(
 | 
					        return Column(
 | 
				
			||||||
          mainAxisSize: MainAxisSize.min,
 | 
					          mainAxisSize: MainAxisSize.min,
 | 
				
			||||||
@ -204,10 +250,10 @@ class _RadioListInput extends StatelessWidget {
 | 
				
			|||||||
                  groupValue: true,
 | 
					                  groupValue: true,
 | 
				
			||||||
                  value: input.value == 'radio1',
 | 
					                  value: input.value == 'radio1',
 | 
				
			||||||
                  onChanged: (_) {
 | 
					                  onChanged: (_) {
 | 
				
			||||||
                    cubit.dataChanged(
 | 
					                    context.read<FormDataCubit>().dataChanged(
 | 
				
			||||||
                      field,
 | 
					                          formFieldRadio,
 | 
				
			||||||
                      const TextString.dirty('radio1'),
 | 
					                          const TextString.dirty('radio1'),
 | 
				
			||||||
                    );
 | 
					                        );
 | 
				
			||||||
                  }),
 | 
					                  }),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            ListTile(
 | 
					            ListTile(
 | 
				
			||||||
@ -216,10 +262,10 @@ class _RadioListInput extends StatelessWidget {
 | 
				
			|||||||
                  groupValue: true,
 | 
					                  groupValue: true,
 | 
				
			||||||
                  value: input.value == 'radio2',
 | 
					                  value: input.value == 'radio2',
 | 
				
			||||||
                  onChanged: (_) {
 | 
					                  onChanged: (_) {
 | 
				
			||||||
                    cubit.dataChanged(
 | 
					                    context.read<FormDataCubit>().dataChanged(
 | 
				
			||||||
                      field,
 | 
					                          formFieldRadio,
 | 
				
			||||||
                      const TextString.dirty('radio2'),
 | 
					                          const TextString.dirty('radio2'),
 | 
				
			||||||
                    );
 | 
					                        );
 | 
				
			||||||
                  }),
 | 
					                  }),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            ListTile(
 | 
					            ListTile(
 | 
				
			||||||
@ -228,15 +274,15 @@ class _RadioListInput extends StatelessWidget {
 | 
				
			|||||||
                  groupValue: true,
 | 
					                  groupValue: true,
 | 
				
			||||||
                  value: input.value == 'radio3',
 | 
					                  value: input.value == 'radio3',
 | 
				
			||||||
                  onChanged: (_) {
 | 
					                  onChanged: (_) {
 | 
				
			||||||
                    cubit.dataChanged(
 | 
					                    context.read<FormDataCubit>().dataChanged(
 | 
				
			||||||
                      field,
 | 
					                          formFieldRadio,
 | 
				
			||||||
                      const TextString.dirty('radio3'),
 | 
					                          const TextString.dirty('radio3'),
 | 
				
			||||||
                    );
 | 
					                        );
 | 
				
			||||||
                  }),
 | 
					                  }),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      }),
 | 
					      },
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -246,18 +292,17 @@ class _CheckHiddenInput extends StatelessWidget {
 | 
				
			|||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return ListTile(
 | 
					    return ListTile(
 | 
				
			||||||
      title: const Text('This input is not exported'),
 | 
					      title: const Text('This input is not exported'),
 | 
				
			||||||
      trailing: InputBuilder<SimpleCustomFormCubit>(
 | 
					      trailing: BlocBuilder<FormDataCubit, FormDataState>(
 | 
				
			||||||
        field: formFieldHidden,
 | 
					        builder: (context, state) {
 | 
				
			||||||
        builder: (context, cubit, state, field, inputValid) {
 | 
					 | 
				
			||||||
          return Checkbox(
 | 
					          return Checkbox(
 | 
				
			||||||
              value: state.form.validatorOf<Boolean>(field).value,
 | 
					              value: state.data.validatorOf<Boolean>(formFieldHidden).value,
 | 
				
			||||||
              onChanged: (v) {
 | 
					              onChanged: (v) {
 | 
				
			||||||
                final value = v!; // state is false, so value can't be null
 | 
					                final value = v!; // state is false, so value can't be null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                cubit.dataChanged(
 | 
					                context.read<FormDataCubit>().dataChanged(
 | 
				
			||||||
                  field,
 | 
					                      formFieldHidden,
 | 
				
			||||||
                  Boolean.dirty(value: value),
 | 
					                      Boolean.dirty(value: value),
 | 
				
			||||||
                );
 | 
					                    );
 | 
				
			||||||
              });
 | 
					              });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
@ -270,24 +315,25 @@ class _CheckIsProInput extends StatelessWidget {
 | 
				
			|||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return ListTile(
 | 
					    return ListTile(
 | 
				
			||||||
      title: const Text('Are you a pro?'),
 | 
					      title: const Text('Are you a pro?'),
 | 
				
			||||||
      trailing: InputBuilder<SimpleCustomFormCubit>(
 | 
					      trailing: BlocBuilder<FormDataCubit, FormDataState>(
 | 
				
			||||||
        field: formFieldPro,
 | 
					        builder: (context, state) {
 | 
				
			||||||
        builder: (context, cubit, state, field, inputValid) {
 | 
					 | 
				
			||||||
          return Checkbox(
 | 
					          return Checkbox(
 | 
				
			||||||
              value: state.form.validatorOf<Boolean>(field).value,
 | 
					              value: state.data.validatorOf<Boolean>(formFieldPro).value,
 | 
				
			||||||
              onChanged: (v) {
 | 
					              onChanged: (isPro) {
 | 
				
			||||||
                final value = v!; // state is false, so value can't be null
 | 
					                final value = isPro!; // state is false, so value can't be null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                cubit.dataChanged(
 | 
					                context.read<FormDataCubit>().dataChanged(
 | 
				
			||||||
                  field,
 | 
					                      formFieldPro,
 | 
				
			||||||
                  Boolean.dirty(value: value),
 | 
					                      Boolean.dirty(value: value),
 | 
				
			||||||
                );
 | 
					                    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (value) {
 | 
					                if (value) {
 | 
				
			||||||
                  cubit.update(App.getProFormData(),
 | 
					                  context.read<FormDataCubit>().updateFormData(
 | 
				
			||||||
 | 
					                      App.getProFormData(),
 | 
				
			||||||
                      operation: SetOperation.union);
 | 
					                      operation: SetOperation.union);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                  cubit.update(App.getNormalFormData(),
 | 
					                  context.read<FormDataCubit>().updateFormData(
 | 
				
			||||||
 | 
					                      App.getNormalFormData(),
 | 
				
			||||||
                      operation: SetOperation.intersection);
 | 
					                      operation: SetOperation.intersection);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              });
 | 
					              });
 | 
				
			||||||
@ -300,28 +346,49 @@ class _CheckIsProInput extends StatelessWidget {
 | 
				
			|||||||
class _SignUpButton extends StatelessWidget {
 | 
					class _SignUpButton extends StatelessWidget {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return SubmitBuilder<SimpleCustomFormCubit>(
 | 
					    return BlocBuilder<FormDataCubit, FormDataState>(
 | 
				
			||||||
        builder: (context, cubit, status) {
 | 
					      buildWhen: (previous, current) => previous.status != current.status,
 | 
				
			||||||
      return status.isSubmissionInProgress
 | 
					      builder: (context, state) {
 | 
				
			||||||
          ? const CircularProgressIndicator()
 | 
					        return state.status.isSubmissionInProgress
 | 
				
			||||||
          : ElevatedButton(
 | 
					            ? const CircularProgressIndicator()
 | 
				
			||||||
              onPressed: status.isValidated ? () => cubit.submit() : null,
 | 
					            : ElevatedButton(
 | 
				
			||||||
              child: const Text('SIGN UP'),
 | 
					                onPressed: state.status.isValidated
 | 
				
			||||||
            );
 | 
					                    ? () => context.read<FormDataCubit>().submitForm()
 | 
				
			||||||
    });
 | 
					                    : null,
 | 
				
			||||||
 | 
					                child: const Text('SIGN UP'),
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _DebugButton extends StatelessWidget {
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return BlocBuilder<FormDataCubit, FormDataState>(
 | 
				
			||||||
 | 
					      builder: (context, state) {
 | 
				
			||||||
 | 
					        return ElevatedButton(
 | 
				
			||||||
 | 
					          onPressed: () {
 | 
				
			||||||
 | 
					            log(state.toString());
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          child: const Text('DEBUG'),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _ResetButton extends StatelessWidget {
 | 
					class _ResetButton extends StatelessWidget {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return SubmitBuilder<SimpleCustomFormCubit>(
 | 
					    return BlocBuilder<FormDataCubit, FormDataState>(
 | 
				
			||||||
        builder: (context, cubit, status) {
 | 
					      builder: (context, state) {
 | 
				
			||||||
      return ElevatedButton(
 | 
					        return ElevatedButton(
 | 
				
			||||||
        onPressed: () => cubit.reset(),
 | 
					          onPressed: () => context.read<FormDataCubit>().resetForm(),
 | 
				
			||||||
        child: const Text('RESET'),
 | 
					          child: const Text('RESET'),
 | 
				
			||||||
      );
 | 
					        );
 | 
				
			||||||
    });
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -330,7 +397,7 @@ class SignUpForm extends StatelessWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return BlocListener<SimpleCustomFormCubit, FormDataState>(
 | 
					    return BlocListener<FormDataCubit, FormDataState>(
 | 
				
			||||||
      listener: (context, state) {
 | 
					      listener: (context, state) {
 | 
				
			||||||
        if (state.status.isSubmissionSuccess) {
 | 
					        if (state.status.isSubmissionSuccess) {
 | 
				
			||||||
          Navigator.of(context).pop(); // Never happens here
 | 
					          Navigator.of(context).pop(); // Never happens here
 | 
				
			||||||
@ -351,6 +418,8 @@ class SignUpForm extends StatelessWidget {
 | 
				
			|||||||
            const SizedBox(height: 8),
 | 
					            const SizedBox(height: 8),
 | 
				
			||||||
            _EmailInput(),
 | 
					            _EmailInput(),
 | 
				
			||||||
            const SizedBox(height: 8),
 | 
					            const SizedBox(height: 8),
 | 
				
			||||||
 | 
					            _PhoneInput(),
 | 
				
			||||||
 | 
					            const SizedBox(height: 8),
 | 
				
			||||||
            _CheckListInput(),
 | 
					            _CheckListInput(),
 | 
				
			||||||
            const SizedBox(height: 8),
 | 
					            const SizedBox(height: 8),
 | 
				
			||||||
            _RadioListInput(),
 | 
					            _RadioListInput(),
 | 
				
			||||||
@ -359,12 +428,13 @@ class SignUpForm extends StatelessWidget {
 | 
				
			|||||||
            const SizedBox(height: 8),
 | 
					            const SizedBox(height: 8),
 | 
				
			||||||
            _CheckIsProInput(),
 | 
					            _CheckIsProInput(),
 | 
				
			||||||
            const SizedBox(height: 8),
 | 
					            const SizedBox(height: 8),
 | 
				
			||||||
            BlocBuilder<SimpleCustomFormCubit, FormDataState>(
 | 
					            BlocBuilder<FormDataCubit, FormDataState>(
 | 
				
			||||||
              builder: (context, state) {
 | 
					              builder: (context, state) {
 | 
				
			||||||
                if (state.form.validatorOf<Boolean>(formFieldPro).value ??
 | 
					                if (state.data.validatorOf<Boolean>(formFieldPro).value) {
 | 
				
			||||||
                    false) {
 | 
					 | 
				
			||||||
                  return Column(children: [
 | 
					                  return Column(children: [
 | 
				
			||||||
                    _PhoneInput(),
 | 
					                    _SirenInput(),
 | 
				
			||||||
 | 
					                    const SizedBox(height: 8),
 | 
				
			||||||
 | 
					                    _IbanInput(),
 | 
				
			||||||
                    const SizedBox(height: 8),
 | 
					                    const SizedBox(height: 8),
 | 
				
			||||||
                  ]);
 | 
					                  ]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -374,6 +444,8 @@ class SignUpForm extends StatelessWidget {
 | 
				
			|||||||
            const SizedBox(height: 8),
 | 
					            const SizedBox(height: 8),
 | 
				
			||||||
            _SignUpButton(),
 | 
					            _SignUpButton(),
 | 
				
			||||||
            const SizedBox(height: 8),
 | 
					            const SizedBox(height: 8),
 | 
				
			||||||
 | 
					            _DebugButton(),
 | 
				
			||||||
 | 
					            const SizedBox(height: 8),
 | 
				
			||||||
            _ResetButton(),
 | 
					            _ResetButton(),
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
 | 
				
			|||||||
@ -1,57 +0,0 @@
 | 
				
			|||||||
// 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:flutter/material.dart';
 | 
					 | 
				
			||||||
import 'package:form_bloc_example/app/metadata.dart';
 | 
					 | 
				
			||||||
import 'package:form_bloc_example/constants.dart';
 | 
					 | 
				
			||||||
import 'package:form_bloc_example/simple_custom_form_cubit/simple_custom_form_cubit.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class _NameInput extends StatelessWidget {
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					 | 
				
			||||||
    return InputBuilderTextController<SimpleCustomFormCubit, String?, Metadata>(
 | 
					 | 
				
			||||||
      field: formFieldName,
 | 
					 | 
				
			||||||
      builder:
 | 
					 | 
				
			||||||
          (context, cubit, state, field, inputValid, controller, metadata) {
 | 
					 | 
				
			||||||
        return TextField(
 | 
					 | 
				
			||||||
          controller: controller,
 | 
					 | 
				
			||||||
          onChanged: (value) => cubit.dataChanged(field, Name.dirty(value)),
 | 
					 | 
				
			||||||
          keyboardType: TextInputType.name,
 | 
					 | 
				
			||||||
          decoration: InputDecoration(
 | 
					 | 
				
			||||||
            labelText: 'name',
 | 
					 | 
				
			||||||
            helperText: '',
 | 
					 | 
				
			||||||
            errorText: !inputValid ? 'invalid name' : null,
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SimpleSignUpForm extends StatelessWidget {
 | 
					 | 
				
			||||||
  const SimpleSignUpForm({Key? key}) : super(key: key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					 | 
				
			||||||
    return Column(
 | 
					 | 
				
			||||||
      children: [
 | 
					 | 
				
			||||||
        _NameInput(),
 | 
					 | 
				
			||||||
        const SizedBox(height: 8),
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,17 +0,0 @@
 | 
				
			|||||||
// 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 'enums/enums.dart';
 | 
					 | 
				
			||||||
@ -1,39 +0,0 @@
 | 
				
			|||||||
// 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/data/form_operations/form_difference.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/data/form_operations/form_intersection.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/data/form_operations/form_replace.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/data/form_operations/form_union.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum SetOperation {
 | 
					 | 
				
			||||||
  /// Replace entire set with new set.
 | 
					 | 
				
			||||||
  replace(FormReplace()),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// Keep common elements between sets.
 | 
					 | 
				
			||||||
  intersection(FormIntersection()),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// Remove common elements between sets.
 | 
					 | 
				
			||||||
  difference(FormDifference()),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// Add new elements to set.
 | 
					 | 
				
			||||||
  union(FormUnion());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final FormOperation operation;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const SetOperation(this.operation);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										110
									
								
								packages/wyatt_form_bloc/lib/src/cubit/form_data_cubit.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								packages/wyatt_form_bloc/lib/src/cubit/form_data_cubit.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					// 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:equatable/equatable.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_form_bloc/src/enums/enums.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_form_bloc/src/form/form.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_form_bloc/src/validators/form/every_input_validator.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					part 'form_data_state.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					abstract class FormDataCubit extends Cubit<FormDataState> {
 | 
				
			||||||
 | 
					  FormValidator validationStrategy;
 | 
				
			||||||
 | 
					  FormData formCopy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FormDataCubit({
 | 
				
			||||||
 | 
					    required FormData inputs,
 | 
				
			||||||
 | 
					    FormValidator validator = const EveryInputValidator(),
 | 
				
			||||||
 | 
					  })  : formCopy = inputs.clone(),
 | 
				
			||||||
 | 
					        validationStrategy = validator,
 | 
				
			||||||
 | 
					        super(FormDataState(data: inputs));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Change value of a field.
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// Inputs:
 | 
				
			||||||
 | 
					  /// - `field`: The key of the field to change.
 | 
				
			||||||
 | 
					  /// - `dirtyValue`: The new value of the field. (Wrapped in a dirty validator)
 | 
				
			||||||
 | 
					  void dataChanged<V>(
 | 
				
			||||||
 | 
					    String field,
 | 
				
			||||||
 | 
					    FormInputValidator<V, ValidationError> dirtyValue,
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    final form = state.data.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (form.contains(field)) {
 | 
				
			||||||
 | 
					      form.updateValidator(field, dirtyValue);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      throw Exception('Form field $field not found');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    emit(
 | 
				
			||||||
 | 
					      state.copyWith(
 | 
				
			||||||
 | 
					        data: form,
 | 
				
			||||||
 | 
					        status: validationStrategy.validate(form),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Just validate the form manually. (Useful if you just update the strategy)
 | 
				
			||||||
 | 
					  void validate() {
 | 
				
			||||||
 | 
					    final form = state.data;
 | 
				
			||||||
 | 
					    emit(state.copyWith(status: validationStrategy.validate(form)));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Update entries list.
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// Inputs:
 | 
				
			||||||
 | 
					  /// - `data`: The new entries list.
 | 
				
			||||||
 | 
					  /// - `operation`: The operation to perform on the entries set.
 | 
				
			||||||
 | 
					  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: validationStrategy.validate(form),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Reset all form inputs
 | 
				
			||||||
 | 
					  void resetForm() {
 | 
				
			||||||
 | 
					    emit(FormDataState(data: formCopy));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Submit the form.
 | 
				
			||||||
 | 
					  Future<void> submitForm();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -16,25 +16,35 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'form_data_cubit.dart';
 | 
					part of 'form_data_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ignore: must_be_immutable
 | 
					class FormDataState extends Equatable {
 | 
				
			||||||
abstract class FormDataState extends Equatable {
 | 
					 | 
				
			||||||
  /// Global status of a form.
 | 
					  /// Global status of a form.
 | 
				
			||||||
  final FormStatus status;
 | 
					  final FormStatus status;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  /// FormData with all inputs, and associated metadata.
 | 
					  /// FormData with all inputs, and associated metadata.
 | 
				
			||||||
  late WyattForm form;
 | 
					  final FormData data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Optional error message.
 | 
					  /// Optional error message.
 | 
				
			||||||
  final String? errorMessage;
 | 
					  final String? errorMessage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FormDataState({
 | 
					  const FormDataState({
 | 
				
			||||||
    WyattForm? form,
 | 
					    required this.data,
 | 
				
			||||||
    this.status = FormStatus.pure,
 | 
					    this.status = FormStatus.pure,
 | 
				
			||||||
    this.errorMessage,
 | 
					    this.errorMessage,
 | 
				
			||||||
  }) {
 | 
					  });
 | 
				
			||||||
    this.form = form ?? WyattFormImpl(const [], name: '');
 | 
					
 | 
				
			||||||
  }
 | 
					  FormDataState copyWith({
 | 
				
			||||||
 | 
					    FormStatus? status,
 | 
				
			||||||
 | 
					    FormData? data,
 | 
				
			||||||
 | 
					    String? errorMessage,
 | 
				
			||||||
 | 
					  }) => FormDataState(
 | 
				
			||||||
 | 
					      status: status ?? this.status,
 | 
				
			||||||
 | 
					      data: data ?? this.data,
 | 
				
			||||||
 | 
					      errorMessage: errorMessage ?? this.errorMessage,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  List<Object?> get props => [status, form, errorMessage];
 | 
					  bool? get stringify => true;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  List<Object?> get props => [status, data, errorMessage];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,35 +0,0 @@
 | 
				
			|||||||
// 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/wyatt_form_impl.dart';
 | 
					 | 
				
			||||||
export 'form_encoders/form_json_encoder.dart';
 | 
					 | 
				
			||||||
export 'form_encoders/form_map_encoder.dart';
 | 
					 | 
				
			||||||
export 'form_operations/form_difference.dart';
 | 
					 | 
				
			||||||
export 'form_operations/form_intersection.dart';
 | 
					 | 
				
			||||||
export 'form_operations/form_replace.dart';
 | 
					 | 
				
			||||||
export 'form_operations/form_union.dart';
 | 
					 | 
				
			||||||
export 'form_validators/every_input_validator.dart';
 | 
					 | 
				
			||||||
export 'form_validators/only_required_input_validator.dart';
 | 
					 | 
				
			||||||
export 'input_validators/boolean.dart';
 | 
					 | 
				
			||||||
export 'input_validators/confirmed_password.dart';
 | 
					 | 
				
			||||||
export 'input_validators/email.dart';
 | 
					 | 
				
			||||||
export 'input_validators/enum_option.dart';
 | 
					 | 
				
			||||||
export 'input_validators/list_option.dart';
 | 
					 | 
				
			||||||
export 'input_validators/name.dart';
 | 
					 | 
				
			||||||
export 'input_validators/password.dart';
 | 
					 | 
				
			||||||
export 'input_validators/phone.dart';
 | 
					 | 
				
			||||||
export 'input_validators/text_string.dart';
 | 
					 | 
				
			||||||
export 'repositories/form_repository_impl.dart';
 | 
					 | 
				
			||||||
@ -1,151 +0,0 @@
 | 
				
			|||||||
// 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/core/enums/form_status.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/data/form_validators/every_input_validator.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input_metadata.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_validators/form_validator.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ignore: must_be_immutable
 | 
					 | 
				
			||||||
class WyattFormImpl extends WyattForm {
 | 
					 | 
				
			||||||
  final List<
 | 
					 | 
				
			||||||
      FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
 | 
					 | 
				
			||||||
          dynamic>> _inputs;
 | 
					 | 
				
			||||||
  final FormValidator _validator;
 | 
					 | 
				
			||||||
  final String _name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  late List<
 | 
					 | 
				
			||||||
      FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
 | 
					 | 
				
			||||||
          dynamic>> _inputsInitial;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  WyattFormImpl(
 | 
					 | 
				
			||||||
    this._inputs, {
 | 
					 | 
				
			||||||
    required String name,
 | 
					 | 
				
			||||||
    FormValidator validationStrategy = const EveryInputValidator(),
 | 
					 | 
				
			||||||
  })  : _name = name,
 | 
					 | 
				
			||||||
        _validator = validationStrategy {
 | 
					 | 
				
			||||||
    _inputsInitial = _inputs.map((input) => input.clone()).toList();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  List<
 | 
					 | 
				
			||||||
      FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
 | 
					 | 
				
			||||||
          dynamic>> get inputs => _inputs;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  FormValidator get formValidationStrategy => _validator;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  String get name => _name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  bool containsKey(String key) => inputs.any((input) => input.key == key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  List<FormInputValidator<Value, Error>>
 | 
					 | 
				
			||||||
      asValidatorList<Value, Error extends ValidationError>() => inputs
 | 
					 | 
				
			||||||
          .map<FormInputValidator<Value, Error>>(
 | 
					 | 
				
			||||||
            (input) => input.validator as FormInputValidator<Value, Error>,
 | 
					 | 
				
			||||||
          )
 | 
					 | 
				
			||||||
          .toList();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  FormInput<dynamic, FormInputValidator<dynamic, ValidationError>, dynamic>
 | 
					 | 
				
			||||||
      inputOf(String key) {
 | 
					 | 
				
			||||||
    if (containsKey(key)) {
 | 
					 | 
				
			||||||
      return inputs.firstWhere((input) => input.key == key);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      throw Exception('FormInput with key `$key` does not exist in form');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Error? errorOf<Error extends ValidationError>(String key) =>
 | 
					 | 
				
			||||||
      (inputOf(key).validator as FormInputValidator<dynamic, Error>).error;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  FormInputMetadata<Extra> metadataOf<Extra>(String key) =>
 | 
					 | 
				
			||||||
      inputOf(key).metadata as FormInputMetadata<Extra>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Validator validatorOf<
 | 
					 | 
				
			||||||
          Validator extends FormInputValidator<dynamic, ValidationError>>(
 | 
					 | 
				
			||||||
    String key,
 | 
					 | 
				
			||||||
  ) =>
 | 
					 | 
				
			||||||
      inputOf(key).validator as Validator;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Value? valueOf<Value>(String key) =>
 | 
					 | 
				
			||||||
      (inputOf(key).validator as FormInputValidator<Value, dynamic>).value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  FormStatus validate() => formValidationStrategy.validate(this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  WyattForm clone() {
 | 
					 | 
				
			||||||
    final clone = WyattFormImpl(
 | 
					 | 
				
			||||||
      _inputs.map((input) => input.clone()).toList(),
 | 
					 | 
				
			||||||
      name: _name,
 | 
					 | 
				
			||||||
      validationStrategy: formValidationStrategy,
 | 
					 | 
				
			||||||
    ).._inputsInitial = _inputsInitial;
 | 
					 | 
				
			||||||
    return clone;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  WyattForm reset() {
 | 
					 | 
				
			||||||
    final newForm = WyattFormImpl(
 | 
					 | 
				
			||||||
      _inputsInitial,
 | 
					 | 
				
			||||||
      name: _name,
 | 
					 | 
				
			||||||
      validationStrategy: formValidationStrategy,
 | 
					 | 
				
			||||||
    ).._inputsInitial = _inputsInitial;
 | 
					 | 
				
			||||||
    return newForm;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  void updateMetadata<Extra>(String key, FormInputMetadata<Extra> metadata) {
 | 
					 | 
				
			||||||
    final index = _inputs.indexOf(
 | 
					 | 
				
			||||||
      inputOf(key),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    _inputs[index] = _inputs[index].copyWith(metadata: metadata);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  void updateValidator<Value>(
 | 
					 | 
				
			||||||
    String key,
 | 
					 | 
				
			||||||
    FormInputValidator<Value?, ValidationError> dirtyValue,
 | 
					 | 
				
			||||||
  ) {
 | 
					 | 
				
			||||||
    final index = _inputs.indexOf(
 | 
					 | 
				
			||||||
      inputOf(key),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    _inputs[index] = _inputs[index].copyWith(validator: dirtyValue);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  WyattForm operationWith(FormOperation operation, WyattForm other) =>
 | 
					 | 
				
			||||||
      operation.call(this, other);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  List<Object?> get props => [_inputs, _name, _validator];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  String toString() =>
 | 
					 | 
				
			||||||
      'WyattForm(name: $name, validation: ${_validator.runtimeType}, inputs: $inputs)';
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,32 +0,0 @@
 | 
				
			|||||||
// 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/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_encoders/form_encoder.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FormMapEncoder extends FormEncoder<Map<String, dynamic>> {
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Map<String, dynamic> encode(WyattForm form) {
 | 
					 | 
				
			||||||
    final inputs = form.inputs;
 | 
					 | 
				
			||||||
    final map = <String, dynamic>{};
 | 
					 | 
				
			||||||
    for (final input in inputs) {
 | 
					 | 
				
			||||||
      if (input.metadata.export) {
 | 
					 | 
				
			||||||
        map[input.name] = input.validator.value;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return map;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,51 +0,0 @@
 | 
				
			|||||||
// 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/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/data/form/wyatt_form_impl.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FormDifference extends FormOperation {
 | 
					 | 
				
			||||||
  const FormDifference();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  WyattForm call(WyattForm a, WyattForm b) {
 | 
					 | 
				
			||||||
    final inputs = <
 | 
					 | 
				
			||||||
        FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
 | 
					 | 
				
			||||||
            dynamic>>[];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (final i in b.inputs) {
 | 
					 | 
				
			||||||
      if (!a.containsKey(i.key)) {
 | 
					 | 
				
			||||||
        inputs.add(i);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (final i in a.inputs) {
 | 
					 | 
				
			||||||
      if (!b.containsKey(i.key)) {
 | 
					 | 
				
			||||||
        inputs.add(i);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return WyattFormImpl(
 | 
					 | 
				
			||||||
      inputs,
 | 
					 | 
				
			||||||
      name: a.name,
 | 
					 | 
				
			||||||
      validationStrategy: a.formValidationStrategy,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,45 +0,0 @@
 | 
				
			|||||||
// 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/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/data/form/wyatt_form_impl.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FormIntersection extends FormOperation {
 | 
					 | 
				
			||||||
  const FormIntersection();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  WyattForm call(WyattForm a, WyattForm b) {
 | 
					 | 
				
			||||||
    final inputs = <
 | 
					 | 
				
			||||||
        FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
 | 
					 | 
				
			||||||
            dynamic>>[];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (final i in a.inputs) {
 | 
					 | 
				
			||||||
      if (b.containsKey(i.key)) {
 | 
					 | 
				
			||||||
        inputs.add(i);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return WyattFormImpl(
 | 
					 | 
				
			||||||
      inputs,
 | 
					 | 
				
			||||||
      name: a.name,
 | 
					 | 
				
			||||||
      validationStrategy: a.formValidationStrategy,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,49 +0,0 @@
 | 
				
			|||||||
// 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/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/data/form/wyatt_form_impl.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FormUnion extends FormOperation {
 | 
					 | 
				
			||||||
  const FormUnion();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  WyattForm call(WyattForm a, WyattForm b) {
 | 
					 | 
				
			||||||
    final inputs = <
 | 
					 | 
				
			||||||
        FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
 | 
					 | 
				
			||||||
            dynamic>>[];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (final i in a.inputs) {
 | 
					 | 
				
			||||||
      inputs.add(i);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (final i in b.inputs) {
 | 
					 | 
				
			||||||
      if (!a.containsKey(i.key)) {
 | 
					 | 
				
			||||||
        inputs.add(i);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return WyattFormImpl(
 | 
					 | 
				
			||||||
      inputs,
 | 
					 | 
				
			||||||
      name: a.name,
 | 
					 | 
				
			||||||
      validationStrategy: a.formValidationStrategy,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,40 +0,0 @@
 | 
				
			|||||||
// 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/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class EnumOption<T> extends AnyValidator<T, List<T>, ValidationError> {
 | 
					 | 
				
			||||||
  const EnumOption.pure({this.enums = const [], T? defaultValue})
 | 
					 | 
				
			||||||
      : super.pure(defaultValue);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const EnumOption.dirty({required this.enums, T? value})
 | 
					 | 
				
			||||||
      : super.dirty(value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final List<T> enums;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  List<T> get allChoices => enums;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  ValidationError get onError => ValidationStandardError.invalid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  ValidationError get onNull => ValidationStandardError.invalid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  bool test(T? element, T value) => element == value;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,40 +0,0 @@
 | 
				
			|||||||
// 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/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ListOption<T> extends AnyValidator<T, Iterable<T>, ValidationError> {
 | 
					 | 
				
			||||||
  const ListOption.pure({this.choices = const [], T? defaultValue})
 | 
					 | 
				
			||||||
      : super.pure(defaultValue);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const ListOption.dirty({required this.choices, T? value})
 | 
					 | 
				
			||||||
      : super.dirty(value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final Iterable<T> choices;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Iterable<T> get allChoices => choices;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  ValidationError get onError => ValidationStandardError.invalid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  ValidationError get onNull => ValidationStandardError.invalid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  bool test(T? element, T value) => element == value;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,60 +0,0 @@
 | 
				
			|||||||
// 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_architecture/wyatt_architecture.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/repositories/form_repository.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FormRepositoryImpl extends FormRepository {
 | 
					 | 
				
			||||||
  final Map<String, WyattForm> _runtimeForms = {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Map<String, WyattForm> get runtimeForms => _runtimeForms;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  WyattForm accessForm(String formName) {
 | 
					 | 
				
			||||||
    if (_runtimeForms.containsKey(formName)) {
 | 
					 | 
				
			||||||
      return _runtimeForms[formName]!;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      throw ClientException(
 | 
					 | 
				
			||||||
        'Form $formName is not registered. Just use '
 | 
					 | 
				
			||||||
        '`FormRepository.register(yourForm);` before any operation on it.',
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  void registerForm(WyattForm form) {
 | 
					 | 
				
			||||||
    _runtimeForms[form.name] = form;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  void updateForm(WyattForm form) {
 | 
					 | 
				
			||||||
    if (_runtimeForms.containsKey(form.name)) {
 | 
					 | 
				
			||||||
      _runtimeForms[form.name] = form;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      throw ClientException(
 | 
					 | 
				
			||||||
        'Form ${form.name} is not registered. Just use '
 | 
					 | 
				
			||||||
        '`FormRepository.register(yourForm);` before any operation on it.',
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  void unregisterForm(String formName) {
 | 
					 | 
				
			||||||
    _runtimeForms.remove(formName);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,24 +0,0 @@
 | 
				
			|||||||
// 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 'entities/form_input.dart';
 | 
					 | 
				
			||||||
export 'entities/form_input_metadata.dart';
 | 
					 | 
				
			||||||
export 'form/wyatt_form.dart';
 | 
					 | 
				
			||||||
export 'form_encoders/form_encoder.dart';
 | 
					 | 
				
			||||||
export 'form_operations/form_operation.dart';
 | 
					 | 
				
			||||||
export 'form_validators/form_validator.dart';
 | 
					 | 
				
			||||||
export 'input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
export 'repositories/form_repository.dart';
 | 
					 | 
				
			||||||
@ -1,61 +0,0 @@
 | 
				
			|||||||
// 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/>.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ignore_for_file: strict_raw_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import 'package:equatable/equatable.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input_metadata.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_validators/form_validator.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class WyattForm extends Equatable {
 | 
					 | 
				
			||||||
  List<FormInput> get inputs;
 | 
					 | 
				
			||||||
  FormValidator get formValidationStrategy;
 | 
					 | 
				
			||||||
  String get name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool containsKey(String key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  FormInput inputOf(String key);
 | 
					 | 
				
			||||||
  Validator validatorOf<
 | 
					 | 
				
			||||||
      Validator extends FormInputValidator<dynamic, ValidationError>>(
 | 
					 | 
				
			||||||
    String key,
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
  Error? errorOf<Error extends ValidationError>(String key);
 | 
					 | 
				
			||||||
  Value? valueOf<Value>(String key);
 | 
					 | 
				
			||||||
  FormInputMetadata<Extra> metadataOf<Extra>(String key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  List<FormInputValidator<Value, Error>>
 | 
					 | 
				
			||||||
      asValidatorList<Value, Error extends ValidationError>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void updateValidator<Value>(
 | 
					 | 
				
			||||||
    String key,
 | 
					 | 
				
			||||||
    FormInputValidator<Value?, ValidationError> dirtyValue,
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void updateMetadata<Extra>(
 | 
					 | 
				
			||||||
    String key,
 | 
					 | 
				
			||||||
    FormInputMetadata<Extra> metadata,
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  FormStatus validate();
 | 
					 | 
				
			||||||
  WyattForm clone();
 | 
					 | 
				
			||||||
  WyattForm operationWith(FormOperation operation, WyattForm other);
 | 
					 | 
				
			||||||
  WyattForm reset();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,24 +0,0 @@
 | 
				
			|||||||
// 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/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ignore: one_member_abstracts
 | 
					 | 
				
			||||||
abstract class FormOperation {
 | 
					 | 
				
			||||||
  const FormOperation();
 | 
					 | 
				
			||||||
  // TODO(hpcl): handle operation on `initialInputs`
 | 
					 | 
				
			||||||
  WyattForm call(WyattForm a, WyattForm b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,45 +0,0 @@
 | 
				
			|||||||
// 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_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class AnyValidator<O, I extends Iterable<O?>,
 | 
					 | 
				
			||||||
    E extends ValidationError> extends FormInputValidator<O?, E> {
 | 
					 | 
				
			||||||
  const AnyValidator.pure(super.value) : super.pure();
 | 
					 | 
				
			||||||
  const AnyValidator.dirty(super.value) : super.dirty();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  I get allChoices;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool test(O? element, O value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  E get onError;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// If value is null.
 | 
					 | 
				
			||||||
  E get onNull;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  E? validator(O? value) {
 | 
					 | 
				
			||||||
    if (value == null) {
 | 
					 | 
				
			||||||
      return onNull;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (allChoices.any(
 | 
					 | 
				
			||||||
      (element) => test(element, value),
 | 
					 | 
				
			||||||
    )) {
 | 
					 | 
				
			||||||
      return null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return onError;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,45 +0,0 @@
 | 
				
			|||||||
// 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_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// {@template equality_validator}
 | 
					 | 
				
			||||||
/// Abstract equality validator validating a value when equals to another.
 | 
					 | 
				
			||||||
/// {@endtemplate}
 | 
					 | 
				
			||||||
abstract class EqualityValidator<O extends Object, E extends ValidationError>
 | 
					 | 
				
			||||||
    extends FormInputValidator<O?, E> {
 | 
					 | 
				
			||||||
  const EqualityValidator.pure(super.value) : super.pure();
 | 
					 | 
				
			||||||
  const EqualityValidator.dirty(super.value) : super.dirty();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  O get another;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// If values are different.
 | 
					 | 
				
			||||||
  E get onNotEqual;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// If value is null.
 | 
					 | 
				
			||||||
  E get onNull;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  E? validator(O? value) {
 | 
					 | 
				
			||||||
    if (value == null) {
 | 
					 | 
				
			||||||
      return onNull;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (value != another) {
 | 
					 | 
				
			||||||
      return onNotEqual;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return null;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,27 +0,0 @@
 | 
				
			|||||||
// 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_architecture/wyatt_architecture.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class FormRepository extends BaseRepository {
 | 
					 | 
				
			||||||
  Map<String, WyattForm> get runtimeForms;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void registerForm(WyattForm form);
 | 
					 | 
				
			||||||
  void updateForm(WyattForm form);
 | 
					 | 
				
			||||||
  WyattForm accessForm(String formName);
 | 
					 | 
				
			||||||
  void unregisterForm(String formName);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -14,9 +14,16 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					enum SetOperation { 
 | 
				
			||||||
 | 
					  /// Replace entire set with new set.
 | 
				
			||||||
 | 
					  replace, 
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
// ignore: one_member_abstracts
 | 
					  /// Keep common elements between sets.
 | 
				
			||||||
abstract class FormEncoder<Output> {
 | 
					  intersection, 
 | 
				
			||||||
  Output encode(WyattForm form);
 | 
					  
 | 
				
			||||||
 | 
					  /// Remove common elements between sets.
 | 
				
			||||||
 | 
					  difference, 
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  /// Add new elements to set.
 | 
				
			||||||
 | 
					  union
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -23,6 +23,5 @@ abstract class ValidationError {}
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
enum ValidationStandardError implements ValidationError {
 | 
					enum ValidationStandardError implements ValidationError {
 | 
				
			||||||
  invalid,
 | 
					  invalid,
 | 
				
			||||||
  empty,
 | 
					  empty
 | 
				
			||||||
  notEqual,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -14,12 +14,15 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					import 'dart:convert';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FormReplace extends FormOperation {
 | 
					import 'package:equatable/equatable.dart';
 | 
				
			||||||
  const FormReplace();
 | 
					import 'package:wyatt_form_bloc/src/enums/form_input_status.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_form_bloc/src/enums/form_status.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_form_bloc/src/enums/validation_error.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					part 'form_data.dart';
 | 
				
			||||||
  WyattForm call(WyattForm a, WyattForm b) => b;
 | 
					part 'form_input.dart';
 | 
				
			||||||
}
 | 
					part 'form_input_metadata.dart';
 | 
				
			||||||
 | 
					part 'form_input_validator.dart';
 | 
				
			||||||
 | 
					part 'form_validator.dart';
 | 
				
			||||||
							
								
								
									
										184
									
								
								packages/wyatt_form_bloc/lib/src/form/form_data.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								packages/wyatt_form_bloc/lib/src/form/form_data.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,184 @@
 | 
				
			|||||||
 | 
					// 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.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FormData extends Equatable {
 | 
				
			||||||
 | 
					  final List<FormInput> _inputs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const FormData(this._inputs);
 | 
				
			||||||
 | 
					  const FormData.empty() : this(const <FormInput>[]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns all inputs as a list
 | 
				
			||||||
 | 
					  List<FormInput> inputs() => _inputs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns the input for the associated key
 | 
				
			||||||
 | 
					  FormInput inputOf(String key) {
 | 
				
			||||||
 | 
					    if (contains(key)) {
 | 
				
			||||||
 | 
					      return _inputs.firstWhere((input) => input.key == key);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      throw Exception('FormInput with key `$key` does not exist in form');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Updates a input (perform a replace at index).
 | 
				
			||||||
 | 
					  void updateInput(String key, FormInput input) {
 | 
				
			||||||
 | 
					    if (contains(key)) {
 | 
				
			||||||
 | 
					      final index = _inputs.indexOf(
 | 
				
			||||||
 | 
					        inputOf(key),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      _inputs[index] = input;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns all associated validators as a list
 | 
				
			||||||
 | 
					  List<FormInputValidator<V, E>> validators<V, E extends ValidationError>() =>
 | 
				
			||||||
 | 
					      _inputs
 | 
				
			||||||
 | 
					          .map<FormInputValidator<V, E>>(
 | 
				
			||||||
 | 
					            (input) => input.validator as FormInputValidator<V, E>,
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					          .toList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// A [FormInputValidator] represents the value of a single form input field.
 | 
				
			||||||
 | 
					  /// It contains information about the [FormInputStatus], value, as well
 | 
				
			||||||
 | 
					  /// as validation status.
 | 
				
			||||||
 | 
					  T validatorOf<T>(String key) => inputOf(key).validator as T;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Updates validator of a given input. (perform copyWith)
 | 
				
			||||||
 | 
					  void updateValidator<V>(
 | 
				
			||||||
 | 
					    String key,
 | 
				
			||||||
 | 
					    FormInputValidator<V, ValidationError> dirtyValue,
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    if (contains(key)) {
 | 
				
			||||||
 | 
					      final index = _inputs.indexOf(
 | 
				
			||||||
 | 
					        inputOf(key),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      _inputs[index] = _inputs[index].copyWith(validator: dirtyValue);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns a validation error if the [FormInputValidator] is invalid.
 | 
				
			||||||
 | 
					  /// Returns null if the [FormInputValidator] is valid.
 | 
				
			||||||
 | 
					  E? errorOf<E extends ValidationError>(String key) =>
 | 
				
			||||||
 | 
					      (inputOf(key).validator as FormInputValidator<dynamic, E>).error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The value of the associated [FormInputValidator]. For example,
 | 
				
			||||||
 | 
					  /// if you have a FormInputValidator for FirstName, the value could be 'Joe'.
 | 
				
			||||||
 | 
					  V valueOf<V>(String key) =>
 | 
				
			||||||
 | 
					      (inputOf(key).validator as FormInputValidator<V, dynamic>).value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns `true` if the [FormInputValidator] is not valid.
 | 
				
			||||||
 | 
					  /// Same as `E? errorOf<V, E>(String key) != null`
 | 
				
			||||||
 | 
					  bool isNotValid(String key) => !inputOf(key).validator.valid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns all associated metadata as a list
 | 
				
			||||||
 | 
					  List<FormInputMetadata<M>> metadata<M>() => _inputs
 | 
				
			||||||
 | 
					      .map<FormInputMetadata<M>>(
 | 
				
			||||||
 | 
					        (input) => input.metadata as FormInputMetadata<M>,
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      .toList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns the metadata associated. With `M` the type of extra data.
 | 
				
			||||||
 | 
					  FormInputMetadata<M> metadataOf<M>(String key) =>
 | 
				
			||||||
 | 
					      inputOf(key).metadata as FormInputMetadata<M>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Updates metadata of a given input. (perform copyWith)
 | 
				
			||||||
 | 
					  void updateMetadata<M>(String key, FormInputMetadata<M> meta) {
 | 
				
			||||||
 | 
					    if (contains(key)) {
 | 
				
			||||||
 | 
					      final index = _inputs.indexOf(
 | 
				
			||||||
 | 
					        inputOf(key),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      _inputs[index] = _inputs[index].copyWith(metadata: meta);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Check if this contains an input with the given key.
 | 
				
			||||||
 | 
					  bool contains(String key) => _inputs.any((input) => input.key == key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Makes an intersection set operation and returns newly created [FormData]
 | 
				
			||||||
 | 
					  FormData intersection(FormData other) {
 | 
				
			||||||
 | 
					    final List<FormInput> inputs = <FormInput>[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (final FormInput i in _inputs) {
 | 
				
			||||||
 | 
					      if (other.contains(i.key)) {
 | 
				
			||||||
 | 
					        inputs.add(i);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return FormData(inputs);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Makes a difference set operation and returns newly created [FormData]
 | 
				
			||||||
 | 
					  FormData difference(FormData other) {
 | 
				
			||||||
 | 
					    final List<FormInput> inputs = <FormInput>[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (final FormInput i in other._inputs) {
 | 
				
			||||||
 | 
					      if (!contains(i.key)) {
 | 
				
			||||||
 | 
					        inputs.add(i);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (final FormInput i in _inputs) {
 | 
				
			||||||
 | 
					      if (!other.contains(i.key)) {
 | 
				
			||||||
 | 
					        inputs.add(i);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return FormData(inputs);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Makes an union set operation and returns newly created [FormData]
 | 
				
			||||||
 | 
					  FormData union(FormData other) {
 | 
				
			||||||
 | 
					    final List<FormInput> inputs = <FormInput>[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (final FormInput i in _inputs) {
 | 
				
			||||||
 | 
					      inputs.add(i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (final FormInput i in other._inputs) {
 | 
				
			||||||
 | 
					      if (!contains(i.key)) {
 | 
				
			||||||
 | 
					        inputs.add(i);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return FormData(inputs);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Deeply copy this.
 | 
				
			||||||
 | 
					  FormData clone() => FormData(
 | 
				
			||||||
 | 
					        _inputs.map((input) => input.clone()).toList(),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Export this to [Map] format.
 | 
				
			||||||
 | 
					  Map<String, dynamic> toMap() {
 | 
				
			||||||
 | 
					    final map = <String, dynamic>{};
 | 
				
			||||||
 | 
					    for (final input in _inputs) {
 | 
				
			||||||
 | 
					      if (input.metadata.export) {
 | 
				
			||||||
 | 
					        map[input.name] = input.validator.value;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return map;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Export this to [String] format.
 | 
				
			||||||
 | 
					  String toJson() => jsonEncode(toMap());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool? get stringify => true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  List<Object?> get props => _inputs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -15,36 +15,27 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:equatable/equatable.dart';
 | 
					part of 'form.dart';
 | 
				
			||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input_metadata.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ignore: must_be_immutable
 | 
					class FormInput<Validator extends FormInputValidator<dynamic, ValidationError>>
 | 
				
			||||||
class FormInput<
 | 
					    extends Equatable {
 | 
				
			||||||
    Value,
 | 
					 | 
				
			||||||
    Validator extends FormInputValidator<Value, ValidationError>,
 | 
					 | 
				
			||||||
    Extra> extends Equatable implements Entity {
 | 
					 | 
				
			||||||
  final String key;
 | 
					  final String key;
 | 
				
			||||||
  final Validator validator;
 | 
					  final Validator validator;
 | 
				
			||||||
  late FormInputMetadata<Extra> metadata;
 | 
					  final FormInputMetadata<dynamic> metadata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  String get name => metadata.name ?? key;
 | 
					  String get name => metadata._name ?? key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FormInput(
 | 
					  const FormInput(
 | 
				
			||||||
    this.key,
 | 
					    this.key,
 | 
				
			||||||
    this.validator, {
 | 
					    this.validator, {
 | 
				
			||||||
    // ignore: avoid_redundant_argument_values
 | 
					    // ignore: avoid_redundant_argument_values
 | 
				
			||||||
    FormInputMetadata<Extra>? metadata,
 | 
					    this.metadata = const FormInputMetadata<void>(export: true),
 | 
				
			||||||
  }) {
 | 
					  });
 | 
				
			||||||
    this.metadata = metadata ?? FormInputMetadata<Extra>();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FormInput<Value, Validator, Extra> copyWith({
 | 
					  FormInput copyWith({
 | 
				
			||||||
    String? key,
 | 
					    String? key,
 | 
				
			||||||
    Validator? validator,
 | 
					    Validator? validator,
 | 
				
			||||||
    FormInputMetadata<Extra>? metadata,
 | 
					    FormInputMetadata? metadata,
 | 
				
			||||||
  }) =>
 | 
					  }) =>
 | 
				
			||||||
      FormInput(
 | 
					      FormInput(
 | 
				
			||||||
        key ?? this.key,
 | 
					        key ?? this.key,
 | 
				
			||||||
@ -52,16 +43,14 @@ class FormInput<
 | 
				
			|||||||
        metadata: metadata ?? this.metadata,
 | 
					        metadata: metadata ?? this.metadata,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FormInput<Value, Validator, Extra> clone() => copyWith(
 | 
					  FormInput clone() => copyWith(
 | 
				
			||||||
        key: key,
 | 
					        key: key,
 | 
				
			||||||
        validator: validator,
 | 
					        validator: validator,
 | 
				
			||||||
        metadata: metadata,
 | 
					        metadata: metadata,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool? get stringify => true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  List<Object?> get props => [key, validator, metadata];
 | 
					  List<Object?> get props => [key, validator, metadata];
 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  String toString() =>
 | 
					 | 
				
			||||||
      'FormInput(name: $name, value: ${validator.value}, status: ${validator.status.name}';
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -15,35 +15,33 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:equatable/equatable.dart';
 | 
					part of 'form.dart';
 | 
				
			||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FormInputMetadata<Extra> extends Equatable
 | 
					class FormInputMetadata<T extends Object?> extends Equatable {
 | 
				
			||||||
    implements Entity {
 | 
					 | 
				
			||||||
  final bool export;
 | 
					  final bool export;
 | 
				
			||||||
  final String? name;
 | 
					  final String? _name;
 | 
				
			||||||
  final Extra? extra;
 | 
					  final T? extra;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const FormInputMetadata({
 | 
					  const FormInputMetadata({
 | 
				
			||||||
    this.export = true,
 | 
					    this.export = true,
 | 
				
			||||||
    this.name,
 | 
					 | 
				
			||||||
    this.extra,
 | 
					    this.extra,
 | 
				
			||||||
  });
 | 
					    String? name,
 | 
				
			||||||
 | 
					  }) : _name = name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FormInputMetadata<Extra> copyWith({
 | 
					  FormInputMetadata<T> copyWith({
 | 
				
			||||||
    bool? export,
 | 
					    bool? export,
 | 
				
			||||||
    String? name,
 | 
					    String? name,
 | 
				
			||||||
    Extra? extra,
 | 
					    T? extra,
 | 
				
			||||||
  }) =>
 | 
					  }) =>
 | 
				
			||||||
      FormInputMetadata<Extra>(
 | 
					      FormInputMetadata<T>(
 | 
				
			||||||
        export: export ?? this.export,
 | 
					        export: export ?? this.export,
 | 
				
			||||||
        name: name ?? this.name,
 | 
					        name: name ?? _name,
 | 
				
			||||||
        extra: extra ?? this.extra,
 | 
					        extra: extra ?? this.extra,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FormInputMetadata<Extra> clone() => copyWith(
 | 
					  FormInputMetadata<T> clone() => copyWith(
 | 
				
			||||||
        export: export,
 | 
					        export: export,
 | 
				
			||||||
        name: name,
 | 
					        name: _name,
 | 
				
			||||||
        extra: extra,
 | 
					        extra: extra,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -51,5 +49,5 @@ class FormInputMetadata<Extra> extends Equatable
 | 
				
			|||||||
  bool? get stringify => true;
 | 
					  bool? get stringify => true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  List<Object?> get props => [export, name, extra];
 | 
					  List<Object?> get props => [export, _name, extra];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -14,15 +14,7 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:equatable/equatable.dart';
 | 
					part of 'form.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/form_input_status.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
part 'any_validator.dart';
 | 
					 | 
				
			||||||
part 'equality_validator.dart';
 | 
					 | 
				
			||||||
part 'nullable_validator.dart';
 | 
					 | 
				
			||||||
part 'regex_validator.dart';
 | 
					 | 
				
			||||||
part 'text_validator.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template form_input_validator}
 | 
					/// {@template form_input_validator}
 | 
				
			||||||
/// A [FormInputValidator] represents the value of a single form input field.
 | 
					/// A [FormInputValidator] represents the value of a single form input field.
 | 
				
			||||||
@ -47,21 +39,21 @@ part 'text_validator.dart';
 | 
				
			|||||||
/// }
 | 
					/// }
 | 
				
			||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class FormInputValidator<Value, Error extends ValidationError>
 | 
					abstract class FormInputValidator<V, E extends ValidationError>
 | 
				
			||||||
    extends Equatable {
 | 
					    extends Equatable {
 | 
				
			||||||
  const FormInputValidator._(this.value, [this.pure = true]);
 | 
					  const FormInputValidator._(this.value, [this.pure = true]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Constructor which create a `pure` [FormInputValidator] with a given value.
 | 
					  /// Constructor which create a `pure` [FormInputValidator] with a given value.
 | 
				
			||||||
  const FormInputValidator.pure(Value value) : this._(value);
 | 
					  const FormInputValidator.pure(V value) : this._(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Constructor which create a `dirty` [FormInputValidator] with a
 | 
					  /// Constructor which create a `dirty` [FormInputValidator] with a
 | 
				
			||||||
  /// given value.
 | 
					  /// given value.
 | 
				
			||||||
  const FormInputValidator.dirty(Value value) : this._(value, false);
 | 
					  const FormInputValidator.dirty(V value) : this._(value, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// The value of the given [FormInputValidator].
 | 
					  /// The value of the given [FormInputValidator].
 | 
				
			||||||
  /// For example, if you have a `FormInputValidator` for `FirstName`,
 | 
					  /// For example, if you have a `FormInputValidator` for `FirstName`,
 | 
				
			||||||
  /// the value could be 'Joe'.
 | 
					  /// the value could be 'Joe'.
 | 
				
			||||||
  final Value? value;
 | 
					  final V value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// If the [FormInputValidator] is pure (has been touched/modified).
 | 
					  /// If the [FormInputValidator] is pure (has been touched/modified).
 | 
				
			||||||
  /// Typically when the `FormInputValidator` is initially created,
 | 
					  /// Typically when the `FormInputValidator` is initially created,
 | 
				
			||||||
@ -88,7 +80,7 @@ abstract class FormInputValidator<Value, Error extends ValidationError>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /// Returns a validation error if the [FormInputValidator] is invalid.
 | 
					  /// Returns a validation error if the [FormInputValidator] is invalid.
 | 
				
			||||||
  /// Returns `null` if the [FormInputValidator] is valid.
 | 
					  /// Returns `null` if the [FormInputValidator] is valid.
 | 
				
			||||||
  Error? get error => validator(value);
 | 
					  E? get error => validator(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Whether the [FormInputValidator] value is valid according to the
 | 
					  /// Whether the [FormInputValidator] value is valid according to the
 | 
				
			||||||
  /// overridden `validator`.
 | 
					  /// overridden `validator`.
 | 
				
			||||||
@ -104,7 +96,7 @@ abstract class FormInputValidator<Value, Error extends ValidationError>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /// A function that must return a validation error if the provided
 | 
					  /// A function that must return a validation error if the provided
 | 
				
			||||||
  /// [value] is invalid and `null` otherwise.
 | 
					  /// [value] is invalid and `null` otherwise.
 | 
				
			||||||
  Error? validator(Value? value);
 | 
					  E? validator(V value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  bool? get stringify => true;
 | 
					  bool? get stringify => true;
 | 
				
			||||||
@ -14,9 +14,7 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.dart';
 | 
					part of 'form.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template form_validator}
 | 
					/// {@template form_validator}
 | 
				
			||||||
/// A [FormValidator] represents the global validaton state of a Form.
 | 
					/// A [FormValidator] represents the global validaton state of a Form.
 | 
				
			||||||
@ -25,9 +23,13 @@ abstract class FormValidator {
 | 
				
			|||||||
  /// {@macro form_validator}
 | 
					  /// {@macro form_validator}
 | 
				
			||||||
  const FormValidator();
 | 
					  const FormValidator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool isPure(WyattForm form) => form
 | 
					  bool isPure(FormData form) => form
 | 
				
			||||||
      .asValidatorList<dynamic, ValidationError>()
 | 
					      .validators<dynamic, ValidationError>()
 | 
				
			||||||
      .every((validator) => validator.pure);
 | 
					      .every((validator) => validator.pure);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FormStatus validate(WyattForm form);
 | 
					  FormStatus validate(FormData form);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FormStatus rawValidate(
 | 
				
			||||||
 | 
					    List<FormInputValidator<dynamic, ValidationError>> validators,
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,50 +0,0 @@
 | 
				
			|||||||
// 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:equatable/equatable.dart';
 | 
					 | 
				
			||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/set_operations.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/data/form/wyatt_form_impl.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
part 'form_data_state.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class FormDataCubit<State extends FormDataState> extends Cubit<State> {
 | 
					 | 
				
			||||||
  FormDataCubit(super.initialState) : super();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  String get formName;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  FutureOr<void> dataChanged<Value>(
 | 
					 | 
				
			||||||
    String key,
 | 
					 | 
				
			||||||
    FormInputValidator<Value, ValidationError> dirtyValue,
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  FutureOr<void> update(
 | 
					 | 
				
			||||||
    WyattForm form, {
 | 
					 | 
				
			||||||
    SetOperation operation = SetOperation.replace,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  FutureOr<void> validate();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  FutureOr<void> reset();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  FutureOr<void> submit();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,98 +0,0 @@
 | 
				
			|||||||
// 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:wyatt_form_bloc/src/core/enums/form_status.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/set_operations.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/repositories/form_repository.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/presentation/features/form_data/form_data_cubit.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
part 'form_data_state_impl.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class FormDataCubitImpl extends FormDataCubit<FormDataStateImpl> {
 | 
					 | 
				
			||||||
  final FormRepository _formRepository;
 | 
					 | 
				
			||||||
  final String _formName;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  FormDataCubitImpl(this._formRepository, this._formName)
 | 
					 | 
				
			||||||
      : super(FormDataStateImpl(form: _formRepository.accessForm(_formName)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  String get formName => _formName;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  FutureOr<void> dataChanged<Value>(
 | 
					 | 
				
			||||||
    String key,
 | 
					 | 
				
			||||||
    FormInputValidator<Value, ValidationError> dirtyValue,
 | 
					 | 
				
			||||||
  ) {
 | 
					 | 
				
			||||||
    final form = _formRepository.accessForm(_formName).clone();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      form.updateValidator(key, dirtyValue);
 | 
					 | 
				
			||||||
      _formRepository.updateForm(form);
 | 
					 | 
				
			||||||
    } catch (e) {
 | 
					 | 
				
			||||||
      rethrow;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    emit(
 | 
					 | 
				
			||||||
      state.copyWith(
 | 
					 | 
				
			||||||
        form: form,
 | 
					 | 
				
			||||||
        status: form.validate(),
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  FutureOr<void> update(
 | 
					 | 
				
			||||||
    WyattForm form, {
 | 
					 | 
				
			||||||
    SetOperation operation = SetOperation.replace,
 | 
					 | 
				
			||||||
  }) {
 | 
					 | 
				
			||||||
    final WyattForm current = _formRepository.accessForm(_formName).clone();
 | 
					 | 
				
			||||||
    final WyattForm newForm = operation.operation.call(current, form);
 | 
					 | 
				
			||||||
    _formRepository.updateForm(newForm);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    emit(
 | 
					 | 
				
			||||||
      state.copyWith(
 | 
					 | 
				
			||||||
        form: newForm,
 | 
					 | 
				
			||||||
        status: newForm.validate(),
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  FutureOr<void> reset() {
 | 
					 | 
				
			||||||
    final form = state.form.reset();
 | 
					 | 
				
			||||||
    _formRepository.updateForm(form);
 | 
					 | 
				
			||||||
    emit(
 | 
					 | 
				
			||||||
      state.copyWith(
 | 
					 | 
				
			||||||
        form: form,
 | 
					 | 
				
			||||||
        status: form.validate(),
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  FutureOr<void> validate() {
 | 
					 | 
				
			||||||
    emit(
 | 
					 | 
				
			||||||
      state.copyWith(
 | 
					 | 
				
			||||||
        status: state.form.validate(),
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,44 +0,0 @@
 | 
				
			|||||||
// 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_data_cubit_impl.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ignore: must_be_immutable
 | 
					 | 
				
			||||||
class FormDataStateImpl extends FormDataState {
 | 
					 | 
				
			||||||
  FormDataStateImpl({
 | 
					 | 
				
			||||||
    required super.form,
 | 
					 | 
				
			||||||
    super.status = FormStatus.pure,
 | 
					 | 
				
			||||||
    super.errorMessage,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  FormDataStateImpl copyWith({
 | 
					 | 
				
			||||||
    FormStatus? status,
 | 
					 | 
				
			||||||
    WyattForm? form,
 | 
					 | 
				
			||||||
    String? errorMessage,
 | 
					 | 
				
			||||||
  }) =>
 | 
					 | 
				
			||||||
      FormDataStateImpl(
 | 
					 | 
				
			||||||
        status: status ?? this.status,
 | 
					 | 
				
			||||||
        form: form ?? this.form,
 | 
					 | 
				
			||||||
        errorMessage: errorMessage ?? this.errorMessage,
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  List<Object?> get props => [status, form, errorMessage];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  String toString() =>
 | 
					 | 
				
			||||||
      'FormDataSate(status: ${status.name} ${(errorMessage != null) ? " [$errorMessage]" : ""}, $form';
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,43 +0,0 @@
 | 
				
			|||||||
// 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:flutter/material.dart';
 | 
					 | 
				
			||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class InputBuilder<Cubit extends FormDataCubit> extends StatelessWidget {
 | 
					 | 
				
			||||||
  const InputBuilder({required this.field, required this.builder, super.key});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final String field;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final Widget Function(
 | 
					 | 
				
			||||||
    BuildContext context,
 | 
					 | 
				
			||||||
    Cubit cubit,
 | 
					 | 
				
			||||||
    FormDataState state,
 | 
					 | 
				
			||||||
    String field,
 | 
					 | 
				
			||||||
    bool inputValid,
 | 
					 | 
				
			||||||
  ) builder;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Widget build(BuildContext context) =>
 | 
					 | 
				
			||||||
      BlocBuilder<Cubit, FormDataState>(
 | 
					 | 
				
			||||||
        builder: (context, state) {
 | 
					 | 
				
			||||||
          final cubit = context.watch<Cubit>();
 | 
					 | 
				
			||||||
          final inputValid = state.form.validatorOf(field).valid;
 | 
					 | 
				
			||||||
          return builder.call(context, cubit, state, field, inputValid);
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,57 +0,0 @@
 | 
				
			|||||||
// 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:flutter/material.dart';
 | 
					 | 
				
			||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input_metadata.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/presentation/presentation.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class InputBuilderMetadata<Cubit extends FormDataCubit, Extra>
 | 
					 | 
				
			||||||
    extends StatelessWidget {
 | 
					 | 
				
			||||||
  const InputBuilderMetadata({
 | 
					 | 
				
			||||||
    required this.field,
 | 
					 | 
				
			||||||
    required this.builder,
 | 
					 | 
				
			||||||
    super.key,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final String field;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final Widget Function(
 | 
					 | 
				
			||||||
    BuildContext context,
 | 
					 | 
				
			||||||
    Cubit cubit,
 | 
					 | 
				
			||||||
    FormDataState state,
 | 
					 | 
				
			||||||
    String field,
 | 
					 | 
				
			||||||
    bool inputValid,
 | 
					 | 
				
			||||||
    FormInputMetadata<Extra>? metadata,
 | 
					 | 
				
			||||||
  ) builder;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Widget build(BuildContext context) => BlocBuilder<Cubit, FormDataState>(
 | 
					 | 
				
			||||||
        builder: (context, state) {
 | 
					 | 
				
			||||||
          final cubit = context.read<Cubit>();
 | 
					 | 
				
			||||||
          final inputValid = state.form.validatorOf(field).valid;
 | 
					 | 
				
			||||||
          final metadata = state.form.metadataOf<Extra>(field);
 | 
					 | 
				
			||||||
          return builder.call(
 | 
					 | 
				
			||||||
            context,
 | 
					 | 
				
			||||||
            cubit,
 | 
					 | 
				
			||||||
            state,
 | 
					 | 
				
			||||||
            field,
 | 
					 | 
				
			||||||
            inputValid,
 | 
					 | 
				
			||||||
            metadata,
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,75 +0,0 @@
 | 
				
			|||||||
// 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:flutter/material.dart';
 | 
					 | 
				
			||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input_metadata.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/repositories/form_repository.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/presentation/features/form_data/form_data_cubit.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class InputBuilderTextController<Cubit extends FormDataCubit, S extends String?,
 | 
					 | 
				
			||||||
    Extra> extends StatelessWidget {
 | 
					 | 
				
			||||||
  InputBuilderTextController({
 | 
					 | 
				
			||||||
    required this.field,
 | 
					 | 
				
			||||||
    required this.builder,
 | 
					 | 
				
			||||||
    super.key,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final String field;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final Widget Function(
 | 
					 | 
				
			||||||
    BuildContext context,
 | 
					 | 
				
			||||||
    Cubit cubit,
 | 
					 | 
				
			||||||
    FormDataState state,
 | 
					 | 
				
			||||||
    String field,
 | 
					 | 
				
			||||||
    bool inputValid,
 | 
					 | 
				
			||||||
    TextEditingController textEditingController,
 | 
					 | 
				
			||||||
    FormInputMetadata<Extra>? metadata,
 | 
					 | 
				
			||||||
  ) builder;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final TextEditingController _controller = TextEditingController();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					 | 
				
			||||||
    final formName = context.watch<Cubit>().formName;
 | 
					 | 
				
			||||||
    final value =
 | 
					 | 
				
			||||||
        context.read<FormRepository>().accessForm(formName).valueOf<S>(field);
 | 
					 | 
				
			||||||
    _controller
 | 
					 | 
				
			||||||
      ..text = value ?? ''
 | 
					 | 
				
			||||||
      ..selection = TextSelection.fromPosition(
 | 
					 | 
				
			||||||
        TextPosition(
 | 
					 | 
				
			||||||
          offset: _controller.text.length,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return BlocBuilder<Cubit, FormDataState>(
 | 
					 | 
				
			||||||
      builder: (context, state) {
 | 
					 | 
				
			||||||
        final cubit = context.read<Cubit>();
 | 
					 | 
				
			||||||
        final inputValid = state.form.validatorOf(field).valid;
 | 
					 | 
				
			||||||
        final metadata = state.form.metadataOf<Extra>(field);
 | 
					 | 
				
			||||||
        return builder.call(
 | 
					 | 
				
			||||||
          context,
 | 
					 | 
				
			||||||
          cubit,
 | 
					 | 
				
			||||||
          state,
 | 
					 | 
				
			||||||
          field,
 | 
					 | 
				
			||||||
          inputValid,
 | 
					 | 
				
			||||||
          _controller,
 | 
					 | 
				
			||||||
          metadata,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,37 +0,0 @@
 | 
				
			|||||||
// 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:flutter/material.dart';
 | 
					 | 
				
			||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/presentation/features/form_data/form_data_cubit.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SubmitBuilder<Cubit extends FormDataCubit> extends StatelessWidget {
 | 
					 | 
				
			||||||
  const SubmitBuilder({required this.builder, super.key});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  final Widget Function(BuildContext context, Cubit cubit, FormStatus status)
 | 
					 | 
				
			||||||
      builder;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Widget build(BuildContext context) => BlocBuilder<Cubit, FormDataState>(
 | 
					 | 
				
			||||||
        buildWhen: (previous, current) => previous.status != current.status,
 | 
					 | 
				
			||||||
        builder: (context, state) => builder.call(
 | 
					 | 
				
			||||||
          context,
 | 
					 | 
				
			||||||
          context.read<Cubit>(),
 | 
					 | 
				
			||||||
          state.status,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,22 +0,0 @@
 | 
				
			|||||||
// 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 'features/form_data/form_data_cubit.dart';
 | 
					 | 
				
			||||||
export 'features/form_data_impl/form_data_cubit_impl.dart';
 | 
					 | 
				
			||||||
export 'features/widgets/input_builder.dart';
 | 
					 | 
				
			||||||
export 'features/widgets/input_builder_metadata.dart';
 | 
					 | 
				
			||||||
export 'features/widgets/input_builder_text_controller.dart';
 | 
					 | 
				
			||||||
export 'features/widgets/submit_builder.dart';
 | 
					 | 
				
			||||||
@ -14,7 +14,7 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export 'core/core.dart';
 | 
					export 'cubit/form_data_cubit.dart';
 | 
				
			||||||
export 'data/data.dart';
 | 
					export 'enums/enums.dart';
 | 
				
			||||||
export 'domain/domain.dart';
 | 
					export 'form/form.dart';
 | 
				
			||||||
export 'presentation/presentation.dart';
 | 
					export 'validators/validators.dart';
 | 
				
			||||||
 | 
				
			|||||||
@ -14,10 +14,7 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.dart';
 | 
					import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_validators/form_validator.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template every}
 | 
					/// {@template every}
 | 
				
			||||||
/// Check and validate every input of a form
 | 
					/// Check and validate every input of a form
 | 
				
			||||||
@ -27,13 +24,18 @@ class EveryInputValidator extends FormValidator {
 | 
				
			|||||||
  const EveryInputValidator() : super();
 | 
					  const EveryInputValidator() : super();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  FormStatus validate(WyattForm form) {
 | 
					  FormStatus validate(FormData form) {
 | 
				
			||||||
    if (isPure(form)) {
 | 
					    if (isPure(form)) {
 | 
				
			||||||
      return FormStatus.pure;
 | 
					      return FormStatus.pure;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final validators = form.asValidatorList<dynamic, ValidationError>();
 | 
					    return rawValidate(form.validators<dynamic, ValidationError>());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  FormStatus rawValidate(
 | 
				
			||||||
 | 
					    List<FormInputValidator<dynamic, ValidationError>> validators,
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
    if (validators.any((validator) => validator.valid == false)) {
 | 
					    if (validators.any((validator) => validator.valid == false)) {
 | 
				
			||||||
      return FormStatus.invalid;
 | 
					      return FormStatus.invalid;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -14,21 +14,20 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
part of 'form_input_validator.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/validation_error.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_form_bloc/src/form/form.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template regex_validator}
 | 
					/// {@template regex_validator}
 | 
				
			||||||
/// Abstract regex validator for form input.
 | 
					/// Abstract regex validator for form input.
 | 
				
			||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class RegexValidator<E extends ValidationError>
 | 
					abstract class RegexValidator<E extends ValidationError>
 | 
				
			||||||
    extends FormInputValidator<String?, E> {
 | 
					    extends FormInputValidator<String, E> {
 | 
				
			||||||
  const RegexValidator.pure(super.value) : super.pure();
 | 
					  const RegexValidator.pure() : super.pure('');
 | 
				
			||||||
  const RegexValidator.dirty(super.value) : super.dirty();
 | 
					  const RegexValidator.dirty([super.value = '']) : super.dirty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  RegExp get regex;
 | 
					  RegExp get regex;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// If the value is **not** null, but empty.
 | 
					  /// If the value is **not** null, but empty.
 | 
				
			||||||
  E get onEmpty;
 | 
					  E get onEmpty;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// If value does not conform to regex.
 | 
					  /// If value does not conform to regex.
 | 
				
			||||||
  E get onError;
 | 
					  E get onError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -14,12 +14,13 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
part of 'form_input_validator.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/validation_error.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_form_bloc/src/form/form.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class TextValidator<E extends ValidationError>
 | 
					abstract class TextValidator<E extends ValidationError>
 | 
				
			||||||
    extends FormInputValidator<String?, E> {
 | 
					    extends FormInputValidator<String, E> {
 | 
				
			||||||
  const TextValidator.pure(super.value) : super.pure();
 | 
					  const TextValidator.pure() : super.pure('');
 | 
				
			||||||
  const TextValidator.dirty(super.value) : super.dirty();
 | 
					  const TextValidator.dirty([super.value = '']) : super.dirty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// If the value is **not** null, but empty.
 | 
					  /// If the value is **not** null, but empty.
 | 
				
			||||||
  E get onEmpty;
 | 
					  E get onEmpty;
 | 
				
			||||||
@ -14,13 +14,13 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/enums.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					import 'package:wyatt_form_bloc/src/form/form.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template boolean}
 | 
					/// {@template boolean}
 | 
				
			||||||
/// Form input for a bool input
 | 
					/// Form input for a bool input
 | 
				
			||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
class Boolean extends NullableValidator<bool, ValidationStandardError> {
 | 
					class Boolean extends FormInputValidator<bool, ValidationStandardError> {
 | 
				
			||||||
  /// {@macro boolean}
 | 
					  /// {@macro boolean}
 | 
				
			||||||
  const Boolean.pure({bool? defaultValue = false})
 | 
					  const Boolean.pure({bool? defaultValue = false})
 | 
				
			||||||
      : super.pure(defaultValue ?? false);
 | 
					      : super.pure(defaultValue ?? false);
 | 
				
			||||||
@ -28,11 +28,7 @@ class Boolean extends NullableValidator<bool, ValidationStandardError> {
 | 
				
			|||||||
  /// {@macro boolean}
 | 
					  /// {@macro boolean}
 | 
				
			||||||
  const Boolean.dirty({bool value = false}) : super.dirty(value);
 | 
					  const Boolean.dirty({bool value = false}) : super.dirty(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  ValidationStandardError get onNull => ValidationStandardError.invalid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  ValidationStandardError? validator(bool? value) =>
 | 
					  ValidationStandardError? validator(bool? value) =>
 | 
				
			||||||
      value != null ? null : onNull;
 | 
					      value != null ? null : ValidationStandardError.invalid;
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -14,31 +14,25 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/enums.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					import 'package:wyatt_form_bloc/src/form/form.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template confirmed_password}
 | 
					/// {@template confirmed_password}
 | 
				
			||||||
/// Form input for a confirmed password input.
 | 
					/// Form input for a confirmed password input.
 | 
				
			||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
class ConfirmedPassword
 | 
					class ConfirmedPassword
 | 
				
			||||||
    extends EqualityValidator<String, ValidationStandardError> {
 | 
					    extends FormInputValidator<String, ValidationStandardError> {
 | 
				
			||||||
  /// {@macro confirmed_password}
 | 
					  /// {@macro confirmed_password}
 | 
				
			||||||
  const ConfirmedPassword.pure({this.password = '', String? defaultValue})
 | 
					  const ConfirmedPassword.pure({this.password = ''}) : super.pure('');
 | 
				
			||||||
      : super.pure(defaultValue);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro confirmed_password}
 | 
					  /// {@macro confirmed_password}
 | 
				
			||||||
  const ConfirmedPassword.dirty({required this.password, String? value})
 | 
					  const ConfirmedPassword.dirty({required this.password, String value = ''})
 | 
				
			||||||
      : super.dirty(value);
 | 
					      : super.dirty(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// The original password.
 | 
					  /// The original password.
 | 
				
			||||||
  final String password;
 | 
					  final String password;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  String get another => password;
 | 
					  ValidationStandardError? validator(String? value) =>
 | 
				
			||||||
 | 
					      password == value ? null : ValidationStandardError.invalid;
 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  ValidationStandardError get onNotEqual => ValidationStandardError.notEqual;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  ValidationStandardError get onNull => ValidationStandardError.invalid;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -14,15 +14,15 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/enums.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template email}
 | 
					/// {@template email}
 | 
				
			||||||
/// Form input for an email input.
 | 
					/// Form input for an email input.
 | 
				
			||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
class Email extends RegexValidator<ValidationStandardError> {
 | 
					class Email extends RegexValidator<ValidationStandardError> {
 | 
				
			||||||
  /// {@macro email}
 | 
					  /// {@macro email}
 | 
				
			||||||
  const Email.pure([super.value]) : super.pure();
 | 
					  const Email.pure() : super.pure();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro email}
 | 
					  /// {@macro email}
 | 
				
			||||||
  const Email.dirty([super.value = '']) : super.dirty();
 | 
					  const Email.dirty([super.value = '']) : super.dirty();
 | 
				
			||||||
@ -14,16 +14,19 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/validation_error.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					import 'package:wyatt_form_bloc/src/validators/inputs/base/text_validator.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_validators/form_validator.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OnlyRequiredInputValidator extends FormValidator {
 | 
					class EnumValidator<E> extends TextValidator<ValidationStandardError> {
 | 
				
			||||||
  const OnlyRequiredInputValidator() : super();
 | 
					  /// {@macro text_string}
 | 
				
			||||||
 | 
					  const EnumValidator.pure() : super.pure();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// {@macro text_string}
 | 
				
			||||||
 | 
					  EnumValidator.dirty(E value) : super.dirty(value.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  FormStatus validate(WyattForm form) {
 | 
					  ValidationStandardError get onEmpty => ValidationStandardError.empty;
 | 
				
			||||||
    // TODO(hpcl): use metadata to check if input is required or not.
 | 
					
 | 
				
			||||||
    return FormStatus.valid;
 | 
					  @override
 | 
				
			||||||
  }
 | 
					  ValidationStandardError get onNull => ValidationStandardError.invalid;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										39
									
								
								packages/wyatt_form_bloc/lib/src/validators/inputs/iban.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								packages/wyatt_form_bloc/lib/src/validators/inputs/iban.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/enums/enums.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template iban}
 | 
				
			||||||
 | 
					/// Form input for an IBAN input.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
 | 
					class Iban extends RegexValidator<ValidationStandardError> {
 | 
				
			||||||
 | 
					  /// {@macro iban}
 | 
				
			||||||
 | 
					  const Iban.pure() : super.pure();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// {@macro iban}
 | 
				
			||||||
 | 
					  const Iban.dirty([super.value = '']) : super.dirty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  ValidationStandardError get onEmpty => ValidationStandardError.empty;
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  ValidationStandardError get onError => ValidationStandardError.invalid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  RegExp get regex => 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}))$',
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					// 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/enums/enums.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_form_bloc/src/form/form.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template list_option}
 | 
				
			||||||
 | 
					/// Form input for a list input
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
 | 
					class ListOption<T>
 | 
				
			||||||
 | 
					    extends FormInputValidator<List<T>, ValidationStandardError> {
 | 
				
			||||||
 | 
					  /// {@macro list_option}
 | 
				
			||||||
 | 
					  const ListOption.pure({List<T>? defaultValue})
 | 
				
			||||||
 | 
					      : super.pure(defaultValue ?? const []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// {@macro list_option}
 | 
				
			||||||
 | 
					  const ListOption.dirty({List<T>? value}) : super.dirty(value ?? const []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ListOption<T> select(T? v) {
 | 
				
			||||||
 | 
					    if (v == null) {
 | 
				
			||||||
 | 
					      return this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (value.contains(v)) {
 | 
				
			||||||
 | 
					      final List<T> newValue = List.from(value)..remove(v);
 | 
				
			||||||
 | 
					      return ListOption<T>.dirty(value: newValue);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      final List<T> newValue = List.from(value)..add(v);
 | 
				
			||||||
 | 
					      return ListOption<T>.dirty(value: newValue);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  ValidationStandardError? validator(List<T>? value) =>
 | 
				
			||||||
 | 
					      value?.isNotEmpty ?? false == true
 | 
				
			||||||
 | 
					          ? null
 | 
				
			||||||
 | 
					          : ValidationStandardError.invalid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -14,15 +14,15 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/enums.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template name}
 | 
					/// {@template name}
 | 
				
			||||||
/// Form input for a name input.
 | 
					/// Form input for a name input.
 | 
				
			||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
class Name extends RegexValidator<ValidationStandardError> {
 | 
					class Name extends RegexValidator<ValidationStandardError> {
 | 
				
			||||||
  /// {@macro name}
 | 
					  /// {@macro name}
 | 
				
			||||||
  const Name.pure([super.value]) : super.pure();
 | 
					  const Name.pure() : super.pure();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro name}
 | 
					  /// {@macro name}
 | 
				
			||||||
  const Name.dirty([super.value = '']) : super.dirty();
 | 
					  const Name.dirty([super.value = '']) : super.dirty();
 | 
				
			||||||
@ -14,18 +14,18 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/enums.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template password}
 | 
					/// {@template password}
 | 
				
			||||||
/// Form input for a password input.
 | 
					/// Form input for a password input.
 | 
				
			||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
class Password extends RegexValidator<ValidationStandardError> {
 | 
					class Password extends RegexValidator<ValidationStandardError> {
 | 
				
			||||||
  /// {@macro password}
 | 
					  /// {@macro password}
 | 
				
			||||||
  const Password.pure([super.value]) : super.pure();
 | 
					  const Password.pure() : super.pure();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro password}
 | 
					  /// {@macro password}
 | 
				
			||||||
  const Password.dirty([super.value]) : super.dirty();
 | 
					  const Password.dirty([super.value = '']) : super.dirty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  ValidationStandardError get onEmpty => ValidationStandardError.empty;
 | 
					  ValidationStandardError get onEmpty => ValidationStandardError.empty;
 | 
				
			||||||
@ -14,15 +14,15 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/enums.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template phone}
 | 
					/// {@template phone}
 | 
				
			||||||
/// Form input for a phone input.
 | 
					/// Form input for a phone input.
 | 
				
			||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
class Phone extends RegexValidator<ValidationStandardError> {
 | 
					class Phone extends RegexValidator<ValidationStandardError> {
 | 
				
			||||||
  /// {@macro phone}
 | 
					  /// {@macro phone}
 | 
				
			||||||
  const Phone.pure([super.value]) : super.pure();
 | 
					  const Phone.pure() : super.pure();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro phone}
 | 
					  /// {@macro phone}
 | 
				
			||||||
  const Phone.dirty([super.value = '']) : super.dirty();
 | 
					  const Phone.dirty([super.value = '']) : super.dirty();
 | 
				
			||||||
@ -14,24 +14,24 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
part of 'form_input_validator.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/enums.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template nullable_validator}
 | 
					/// {@template siren}
 | 
				
			||||||
/// Abstract nullable validator not validating null values.
 | 
					/// Form input for a SIREN input.
 | 
				
			||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class NullableValidator<O extends Object, E extends ValidationError>
 | 
					class Siren extends RegexValidator<ValidationStandardError> {
 | 
				
			||||||
    extends FormInputValidator<O?, E> {
 | 
					  /// {@macro siren}
 | 
				
			||||||
  const NullableValidator.pure(super.value) : super.pure();
 | 
					  const Siren.pure() : super.pure();
 | 
				
			||||||
  const NullableValidator.dirty(super.value) : super.dirty();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// If value is null.
 | 
					  /// {@macro siren}
 | 
				
			||||||
  E get onNull;
 | 
					  const Siren.dirty([super.value = '']) : super.dirty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  E? validator(O? value) {
 | 
					  ValidationStandardError get onEmpty => ValidationStandardError.empty;
 | 
				
			||||||
    if (value == null) {
 | 
					  @override
 | 
				
			||||||
      return onNull;
 | 
					  ValidationStandardError get onError => ValidationStandardError.invalid;
 | 
				
			||||||
    }
 | 
					
 | 
				
			||||||
    return null;
 | 
					  @override
 | 
				
			||||||
  }
 | 
					  RegExp get regex => RegExp(r'(\d{9}|\d{3}[ ]\d{3}[ ]\d{3})$');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -14,15 +14,15 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
 | 
					import 'package:wyatt_form_bloc/src/enums/enums.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
 | 
					import 'package:wyatt_form_bloc/src/validators/inputs/base/text_validator.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template text_string}
 | 
					/// {@template text_string}
 | 
				
			||||||
/// Form input for a text input
 | 
					/// Form input for a text input
 | 
				
			||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
class TextString extends TextValidator<ValidationStandardError> {
 | 
					class TextString extends TextValidator<ValidationStandardError> {
 | 
				
			||||||
  /// {@macro text_string}
 | 
					  /// {@macro text_string}
 | 
				
			||||||
  const TextString.pure([super.value]) : super.pure();
 | 
					  const TextString.pure() : super.pure();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro text_string}
 | 
					  /// {@macro text_string}
 | 
				
			||||||
  const TextString.dirty([super.value = '']) : super.dirty();
 | 
					  const TextString.dirty([super.value = '']) : super.dirty();
 | 
				
			||||||
@ -14,17 +14,17 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'dart:convert';
 | 
					export 'form/every_input_validator.dart';
 | 
				
			||||||
 | 
					export 'inputs/base/regex_validator.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/data/form_encoders/form_map_encoder.dart';
 | 
					export 'inputs/base/text_validator.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
 | 
					export 'inputs/boolean.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/src/domain/form_encoders/form_encoder.dart';
 | 
					export 'inputs/confirmed_password.dart';
 | 
				
			||||||
 | 
					export 'inputs/email.dart';
 | 
				
			||||||
class FormJsonEncoder extends FormEncoder<String> {
 | 
					export 'inputs/enum_validator.dart';
 | 
				
			||||||
  @override
 | 
					export 'inputs/iban.dart';
 | 
				
			||||||
  String encode(WyattForm form) {
 | 
					export 'inputs/list_option.dart';
 | 
				
			||||||
    final mapEncoder = FormMapEncoder();
 | 
					export 'inputs/name.dart';
 | 
				
			||||||
    final map = mapEncoder.encode(form);
 | 
					export 'inputs/password.dart';
 | 
				
			||||||
    return jsonEncode(map);
 | 
					export 'inputs/phone.dart';
 | 
				
			||||||
  }
 | 
					export 'inputs/siren.dart';
 | 
				
			||||||
}
 | 
					export 'inputs/text_string.dart';
 | 
				
			||||||
@ -3,33 +3,15 @@ description: Manage forms in Dart & Flutter with Bloc
 | 
				
			|||||||
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_form_bloc
 | 
					repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_form_bloc
 | 
				
			||||||
version: 0.0.6
 | 
					version: 0.0.6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
environment:
 | 
					environment:
 | 
				
			||||||
  sdk: ">=2.17.2 <3.0.0"
 | 
					  sdk: '>=2.17.2 <3.0.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dependencies:
 | 
					dependencies:
 | 
				
			||||||
  flutter:
 | 
					  bloc: ^8.1.0
 | 
				
			||||||
    sdk: flutter
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  flutter_bloc: ^8.1.0
 | 
					 | 
				
			||||||
  equatable: ^2.0.5
 | 
					  equatable: ^2.0.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  wyatt_architecture:
 | 
					 | 
				
			||||||
    git:
 | 
					 | 
				
			||||||
      url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
 | 
					 | 
				
			||||||
      ref: wyatt_architecture-v0.0.2-dev.0
 | 
					 | 
				
			||||||
      path: packages/wyatt_architecture
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  wyatt_type_utils:
 | 
					 | 
				
			||||||
    git:
 | 
					 | 
				
			||||||
      url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
 | 
					 | 
				
			||||||
      ref: wyatt_type_utils-v0.0.3+1
 | 
					 | 
				
			||||||
      path: packages/wyatt_type_utils
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
dev_dependencies:
 | 
					dev_dependencies:
 | 
				
			||||||
  flutter_test:
 | 
					  test: ^1.21.4
 | 
				
			||||||
    sdk: flutter
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  wyatt_analysis:
 | 
					  wyatt_analysis:
 | 
				
			||||||
    git:
 | 
					    git:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user