TextField should support disabled input text style (#119216)
Co-authored-by: Renzo Olivares <roliv@google.com>
This commit is contained in:
parent
bcdab118ba
commit
358d79cb0d
@ -9,6 +9,13 @@ class TextFieldTemplate extends TokenTemplate {
|
||||
|
||||
@override
|
||||
String generate() => '''
|
||||
TextStyle? _m3StateInputStyle(BuildContext context) => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return TextStyle(color: ${textStyle("md.comp.filled-text-field.label-text")}!.color?.withOpacity(0.38));
|
||||
}
|
||||
return TextStyle(color: ${textStyle("md.comp.filled-text-field.label-text")}!.color);
|
||||
});
|
||||
|
||||
TextStyle _m3InputStyle(BuildContext context) => ${textStyle("md.comp.filled-text-field.label-text")}!;
|
||||
|
||||
TextStyle _m3CounterErrorStyle(BuildContext context) =>
|
||||
|
@ -11,6 +11,7 @@ import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'adaptive_text_selection_toolbar.dart';
|
||||
import 'color_scheme.dart';
|
||||
import 'colors.dart';
|
||||
import 'debug.dart';
|
||||
import 'desktop_text_selection.dart';
|
||||
@ -1191,6 +1192,22 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
|
||||
}
|
||||
// AutofillClient implementation end.
|
||||
|
||||
Set<MaterialState> get _materialState {
|
||||
return <MaterialState>{
|
||||
if (!_isEnabled) MaterialState.disabled,
|
||||
if (_isHovering) MaterialState.hovered,
|
||||
if (_effectiveFocusNode.hasFocus) MaterialState.focused,
|
||||
if (_hasError) MaterialState.error,
|
||||
};
|
||||
}
|
||||
|
||||
TextStyle _getInputStyleForState(TextStyle style) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
final TextStyle stateStyle = MaterialStateProperty.resolveAs(theme.useMaterial3 ? _m3StateInputStyle(context)! : _m2StateInputStyle(context)!, _materialState);
|
||||
final TextStyle providedStyle = MaterialStateProperty.resolveAs(style, _materialState);
|
||||
return providedStyle.merge(stateStyle);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
assert(debugCheckHasMaterial(context));
|
||||
@ -1204,7 +1221,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
|
||||
|
||||
final ThemeData theme = Theme.of(context);
|
||||
final DefaultSelectionStyle selectionStyle = DefaultSelectionStyle.of(context);
|
||||
final TextStyle style = (theme.useMaterial3 ? _m3InputStyle(context) : theme.textTheme.titleMedium!).merge(widget.style);
|
||||
final TextStyle style = _getInputStyleForState(theme.useMaterial3 ? _m3InputStyle(context) : theme.textTheme.titleMedium!).merge(widget.style);
|
||||
final Brightness keyboardAppearance = widget.keyboardAppearance ?? theme.brightness;
|
||||
final TextEditingController controller = _effectiveController;
|
||||
final FocusNode focusNode = _effectiveFocusNode;
|
||||
@ -1402,12 +1419,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
|
||||
}
|
||||
final MouseCursor effectiveMouseCursor = MaterialStateProperty.resolveAs<MouseCursor>(
|
||||
widget.mouseCursor ?? MaterialStateMouseCursor.textable,
|
||||
<MaterialState>{
|
||||
if (!_isEnabled) MaterialState.disabled,
|
||||
if (_isHovering) MaterialState.hovered,
|
||||
if (focusNode.hasFocus) MaterialState.focused,
|
||||
if (_hasError) MaterialState.error,
|
||||
},
|
||||
_materialState,
|
||||
);
|
||||
|
||||
final int? semanticsMaxValueLength;
|
||||
@ -1453,6 +1465,14 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
|
||||
}
|
||||
}
|
||||
|
||||
TextStyle? _m2StateInputStyle(BuildContext context) => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return TextStyle(color: theme.disabledColor);
|
||||
}
|
||||
return TextStyle(color: theme.textTheme.titleMedium?.color);
|
||||
});
|
||||
|
||||
TextStyle _m2CounterErrorStyle(BuildContext context) =>
|
||||
Theme.of(context).textTheme.bodySmall!.copyWith(color: Theme.of(context).colorScheme.error);
|
||||
|
||||
@ -1465,6 +1485,13 @@ TextStyle _m2CounterErrorStyle(BuildContext context) =>
|
||||
|
||||
// Token database version: v0_162
|
||||
|
||||
TextStyle? _m3StateInputStyle(BuildContext context) => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return TextStyle(color: Theme.of(context).textTheme.bodyLarge!.color?.withOpacity(0.38));
|
||||
}
|
||||
return TextStyle(color: Theme.of(context).textTheme.bodyLarge!.color);
|
||||
});
|
||||
|
||||
TextStyle _m3InputStyle(BuildContext context) => Theme.of(context).textTheme.bodyLarge!;
|
||||
|
||||
TextStyle _m3CounterErrorStyle(BuildContext context) =>
|
||||
|
@ -6071,6 +6071,51 @@ void main() {
|
||||
expect(errorWidget.style!.color, equals(Colors.transparent));
|
||||
});
|
||||
|
||||
testWidgets('Disabled text field has default M2 disabled text style for the input text', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
enabled: false,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final EditableText editableText = tester.widget(find.byType(EditableText));
|
||||
expect(editableText.style.color, Colors.black38); // Colors.black38 is the default disabled color for ThemeData.light().
|
||||
});
|
||||
|
||||
testWidgets('Disabled text field has default M3 disabled text style for the input text', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
);
|
||||
|
||||
final ThemeData theme = ThemeData.light(useMaterial3: true);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
enabled: false,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final EditableText editableText = tester.widget(find.byType(EditableText));
|
||||
expect(editableText.style.color, theme.textTheme.bodyLarge!.color!.withOpacity(0.38));
|
||||
});
|
||||
|
||||
testWidgets('currentValueLength/maxValueLength are in the tree', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
final TextEditingController controller = TextEditingController();
|
||||
@ -8355,7 +8400,11 @@ void main() {
|
||||
// Empty TextStyle is overridden by theme
|
||||
await tester.pumpWidget(buildFrame(const TextStyle()));
|
||||
EditableText editableText = tester.widget(find.byType(EditableText));
|
||||
|
||||
// According to material 3 spec, the input text should be the color of onSurface.
|
||||
// https://github.com/flutter/flutter/issues/107686 is tracking this issue.
|
||||
expect(editableText.style.color, themeData.textTheme.bodyLarge!.color);
|
||||
|
||||
expect(editableText.style.background, themeData.textTheme.bodyLarge!.background);
|
||||
expect(editableText.style.shadows, themeData.textTheme.bodyLarge!.shadows);
|
||||
expect(editableText.style.decoration, themeData.textTheme.bodyLarge!.decoration);
|
||||
|
Loading…
x
Reference in New Issue
Block a user