refactor(ui)!: remove bloc export in buttons to be state management solution agnostic (closes #147)

This commit is contained in:
2023-02-23 16:59:56 +01:00
parent d6c9dfd8a7
commit 6c54689393
32 changed files with 673 additions and 342 deletions
@@ -15,14 +15,23 @@
// 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:gap/gap.dart';
import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
import 'package:wyatt_ui_kit_example/theme/constants.dart';
class FileSelectionButtons extends StatelessWidget {
class FileSelectionButtons extends StatefulWidget {
const FileSelectionButtons({super.key});
@override
State<FileSelectionButtons> createState() => _FileSelectionButtonsState();
}
class _FileSelectionButtonsState extends State<FileSelectionButtons> {
final _disabled = ValueNotifier(true);
final _dynamic = ValueNotifier(false);
Widget _leading() => const DecoratedBox(
decoration: BoxDecoration(
color: Constants.grey2,
@@ -48,6 +57,7 @@ class FileSelectionButtons extends StatelessWidget {
style: Theme.of(context).textTheme.titleMedium,
),
const Gap(20),
// Default
FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
@@ -56,65 +66,99 @@ class FileSelectionButtons extends StatelessWidget {
subTitle: const TextWrapper('Taille max: 20 Mo'),
),
const Gap(20),
FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Enabled',
BlocProvider(
create: (context) => InvalidButtonCubit()..freeze(),
child: FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Enabled',
),
subTitle: const TextWrapper('Subtitle'),
),
subTitle: const TextWrapper('Subtitle'),
)
..bloc.enable()
..bloc.freeze(),
),
const Gap(20),
// Using a ValueNotifier to disable the button
FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Disabled',
),
subTitle: const TextWrapper('Subtitle'),
)
..bloc.disable()
..bloc.freeze(),
disabled: _disabled,
),
const Gap(20),
FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Hovered',
BlocProvider(
create: (context) => InvalidButtonCubit()..hover(),
child: FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Hovered',
),
subTitle: const TextWrapper('Subtitle'),
),
subTitle: const TextWrapper('Subtitle'),
)
..bloc.onMouseEnter()
..bloc.freeze(),
),
const Gap(20),
FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Focused',
BlocProvider(
create: (context) => InvalidButtonCubit()..focus(),
child: FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Focused',
),
subTitle: const TextWrapper('Subtitle'),
),
subTitle: const TextWrapper('Subtitle'),
)
..bloc.onFocus()
..bloc.freeze(),
),
const Gap(20),
FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Tapped',
BlocProvider(
create: (context) => InvalidButtonCubit()..tap(),
child: FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Tapped',
),
subTitle: const TextWrapper('Subtitle'),
),
subTitle: const TextWrapper('Subtitle'),
)
..bloc.onClickDown()
..bloc.freeze(),
),
const Gap(20),
FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Invalid',
BlocProvider(
create: (context) => InvalidButtonCubit()..invalidate(),
child: FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Invalid',
),
subTitle: const TextWrapper('Subtitle'),
),
subTitle: const TextWrapper('Subtitle'),
)
..bloc.invalidate()
..bloc.freeze(),
),
const Gap(20),
// Dynamic, disabled with ValueNotifier and invalid with BlocProvider.
// Keep the state when the button is disabled.
Column(
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Enabled'),
Checkbox(
value: !_dynamic.value,
onChanged: (value) {
setState(() {
_dynamic.value = !_dynamic.value;
});
},
),
],
),
FileSelectionButton(
leading: _leading(),
title: const TextWrapper(
'Dynamic',
),
subTitle: const TextWrapper('Subtitle'),
disabled: _dynamic,
),
],
),
const Gap(20),
],
);
@@ -15,13 +15,22 @@
// 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:gap/gap.dart';
import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
class FlatButtons extends StatelessWidget {
class FlatButtons extends StatefulWidget {
const FlatButtons({super.key});
@override
State<FlatButtons> createState() => _FlatButtonsState();
}
class _FlatButtonsState extends State<FlatButtons> {
final _disabled = ValueNotifier(true);
final _dynamic = ValueNotifier(false);
@override
Widget build(BuildContext context) => Column(
children: [
@@ -30,56 +39,80 @@ class FlatButtons extends StatelessWidget {
style: Theme.of(context).textTheme.titleMedium,
),
const Gap(20),
Center(
// Default
const Center(
/// You can overwrite global textstyle of the label with [label],
/// but if you only want to override the color/gradient of the text
/// in a particular case you can override the style that will
/// be merge during the build.
child: FlatButton(
label: const TextWrapper(
label: TextWrapper(
'Voir notre savoir faire',
),
),
),
const Gap(20),
Center(
child: FlatButton(
label: const TextWrapper('Enabled'),
)
..bloc.enable()
..bloc.freeze(),
child: BlocProvider(
create: (context) => ButtonCubit()..freeze(),
child: const FlatButton(
label: TextWrapper('Enabled'),
),
),
),
const Gap(20),
// Disabled with ValueNotifier
Center(
child: FlatButton(
label: const TextWrapper('Disabled'),
)
..bloc.disable()
..bloc.freeze(),
disabled: _disabled,
),
),
const Gap(20),
Center(
child: FlatButton(
label: const TextWrapper('Hovered'),
)
..bloc.onMouseEnter()
..bloc.freeze(),
child: BlocProvider(
create: (context) => ButtonCubit()..hover(),
child: const FlatButton(
label: TextWrapper('Hovered'),
),
),
),
const Gap(20),
Center(
child: FlatButton(
label: const TextWrapper('Focused'),
)
..bloc.onFocus()
..bloc.freeze(),
child: BlocProvider(
create: (context) => ButtonCubit()..focus(),
child: const FlatButton(
label: TextWrapper('Focused'),
),
),
),
const Gap(20),
Center(
child: FlatButton(
label: const TextWrapper('Tapped'),
)
..bloc.onClickDown()
..bloc.freeze(),
child: BlocProvider(
create: (context) => ButtonCubit()..tap(),
child: const FlatButton(
label: TextWrapper('Tapped'),
),
),
),
const Gap(20),
// Dynamic, disabled with ValueNotifier and
// keep the state when the button is disabled
Row(
children: [
Checkbox(
value: !_dynamic.value,
onChanged: (value) {
setState(() {
_dynamic.value = !_dynamic.value;
});
},
),
FlatButton(
label: const TextWrapper('Dynamic'),
disabled: _dynamic,
),
],
),
const Gap(20),
],
@@ -15,12 +15,21 @@
// 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:gap/gap.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
class SimpleIconButtons extends StatelessWidget {
class SimpleIconButtons extends StatefulWidget {
const SimpleIconButtons({super.key});
@override
State<SimpleIconButtons> createState() => _SimpleIconButtonsState();
}
class _SimpleIconButtonsState extends State<SimpleIconButtons> {
final _disabled = ValueNotifier(true);
final _dynamic = ValueNotifier(false);
@override
Widget build(BuildContext context) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -30,8 +39,9 @@ class SimpleIconButtons extends StatelessWidget {
style: Theme.of(context).textTheme.titleMedium,
),
const Gap(20),
SimpleIconButton(
icon: const Icon(
// Default
const SimpleIconButton(
icon: Icon(
Icons.storm_outlined,
size: 17,
),
@@ -42,71 +52,101 @@ class SimpleIconButtons extends StatelessWidget {
style: Theme.of(context).textTheme.labelMedium,
),
const Gap(10),
SimpleIconButton(
icon: const Icon(
Icons.storm_outlined,
size: 17,
BlocProvider(
create: (context) => ButtonCubit()..freeze(),
child: const SimpleIconButton(
icon: Icon(
Icons.storm_outlined,
size: 17,
),
),
)
..bloc.enable()
..bloc.freeze(),
),
const Gap(20),
Text(
'Disabled',
style: Theme.of(context).textTheme.labelMedium,
),
const Gap(10),
// Disabled using ValueNotifier
SimpleIconButton(
icon: const Icon(
Icons.storm_outlined,
size: 17,
),
)
..bloc.disable()
..bloc.freeze(),
disabled: _disabled,
),
const Gap(20),
Text(
'Hovered',
style: Theme.of(context).textTheme.labelMedium,
),
const Gap(10),
SimpleIconButton(
icon: const Icon(
Icons.storm_outlined,
size: 17,
BlocProvider(
create: (context) => ButtonCubit()..hover(),
child: const SimpleIconButton(
icon: Icon(
Icons.storm_outlined,
size: 17,
),
),
)
..bloc.onMouseEnter()
..bloc.freeze(),
),
const Gap(20),
Text(
'Focused',
style: Theme.of(context).textTheme.labelMedium,
),
const Gap(10),
SimpleIconButton(
icon: const Icon(
Icons.storm_outlined,
size: 17,
BlocProvider(
create: (context) => ButtonCubit()..focus(),
child: const SimpleIconButton(
icon: Icon(
Icons.storm_outlined,
size: 17,
),
),
)
..bloc.onFocus()
..bloc.freeze(),
),
const Gap(20),
Text(
'Tapped',
style: Theme.of(context).textTheme.labelMedium,
),
const Gap(10),
SimpleIconButton(
icon: const Icon(
Icons.storm_outlined,
size: 17,
BlocProvider(
create: (context) => ButtonCubit()..tap(),
child: const SimpleIconButton(
icon: Icon(
Icons.storm_outlined,
size: 17,
),
),
)
..bloc.onClickDown()
..bloc.freeze(),
),
const Gap(20),
Text(
'Dynamic',
style: Theme.of(context).textTheme.labelMedium,
),
const Gap(10),
// Dynamic, disabled with ValueNotifier and
// keep the state when the button is disabled
Row(
children: [
Checkbox(
value: !_dynamic.value,
onChanged: (value) {
setState(() {
_dynamic.value = !_dynamic.value;
});
},
),
SimpleIconButton(
icon: const Icon(
Icons.storm_outlined,
size: 17,
),
disabled: _dynamic,
),
],
),
],
);
}
@@ -15,14 +15,23 @@
// 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:gap/gap.dart';
import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
import 'package:wyatt_ui_kit_example/theme/constants.dart';
class SymbolButtons extends StatelessWidget {
class SymbolButtons extends StatefulWidget {
const SymbolButtons({super.key});
@override
State<SymbolButtons> createState() => _SymbolButtonsState();
}
class _SymbolButtonsState extends State<SymbolButtons> {
final _disabled = ValueNotifier(true);
final _dynamic = ValueNotifier(false);
Icon _icon(BuildContext context) => Icon(
Icons.android,
size: 25,
@@ -45,47 +54,70 @@ class SymbolButtons extends StatelessWidget {
icon: _icon(context),
),
const Gap(20),
SymbolButton(
label: const TextWrapper('Enabled'),
icon: _icon(context),
)
..bloc.enable()
..bloc.freeze(),
BlocProvider(
create: (context) => SelectableButtonCubit()..freeze(),
child: SymbolButton(
label: const TextWrapper('Enabled'),
icon: _icon(context),
),
),
const Gap(20),
// Disabled
SymbolButton(
label: const TextWrapper('Disabled'),
icon: _icon(context),
)
..bloc.disable()
..bloc.freeze(),
disabled: _disabled,
),
const Gap(20),
SymbolButton(
label: const TextWrapper('Hovered'),
icon: _icon(context),
)
..bloc.onMouseEnter()
..bloc.freeze(),
BlocProvider(
create: (context) => SelectableButtonCubit()..hover(),
child: SymbolButton(
label: const TextWrapper('Hovered'),
icon: _icon(context),
),
),
const Gap(20),
SymbolButton(
label: const TextWrapper('Focused'),
icon: _icon(context),
)
..bloc.onFocus()
..bloc.freeze(),
BlocProvider(
create: (context) => SelectableButtonCubit()..focus(),
child: SymbolButton(
label: const TextWrapper('Focused'),
icon: _icon(context),
),
),
const Gap(20),
SymbolButton(
label: const TextWrapper('Tapped'),
icon: _icon(context),
)
..bloc.onClickDown()
..bloc.freeze(),
BlocProvider(
create: (context) => SelectableButtonCubit()..tap(),
child: SymbolButton(
label: const TextWrapper('Tapped'),
icon: _icon(context),
),
),
const Gap(20),
SymbolButton(
label: const TextWrapper('Selected'),
icon: _icon(context),
)
..bloc.select()
..bloc.freeze(),
BlocProvider(
create: (context) => SelectableButtonCubit()..select(),
child: SymbolButton(
label: const TextWrapper('Selected'),
icon: _icon(context),
),
),
const Gap(20),
Row(
children: [
Checkbox(
value: !_dynamic.value,
onChanged: (value) {
setState(() {
_dynamic.value = !_dynamic.value;
});
},
),
SymbolButton(
label: const TextWrapper('Dynamic'),
icon: _icon(context),
disabled: _dynamic,
),
],
),
const Gap(20),
DecoratedBox(
decoration: BoxDecoration(