Compare commits

...
Author SHA1 Message Date
hugo 74db784973 chore(release): publish packages
- wyatt_form_bloc@0.0.2
 - wyatt_authentication_bloc@0.2.0+1
2022-05-02 14:44:17 +02:00
hugo fe5fa692f7 feat(form): add list option validator 2022-05-02 14:41:24 +02:00
14 changed files with 327 additions and 83 deletions
+28
View File
@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## 2022-05-02
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`wyatt_form_bloc` - `v0.0.2`](#wyatt_form_bloc---v002)
- [`wyatt_authentication_bloc` - `v0.2.0+1`](#wyatt_authentication_bloc---v0201)
Packages with dependency updates only:
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
- `wyatt_authentication_bloc` - `v0.2.0+1`
---
#### `wyatt_form_bloc` - `v0.0.2`
- **FEAT**: add list option validator.
## 2022-04-20
### Changes
@@ -1,3 +1,7 @@
## 0.2.0+1
- Update a dependency to the latest release.
## 0.2.0
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
@@ -38,7 +38,7 @@ dependencies:
wyatt_form_bloc:
git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
ref: wyatt_form_bloc-v0.0.1
ref: wyatt_form_bloc-v0.0.2
path: packages/wyatt_form_bloc
# The following adds the Cupertino Icons font to your application.
@@ -1,7 +1,7 @@
name: wyatt_authentication_bloc
description: Authentication BLoC for Flutter
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_authentication_bloc
version: 0.2.0
version: 0.2.0+1
environment:
sdk: ">=2.15.1 <3.0.0"
@@ -18,7 +18,7 @@ dependencies:
wyatt_form_bloc:
git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
ref: wyatt_form_bloc-v0.0.1
ref: wyatt_form_bloc-v0.0.2
path: packages/wyatt_form_bloc
+4
View File
@@ -1,3 +1,7 @@
## 0.0.2
- **FEAT**: add list option validator.
## 0.0.1
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
@@ -14,50 +14,48 @@
// 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:developer';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.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';
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
static FormData getNormalFormData() {
return const FormData([
static List<FormEntry> getNormalEntries() {
return const [
FormEntry(formFieldName, Name.pure()),
FormEntry(formFieldEmail, Email.pure()),
FormEntry(formFieldPhone, Phone.pure()),
FormEntry(
formFieldList, ListOption<String>.pure(defaultValue: ['checkbox3'])),
FormEntry(formFieldRadio, TextString.pure()),
FormEntry(formFieldPro, Boolean.pure(), name: 'business'),
FormEntry(formFieldHidden, Boolean.pure(), export: false),
]);
];
}
static List<FormEntry> getBusinessEntries() {
const entries = [
FormEntry(formFieldSiren, Siren.pure()),
FormEntry(formFieldIban, Iban.pure()),
];
return getNormalEntries() + entries;
}
static FormData getNormalFormData() {
return FormData(getNormalEntries());
}
static FormData getProFormData() {
return const FormData([
FormEntry(formFieldName, Name.pure()),
FormEntry(formFieldEmail, Email.pure()),
FormEntry(formFieldPhone, Phone.pure()),
FormEntry(formFieldPro, Boolean.pure(), name: 'business'),
FormEntry(formFieldHidden, Boolean.pure(), export: false),
FormEntry(formFieldSiren, Siren.pure()),
FormEntry(formFieldIban, Iban.pure()),
]);
}
Future<bool> onSubmit(FormDataState state) async {
log(state.data.toMap().toString());
return true;
return FormData(getBusinessEntries());
}
@override
Widget build(BuildContext context) {
FormDataCubit _formCubit = FormDataCubit(
entries: getNormalFormData(),
onSubmit: onSubmit,
);
FormDataCubit _formCubit = CustomFormCubit(entries: getNormalFormData());
return BlocProvider(
create: (context) => _formCubit,
@@ -19,6 +19,8 @@ const String formFieldPhone = 'phone';
const String formFieldEmail = 'email';
const String formFieldSiren = 'siren';
const String formFieldIban = 'iban';
const String formFieldList = 'list';
const String formFieldRadio = 'radio';
const String formFieldHidden = 'hidden';
const String formFieldPro = 'isPro';
@@ -0,0 +1,33 @@
// 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: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);
@override
Future<void> submitForm() {
log(state.data.toMap().toString());
return Future.value();
}
}
@@ -0,0 +1,22 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
part of 'custom_form_cubit.dart';
@immutable
abstract class CustomFormState {}
class CustomFormInitial extends CustomFormState {}
@@ -135,6 +135,112 @@ class _IbanInput extends StatelessWidget {
}
}
class _CheckListInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<FormDataCubit, FormDataState>(
builder: (context, state) {
final _input =
state.data.input<List<String>>(formFieldList) as ListOption<String>;
final _options = _input.value;
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: const Text('Checkbox1'),
trailing: Checkbox(
value: _options.contains('checkbox1'),
onChanged: (_) {
context.read<FormDataCubit>().dataChanged(
formFieldList,
_input.select('checkbox1'),
);
}),
),
ListTile(
title: const Text('Checkbox2'),
trailing: Checkbox(
value: _options.contains('checkbox2'),
onChanged: (_) {
context.read<FormDataCubit>().dataChanged(
formFieldList,
_input.select('checkbox2'),
);
}),
),
ListTile(
title: const Text('Checkbox3 (default)'),
trailing: Checkbox(
value: _options.contains('checkbox3'),
onChanged: (_) {
context.read<FormDataCubit>().dataChanged(
formFieldList,
_input.select('checkbox3'),
);
}),
),
],
);
},
);
}
}
class _RadioListInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<FormDataCubit, FormDataState>(
builder: (context, state) {
final _input =
state.data.input<String>(formFieldRadio) as TextString;
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: const Text('Radio1'),
trailing: Radio<bool>(
groupValue: true,
value: _input.value == 'radio1',
onChanged: (_) {
context.read<FormDataCubit>().dataChanged(
formFieldRadio,
const TextString.dirty('radio1'),
);
}),
),
ListTile(
title: const Text('Radio2'),
trailing: Radio<bool>(
groupValue: true,
value: _input.value == 'radio2',
onChanged: (_) {
context.read<FormDataCubit>().dataChanged(
formFieldRadio,
const TextString.dirty('radio2'),
);
}),
),
ListTile(
title: const Text('Radio3'),
trailing: Radio<bool>(
groupValue: true,
value: _input.value == 'radio3',
onChanged: (_) {
context.read<FormDataCubit>().dataChanged(
formFieldRadio,
const TextString.dirty('radio3'),
);
}),
),
],
);
},
);
}
}
class _CheckHiddenInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
@@ -201,8 +307,7 @@ class _SignUpButton extends StatelessWidget {
? const CircularProgressIndicator()
: ElevatedButton(
onPressed: state.status.isValidated
? () =>
context.read<FormDataCubit>().submitForm()
? () => context.read<FormDataCubit>().submitForm()
: null,
child: const Text('SIGN UP'),
);
@@ -244,8 +349,6 @@ class SignUpForm extends StatelessWidget {
);
}
},
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Align(
alignment: const Alignment(0, -1 / 3),
child: Column(
@@ -257,6 +360,10 @@ class SignUpForm extends StatelessWidget {
const SizedBox(height: 8),
_PhoneInput(),
const SizedBox(height: 8),
_CheckListInput(),
const SizedBox(height: 8),
_RadioListInput(),
const SizedBox(height: 8),
_CheckHiddenInput(),
const SizedBox(height: 8),
_CheckIsProInput(),
@@ -281,7 +388,6 @@ class SignUpForm extends StatelessWidget {
],
),
),
),
);
}
}
@@ -23,16 +23,16 @@ import 'package:wyatt_form_bloc/src/form/form.dart';
part 'form_data_state.dart';
class FormDataCubit extends Cubit<FormDataState> {
final Future<bool> Function(FormDataState state)? _onSubmit;
abstract class FormDataCubit extends Cubit<FormDataState> {
FormDataCubit({required FormData entries})
: super(FormDataState(data: entries));
FormDataCubit({
required FormData entries,
Future<bool> Function(FormDataState state)? onSubmit,
}) : _onSubmit = onSubmit,
super(FormDataState(data: entries));
void dataChanged<T>(String field, FormInput dirtyValue) {
/// Change value of a field.
///
/// Inputs:
/// - `field`: The key of the field to change.
/// - `dirtyValue`: The new value of the field.
void dataChanged(String field, FormInput dirtyValue) {
final _form = state.data.clone();
if (_form.contains(field)) {
@@ -49,6 +49,11 @@ class FormDataCubit extends Cubit<FormDataState> {
);
}
/// 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,
@@ -78,13 +83,6 @@ class FormDataCubit extends Cubit<FormDataState> {
);
}
Future<void> submitForm() async {
unawaited(
_onSubmit?.call(state).then((bool reemit) {
if (reemit) {
emit(state);
}
}),
);
}
/// Submit the form.
Future<void> submitForm();
}
@@ -0,0 +1,48 @@
// 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 FormInput<List<T>, ValidationError> {
/// {@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 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
ValidationError? validator(List<T>? value) {
return value?.isNotEmpty == true ? null : ValidationError.invalid;
}
}
@@ -18,6 +18,7 @@ export 'boolean.dart';
export 'confirmed_password.dart';
export 'email.dart';
export 'iban.dart';
export 'list_option.dart';
export 'name.dart';
export 'password.dart';
export 'phone.dart';
+1 -1
View File
@@ -1,7 +1,7 @@
name: wyatt_form_bloc
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
version: 0.0.1
version: 0.0.2
environment:
sdk: '>=2.16.2 <3.0.0'