From 1d1885db61198533047e35ea70da41ad0072a2b2 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Tue, 14 Feb 2023 10:33:20 +0100 Subject: [PATCH] feat(ui_kit): implement simple icon button and use dimension style --- .../example/lib/buttons/buttons.dart | 182 +++++++++++----- .../lib/src/components/buttons/buttons.dart | 1 + .../buttons/flat_button/flat_button.g.dart | 1 + .../simple_icon_button.dart | 84 ++++++++ .../simple_icon_button.g.dart | 66 ++++++ .../simple_icon_screen.dart | 196 ++++++++++++++++++ .../symbol_button/symbol_button.g.dart | 9 + .../symbol_button/symbol_button_screen.dart | 6 +- 8 files changed, 487 insertions(+), 58 deletions(-) create mode 100644 packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_button.dart create mode 100644 packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_button.g.dart create mode 100644 packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_screen.dart diff --git a/packages/wyatt_ui_kit/example/lib/buttons/buttons.dart b/packages/wyatt_ui_kit/example/lib/buttons/buttons.dart index 363ced46..f7e312e3 100644 --- a/packages/wyatt_ui_kit/example/lib/buttons/buttons.dart +++ b/packages/wyatt_ui_kit/example/lib/buttons/buttons.dart @@ -170,7 +170,6 @@ class Buttons extends StatelessWidget { ), const Gap(20), FlatButton( - onPressed: (state) => print('pressed, from $state'), label: TextWrapper( 'Démarrer mon projet', style: @@ -196,63 +195,136 @@ class Buttons extends StatelessWidget { ColoredBox( color: _background, child: Center( - child: Column( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ + Column( + children: [ + const Gap(20), + SymbolButton( + icon: const Icon( + Icons.android, + size: 25, + ), + label: const TextWrapper('Texte'), + normalStyle: const SymbolButtonStyle( + borderColors: MultiColor(_disabledColors), + foregroundColors: MultiColor.single(Colors.white), + backgroundColors: + MultiColor.single(_disabledBackground), + stroke: 1, + ), + hoveredStyle: const SymbolButtonStyle( + borderColors: MultiColor(_disabledColors), + foregroundColors: MultiColor.single(Colors.white), + backgroundColors: MultiColor.single(_background), + stroke: 1, + ), + selectedStyle: const SymbolButtonStyle( + borderColors: MultiColor(_selectedColors), + foregroundColors: MultiColor.single(Colors.white), + backgroundColors: + MultiColor.single(_disabledBackground), + stroke: 1, + ), + ) + ..bloc.onClickUpIn() + ..bloc.freeze(), + const Gap(20), + SymbolButton( + icon: const Icon( + Icons.android, + size: 25, + ), + label: const TextWrapper('Texte'), + normalStyle: const SymbolButtonStyle( + borderColors: MultiColor(_disabledColors), + foregroundColors: MultiColor.single(Colors.white), + backgroundColors: + MultiColor.single(_disabledBackground), + stroke: 1, + ), + hoveredStyle: const SymbolButtonStyle( + borderColors: MultiColor(_disabledColors), + foregroundColors: MultiColor.single(Colors.white), + backgroundColors: MultiColor.single(_background), + stroke: 1, + ), + selectedStyle: const SymbolButtonStyle( + borderColors: MultiColor(_selectedColors), + foregroundColors: MultiColor.single(Colors.white), + backgroundColors: + MultiColor.single(_disabledBackground), + stroke: 1, + ), + )..bloc.freeze(), + const Gap(20), + ], + ), const Gap(20), - SymbolButton( - icon: const Icon( - Icons.android, - size: 25, - ), - label: const TextWrapper('Texte'), - normalStyle: const SymbolButtonStyle( - borderColors: MultiColor(_disabledColors), - foregroundColors: MultiColor.single(Colors.white), - backgroundColors: MultiColor.single(_disabledBackground), - stroke: 1, - ), - hoveredStyle: const SymbolButtonStyle( - borderColors: MultiColor(_disabledColors), - foregroundColors: MultiColor.single(Colors.white), - backgroundColors: MultiColor.single(_background), - stroke: 1, - ), - selectedStyle: const SymbolButtonStyle( - borderColors: MultiColor(_selectedColors), - foregroundColors: MultiColor.single(Colors.white), - backgroundColors: MultiColor.single(_disabledBackground), - stroke: 1, - ), - ) - ..bloc.onClickUpIn() - ..bloc.freeze(), - const Gap(20), - SymbolButton( - icon: const Icon( - Icons.android, - size: 25, - ), - label: const TextWrapper('Texte'), - normalStyle: const SymbolButtonStyle( - borderColors: MultiColor(_disabledColors), - foregroundColors: MultiColor.single(Colors.white), - backgroundColors: MultiColor.single(_disabledBackground), - stroke: 1, - ), - hoveredStyle: const SymbolButtonStyle( - borderColors: MultiColor(_disabledColors), - foregroundColors: MultiColor.single(Colors.white), - backgroundColors: MultiColor.single(_background), - stroke: 1, - ), - selectedStyle: const SymbolButtonStyle( - borderColors: MultiColor(_selectedColors), - foregroundColors: MultiColor.single(Colors.white), - backgroundColors: MultiColor.single(_disabledBackground), - stroke: 1, - ), - )..bloc.freeze(), + Row( + children: [ + SimpleIconButton( + icon: const Icon( + Icons.storm_outlined, + size: 17, + ), + normalStyle: const SimpleIconButtonStyle( + backgroundColors: MultiColor.single(_disabled), + ), + hoveredStyle: SimpleIconButtonStyle( + backgroundColors: + MultiColor.single(_disabledColors.last), + ), + ), + const Gap(10), + SimpleIconButton( + icon: const Icon( + Icons.sunny, + size: 17, + ), + normalStyle: const SimpleIconButtonStyle( + backgroundColors: MultiColor.single(_disabled), + ), + hoveredStyle: SimpleIconButtonStyle( + backgroundColors: + MultiColor.single(_disabledColors.last), + ), + ), + const Gap(10), + SimpleIconButton( + icon: const Icon( + Icons.wechat, + size: 17, + ), + normalStyle: const SimpleIconButtonStyle( + backgroundColors: MultiColor.single(_disabled), + ), + hoveredStyle: SimpleIconButtonStyle( + backgroundColors: + MultiColor.single(_disabledColors.last), + ), + ) + ], + ), const Gap(20), + Row( + children: [ + SymbolButton( + icon: const FlutterLogo( + size: 50, + ), + normalStyle: const SymbolButtonStyle( + dimension: 73, + backgroundColors: MultiColor.single(Colors.white), + ), + hoveredStyle: SymbolButtonStyle( + dimension: 73, + backgroundColors: MultiColor.single(Colors.grey[300]), + ), + ), + ], + ), ], ), ), diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/buttons.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/buttons.dart index c8bab7cb..c3cd55d7 100644 --- a/packages/wyatt_ui_kit/lib/src/components/buttons/buttons.dart +++ b/packages/wyatt_ui_kit/lib/src/components/buttons/buttons.dart @@ -15,4 +15,5 @@ // along with this program. If not, see . export './flat_button/flat_button.dart'; +export './simple_icon_button/simple_icon_button.dart'; export './symbol_button/symbol_button.dart'; diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/flat_button/flat_button.g.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/flat_button/flat_button.g.dart index fc436468..379f13ba 100644 --- a/packages/wyatt_ui_kit/lib/src/components/buttons/flat_button/flat_button.g.dart +++ b/packages/wyatt_ui_kit/lib/src/components/buttons/flat_button/flat_button.g.dart @@ -62,6 +62,7 @@ class $FlatButtonCWProxyImpl implements $FlatButtonComponentCWProxy { focusedStyle: focusedStyle ?? _value.focusedStyle, tappedStyle: tappedStyle ?? _value.tappedStyle, onPressed: onPressed ?? _value.onPressed, + mainAxisSize: mainAxisSize ?? _value.mainAxisSize, key: key ?? _value.key, ); } diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_button.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_button.dart new file mode 100644 index 00000000..db4a188e --- /dev/null +++ b/packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_button.dart @@ -0,0 +1,84 @@ +// Copyright (C) 2023 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 . + +import 'package:flutter/material.dart' hide ButtonStyle; +import 'package:wyatt_component_copy_with_extension/component_copy_with_extension.dart'; +import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart'; +import 'package:wyatt_ui_kit/src/components/buttons/cubit/button_cubit.dart'; +import 'package:wyatt_ui_kit/src/components/buttons/simple_icon_button/simple_icon_screen.dart'; +import 'package:wyatt_ui_kit/src/core/mixin/export_bloc_mixin.dart'; + +part 'simple_icon_button.g.dart'; + +@ComponentCopyWithExtension() +class SimpleIconButton extends SimpleIconButtonComponent + with $SimpleIconButtonCWMixin, ExportBloc { + SimpleIconButton({ + super.icon, + super.disabledStyle, + super.normalStyle, + super.hoveredStyle, + super.focusedStyle, + super.tappedStyle, + super.selectedStyle, + super.onPressed, + super.key, + }); + + final ButtonCubit _cubit = ButtonCubit(); + + @override + ButtonCubit get bloc => _cubit; + + @override + SimpleIconButtonStyle? get disabledStyle => + super.disabledStyle as SimpleIconButtonStyle?; + + @override + SimpleIconButtonStyle? get normalStyle => + super.normalStyle as SimpleIconButtonStyle?; + + @override + SimpleIconButtonStyle? get hoveredStyle => + super.hoveredStyle as SimpleIconButtonStyle?; + + @override + SimpleIconButtonStyle? get focusedStyle => + super.focusedStyle as SimpleIconButtonStyle?; + + @override + SimpleIconButtonStyle? get tappedStyle => + super.tappedStyle as SimpleIconButtonStyle?; + + @override + SimpleIconButtonStyle? get selectedStyle => + super.selectedStyle as SimpleIconButtonStyle?; + + @override + Widget build(BuildContext context) => exportBloc( + child: SimpleIconButtonScreen( + icon: icon, + disabledStyle: disabledStyle, + normalStyle: normalStyle, + hoveredStyle: hoveredStyle, + focusedStyle: focusedStyle, + tappedStyle: tappedStyle, + selectedStyle: selectedStyle, + onPressed: onPressed, + key: key, + ), + ); +} diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_button.g.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_button.g.dart new file mode 100644 index 00000000..87f97ab8 --- /dev/null +++ b/packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_button.g.dart @@ -0,0 +1,66 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'simple_icon_button.dart'; + +// ************************************************************************** +// ComponentCopyWithGenerator +// ************************************************************************** + +class $SimpleIconButtonCWProxyImpl + implements $SimpleIconButtonComponentCWProxy { + const $SimpleIconButtonCWProxyImpl(this._value); + final SimpleIconButton _value; + @override + SimpleIconButton icon(Icon? icon) => this(icon: icon); + @override + SimpleIconButton disabledStyle(ButtonStyle? disabledStyle) => + this(disabledStyle: disabledStyle); + @override + SimpleIconButton normalStyle(ButtonStyle? normalStyle) => + this(normalStyle: normalStyle); + @override + SimpleIconButton hoveredStyle(ButtonStyle? hoveredStyle) => + this(hoveredStyle: hoveredStyle); + @override + SimpleIconButton focusedStyle(ButtonStyle? focusedStyle) => + this(focusedStyle: focusedStyle); + @override + SimpleIconButton tappedStyle(ButtonStyle? tappedStyle) => + this(tappedStyle: tappedStyle); + @override + SimpleIconButton selectedStyle(ButtonStyle? selectedStyle) => + this(selectedStyle: selectedStyle); + @override + SimpleIconButton onPressed(void Function(ControlState)? onPressed) => + this(onPressed: onPressed); + @override + SimpleIconButton key(Key? key) => this(key: key); + @override + SimpleIconButton call({ + Icon? icon, + ButtonStyle? disabledStyle, + ButtonStyle? normalStyle, + ButtonStyle? hoveredStyle, + ButtonStyle? focusedStyle, + ButtonStyle? tappedStyle, + ButtonStyle? selectedStyle, + void Function(ControlState)? onPressed, + Key? key, + }) => + SimpleIconButton( + icon: icon ?? _value.icon, + disabledStyle: disabledStyle ?? _value.disabledStyle, + normalStyle: normalStyle ?? _value.normalStyle, + hoveredStyle: hoveredStyle ?? _value.hoveredStyle, + focusedStyle: focusedStyle ?? _value.focusedStyle, + tappedStyle: tappedStyle ?? _value.tappedStyle, + selectedStyle: selectedStyle ?? _value.selectedStyle, + onPressed: onPressed ?? _value.onPressed, + key: key ?? _value.key, + ); +} + +mixin $SimpleIconButtonCWMixin on Component { + $SimpleIconButtonComponentCWProxy get copyWith => + $SimpleIconButtonCWProxyImpl(this as SimpleIconButton); +} diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_screen.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_screen.dart new file mode 100644 index 00000000..64e5bc49 --- /dev/null +++ b/packages/wyatt_ui_kit/lib/src/components/buttons/simple_icon_button/simple_icon_screen.dart @@ -0,0 +1,196 @@ +// Copyright (C) 2023 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 . + +import 'package:flutter/material.dart' hide ButtonStyle; +import 'package:flutter/services.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; +import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart'; +import 'package:wyatt_ui_kit/src/components/buttons/cubit/button_cubit.dart'; +import 'package:wyatt_ui_kit/src/components/gradients/gradient_box_border.dart'; +import 'package:wyatt_ui_kit/src/core/extensions/theme_extensions.dart'; + +class SimpleIconButtonScreen extends CubitScreen { + const SimpleIconButtonScreen({ + this.icon, + this.disabledStyle, + this.normalStyle, + this.hoveredStyle, + this.focusedStyle, + this.tappedStyle, + this.selectedStyle, + this.onPressed, + super.key, + }); + + final Icon? icon; + + final SimpleIconButtonStyle? disabledStyle; + final SimpleIconButtonStyle? normalStyle; + final SimpleIconButtonStyle? hoveredStyle; + final SimpleIconButtonStyle? focusedStyle; + final SimpleIconButtonStyle? tappedStyle; + final SimpleIconButtonStyle? selectedStyle; + + final void Function(ControlState state)? onPressed; + + @override + ButtonCubit create(BuildContext context) => ButtonCubit(); + + @override + Widget onBuild(BuildContext context, ButtonState state) { + // Set a default style + SimpleIconButtonStyle? style = normalStyle ?? const SimpleIconButtonStyle(); + + switch (state.state) { + case ControlState.disabled: + style = disabledStyle ?? style; + break; + case ControlState.hovered: + style = hoveredStyle ?? style; + break; + case ControlState.tapped: + style = tappedStyle ?? style; + break; + case ControlState.focused: + style = focusedStyle ?? style; + break; + case ControlState.normal: + break; + } + + return Focus( + onFocusChange: (hasFocus) => + hasFocus ? bloc(context).onFocus() : bloc(context).onUnfocus(), + onKeyEvent: (focusNode, event) { + if (event.logicalKey == LogicalKeyboardKey.enter && state.isFocused) { + onPressed?.call(state.state); + bloc(context).onClickUpOut(); + return KeyEventResult.handled; + } + return KeyEventResult.ignored; + }, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (event) { + bloc(context).onMouseEnter(); + }, + onExit: (event) { + bloc(context).onMouseLeave(); + }, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTapDown: (details) { + bloc(context).onClickDown(); + }, + onTapUp: (details) { + onPressed?.call(state.state); + bloc(context).onClickUpIn(); + }, + onTapCancel: () { + onPressed?.call(state.state); + bloc(context).onClickUpOut(); + }, + child: SizedBox.square( + dimension: style.dimension ?? 30, + child: AspectRatio( + aspectRatio: 1, + child: DecoratedBox( + decoration: BoxDecoration( + color: style.backgroundColors?.color ?? + context.colorScheme.tertiary, + // If no border color => no default value + border: (style.borderColors != null) + ? (style.borderColors?.isGradient ?? false) + ? GradientBoxBorder( + gradient: LinearGradient( + colors: style.borderColors!.colors, + ), + width: style.stroke ?? 2, + ) + : Border.all( + color: style.borderColors!.color, + width: style.stroke ?? 2, + ) + : null, + // if no gradient colors => no default value + gradient: (style.backgroundColors?.isGradient ?? false) + ? LinearGradient( + colors: style.backgroundColors!.colors, + ) + : null, + boxShadow: [ + if (style.shadow != null) ...[style.shadow!] + ], + borderRadius: BorderRadius.all( + Radius.circular(style.radius ?? 0), + ), + ), + child: ConstrainedBox( + constraints: BoxConstraints( + minWidth: style.dimension ?? 30, + ), // min sizes for Material buttons + child: Padding( + padding: EdgeInsets.all(style.padding ?? 0), + child: Center( + // Choose color + // button.foreground.colors (gradient) ?? + // buttonStyle.foregroundColor.color ?? + // context.colorScheme.onTertiary + child: Builder( + builder: (context) { + if (icon?.color != null) { + return icon!; + } + final gradient = + (style?.foregroundColors?.isGradient ?? false) + ? LinearGradient( + colors: style!.foregroundColors!.colors, + ) + : null; + final color = style?.foregroundColors?.color ?? + context.colorScheme.onTertiary; + if (gradient != null) { + return ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) => gradient.createShader( + Rect.fromLTWH( + 0, + 0, + bounds.width, + bounds.height, + ), + ), + child: icon, + ); + } + return ColorFiltered( + colorFilter: + ColorFilter.mode(color, BlendMode.srcIn), + child: icon, + ); + }, + ), + ), + ), + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/symbol_button/symbol_button.g.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/symbol_button/symbol_button.g.dart index 30476ddd..7aa6b439 100644 --- a/packages/wyatt_ui_kit/lib/src/components/buttons/symbol_button/symbol_button.g.dart +++ b/packages/wyatt_ui_kit/lib/src/components/buttons/symbol_button/symbol_button.g.dart @@ -10,6 +10,11 @@ class $SymbolButtonCWProxyImpl implements $SymbolButtonComponentCWProxy { const $SymbolButtonCWProxyImpl(this._value); final SymbolButton _value; @override + SymbolButton mainAxisSize(MainAxisSize? mainAxisSize) => + this(mainAxisSize: mainAxisSize); + @override + SymbolButton label(TextWrapper? label) => this(label: label); + @override SymbolButton icon(Widget? icon) => this(icon: icon); @override SymbolButton disabledStyle(ButtonStyle? disabledStyle) => @@ -36,6 +41,8 @@ class $SymbolButtonCWProxyImpl implements $SymbolButtonComponentCWProxy { SymbolButton key(Key? key) => this(key: key); @override SymbolButton call({ + MainAxisSize? mainAxisSize, + TextWrapper? label, Widget? icon, ButtonStyle? disabledStyle, ButtonStyle? normalStyle, @@ -48,12 +55,14 @@ class $SymbolButtonCWProxyImpl implements $SymbolButtonComponentCWProxy { }) => SymbolButton( icon: icon ?? _value.icon, + label: label ?? _value.label, disabledStyle: disabledStyle ?? _value.disabledStyle, normalStyle: normalStyle ?? _value.normalStyle, hoveredStyle: hoveredStyle ?? _value.hoveredStyle, focusedStyle: focusedStyle ?? _value.focusedStyle, tappedStyle: tappedStyle ?? _value.tappedStyle, selectedStyle: selectedStyle ?? _value.selectedStyle, + mainAxisSize: mainAxisSize ?? _value.mainAxisSize, onPressed: onPressed ?? _value.onPressed, key: key ?? _value.key, ); diff --git a/packages/wyatt_ui_kit/lib/src/components/buttons/symbol_button/symbol_button_screen.dart b/packages/wyatt_ui_kit/lib/src/components/buttons/symbol_button/symbol_button_screen.dart index 11f9050d..0b993bc2 100644 --- a/packages/wyatt_ui_kit/lib/src/components/buttons/symbol_button/symbol_button_screen.dart +++ b/packages/wyatt_ui_kit/lib/src/components/buttons/symbol_button/symbol_button_screen.dart @@ -122,7 +122,7 @@ class SymbolButtonScreen mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox.square( - dimension: 60, + dimension: style.dimension ?? 60, child: AspectRatio( aspectRatio: 1, child: DecoratedBox( @@ -157,8 +157,8 @@ class SymbolButtonScreen ), ), child: ConstrainedBox( - constraints: const BoxConstraints( - minWidth: 50, + constraints: BoxConstraints( + minWidth: style.dimension ?? 60, ), // min sizes for Material buttons child: Padding( padding: EdgeInsets.all(style.padding ?? 0),