doc: update example

This commit is contained in:
2022-07-10 21:13:43 +02:00
parent d0f1d07363
commit 741f05e1be
13 changed files with 233 additions and 59 deletions
@@ -16,31 +16,37 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:form_bloc_example/app/metadata.dart';
import 'package:form_bloc_example/constants.dart';
import 'package:form_bloc_example/cubit/custom_form_cubit.dart';
import 'package:form_bloc_example/sign_up/sign_up_page.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
const blue = Metadata(category: Category.perso);
const red = Metadata(category: Category.business);
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
static List<FormEntry> getNormalEntries() {
static List<FormInput> getNormalEntries() {
return const [
FormEntry(formFieldName, Name.pure()),
FormEntry(formFieldEmail, Email.pure()),
FormEntry(formFieldPhone, Phone.pure()),
FormEntry(
FormInput(formFieldName, Name.pure(), metadata: FormInputMetadata<Metadata>(extra: blue)),
FormInput(formFieldEmail, Email.pure(), metadata: FormInputMetadata<Metadata>(extra: blue)),
FormInput(formFieldPhone, Phone.pure(), metadata: FormInputMetadata<Metadata>(extra: red)),
FormInput(
formFieldList, ListOption<String>.pure(defaultValue: ['checkbox3'])),
FormEntry(formFieldRadio, TextString.pure()),
FormEntry(formFieldPro, Boolean.pure(), name: 'business'),
FormEntry(formFieldHidden, Boolean.pure(), export: false),
FormInput(formFieldRadio, TextString.pure()),
FormInput(formFieldPro, Boolean.pure(),
metadata: FormInputMetadata<Metadata>(name: 'business')),
FormInput(formFieldHidden, Boolean.pure(),
metadata: FormInputMetadata<Metadata>(export: false, extra: blue)),
];
}
static List<FormEntry> getBusinessEntries() {
static List<FormInput> getBusinessEntries() {
const entries = [
FormEntry(formFieldSiren, Siren.pure()),
FormEntry(formFieldIban, Iban.pure()),
FormInput(formFieldSiren, Siren.pure()),
FormInput(formFieldIban, Iban.pure()),
];
return getNormalEntries() + entries;
}
@@ -55,7 +61,7 @@ class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
FormDataCubit _formCubit = CustomFormCubit(entries: getNormalFormData());
FormDataCubit _formCubit = CustomFormCubit(inputs: getNormalFormData());
return BlocProvider(
create: (context) => _formCubit,
@@ -1,3 +1,4 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
@@ -14,9 +15,20 @@
// 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 'custom_form_cubit.dart';
enum Category {
perso,
business
}
@immutable
abstract class CustomFormState {}
class Metadata {
final Category category;
class CustomFormInitial extends CustomFormState {}
const Metadata({
required this.category,
});
@override
String toString() {
return category.toString();
}
}
@@ -16,18 +16,15 @@
import 'dart:developer';
import 'package:meta/meta.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
part 'custom_form_state.dart';
class CustomFormCubit extends FormDataCubit {
CustomFormCubit({required FormData entries}) : super(entries: entries);
CustomFormCubit({required FormData inputs}) : super(inputs: inputs);
@override
Future<void> submitForm() {
log(state.data.toMap().toString());
return Future.value();
}
}
@@ -19,35 +19,83 @@ import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:form_bloc_example/app/app.dart';
import 'package:form_bloc_example/app/metadata.dart';
import 'package:form_bloc_example/constants.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
class CategoryIndicator extends StatelessWidget {
const CategoryIndicator(
{Key? key, required this.field, required this.builder})
: super(key: key);
final String field;
final Function(BuildContext context, FormDataState state) builder;
Color computeColor(Metadata meta) {
switch (meta.category) {
case Category.perso:
return Colors.blue;
case Category.business:
return Colors.red;
}
}
@override
Widget build(BuildContext context) {
return BlocBuilder<FormDataCubit, FormDataState>(
builder: ((context, state) {
final meta = state.data.metadataOf(field).extra as Metadata;
final color = computeColor(meta);
return Row(
children: [
Container(
height: 8,
width: 8,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(8),
),
),
const SizedBox(width: 20,),
SizedBox(
width: MediaQuery.of(context).size.width - 45,
child: builder(context, state),
)
],
);
}),
);
}
}
class _NameInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<FormDataCubit, FormDataState>(
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.input(formFieldName).invalid ? 'invalid name' : null,
),
);
},
);
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 BlocBuilder<FormDataCubit, FormDataState>(
return CategoryIndicator(
field: formFieldEmail,
builder: (context, state) {
return TextField(
onChanged: (email) => context
@@ -57,9 +105,8 @@ class _EmailInput extends StatelessWidget {
decoration: InputDecoration(
labelText: 'email',
helperText: '',
errorText: state.data.input(formFieldEmail).invalid
? 'invalid email'
: null,
errorText:
state.data.isNotValid(formFieldEmail) ? 'invalid email' : null,
),
);
},
@@ -70,7 +117,8 @@ class _EmailInput extends StatelessWidget {
class _PhoneInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<FormDataCubit, FormDataState>(
return CategoryIndicator(
field: formFieldPhone,
builder: (context, state) {
return TextField(
onChanged: (phone) => context
@@ -80,9 +128,8 @@ class _PhoneInput extends StatelessWidget {
decoration: InputDecoration(
labelText: 'phone',
helperText: '',
errorText: state.data.input(formFieldPhone).invalid
? 'invalid phone'
: null,
errorText:
state.data.isNotValid(formFieldPhone) ? 'invalid phone' : null,
),
);
},
@@ -93,7 +140,8 @@ class _PhoneInput extends StatelessWidget {
class _SirenInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<FormDataCubit, FormDataState>(
return CategoryIndicator(
field: formFieldName,
builder: (context, state) {
return TextField(
onChanged: (siren) => context
@@ -103,9 +151,8 @@ class _SirenInput extends StatelessWidget {
decoration: InputDecoration(
labelText: 'siren',
helperText: '',
errorText: state.data.input(formFieldSiren).invalid
? 'invalid SIREN'
: null,
errorText:
state.data.isNotValid(formFieldSiren) ? 'invalid SIREN' : null,
),
);
},
@@ -127,7 +174,7 @@ class _IbanInput extends StatelessWidget {
labelText: 'iban',
helperText: '',
errorText:
state.data.input(formFieldIban).invalid ? 'invalid IBAN' : null,
state.data.isNotValid(formFieldIban) ? 'invalid IBAN' : null,
),
);
},
@@ -141,7 +188,7 @@ class _CheckListInput extends StatelessWidget {
return BlocBuilder<FormDataCubit, FormDataState>(
builder: (context, state) {
final _input =
state.data.input<List<String>>(formFieldList) as ListOption<String>;
state.data.validatorOf<ListOption<String>>(formFieldList);
final _options = _input.value;
return Column(
@@ -192,8 +239,7 @@ class _RadioListInput extends StatelessWidget {
Widget build(BuildContext context) {
return BlocBuilder<FormDataCubit, FormDataState>(
builder: (context, state) {
final _input =
state.data.input<String>(formFieldRadio) as TextString;
final _input = state.data.validatorOf<TextString>(formFieldRadio);
return Column(
mainAxisSize: MainAxisSize.min,
@@ -249,7 +295,7 @@ class _CheckHiddenInput extends StatelessWidget {
trailing: BlocBuilder<FormDataCubit, FormDataState>(
builder: (context, state) {
return Checkbox(
value: state.data.input<bool>(formFieldHidden).value,
value: state.data.validatorOf<Boolean>(formFieldHidden).value,
onChanged: (v) {
final value = v!; // state is false, so value can't be null
@@ -272,7 +318,7 @@ class _CheckIsProInput extends StatelessWidget {
trailing: BlocBuilder<FormDataCubit, FormDataState>(
builder: (context, state) {
return Checkbox(
value: state.data.input<bool>(formFieldPro).value,
value: state.data.validatorOf<Boolean>(formFieldPro).value,
onChanged: (isPro) {
final value = isPro!; // state is false, so value can't be null
@@ -370,7 +416,7 @@ class SignUpForm extends StatelessWidget {
const SizedBox(height: 8),
BlocBuilder<FormDataCubit, FormDataState>(
builder: (context, state) {
if (state.data.input<bool>(formFieldPro).value) {
if (state.data.validatorOf<Boolean>(formFieldPro).value) {
return Column(children: [
_SirenInput(),
const SizedBox(height: 8),