Skip to content

Conversation

@guidezpl
Copy link
Member

@guidezpl guidezpl commented Feb 8, 2022

This change enables adding anything to ThemeData, with a concept called "Theme extensions".

Rather than extending (in the Dart sense) ThemeData and re-implement its copyWith, lerp, and other methods, end-developers will be able to specify ThemeData.extensions. Additionally, package developers will be able to provide ThemeExtensions.

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:
Kapture 2022-02-08 at 14 53 40

Fixes #31522

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard flutter-dashboard bot added d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos documentation f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. c: contributor-productivity Team-specific productivity, code health, technical debt. labels Feb 8, 2022
Copy link
Contributor

@HansMuller HansMuller left a 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,
Copy link
Contributor

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

Copy link

@jeffkwoh jeffkwoh left a 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;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this!

@HansMuller
Copy link
Contributor

CC @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]

@matasb-google
Copy link
Contributor

matasb-google commented Feb 14, 2022 via email

Copy link
Contributor

@darrenaustin darrenaustin left a 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.

@guidezpl guidezpl changed the title ThemeData extensions Introduce Theme extensions Mar 1, 2022
@guidezpl
Copy link
Member Author

guidezpl commented Mar 1, 2022

I've made suggested improvements, including supporting multiple extensions and adding a convenience getter extension<>.

Still TODO, tests

Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@guidezpl guidezpl marked this pull request as ready for review March 16, 2022 17:54
@guidezpl guidezpl requested a review from HansMuller March 18, 2022 10:50
Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@raulmabe
Copy link

Which flutter release will be introducing this feature? Is it already known?

@guidezpl
Copy link
Member Author

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, 8c1c2f6 is currently available on master, and will be available in the next beta release, 2.13.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c: contributor-productivity Team-specific productivity, code health, technical debt. d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Extend ThemeData with app-specific palettes

6 participants