feat(ui): fix, rename, rewrite some helpers
This commit is contained in:
parent
cef73aa62d
commit
3fb4020594
@ -16,6 +16,5 @@
|
||||
|
||||
export 'enums/enums.dart';
|
||||
export 'extensions/build_context_extensions.dart';
|
||||
export 'extensions/string_extension.dart';
|
||||
export 'mixins/copy_with_mixin.dart';
|
||||
export 'utils/utils.dart';
|
||||
|
@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
|
||||
extension StringExtension on String? {
|
||||
TextWrapper? wrap({TextStyle? style, MultiColor? gradientColors}) =>
|
||||
this != null
|
||||
? TextWrapper(this!, style: style, gradientColors: gradientColors)
|
||||
: null;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
|
||||
abstract class GradientHelper {
|
||||
static LinearGradient? linearFromNullableColors(List<Color>? colors) =>
|
||||
colors != null ? LinearGradient(colors: colors) : null;
|
||||
|
||||
static LinearGradient? linearFromMultiColor(MultiColor multiColor) =>
|
||||
multiColor.isGradient ? LinearGradient(colors: multiColor.colors) : null;
|
||||
|
||||
static RadialGradient? radialFromNullableColors(List<Color>? colors) =>
|
||||
colors != null ? RadialGradient(colors: colors) : null;
|
||||
|
||||
static RadialGradient? radialFromMultiColor(MultiColor multiColor) =>
|
||||
multiColor.isGradient ? RadialGradient(colors: multiColor.colors) : null;
|
||||
|
||||
static SweepGradient? sweepFromNullableColors(List<Color>? colors) =>
|
||||
colors != null ? SweepGradient(colors: colors) : null;
|
||||
|
||||
static SweepGradient? sweepFromMultiColor(MultiColor multiColor) =>
|
||||
multiColor.isGradient ? SweepGradient(colors: multiColor.colors) : null;
|
||||
}
|
@ -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;
|
||||
|
@ -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<P, T>(
|
||||
/// - [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<P, T>(
|
||||
List<P?>? 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<P?>? 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<P, T>(
|
||||
List<P?>? styles, {
|
||||
T? Function(P?)? transform,
|
||||
bool? Function(P?)? valueValidator,
|
||||
P? Function(P?, P?)? combine,
|
||||
}) {
|
||||
final result = maybeGetElement<P, T>(
|
||||
styles,
|
||||
transform: transform,
|
||||
valueValidator: valueValidator,
|
||||
combine: combine,
|
||||
);
|
||||
|
||||
if (result == null) {
|
||||
throw Exception('No valid style found');
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,25 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
|
||||
class LinearGradientHelper {
|
||||
static LinearGradient? fromNullableColors(List<Color>? 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>(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;
|
||||
}
|
||||
}
|
@ -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<S extends ThemeStyle<S>, T, E> {
|
||||
abstract class ThemeResolver<Style extends ThemeStyle<Style>, Extension,
|
||||
Extra> {
|
||||
/// {@macro theme_resolver}
|
||||
const ThemeResolver();
|
||||
|
||||
S? Function(BuildContext context, {E? extra}) get customStyleFn;
|
||||
|
||||
/// Compute default value from Flutter Theme or with hardcoded values.
|
||||
S computeDefaultValue(
|
||||
Style computeDefaultValue(
|
||||
BuildContext context, {
|
||||
E? extra,
|
||||
Extra? extra,
|
||||
});
|
||||
|
||||
/// Compute custom style from context.
|
||||
Style? Function(BuildContext context, {Extra? extra}) get customStyleFn;
|
||||
|
||||
/// Compute extension value from custom component extension.
|
||||
S? computeExtensionValueFn(
|
||||
Style? computeExtensionValueFn(
|
||||
BuildContext context,
|
||||
T? themeExtension, {
|
||||
E? extra,
|
||||
Extension? themeExtension, {
|
||||
Extra? extra,
|
||||
});
|
||||
|
||||
/// Choose most suitable style for a given context.
|
||||
S negotiate(BuildContext context, {E? extra}) {
|
||||
Style negotiate(BuildContext context, {Extra? extra}) {
|
||||
// 1) Custom style passed in constructor (cannot be null)
|
||||
final style = computeDefaultValue(context, extra: extra);
|
||||
return ThemeHelper.getThemeElement<S, S>(
|
||||
[
|
||||
style,
|
||||
computeExtensionValueFn(
|
||||
context,
|
||||
Theme.of(context).extension<T>(),
|
||||
extra: extra,
|
||||
),
|
||||
customStyleFn(context, extra: extra)
|
||||
],
|
||||
transform: (value) => value,
|
||||
combine: (value, element) => value?.mergeWith(element),
|
||||
) ??
|
||||
style;
|
||||
return ThemeHelper.getElement<Style, Style>(
|
||||
[
|
||||
// 1) Custom style passed in constructor
|
||||
customStyleFn(context, extra: extra),
|
||||
// 2) Theme extension
|
||||
computeExtensionValueFn(
|
||||
context,
|
||||
Theme.of(context).extension<Extension>(),
|
||||
extra: extra,
|
||||
),
|
||||
// 3) Default
|
||||
style,
|
||||
],
|
||||
transform: (value) => value,
|
||||
combine: (value, element) => value?.mergeWith(element),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'gradient_helper.dart';
|
||||
export 'multi_color.dart';
|
||||
export 'text_wrapper.dart';
|
||||
export 'theme_helper.dart';
|
||||
|
@ -15,4 +15,3 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export './extensions/extensions.dart';
|
||||
export './helpers/helpers.dart';
|
||||
|
@ -1,17 +0,0 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export './linear_gradient_helper.dart';
|
@ -17,7 +17,11 @@
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
|
||||
/// {@template wyatt_component_theme_data}
|
||||
/// A class that holds the theme data for the Wyatt UI Kit.
|
||||
/// {@endtemplate}
|
||||
class WyattComponentThemeData {
|
||||
/// {@macro wyatt_component_theme_data}
|
||||
static ComponentThemeData get wyattComponentThemeData => ComponentThemeData(
|
||||
appBar: const TopAppBar(),
|
||||
topNavigationBarComponent: const TopNavigationBar(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user