ui_kit/feat/cascade-theme-helper #156
@ -58,16 +58,15 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
 | 
			
		||||
            valueValidator: (value) => value?.isGradient,
 | 
			
		||||
            transform: (value) =>
 | 
			
		||||
                LinearGradientHelper.fromNullableColors(value?.colors),
 | 
			
		||||
            defaultValue: null,
 | 
			
		||||
          ),
 | 
			
		||||
          color: ThemeHelper.getThemeElement<MultiColor, Color>(
 | 
			
		||||
            [
 | 
			
		||||
              backgroundColor,
 | 
			
		||||
              context.themeExtension<TopBarThemeExtension>()?.backgroundColors,
 | 
			
		||||
              MultiColor.single(Theme.of(context).appBarTheme.backgroundColor),
 | 
			
		||||
            ],
 | 
			
		||||
            valueValidator: (value) => value?.isColor,
 | 
			
		||||
            transform: (value) => value?.color,
 | 
			
		||||
            defaultValue: Theme.of(context).appBarTheme.backgroundColor,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
        child: Column(
 | 
			
		||||
@ -88,10 +87,10 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
 | 
			
		||||
                [
 | 
			
		||||
                  iconTheme,
 | 
			
		||||
                  context.themeExtension<TopBarThemeExtension>()?.iconTheme,
 | 
			
		||||
                  Theme.of(context).iconTheme,
 | 
			
		||||
                ],
 | 
			
		||||
                valueValidator: (value) => value != null,
 | 
			
		||||
                transform: (value) => value,
 | 
			
		||||
                defaultValue: Theme.of(context).iconTheme,
 | 
			
		||||
              ),
 | 
			
		||||
              primary: primary ?? true,
 | 
			
		||||
              excludeHeaderSemantics: excludeHeaderSemantics ?? false,
 | 
			
		||||
@ -100,12 +99,13 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
 | 
			
		||||
                title?.data ?? '',
 | 
			
		||||
                style: ThemeHelper.getThemeElement<TextStyle, TextStyle>(
 | 
			
		||||
                  [
 | 
			
		||||
                    context.textTheme.titleLarge,
 | 
			
		||||
                    context.themeExtension<TopBarThemeExtension>()?.titleStyle,
 | 
			
		||||
                    title?.style,
 | 
			
		||||
                    context.themeExtension<TopBarThemeExtension>()?.titleStyle
 | 
			
		||||
                  ],
 | 
			
		||||
                  valueValidator: (value) => value != null,
 | 
			
		||||
                  combine: (p0, p1) => p0?.merge(p1),
 | 
			
		||||
                  transform: (value) => value,
 | 
			
		||||
                  defaultValue: context.textTheme.titleLarge,
 | 
			
		||||
                ),
 | 
			
		||||
              ).toGradient(gradientColors: title?.gradientColors),
 | 
			
		||||
              leading: leading,
 | 
			
		||||
@ -120,10 +120,10 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
 | 
			
		||||
                        .themeExtension<TopBarThemeExtension>()
 | 
			
		||||
                        ?.secondaryColor
 | 
			
		||||
                        ?.withOpacity(0.1),
 | 
			
		||||
                    Theme.of(context).dividerColor,
 | 
			
		||||
                  ],
 | 
			
		||||
                  valueValidator: (value) => value != null,
 | 
			
		||||
                  transform: (value) => value,
 | 
			
		||||
                  defaultValue: Theme.of(context).dividerColor,
 | 
			
		||||
                ),
 | 
			
		||||
                context: context,
 | 
			
		||||
                tiles: expandedWidget!,
 | 
			
		||||
 | 
			
		||||
@ -62,16 +62,15 @@ class TopNavigationBar extends TopNavigationBarComponent
 | 
			
		||||
            valueValidator: (value) => value?.isGradient,
 | 
			
		||||
            transform: (value) =>
 | 
			
		||||
                LinearGradientHelper.fromNullableColors(value?.colors),
 | 
			
		||||
            defaultValue: null,
 | 
			
		||||
          ),
 | 
			
		||||
          color: ThemeHelper.getThemeElement<MultiColor, Color>(
 | 
			
		||||
            [
 | 
			
		||||
              backgroundColor,
 | 
			
		||||
              context.themeExtension<TopBarThemeExtension>()?.backgroundColors,
 | 
			
		||||
              MultiColor.single(Theme.of(context).appBarTheme.backgroundColor),
 | 
			
		||||
            ],
 | 
			
		||||
            valueValidator: (value) => value?.isColor,
 | 
			
		||||
            transform: (value) => value?.color,
 | 
			
		||||
            defaultValue: Theme.of(context).appBarTheme.backgroundColor,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
        child: AppBar(
 | 
			
		||||
@ -90,10 +89,10 @@ class TopNavigationBar extends TopNavigationBarComponent
 | 
			
		||||
            [
 | 
			
		||||
              iconTheme,
 | 
			
		||||
              context.themeExtension<TopBarThemeExtension>()?.iconTheme,
 | 
			
		||||
              Theme.of(context).iconTheme,
 | 
			
		||||
            ],
 | 
			
		||||
            valueValidator: (value) => value != null,
 | 
			
		||||
            transform: (value) => value,
 | 
			
		||||
            defaultValue: Theme.of(context).iconTheme,
 | 
			
		||||
          ),
 | 
			
		||||
          primary: primary ?? true,
 | 
			
		||||
          excludeHeaderSemantics: excludeHeaderSemantics ?? false,
 | 
			
		||||
 | 
			
		||||
@ -41,11 +41,11 @@ class NavigationItem extends StatelessWidget {
 | 
			
		||||
                  [
 | 
			
		||||
                    context
 | 
			
		||||
                        .themeExtension<TopBarThemeExtension>()
 | 
			
		||||
                        ?.secondaryColor
 | 
			
		||||
                        ?.secondaryColor,
 | 
			
		||||
                    Theme.of(context).primaryColor,
 | 
			
		||||
                  ],
 | 
			
		||||
                  valueValidator: (value) => value != null,
 | 
			
		||||
                  transform: (value) => value,
 | 
			
		||||
                  defaultValue: Theme.of(context).primaryColor,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
@ -56,14 +56,15 @@ class NavigationItem extends StatelessWidget {
 | 
			
		||||
                item.data,
 | 
			
		||||
                style: ThemeHelper.getThemeElement<TextStyle, TextStyle>(
 | 
			
		||||
                  [
 | 
			
		||||
                    item.style,
 | 
			
		||||
                    context.textTheme.titleMedium,
 | 
			
		||||
                    context
 | 
			
		||||
                        .themeExtension<TopBarThemeExtension>()
 | 
			
		||||
                        ?.subTitleStyle
 | 
			
		||||
                        ?.subTitleStyle,
 | 
			
		||||
                    item.style,
 | 
			
		||||
                  ],
 | 
			
		||||
                  combine: (value, element) => value?.merge(element),
 | 
			
		||||
                  valueValidator: (value) => value != null,
 | 
			
		||||
                  transform: (value) => value,
 | 
			
		||||
                  defaultValue: context.textTheme.titleMedium,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
 | 
			
		||||
@ -74,7 +74,6 @@ class CardWrapper extends StatelessWidget {
 | 
			
		||||
      ],
 | 
			
		||||
      valueValidator: (shadow) => shadow != null,
 | 
			
		||||
      transform: (shadow) => shadow,
 | 
			
		||||
      defaultValue: null,
 | 
			
		||||
    );
 | 
			
		||||
    return (themeShadow != null) ? [themeShadow] : [];
 | 
			
		||||
  }
 | 
			
		||||
@ -92,11 +91,9 @@ class CardWrapper extends StatelessWidget {
 | 
			
		||||
                    .extension<CardThemeExtension>()
 | 
			
		||||
                    ?.backgroundColors,
 | 
			
		||||
              ],
 | 
			
		||||
              valueValidator: (multiColor) =>
 | 
			
		||||
                  multiColor != null && multiColor.isGradient,
 | 
			
		||||
              valueValidator: (multiColor) => multiColor?.isGradient,
 | 
			
		||||
              transform: (multiColor) =>
 | 
			
		||||
                  LinearGradientHelper.fromMultiColor(multiColor!),
 | 
			
		||||
              defaultValue: null,
 | 
			
		||||
            ),
 | 
			
		||||
            color: ThemeHelper.getThemeElement<MultiColor, Color>(
 | 
			
		||||
              [
 | 
			
		||||
@ -104,11 +101,11 @@ class CardWrapper extends StatelessWidget {
 | 
			
		||||
                Theme.of(context)
 | 
			
		||||
                    .extension<CardThemeExtension>()
 | 
			
		||||
                    ?.backgroundColors,
 | 
			
		||||
                MultiColor.single(Theme.of(context).cardColor),
 | 
			
		||||
              ],
 | 
			
		||||
              valueValidator: (multiColor) =>
 | 
			
		||||
                  multiColor != null && multiColor.isColor,
 | 
			
		||||
              transform: (multiColor) => multiColor?.color,
 | 
			
		||||
              defaultValue: Theme.of(context).cardColor,
 | 
			
		||||
            ),
 | 
			
		||||
            border: ThemeHelper.getThemeElement<MultiColor, BoxBorder>(
 | 
			
		||||
              [
 | 
			
		||||
@ -130,7 +127,6 @@ class CardWrapper extends StatelessWidget {
 | 
			
		||||
                  color: multiColor.color,
 | 
			
		||||
                );
 | 
			
		||||
              },
 | 
			
		||||
              defaultValue: null,
 | 
			
		||||
            ),
 | 
			
		||||
            boxShadow: _shadow(context),
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
@ -16,26 +16,34 @@
 | 
			
		||||
 | 
			
		||||
/// A helper class for getting theme elements.
 | 
			
		||||
abstract class ThemeHelper {
 | 
			
		||||
 | 
			
		||||
  /// Gets a theme element from a list of styles.
 | 
			
		||||
  /// Styles are checked in order, and the first one that passes the
 | 
			
		||||
  /// [valueValidator] is returned.
 | 
			
		||||
  /// If no style passes the [valueValidator], the [defaultValue] is returned.
 | 
			
		||||
  /// If [styles] is null or empty, the [defaultValue] 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>(
 | 
			
		||||
    List<P?>? styles, {
 | 
			
		||||
    required T? Function(P?)? transform,
 | 
			
		||||
    required T? defaultValue,
 | 
			
		||||
    bool? Function(P?)? valueValidator,
 | 
			
		||||
    P? Function(P?, P?)? combine,
 | 
			
		||||
  }) {
 | 
			
		||||
    if (styles?.isNotEmpty ?? false) {
 | 
			
		||||
      for (final element in styles!) {
 | 
			
		||||
        if (valueValidator?.call(element) ?? false) {
 | 
			
		||||
          return transform?.call(element);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return defaultValue;
 | 
			
		||||
    final Iterable<P?>? validStyles = styles?.where(
 | 
			
		||||
      (element) => valueValidator?.call(element) ?? (element != null),
 | 
			
		||||
    );
 | 
			
		||||
    return (validStyles?.isNotEmpty ?? false)
 | 
			
		||||
        ? transform?.call(
 | 
			
		||||
            validStyles?.reduce(
 | 
			
		||||
              (value, element) => combine?.call(value, element) ?? value,
 | 
			
		||||
            ),
 | 
			
		||||
          )
 | 
			
		||||
        : null;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user