? colors) =>
+ colors != null ? SweepGradient(colors: colors) : null;
+
+ static SweepGradient? sweepFromMultiColor(MultiColor multiColor) =>
+ multiColor.isGradient ? SweepGradient(colors: multiColor.colors) : null;
+}
diff --git a/packages/wyatt_ui_components/lib/src/core/utils/text_wrapper.dart b/packages/wyatt_ui_components/lib/src/core/utils/text_wrapper.dart
index 2c6e248e..bed9dd99 100644
--- a/packages/wyatt_ui_components/lib/src/core/utils/text_wrapper.dart
+++ b/packages/wyatt_ui_components/lib/src/core/utils/text_wrapper.dart
@@ -36,15 +36,28 @@ class TextWrapper {
});
/// Creates a [TextWrapper] from a [Text] widget.
- const TextWrapper.text(this.data)
- : style = null,
+ TextWrapper.text(Text text)
+ : data = text.data!,
+ style = text.style,
gradientColors = null,
- textAlign = null,
- textDirection = null,
- softWrap = null,
- overflow = null,
- maxLines = null,
- selectionColor = null;
+ textAlign = text.textAlign,
+ textDirection = text.textDirection,
+ softWrap = text.softWrap,
+ overflow = text.overflow,
+ maxLines = text.maxLines,
+ selectionColor = text.selectionColor;
+
+ /// Creates a [TextWrapper] from a [RichText] widget.
+ TextWrapper.rich(RichText richText)
+ : data = richText.text.toPlainText(),
+ style = richText.text.style,
+ gradientColors = null,
+ textAlign = richText.textAlign,
+ textDirection = richText.textDirection,
+ softWrap = richText.softWrap,
+ overflow = richText.overflow,
+ maxLines = richText.maxLines,
+ selectionColor = richText.selectionColor;
/// Text to be displayed
final String data;
diff --git a/packages/wyatt_ui_components/lib/src/core/utils/theme_helper.dart b/packages/wyatt_ui_components/lib/src/core/utils/theme_helper.dart
index 97fe94a0..f376b5c9 100644
--- a/packages/wyatt_ui_components/lib/src/core/utils/theme_helper.dart
+++ b/packages/wyatt_ui_components/lib/src/core/utils/theme_helper.dart
@@ -16,33 +16,76 @@
/// A helper class for getting theme elements.
abstract class ThemeHelper {
- /// Gets a theme element from a list of styles.
+ /// Gets a nullable theme element from a list of styles.
+ /// {@template getElement}
/// Styles are checked in order, and the first one that passes the
/// [valueValidator] is returned.
/// Style elements are transformed using the [transform] function.
///
- /// [styles]: A list of styles that need to be checked.
- /// [transform]: A function that transforms each style element
- /// to a [T] type.
- /// [valueValidator]: An optional validation function that
- /// determines if a style element is valid.
- /// [combine]: A function that combines two [P] type objects to create
- /// a new object.
- static T? getThemeElement(
+ /// - [styles] : A list of styles that need to be checked.
+ ///
+ /// - [transform] : An optional function that transforms each style element
+ /// to a [T] type after it passes the [valueValidator]. *(default: returns
+ /// element as is)*
+ ///
+ /// - [valueValidator] : An optional validation function that
+ /// determines if a style element is valid. *(default: checks if element
+ /// is not null)*
+ ///
+ /// - [combine] : A function that combines two [P] type objects to create
+ /// a new object. *(default: returns the first element)*
+ ///
+ /// So, if you only pass a [styles] list, the first valid style element
+ /// will be returned as is.
+ /// If you pass a [transform] function, the first valid style element
+ /// will be transformed to a [T] type.
+ /// {@endtemplate}
+ static T? maybeGetElement
(
List
? styles, {
- required T? Function(P?)? transform,
+ T? Function(P?)? transform,
bool? Function(P?)? valueValidator,
P? Function(P?, P?)? combine,
}) {
+ // List of valid styles
final Iterable
? validStyles = styles?.where(
(element) => valueValidator?.call(element) ?? (element != null),
);
+
+ // tranformation function
+ final transformation = transform ?? (element) => element as T?;
+
return (validStyles?.isNotEmpty ?? false)
- ? transform?.call(
+ ? transformation.call(
validStyles?.reduce(
(value, element) => combine?.call(value, element) ?? value,
),
)
: null;
}
+
+ /// Gets a theme element from a list of styles. Throws an exception if no
+ /// valid style is found.
+ ///
+ /// See [maybeGetElement] for more details.
+ ///
+ /// {@macro getElement}
+ static T getElement
(
+ List
? styles, {
+ T? Function(P?)? transform,
+ bool? Function(P?)? valueValidator,
+ P? Function(P?, P?)? combine,
+ }) {
+ final result = maybeGetElement
(
+ styles,
+ transform: transform,
+ valueValidator: valueValidator,
+ combine: combine,
+ );
+
+ if (result == null) {
+ throw Exception('No valid style found');
+ }
+
+ return result;
+ }
}
diff --git a/packages/wyatt_ui_kit/lib/src/core/helpers/linear_gradient_helper.dart b/packages/wyatt_ui_components/lib/src/core/utils/theme_importer.dart
similarity index 58%
rename from packages/wyatt_ui_kit/lib/src/core/helpers/linear_gradient_helper.dart
rename to packages/wyatt_ui_components/lib/src/core/utils/theme_importer.dart
index 49eb9c80..a5c5eae0 100644
--- a/packages/wyatt_ui_kit/lib/src/core/helpers/linear_gradient_helper.dart
+++ b/packages/wyatt_ui_components/lib/src/core/utils/theme_importer.dart
@@ -15,12 +15,25 @@
// along with this program. If not, see .
import 'package:flutter/material.dart';
-import 'package:wyatt_ui_components/wyatt_ui_components.dart';
-class LinearGradientHelper {
- static LinearGradient? fromNullableColors(List? colors) =>
- colors != null ? LinearGradient(colors: colors) : null;
+abstract class ThemeImporter {
+ /// Imports a [ThemeData] from either a [BuildContext] or a [ThemeData].
+ ///
+ /// Throws an [ArgumentError] if the type of [from] is not a [BuildContext]
+ /// or a [ThemeData].
+ static ThemeData importFrom(T from) {
+ ThemeData theme;
- static LinearGradient? fromMultiColor(MultiColor multiColor) =>
- multiColor.isGradient ? LinearGradient(colors: multiColor.colors) : null;
+ if (from is BuildContext) {
+ theme = Theme.of(from);
+ } else if (from is ThemeData) {
+ theme = from;
+ } else {
+ throw ArgumentError(
+ 'from must be either a BuildContext or a ThemeData',
+ );
+ }
+
+ return theme;
+ }
}
diff --git a/packages/wyatt_ui_components/lib/src/core/utils/theme_resolver.dart b/packages/wyatt_ui_components/lib/src/core/utils/theme_resolver.dart
index a8cb2d1e..72a9d231 100644
--- a/packages/wyatt_ui_components/lib/src/core/utils/theme_resolver.dart
+++ b/packages/wyatt_ui_components/lib/src/core/utils/theme_resolver.dart
@@ -26,47 +26,52 @@ import 'package:wyatt_ui_components/src/domain/entities/theme_style.dart';
/// 1) Pass the "radius" into the constructor, `Component(radius: 12)`.
/// 2) Set up a theme extension `ComponentThemeExtension(radius: 15)`.
/// 3) Let `wyatt_ui_kit` "negotiate" and try to find a suitable style in the
-/// flutter theme.
+/// flutter theme, or use a hardcoded value.
///
-/// If this negotiation phase fails, then:
-/// - If the value is mandatory: a hardcoded value in "wyatt_ui_kit" is chosen.
-/// - If not, the style is simply not applied.
+/// If a negotiation phase fails, it will fallback to the next one.
+///
+/// This resolver uses [ThemeHelper] to negotiate and merge styles.
/// {@endtemplate}
-abstract class ThemeResolver, T, E> {
+abstract class ThemeResolver