feat(ui)!: move last extensions + add extension provider
Some checks failed
continuous-integration/drone/pr Build is failing

This commit is contained in:
Hugo Pointcheval 2023-04-27 20:28:08 +02:00
parent 8f5e3923d6
commit 4097a420c8
Signed by: hugo
GPG Key ID: 3AAC487E131E00BC
33 changed files with 824 additions and 472 deletions

View File

@ -28,7 +28,7 @@ class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) => ComponentTheme(
componentThemeWidget: AppThemeComponent.components,
data: AppThemeComponent.components,
child: MaterialApp(
title: 'Wyatt Ui Components Example',
theme: ThemeData(

View File

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with super program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
/// A helper class for getting theme elements.
abstract class ThemeHelper {
/// Gets a nullable theme element from a list of styles.
@ -83,7 +85,11 @@ abstract class ThemeHelper {
);
if (result == null) {
throw Exception('No valid style found');
throw FlutterError(
'No valid style found.\nPlease check your theme configuration.\n'
'Searching for: $P in $styles (transform to $T)\n'
'If this value can be null, use maybeGetElement instead.',
);
}
return result;

View File

@ -45,7 +45,7 @@ class CardThemeExtensionDefault extends CardThemeExtension {
factory CardThemeExtensionDefault.from(ThemeData theme) =>
CardThemeExtensionDefault(
radius: const BorderRadius.all(Radius.circular(12)),
padding: theme.cardTheme.margin,
padding: theme.cardTheme.margin ?? const EdgeInsets.all(4),
backgroundColors: MultiColor.single(theme.cardTheme.color),
borderColors: MultiColor.single(theme.cardTheme.color),
minSize: const Size(330, 0),

View File

@ -0,0 +1,50 @@
// 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';
/// {@template loader_theme_extension_default}
/// The default [LoaderThemeExtension].
/// {@endtemplate}
class LoaderThemeExtensionDefault extends LoaderThemeExtension {
/// {@macro loader_theme_extension_default}
const LoaderThemeExtensionDefault({
required super.colors,
required super.stroke,
});
/// Creates a [LoaderThemeExtensionDefault] from a [ThemeData]
/// and opinionated defaults.
///
/// {@macro card_theme_extension_default}
factory LoaderThemeExtensionDefault.from(ThemeData theme) =>
LoaderThemeExtensionDefault(
colors: MultiColor([
theme.progressIndicatorTheme.color ?? theme.colorScheme.primary,
Colors.transparent,
]),
stroke: 4,
);
/// Creates a [LoaderThemeExtensionDefault] from a dark [ThemeData]
factory LoaderThemeExtensionDefault.dark() =>
LoaderThemeExtensionDefault.from(ThemeData.dark());
/// Creates a [LoaderThemeExtensionDefault] from a light [ThemeData]
factory LoaderThemeExtensionDefault.light() =>
LoaderThemeExtensionDefault.from(ThemeData.light());
}

View File

@ -0,0 +1,73 @@
// 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/src/domain/theme_extensions/rich_text_builder_theme_extension.dart';
class RichTextBuilderThemeExtensionDefault
extends RichTextBuilderThemeExtension {
const RichTextBuilderThemeExtensionDefault({
required super.defaultStyle,
required super.styles,
});
/// Creates a [RichTextBuilderThemeExtensionDefault] from a [ThemeData]
/// and opinionated defaults.
///
/// {@macro card_theme_extension_default}
factory RichTextBuilderThemeExtensionDefault.from(ThemeData theme) =>
RichTextBuilderThemeExtensionDefault(
defaultStyle: theme.textTheme.bodyMedium,
styles: {
'blue': theme.textTheme.bodyMedium?.copyWith(
color: Colors.blue,
) ??
const TextStyle(
color: Colors.blue,
),
'red': theme.textTheme.bodyMedium?.copyWith(
color: Colors.red,
) ??
const TextStyle(
color: Colors.red,
),
'green': theme.textTheme.bodyMedium?.copyWith(
color: Colors.green,
) ??
const TextStyle(
color: Colors.green,
),
'bold': theme.textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.bold,
) ??
const TextStyle(
fontWeight: FontWeight.bold,
),
'italic': theme.textTheme.bodyMedium?.copyWith(
fontStyle: FontStyle.italic,
) ??
const TextStyle(fontStyle: FontStyle.italic),
},
);
/// Creates a [RichTextBuilderThemeExtensionDefault] from a dark [ThemeData]
factory RichTextBuilderThemeExtensionDefault.dark() =>
RichTextBuilderThemeExtensionDefault.from(ThemeData.dark());
/// Creates a [RichTextBuilderThemeExtensionDefault] from a light [ThemeData]
factory RichTextBuilderThemeExtensionDefault.light() =>
RichTextBuilderThemeExtensionDefault.from(ThemeData.light());
}

View File

@ -16,4 +16,7 @@
export 'button_theme_extension/button_theme_extension.dart';
export 'card_theme_extension_default.dart';
export 'loader_theme_extension_default.dart';
export 'rich_text_builder_theme_extension_default.dart';
export 'text_input_theme_extension_default.dart';
export 'top_bar_theme_extension_default.dart';

View File

@ -0,0 +1,54 @@
// 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';
class TopBarThemeExtensionDefault extends TopBarThemeExtension {
const TopBarThemeExtensionDefault({
required super.iconTheme,
required super.backgroundColors,
required super.titleStyle,
required super.subtitleStyle,
required super.selectedIndicatorColors,
required super.selectedIndicatorSize,
required super.dividerColor,
});
/// Creates a [TopBarThemeExtensionDefault] from a [ThemeData]
/// and opinionated defaults.
///
/// {@macro card_theme_extension_default}
factory TopBarThemeExtensionDefault.from(ThemeData theme) =>
TopBarThemeExtensionDefault(
backgroundColors: MultiColor.single(theme.appBarTheme.backgroundColor),
titleStyle:
theme.appBarTheme.titleTextStyle ?? theme.textTheme.titleMedium,
subtitleStyle: theme.textTheme.bodyMedium,
selectedIndicatorColors: MultiColor.single(theme.colorScheme.primary),
selectedIndicatorSize: const Size(70, 5),
iconTheme: theme.iconTheme,
dividerColor: theme.colorScheme.onSurface.withOpacity(0.12),
);
/// Creates a [TopBarThemeExtensionDefault] from a dark [ThemeData]
factory TopBarThemeExtensionDefault.dark() =>
TopBarThemeExtensionDefault.from(ThemeData.dark());
/// Creates a [TopBarThemeExtensionDefault] from a light [ThemeData]
factory TopBarThemeExtensionDefault.light() =>
TopBarThemeExtensionDefault.from(ThemeData.light());
}

View File

@ -18,31 +18,25 @@ import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
import 'package:wyatt_ui_kit_example/theme/constants.dart';
class LoaderTheme extends LoaderThemeExtension {
const LoaderTheme({
super.colors,
super.stroke,
class LoaderThemeExtension extends ThemeExtension<LoaderThemeExtension> {
const LoaderThemeExtension({
this.colors,
this.stroke,
});
factory LoaderTheme.light() => const LoaderTheme(
colors: MultiColor([Constants.blue1, Constants.white]),
stroke: 15,
);
/// Gradient colors from start to end.
final MultiColor? colors;
factory LoaderTheme.dark() => const LoaderTheme(
colors: MultiColor([Constants.blue2, Constants.grey2]),
stroke: 15,
);
/// Loader stroke width
final double? stroke;
@override
ThemeExtension<LoaderThemeExtension> copyWith({
MultiColor? colors,
double? stroke,
}) =>
LoaderTheme(
LoaderThemeExtension(
colors: colors ?? this.colors,
stroke: stroke ?? this.stroke,
);
@ -52,10 +46,10 @@ class LoaderTheme extends LoaderThemeExtension {
covariant ThemeExtension<LoaderThemeExtension>? other,
double t,
) {
if (other is! LoaderTheme) {
if (other is! LoaderThemeExtension) {
return this;
}
return LoaderTheme(
return LoaderThemeExtension(
colors: MultiColor.lerp(colors, other.colors, t),
stroke: lerpDouble(stroke, other.stroke, t),
);

View File

@ -16,7 +16,7 @@
import 'package:flutter/material.dart';
abstract class RichTextBuilderThemeExtension
class RichTextBuilderThemeExtension
extends ThemeExtension<RichTextBuilderThemeExtension> {
const RichTextBuilderThemeExtension({
this.defaultStyle,
@ -28,4 +28,28 @@ abstract class RichTextBuilderThemeExtension
/// Used styles in this rich text component.
final Map<String, TextStyle>? styles;
@override
ThemeExtension<RichTextBuilderThemeExtension> copyWith({
TextStyle? defaultStyle,
Map<String, TextStyle>? styles,
}) =>
RichTextBuilderThemeExtension(
defaultStyle: defaultStyle ?? this.defaultStyle,
styles: styles ?? this.styles,
);
@override
ThemeExtension<RichTextBuilderThemeExtension> lerp(
covariant ThemeExtension<RichTextBuilderThemeExtension>? other,
double t,
) {
if (other is! RichTextBuilderThemeExtension) {
return this;
}
return RichTextBuilderThemeExtension(
defaultStyle: TextStyle.lerp(defaultStyle, other.defaultStyle, t),
styles: styles,
);
}
}

View File

@ -16,4 +16,7 @@
export 'button_theme_extension/button_theme_extension.dart';
export 'card_theme_extension.dart';
export 'loader_theme_extension.dart';
export 'rich_text_builder_theme_extension.dart';
export 'text_input_theme_extension.dart';
export 'top_bar_theme_extension.dart';

View File

@ -0,0 +1,95 @@
// 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';
class TopBarThemeExtension extends ThemeExtension<TopBarThemeExtension> {
const TopBarThemeExtension({
this.iconTheme,
this.backgroundColors,
this.titleStyle,
this.subtitleStyle,
this.selectedIndicatorColors,
this.selectedIndicatorSize,
this.dividerColor,
});
/// Background colors from start to end of the top bar.
final MultiColor? backgroundColors;
/// Icon theme used in this top bar.
final IconThemeData? iconTheme;
/// Selected indicator colors used in this top bar.
final MultiColor? selectedIndicatorColors;
/// Divider color used in this top bar.
final Color? dividerColor;
/// Title style used in this top bar.
final TextStyle? titleStyle;
/// Subtitle style used in this top bar.
final TextStyle? subtitleStyle;
/// Selected indicator size used in this top bar.
final Size? selectedIndicatorSize;
@override
ThemeExtension<TopBarThemeExtension> copyWith({
MultiColor? backgroundColors,
IconThemeData? iconTheme,
MultiColor? selectedIndicatorColors,
Color? dividerColor,
TextStyle? titleStyle,
TextStyle? subtitleStyle,
Size? selectedIndicatorSize,
}) =>
TopBarThemeExtension(
iconTheme: iconTheme ?? this.iconTheme,
backgroundColors: backgroundColors ?? this.backgroundColors,
selectedIndicatorColors:
selectedIndicatorColors ?? this.selectedIndicatorColors,
dividerColor: dividerColor ?? this.dividerColor,
titleStyle: titleStyle ?? this.titleStyle,
subtitleStyle: subtitleStyle ?? this.subtitleStyle,
selectedIndicatorSize:
selectedIndicatorSize ?? this.selectedIndicatorSize,
);
@override
ThemeExtension<TopBarThemeExtension> lerp(
covariant ThemeExtension<TopBarThemeExtension>? other,
double t,
) {
if (other is! TopBarThemeExtension) {
return this;
}
return TopBarThemeExtension(
iconTheme: IconThemeData.lerp(iconTheme, other.iconTheme, t),
backgroundColors:
MultiColor.lerp(backgroundColors, other.backgroundColors, t),
selectedIndicatorColors: MultiColor.lerp(
selectedIndicatorColors, other.selectedIndicatorColors, t,),
dividerColor: Color.lerp(dividerColor, other.dividerColor, t),
titleStyle: TextStyle.lerp(titleStyle, other.titleStyle, t),
subtitleStyle: TextStyle.lerp(subtitleStyle, other.subtitleStyle, t),
selectedIndicatorSize:
Size.lerp(selectedIndicatorSize, other.selectedIndicatorSize, t),
);
}
}

View File

@ -15,7 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/src/features/features.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
/// {@template component_theme}
/// A [ComponentTheme] widget that provides a [ComponentThemeData] to its
@ -25,11 +25,22 @@ class ComponentTheme extends StatelessWidget {
/// {@macro component_theme}
const ComponentTheme({
required this.child,
required this.componentThemeWidget,
required this.data,
this.themeExtensionProvider = const DefaultThemeExtensionProvider(),
super.key,
});
/// The [ComponentThemeData] of this widget.
///
/// This contains all components instances of the theme.
final ComponentThemeData data;
/// The [ThemeExtensionProvider] that provides the extensions for the
/// current theme.
final ThemeExtensionProvider themeExtensionProvider;
/// The widget below this widget in the tree.
final Widget child;
final ComponentThemeData componentThemeWidget;
/// Returns the [ComponentThemeData] of the closest ancestor [ComponentTheme]
/// widget. If there is no ancestor [ComponentTheme] widget, it throws an
@ -42,7 +53,7 @@ class ComponentTheme extends StatelessWidget {
inheritedThemeComponent != null,
'Theme component not find in tree',
);
return inheritedThemeComponent!.themeWidget.componentThemeWidget;
return inheritedThemeComponent!.themeWidget.data;
}
/// Returns the [ComponentThemeData] of the closest ancestor [ComponentTheme]
@ -51,13 +62,17 @@ class ComponentTheme extends StatelessWidget {
final _InheritedComponentTheme? inheritedThemeComponent =
context.dependOnInheritedWidgetOfExactType<_InheritedComponentTheme>();
return inheritedThemeComponent?.themeWidget.componentThemeWidget;
return inheritedThemeComponent?.themeWidget.data;
}
@override
Widget build(BuildContext context) => _InheritedComponentTheme(
this,
child: child,
Widget build(BuildContext context) => Theme(
// Injections of the default extensions for the current brightness
data: themeExtensionProvider.applyExtensionsTo(Theme.of(context)),
child: _InheritedComponentTheme(
this,
child: child,
),
);
}

View File

@ -16,3 +16,4 @@
export 'component_theme.dart';
export 'component_theme_data.dart';
export 'theme_extension_provider.dart';

View File

@ -0,0 +1,107 @@
// 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';
/// {@template theme_extension_provider}
/// A provider of [ThemeExtension]s to automatically apply to a [Theme].
/// {@endtemplate}
abstract class ThemeExtensionProvider {
/// {@macro theme_extension_provider}
const ThemeExtensionProvider();
/// Returns the [ThemeExtension]s to apply to the current [ThemeData].
List<ThemeExtension<dynamic>> getThemeExtensionsFor(ThemeData theme);
/// Returns a [ThemeData] with the [ThemeExtension]s applied.
ThemeData applyExtensionsTo(
ThemeData theme,
) =>
theme.copyWith(
extensions: [
...theme.extensions.values,
...getThemeExtensionsFor(theme),
],
);
}
/// {@template default_theme_extension_provider}
/// A [ThemeExtensionProvider] that provides the default [ThemeExtension]s
/// for the current [ThemeData.brightness].
/// {@endtemplate}
class DefaultThemeExtensionProvider extends ThemeExtensionProvider {
/// {@macro default_theme_extension_provider}
const DefaultThemeExtensionProvider();
/// Default light theme extensions form Wyatt UI Components
///
/// This needs to be added to the [ThemeData] in order to use the
/// Wyatt UI Components widgets.
///
/// Those extensions are the default ones used in fallback mode
/// when no custom theme is provided.
///
/// See `wyatt_ui_kit` for a custom theme example.
static List<ThemeExtension<dynamic>> get defaultLight => [
// Cards
CardThemeExtensionDefault.light(),
// Loader
LoaderThemeExtensionDefault.light(),
// RichText
RichTextBuilderThemeExtensionDefault.light(),
// Buttons
FileSelectionButtonThemeExtensionDefault.light(),
FlatButtonThemeExtensionDefault.light(),
SimpleIconButtonThemeExtensionDefault.light(),
SymbolButtonThemeExtensionDefault.light(),
// TextInput
TextInputThemeExtensionDefault.light(),
// TopBar
TopBarThemeExtensionDefault.light(),
];
/// Default dark theme extensions form Wyatt UI Components
///
/// This needs to be added to the [ThemeData] in order to use the
/// Wyatt UI Components widgets.
///
/// Those extensions are the default ones used in fallback mode
/// when no custom theme is provided.
///
/// See `wyatt_ui_kit` for a custom theme example.
static List<ThemeExtension<dynamic>> get defaultDark => [
// Cards
CardThemeExtensionDefault.dark(),
// Loader
LoaderThemeExtensionDefault.dark(),
// RichText
RichTextBuilderThemeExtensionDefault.dark(),
// Buttons
FileSelectionButtonThemeExtensionDefault.dark(),
FlatButtonThemeExtensionDefault.dark(),
SimpleIconButtonThemeExtensionDefault.dark(),
SymbolButtonThemeExtensionDefault.dark(),
// TextInput
TextInputThemeExtensionDefault.dark(),
// TopBar
TopBarThemeExtensionDefault.dark(),
];
@override
List<ThemeExtension<dynamic>> getThemeExtensionsFor(ThemeData theme) =>
theme.brightness == Brightness.light ? defaultLight : defaultDark;
}

View File

@ -17,6 +17,8 @@
import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
import 'package:wyatt_ui_kit_example/home.dart';
import 'package:wyatt_ui_kit_example/theme/themes.dart';
@ -43,20 +45,23 @@ class App extends StatelessWidget {
initial: AdaptiveThemeMode.light,
light: Themes.lightFromTheme(defaultTheme),
dark: Themes.darkFromTheme(defaultTheme),
builder: (light, dark) => MaterialApp(
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
theme: light,
darkTheme: dark,
supportedLocales: const [
Locale('fr', ''),
],
title: title,
home: Home(
forceIndex: defaultPage,
builder: (light, dark) => ComponentTheme(
data: WyattComponentThemeData.wyattComponentThemeData,
child: MaterialApp(
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
theme: light,
darkTheme: dark,
supportedLocales: const [
Locale('fr', ''),
],
title: title,
home: Home(
forceIndex: defaultPage,
),
),
),
);

View File

@ -1,120 +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/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
import 'package:wyatt_ui_kit_example/theme/constants.dart';
final Map<String, TextStyle> _styles = {
'gradient-blue': GradientTextStyle.from(
GoogleFonts.montserrat(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Constants.blue1,
height: 1.8,
),
const MultiColor(Constants.blueGradient),
),
'gradient-red': GradientTextStyle.from(
GoogleFonts.montserrat(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Constants.red1,
height: 1.8,
),
const MultiColor(Constants.redGradient),
),
'gradient-green': GradientTextStyle.from(
GoogleFonts.montserrat(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Constants.green1,
height: 1.8,
),
const MultiColor(Constants.greenGradient),
),
'blue': GoogleFonts.montserrat(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Constants.blue1,
height: 1.8,
),
'red': GoogleFonts.montserrat(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Constants.red1,
height: 1.8,
),
'green': GoogleFonts.montserrat(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Constants.green1,
height: 1.8,
),
};
class RichTextBuilderTheme extends RichTextBuilderThemeExtension {
const RichTextBuilderTheme({
super.defaultStyle,
super.styles,
});
factory RichTextBuilderTheme.light() => RichTextBuilderTheme(
defaultStyle: GoogleFonts.montserrat(
fontSize: 18,
fontWeight: FontWeight.w500,
color: Constants.grey3,
height: 1.8,
),
styles: _styles,
);
factory RichTextBuilderTheme.dark() => RichTextBuilderTheme(
defaultStyle: GoogleFonts.montserrat(
fontSize: 18,
fontWeight: FontWeight.w500,
color: Constants.white,
height: 1.8,
),
styles: _styles,
);
@override
ThemeExtension<RichTextBuilderThemeExtension> copyWith({
TextStyle? defaultStyle,
Map<String, TextStyle>? styles,
}) =>
RichTextBuilderTheme(
defaultStyle: defaultStyle ?? this.defaultStyle,
styles: styles ?? this.styles,
);
@override
ThemeExtension<RichTextBuilderThemeExtension> lerp(
covariant ThemeExtension<RichTextBuilderThemeExtension>? other,
double t,
) {
if (other is! RichTextBuilderTheme) {
return this;
}
return RichTextBuilderTheme(
defaultStyle: TextStyle.lerp(defaultStyle, other.defaultStyle, t),
styles: styles,
);
}
}

View File

@ -17,11 +17,7 @@
import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/material.dart' hide CardTheme;
import 'package:google_fonts/google_fonts.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
import 'package:wyatt_ui_kit_example/theme/loader_theme.dart';
import 'package:wyatt_ui_kit_example/theme/rich_text_builder_theme.dart';
import 'package:wyatt_ui_kit_example/theme/top_bar_theme.dart';
/// Easely switch between Material and Studio themes.
abstract class Themes {
@ -67,17 +63,6 @@ abstract class Themes {
textTheme: GoogleFonts.robotoTextTheme(
ThemeData.light().textTheme,
),
extensions: <ThemeExtension<dynamic>>[
// Cards
CardThemeExtensionDefault.light(),
// Buttons
FileSelectionButtonThemeExtensionDefault.light(),
FlatButtonThemeExtensionDefault.light(),
SimpleIconButtonThemeExtensionDefault.light(),
SymbolButtonThemeExtensionDefault.light(),
// TextInput
TextInputThemeExtensionDefault.light(),
],
);
static ThemeData get studioLight {
@ -97,41 +82,13 @@ abstract class Themes {
),
);
return theme.copyWith(
extensions: <ThemeExtension<dynamic>>[
// Cards
CardThemeExtensionImpl.light(theme: theme),
// Buttons
FileSelectionButtonThemeExtensionImpl.light(theme: theme),
FlatButtonThemeExtensionImpl.light(theme: theme),
SimpleIconButtonThemeExtensionImpl.light(theme: theme),
SymbolButtonThemeExtensionImpl.light(theme: theme),
// Loader
LoaderTheme.light(),
// Rich Text
RichTextBuilderTheme.light(),
// TextInput
TextInputThemeExtensionImpl.light(theme: theme),
TopAppBarTheme.light(),
],
);
return const WyattThemeExtensions().applyExtensionsTo(theme);
}
static ThemeData get materialDark => ThemeData.dark().copyWith(
textTheme: GoogleFonts.robotoTextTheme(
ThemeData.dark().textTheme,
),
extensions: <ThemeExtension<dynamic>>[
// Cards
CardThemeExtensionDefault.dark(),
// Buttons
FileSelectionButtonThemeExtensionDefault.dark(),
FlatButtonThemeExtensionDefault.dark(),
SimpleIconButtonThemeExtensionDefault.dark(),
SymbolButtonThemeExtensionDefault.dark(),
// TextInput
TextInputThemeExtensionDefault.dark(),
],
);
static ThemeData get studioDark {
@ -154,23 +111,6 @@ abstract class Themes {
),
);
return theme.copyWith(
extensions: <ThemeExtension<dynamic>>[
// Cards
CardThemeExtensionImpl.dark(theme: theme),
// Buttons
FileSelectionButtonThemeExtensionImpl.dark(theme: theme),
FlatButtonThemeExtensionImpl.dark(theme: theme),
SimpleIconButtonThemeExtensionImpl.dark(theme: theme),
SymbolButtonThemeExtensionImpl.dark(theme: theme),
// Loader
LoaderTheme.dark(),
// Rich Text
RichTextBuilderTheme.dark(),
// TextInput
TextInputThemeExtensionImpl.dark(theme: theme),
TopAppBarTheme.dark(),
],
);
return const WyattThemeExtensions().applyExtensionsTo(theme);
}
}

View File

@ -1,81 +0,0 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
class TopAppBarTheme extends TopBarThemeExtension {
const TopAppBarTheme({
super.iconTheme,
super.backgroundColors,
super.secondaryColor,
super.titleStyle,
super.subTitleStyle,
});
factory TopAppBarTheme.light() => TopAppBarTheme(
backgroundColors: const MultiColor.single(
Color.fromRGBO(246, 246, 246, 1),
),
secondaryColor: const Color.fromRGBO(36, 38, 42, 1),
titleStyle: GoogleFonts.montserrat(
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(36, 38, 42, 1),
fontSize: 18,
),
subTitleStyle: GoogleFonts.montserrat(
fontWeight: FontWeight.w400,
color: const Color.fromRGBO(36, 38, 42, 1),
fontSize: 18,
),
iconTheme: const IconThemeData(color: Color.fromRGBO(36, 38, 42, 1)),
);
factory TopAppBarTheme.dark() => TopAppBarTheme(
backgroundColors: const MultiColor([
Color.fromRGBO(44, 50, 56, 1),
Color.fromRGBO(39, 47, 61, 1),
Color.fromRGBO(44, 50, 56, 1),
]),
secondaryColor: Colors.white,
titleStyle: GoogleFonts.montserrat(
fontWeight: FontWeight.bold,
fontSize: 18,
),
subTitleStyle: GoogleFonts.montserrat(
fontWeight: FontWeight.w400,
fontSize: 18,
),
iconTheme: const IconThemeData(color: Colors.white),
);
@override
ThemeExtension<TopBarThemeExtension> copyWith({
IconThemeData? iconTheme,
MultiColor? backgroundColors,
Color? secondaryColor,
TextStyle? titleStyle,
}) =>
TopAppBarTheme(
iconTheme: iconTheme ?? this.iconTheme,
backgroundColors: backgroundColors ?? this.backgroundColors,
secondaryColor: secondaryColor ?? this.secondaryColor,
titleStyle: titleStyle ?? this.titleStyle,
);
@override
ThemeExtension<TopBarThemeExtension> lerp(
covariant ThemeExtension<TopBarThemeExtension>? other,
double t,
) {
if (other is! TopAppBarTheme) {
return this;
}
return TopAppBarTheme(
iconTheme: IconThemeData.lerp(iconTheme, other.iconTheme, t),
backgroundColors:
MultiColor.lerp(backgroundColors, other.backgroundColors, t),
secondaryColor: Color.lerp(secondaryColor, other.secondaryColor, t),
titleStyle: TextStyle.lerp(titleStyle, other.titleStyle, t),
);
}
}

View File

@ -54,6 +54,8 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
[
backgroundColor,
context.themeExtension<TopBarThemeExtension>()?.backgroundColors,
TopBarThemeExtensionDefault.from(Theme.of(context))
.backgroundColors,
],
valueValidator: (value) => value?.isGradient,
transform: (value) =>
@ -63,7 +65,8 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
[
backgroundColor,
context.themeExtension<TopBarThemeExtension>()?.backgroundColors,
MultiColor.single(Theme.of(context).appBarTheme.backgroundColor),
TopBarThemeExtensionDefault.from(Theme.of(context))
.backgroundColors,
],
valueValidator: (value) => value?.isColor,
transform: (value) => value?.color,
@ -86,10 +89,8 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
[
iconTheme,
context.themeExtension<TopBarThemeExtension>()?.iconTheme,
Theme.of(context).iconTheme,
TopBarThemeExtensionDefault.from(Theme.of(context)).iconTheme,
],
valueValidator: (value) => value != null,
transform: (value) => value,
),
primary: primary ?? true,
excludeHeaderSemantics: excludeHeaderSemantics ?? false,
@ -98,13 +99,12 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
data: title?.data ?? '',
style: ThemeHelper.getElement<TextStyle, TextStyle>(
[
context.textTheme.titleLarge,
TopBarThemeExtensionDefault.from(Theme.of(context))
.titleStyle,
context.themeExtension<TopBarThemeExtension>()?.titleStyle,
title?.style,
],
valueValidator: (value) => value != null,
combine: (p0, p1) => p0?.merge(p1),
transform: (value) => value,
combine: (value, element) => value?.merge(element),
),
gradientColors: const MultiColor([]),
),
@ -118,12 +118,10 @@ class TopAppBar extends TopAppBarComponent with $TopAppBarCWMixin {
[
context
.themeExtension<TopBarThemeExtension>()
?.secondaryColor
?.withOpacity(0.1),
Theme.of(context).dividerColor,
?.dividerColor,
TopBarThemeExtensionDefault.from(Theme.of(context))
.dividerColor,
],
valueValidator: (value) => value != null,
transform: (value) => value,
),
context: context,
tiles: expandedWidget!,

View File

@ -58,6 +58,8 @@ class TopNavigationBar extends TopNavigationBarComponent
[
backgroundColor,
context.themeExtension<TopBarThemeExtension>()?.backgroundColors,
TopBarThemeExtensionDefault.from(Theme.of(context))
.backgroundColors,
],
valueValidator: (value) => value?.isGradient,
transform: (value) =>
@ -67,7 +69,8 @@ class TopNavigationBar extends TopNavigationBarComponent
[
backgroundColor,
context.themeExtension<TopBarThemeExtension>()?.backgroundColors,
MultiColor.single(Theme.of(context).appBarTheme.backgroundColor),
TopBarThemeExtensionDefault.from(Theme.of(context))
.backgroundColors,
],
valueValidator: (value) => value?.isColor,
transform: (value) => value?.color,
@ -89,10 +92,8 @@ class TopNavigationBar extends TopNavigationBarComponent
[
iconTheme,
context.themeExtension<TopBarThemeExtension>()?.iconTheme,
Theme.of(context).iconTheme,
TopBarThemeExtensionDefault.from(Theme.of(context)).iconTheme,
],
valueValidator: (value) => value != null,
transform: (value) => value,
),
primary: primary ?? true,
excludeHeaderSemantics: excludeHeaderSemantics ?? false,

View File

@ -37,35 +37,48 @@ class NavigationItem extends StatelessWidget {
[
context
.themeExtension<TopBarThemeExtension>()
?.selectedIndicatorHeight,
// TODO(wyatt): move default value
5,
?.selectedIndicatorSize
?.height,
TopBarThemeExtensionDefault.from(Theme.of(context))
.selectedIndicatorSize
?.height,
],
valueValidator: (value) => value != null,
transform: (value) => value,
),
width: ThemeHelper.getElement<double, double>(
[
context
.themeExtension<TopBarThemeExtension>()
?.selectedIndicatorWidth,
// TODO(wyatt): move default value
70,
?.selectedIndicatorSize
?.width,
TopBarThemeExtensionDefault.from(Theme.of(context))
.selectedIndicatorSize
?.width,
],
valueValidator: (value) => value != null,
transform: (value) => value,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: ThemeHelper.getElement<Color, Color>(
gradient: ThemeHelper.maybeGetElement<MultiColor, Gradient>(
[
context
.themeExtension<TopBarThemeExtension>()
?.secondaryColor,
context.colorScheme.primary
?.selectedIndicatorColors,
TopBarThemeExtensionDefault.from(Theme.of(context))
.selectedIndicatorColors
],
valueValidator: (value) => value != null,
transform: (value) => value,
valueValidator: (value) => value?.isGradient,
transform: (value) =>
GradientHelper.linearFromNullableColors(value?.colors),
),
color: ThemeHelper.getElement<MultiColor, Color>(
[
context
.themeExtension<TopBarThemeExtension>()
?.selectedIndicatorColors,
TopBarThemeExtensionDefault.from(Theme.of(context))
.selectedIndicatorColors
],
valueValidator: (value) => value?.isColor,
transform: (value) => value?.color,
),
),
),
@ -75,12 +88,12 @@ class NavigationItem extends StatelessWidget {
[
context
.themeExtension<TopBarThemeExtension>()
?.selectedIndicatorWidth,
// TODO(wyatt): move default value
70,
?.selectedIndicatorSize
?.width,
TopBarThemeExtensionDefault.from(Theme.of(context))
.selectedIndicatorSize
?.width,
],
valueValidator: (value) => value != null,
transform: (value) => value,
),
),
child: SizedBox(
@ -90,15 +103,14 @@ class NavigationItem extends StatelessWidget {
item.data,
style: ThemeHelper.getElement<TextStyle, TextStyle>(
[
context.textTheme.titleMedium,
TopBarThemeExtensionDefault.from(Theme.of(context))
.subtitleStyle,
context
.themeExtension<TopBarThemeExtension>()
?.subTitleStyle,
?.subtitleStyle,
item.style,
],
combine: (value, element) => value?.merge(element),
valueValidator: (value) => value != null,
transform: (value) => value,
),
),
),

View File

@ -48,29 +48,18 @@ class Loader extends LoaderComponent with $LoaderCWMixin {
[
colors,
Theme.of(context).extension<LoaderThemeExtension>()?.colors,
MultiColor([
Theme.of(context).progressIndicatorTheme.color ??
context.colorScheme.primary,
context.colorScheme.onPrimary,
]),
/// This is the default value. So the final
/// value cannot be null.
const MultiColor([])
LoaderThemeExtensionDefault.from(Theme.of(context)).colors,
],
valueValidator: (multiColor) =>
multiColor != null && multiColor.isColor,
transform: (multiColor) => multiColor,
),
dimension / 2,
ThemeHelper.getElement<double, double>(
[
stroke,
Theme.of(context).extension<LoaderThemeExtension>()?.stroke,
4,
LoaderThemeExtensionDefault.from(Theme.of(context)).stroke,
],
valueValidator: (stroke) => stroke != null,
transform: (stroke) => stroke,
),
flip: flip ?? false,
),

View File

@ -45,21 +45,19 @@ class RichTextBuilder extends RichTextBuilderComponent
Theme.of(context)
.extension<RichTextBuilderThemeExtension>()
?.defaultStyle,
context.textTheme.bodyMedium,
RichTextBuilderThemeExtensionDefault.from(Theme.of(context))
.defaultStyle,
],
valueValidator: (style) => style != null,
transform: (style) => style,
),
ThemeHelper.getElement<Map<String, TextStyle>, Map<String, TextStyle>>(
[
styles,
RichTextBuilderThemeExtensionDefault.from(Theme.of(context)).styles,
Theme.of(context)
.extension<RichTextBuilderThemeExtension>()
?.styles,
const <String, TextStyle>{},
styles,
],
valueValidator: (styles) => styles != null,
transform: (styles) => styles,
combine: (value, element) => value?..addAll(element ?? {}),
),
null,
),

View File

@ -17,16 +17,33 @@
import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
abstract class LoaderThemeExtension
extends ThemeExtension<LoaderThemeExtension> {
const LoaderThemeExtension({
this.colors,
this.stroke,
class LoaderThemeExtensionImpl extends LoaderThemeExtension {
const LoaderThemeExtensionImpl({
super.colors,
super.stroke,
});
/// Gradient colors from start to end.
final MultiColor? colors;
factory LoaderThemeExtensionImpl.light({ThemeData? theme}) {
theme ??= ThemeData.light();
return const LoaderThemeExtensionImpl(
colors: MultiColor([
Color(0xFF436EF4),
Color(0xFF3C97FB),
Colors.transparent,
]),
stroke: 15,
);
}
/// Loader stroke width
final double? stroke;
factory LoaderThemeExtensionImpl.dark({ThemeData? theme}) {
theme ??= ThemeData.dark();
return const LoaderThemeExtensionImpl(
colors: MultiColor([
Color(0xFF3C97FB),
Color(0xFF436EF4),
Colors.transparent,
]),
stroke: 15,
);
}
}

View File

@ -0,0 +1,111 @@
// 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';
import 'package:wyatt_ui_kit/src/components/gradients/gradient_text_style.dart';
class RichTextBuilderThemeExtensionImpl extends RichTextBuilderThemeExtension {
const RichTextBuilderThemeExtensionImpl({
super.defaultStyle,
super.styles,
});
factory RichTextBuilderThemeExtensionImpl.dark({ThemeData? theme}) {
theme ??= ThemeData.dark();
return RichTextBuilderThemeExtensionImpl(
defaultStyle: theme.textTheme.bodyMedium?.copyWith(
height: 1.8,
),
styles: stylesFor(theme),
);
}
factory RichTextBuilderThemeExtensionImpl.light({ThemeData? theme}) {
theme ??= ThemeData.light();
return RichTextBuilderThemeExtensionImpl(
defaultStyle: theme.textTheme.bodyMedium?.copyWith(
height: 1.8,
),
styles: stylesFor(theme),
);
}
static Map<String, TextStyle> stylesFor(ThemeData theme) => {
'gradient-blue': GradientTextStyle.from(
theme.textTheme.bodyMedium?.copyWith(
fontSize: 20,
fontWeight: FontWeight.w600,
height: 1.8,
),
const MultiColor([
Color(0xFF3C97FB),
Color(0xFF436EF4),
]),
),
'gradient-red': GradientTextStyle.from(
theme.textTheme.bodyMedium?.copyWith(
fontSize: 20,
fontWeight: FontWeight.w600,
height: 1.8,
),
const MultiColor([
Color(0xFFF44464),
Color(0xFFF44464),
]),
),
'gradient-green': GradientTextStyle.from(
theme.textTheme.bodyMedium?.copyWith(
fontSize: 20,
fontWeight: FontWeight.w600,
height: 1.8,
),
const MultiColor([
Color(0xFF00D16C),
Color(0xFF00D16C),
]),
),
'blue': theme.textTheme.bodyMedium?.copyWith(
fontSize: 20,
fontWeight: FontWeight.w600,
color: const Color(0xFF3C97FB),
height: 1.8,
) ??
const TextStyle(
color: Color(0xFF3C97FB),
),
'red': theme.textTheme.bodyMedium?.copyWith(
fontSize: 20,
fontWeight: FontWeight.w600,
color: const Color(0xFFF44464),
height: 1.8,
) ??
const TextStyle(
color: Color(0xFFF44464),
),
'green': theme.textTheme.bodyMedium?.copyWith(
fontSize: 20,
fontWeight: FontWeight.w600,
color: const Color(0xFF00D16C),
height: 1.8,
) ??
const TextStyle(
color: Color(0xFF00D16C),
),
};
}

View File

@ -16,4 +16,7 @@
export 'button_theme_extensions/button_theme_extensions.dart';
export 'card_theme_extension_impl.dart';
export 'loader_theme_extension_impl.dart';
export 'rich_text_builder_theme_extension_impl.dart';
export 'text_input_theme_extension_impl.dart';
export 'top_bar_theme_extension_impl.dart';

View File

@ -0,0 +1,75 @@
// 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';
class TopBarThemeExtensionImpl extends TopBarThemeExtension {
const TopBarThemeExtensionImpl({
super.iconTheme,
super.backgroundColors,
super.selectedIndicatorColors,
super.selectedIndicatorSize,
super.dividerColor,
super.titleStyle,
super.subtitleStyle,
});
factory TopBarThemeExtensionImpl.light({ThemeData? theme}) {
theme ??= ThemeData.light();
return TopBarThemeExtensionImpl(
backgroundColors: const MultiColor.single(
Color.fromRGBO(246, 246, 246, 1),
),
dividerColor: const Color.fromRGBO(36, 38, 42, 0.1),
selectedIndicatorColors:
const MultiColor.single(Color.fromRGBO(36, 38, 42, 1)),
titleStyle: theme.textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(36, 38, 42, 1),
fontSize: 18,
),
subtitleStyle: theme.textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w400,
color: const Color.fromRGBO(36, 38, 42, 1),
fontSize: 18,
),
iconTheme: const IconThemeData(color: Color.fromRGBO(36, 38, 42, 1)),
);
}
factory TopBarThemeExtensionImpl.dark({ThemeData? theme}) {
theme ??= ThemeData.dark();
return TopBarThemeExtensionImpl(
backgroundColors: const MultiColor([
Color.fromRGBO(44, 50, 56, 1),
Color.fromRGBO(39, 47, 61, 1),
Color.fromRGBO(44, 50, 56, 1),
]),
dividerColor: const Color.fromRGBO(255, 255, 255, 0.1),
selectedIndicatorColors: const MultiColor.single(Colors.white),
titleStyle: theme.textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.bold,
fontSize: 18,
),
subtitleStyle: theme.textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w400,
fontSize: 18,
),
iconTheme: const IconThemeData(color: Colors.white),
);
}
}

View File

@ -1,20 +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 './loader_theme_extension.dart';
export './rich_text_builder_theme_extension.dart';
export './text_input_theme_extension.dart';
export 'top_bar_theme_extension.dart';

View File

@ -1,33 +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/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
abstract class TextInputThemeExtension
extends ThemeExtension<TextInputThemeExtension> {
const TextInputThemeExtension({
this.normalStyle,
this.focusedStyle,
this.errorStyle,
this.disableStyle,
});
final TextInputStyle? normalStyle;
final TextInputStyle? focusedStyle;
final TextInputStyle? errorStyle;
final TextInputStyle? disableStyle;
}

View File

@ -1,41 +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/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
abstract class TopBarThemeExtension
extends ThemeExtension<TopBarThemeExtension> {
const TopBarThemeExtension({
this.iconTheme,
this.backgroundColors,
this.secondaryColor,
this.titleStyle,
this.subTitleStyle,
this.selectedIndicatorHeight,
this.selectedIndicatorWidth,
});
final MultiColor? backgroundColors;
final IconThemeData? iconTheme;
final Color? secondaryColor;
final TextStyle? titleStyle;
final TextStyle? subTitleStyle;
final double? selectedIndicatorHeight;
final double? selectedIndicatorWidth;
}

View File

@ -20,7 +20,7 @@ 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 {
abstract class WyattComponentThemeData {
/// {@macro wyatt_component_theme_data}
static ComponentThemeData get wyattComponentThemeData => ComponentThemeData(
appBar: const TopAppBar(),

View File

@ -0,0 +1,73 @@
// 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';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
/// {@template wyatt_theme_extensions}
/// Wyatt UI Kit theme extensions
///
/// This class is used to provide the theme extensions for the Wyatt UI Kit.
/// {@endtemplate}
class WyattThemeExtensions extends ThemeExtensionProvider {
/// {@macro wyatt_theme_extensions}
const WyattThemeExtensions() : super();
/// Wyatt UI Kit, light theme extensions
static List<ThemeExtension<dynamic>> light({ThemeData? theme}) => [
// Cards
CardThemeExtensionImpl.light(theme: theme),
// Loader
LoaderThemeExtensionImpl.light(theme: theme),
// RichTextBuilder
RichTextBuilderThemeExtensionImpl.light(theme: theme),
// Buttons
FileSelectionButtonThemeExtensionImpl.light(theme: theme),
FlatButtonThemeExtensionImpl.light(theme: theme),
SimpleIconButtonThemeExtensionImpl.light(theme: theme),
SymbolButtonThemeExtensionImpl.light(theme: theme),
// TextInput
TextInputThemeExtensionImpl.light(theme: theme),
// TopBar
TopBarThemeExtensionImpl.light(theme: theme),
];
/// Wyatt UI Kit, dark theme extensions
static List<ThemeExtension<dynamic>> dark({ThemeData? theme}) => [
// Cards
CardThemeExtensionImpl.dark(theme: theme),
// Loader
LoaderThemeExtensionImpl.dark(theme: theme),
// RichTextBuilder
RichTextBuilderThemeExtensionImpl.dark(theme: theme),
// Buttons
FileSelectionButtonThemeExtensionImpl.dark(theme: theme),
FlatButtonThemeExtensionImpl.dark(theme: theme),
SimpleIconButtonThemeExtensionImpl.dark(theme: theme),
SymbolButtonThemeExtensionImpl.dark(theme: theme),
// TextInput
TextInputThemeExtensionImpl.dark(theme: theme),
// TopBar
TopBarThemeExtensionImpl.dark(theme: theme),
];
@override
List<ThemeExtension<dynamic>> getThemeExtensionsFor(ThemeData theme) =>
theme.brightness == Brightness.light
? light(theme: theme)
: dark(theme: theme);
}

View File

@ -17,5 +17,5 @@
export 'components/components.dart';
export 'core/core.dart';
export 'data/data.dart';
export 'domain/domain.dart';
export 'features/wyatt_component_theme_data.dart';
export 'features/wyatt_theme_extensions.dart';