Repository: flutter
Issue: Automatically Style `Text`, `Icon`, etc according to their parent `Material`
Labels: c: new feature,framework,f: material design,c: proposal,P3,team-design,triaged-design

## Use case

The color scheme and material system provides a pretty good guideline for how to properly color-style an app. You define a series of colors for different materials (primary, secondary, background, surface, etc) and then a series of colors for elements (text, icons, etc) that appear on top of those respective materials.

However, the connection between the material and the color of the element on top of it is entirely up to the developer to manually set. For example, if I have a Material widget with `color: Theme.of(context).colorScheme.surface` and then I put a text widget inside of it, I have to manually set the text style to use `Theme.of(context).colorScheme.onSurface`.

This is extremely verbose:
```dart
return Material(
  color: Theme.of(context).colorScheme.surface,
  child: Text(
    'I am become text, communicator of ideas',
    textStyle: TextStlye(
      color: Theme.of(context).colorScheme.onSurface,
    ),
  ),
);
```
It's also tedious, especially so when doing large refactors to layout and color. It's very easy to miss a spot where a text style didn't get properly updated and is no longer using the correct style corresponding to the material its being drawn on top of.

Alternatively, I could use the `Material.textStyle` argument:
```dart
return Material(
  color: Theme.of(context).colorScheme.surface,
  style: TextStlye(
    color: Theme.of(context).colorScheme.onSurface,
  ),
  child: Text(
    'I am become text, communicator of ideas',
  ),
);
```

This is MUCH less tedious as now I only have to specify the color once for all text widgets and when I redesign my UI heavily, the text automatically updates its color to appropriately reflect the color it's being drawn on top of. However, this is still pretty unsatisfactory because:

1. It only accounts for text, the icon style does not get set appropriately
2. I still have to manually create the connection between the background color and the foreground element color which is still tedious

TLDR: The Material system provides a good framework for coloring an app, but then it expects the developer to manually enforce the framework (eg what colors are drawn on top of what surfaces). Flutter's Material system should provide the option (if not the default behavior) to automatically set the colors of foreground elements according to the color of their nearest enclosing Material parent.

## Proposal

An update to the Material system that provides widgets that automatically set the colors of their child widgets (via `DefaultTextStyle`, `IconTheme` and any other relevant inherited style widgets).

Here are a few (of many) ways this could be achieved:

1. Have Material check if its `color` attribute matches a color from the color scheme and then wrap it's children with theme widgets applying the corresponding `on*` color
Pros: Smallest possible change, provides good behavior by default
Cons: Will cause massive likely unwanted color changes to existing apps, relies on color matching which is sloppy: a developer may happen to use the `Surface` color on a UI element that doesn't conceptually act as a surface (`color: Colors.black` where the surface color coincidentally also happens to be `Colors.black`)
2. Add an enum argument to `Material` for `materialType`. The enum has values corresponding to the core `colorScheme` colors. If `materialType` is non-null, `Material` will automatically set it's color to the corresponding value and wrap it's children in inherited styles applying the corresponding `on` color.
Pros: entirely opt-in so it will not change existing apps
Cons: default (existing) behavior remains bad, new argument is slightly redundant to the existing `color` and `style` arguments
3. The above, but use the existing outdated and useless `Material.type` attribute.
4. Add a series of thin-wrapper classes that extend Material. `Surface` for surface colored materials, `Background` for background colored materials. These wrappers apply the logic listed above.
Pros: really clean and intuitive API surface
Cons: default (existing) behavior remains bad,  not very discoverable for people currently using `Material`

Limitations:
1. This system cannot always properly style child widgets in situations like `Stack` where the child widget can't reliably tell when parent widget it will be drawn on top of. For these situations, the developer may have to fall back on the existing system of manually setting the style of child widgets.
2. Right now `IconTheme` uses it's own separate coloring (eg the default `onSurface` is black but the default `iconColor` is grey and entirely unrelated to `colorScheme`). As a precursor to this proposal, `colorScheme` should probably have a set of `secondaryOn____` attributes for `IconTheme` to pull from.
3. This proposal does not automatically recolor non-default text styles. This would be more complicated as some text theme styles (like headlines) will have colors that differ from the color scheme. This proposal could be extended to automatically color the entire text theme according to the color scheme if all text theme styles were, by default, defined in terms of the color scheme (see `secondaryOn<MaterialType>` proposal above). And/or the proposed new system could have a `recolorTextTheme` optional bool flag so the developer could opt-in to having the system override all of the their text theme's colors. 
An entirely different approach to solving this problem would be to define the `textTheme` styles directly in relation to the color scheme materials. Instead of `bodyText2`, we have `onSurface` and instead of `headline1` we have `onPrimary`, and so on. This way, the proposed new material system would ensure text below it gets properly styled simply by setting the default text theme to the corresponding `on<MaterialType>` text style.  This is probably a good change regardless as it unifies `TextTheme` and `ColorScheme` into one coherent system. It could be done (relatively) painlessly by starting with a new class implementing `TextTheme` that defines it's styles in terms of `on<MaterialType>` and then has a series of getters to return `bodyText*` etc in terms of `on<MaterialType>`.

## Why not a package?

This could be made as a package (and in fact I use a really janky version of this internally in my own projects). However, the existing material and color scheme systems are really begging to have this feature and, in its absence, developers are getting a degraded experience. Flutter's core value proposition (or at least as I see it) is an elegant developer experience that makes it as easy as possible for developers of all skill levels to build a professional quality app. Flutter generally does a spectacular job at this (seriously, Flutter is amazing I'm a huge evangelist), but color styling is one place where it's falling a bit short. A third party package would not ensure that the beginner opening up Flutter gets a good experience.

Additionally, making this a core part of Flutter as opposed to just a third party package would allow all material widgets such as `Scaffold`, `FloatingActionButton` etc to integrate with this system rather than all of them ad-hoc setting their child stylings as they do now. For example, as is, if I want a `FloatingActionButton` that uses the secondary color instead of the primary color, the `FloatingActionButton` would improperly style it's child icon/text to use `colorScheme.onPrimary`. If `FloatingActionButton` integrated with this proposal it'd automatically correctly style it's children's color relative to its own.

If I find the time, I will rebuild my janky internal version of this into something worth sharing with the public and publish it as a package, but whether or not I do so I think it is well worth building this system into Flutter.