diff --git a/example/common/lib/main.dart b/example/common/lib/main.dart index 83e72e9..8eb963b 100644 --- a/example/common/lib/main.dart +++ b/example/common/lib/main.dart @@ -15,7 +15,7 @@ class App extends StatelessWidget { return builder((context) { final platformBrightness = MediaQuery.of(context).platformBrightness; final brightness = context.findAndTrust(); - final theme = context.findAndTrust(); + final theme = context.findAndTrust(); return [ 'Platform brightness: ${platformBrightness.name}'.asText, 'Theme brightness: ${brightness.name}'.asText, @@ -24,19 +24,19 @@ class App extends StatelessWidget { ].asColumn; }) .center - .theme(light: const ThemeData.light(), dark: const ThemeData.dark()) + .theme(light: const Theme.light(), dark: const Theme.dark()) .ensureDirection(context) .ensureMedia(context); } } -class ThemeData with Theme { - const ThemeData.light({ +class Theme with ThemeMixin { + const Theme.light({ this.background = MonoColors.snow, this.foreground = MonoColors.ink, }); - const ThemeData.dark({ + const Theme.dark({ this.background = MonoColors.night, this.foreground = MonoColors.lunar, }); diff --git a/lib/src/theme.dart b/lib/src/theme.dart index 1c61fb6..c02d0fa 100644 --- a/lib/src/theme.dart +++ b/lib/src/theme.dart @@ -4,13 +4,35 @@ import 'package:flutter/widgets.dart'; import 'inherit.dart'; import 'wrap.dart'; -mixin Theme { - /// Default background of the theme. - /// It's recommended to use a final parameter rather than a getter. +/// All handled theme data should have basic properties defined in this mixin. +/// +/// The [foreground] and [background] are elementary components of a theme, +/// without such parameters, the theme will be useless. +/// So that they are required. +/// +/// It's recommended to use a final parameter rather than a getter. +/// It is defined as a getter here because of the limit of Dart syntax. +/// For example: +/// +/// ```dart +/// class Theme with ThemeMixin { +/// const Theme({ +/// required this.background, +/// required this.foreground, +/// }) +/// +/// @override +/// final Color background; +/// +/// @override +/// final Color foreground; +/// } +/// ``` +mixin ThemeMixin { + /// Default background of the theme, see [ThemeMixin]. Color get background; - /// Default foreground, text and icon color, of the theme. - /// It's recommended to use a final parameter rather than a getter. + /// Default foreground, text and icon color, of the theme, see [ThemeMixin]. Color get foreground; } @@ -27,7 +49,7 @@ extension WrapTheme on Widget { /// [light] theme directly when there's no [dark] theme, /// because even if the [dark] theme is not provided, /// it might be modifier by its descendants. - Widget theme({ + Widget theme({ required T light, T? dark, ThemeMode mode = ThemeMode.system, @@ -40,11 +62,11 @@ extension WrapTheme on Widget { ); } -/// Handle a [Theme] and the [ThemeMode], +/// Handle a [ThemeMixin] and the [ThemeMode], /// and it will also provide the [Brightness] of current theme. -/// And you can also modify current [Theme] and [ThemeMode] from +/// And you can also modify current [ThemeMixin] and [ThemeMode] from /// its descendants in the widget tree via the context. -class ThemeHandler extends StatefulWidget { +class ThemeHandler extends StatefulWidget { const ThemeHandler({ super.key, required this.light, @@ -62,7 +84,7 @@ class ThemeHandler extends StatefulWidget { State> createState() => _ThemeHandlerState(); } -class _ThemeHandlerState extends State> { +class _ThemeHandlerState extends State> { late T _light = widget.light; late T _dark = widget.dark; late ThemeMode _mode = widget.mode; diff --git a/test/theme_test.dart b/test/theme_test.dart index fd4f00b..5d1f232 100644 --- a/test/theme_test.dart +++ b/test/theme_test.dart @@ -108,7 +108,7 @@ void main() { }); } -class CustomizedTheme with Theme { +class CustomizedTheme with ThemeMixin { const CustomizedTheme.light({ this.background = MonoColors.snow, this.foreground = MonoColors.coal,