-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Introduce Theme extensions #98033
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce Theme extensions #98033
Conversation
HansMuller
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great. All of the piddling comments are just to prove that I looked at it carefully.
| red: Color(0xFFEF9A9A), | ||
| ), | ||
| ), | ||
| themeMode: isLightTheme ? ThemeMode.light : ThemeMode.dark, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad to see this in an example
jeffkwoh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM for our usecase! Have also pinged matas for a closer look (-: He should have more context on how Theme is used--being an OWNER of our codebase
| /// | ||
| /// ** See code in examples/api/lib/material/theme/theme_extension.1.dart ** | ||
| /// {@end-tool} | ||
| final ThemeExtension? themeExtension; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this!
|
Flutter packages may want to include their own theme extensions so it may be useful to support that. If ThemeData.themeExtensions (maybe just "extensions"?) was a ThemeExtension<T> {
Object get id => T;
...
}and the type parameter was typically the type of the subclass, so: ThemeExtension<T> {
Object get id => T;
...
}Then extensions: [AppExtensions(), Package1Extensions(), Package2Extensions()]And lookup would be by type, like ThemeData.of(context).extensions[AppExtensions] |
|
This suggestion looks great!
Note maybe to follow flutter patterns in code base would be possible to do
something like:
ThemeExtension.of<AppExtension>(context);
Where it is implemented as
class ThemeExtension {
static T? of<T>(context) {
return ThemeData.of(context).extension<T>();
}
}
class ThemeData {
Map<Object, ThemeExtension> extensions;
T? extension<T>() => _extensions[T];
// I guess this is the most complicated/hacky part if multiple extensions
are allowed.
// E.g. behaviour needs to be defined, what happens if a has extension,
and b does not and other way round.
Map<Object, ThemeExtension> _lerpThemeExtensions(ThemeData a, ThemeData
b, double t) {
a.extensions.map((key, value) => b.extensions[key] != null ?
value.lerp(b.extensions[key], t) ?? value);
}
}
…On Fri, Feb 11, 2022 at 3:08 AM Hans Muller ***@***.***> wrote:
CC @darrenaustin <https://github.com/darrenaustin>
Flutter packages may want to include their own theme extensions so it may
be useful to support that.
If ThemeData.themeExtensions (maybe just "extensions"?) was a Map<Object,
ThemeExtension> then initialization would be a little more complicated,
but we could support multiple extensions. If ThemeExtension was:
ThemeExtension<T> {
Object get id => T;
...
}
and the type parameter was typically the type of the subclass, so:
ThemeExtension<T> {
Object get id => T;
...
}
Then ThemeData.extensions could be a list, e.g.
extensions: [AppExtensions(), Package1Extensions(), Package2Extensions()]
And lookup would be by type, like
ThemeData.of(context).extensions[AppExtensions]
—
Reply to this email directly, view it on GitHub
<#98033 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ATPCA7J5RUXTNVMVQHLRHZTU2QEKJANCNFSM5N2SR2NA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you commented.Message ID:
***@***.***>
|
darrenaustin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all looks great to me. However I share the same concern as @HansMuller about needing to support multiple theme extensions instead of just one. We could have packages that provide extensions in addition to application specific extensions and it would be nice if we had a way for them all live together in a single ThemeData.
|
I've made suggested improvements, including supporting multiple extensions and adding a convenience getter Still TODO, tests |
HansMuller
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
HansMuller
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
Which flutter release will be introducing this feature? Is it already known? |
|
https://github.com/flutter/flutter/wiki/Flutter-build-release-channels details the release cadence, and https://github.com/flutter/flutter/wiki/Where%27s-my-Commit%3F#finding-the-versions-that-contain-framework-commit-x details finding the release for a specific PR's merge commit. For this PR, |
This change enables adding anything to
ThemeData, with a concept called "Theme extensions".Rather than extending (in the Dart sense)
ThemeDataand re-implement itscopyWith,lerp, and other methods, end-developers will be able to specifyThemeData.extensions. Additionally, package developers will be able to provideThemeExtensions.The design doc can be found at flutter.dev/go/theme-extensions. This solution balances a few needs, namely, limited boilerplate, type safety, ease of use, lerp-ability, and ability to specify multiple extensions.
See the following sample for usage:

Fixes #31522
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.