diff --git a/forui/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/forui/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java new file mode 100644 index 000000000..ae159a9dd --- /dev/null +++ b/forui/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -0,0 +1,24 @@ +package io.flutter.plugins; + +import androidx.annotation.Keep; +import androidx.annotation.NonNull; +import io.flutter.Log; + +import io.flutter.embedding.engine.FlutterEngine; + +/** + * Generated file. Do not edit. + * This file is generated by the Flutter tool based on the + * plugins that support the Android platform. + */ +@Keep +public final class GeneratedPluginRegistrant { + private static final String TAG = "GeneratedPluginRegistrant"; + public static void registerWith(@NonNull FlutterEngine flutterEngine) { + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin path_provider_android, io.flutter.plugins.pathprovider.PathProviderPlugin", e); + } + } +} diff --git a/forui/example/android/local.properties b/forui/example/android/local.properties new file mode 100644 index 000000000..c0dbe009c --- /dev/null +++ b/forui/example/android/local.properties @@ -0,0 +1,2 @@ +sdk.dir=C:\\Users\\Matthias\\AppData\\Local\\Android\\sdk +flutter.sdk=C:\\Users\\Matthias\\Documents\\flutter \ No newline at end of file diff --git a/forui/example/ios/Flutter/Generated.xcconfig b/forui/example/ios/Flutter/Generated.xcconfig new file mode 100644 index 000000000..a5765edf3 --- /dev/null +++ b/forui/example/ios/Flutter/Generated.xcconfig @@ -0,0 +1,14 @@ +// This is a generated file; do not edit or check into version control. +FLUTTER_ROOT=C:\Users\Matthias\Documents\flutter +FLUTTER_APPLICATION_PATH=C:\Users\Matthias\Documents\NetBeansProjects\forui\forui\example +COCOAPODS_PARALLEL_CODE_SIGN=true +FLUTTER_TARGET=lib\main.dart +FLUTTER_BUILD_DIR=build +FLUTTER_BUILD_NAME=1.0.0 +FLUTTER_BUILD_NUMBER=1 +EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 +EXCLUDED_ARCHS[sdk=iphoneos*]=armv7 +DART_OBFUSCATION=false +TRACK_WIDGET_CREATION=true +TREE_SHAKE_ICONS=false +PACKAGE_CONFIG=.dart_tool/package_config.json diff --git a/forui/example/ios/Flutter/flutter_export_environment.sh b/forui/example/ios/Flutter/flutter_export_environment.sh new file mode 100644 index 000000000..1fc3763e9 --- /dev/null +++ b/forui/example/ios/Flutter/flutter_export_environment.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=C:\Users\Matthias\Documents\flutter" +export "FLUTTER_APPLICATION_PATH=C:\Users\Matthias\Documents\NetBeansProjects\forui\forui\example" +export "COCOAPODS_PARALLEL_CODE_SIGN=true" +export "FLUTTER_TARGET=lib\main.dart" +export "FLUTTER_BUILD_DIR=build" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=1" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=true" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=.dart_tool/package_config.json" diff --git a/forui/example/ios/Runner/GeneratedPluginRegistrant.h b/forui/example/ios/Runner/GeneratedPluginRegistrant.h new file mode 100644 index 000000000..7a8909271 --- /dev/null +++ b/forui/example/ios/Runner/GeneratedPluginRegistrant.h @@ -0,0 +1,19 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GeneratedPluginRegistrant_h +#define GeneratedPluginRegistrant_h + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface GeneratedPluginRegistrant : NSObject ++ (void)registerWithRegistry:(NSObject*)registry; +@end + +NS_ASSUME_NONNULL_END +#endif /* GeneratedPluginRegistrant_h */ diff --git a/forui/example/ios/Runner/GeneratedPluginRegistrant.m b/forui/example/ios/Runner/GeneratedPluginRegistrant.m new file mode 100644 index 000000000..c0d0cbad8 --- /dev/null +++ b/forui/example/ios/Runner/GeneratedPluginRegistrant.m @@ -0,0 +1,21 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#import "GeneratedPluginRegistrant.h" + +#if __has_include() +#import +#else +@import path_provider_foundation; +#endif + +@implementation GeneratedPluginRegistrant + ++ (void)registerWithRegistry:(NSObject*)registry { + [PathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@"PathProviderPlugin"]]; +} + +@end diff --git a/forui/lib/forui.dart b/forui/lib/forui.dart index a358f5f04..f37468f95 100644 --- a/forui/lib/forui.dart +++ b/forui/lib/forui.dart @@ -18,7 +18,7 @@ export 'src/widgets/box/box.dart'; 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_styles.dart'; export 'src/widgets/button/button_content_style.dart'; -export 'src/widgets/button/button_type_style.dart'; +export 'src/widgets/button/button_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 20d162a71..49d58579d 100644 --- a/forui/lib/src/theme/widget_data.dart +++ b/forui/lib/src/theme/widget_data.dart @@ -6,7 +6,7 @@ class FWidgetData { final FBoxStyle box; /// The button style. - final FButtonStyle button; + final FButtonStyles button; /// The card style. final FCardStyle card; diff --git a/forui/lib/src/widgets/button/button.dart b/forui/lib/src/widgets/button/button.dart index 49fc912dd..b125c722e 100644 --- a/forui/lib/src/widgets/button/button.dart +++ b/forui/lib/src/widgets/button/button.dart @@ -1,10 +1,14 @@ import 'package:flutter/material.dart'; import 'package:forui/forui.dart'; -import 'package:forui/src/widgets/button/button_content.dart'; -/// A [FButtonType] represents the possible states that a [FButton] can be in. -enum FButtonType { +import 'button_content.dart'; + + +sealed class FButtonDesign {} + +/// A [FButtonVariant] represents the possible states that a [FButton] can be in. +enum FButtonVariant implements FButtonDesign { /// a primary button primary, @@ -20,8 +24,6 @@ enum FButtonType { /// Represents a button widget. class FButton extends StatelessWidget { - /// The type of button. - final FButtonType type; /// Called when the FButton is tapped or otherwise activated. final VoidCallback? onPressed; @@ -30,63 +32,45 @@ class FButton extends StatelessWidget { final Widget child; /// The style. - final FButtonStyle? style; + final FButtonDesign style; /// Creates a [FButton] widget. FButton({ - required this.type, + required this.style, required this.onPressed, String? text, String? icon, - this.style, super.key, - }) : child = FButtonContent(text: text, icon: icon, style: style?.content); + }) : child = FButtonContent(text: text, icon: icon, style: style, disabled: onPressed == null); /// Creates a [FButton]. - const FButton.raw({required this.type, required this.onPressed, required this.child, this.style, super.key}); + const FButton.raw({required this.onPressed, required this.child, required this.style, super.key}); @override Widget build(BuildContext context) { - final style = this.style ?? FTheme.of(context).widgets.button; - - switch (type) { - case FButtonType.primary: - return _Button(onPressed: onPressed, style: style, type: style.primary, child: child); - case FButtonType.secondary: - return _Button(onPressed: onPressed, style: style, type: style.secondary, child: child); - case FButtonType.destructive: - return _Button(onPressed: onPressed, style: style, type: style.destructive, child: child); - case FButtonType.outlined: - return _Button(onPressed: onPressed, style: style, type: style.outlined, child: child); - } - } -} - -class _Button extends StatelessWidget { - final FButtonStyle style; - final FButtonTypeStyle type; - final Widget child; - final VoidCallback? onPressed; - - const _Button({ - required this.style, - required this.type, - required this.onPressed, - required this.child, - super.key, - }); - - @override - Widget build(BuildContext context) => FTappable( + final buttonStyles = FTheme.of(context).widgets.button; + + // TODO: Move into a method in the Style + final style = switch (this.style) { + final FButtonStyle style => style, + FButtonVariant.primary => buttonStyles.primary, + FButtonVariant.secondary => buttonStyles.secondary, + FButtonVariant.destructive => buttonStyles.destructive, + FButtonVariant.outlined => buttonStyles.outlined, + }; + + return FTappable( onPressed: onPressed, - child: Container( + child: DecoratedBox( decoration: BoxDecoration( - border: Border.all(color: type.border), + border: Border.all(color: onPressed == null ? style.border : style.disabled), borderRadius: style.borderRadius, - color: type.background, + color: style.background, ), - padding: style.padding, child: child, ), ); + } + + } diff --git a/forui/lib/src/widgets/button/button_content.dart b/forui/lib/src/widgets/button/button_content.dart index e1a9abf8b..11a172d15 100644 --- a/forui/lib/src/widgets/button/button_content.dart +++ b/forui/lib/src/widgets/button/button_content.dart @@ -13,7 +13,7 @@ final class FButtonContent extends StatelessWidget { final Widget? child; /// The style. - final FButtonContentStyle? style; + final FButtonStyle? style; /// Creates a [FButtonContent]. const FButtonContent({ @@ -26,19 +26,22 @@ final class FButtonContent extends StatelessWidget { @override 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!, - //TODO: How do I make this specific to Button Type - style: style.text)), - - if (child != null) child! - ]); + final style = this.style ?? FTheme.of(context).widgets.button.primary.content; + + return Padding( + padding: style.padding, + child: 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!, + //TODO: How do I make this specific to Button Type + style: style.text)), + + if (child != null) child! + ]), + ); } } diff --git a/forui/lib/src/widgets/button/button_content_style.dart b/forui/lib/src/widgets/button/button_content_style.dart index d4e9094f5..a79c5c875 100644 --- a/forui/lib/src/widgets/button/button_content_style.dart +++ b/forui/lib/src/widgets/button/button_content_style.dart @@ -6,20 +6,31 @@ class FButtonContentStyle { /// The title. final TextStyle text; + /// The padding. + final EdgeInsets padding; + /// Creates a [FButtonContentStyle]. const FButtonContentStyle({ required this.text, + required this.padding, }); /// Creates a [FButtonContentStyle] that inherits its properties from [style] and [font]. - FButtonContentStyle.inherit({required FStyleData style, required FFontData font}) - : text = ScaledTextStyle( + FButtonContentStyle.inherit({required FStyleData style, required FFontData font, required Color color}) + : + padding = const EdgeInsets.symmetric( + horizontal: 5, + vertical: 17, + ), + text = ScaledTextStyle( TextStyle( fontSize: 16, fontWeight: FontWeight.w600, //TODO: How do I make this specific to Button Type - color: style.primaryForeground, + color: color, ), font, ); + + } diff --git a/forui/lib/src/widgets/button/button_style.dart b/forui/lib/src/widgets/button/button_style.dart index 8c71ffc2f..317df55f4 100644 --- a/forui/lib/src/widgets/button/button_style.dart +++ b/forui/lib/src/widgets/button/button_style.dart @@ -1,205 +1,52 @@ import 'package:flutter/material.dart'; import 'package:forui/forui.dart'; -import 'package:sugar/collection.dart'; - -const _borderRadius = 8.0; -const _overlayOpacity = 0.20; -const _textStyle = TextStyle( - overflow: TextOverflow.ellipsis, - fontWeight: FontWeight.w600, - fontSize: 16, -); - -/// [FButtonStyle]'s style. +// TODO: make FButtonStyle extend Marked +/// Represents the theme data that is inherited by [FButtonStyle] and used by child [FButton] widgets. class FButtonStyle { - /// The primary style. - final FButtonTypeStyle primary; - - /// The secondary style. - final FButtonTypeStyle secondary; + /// The background color. + final Color background; - /// The destructive style. - final FButtonTypeStyle destructive; + /// The foreground color. + final Color foreground; - /// The outlined style. - final FButtonTypeStyle outlined; + /// The primary color. + final Color disabled; - /// The text. - final TextStyle text; + /// The border color. + final Color border; - /// The padding. - final EdgeInsets padding; - - /// The padding. + /// The border radius. final BorderRadius borderRadius; - /// The text. + /// The content. final FButtonContentStyle content; /// Creates a [FButtonStyle]. const FButtonStyle({ - required this.primary, - required this.secondary, - required this.destructive, - required this.outlined, - required this.text, - required this.padding, + required this.background, + required this.foreground, + required this.disabled, + required this.border, required this.borderRadius, required this.content, }); - /// Creates a [FButtonStyle] that inherits its properties from [data] and [style]. - FButtonStyle.inherit({required FFontData font, required FStyleData style}) - : primary = FButtonTypeStyle( - background: style.primary, - foreground: style.primaryForeground, - disabled: style.mutedForeground, - border: style.background, - ), - secondary = FButtonTypeStyle( - background: style.secondary, - foreground: style.secondaryForeground, - disabled: style.mutedForeground, - border: style.background, - ), - destructive = FButtonTypeStyle( - background: style.destructive, - foreground: style.foreground, - disabled: style.mutedForeground, - border: style.background, - ), - outlined = FButtonTypeStyle( - background: style.background, - foreground: style.foreground, - disabled: style.mutedForeground, - border: style.background, - ), - text = ScaledTextStyle(_textStyle, font), - padding = const EdgeInsets.symmetric( - horizontal: 5, - vertical: 17, - ), - borderRadius = style.borderRadius, - content = FButtonContentStyle.inherit(style: style, font: font); + /// Creates a copy of this [FButtonTypeStyle] with the given properties replaced. + FButtonStyle copyWith({ + Color? background, + Color? foreground, + Color? disabled, + Color? border, + BorderRadius? borderRadius, + FButtonContentStyle? content, + }) => + FButtonStyle( + background: background ?? this.background, + foreground: foreground ?? this.foreground, + disabled: disabled ?? this.disabled, + border: border ?? this.border, + borderRadius: borderRadius ?? this.borderRadius, + content: content ?? this.content, + ); } - - -final _primaryStyle = ButtonStyle( - backgroundColor: MaterialStateProperty.resolveWith( - (states) => states.contains(MaterialState.disabled) ? const Color(0xFFBFBFBF) : Colors.black, - ), - elevation: MaterialStateProperty.all(0), - foregroundColor: MaterialStateProperty.all(Colors.white), - overlayColor: MaterialStateProperty.resolveWith( - (states) => switch (states) { - _ when !disjoint(states, const {MaterialState.hovered, MaterialState.focused, MaterialState.pressed}) => - Colors.white.withOpacity(_overlayOpacity), - _ => null - }, - ), - splashFactory: NoSplash.splashFactory, - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(_borderRadius), - ), - ), - textStyle: MaterialStateProperty.all(_textStyle), -); - -final _secondaryStyle = ButtonStyle( - backgroundColor: MaterialStateProperty.all(const Color(0xFFE4E5E7)), - elevation: MaterialStateProperty.all(0), - overlayColor: MaterialStateProperty.resolveWith( - (states) => switch (states) { - _ when !disjoint(states, const {MaterialState.hovered, MaterialState.focused, MaterialState.pressed}) => - Colors.white.withOpacity(0.3), - _ => null - }, - ), - foregroundColor: MaterialStateProperty.resolveWith( - (states) => states.contains(MaterialState.disabled) ? Colors.white : Colors.black, - ), - splashFactory: NoSplash.splashFactory, - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(_borderRadius), - ), - ), - textStyle: MaterialStateProperty.all(_textStyle), -); - -final _destructiveStyle = ButtonStyle( - backgroundColor: MaterialStateProperty.resolveWith( - (states) => states.contains(MaterialState.disabled) ? const Color(0xFFBFBFBF) : Colors.red, - ), - elevation: MaterialStateProperty.all(0), - overlayColor: MaterialStateProperty.resolveWith( - (states) => switch (states) { - _ when !disjoint(states, const {MaterialState.hovered, MaterialState.focused, MaterialState.pressed}) => - Colors.white.withOpacity(_overlayOpacity), - _ => null - }, - ), - foregroundColor: MaterialStateProperty.all(Colors.white), - splashFactory: NoSplash.splashFactory, - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(_borderRadius), - ), - ), - textStyle: MaterialStateProperty.all(_textStyle), -); - -final _outlinedStyle = ButtonStyle( - side: MaterialStateProperty.all(const BorderSide(color: Color(0xFFE4E5E7))), - elevation: MaterialStateProperty.all(0), - backgroundColor: MaterialStateProperty.all(Colors.white), - foregroundColor: MaterialStateProperty.resolveWith( - (states) => states.contains(MaterialState.disabled) ? const Color(0xFFBFBFBF) : Colors.black, - ), - overlayColor: MaterialStateProperty.all(const Color(0xFFE4E5E7)), - splashFactory: NoSplash.splashFactory, - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(_borderRadius), - ), - ), - textStyle: MaterialStateProperty.all(_textStyle), -); - -final _linkStyle = ButtonStyle( - elevation: MaterialStateProperty.all(0), - backgroundColor: MaterialStateProperty.all(Colors.transparent), - foregroundColor: MaterialStateProperty.resolveWith( - (states) => switch (states) { - _ when !disjoint(states, const {MaterialState.hovered, MaterialState.focused, MaterialState.pressed}) => - Colors.black, - _ when states.contains(MaterialState.disabled) => const Color(0xFFBFBFBF), - _ => const Color(0xFF8E97AA), - }, - ), - overlayColor: MaterialStateProperty.all(Colors.transparent), - splashFactory: NoSplash.splashFactory, - shape: MaterialStateProperty.all(LinearBorder.bottom()), - side: MaterialStateProperty.resolveWith( - (states) => switch (states) { - _ when !disjoint(states, const {MaterialState.hovered, MaterialState.focused, MaterialState.pressed}) => - const BorderSide(), - _ when states.contains(MaterialState.disabled) => const BorderSide(color: Color(0xFFBFBFBF)), - _ => const BorderSide(color: Color(0xFF8E97AA)), - }, - ), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - visualDensity: VisualDensity.compact, - padding: MaterialStateProperty.all(const EdgeInsets.only(bottom: 10)), - minimumSize: MaterialStateProperty.all(Size.zero), - textStyle: MaterialStateProperty.all( - const TextStyle( - color: Color(0xFF8E97AA), - overflow: TextOverflow.ellipsis, - fontWeight: FontWeight.w400, - fontSize: 14, - ), - ), -); diff --git a/forui/lib/src/widgets/button/button_styles.dart b/forui/lib/src/widgets/button/button_styles.dart new file mode 100644 index 000000000..60999713b --- /dev/null +++ b/forui/lib/src/widgets/button/button_styles.dart @@ -0,0 +1,59 @@ +import 'package:forui/forui.dart'; + +/// [FButtonStyle]'s style. +class FButtonStyles { + /// The primary style. + final FButtonStyle primary; + + /// The secondary style. + final FButtonStyle secondary; + + /// The destructive style. + final FButtonStyle destructive; + + /// The outlined style. + final FButtonStyle outlined; + + /// Creates a [FButtonStyle]. + const FButtonStyles({ + required this.primary, + required this.secondary, + required this.destructive, + required this.outlined, + }); + + /// Creates a [FButtonStyle] that inherits its properties from [data] and [style]. + FButtonStyles.inherit({required FFontData font, required FStyleData style}) + : primary = FButtonStyle( + background: style.primary, + foreground: style.primaryForeground, + disabled: style.mutedForeground, + border: style.primary, + borderRadius: style.borderRadius, + content: FButtonContentStyle.inherit(style: style, font: font, color: style.primaryForeground,), + ), + secondary = FButtonStyle( + background: style.mutedForeground, + foreground: style.secondaryForeground, + disabled: style.mutedForeground, + border: style.mutedForeground, + borderRadius: style.borderRadius, + content: FButtonContentStyle.inherit(style: style, font: font, color: style.secondaryForeground,), + ), + destructive = FButtonStyle( + background: style.destructive, + foreground: style.foreground, + disabled: style.mutedForeground, + border: style.destructive, + borderRadius: style.borderRadius, + content: FButtonContentStyle.inherit(style: style, font: font, color: style.foreground,), + ), + outlined = FButtonStyle( + background: style.secondary, + foreground: style.secondaryForeground, + disabled: style.mutedForeground, + border: style.mutedForeground, + borderRadius: style.borderRadius, + content: FButtonContentStyle.inherit(style: style, font: font, color: style.secondaryForeground,), + ); +} diff --git a/forui/lib/src/widgets/button/button_type_style.dart b/forui/lib/src/widgets/button/button_type_style.dart deleted file mode 100644 index ed9d217fd..000000000 --- a/forui/lib/src/widgets/button/button_type_style.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -/// Represents the theme data that is inherited by [FButtonStyle] and used by child [FButton] widgets. -class FButtonTypeStyle { - /// The background color. - final Color background; - - /// The foreground color. - final Color foreground; - - /// The primary color. - final Color disabled; - - /// The border color. - final Color border; - - /// Creates a [FButtonTypeStyle]. - const FButtonTypeStyle({ - required this.background, - required this.foreground, - required this.disabled, - required this.border, - }); - - /// Creates a copy of this [FButtonTypeStyle] with the given properties replaced. - FButtonTypeStyle copyWith({ - Color? background, - Color? foreground, - Color? disabled, - Color? border, - }) => - FButtonTypeStyle( - background: background ?? this.background, - foreground: foreground ?? this.foreground, - disabled: disabled ?? this.disabled, - border: border ?? this.border, - ); -}