From 8fea86c8988427862e1c5e03b99a7bd981620e72 Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Wed, 10 Sep 2025 15:38:19 +0700 Subject: [PATCH 01/11] Release v1.9.1 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 6a58706..f267107 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: supa_architecture description: Architecture library for Supa Flutter applications -version: 1.9.1+6 +version: 1.9.1 homepage: https://github.supa.vn environment: From 696e0357a7c5d412028407edd866b7d2e7073e48 Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Thu, 11 Sep 2025 09:25:17 +0700 Subject: [PATCH 02/11] Update JSON serialization methods in TestNestedSerializableClass to improve performance and maintainability. Refactor nestedObject and nestedList to use public fields. --- lib/theme/supa_extended_color_theme.dart | 630 ++++++++++++++++++ .../supa_extended_color_token_group.dart | 13 + 2 files changed, 643 insertions(+) create mode 100644 lib/theme/supa_extended_color_theme.dart create mode 100644 lib/theme/supa_extended_color_token_group.dart diff --git a/lib/theme/supa_extended_color_theme.dart b/lib/theme/supa_extended_color_theme.dart new file mode 100644 index 0000000..5409fc2 --- /dev/null +++ b/lib/theme/supa_extended_color_theme.dart @@ -0,0 +1,630 @@ +import 'package:flutter/material.dart'; + +import 'supa_extended_color_token_group.dart'; + +class SupaExtendedColorScheme extends ThemeExtension { + // Warning colors + final Color warningText; + final Color warningBackground; + final Color warningBorder; + + // Information colors + final Color informationText; + final Color informationBackground; + final Color informationBorder; + + // Success colors + final Color successText; + final Color successBackground; + final Color successBorder; + + // Default colors + final Color defaultText; + final Color defaultBackground; + final Color defaultBorder; + + // Error colors + final Color errorText; + final Color errorBackground; + final Color errorBorder; + + // Blue tag colors + final Color blueTagText; + final Color blueTagBackground; + final Color blueTagBorder; + + // Cyan tag colors + final Color cyanTagText; + final Color cyanTagBackground; + final Color cyanTagBorder; + + // Geek blue tag colors + final Color geekblueTagText; + final Color geekblueTagBackground; + final Color geekblueTagBorder; + + // Gold tag colors + final Color goldTagText; + final Color goldTagBackground; + final Color goldTagBorder; + + // Green tag colors + final Color greenTagText; + final Color greenTagBackground; + final Color greenTagBorder; + + // Lime tag colors + final Color limeTagText; + final Color limeTagBackground; + final Color limeTagBorder; + + // Magenta tag colors + final Color magentaTagText; + final Color magentaTagBackground; + final Color magentaTagBorder; + + // Orange tag colors + final Color orangeTagText; + final Color orangeTagBackground; + final Color orangeTagBorder; + + // Purple tag colors + final Color purpleTagText; + final Color purpleTagBackground; + final Color purpleTagBorder; + + // Red tag colors + final Color redTagText; + final Color redTagBackground; + final Color redTagBorder; + + // Volcano tag colors + final Color volcanoTagText; + final Color volcanoTagBackground; + final Color volcanoTagBorder; + + const SupaExtendedColorScheme({ + required this.warningText, + required this.warningBackground, + required this.warningBorder, + required this.informationText, + required this.informationBackground, + required this.informationBorder, + required this.successText, + required this.successBackground, + required this.successBorder, + required this.defaultText, + required this.defaultBackground, + required this.defaultBorder, + required this.errorText, + required this.errorBackground, + required this.errorBorder, + required this.blueTagText, + required this.blueTagBackground, + required this.blueTagBorder, + required this.cyanTagText, + required this.cyanTagBackground, + required this.cyanTagBorder, + required this.geekblueTagText, + required this.geekblueTagBackground, + required this.geekblueTagBorder, + required this.goldTagText, + required this.goldTagBackground, + required this.goldTagBorder, + required this.greenTagText, + required this.greenTagBackground, + required this.greenTagBorder, + required this.limeTagText, + required this.limeTagBackground, + required this.limeTagBorder, + required this.magentaTagText, + required this.magentaTagBackground, + required this.magentaTagBorder, + required this.orangeTagText, + required this.orangeTagBackground, + required this.orangeTagBorder, + required this.purpleTagText, + required this.purpleTagBackground, + required this.purpleTagBorder, + required this.redTagText, + required this.redTagBackground, + required this.redTagBorder, + required this.volcanoTagText, + required this.volcanoTagBackground, + required this.volcanoTagBorder, + }); + + @override + ThemeExtension copyWith({ + Color? warningText, + Color? warningBackground, + Color? warningBorder, + Color? informationText, + Color? informationBackground, + Color? informationBorder, + Color? successText, + Color? successBackground, + Color? successBorder, + Color? defaultText, + Color? defaultBackground, + Color? defaultBorder, + Color? errorText, + Color? errorBackground, + Color? errorBorder, + Color? blueTagText, + Color? blueTagBackground, + Color? blueTagBorder, + Color? cyanTagText, + Color? cyanTagBackground, + Color? cyanTagBorder, + Color? geekblueTagText, + Color? geekblueTagBackground, + Color? geekblueTagBorder, + Color? goldTagText, + Color? goldTagBackground, + Color? goldTagBorder, + Color? greenTagText, + Color? greenTagBackground, + Color? greenTagBorder, + Color? limeTagText, + Color? limeTagBackground, + Color? limeTagBorder, + Color? magentaTagText, + Color? magentaTagBackground, + Color? magentaTagBorder, + Color? orangeTagText, + Color? orangeTagBackground, + Color? orangeTagBorder, + Color? purpleTagText, + Color? purpleTagBackground, + Color? purpleTagBorder, + Color? redTagText, + Color? redTagBackground, + Color? redTagBorder, + Color? volcanoTagText, + Color? volcanoTagBackground, + Color? volcanoTagBorder, + }) { + return SupaExtendedColorScheme( + warningText: warningText ?? this.warningText, + warningBackground: warningBackground ?? this.warningBackground, + warningBorder: warningBorder ?? this.warningBorder, + informationText: informationText ?? this.informationText, + informationBackground: + informationBackground ?? this.informationBackground, + informationBorder: informationBorder ?? this.informationBorder, + successText: successText ?? this.successText, + successBackground: successBackground ?? this.successBackground, + successBorder: successBorder ?? this.successBorder, + defaultText: defaultText ?? this.defaultText, + defaultBackground: defaultBackground ?? this.defaultBackground, + defaultBorder: defaultBorder ?? this.defaultBorder, + errorText: errorText ?? this.errorText, + errorBackground: errorBackground ?? this.errorBackground, + errorBorder: errorBorder ?? this.errorBorder, + blueTagText: blueTagText ?? this.blueTagText, + blueTagBackground: blueTagBackground ?? this.blueTagBackground, + blueTagBorder: blueTagBorder ?? this.blueTagBorder, + cyanTagText: cyanTagText ?? this.cyanTagText, + cyanTagBackground: cyanTagBackground ?? this.cyanTagBackground, + cyanTagBorder: cyanTagBorder ?? this.cyanTagBorder, + geekblueTagText: geekblueTagText ?? this.geekblueTagText, + geekblueTagBackground: + geekblueTagBackground ?? this.geekblueTagBackground, + geekblueTagBorder: geekblueTagBorder ?? this.geekblueTagBorder, + goldTagText: goldTagText ?? this.goldTagText, + goldTagBackground: goldTagBackground ?? this.goldTagBackground, + goldTagBorder: goldTagBorder ?? this.goldTagBorder, + greenTagText: greenTagText ?? this.greenTagText, + greenTagBackground: greenTagBackground ?? this.greenTagBackground, + greenTagBorder: greenTagBorder ?? this.greenTagBorder, + limeTagText: limeTagText ?? this.limeTagText, + limeTagBackground: limeTagBackground ?? this.limeTagBackground, + limeTagBorder: limeTagBorder ?? this.limeTagBorder, + magentaTagText: magentaTagText ?? this.magentaTagText, + magentaTagBackground: magentaTagBackground ?? this.magentaTagBackground, + magentaTagBorder: magentaTagBorder ?? this.magentaTagBorder, + orangeTagText: orangeTagText ?? this.orangeTagText, + orangeTagBackground: orangeTagBackground ?? this.orangeTagBackground, + orangeTagBorder: orangeTagBorder ?? this.orangeTagBorder, + purpleTagText: purpleTagText ?? this.purpleTagText, + purpleTagBackground: purpleTagBackground ?? this.purpleTagBackground, + purpleTagBorder: purpleTagBorder ?? this.purpleTagBorder, + redTagText: redTagText ?? this.redTagText, + redTagBackground: redTagBackground ?? this.redTagBackground, + redTagBorder: redTagBorder ?? this.redTagBorder, + volcanoTagText: volcanoTagText ?? this.volcanoTagText, + volcanoTagBackground: volcanoTagBackground ?? this.volcanoTagBackground, + volcanoTagBorder: volcanoTagBorder ?? this.volcanoTagBorder, + ); + } + + @override + ThemeExtension lerp( + covariant ThemeExtension? other, + double t, + ) { + if (other is! SupaExtendedColorScheme) { + return this; + } + + return SupaExtendedColorScheme( + warningText: Color.lerp(warningText, other.warningText, t) ?? warningText, + warningBackground: + Color.lerp(warningBackground, other.warningBackground, t) ?? + warningBackground, + warningBorder: + Color.lerp(warningBorder, other.warningBorder, t) ?? warningBorder, + informationText: Color.lerp(informationText, other.informationText, t) ?? + informationText, + informationBackground: + Color.lerp(informationBackground, other.informationBackground, t) ?? + informationBackground, + informationBorder: + Color.lerp(informationBorder, other.informationBorder, t) ?? + informationBorder, + successText: Color.lerp(successText, other.successText, t) ?? successText, + successBackground: + Color.lerp(successBackground, other.successBackground, t) ?? + successBackground, + successBorder: + Color.lerp(successBorder, other.successBorder, t) ?? successBorder, + defaultText: Color.lerp(defaultText, other.defaultText, t) ?? defaultText, + defaultBackground: + Color.lerp(defaultBackground, other.defaultBackground, t) ?? + defaultBackground, + defaultBorder: + Color.lerp(defaultBorder, other.defaultBorder, t) ?? defaultBorder, + errorText: Color.lerp(errorText, other.errorText, t) ?? errorText, + errorBackground: Color.lerp(errorBackground, other.errorBackground, t) ?? + errorBackground, + errorBorder: Color.lerp(errorBorder, other.errorBorder, t) ?? errorBorder, + blueTagText: Color.lerp(blueTagText, other.blueTagText, t) ?? blueTagText, + blueTagBackground: + Color.lerp(blueTagBackground, other.blueTagBackground, t) ?? + blueTagBackground, + blueTagBorder: + Color.lerp(blueTagBorder, other.blueTagBorder, t) ?? blueTagBorder, + cyanTagText: Color.lerp(cyanTagText, other.cyanTagText, t) ?? cyanTagText, + cyanTagBackground: + Color.lerp(cyanTagBackground, other.cyanTagBackground, t) ?? + cyanTagBackground, + cyanTagBorder: + Color.lerp(cyanTagBorder, other.cyanTagBorder, t) ?? cyanTagBorder, + geekblueTagText: Color.lerp(geekblueTagText, other.geekblueTagText, t) ?? + geekblueTagText, + geekblueTagBackground: + Color.lerp(geekblueTagBackground, other.geekblueTagBackground, t) ?? + geekblueTagBackground, + geekblueTagBorder: + Color.lerp(geekblueTagBorder, other.geekblueTagBorder, t) ?? + geekblueTagBorder, + goldTagText: Color.lerp(goldTagText, other.goldTagText, t) ?? goldTagText, + goldTagBackground: + Color.lerp(goldTagBackground, other.goldTagBackground, t) ?? + goldTagBackground, + goldTagBorder: + Color.lerp(goldTagBorder, other.goldTagBorder, t) ?? goldTagBorder, + greenTagText: + Color.lerp(greenTagText, other.greenTagText, t) ?? greenTagText, + greenTagBackground: + Color.lerp(greenTagBackground, other.greenTagBackground, t) ?? + greenTagBackground, + greenTagBorder: + Color.lerp(greenTagBorder, other.greenTagBorder, t) ?? greenTagBorder, + limeTagText: Color.lerp(limeTagText, other.limeTagText, t) ?? limeTagText, + limeTagBackground: + Color.lerp(limeTagBackground, other.limeTagBackground, t) ?? + limeTagBackground, + limeTagBorder: + Color.lerp(limeTagBorder, other.limeTagBorder, t) ?? limeTagBorder, + magentaTagText: + Color.lerp(magentaTagText, other.magentaTagText, t) ?? magentaTagText, + magentaTagBackground: + Color.lerp(magentaTagBackground, other.magentaTagBackground, t) ?? + magentaTagBackground, + magentaTagBorder: + Color.lerp(magentaTagBorder, other.magentaTagBorder, t) ?? + magentaTagBorder, + orangeTagText: + Color.lerp(orangeTagText, other.orangeTagText, t) ?? orangeTagText, + orangeTagBackground: + Color.lerp(orangeTagBackground, other.orangeTagBackground, t) ?? + orangeTagBackground, + orangeTagBorder: Color.lerp(orangeTagBorder, other.orangeTagBorder, t) ?? + orangeTagBorder, + purpleTagText: + Color.lerp(purpleTagText, other.purpleTagText, t) ?? purpleTagText, + purpleTagBackground: + Color.lerp(purpleTagBackground, other.purpleTagBackground, t) ?? + purpleTagBackground, + purpleTagBorder: Color.lerp(purpleTagBorder, other.purpleTagBorder, t) ?? + purpleTagBorder, + redTagText: Color.lerp(redTagText, other.redTagText, t) ?? redTagText, + redTagBackground: + Color.lerp(redTagBackground, other.redTagBackground, t) ?? + redTagBackground, + redTagBorder: + Color.lerp(redTagBorder, other.redTagBorder, t) ?? redTagBorder, + volcanoTagText: + Color.lerp(volcanoTagText, other.volcanoTagText, t) ?? volcanoTagText, + volcanoTagBackground: + Color.lerp(volcanoTagBackground, other.volcanoTagBackground, t) ?? + volcanoTagBackground, + volcanoTagBorder: + Color.lerp(volcanoTagBorder, other.volcanoTagBorder, t) ?? + volcanoTagBorder, + ); + } + + SupaExtendedColorTokenGroup getTokenGroup(String name) { + switch (name) { + case 'warning': + return SupaExtendedColorTokenGroup( + text: warningText, + background: warningBackground, + border: warningBorder, + ); + case 'information': + return SupaExtendedColorTokenGroup( + text: informationText, + background: informationBackground, + border: informationBorder, + ); + case 'success': + return SupaExtendedColorTokenGroup( + text: successText, + background: successBackground, + border: successBorder, + ); + case 'default': + return SupaExtendedColorTokenGroup( + text: defaultText, + background: defaultBackground, + border: defaultBorder, + ); + case 'error': + return SupaExtendedColorTokenGroup( + text: errorText, + background: errorBackground, + border: errorBorder, + ); + case 'blueTag': + return SupaExtendedColorTokenGroup( + text: blueTagText, + background: blueTagBackground, + border: blueTagBorder, + ); + case 'cyanTag': + return SupaExtendedColorTokenGroup( + text: cyanTagText, + background: cyanTagBackground, + border: cyanTagBorder, + ); + case 'geekblueTag': + return SupaExtendedColorTokenGroup( + text: geekblueTagText, + background: geekblueTagBackground, + border: geekblueTagBorder, + ); + case 'goldTag': + return SupaExtendedColorTokenGroup( + text: goldTagText, + background: goldTagBackground, + border: goldTagBorder, + ); + case 'greenTag': + return SupaExtendedColorTokenGroup( + text: greenTagText, + background: greenTagBackground, + border: greenTagBorder, + ); + case 'limeTag': + return SupaExtendedColorTokenGroup( + text: limeTagText, + background: limeTagBackground, + border: limeTagBorder, + ); + case 'magentaTag': + return SupaExtendedColorTokenGroup( + text: magentaTagText, + background: magentaTagBackground, + border: magentaTagBorder, + ); + case 'orangeTag': + return SupaExtendedColorTokenGroup( + text: orangeTagText, + background: orangeTagBackground, + border: orangeTagBorder, + ); + case 'purpleTag': + return SupaExtendedColorTokenGroup( + text: purpleTagText, + background: purpleTagBackground, + border: purpleTagBorder, + ); + case 'redTag': + return SupaExtendedColorTokenGroup( + text: redTagText, + background: redTagBackground, + border: redTagBorder, + ); + case 'volcanoTag': + return SupaExtendedColorTokenGroup( + text: volcanoTagText, + background: volcanoTagBackground, + border: volcanoTagBorder, + ); + default: + throw Exception('Invalid token group name: $name'); + } + } + + // Helper methods to match SupaExtendedColorScheme interface + Color getTextColor(String key) { + switch (key) { + case 'warning': + return warningText; + case 'processing': + return informationText; + case 'success': + return successText; + case 'critical': + return errorText; + case 'error': + return errorText; + case 'defaultColor': + return defaultText; + case 'blue': + return blueTagText; + case 'cyan': + return cyanTagText; + case 'geekblue': + return geekblueTagText; + case 'gold': + return goldTagText; + case 'green': + return greenTagText; + case 'lime': + return limeTagText; + case 'magenta': + return magentaTagText; + case 'orange': + return orangeTagText; + case 'purple': + return purpleTagText; + case 'red': + return redTagText; + case 'volcano': + return volcanoTagText; + default: + return defaultText; + } + } + + Color getBackgroundColor(String key) { + switch (key) { + case 'warning': + return warningBackground; + case 'processing': + return informationBackground; + case 'success': + return successBackground; + case 'critical': + return errorBackground; + case 'error': + return errorBackground; + case 'defaultColor': + return defaultBackground; + case 'blue': + return blueTagBackground; + case 'cyan': + return cyanTagBackground; + case 'geekblue': + return geekblueTagBackground; + case 'gold': + return goldTagBackground; + case 'green': + return greenTagBackground; + case 'lime': + return limeTagBackground; + case 'magenta': + return magentaTagBackground; + case 'orange': + return orangeTagBackground; + case 'purple': + return purpleTagBackground; + case 'red': + return redTagBackground; + case 'volcano': + return volcanoTagBackground; + default: + return defaultBackground; + } + } + + Color getBorderColor(String key) { + switch (key) { + case 'warning': + return warningBorder; + case 'processing': + return informationBorder; + case 'success': + return successBorder; + case 'critical': + return errorBorder; + case 'error': + return errorBorder; + case 'defaultColor': + return defaultBorder; + case 'blue': + return blueTagBorder; + case 'cyan': + return cyanTagBorder; + case 'geekblue': + return geekblueTagBorder; + case 'gold': + return goldTagBorder; + case 'green': + return greenTagBorder; + case 'lime': + return limeTagBorder; + case 'magenta': + return magentaTagBorder; + case 'orange': + return orangeTagBorder; + case 'purple': + return purpleTagBorder; + case 'red': + return redTagBorder; + case 'volcano': + return volcanoTagBorder; + default: + return defaultBorder; + } + } + + Color fromKey(String key) { + switch (key) { + case 'warning': + return warningText; + case 'onWarning': + return warningBackground; + case 'warningContainer': + return warningBorder; + case 'onWarningContainer': + return warningText; + case 'information': + return informationText; + case 'onInformation': + return informationBackground; + case 'informationContainer': + return informationBorder; + case 'onInformationContainer': + return informationText; + case 'success': + return successText; + case 'onSuccess': + return successBackground; + case 'successContainer': + return successBorder; + case 'onSuccessContainer': + return successText; + case 'default': + case 'defaultColor': + return defaultText; + case 'onDefault': + return defaultBackground; + case 'defaultContainer': + return defaultBorder; + case 'onDefaultContainer': + return defaultText; + case 'critical': + return errorText; + case 'onCritical': + return errorBackground; + default: + return defaultText; + } + } +} diff --git a/lib/theme/supa_extended_color_token_group.dart b/lib/theme/supa_extended_color_token_group.dart new file mode 100644 index 0000000..f967983 --- /dev/null +++ b/lib/theme/supa_extended_color_token_group.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class SupaExtendedColorTokenGroup { + final Color text; + final Color background; + final Color border; + + const SupaExtendedColorTokenGroup({ + required this.text, + required this.background, + required this.border, + }); +} From 1c84cc7ce67c0afea021207a3f06e9a69ab7370c Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Thu, 11 Sep 2025 09:36:36 +0700 Subject: [PATCH 03/11] Refactor SupaExtendedColorScheme to use constants for color keys, improving readability and maintainability. Update switch cases to utilize these constants for color token retrieval. --- lib/theme/supa_extended_color_theme.dart | 206 +++++++++++------------ 1 file changed, 95 insertions(+), 111 deletions(-) diff --git a/lib/theme/supa_extended_color_theme.dart b/lib/theme/supa_extended_color_theme.dart index 5409fc2..d9e87e2 100644 --- a/lib/theme/supa_extended_color_theme.dart +++ b/lib/theme/supa_extended_color_theme.dart @@ -2,6 +2,26 @@ import 'package:flutter/material.dart'; import 'supa_extended_color_token_group.dart'; +const String _default = 'default'; +const String _warning = 'warning'; +const String _information = 'information'; +const String _success = 'success'; +const String _error = 'error'; +const String _blueTag = 'blue'; +const String _cyanTag = 'cyan'; +const String _geekblueTag = 'geekblue'; +const String _goldTag = 'gold'; +const String _greenTag = 'green'; +const String _limeTag = 'lime'; +const String _magentaTag = 'magenta'; +const String _orangeTag = 'orange'; +const String _purpleTag = 'purple'; +const String _redTag = 'red'; +const String _volcanoTag = 'volcano'; + +const String _processing = 'processing'; +const String _critical = 'critical'; + class SupaExtendedColorScheme extends ThemeExtension { // Warning colors final Color warningText; @@ -359,97 +379,97 @@ class SupaExtendedColorScheme extends ThemeExtension { SupaExtendedColorTokenGroup getTokenGroup(String name) { switch (name) { - case 'warning': + case _warning: return SupaExtendedColorTokenGroup( text: warningText, background: warningBackground, border: warningBorder, ); - case 'information': + case _information: return SupaExtendedColorTokenGroup( text: informationText, background: informationBackground, border: informationBorder, ); - case 'success': + case _success: return SupaExtendedColorTokenGroup( text: successText, background: successBackground, border: successBorder, ); - case 'default': + case _default: return SupaExtendedColorTokenGroup( text: defaultText, background: defaultBackground, border: defaultBorder, ); - case 'error': + case _error: return SupaExtendedColorTokenGroup( text: errorText, background: errorBackground, border: errorBorder, ); - case 'blueTag': + case _blueTag: return SupaExtendedColorTokenGroup( text: blueTagText, background: blueTagBackground, border: blueTagBorder, ); - case 'cyanTag': + case _cyanTag: return SupaExtendedColorTokenGroup( text: cyanTagText, background: cyanTagBackground, border: cyanTagBorder, ); - case 'geekblueTag': + case _geekblueTag: return SupaExtendedColorTokenGroup( text: geekblueTagText, background: geekblueTagBackground, border: geekblueTagBorder, ); - case 'goldTag': + case _goldTag: return SupaExtendedColorTokenGroup( text: goldTagText, background: goldTagBackground, border: goldTagBorder, ); - case 'greenTag': + case _greenTag: return SupaExtendedColorTokenGroup( text: greenTagText, background: greenTagBackground, border: greenTagBorder, ); - case 'limeTag': + case _limeTag: return SupaExtendedColorTokenGroup( text: limeTagText, background: limeTagBackground, border: limeTagBorder, ); - case 'magentaTag': + case _magentaTag: return SupaExtendedColorTokenGroup( text: magentaTagText, background: magentaTagBackground, border: magentaTagBorder, ); - case 'orangeTag': + case _orangeTag: return SupaExtendedColorTokenGroup( text: orangeTagText, background: orangeTagBackground, border: orangeTagBorder, ); - case 'purpleTag': + case _purpleTag: return SupaExtendedColorTokenGroup( text: purpleTagText, background: purpleTagBackground, border: purpleTagBorder, ); - case 'redTag': + case _redTag: return SupaExtendedColorTokenGroup( text: redTagText, background: redTagBackground, border: redTagBorder, ); - case 'volcanoTag': + case _volcanoTag: return SupaExtendedColorTokenGroup( text: volcanoTagText, background: volcanoTagBackground, @@ -463,39 +483,41 @@ class SupaExtendedColorScheme extends ThemeExtension { // Helper methods to match SupaExtendedColorScheme interface Color getTextColor(String key) { switch (key) { - case 'warning': + case _warning: return warningText; - case 'processing': + case _processing: return informationText; - case 'success': + case _information: + return informationText; + case _success: return successText; - case 'critical': + case _critical: return errorText; - case 'error': + case _error: return errorText; - case 'defaultColor': + case _default: return defaultText; - case 'blue': + case _blueTag: return blueTagText; - case 'cyan': + case _cyanTag: return cyanTagText; - case 'geekblue': + case _geekblueTag: return geekblueTagText; - case 'gold': + case _goldTag: return goldTagText; - case 'green': + case _greenTag: return greenTagText; - case 'lime': + case _limeTag: return limeTagText; - case 'magenta': + case _magentaTag: return magentaTagText; - case 'orange': + case _orangeTag: return orangeTagText; - case 'purple': + case _purpleTag: return purpleTagText; - case 'red': + case _redTag: return redTagText; - case 'volcano': + case _volcanoTag: return volcanoTagText; default: return defaultText; @@ -504,39 +526,42 @@ class SupaExtendedColorScheme extends ThemeExtension { Color getBackgroundColor(String key) { switch (key) { - case 'warning': + case _warning: return warningBackground; - case 'processing': + case _processing: + return informationBackground; + case _information: return informationBackground; - case 'success': + case _success: return successBackground; - case 'critical': + case _critical: return errorBackground; - case 'error': + case _error: return errorBackground; - case 'defaultColor': + case _default: + case 'defaultColor': // keep for backward compatibility if needed return defaultBackground; - case 'blue': + case _blueTag: return blueTagBackground; - case 'cyan': + case _cyanTag: return cyanTagBackground; - case 'geekblue': + case _geekblueTag: return geekblueTagBackground; - case 'gold': + case _goldTag: return goldTagBackground; - case 'green': + case _greenTag: return greenTagBackground; - case 'lime': + case _limeTag: return limeTagBackground; - case 'magenta': + case _magentaTag: return magentaTagBackground; - case 'orange': + case _orangeTag: return orangeTagBackground; - case 'purple': + case _purpleTag: return purpleTagBackground; - case 'red': + case _redTag: return redTagBackground; - case 'volcano': + case _volcanoTag: return volcanoTagBackground; default: return defaultBackground; @@ -545,86 +570,45 @@ class SupaExtendedColorScheme extends ThemeExtension { Color getBorderColor(String key) { switch (key) { - case 'warning': + case _warning: return warningBorder; - case 'processing': + case _processing: return informationBorder; - case 'success': + case _information: + return informationBorder; + case _success: return successBorder; - case 'critical': + case _critical: return errorBorder; - case 'error': + case _error: return errorBorder; - case 'defaultColor': + case _default: + case 'defaultColor': // keep for backward compatibility if needed return defaultBorder; - case 'blue': + case _blueTag: return blueTagBorder; - case 'cyan': + case _cyanTag: return cyanTagBorder; - case 'geekblue': + case _geekblueTag: return geekblueTagBorder; - case 'gold': + case _goldTag: return goldTagBorder; - case 'green': + case _greenTag: return greenTagBorder; - case 'lime': + case _limeTag: return limeTagBorder; - case 'magenta': + case _magentaTag: return magentaTagBorder; - case 'orange': + case _orangeTag: return orangeTagBorder; - case 'purple': + case _purpleTag: return purpleTagBorder; - case 'red': + case _redTag: return redTagBorder; - case 'volcano': + case _volcanoTag: return volcanoTagBorder; default: return defaultBorder; } } - - Color fromKey(String key) { - switch (key) { - case 'warning': - return warningText; - case 'onWarning': - return warningBackground; - case 'warningContainer': - return warningBorder; - case 'onWarningContainer': - return warningText; - case 'information': - return informationText; - case 'onInformation': - return informationBackground; - case 'informationContainer': - return informationBorder; - case 'onInformationContainer': - return informationText; - case 'success': - return successText; - case 'onSuccess': - return successBackground; - case 'successContainer': - return successBorder; - case 'onSuccessContainer': - return successText; - case 'default': - case 'defaultColor': - return defaultText; - case 'onDefault': - return defaultBackground; - case 'defaultContainer': - return defaultBorder; - case 'onDefaultContainer': - return defaultText; - case 'critical': - return errorText; - case 'onCritical': - return errorBackground; - default: - return defaultText; - } - } } From 8ac6b2130ba3d32f6a5566a8a6de543b44b643be Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Thu, 11 Sep 2025 09:46:02 +0700 Subject: [PATCH 04/11] Deprecate backgroundColor properties in EnumModel and TextStatusBadge, introducing backgroundColorKey for improved theme integration. Update EnumStatusBadge to utilize new keys while maintaining legacy support. --- lib/models/enum_model.dart | 4 ++ lib/widgets/atoms/text_status_badge.dart | 71 +++++++++++++++++++- lib/widgets/molecules/enum_status_badge.dart | 34 +++------- 3 files changed, 83 insertions(+), 26 deletions(-) diff --git a/lib/models/enum_model.dart b/lib/models/enum_model.dart index 2adca15..db4fb30 100644 --- a/lib/models/enum_model.dart +++ b/lib/models/enum_model.dart @@ -27,5 +27,9 @@ class EnumModel extends JsonModel { /// The color associated with the enumeration. JsonString color = JsonString("color"); + /// Deprecated: use consolidated color extension with token/background keys. + /// This field will be removed in a future release. + @Deprecated( + 'Use consolidated color extension with token/background keys; this field will be removed in a future release.') JsonString backgroundColor = JsonString("backgroundColor"); } diff --git a/lib/widgets/atoms/text_status_badge.dart b/lib/widgets/atoms/text_status_badge.dart index 5b834bb..a7cc6d8 100644 --- a/lib/widgets/atoms/text_status_badge.dart +++ b/lib/widgets/atoms/text_status_badge.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:supa_architecture/extensions/extensions.dart'; +import 'package:supa_architecture/theme/supa_extended_color_theme.dart'; /// A badge widget to display status with automatic text color adjustment /// based on the background color's luminance. @@ -13,20 +15,82 @@ class TextStatusBadge extends StatelessWidget { final String status; + /// Either provide explicit [color] or a [textColorKey] (token key or hex '#xxxxxx'). final Color? color; + /// Token key or hex for text color (e.g., 'warning' or '#FFFFFF'). + final String? textColorKey; + + /// Either provide explicit [backgroundColor] or a [backgroundColorKey] (token key or hex '#xxxxxx'). + @Deprecated( + 'Use backgroundColorKey or theme tokens; this prop will be removed in a future release.') final Color backgroundColor; + /// Token key or hex for background color (e.g., 'warning' or '#FDDC69'). + final String? backgroundColorKey; + const TextStatusBadge({ super.key, required this.status, + @Deprecated( + 'Use backgroundColorKey or theme tokens; this prop will be removed in a future release.') this.backgroundColor = const Color(0xFFFDDC69), // Default background color this.color = const Color(0xFF000000), // Default text color + this.textColorKey, + this.backgroundColorKey, }); @override Widget build(BuildContext context) { - final textColor = color ?? getTextColorBasedOnBackground(backgroundColor); + final themeExtension = + Theme.of(context).extension(); + + Color? resolvedBackground; + Color? resolvedText; + Color? resolvedBorder; + + bool isHex(String? v) => v != null && v.trim().startsWith('#'); + + final String? bgKey = + (backgroundColorKey == null || backgroundColorKey!.trim().isEmpty) + ? null + : backgroundColorKey!.trim().toLowerCase(); + final String? textKey = + (textColorKey == null || textColorKey!.trim().isEmpty) + ? null + : textColorKey!.trim().toLowerCase(); + + if (bgKey != null) { + if (isHex(bgKey)) { + resolvedBackground = HexColor.fromHex(bgKey); + } else if (themeExtension != null) { + resolvedBackground = themeExtension.getBackgroundColor(bgKey); + resolvedBorder = themeExtension.getBorderColor(bgKey); + } + } + + if (textKey != null) { + if (isHex(textKey)) { + resolvedText = HexColor.fromHex(textKey); + } else if (themeExtension != null) { + resolvedText = themeExtension.getTextColor(textKey); + // Only set border if not derived from background key + resolvedBorder ??= themeExtension.getBorderColor(textKey); + } + } + + // Default to 'default' token group if neither key provided + if (bgKey == null && textKey == null && themeExtension != null) { + resolvedBackground = themeExtension.getBackgroundColor('default'); + resolvedText = themeExtension.getTextColor('default'); + resolvedBorder = themeExtension.getBorderColor('default'); + } + + final Color effectiveBackground = resolvedBackground ?? backgroundColor; + final Color effectiveText = resolvedText ?? + color ?? + getTextColorBasedOnBackground(effectiveBackground); + final Color effectiveBorder = resolvedBorder ?? Colors.transparent; return Container( padding: const EdgeInsets.symmetric( @@ -34,16 +98,17 @@ class TextStatusBadge extends StatelessWidget { vertical: 0, ), decoration: ShapeDecoration( - color: backgroundColor, + color: effectiveBackground, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4), + side: BorderSide(color: effectiveBorder, width: 1), ), ), child: Text( status, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: textColor, + color: effectiveText, height: 1.5, fontWeight: FontWeight.w500, ), diff --git a/lib/widgets/molecules/enum_status_badge.dart b/lib/widgets/molecules/enum_status_badge.dart index e1bdb9a..a06598c 100644 --- a/lib/widgets/molecules/enum_status_badge.dart +++ b/lib/widgets/molecules/enum_status_badge.dart @@ -1,42 +1,30 @@ import 'package:flutter/material.dart'; -import 'package:supa_architecture/extensions/extensions.dart'; import 'package:supa_architecture/models/models.dart'; import 'package:supa_architecture/widgets/atoms/text_status_badge.dart'; class EnumStatusBadge extends StatelessWidget { final EnumModel status; + @Deprecated( + 'Use backgroundColorKey via EnumModel.backgroundColor or theme tokens; this prop will be removed in a future release.') + final Color? backgroundColor; + const EnumStatusBadge({ super.key, required this.status, + @Deprecated( + 'Use backgroundColorKey via EnumModel.backgroundColor or theme tokens; this prop will be removed in a future release.') + this.backgroundColor, }); @override Widget build(BuildContext context) { return TextStatusBadge( status: status.name.rawValue ?? 'Đang tải', - color: _getColorFromHex( - status.color.rawValue, - defaultValue: Colors.black, - ), - backgroundColor: _getColorFromHex( - status.backgroundColor.rawValue, - defaultValue: Colors.grey.shade200, - ), + textColorKey: status.color.rawValue, + backgroundColorKey: status.backgroundColor.rawValue, + // Keep legacy prop working but prefer keys + backgroundColor: backgroundColor ?? Colors.transparent, ); } - - static Color _getColorFromHex( - String? hexColor, { - required Color defaultValue, - }) { - if (hexColor == null || hexColor.isEmpty) { - return defaultValue; - } - try { - return HexColor.fromHex(hexColor); - } catch (e) { - return defaultValue; - } - } } From a5b3bc765d763e136dd3ecccd3b6ccef8f82c8d7 Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Thu, 11 Sep 2025 10:08:49 +0700 Subject: [PATCH 05/11] Update project configuration and dependencies: enhance .gitignore, update iOS deployment target to 13.0, add GoRouter dependency, and refactor main app structure for improved routing and theme management. --- .vscode/launch.json | 45 +++ example/.gitignore | 2 + example/ios/Podfile | 2 +- example/ios/Podfile.lock | 322 ++++++++++++++++++ example/ios/Runner.xcodeproj/project.pbxproj | 133 ++++++++ .../contents.xcworkspacedata | 3 + example/lib/enum_badges_page.dart | 68 ++++ example/lib/main.dart | 81 ++--- example/lib/supa_color_scheme.dart | 206 +++++++++++ example/pubspec.lock | 4 +- example/pubspec.yaml | 1 + example/test/widget_test.dart | 7 +- 12 files changed, 820 insertions(+), 54 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 example/ios/Podfile.lock create mode 100644 example/lib/enum_badges_page.dart create mode 100644 example/lib/supa_color_scheme.dart diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..7f89c5d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "example", + "cwd": "example", + "request": "launch", + "type": "dart" + }, + { + "name": "example (profile mode)", + "cwd": "example", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "example (release mode)", + "cwd": "example", + "request": "launch", + "type": "dart", + "flutterMode": "release" + }, + { + "name": "supa_architecture", + "request": "launch", + "type": "dart" + }, + { + "name": "supa_architecture (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "supa_architecture (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/example/.gitignore b/example/.gitignore index 29a3a50..79c113f 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -5,9 +5,11 @@ *.swp .DS_Store .atom/ +.build/ .buildlog/ .history .svn/ +.swiftpm/ migrate_working_dir/ # IntelliJ related diff --git a/example/ios/Podfile b/example/ios/Podfile index d97f17e..3e44f9c 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '12.0' +platform :ios, '13.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock new file mode 100644 index 0000000..ebcaf4b --- /dev/null +++ b/example/ios/Podfile.lock @@ -0,0 +1,322 @@ +PODS: + - AppAuth (1.7.6): + - AppAuth/Core (= 1.7.6) + - AppAuth/ExternalUserAgent (= 1.7.6) + - AppAuth/Core (1.7.6) + - AppAuth/ExternalUserAgent (1.7.6): + - AppAuth/Core + - device_info_plus (0.0.1): + - Flutter + - DKImagePickerController/Core (4.3.9): + - DKImagePickerController/ImageDataManager + - DKImagePickerController/Resource + - DKImagePickerController/ImageDataManager (4.3.9) + - DKImagePickerController/PhotoGallery (4.3.9): + - DKImagePickerController/Core + - DKPhotoGallery + - DKImagePickerController/Resource (4.3.9) + - DKPhotoGallery (0.0.19): + - DKPhotoGallery/Core (= 0.0.19) + - DKPhotoGallery/Model (= 0.0.19) + - DKPhotoGallery/Preview (= 0.0.19) + - DKPhotoGallery/Resource (= 0.0.19) + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Core (0.0.19): + - DKPhotoGallery/Model + - DKPhotoGallery/Preview + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Model (0.0.19): + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Preview (0.0.19): + - DKPhotoGallery/Model + - DKPhotoGallery/Resource + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Resource (0.0.19): + - SDWebImage + - SwiftyGif + - file_picker (0.0.1): + - DKImagePickerController/PhotoGallery + - Flutter + - Firebase/CoreOnly (11.10.0): + - FirebaseCore (~> 11.10.0) + - Firebase/Crashlytics (11.10.0): + - Firebase/CoreOnly + - FirebaseCrashlytics (~> 11.10.0) + - Firebase/Messaging (11.10.0): + - Firebase/CoreOnly + - FirebaseMessaging (~> 11.10.0) + - firebase_core (3.13.0): + - Firebase/CoreOnly (= 11.10.0) + - Flutter + - firebase_crashlytics (4.3.5): + - Firebase/Crashlytics (= 11.10.0) + - firebase_core + - Flutter + - firebase_messaging (15.2.5): + - Firebase/Messaging (= 11.10.0) + - firebase_core + - Flutter + - FirebaseCore (11.10.0): + - FirebaseCoreInternal (~> 11.10.0) + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/Logger (~> 8.0) + - FirebaseCoreExtension (11.10.0): + - FirebaseCore (~> 11.10.0) + - FirebaseCoreInternal (11.10.0): + - "GoogleUtilities/NSData+zlib (~> 8.0)" + - FirebaseCrashlytics (11.10.0): + - FirebaseCore (~> 11.10.0) + - FirebaseInstallations (~> 11.0) + - FirebaseRemoteConfigInterop (~> 11.0) + - FirebaseSessions (~> 11.0) + - GoogleDataTransport (~> 10.0) + - GoogleUtilities/Environment (~> 8.0) + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) + - FirebaseInstallations (11.10.0): + - FirebaseCore (~> 11.10.0) + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - PromisesObjC (~> 2.4) + - FirebaseMessaging (11.10.0): + - FirebaseCore (~> 11.10.0) + - FirebaseInstallations (~> 11.0) + - GoogleDataTransport (~> 10.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.0) + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/Reachability (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - nanopb (~> 3.30910.0) + - FirebaseRemoteConfigInterop (11.15.0) + - FirebaseSessions (11.10.0): + - FirebaseCore (~> 11.10.0) + - FirebaseCoreExtension (~> 11.10.0) + - FirebaseInstallations (~> 11.0) + - GoogleDataTransport (~> 10.0) + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - nanopb (~> 3.30910.0) + - PromisesSwift (~> 2.1) + - Flutter (1.0.0) + - flutter_secure_storage (6.0.0): + - Flutter + - google_sign_in_ios (0.0.1): + - AppAuth (>= 1.7.4) + - Flutter + - FlutterMacOS + - GoogleSignIn (~> 7.1) + - GTMSessionFetcher (>= 3.4.0) + - GoogleDataTransport (10.1.0): + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) + - GoogleSignIn (7.1.0): + - AppAuth (< 2.0, >= 1.7.3) + - GTMAppAuth (< 5.0, >= 4.1.1) + - GTMSessionFetcher/Core (~> 3.3) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GTMAppAuth (4.1.1): + - AppAuth/Core (~> 1.7) + - GTMSessionFetcher/Core (< 4.0, >= 3.3) + - GTMSessionFetcher (3.5.0): + - GTMSessionFetcher/Full (= 3.5.0) + - GTMSessionFetcher/Core (3.5.0) + - GTMSessionFetcher/Full (3.5.0): + - GTMSessionFetcher/Core + - image_picker_ios (0.0.1): + - Flutter + - integration_test (0.0.1): + - Flutter + - local_auth_darwin (0.0.1): + - Flutter + - FlutterMacOS + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - open_file_ios (0.0.1): + - Flutter + - package_info_plus (0.4.5): + - Flutter + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - PromisesObjC (2.4.0) + - PromisesSwift (2.4.0): + - PromisesObjC (= 2.4.0) + - SDWebImage (5.21.1): + - SDWebImage/Core (= 5.21.1) + - SDWebImage/Core (5.21.1) + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sign_in_with_apple (0.0.1): + - Flutter + - supa_architecture (0.0.1): + - Flutter + - SwiftyGif (5.4.5) + - url_launcher_ios (0.0.1): + - Flutter + - webview_flutter_wkwebview (0.0.1): + - Flutter + - FlutterMacOS + +DEPENDENCIES: + - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) + - file_picker (from `.symlinks/plugins/file_picker/ios`) + - firebase_core (from `.symlinks/plugins/firebase_core/ios`) + - firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`) + - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) + - Flutter (from `Flutter`) + - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) + - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`) + - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) + - integration_test (from `.symlinks/plugins/integration_test/ios`) + - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`) + - open_file_ios (from `.symlinks/plugins/open_file_ios/ios`) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`) + - supa_architecture (from `.symlinks/plugins/supa_architecture/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`) + +SPEC REPOS: + trunk: + - AppAuth + - DKImagePickerController + - DKPhotoGallery + - Firebase + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal + - FirebaseCrashlytics + - FirebaseInstallations + - FirebaseMessaging + - FirebaseRemoteConfigInterop + - FirebaseSessions + - GoogleDataTransport + - GoogleSignIn + - GoogleUtilities + - GTMAppAuth + - GTMSessionFetcher + - nanopb + - PromisesObjC + - PromisesSwift + - SDWebImage + - SwiftyGif + +EXTERNAL SOURCES: + device_info_plus: + :path: ".symlinks/plugins/device_info_plus/ios" + file_picker: + :path: ".symlinks/plugins/file_picker/ios" + firebase_core: + :path: ".symlinks/plugins/firebase_core/ios" + firebase_crashlytics: + :path: ".symlinks/plugins/firebase_crashlytics/ios" + firebase_messaging: + :path: ".symlinks/plugins/firebase_messaging/ios" + Flutter: + :path: Flutter + flutter_secure_storage: + :path: ".symlinks/plugins/flutter_secure_storage/ios" + google_sign_in_ios: + :path: ".symlinks/plugins/google_sign_in_ios/darwin" + image_picker_ios: + :path: ".symlinks/plugins/image_picker_ios/ios" + integration_test: + :path: ".symlinks/plugins/integration_test/ios" + local_auth_darwin: + :path: ".symlinks/plugins/local_auth_darwin/darwin" + open_file_ios: + :path: ".symlinks/plugins/open_file_ios/ios" + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/darwin" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + sign_in_with_apple: + :path: ".symlinks/plugins/sign_in_with_apple/ios" + supa_architecture: + :path: ".symlinks/plugins/supa_architecture/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + webview_flutter_wkwebview: + :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin" + +SPEC CHECKSUMS: + AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73 + device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe + DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c + DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 + file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be + Firebase: 1fe1c0a7d9aaea32efe01fbea5f0ebd8d70e53a2 + firebase_core: 2d4534e7b489907dcede540c835b48981d890943 + firebase_crashlytics: 961a0812ba79ed8f89a8d5d1e3763daa6267a87a + firebase_messaging: 75bc93a4df25faccad67f6662ae872ac9ae69b64 + FirebaseCore: 8344daef5e2661eb004b177488d6f9f0f24251b7 + FirebaseCoreExtension: 6f357679327f3614e995dc7cf3f2d600bdc774ac + FirebaseCoreInternal: ef4505d2afb1d0ebbc33162cb3795382904b5679 + FirebaseCrashlytics: 84b073c997235740e6a951b7ee49608932877e5c + FirebaseInstallations: 9980995bdd06ec8081dfb6ab364162bdd64245c3 + FirebaseMessaging: 2b9f56aa4ed286e1f0ce2ee1d413aabb8f9f5cb9 + FirebaseRemoteConfigInterop: 1c6135e8a094cc6368949f5faeeca7ee8948b8aa + FirebaseSessions: 9b3b30947b97a15370e0902ee7a90f50ef60ead6 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13 + google_sign_in_ios: 19297361f2c51d7d8ac0201b866ef1fa5d1f94a8 + GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 + GoogleSignIn: d4281ab6cf21542b1cfaff85c191f230b399d2db + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de + GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 + image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a + integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e + local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + open_file_ios: 5ff7526df64e4394b4fe207636b67a95e83078bb + package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 + path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 + SDWebImage: f29024626962457f3470184232766516dee8dfea + shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418 + supa_architecture: 8f6124067382c1585e90303c4ccb7d9807bb53aa + SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 + url_launcher_ios: 694010445543906933d732453a59da0a173ae33d + webview_flutter_wkwebview: 1821ceac936eba6f7984d89a9f3bcb4dea99ebb2 + +PODFILE CHECKSUM: a57f30d18f102dd3ce366b1d62a55ecbef2158e5 + +COCOAPODS: 1.16.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 0748233..43d1142 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -14,6 +14,8 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + B5CAC2520D3255ED7C6E2A66 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7EA569BFFFB128133C0D8540 /* Pods_Runner.framework */; }; + E582BA7A6D50632EC2DCF8EC /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E07FF61884B9B4EE480A8D1 /* Pods_RunnerTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -45,9 +47,13 @@ 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 40EA0C79C90586DED57A4032 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 56E14CDD01A3A1C09CEE061B /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7E07FF61884B9B4EE480A8D1 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7EA569BFFFB128133C0D8540 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -55,13 +61,26 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9939628CB7A0E11D69720F57 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + B4E25FBE846EA62116C20046 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + CCD4F8C87091F47BE37F1B85 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + F793D53B21264B3D34780420 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 3B0965C10ABD2389FFE49ECB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E582BA7A6D50632EC2DCF8EC /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B5CAC2520D3255ED7C6E2A66 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -76,6 +95,20 @@ path = RunnerTests; sourceTree = ""; }; + 54982B70DC40C5ED3F259A0C /* Pods */ = { + isa = PBXGroup; + children = ( + CCD4F8C87091F47BE37F1B85 /* Pods-Runner.debug.xcconfig */, + 40EA0C79C90586DED57A4032 /* Pods-Runner.release.xcconfig */, + 56E14CDD01A3A1C09CEE061B /* Pods-Runner.profile.xcconfig */, + 9939628CB7A0E11D69720F57 /* Pods-RunnerTests.debug.xcconfig */, + F793D53B21264B3D34780420 /* Pods-RunnerTests.release.xcconfig */, + B4E25FBE846EA62116C20046 /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -94,6 +127,8 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, + 54982B70DC40C5ED3F259A0C /* Pods */, + DA9024E10310B38A70D3BCAC /* Frameworks */, ); sourceTree = ""; }; @@ -121,6 +156,15 @@ path = Runner; sourceTree = ""; }; + DA9024E10310B38A70D3BCAC /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7EA569BFFFB128133C0D8540 /* Pods_Runner.framework */, + 7E07FF61884B9B4EE480A8D1 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -128,8 +172,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 6298E1E62D9604DE6EB307B7 /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, + 3B0965C10ABD2389FFE49ECB /* Frameworks */, ); buildRules = ( ); @@ -145,12 +191,15 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + D8D8A8F7C4EC01BF68E1957B /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 1B362956993E6EDA2C572E7A /* [CP] Embed Pods Frameworks */, + D8AF86A802619D250AC6EBAB /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -222,6 +271,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 1B362956993E6EDA2C572E7A /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -238,6 +304,28 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 6298E1E62D9604DE6EB307B7 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -253,6 +341,45 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + D8AF86A802619D250AC6EBAB /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + D8D8A8F7C4EC01BF68E1957B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -365,6 +492,7 @@ DEVELOPMENT_TEAM = X7M392FCT9; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -379,6 +507,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 9939628CB7A0E11D69720F57 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -396,6 +525,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = F793D53B21264B3D34780420 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -411,6 +541,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = B4E25FBE846EA62116C20046 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -545,6 +676,7 @@ DEVELOPMENT_TEAM = X7M392FCT9; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -568,6 +700,7 @@ DEVELOPMENT_TEAM = X7M392FCT9; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/example/lib/enum_badges_page.dart b/example/lib/enum_badges_page.dart new file mode 100644 index 0000000..71dd2df --- /dev/null +++ b/example/lib/enum_badges_page.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import 'package:supa_architecture/models/models.dart'; +import 'package:supa_architecture/theme/supa_extended_color_theme.dart'; +import 'package:supa_architecture/widgets/widgets.dart'; + +class EnumBadgesPage extends StatelessWidget { + const EnumBadgesPage({super.key}); + + static const List _tokenKeys = [ + 'default', + 'warning', + 'information', + 'success', + 'error', + 'blue', + 'cyan', + 'geekblue', + 'gold', + 'green', + 'lime', + 'magenta', + 'orange', + 'purple', + 'red', + 'volcano', + ]; + + @override + Widget build(BuildContext context) { + final extended = Theme.of(context).extension(); + + return Scaffold( + appBar: AppBar( + title: const Text('Enum Badges Demo'), + ), + body: ListView.separated( + padding: const EdgeInsets.all(16), + itemCount: _tokenKeys.length, + separatorBuilder: (_, __) => const SizedBox(height: 12), + itemBuilder: (context, index) { + final key = _tokenKeys[index]; + final enumModel = EnumModel() + ..name.rawValue = key + ..color.rawValue = key + ..backgroundColor.rawValue = key; // legacy path still supported + + final token = extended?.getTokenGroup(key); + + return Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: token?.background ?? Colors.transparent, + border: Border.all(color: token?.border ?? Colors.transparent), + borderRadius: BorderRadius.circular(8), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(key, style: Theme.of(context).textTheme.titleMedium), + EnumStatusBadge(status: enumModel), + ], + ), + ); + }, + ), + ); + } +} diff --git a/example/lib/main.dart b/example/lib/main.dart index db71a32..1ad8573 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,60 +1,47 @@ -import 'dart:async'; - import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; -void main() { - runApp(const MyApp()); -} +import 'enum_badges_page.dart'; +import 'supa_color_scheme.dart'; -class MyApp extends StatefulWidget { - const MyApp({super.key}); - - @override - State createState() => _MyAppState(); +void main() { + runApp(const ExampleApp()); } -class _MyAppState extends State { - final String _platformVersion = 'Unknown'; +class ExampleApp extends StatelessWidget { + const ExampleApp({super.key}); @override - void initState() { - super.initState(); - initPlatformState(); - } - - // Platform messages are asynchronous, so we initialize in an async method. - Future initPlatformState() async { - // String platformVersion; - // Platform messages may fail, so we use a try/catch PlatformException. - // We also handle the message potentially returning null. - // try { - // platformVersion = await _supaArchitecturePlugin.getPlatformVersion() ?? - // 'Unknown platform version'; - // } on PlatformException { - // platformVersion = 'Failed to get platform version.'; - // } + Widget build(BuildContext context) { + final router = GoRouter( + routes: [ + GoRoute( + path: '/', + builder: (context, state) => const EnumBadgesPage(), + ), + ], + ); - // If the widget was removed from the tree while the asynchronous platform - // message was in flight, we want to discard the reply rather than calling - // setState to update our non-existent appearance. - if (!mounted) return; + final ThemeData lightTheme = ThemeData.from( + colorScheme: lightColorScheme, + useMaterial3: true, + ).copyWith( + extensions: const [lightExtendedColorScheme], + ); - setState(() { - // _platformVersion = platformVersion; - }); - } + final ThemeData darkTheme = ThemeData.from( + colorScheme: darkColorScheme, + useMaterial3: true, + ).copyWith( + extensions: const [darkExtendedColorScheme], + ); - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar( - title: const Text('Plugin example app'), - ), - body: Center( - child: Text('Running on: $_platformVersion\n'), - ), - ), + return MaterialApp.router( + title: 'Supa Architecture Example', + theme: lightTheme, + darkTheme: darkTheme, + routerConfig: router, + debugShowCheckedModeBanner: false, ); } } diff --git a/example/lib/supa_color_scheme.dart b/example/lib/supa_color_scheme.dart new file mode 100644 index 0000000..290cdcb --- /dev/null +++ b/example/lib/supa_color_scheme.dart @@ -0,0 +1,206 @@ +// GENERATED FILE - DO NOT MODIFY BY HAND +import 'package:flutter/material.dart'; +import 'package:supa_architecture/theme/supa_extended_color_theme.dart'; + +const ColorScheme lightColorScheme = ColorScheme( + brightness: Brightness.light, + primary: Color(0xFF6D14E0), + surfaceTint: Color(0xFF7628E9), + onPrimary: Color(0xFFFFFFFF), + primaryContainer: Color(0xFF863EF9), + onPrimaryContainer: Color(0xFFF7EDFF), + secondary: Color(0xFF5C00C4), + onSecondary: Color(0xFFFFFFFF), + secondaryContainer: Color(0xFFEBDCFF), + onSecondaryContainer: Color(0xFF260059), + tertiary: Color(0xFF71585D), + onTertiary: Color(0xFFFFFFFF), + tertiaryContainer: Color(0xFFFFDDE3), + onTertiaryContainer: Color(0xFF795F65), + error: Color(0xFFBA1A1A), + onError: Color(0xFFFFFFFF), + errorContainer: Color(0xFFFFDAD6), + onErrorContainer: Color(0xFF93000A), + surface: Color(0xFFFCF8F8), + onSurface: Color(0xFF1C1B1B), + onSurfaceVariant: Color(0xFF4A4455), + outline: Color(0xFF7C7487), + outlineVariant: Color(0xFFCDC2D8), + shadow: Color(0xFF000000), + scrim: Color(0xFF000000), + inverseSurface: Color(0xFF313030), + onInverseSurface: Color(0xFFF4F0EF), + inversePrimary: Color(0xFFD4BBFF), + primaryFixed: Color(0xFFEBDCFF), + onPrimaryFixed: Color(0xFF260059), + primaryFixedDim: Color(0xFFD4BBFF), + onPrimaryFixedVariant: Color(0xFF5C00C4), + secondaryFixed: Color(0xFFE8DEFF), + onSecondaryFixed: Color(0xFF1E153B), + secondaryFixedDim: Color(0xFFCCC0F0), + onSecondaryFixedVariant: Color(0xFF4A4169), + tertiaryFixed: Color(0xFFFCDAE0), + onTertiaryFixed: Color(0xFF29161B), + tertiaryFixedDim: Color(0xFFDFBEC4), + onTertiaryFixedVariant: Color(0xFF584146), + surfaceDim: Color(0xFFDDD9D9), + surfaceBright: Color(0xFFFCF8F8), + surfaceContainerLowest: Color(0xFFFFFFFF), + surfaceContainerLow: Color(0xFFF6F3F2), + surfaceContainer: Color(0xFFF1EDEC), + surfaceContainerHigh: Color(0xFFEBE7E7), + surfaceContainerHighest: Color(0xFFE5E2E1), +); + +const ColorScheme darkColorScheme = ColorScheme( + brightness: Brightness.dark, + primary: Color(0xFFD4BBFF), + surfaceTint: Color(0xFFD4BBFF), + onPrimary: Color(0xFF40008C), + primaryContainer: Color(0xFF863EF9), + onPrimaryContainer: Color(0xFFF7EDFF), + secondary: Color(0xFFF6EEFF), + onSecondary: Color(0xFF332A51), + secondaryContainer: Color(0xFFDBCEFF), + onSecondaryContainer: Color(0xFF605680), + tertiary: Color(0xFFFFFFFF), + onTertiary: Color(0xFF402B2F), + tertiaryContainer: Color(0xFFFCDAE0), + onTertiaryContainer: Color(0xFF775E63), + error: Color(0xFFFFB4AB), + onError: Color(0xFF690005), + errorContainer: Color(0xFF93000A), + onErrorContainer: Color(0xFFFFDAD6), + surface: Color(0xFF141313), + onSurface: Color(0xFFE5E2E1), + onSurfaceVariant: Color(0xFFCDC2D8), + outline: Color(0xFF968DA1), + outlineVariant: Color(0xFF4A4455), + shadow: Color(0xFF000000), + scrim: Color(0xFF000000), + inverseSurface: Color(0xFFE5E2E1), + onInverseSurface: Color(0xFF313030), + inversePrimary: Color(0xFF7628E9), + primaryFixed: Color(0xFFEBDCFF), + onPrimaryFixed: Color(0xFF260059), + primaryFixedDim: Color(0xFFD4BBFF), + onPrimaryFixedVariant: Color(0xFF5C00C4), + secondaryFixed: Color(0xFFE8DEFF), + onSecondaryFixed: Color(0xFF1E153B), + secondaryFixedDim: Color(0xFFCCC0F0), + onSecondaryFixedVariant: Color(0xFF4A4169), + tertiaryFixed: Color(0xFFFCDAE0), + onTertiaryFixed: Color(0xFF29161B), + tertiaryFixedDim: Color(0xFFDFBEC4), + onTertiaryFixedVariant: Color(0xFF584146), + surfaceDim: Color(0xFF141313), + surfaceBright: Color(0xFF3A3939), + surfaceContainerLowest: Color(0xFF0E0E0E), + surfaceContainerLow: Color(0xFF1C1B1B), + surfaceContainer: Color(0xFF201F1F), + surfaceContainerHigh: Color(0xFF2A2A2A), + surfaceContainerHighest: Color(0xFF353434), +); + +const SupaExtendedColorScheme lightExtendedColorScheme = + SupaExtendedColorScheme( + warningText: Color(0xFFFAAD14), + warningBackground: Color(0xFFFFFBE6), + warningBorder: Color(0xFFFFE58F), + informationText: Color(0xFF1677FF), + informationBackground: Color(0xFFE6F4FF), + informationBorder: Color(0xFF91CAFF), + successText: Color(0xFF52C41A), + successBackground: Color(0xFFF6FFED), + successBorder: Color(0xFFB7EB8F), + defaultText: Color(0xFF000000), + defaultBackground: Color(0xFFF0f0f0), + defaultBorder: Color(0xFFD9D9D9), + errorText: Color(0xFFFF4D4F), + errorBackground: Color(0xFFFFF2F0), + errorBorder: Color(0xFFFFCCC7), + blueTagText: Color(0xFF1668DC), + blueTagBackground: Color(0xFFE6F4FF), + blueTagBorder: Color(0xFF91CAFF), + cyanTagText: Color(0xFF13A8A8), + cyanTagBackground: Color(0xFFE6FFFB), + cyanTagBorder: Color(0xFF87E8DE), + geekblueTagText: Color(0xFF2B4ACB), + geekblueTagBackground: Color(0xFFF0F5FF), + geekblueTagBorder: Color(0xFFADC6FF), + goldTagText: Color(0xFFD89614), + goldTagBackground: Color(0xFFFFFBE6), + goldTagBorder: Color(0xFFFFD666), + greenTagText: Color(0xFF49AA19), + greenTagBackground: Color(0xFFF6FFED), + greenTagBorder: Color(0xFFB7EB8F), + limeTagText: Color(0xFF8BBB11), + limeTagBackground: Color(0xFFFCFFE6), + limeTagBorder: Color(0xFFEAFF8F), + magentaTagText: Color(0xFFCB2B83), + magentaTagBackground: Color(0xFFFFF0F6), + magentaTagBorder: Color(0xFFFFADD2), + orangeTagText: Color(0xFFD87A16), + orangeTagBackground: Color(0xFFFFF7E6), + orangeTagBorder: Color(0xFFFFD591), + purpleTagText: Color(0xFF722ED1), + purpleTagBackground: Color(0xFFF9F0FF), + purpleTagBorder: Color(0xFFD3ADF7), + redTagText: Color(0xFFD32029), + redTagBackground: Color(0xFFFFF2F0), + redTagBorder: Color(0xFFFFCCC7), + volcanoTagText: Color(0xFFD84A1B), + volcanoTagBackground: Color(0xFFFFF2E8), + volcanoTagBorder: Color(0xFFFFBB96), +); + +const SupaExtendedColorScheme darkExtendedColorScheme = SupaExtendedColorScheme( + warningText: Color(0xFFFAAD14), + warningBackground: Color(0xFFFFFBE6), + warningBorder: Color(0xFFFFE58F), + informationText: Color(0xFF1677FF), + informationBackground: Color(0xFFE6F4FF), + informationBorder: Color(0xFF91CAFF), + successText: Color(0xFF52C41A), + successBackground: Color(0xFFF6FFED), + successBorder: Color(0xFFB7EB8F), + defaultText: Color(0xFF000000), + defaultBackground: Color(0xFFF0f0f0), + defaultBorder: Color(0xFFD9D9D9), + errorText: Color(0xFFFF4D4F), + errorBackground: Color(0xFFFFF2F0), + errorBorder: Color(0xFFFFCCC7), + blueTagText: Color(0xFF1668DC), + blueTagBackground: Color(0xFFE6F4FF), + blueTagBorder: Color(0xFF91CAFF), + cyanTagText: Color(0xFF13A8A8), + cyanTagBackground: Color(0xFFE6FFFB), + cyanTagBorder: Color(0xFF87E8DE), + geekblueTagText: Color(0xFF2B4ACB), + geekblueTagBackground: Color(0xFFF0F5FF), + geekblueTagBorder: Color(0xFFADC6FF), + goldTagText: Color(0xFFD89614), + goldTagBackground: Color(0xFFFFFBE6), + goldTagBorder: Color(0xFFFFD666), + greenTagText: Color(0xFF49AA19), + greenTagBackground: Color(0xFFF6FFED), + greenTagBorder: Color(0xFFB7EB8F), + limeTagText: Color(0xFF8BBB11), + limeTagBackground: Color(0xFFFCFFE6), + limeTagBorder: Color(0xFFEAFF8F), + magentaTagText: Color(0xFFCB2B83), + magentaTagBackground: Color(0xFFFFF0F6), + magentaTagBorder: Color(0xFFFFADD2), + orangeTagText: Color(0xFFD87A16), + orangeTagBackground: Color(0xFFFFF7E6), + orangeTagBorder: Color(0xFFFFD591), + purpleTagText: Color(0xFF722ED1), + purpleTagBackground: Color(0xFFF9F0FF), + purpleTagBorder: Color(0xFFD3ADF7), + redTagText: Color(0xFFD32029), + redTagBackground: Color(0xFFFFF2F0), + redTagBorder: Color(0xFFFFCCC7), + volcanoTagText: Color(0xFFD84A1B), + volcanoTagBackground: Color(0xFFFFF2E8), + volcanoTagBorder: Color(0xFFFFBB96), +); diff --git a/example/pubspec.lock b/example/pubspec.lock index bde4775..a3b31fa 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -392,7 +392,7 @@ packages: source: hosted version: "8.0.3" go_router: - dependency: transitive + dependency: "direct main" description: name: go_router sha256: b453934c36e289cef06525734d1e676c1f91da9e22e2017d9dcab6ce0f999175 @@ -1007,7 +1007,7 @@ packages: path: ".." relative: true source: path - version: "1.9.1+5" + version: "1.9.1" supa_carbon_icons: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 51eb061..74f00aa 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -28,6 +28,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 + go_router: ^15.0.0 dev_dependencies: integration_test: diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index d49652c..d617333 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -7,19 +7,18 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; - import 'package:supa_architecture_example/main.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); + await tester.pumpWidget(const ExampleApp()); // Verify that platform version is retrieved. expect( find.byWidgetPredicate( - (Widget widget) => widget is Text && - widget.data!.startsWith('Running on:'), + (Widget widget) => + widget is Text && widget.data!.startsWith('Running on:'), ), findsOneWidget, ); From 4f533825a1510e705ee2c2f7e439d130b181a8c0 Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Thu, 11 Sep 2025 10:12:36 +0700 Subject: [PATCH 06/11] Enhance text styling in EnumBadgesPage by applying dynamic color to the title text based on the provided token, improving visual consistency with the theme. --- example/lib/enum_badges_page.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/example/lib/enum_badges_page.dart b/example/lib/enum_badges_page.dart index 71dd2df..0e260ad 100644 --- a/example/lib/enum_badges_page.dart +++ b/example/lib/enum_badges_page.dart @@ -56,7 +56,12 @@ class EnumBadgesPage extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(key, style: Theme.of(context).textTheme.titleMedium), + Text( + key, + style: Theme.of(context).textTheme.titleMedium?.copyWith( + color: token?.text ?? Colors.black, + ), + ), EnumStatusBadge(status: enumModel), ], ), From 76b195151d0e865e49d65e2473efd7ca9ab23bb6 Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Thu, 11 Sep 2025 10:16:33 +0700 Subject: [PATCH 07/11] v1.10.0-rc.1 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index f267107..2ecc872 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: supa_architecture description: Architecture library for Supa Flutter applications -version: 1.9.1 +version: 1.10.0-rc.1 homepage: https://github.supa.vn environment: From 45c7e4f60f85b8863f74afd71136d68bcdf98780 Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Thu, 11 Sep 2025 10:16:54 +0700 Subject: [PATCH 08/11] Update pubspec.lock to version 1.10.0-rc.1, reflecting the latest dependency changes. --- example/pubspec.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index a3b31fa..acd5ba9 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1007,7 +1007,7 @@ packages: path: ".." relative: true source: path - version: "1.9.1" + version: "1.10.0-rc.1" supa_carbon_icons: dependency: transitive description: From 0aeadce1a85db9aaabffef740328202095250022 Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Thu, 11 Sep 2025 15:00:54 +0700 Subject: [PATCH 09/11] v1.10.0-rc.2 --- lib/supa_architecture.dart | 1 + lib/theme/theme.dart | 2 ++ lib/widgets/atoms/text_status_badge.dart | 33 +++++++++++++++++--- lib/widgets/molecules/enum_status_badge.dart | 12 +++++-- pubspec.yaml | 2 +- 5 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 lib/theme/theme.dart diff --git a/lib/supa_architecture.dart b/lib/supa_architecture.dart index 066bd6b..9d3d827 100644 --- a/lib/supa_architecture.dart +++ b/lib/supa_architecture.dart @@ -18,6 +18,7 @@ export 'models/models.dart'; export 'providers/providers.dart'; export 'repositories/repositories.dart'; export 'services/services.dart'; +export 'theme/theme.dart'; export 'widgets/widgets.dart'; PersistentStorage get persistentStorage => diff --git a/lib/theme/theme.dart b/lib/theme/theme.dart new file mode 100644 index 0000000..eba0f21 --- /dev/null +++ b/lib/theme/theme.dart @@ -0,0 +1,2 @@ +export 'supa_extended_color_theme.dart'; +export 'supa_extended_color_token_group.dart'; diff --git a/lib/widgets/atoms/text_status_badge.dart b/lib/widgets/atoms/text_status_badge.dart index a7cc6d8..90974c2 100644 --- a/lib/widgets/atoms/text_status_badge.dart +++ b/lib/widgets/atoms/text_status_badge.dart @@ -29,6 +29,12 @@ class TextStatusBadge extends StatelessWidget { /// Token key or hex for background color (e.g., 'warning' or '#FDDC69'). final String? backgroundColorKey; + /// Optional explicit border color. Prefer [borderColorKey] for tokens/hex. + final Color? borderColor; + + /// Token key or hex for border color (e.g., 'warning' or '#FFD591'). + final String? borderColorKey; + const TextStatusBadge({ super.key, required this.status, @@ -38,6 +44,8 @@ class TextStatusBadge extends StatelessWidget { this.color = const Color(0xFF000000), // Default text color this.textColorKey, this.backgroundColorKey, + this.borderColor, + this.borderColorKey, }); @override @@ -55,17 +63,22 @@ class TextStatusBadge extends StatelessWidget { (backgroundColorKey == null || backgroundColorKey!.trim().isEmpty) ? null : backgroundColorKey!.trim().toLowerCase(); + final String? textKey = (textColorKey == null || textColorKey!.trim().isEmpty) ? null : textColorKey!.trim().toLowerCase(); + final String? borderKey = + (borderColorKey == null || borderColorKey!.trim().isEmpty) + ? null + : borderColorKey!.trim().toLowerCase(); + if (bgKey != null) { if (isHex(bgKey)) { resolvedBackground = HexColor.fromHex(bgKey); } else if (themeExtension != null) { resolvedBackground = themeExtension.getBackgroundColor(bgKey); - resolvedBorder = themeExtension.getBorderColor(bgKey); } } @@ -74,13 +87,22 @@ class TextStatusBadge extends StatelessWidget { resolvedText = HexColor.fromHex(textKey); } else if (themeExtension != null) { resolvedText = themeExtension.getTextColor(textKey); - // Only set border if not derived from background key - resolvedBorder ??= themeExtension.getBorderColor(textKey); + } + } + + if (borderKey != null) { + if (isHex(borderKey)) { + resolvedBorder = HexColor.fromHex(borderKey); + } else if (themeExtension != null) { + resolvedBorder = themeExtension.getBorderColor(borderKey); } } // Default to 'default' token group if neither key provided - if (bgKey == null && textKey == null && themeExtension != null) { + if (bgKey == null && + textKey == null && + borderKey == null && + themeExtension != null) { resolvedBackground = themeExtension.getBackgroundColor('default'); resolvedText = themeExtension.getTextColor('default'); resolvedBorder = themeExtension.getBorderColor('default'); @@ -90,7 +112,8 @@ class TextStatusBadge extends StatelessWidget { final Color effectiveText = resolvedText ?? color ?? getTextColorBasedOnBackground(effectiveBackground); - final Color effectiveBorder = resolvedBorder ?? Colors.transparent; + final Color effectiveBorder = + borderColor ?? resolvedBorder ?? Colors.transparent; return Container( padding: const EdgeInsets.symmetric( diff --git a/lib/widgets/molecules/enum_status_badge.dart b/lib/widgets/molecules/enum_status_badge.dart index a06598c..01a2a24 100644 --- a/lib/widgets/molecules/enum_status_badge.dart +++ b/lib/widgets/molecules/enum_status_badge.dart @@ -19,10 +19,18 @@ class EnumStatusBadge extends StatelessWidget { @override Widget build(BuildContext context) { + bool isHex(String? v) => v != null && v.trim().startsWith('#'); + final String? colorRaw = status.color.rawValue; + final String? computedBorderKey = + (colorRaw != null && colorRaw.trim().isNotEmpty && !isHex(colorRaw)) + ? colorRaw + : null; + return TextStatusBadge( status: status.name.rawValue ?? 'Đang tải', - textColorKey: status.color.rawValue, - backgroundColorKey: status.backgroundColor.rawValue, + textColorKey: status.color.rawValue ?? 'default', + backgroundColorKey: status.backgroundColor.rawValue ?? 'default', + borderColorKey: computedBorderKey, // Keep legacy prop working but prefer keys backgroundColor: backgroundColor ?? Colors.transparent, ); diff --git a/pubspec.yaml b/pubspec.yaml index 2ecc872..72fdc90 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: supa_architecture description: Architecture library for Supa Flutter applications -version: 1.10.0-rc.1 +version: 1.10.0-rc.2 homepage: https://github.supa.vn environment: From 69080f5f3037ff309d8c82a199abda46848920a8 Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Fri, 12 Sep 2025 09:53:39 +0700 Subject: [PATCH 10/11] Refactor TextStatusBadge and EnumStatusBadge to improve color property naming for clarity. Update variable names from resolvedBackground, resolvedText, and resolvedBorder to resolvedBackgroundColor, resolvedTextColor, and resolvedBorderColor. Maintain legacy support in EnumStatusBadge while enhancing theme integration. --- lib/widgets/atoms/text_status_badge.dart | 44 +++++++++++--------- lib/widgets/molecules/enum_status_badge.dart | 3 +- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/lib/widgets/atoms/text_status_badge.dart b/lib/widgets/atoms/text_status_badge.dart index 90974c2..6a50a45 100644 --- a/lib/widgets/atoms/text_status_badge.dart +++ b/lib/widgets/atoms/text_status_badge.dart @@ -53,9 +53,9 @@ class TextStatusBadge extends StatelessWidget { final themeExtension = Theme.of(context).extension(); - Color? resolvedBackground; - Color? resolvedText; - Color? resolvedBorder; + Color? resolvedBackgroundColor; + Color? resolvedTextColor; + Color? resolvedBorderColor; bool isHex(String? v) => v != null && v.trim().startsWith('#'); @@ -76,25 +76,25 @@ class TextStatusBadge extends StatelessWidget { if (bgKey != null) { if (isHex(bgKey)) { - resolvedBackground = HexColor.fromHex(bgKey); + resolvedBackgroundColor = HexColor.fromHex(bgKey); } else if (themeExtension != null) { - resolvedBackground = themeExtension.getBackgroundColor(bgKey); + resolvedBackgroundColor = themeExtension.getBackgroundColor(bgKey); } } if (textKey != null) { if (isHex(textKey)) { - resolvedText = HexColor.fromHex(textKey); + resolvedTextColor = HexColor.fromHex(textKey); } else if (themeExtension != null) { - resolvedText = themeExtension.getTextColor(textKey); + resolvedTextColor = themeExtension.getTextColor(textKey); } } if (borderKey != null) { if (isHex(borderKey)) { - resolvedBorder = HexColor.fromHex(borderKey); + resolvedBorderColor = HexColor.fromHex(borderKey); } else if (themeExtension != null) { - resolvedBorder = themeExtension.getBorderColor(borderKey); + resolvedBorderColor = themeExtension.getBorderColor(borderKey); } } @@ -103,17 +103,18 @@ class TextStatusBadge extends StatelessWidget { textKey == null && borderKey == null && themeExtension != null) { - resolvedBackground = themeExtension.getBackgroundColor('default'); - resolvedText = themeExtension.getTextColor('default'); - resolvedBorder = themeExtension.getBorderColor('default'); + resolvedBackgroundColor = themeExtension.getBackgroundColor('default'); + resolvedTextColor = themeExtension.getTextColor('default'); + resolvedBorderColor = themeExtension.getBorderColor('default'); } - final Color effectiveBackground = resolvedBackground ?? backgroundColor; - final Color effectiveText = resolvedText ?? + final Color effectiveBackgroundColor = + resolvedBackgroundColor ?? backgroundColor; + final Color effectiveTextColor = resolvedTextColor ?? color ?? - getTextColorBasedOnBackground(effectiveBackground); - final Color effectiveBorder = - borderColor ?? resolvedBorder ?? Colors.transparent; + getTextColorBasedOnBackground(effectiveBackgroundColor); + final Color effectiveBorderColor = + borderColor ?? resolvedBorderColor ?? Colors.transparent; return Container( padding: const EdgeInsets.symmetric( @@ -121,17 +122,20 @@ class TextStatusBadge extends StatelessWidget { vertical: 0, ), decoration: ShapeDecoration( - color: effectiveBackground, + color: effectiveBackgroundColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4), - side: BorderSide(color: effectiveBorder, width: 1), + side: BorderSide( + color: effectiveBorderColor, + width: 1, + ), ), ), child: Text( status, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: effectiveText, + color: effectiveTextColor, height: 1.5, fontWeight: FontWeight.w500, ), diff --git a/lib/widgets/molecules/enum_status_badge.dart b/lib/widgets/molecules/enum_status_badge.dart index 01a2a24..824765b 100644 --- a/lib/widgets/molecules/enum_status_badge.dart +++ b/lib/widgets/molecules/enum_status_badge.dart @@ -20,6 +20,7 @@ class EnumStatusBadge extends StatelessWidget { @override Widget build(BuildContext context) { bool isHex(String? v) => v != null && v.trim().startsWith('#'); + final String? colorRaw = status.color.rawValue; final String? computedBorderKey = (colorRaw != null && colorRaw.trim().isNotEmpty && !isHex(colorRaw)) @@ -31,8 +32,6 @@ class EnumStatusBadge extends StatelessWidget { textColorKey: status.color.rawValue ?? 'default', backgroundColorKey: status.backgroundColor.rawValue ?? 'default', borderColorKey: computedBorderKey, - // Keep legacy prop working but prefer keys - backgroundColor: backgroundColor ?? Colors.transparent, ); } } From 7b7e4b8f349c43e49a729c89b96f66eb56c3a0aa Mon Sep 17 00:00:00 2001 From: thanhtunguet Date: Fri, 12 Sep 2025 10:03:48 +0700 Subject: [PATCH 11/11] v1.10.0-rc.3 --- lib/widgets/atoms/text_status_badge.dart | 25 +++++++------------- lib/widgets/molecules/enum_status_badge.dart | 10 -------- pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 28 deletions(-) diff --git a/lib/widgets/atoms/text_status_badge.dart b/lib/widgets/atoms/text_status_badge.dart index 6a50a45..b077995 100644 --- a/lib/widgets/atoms/text_status_badge.dart +++ b/lib/widgets/atoms/text_status_badge.dart @@ -26,15 +26,9 @@ class TextStatusBadge extends StatelessWidget { 'Use backgroundColorKey or theme tokens; this prop will be removed in a future release.') final Color backgroundColor; - /// Token key or hex for background color (e.g., 'warning' or '#FDDC69'). - final String? backgroundColorKey; - /// Optional explicit border color. Prefer [borderColorKey] for tokens/hex. final Color? borderColor; - /// Token key or hex for border color (e.g., 'warning' or '#FFD591'). - final String? borderColorKey; - const TextStatusBadge({ super.key, required this.status, @@ -43,9 +37,7 @@ class TextStatusBadge extends StatelessWidget { this.backgroundColor = const Color(0xFFFDDC69), // Default background color this.color = const Color(0xFF000000), // Default text color this.textColorKey, - this.backgroundColorKey, this.borderColor, - this.borderColorKey, }); @override @@ -59,20 +51,14 @@ class TextStatusBadge extends StatelessWidget { bool isHex(String? v) => v != null && v.trim().startsWith('#'); - final String? bgKey = - (backgroundColorKey == null || backgroundColorKey!.trim().isEmpty) - ? null - : backgroundColorKey!.trim().toLowerCase(); - final String? textKey = (textColorKey == null || textColorKey!.trim().isEmpty) ? null : textColorKey!.trim().toLowerCase(); - final String? borderKey = - (borderColorKey == null || borderColorKey!.trim().isEmpty) - ? null - : borderColorKey!.trim().toLowerCase(); + final String? bgKey = (isHex(textKey) ? null : textKey); + + final String? borderKey = (isHex(textKey) ? null : textKey); if (bgKey != null) { if (isHex(bgKey)) { @@ -116,6 +102,11 @@ class TextStatusBadge extends StatelessWidget { final Color effectiveBorderColor = borderColor ?? resolvedBorderColor ?? Colors.transparent; + print('bgColor $bgKey'); + print('textColor $textKey'); + print('borderColor $borderKey'); + print('---------------------\n\n'); + return Container( padding: const EdgeInsets.symmetric( horizontal: 8, diff --git a/lib/widgets/molecules/enum_status_badge.dart b/lib/widgets/molecules/enum_status_badge.dart index 824765b..6112389 100644 --- a/lib/widgets/molecules/enum_status_badge.dart +++ b/lib/widgets/molecules/enum_status_badge.dart @@ -19,19 +19,9 @@ class EnumStatusBadge extends StatelessWidget { @override Widget build(BuildContext context) { - bool isHex(String? v) => v != null && v.trim().startsWith('#'); - - final String? colorRaw = status.color.rawValue; - final String? computedBorderKey = - (colorRaw != null && colorRaw.trim().isNotEmpty && !isHex(colorRaw)) - ? colorRaw - : null; - return TextStatusBadge( status: status.name.rawValue ?? 'Đang tải', textColorKey: status.color.rawValue ?? 'default', - backgroundColorKey: status.backgroundColor.rawValue ?? 'default', - borderColorKey: computedBorderKey, ); } } diff --git a/pubspec.yaml b/pubspec.yaml index 72fdc90..d882c0e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: supa_architecture description: Architecture library for Supa Flutter applications -version: 1.10.0-rc.2 +version: 1.10.0-rc.3 homepage: https://github.supa.vn environment: