Skip to content

Commit

Permalink
optimize theme api
Browse files Browse the repository at this point in the history
  • Loading branch information
aprosail committed Jun 30, 2024
2 parents d5fb0a9 + f10f2a6 commit 6798dfb
Show file tree
Hide file tree
Showing 14 changed files with 185 additions and 22 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.4.1

- Rename `ThemeMixin` (API change).
- Example code for theme usages.
- Review scripts for all child repos.

## 0.4.0

- Theme template and theme handler.
Expand Down
2 changes: 1 addition & 1 deletion example/after/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ dependencies:

dev_dependencies:
flutter_test: {sdk: flutter}
lintall: ^0.1.0
lintall: ^0.1.1
2 changes: 1 addition & 1 deletion example/before/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ dependencies:

dev_dependencies:
flutter_test: {sdk: flutter}
lintall: ^0.1.0
lintall: ^0.1.1
30 changes: 30 additions & 0 deletions example/common/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "761747bfc538b5af34aa0d3fac380f1bc331ec49"
channel: "stable"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
- platform: web
create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
1 change: 1 addition & 0 deletions example/common/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include: ../../analysis_options.yaml
49 changes: 49 additions & 0 deletions example/common/lib/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'package:color_chart/color_chart.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:modifier/modifier.dart';

void main() {
runApp(const App());
}

class App extends StatelessWidget {
const App({super.key});

@override
Widget build(BuildContext context) {
return builder((context) {
final platformBrightness = MediaQuery.of(context).platformBrightness;
final brightness = context.findAndTrust<Brightness>();
final theme = context.findAndTrust<Theme>();
return [
'Platform brightness: ${platformBrightness.name}'.asText,
'Theme brightness: ${brightness.name}'.asText,
'Foreground: ${theme.foreground.hex}'.asText,
'Background: ${theme.background.hex}'.asText,
].asColumn;
})
.center
.theme(light: const Theme.light(), dark: const Theme.dark())
.ensureDirection(context)
.ensureMedia(context);
}
}

class Theme with ThemeMixin {
const Theme.light({
this.background = MonoColors.snow,
this.foreground = MonoColors.ink,
});

const Theme.dark({
this.background = MonoColors.night,
this.foreground = MonoColors.lunar,
});

@override
final Color background;

@override
final Color foreground;
}
14 changes: 14 additions & 0 deletions example/common/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: common
description: Example for theme and locale using the modifier package.
publish_to: "none"
version: 0.0.0 # The version code will always be zero.
environment: {sdk: ">=3.4.3 <4.0.0"}

dependencies:
color_chart: ^0.2.0
flutter: {sdk: flutter}
modifier: {path: ../../}

dev_dependencies:
flutter_test: {sdk: flutter}
lintall: ^0.1.1
19 changes: 19 additions & 0 deletions example/common/web/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!doctype html>
<html>
<head>
<base href="$FLUTTER_BASE_HREF" />
<meta charset="UTF-8" />
<meta content="IE=Edge" http-equiv="X-UA-Compatible" />
<meta name="description" content="A new Flutter project." />

<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="before" />

<title>common</title>
<link rel="manifest" href="manifest.json" />
</head>
<body>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>
12 changes: 12 additions & 0 deletions example/common/web/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "common",
"short_name": "common",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "Example for theme and locale customizations.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": []
}
42 changes: 32 additions & 10 deletions lib/src/theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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<T extends Theme>({
Widget theme<T extends ThemeMixin>({
required T light,
T? dark,
ThemeMode mode = ThemeMode.system,
Expand All @@ -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<T extends Theme> extends StatefulWidget {
class ThemeHandler<T extends ThemeMixin> extends StatefulWidget {
const ThemeHandler({
super.key,
required this.light,
Expand All @@ -62,7 +84,7 @@ class ThemeHandler<T extends Theme> extends StatefulWidget {
State<ThemeHandler<T>> createState() => _ThemeHandlerState<T>();
}

class _ThemeHandlerState<T extends Theme> extends State<ThemeHandler<T>> {
class _ThemeHandlerState<T extends ThemeMixin> extends State<ThemeHandler<T>> {
late T _light = widget.light;
late T _dark = widget.dark;
late ThemeMode _mode = widget.mode;
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: modifier
description: Syntax sugar optimizations to avoid nesting hell in Flutter.
version: 0.4.0
version: 0.4.1
homepage: https://github.com/treeinfra/modifier
repository: https://github.com/treeinfra/modifier
environment: {sdk: ">=3.4.3 <4.0.0", flutter: ">=3.22.2"}
Expand Down
22 changes: 16 additions & 6 deletions review.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
echo_pos() { echo && echo "\033[34m[$1]\033[0m" && echo; }

echo_pos "root"
flutter pub get || exit 1
dart format --output=none --set-exit-if-changed . || exit 1
flutter analyze --fatal-infos || exit 1
flutter test || exit 1

# Build the examples to validate.
cd example/before
flutter build web || exit 1
cd ../after
flutter build web || exit 1
cd ../..
process_example() {
name=$1
echo_pos "example/$name"
cd example/$name || exit 1
flutter pub get || exit 1
flutter build web || exit 1
cd ../..
}

process_example before || exit 1
process_example after || exit 1
process_example common || exit 1

echo_pos "root"
flutter pub publish --dry-run || exit 1
4 changes: 2 additions & 2 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
aim=$1

# Ensure input parameter is valid (only two examples: before and after).
if [ "$aim" != "before" ] && [ "$aim" != "after" ]; then
echo "Usage: $0 <before|after>"
if [ "$aim" != "before" ] && [ "$aim" != "after" ] && [ "$aim" != "common" ]; then
echo "Usage: $0 <before|after|common>"
exit 1
fi

Expand Down
2 changes: 1 addition & 1 deletion test/theme_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 6798dfb

Please sign in to comment.