auth/wyatt_arch_migration #25
| @ -32,3 +32,4 @@ export 'input_validators/name.dart'; | |||||||
| export 'input_validators/password.dart'; | export 'input_validators/password.dart'; | ||||||
| export 'input_validators/phone.dart'; | export 'input_validators/phone.dart'; | ||||||
| export 'input_validators/text_string.dart'; | export 'input_validators/text_string.dart'; | ||||||
|  | export 'repositories/form_repository_impl.dart'; | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ class WyattFormImpl extends WyattForm { | |||||||
|       FormInput<dynamic, FormInputValidator<dynamic, ValidationError>, |       FormInput<dynamic, FormInputValidator<dynamic, ValidationError>, | ||||||
|           dynamic>> _inputs; |           dynamic>> _inputs; | ||||||
|   final FormValidator _validator; |   final FormValidator _validator; | ||||||
|  |   final String _name; | ||||||
| 
 | 
 | ||||||
|   late List< |   late List< | ||||||
|       FormInput<dynamic, FormInputValidator<dynamic, ValidationError>, |       FormInput<dynamic, FormInputValidator<dynamic, ValidationError>, | ||||||
| @ -37,8 +38,10 @@ class WyattFormImpl extends WyattForm { | |||||||
| 
 | 
 | ||||||
|   WyattFormImpl( |   WyattFormImpl( | ||||||
|     this._inputs, { |     this._inputs, { | ||||||
|  |     required String name, | ||||||
|     FormValidator validationStrategy = const EveryInputValidator(), |     FormValidator validationStrategy = const EveryInputValidator(), | ||||||
|   }) : _validator = validationStrategy { |   })  : _name = name, | ||||||
|  |         _validator = validationStrategy { | ||||||
|     _inputsInitial = _inputs.map((input) => input.clone()).toList(); |     _inputsInitial = _inputs.map((input) => input.clone()).toList(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -50,6 +53,9 @@ class WyattFormImpl extends WyattForm { | |||||||
|   @override |   @override | ||||||
|   FormValidator get formValidationStrategy => _validator; |   FormValidator get formValidationStrategy => _validator; | ||||||
| 
 | 
 | ||||||
|  |   @override | ||||||
|  |   String get name => _name; | ||||||
|  | 
 | ||||||
|   @override |   @override | ||||||
|   bool containsKey(String key) => inputs.any((input) => input.key == key); |   bool containsKey(String key) => inputs.any((input) => input.key == key); | ||||||
| 
 | 
 | ||||||
| @ -94,22 +100,24 @@ class WyattFormImpl extends WyattForm { | |||||||
|   FormStatus validate() => formValidationStrategy.validate(this); |   FormStatus validate() => formValidationStrategy.validate(this); | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   WyattForm clone() => WyattFormImpl( |   WyattForm clone() { | ||||||
|  |     final clone = WyattFormImpl( | ||||||
|       _inputs.map((input) => input.clone()).toList(), |       _inputs.map((input) => input.clone()).toList(), | ||||||
|  |       name: _name, | ||||||
|       validationStrategy: formValidationStrategy, |       validationStrategy: formValidationStrategy, | ||||||
|       ); |     ).._inputsInitial = _inputsInitial; | ||||||
|  |     return clone; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   WyattForm reset() => WyattFormImpl( |   WyattForm reset() { | ||||||
|  |     final newForm = WyattFormImpl( | ||||||
|       _inputsInitial, |       _inputsInitial, | ||||||
|  |       name: _name, | ||||||
|       validationStrategy: formValidationStrategy, |       validationStrategy: formValidationStrategy, | ||||||
|       ); |     ).._inputsInitial = _inputsInitial; | ||||||
| 
 |     return newForm; | ||||||
|   @override |   } | ||||||
|   bool? get stringify => true; |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   List<Object?> get props => _inputs; |  | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   void updateMetadata<Extra>(String key, FormInputMetadata<Extra> metadata) { |   void updateMetadata<Extra>(String key, FormInputMetadata<Extra> metadata) { | ||||||
| @ -133,4 +141,11 @@ class WyattFormImpl extends WyattForm { | |||||||
|   @override |   @override | ||||||
|   WyattForm operationWith(FormOperation operation, WyattForm other) => |   WyattForm operationWith(FormOperation operation, WyattForm other) => | ||||||
|       operation.call(this, other); |       operation.call(this, other); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   List<Object?> get props => [_inputs, _name, _validator]; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   String toString() => | ||||||
|  |       'WyattForm(name: $name, validation: ${_validator.runtimeType}, inputs: $inputs)'; | ||||||
| } | } | ||||||
|  | |||||||
| @ -44,6 +44,7 @@ class FormDifference extends FormOperation { | |||||||
| 
 | 
 | ||||||
|     return WyattFormImpl( |     return WyattFormImpl( | ||||||
|       inputs, |       inputs, | ||||||
|  |       name: a.name, | ||||||
|       validationStrategy: a.formValidationStrategy, |       validationStrategy: a.formValidationStrategy, | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -38,6 +38,7 @@ class FormIntersection extends FormOperation { | |||||||
| 
 | 
 | ||||||
|     return WyattFormImpl( |     return WyattFormImpl( | ||||||
|       inputs, |       inputs, | ||||||
|  |       name: a.name, | ||||||
|       validationStrategy: a.formValidationStrategy, |       validationStrategy: a.formValidationStrategy, | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -42,6 +42,7 @@ class FormUnion extends FormOperation { | |||||||
| 
 | 
 | ||||||
|     return WyattFormImpl( |     return WyattFormImpl( | ||||||
|       inputs, |       inputs, | ||||||
|  |       name: a.name, | ||||||
|       validationStrategy: a.formValidationStrategy, |       validationStrategy: a.formValidationStrategy, | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -0,0 +1,60 @@ | |||||||
|  | // 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); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -21,3 +21,4 @@ export 'form_encoders/form_encoder.dart'; | |||||||
| export 'form_operations/form_operation.dart'; | export 'form_operations/form_operation.dart'; | ||||||
| export 'form_validators/form_validator.dart'; | export 'form_validators/form_validator.dart'; | ||||||
| export 'input_validators/form_input_validator.dart'; | export 'input_validators/form_input_validator.dart'; | ||||||
|  | export 'repositories/form_repository.dart'; | ||||||
|  | |||||||
| @ -59,8 +59,9 @@ class FormInput< | |||||||
|       ); |       ); | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   bool? get stringify => true; |   List<Object?> get props => [key, validator, metadata]; | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   List<Object?> get props => [key, validator, metadata]; |   String toString() => | ||||||
|  |       'FormInput(name: $name, value: ${validator.value}, status: ${validator.status.name}'; | ||||||
| } | } | ||||||
|  | |||||||
| @ -28,6 +28,7 @@ import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator | |||||||
| abstract class WyattForm extends Equatable { | abstract class WyattForm extends Equatable { | ||||||
|   List<FormInput> get inputs; |   List<FormInput> get inputs; | ||||||
|   FormValidator get formValidationStrategy; |   FormValidator get formValidationStrategy; | ||||||
|  |   String get name; | ||||||
| 
 | 
 | ||||||
|   bool containsKey(String key); |   bool containsKey(String key); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -19,5 +19,6 @@ import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart'; | |||||||
| // ignore: one_member_abstracts | // ignore: one_member_abstracts | ||||||
| abstract class FormOperation { | abstract class FormOperation { | ||||||
|   const FormOperation(); |   const FormOperation(); | ||||||
|  |   // TODO(hpcl): handle operation on `initialInputs` | ||||||
|   WyattForm call(WyattForm a, WyattForm b); |   WyattForm call(WyattForm a, WyattForm b); | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,11 +18,11 @@ import 'package:equatable/equatable.dart'; | |||||||
| import 'package:wyatt_form_bloc/src/core/enums/form_input_status.dart'; | import 'package:wyatt_form_bloc/src/core/enums/form_input_status.dart'; | ||||||
| import 'package:wyatt_form_bloc/src/core/enums/validation_error.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 'regex_validator.dart'; | ||||||
| part 'text_validator.dart'; | part 'text_validator.dart'; | ||||||
| part 'nullable_validator.dart'; |  | ||||||
| part 'equality_validator.dart'; |  | ||||||
| part 'any_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. | ||||||
|  | |||||||
| @ -0,0 +1,27 @@ | |||||||
|  | // Copyright (C) 2022 WYATT GROUP | ||||||
|  | // Please see the AUTHORS file for details. | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // any later version. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||||
|  | 
 | ||||||
|  | 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); | ||||||
|  | } | ||||||
| @ -29,6 +29,8 @@ part 'form_data_state.dart'; | |||||||
| abstract class FormDataCubit<State extends FormDataState> extends Cubit<State> { | abstract class FormDataCubit<State extends FormDataState> extends Cubit<State> { | ||||||
|   FormDataCubit(super.initialState) : super(); |   FormDataCubit(super.initialState) : super(); | ||||||
| 
 | 
 | ||||||
|  |   String get formName; | ||||||
|  | 
 | ||||||
|   FutureOr<void> dataChanged<Value>( |   FutureOr<void> dataChanged<Value>( | ||||||
|     String key, |     String key, | ||||||
|     FormInputValidator<Value, ValidationError> dirtyValue, |     FormInputValidator<Value, ValidationError> dirtyValue, | ||||||
|  | |||||||
| @ -21,22 +21,31 @@ 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/core/enums/validation_error.dart'; | ||||||
| import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.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/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'; | import 'package:wyatt_form_bloc/src/presentation/features/form_data/form_data_cubit.dart'; | ||||||
| 
 | 
 | ||||||
| part 'form_data_state_impl.dart'; | part 'form_data_state_impl.dart'; | ||||||
| 
 | 
 | ||||||
| abstract class FormDataCubitImpl extends FormDataCubit<FormDataStateImpl> { | abstract class FormDataCubitImpl extends FormDataCubit<FormDataStateImpl> { | ||||||
|   FormDataCubitImpl(WyattForm form) : super(FormDataStateImpl(form: form)); |   final FormRepository _formRepository; | ||||||
|  |   final String _formName; | ||||||
|  | 
 | ||||||
|  |   FormDataCubitImpl(this._formRepository, this._formName) | ||||||
|  |       : super(FormDataStateImpl(form: _formRepository.accessForm(_formName))); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   String get formName => _formName; | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   FutureOr<void> dataChanged<Value>( |   FutureOr<void> dataChanged<Value>( | ||||||
|     String key, |     String key, | ||||||
|     FormInputValidator<Value, ValidationError> dirtyValue, |     FormInputValidator<Value, ValidationError> dirtyValue, | ||||||
|   ) { |   ) { | ||||||
|     final form = state.form.clone(); |     final form = _formRepository.accessForm(_formName).clone(); | ||||||
| 
 | 
 | ||||||
|     try { |     try { | ||||||
|       form.updateValidator(key, dirtyValue); |       form.updateValidator(key, dirtyValue); | ||||||
|  |       _formRepository.updateForm(form); | ||||||
|     } catch (e) { |     } catch (e) { | ||||||
|       rethrow; |       rethrow; | ||||||
|     } |     } | ||||||
| @ -54,7 +63,9 @@ abstract class FormDataCubitImpl extends FormDataCubit<FormDataStateImpl> { | |||||||
|     WyattForm form, { |     WyattForm form, { | ||||||
|     SetOperation operation = SetOperation.replace, |     SetOperation operation = SetOperation.replace, | ||||||
|   }) { |   }) { | ||||||
|     final WyattForm newForm = operation.operation.call(state.form, form); |     final WyattForm current = _formRepository.accessForm(_formName).clone(); | ||||||
|  |     final WyattForm newForm = operation.operation.call(current, form); | ||||||
|  |     _formRepository.updateForm(newForm); | ||||||
| 
 | 
 | ||||||
|     emit( |     emit( | ||||||
|       state.copyWith( |       state.copyWith( | ||||||
| @ -67,6 +78,7 @@ abstract class FormDataCubitImpl extends FormDataCubit<FormDataStateImpl> { | |||||||
|   @override |   @override | ||||||
|   FutureOr<void> reset() { |   FutureOr<void> reset() { | ||||||
|     final form = state.form.reset(); |     final form = state.form.reset(); | ||||||
|  |     _formRepository.updateForm(form); | ||||||
|     emit( |     emit( | ||||||
|       state.copyWith( |       state.copyWith( | ||||||
|         form: form, |         form: form, | ||||||
|  | |||||||
| @ -35,8 +35,9 @@ class FormDataStateImpl extends FormDataState { | |||||||
|       ); |       ); | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   bool? get stringify => true; |   List<Object?> get props => [status, form, errorMessage]; | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   List<Object?> get props => [status, form, errorMessage]; |   String toString() => | ||||||
|  |       'FormDataSate(status: ${status.name} ${(errorMessage != null) ? " [$errorMessage]" : ""}, $form'; | ||||||
| } | } | ||||||
|  | |||||||
| @ -35,7 +35,7 @@ class InputBuilder<Cubit extends FormDataCubit> extends StatelessWidget { | |||||||
|   Widget build(BuildContext context) => |   Widget build(BuildContext context) => | ||||||
|       BlocBuilder<Cubit, FormDataState>( |       BlocBuilder<Cubit, FormDataState>( | ||||||
|         builder: (context, state) { |         builder: (context, state) { | ||||||
|           final cubit = context.read<Cubit>(); |           final cubit = context.watch<Cubit>(); | ||||||
|           final inputValid = state.form.validatorOf(field).valid; |           final inputValid = state.form.validatorOf(field).valid; | ||||||
|           return builder.call(context, cubit, state, field, inputValid); |           return builder.call(context, cubit, state, field, inputValid); | ||||||
|         }, |         }, | ||||||
|  | |||||||
| @ -0,0 +1,75 @@ | |||||||
|  | // 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, | ||||||
|  |         ); | ||||||
|  |       }, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -18,4 +18,5 @@ export 'features/form_data/form_data_cubit.dart'; | |||||||
| export 'features/form_data_impl/form_data_cubit_impl.dart'; | export 'features/form_data_impl/form_data_cubit_impl.dart'; | ||||||
| export 'features/widgets/input_builder.dart'; | export 'features/widgets/input_builder.dart'; | ||||||
| export 'features/widgets/input_builder_metadata.dart'; | export 'features/widgets/input_builder_metadata.dart'; | ||||||
|  | export 'features/widgets/input_builder_text_controller.dart'; | ||||||
| export 'features/widgets/submit_builder.dart'; | export 'features/widgets/submit_builder.dart'; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user