feat(ui_kit): implement simple icon button and use dimension style

This commit is contained in:
Hugo Pointcheval 2023-02-14 10:33:20 +01:00
parent 4f1a064298
commit e4d904eb8d
Signed by: hugo
GPG Key ID: 3AAC487E131E00BC
8 changed files with 487 additions and 58 deletions

View File

@ -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]),
),
),
],
),
],
),
),

View File

@ -15,4 +15,5 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export './flat_button/flat_button.dart';
export './simple_icon_button/simple_icon_button.dart';
export './symbol_button/symbol_button.dart';

View File

@ -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,
);
}

View File

@ -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 <https://www.gnu.org/licenses/>.
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<ButtonCubit> {
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,
),
);
}

View File

@ -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);
}

View File

@ -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 <https://www.gnu.org/licenses/>.
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<ButtonCubit, ButtonState> {
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,
);
},
),
),
),
),
),
),
),
),
),
);
}
}

View File

@ -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,
);

View File

@ -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),