diff --git a/forui/lib/forui.dart b/forui/lib/forui.dart index ddb080703..d9204f8c2 100644 --- a/forui/lib/forui.dart +++ b/forui/lib/forui.dart @@ -19,4 +19,5 @@ export 'src/widgets/button/tappable.dart'; export 'src/widgets/button/button.dart'; export 'src/widgets/button/link_button.dart'; export 'src/widgets/button/button_style.dart'; +export 'src/widgets/button/button_content_style.dart'; export 'src/widgets/card/card.dart'; diff --git a/forui/lib/src/theme/widget_data.dart b/forui/lib/src/theme/widget_data.dart index 22ad81da7..20d162a71 100644 --- a/forui/lib/src/theme/widget_data.dart +++ b/forui/lib/src/theme/widget_data.dart @@ -20,7 +20,7 @@ class FWidgetData { /// Creates a [FWidgetData] that inherits the properties from the given [FFontData] and [FStyleData]. FWidgetData.inherit({required FFontData data, required FStyleData style}) - : button = FButtonStyle.inherit(data: data, style: style), + : button = FButtonStyle.inherit(font: data, style: style), box = FBoxStyle.inherit(style: style, font: data), card = FCardStyle.inherit(style: style, font: data); diff --git a/forui/lib/src/widgets/button/button.dart b/forui/lib/src/widgets/button/button.dart index f574f79eb..23dfdc719 100644 --- a/forui/lib/src/widgets/button/button.dart +++ b/forui/lib/src/widgets/button/button.dart @@ -1,129 +1,76 @@ import 'package:flutter/material.dart'; import 'package:forui/forui.dart'; +import 'package:forui/src/widgets/button/button_content.dart'; -/// A [FButton] widget. -abstract class FButton extends StatelessWidget { +enum FButtonType { + primary, + secondary, + destructive, + outlined, +} + +class Fbutton extends StatelessWidget { /// The style. final FButtonStyle? style; - /// This FButton's content. - final Widget content; + /// The type of button. + final FButtonType type; + + /// This FButton's child. + final Widget child; /// Called when the FButton is tapped or otherwise activated. final VoidCallback? onPressed; /// Creates a [FButton] widget. - const FButton._({ - required this.content, + Fbutton({ required this.onPressed, + required this.type, + String? text, + String? icon, + Widget? child, this.style, super.key, - }); + }) : child = FButtonContent(text: text, icon: icon, child: child); - /// Creates a primary [FButton]. - /// - /// ```dart - /// FButton.primary( - /// content: FTextButtonContent('Example'), - /// onPressed: (){} - /// ); - /// ``` - factory FButton.primary({ - required Widget content, - required VoidCallback? onPressed, - FButtonStyle? style, - Key? key, - }) => - _FlatButton( - key: key, - style: style, - content: content, - onPressed: onPressed, - ); - - /// Creates a secondary [FButton]. - /// - /// ```dart - /// FButton.secondary( - /// content: FTextButtonContent('Example'), - /// onPressed: (){} - /// ); - /// ``` - factory FButton.secondary({ - required Widget content, - required VoidCallback? onPressed, - FButtonStyle? style, - Key? key, - }) => - // TODO: How do I link the default buttonStyles to the corresponding Factory constructor - _FlatButton( - key: key, - style: style, - content: content, - onPressed: onPressed, - ); - - /// Creates a destructive [FButton]. - /// - /// ```dart - /// FButton.destructive( - /// content: FTextButtonContent('Example'), - /// onPressed: (){} - /// ); - /// ``` - factory FButton.destructive({ - required Widget content, - required VoidCallback? onPressed, - FButtonStyle? style, - Key? key, - }) => - _FlatButton( - key: key, - style: style, - content: content, - onPressed: onPressed, - ); - - /// Creates an outlined [FButton]. - /// - /// ```dart - /// FButton.outline( - /// content: FTextButtonContent('Example'), - /// onPressed: (){} - /// ); - /// ``` - factory FButton.outlined({ - required Widget content, - required VoidCallback? onPressed, - FButtonStyle? style, - Key? key, - }) => - _OutlinedButton( - key: key, - style: style, - content: content, - onPressed: onPressed, - ); + /// Creates a [Fbutton]. + const Fbutton.raw({required this.type, required this.child, required this.onPressed, this.style, super.key}); + + @override + Widget build(BuildContext context) { + final style = this.style ?? FTheme.of(context).widgets.button; + + switch (type) { + case FButtonType.primary: + return _FlatButton(content: child, onPressed: onPressed, style: style.primary); + case FButtonType.secondary: + return _FlatButton(content: child, onPressed: onPressed, style: style.secondary); + case FButtonType.destructive: + return _FlatButton(content: child, onPressed: onPressed, style: style.destructive); + case FButtonType.outlined: + return _OutlinedButton(content: child, onPressed: onPressed, style: style.outlined); + } + } } -class _FlatButton extends FButton { +class _FlatButton extends StatelessWidget { + final ButtonStyle style; + final Widget content; + final VoidCallback? onPressed; + const _FlatButton({ - required super.content, - required super.onPressed, - super.style, + required this.content, + required this.onPressed, + required this.style, super.key, - }) : super._(); + }); @override - Widget build(BuildContext context) { - // TODO: Insert button type here? - final style = this.style ?? FTheme.of(context).widgets.button; - - return FTappable( + Widget build(BuildContext context) => FTappable( onPressed: onPressed, builder: (context, onPressed) => ElevatedButton( - style: style.button, + style: style, onPressed: onPressed, child: Padding( padding: const EdgeInsets.symmetric( @@ -134,25 +81,25 @@ class _FlatButton extends FButton { ), ), ); - } } -class _OutlinedButton extends FButton { +class _OutlinedButton extends StatelessWidget { + final ButtonStyle style; + final Widget content; + final VoidCallback? onPressed; + const _OutlinedButton({ - required super.content, - required super.onPressed, - super.style, + required this.content, + required this.onPressed, + required this.style, super.key, - }) : super._(); + }); @override - Widget build(BuildContext context) { - final style = this.style ?? FTheme.of(context).widgets.button; - - return FTappable( + Widget build(BuildContext context) => FTappable( onPressed: onPressed, builder: (context, onPressed) => OutlinedButton( - style: style.button, + style: style, onPressed: onPressed, child: Padding( padding: const EdgeInsets.symmetric( @@ -163,5 +110,4 @@ class _OutlinedButton extends FButton { ), ), ); - } } diff --git a/forui/lib/src/widgets/button/button_content.dart b/forui/lib/src/widgets/button/button_content.dart index aad92b123..90eceec36 100644 --- a/forui/lib/src/widgets/button/button_content.dart +++ b/forui/lib/src/widgets/button/button_content.dart @@ -1,55 +1,39 @@ import 'package:flutter/material.dart'; +import 'package:forui/forui.dart'; -/// The content for a text button. -class FTextButtonContent extends StatelessWidget { +/// Represents a content for [FButton]. +final class FButtonContent extends StatelessWidget { /// The label on the button. - final String text; + final String? text; - /// Creates a [FTextButtonContent]. - const FTextButtonContent( - this.text, { - super.key, - }); + /// The icon; + final String? icon; + + /// The child. + final Widget? child; + + /// The style. + final FButtonContentStyle? style; + + /// Creates a [FButtonContent]. + const FButtonContent({ + this.text, + this.icon, + this.child, + this.style, + super.key, + }); @override - Widget build(BuildContext context) => Container( - alignment: Alignment.center, - child: Text(text), - ); + Widget build(BuildContext context) { + final style = this.style ?? FTheme.of(context).widgets.button.content; + + return Row(mainAxisAlignment: MainAxisAlignment.center, children: [ + // [SvgTheme] provides a default color that overrides material's ButtonStyle foregroundColor + // This is a workaround, the color of the icon is set here instead of the ButtonStyle. + if (icon != null) //...[icon(height: 20, color: style.color), const SizedBox(width: 10)], + if (text != null) Flexible(child: Text(text!, style: style.text)), + if (child != null) child! + ]); + } } -// -// /// The content for a icon button. -// class IconButtonContent extends StatelessWidget { -// /// The label on the button. -// final String text; -// -// /// The icon. -// final SvgAsset icon; -// -// /// The icon color -// final Color color; -// -// /// Creates a [TextButtonContent]. -// const IconButtonContent({ -// required this.text, -// required this.icon, -// this.color = Colors.white, -// super.key, -// }); -// -// @override -// Widget build(BuildContext context) => Row( -// mainAxisAlignment: MainAxisAlignment.center, -// children: [ -// // [SvgTheme] provides a default color that overrides material's ButtonStyle foregroundColor -// // This is a workaround, the color of the icon is set here instead of the ButtonStyle. -// icon(height: 20, color: color), -// const SizedBox(width: 10), -// Flexible( -// child: Text( -// text, -// ), -// ), -// ], -// ); -// } diff --git a/forui/lib/src/widgets/button/button_content_style.dart b/forui/lib/src/widgets/button/button_content_style.dart new file mode 100644 index 000000000..f79968dd2 --- /dev/null +++ b/forui/lib/src/widgets/button/button_content_style.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:forui/forui.dart'; + +/// [FButtonContent]'s style. +class FButtonContentStyle { + /// The padding. + final EdgeInsets padding; + + /// The title. + final TextStyle text; + + /// The icon color. + final Color color; + + /// Creates a [FButtonContentStyle]. + const FButtonContentStyle({required this.padding, required this.text, required this.color}); + + /// Creates a [FButtonContentStyle] that inherits its properties from [style] and [font]. + FButtonContentStyle.inherit({required FStyleData style, required FFontData font}) + : padding = const EdgeInsets.fromLTRB(16, 12, 16, 16), + text = ScaledTextStyle( + TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: style.foreground, + ), + font, + ), + color = Colors.white; +} diff --git a/forui/lib/src/widgets/button/button_style.dart b/forui/lib/src/widgets/button/button_style.dart index 6a9176032..9e7f4c2c4 100644 --- a/forui/lib/src/widgets/button/button_style.dart +++ b/forui/lib/src/widgets/button/button_style.dart @@ -13,38 +13,48 @@ const _textStyle = TextStyle( /// [FButtonStyle]'s style. class FButtonStyle { - /// The color. - final ButtonStyle button; + /// The primary style. + final ButtonStyle primary; - /// The text. - final TextStyle text; + /// The secondary style. + final ButtonStyle secondary; - /// Creates a [FButtonStyle]. - const FButtonStyle({required this.button, required this.text}); + /// The destructive style. + final ButtonStyle destructive; - /// Creates a [FButtonStyle] that inherits its properties from [data] and [style]. - FButtonStyle.inherit({required FFontData data, required FStyleData style}) - // TODO: How do I link the default buttonStyles to the corresponding Factory constructor - : button = Style.secondary, - text = ScaledTextStyle(_textStyle, data); -} + /// The outlined style. + final ButtonStyle outlined; -/// An extension to apply the default buttonStyles. -extension Style on Never { - /// buttonStyle for a primary button - static final primary = _primaryStyle; + /// The link style. + final ButtonStyle link; - /// buttonStyle for a secondary button - static final secondary = _secondaryStyle; + /// The text. + final TextStyle text; - /// buttonStyle for a destructive button - static final destructive = _destructiveStyle; + /// The text. + final FButtonContentStyle content; - /// buttonStyle for a outlined button - static final outlined = _outlinedStyle; + /// Creates a [FButtonStyle]. + const FButtonStyle({ + required this.primary, + required this.secondary, + required this.destructive, + required this.outlined, + required this.link, + required this.text, + required this.content, + }); - /// buttonStyle for a link button - static final link = _linkStyle; + /// Creates a [FButtonStyle] that inherits its properties from [data] and [style]. + FButtonStyle.inherit({required FFontData font, required FStyleData style}) + // TODO: How do I link the default buttonStyles to the corresponding Factory constructor + : primary = _primaryStyle, + secondary = _secondaryStyle, + destructive = _destructiveStyle, + outlined = _outlinedStyle, + link = _linkStyle, + text = ScaledTextStyle(_textStyle, font), + content = FButtonContentStyle.inherit(style: style, font: font); } final _primaryStyle = ButtonStyle( diff --git a/forui/lib/src/widgets/button/link_button.dart b/forui/lib/src/widgets/button/link_button.dart index 6798f059b..f73b079c1 100644 --- a/forui/lib/src/widgets/button/link_button.dart +++ b/forui/lib/src/widgets/button/link_button.dart @@ -54,7 +54,7 @@ class FLinkButton extends StatelessWidget { Widget build(BuildContext context) { final style = this.style ?? FTheme.of(context).widgets.button; return TextButton( - style: style.button, + style: style.link, onPressed: onPressed, child: Text( text,