From c682f0031920b0a29d3e001d3084d716f4bff21c Mon Sep 17 00:00:00 2001 From: Joe Date: Fri, 17 May 2024 12:56:24 +0800 Subject: [PATCH] Initial card widget --- forui/lib/forui.dart | 3 +- forui/lib/src/theme/widget_data.dart | 22 +++++++--- forui/lib/src/widgets/box/box.dart | 2 + forui/lib/src/widgets/box/box_style.dart | 10 ++--- forui/lib/src/widgets/card/card.dart | 38 ++++++++++++++++++ forui/lib/src/widgets/card/card_content.dart | 40 +++++++++++++++++++ .../src/widgets/card/card_content_style.dart | 35 ++++++++++++++++ forui/lib/src/widgets/card/card_style.dart | 21 ++++++++++ samples/ios/Runner.xcodeproj/project.pbxproj | 4 +- samples/lib/main.dart | 22 +++++++--- samples/pubspec.lock | 24 +++++------ 11 files changed, 189 insertions(+), 32 deletions(-) create mode 100644 forui/lib/src/widgets/card/card.dart create mode 100644 forui/lib/src/widgets/card/card_content.dart create mode 100644 forui/lib/src/widgets/card/card_content_style.dart create mode 100644 forui/lib/src/widgets/card/card_style.dart diff --git a/forui/lib/forui.dart b/forui/lib/forui.dart index 3f5fc5b56..2538eafad 100644 --- a/forui/lib/forui.dart +++ b/forui/lib/forui.dart @@ -10,8 +10,9 @@ export 'src/theme/widget_data.dart'; export 'src/theme/font/font_data.dart'; export 'src/theme/font/scaled_text_style.dart'; +// Themes export 'src/themes/zinc_theme.dart'; // Widgets export 'src/widgets/box/box.dart'; -export 'src/widgets/box/box_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 f63a3ddce..92c6e65cc 100644 --- a/forui/lib/src/theme/widget_data.dart +++ b/forui/lib/src/theme/widget_data.dart @@ -5,17 +5,27 @@ class FWidgetData { /// The box style. final FBoxStyle box; + /// The card style. + final FCardStyle card; + /// Creates a [FWidgetData]. - FWidgetData({required this.box}); + FWidgetData({ + required this.box, + required this.card, + }); /// Creates a [FWidgetData] that inherits the properties from the given [FFontData] and [FStyleData]. - FWidgetData.inherit({required FFontData data, required FStyleData style}): - box = FBoxStyle.inherit(data: data, style: style); + FWidgetData.inherit({required FFontData data, required FStyleData style}) + : box = FBoxStyle.inherit(style: style, font: data), + card = FCardStyle.inherit(style: style, font: data); /// Creates a copy of this [FWidgetData] with the given properties replaced. FWidgetData copyWith({ FBoxStyle? boxStyle, - }) => FWidgetData( - box: boxStyle ?? box, - ); + FCardStyle? cardStyle, + }) => + FWidgetData( + box: boxStyle ?? box, + card: cardStyle ?? card, + ); } diff --git a/forui/lib/src/widgets/box/box.dart b/forui/lib/src/widgets/box/box.dart index 9d1c8a752..63e7aed6e 100644 --- a/forui/lib/src/widgets/box/box.dart +++ b/forui/lib/src/widgets/box/box.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:forui/forui.dart'; +part 'box_style.dart'; + /// A sample widget that demonstrates Forui's architecture. class FBox extends StatelessWidget { /// The text. diff --git a/forui/lib/src/widgets/box/box_style.dart b/forui/lib/src/widgets/box/box_style.dart index bf4bf75c7..b06928f66 100644 --- a/forui/lib/src/widgets/box/box_style.dart +++ b/forui/lib/src/widgets/box/box_style.dart @@ -1,6 +1,4 @@ -import 'package:flutter/material.dart'; - -import 'package:forui/forui.dart'; +part of 'box.dart'; /// [FBox]'s style. class FBoxStyle { @@ -13,7 +11,7 @@ class FBoxStyle { /// Creates a [FBoxStyle]. const FBoxStyle({required this.color, required this.text}); - /// Creates a [FBoxStyle] that inherits its properties from [data] and [style]. - FBoxStyle.inherit({required FFontData data, required FStyleData style}): - color = style.background, text = ScaledTextStyle(const TextStyle(fontSize: 20), data); + /// Creates a [FBoxStyle] that inherits its properties from [font] and [style]. + FBoxStyle.inherit({required FStyleData style, required FFontData font}): + color = style.muted, text = ScaledTextStyle(const TextStyle(fontSize: 20), font); } diff --git a/forui/lib/src/widgets/card/card.dart b/forui/lib/src/widgets/card/card.dart new file mode 100644 index 000000000..f46f25a4e --- /dev/null +++ b/forui/lib/src/widgets/card/card.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; + +import 'package:forui/forui.dart'; + +part 'card_content.dart'; +part 'card_style.dart'; +part 'card_content_style.dart'; + +/// Represents a card widget. +class FCard extends StatelessWidget { + /// The child. + final Widget child; + + /// The style. + final FCardStyle? style; + + /// Creates a [FCard]. + FCard({ + String? title, + String? subtitle, + Widget? content, + this.style, + super.key, + }) : child = FCardContent(title: title, subtitle: subtitle, content: content); + + /// Creates a [FCard]. + const FCard.raw({required this.child, this.style, super.key}); + + @override + Widget build(BuildContext context) { + final style = this.style ?? FTheme.of(context).widgets.card; + + return DecoratedBox( + decoration: style.decoration, + child: child, + ); + } +} diff --git a/forui/lib/src/widgets/card/card_content.dart b/forui/lib/src/widgets/card/card_content.dart new file mode 100644 index 000000000..7e9366519 --- /dev/null +++ b/forui/lib/src/widgets/card/card_content.dart @@ -0,0 +1,40 @@ +part of 'card.dart'; + +/// Represents a content for [FCard]. +final class FCardContent extends StatelessWidget { + /// The title. + final String? title; + + /// The subtitle. + final String? subtitle; + + /// The child. + final Widget? content; + + /// The style. + final FCardContentStyle? style; + + /// Creates a [FCardContent]. + const FCardContent({this.title, this.subtitle, this.content, this.style, super.key}); + + @override + Widget build(BuildContext context) { + final style = this.style ?? FTheme.of(context).widgets.card.content; + + return Padding( + padding: const EdgeInsets.fromLTRB(16, 12, 16, 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (title != null) Text(title!, style: style.title), + if (subtitle != null) Text(subtitle!, style: style.subtitle), + if (content != null) + Padding( + padding: (title != null || subtitle != null) ? const EdgeInsets.only(top: 10) : const EdgeInsets.only(top: 4), + child: content!, + ), + ], + ), + ); + } +} diff --git a/forui/lib/src/widgets/card/card_content_style.dart b/forui/lib/src/widgets/card/card_content_style.dart new file mode 100644 index 000000000..e6c68b5c2 --- /dev/null +++ b/forui/lib/src/widgets/card/card_content_style.dart @@ -0,0 +1,35 @@ +part of 'card.dart'; + +/// [FCardContent]'s style. +class FCardContentStyle { + /// The padding. + final EdgeInsets padding; + + /// The title. + final TextStyle title; + + /// The subtitle. + final TextStyle subtitle; + + /// Creates a [FCardContentStyle]. + const FCardContentStyle({required this.padding, required this.title, required this.subtitle}); + + /// Creates a [FCardContentStyle] that inherits its properties from [style] and [font]. + FCardContentStyle.inherit({required FStyleData style, required FFontData font}) + : padding = const EdgeInsets.all(20), + title = ScaledTextStyle( + TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: style.foreground, + ), + font, + ), + subtitle = ScaledTextStyle( + TextStyle( + fontSize: 12, + color: style.mutedForeground, + ), + font, + ); +} diff --git a/forui/lib/src/widgets/card/card_style.dart b/forui/lib/src/widgets/card/card_style.dart new file mode 100644 index 000000000..7429c80dd --- /dev/null +++ b/forui/lib/src/widgets/card/card_style.dart @@ -0,0 +1,21 @@ +part of 'card.dart'; + +/// [FCard]'s style. +class FCardStyle { + /// The decoration. + final BoxDecoration decoration; + + /// The [FCardContent] style. + final FCardContentStyle content; + + /// Creates a [FCardStyle]. + FCardStyle({required this.decoration, required this.content}); + + /// Creates a [FCardStyle] that inherits its properties from [style] and [font]. + FCardStyle.inherit({required FStyleData style, required FFontData font}) + : decoration = BoxDecoration( + border: Border.all(color: style.border), + borderRadius: style.borderRadius, + ), + content = FCardContentStyle.inherit(style: style, font: font); +} diff --git a/samples/ios/Runner.xcodeproj/project.pbxproj b/samples/ios/Runner.xcodeproj/project.pbxproj index 802f3e682..d56f0a8d3 100644 --- a/samples/ios/Runner.xcodeproj/project.pbxproj +++ b/samples/ios/Runner.xcodeproj/project.pbxproj @@ -161,7 +161,6 @@ 5DAA52B6E1FD3566C27C266B /* Pods-RunnerTests.release.xcconfig */, FDF022EB433B927048DC1954 /* Pods-RunnerTests.profile.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -471,6 +470,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = TKQ634K5JU; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -653,6 +653,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = TKQ634K5JU; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -675,6 +676,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = TKQ634K5JU; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/samples/lib/main.dart b/samples/lib/main.dart index 46b94187c..afa557779 100644 --- a/samples/lib/main.dart +++ b/samples/lib/main.dart @@ -16,12 +16,22 @@ class Application extends StatelessWidget { home: FTheme( data: FZincTheme.light, child: Scaffold( - body: Container( - alignment: Alignment.center, - // TODO: Replace with FText. - child: Text( - 'Hello', - style: ScaledTextStyle(const TextStyle(fontWeight: FontWeight.w500), FTheme.of(context).font), + backgroundColor: Colors.white, + body: Padding( + padding: const EdgeInsets.all(16), + child: ListView( + children: [ + FCard( + title: 'Notification', + subtitle: 'You have 3 unread messages.', + content: const SizedBox( + width: double.infinity, + child: FBox( + text: 'BODY', + ), + ), + ), + ], ), ), ), diff --git a/samples/pubspec.lock b/samples/pubspec.lock index 28e312b4a..9c5846592 100644 --- a/samples/pubspec.lock +++ b/samples/pubspec.lock @@ -310,26 +310,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" logging: dependency: transitive description: @@ -358,10 +358,10 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.0" mime: dependency: transitive description: @@ -580,10 +580,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" timing: dependency: transitive description: @@ -612,10 +612,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.1" watcher: dependency: transitive description: