mirror of
https://github.com/flutter/flutter
synced 2024-09-17 23:31:55 +00:00
Fix InputDecorator default hint text style on M3 (#148944)
## Description This PRs makes the `InputDecoration.hintText` style compliant with the M3 spec. The hint style is not clearly specified in https://m3.material.io/components/text-fields/specs, but it is in the M3 Figma kit. ('hint' terminology came from the Material1 specification, since M2 the terminology is 'Placeholder'). See this Figma screenshot taken while focusing on the 'Placeholder' text (which corresponds to hint). ![image](https://github.com/flutter/flutter/assets/840911/58d3d5c9-0984-497a-9d47-4724dcd7b2b3) It seems that the intention is that the 'Placeholder' colors should be the same as the 'supporting text' ones, that is why is reused 'supporting text' tokens. ## Related Issue Fixes https://github.com/flutter/flutter/issues/148787. ## Tests Updates several tests.
This commit is contained in:
parent
2b700dda38
commit
b201fbdee5
|
@ -34,9 +34,9 @@ class _${blockName}DefaultsM3 extends InputDecorationTheme {
|
|||
@override
|
||||
TextStyle? get hintStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return TextStyle(color: Theme.of(context).disabledColor);
|
||||
return TextStyle(color: ${componentColor('md.comp.filled-text-field.disabled.supporting-text')});
|
||||
}
|
||||
return TextStyle(color: Theme.of(context).hintColor);
|
||||
return TextStyle(color: ${componentColor('md.comp.filled-text-field.supporting-text')});
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
|
@ -1754,8 +1754,10 @@ class InputDecorator extends StatefulWidget {
|
|||
/// The style on which to base the label, hint, counter, and error styles
|
||||
/// if the [decoration] does not provide explicit styles.
|
||||
///
|
||||
/// If null, [baseStyle] defaults to the `titleMedium` style from the
|
||||
/// current [Theme], see [ThemeData.textTheme].
|
||||
/// If null, [TextTheme.bodyLarge] will be used.
|
||||
///
|
||||
/// If null and [ThemeData.useMaterial3] is false, [TextTheme.titleMedium] will
|
||||
/// be used.
|
||||
///
|
||||
/// The [TextStyle.textBaseline] of the [baseStyle] is used to determine
|
||||
/// the baseline used for text alignment.
|
||||
|
@ -2062,7 +2064,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
|||
final TextStyle? style = MaterialStateProperty.resolveAs(decoration.hintStyle, materialState)
|
||||
?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.hintStyle, materialState);
|
||||
|
||||
return themeData.textTheme.titleMedium!
|
||||
return (themeData.useMaterial3 ? themeData.textTheme.bodyLarge! : themeData.textTheme.titleMedium!)
|
||||
.merge(widget.baseStyle)
|
||||
.merge(defaultStyle)
|
||||
.merge(style);
|
||||
|
@ -4672,9 +4674,9 @@ class _InputDecoratorDefaultsM3 extends InputDecorationTheme {
|
|||
@override
|
||||
TextStyle? get hintStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return TextStyle(color: Theme.of(context).disabledColor);
|
||||
return TextStyle(color: _colors.onSurface.withOpacity(0.38));
|
||||
}
|
||||
return TextStyle(color: Theme.of(context).hintColor);
|
||||
return TextStyle(color: _colors.onSurfaceVariant);
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
|
@ -2835,10 +2835,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.
|
||||
final Color expectedColor = theme.hintColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurfaceVariant;
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -2901,10 +2899,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.withOpacity(0.38).
|
||||
final Color expectedColor = theme.disabledColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurface.withOpacity(0.38);
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -2967,10 +2963,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.
|
||||
final Color expectedColor = theme.hintColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurfaceVariant;
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -3033,10 +3027,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.
|
||||
final Color expectedColor = theme.hintColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurfaceVariant;
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -3099,10 +3091,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.
|
||||
final Color expectedColor = theme.hintColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurfaceVariant;
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -3309,10 +3299,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.
|
||||
final Color expectedColor = theme.hintColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurfaceVariant;
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -3423,10 +3411,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.
|
||||
final Color expectedColor = theme.hintColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurfaceVariant;
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -3489,10 +3475,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.withOpacity(0.38).
|
||||
final Color expectedColor = theme.disabledColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurface.withOpacity(0.38);
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -3555,10 +3539,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.
|
||||
final Color expectedColor = theme.hintColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurfaceVariant;
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -3621,10 +3603,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.
|
||||
final Color expectedColor = theme.hintColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurfaceVariant;
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -3687,10 +3667,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.
|
||||
final Color expectedColor = theme.hintColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurfaceVariant;
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
@ -3895,10 +3873,8 @@ void main() {
|
|||
expect(getHintOpacity(tester), 1.0);
|
||||
|
||||
final ThemeData theme = Theme.of(tester.element(findDecorator()));
|
||||
// TODO(bleroux): from M3 specification, it should be theme.colorScheme.onSurface.
|
||||
final Color expectedColor = theme.hintColor;
|
||||
// TODO(bleroux): from M3 specification, it should be textTheme.bodyLarge.
|
||||
final TextStyle expectedStyle = theme.textTheme.titleMedium!.copyWith(color: expectedColor);
|
||||
final Color expectedColor = theme.colorScheme.onSurfaceVariant;
|
||||
final TextStyle expectedStyle = theme.textTheme.bodyLarge!.copyWith(color: expectedColor);
|
||||
expect(getHintStyle(tester), expectedStyle);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5409,11 +5409,38 @@ void main() {
|
|||
});
|
||||
|
||||
testWidgets('TextField with default hintStyle', (WidgetTester tester) async {
|
||||
final TextStyle style = TextStyle(
|
||||
color: Colors.pink[500],
|
||||
fontSize: 10.0,
|
||||
);
|
||||
final ThemeData themeData = ThemeData();
|
||||
|
||||
await tester.pumpWidget(
|
||||
overlay(
|
||||
child: Theme(
|
||||
data: themeData,
|
||||
child: TextField(
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Placeholder',
|
||||
),
|
||||
style: style,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Text hintText = tester.widget(find.text('Placeholder'));
|
||||
expect(hintText.style!.color, themeData.colorScheme.onSurfaceVariant);
|
||||
expect(hintText.style!.fontSize, style.fontSize);
|
||||
});
|
||||
|
||||
testWidgets('Material2 - TextField with default hintStyle', (WidgetTester tester) async {
|
||||
final TextStyle style = TextStyle(
|
||||
color: Colors.pink[500],
|
||||
fontSize: 10.0,
|
||||
);
|
||||
final ThemeData themeData = ThemeData(
|
||||
useMaterial3: false,
|
||||
hintColor: Colors.blue[500],
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue