Skip to content

Commit c5e8757

Browse files
authored
Add M3 support for iconbuttons in error state in TextFields (#119925)
* add m3 iconbutton override * changes * spring cleaning * whitespace fix * sneaky whitespaces
1 parent e0b2138 commit c5e8757

File tree

2 files changed

+72
-20
lines changed

2 files changed

+72
-20
lines changed

packages/flutter/lib/src/material/input_decorator.dart

+38-20
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import 'package:flutter/widgets.dart';
1212
import 'color_scheme.dart';
1313
import 'colors.dart';
1414
import 'constants.dart';
15+
import 'icon_button.dart';
16+
import 'icon_button_theme.dart';
1517
import 'input_border.dart';
1618
import 'material.dart';
1719
import 'material_state.dart';
@@ -2307,19 +2309,27 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
23072309
cursor: SystemMouseCursors.basic,
23082310
child: ConstrainedBox(
23092311
constraints: decoration.prefixIconConstraints ??
2310-
themeData.visualDensity.effectiveConstraints(
2311-
const BoxConstraints(
2312-
minWidth: kMinInteractiveDimension,
2313-
minHeight: kMinInteractiveDimension,
2314-
),
2312+
themeData.visualDensity.effectiveConstraints(
2313+
const BoxConstraints(
2314+
minWidth: kMinInteractiveDimension,
2315+
minHeight: kMinInteractiveDimension,
23152316
),
2317+
),
23162318
child: IconTheme.merge(
23172319
data: IconThemeData(
23182320
color: _getPrefixIconColor(themeData, defaults),
23192321
size: iconSize,
23202322
),
2321-
child: Semantics(
2322-
child: decoration.prefixIcon,
2323+
child: IconButtonTheme(
2324+
data: IconButtonThemeData(
2325+
style: IconButton.styleFrom(
2326+
foregroundColor: _getPrefixIconColor(themeData, defaults),
2327+
iconSize: iconSize,
2328+
),
2329+
),
2330+
child: Semantics(
2331+
child: decoration.prefixIcon,
2332+
),
23232333
),
23242334
),
23252335
),
@@ -2334,24 +2344,32 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
23342344
cursor: SystemMouseCursors.basic,
23352345
child: ConstrainedBox(
23362346
constraints: decoration.suffixIconConstraints ??
2337-
themeData.visualDensity.effectiveConstraints(
2338-
const BoxConstraints(
2339-
minWidth: kMinInteractiveDimension,
2340-
minHeight: kMinInteractiveDimension,
2341-
),
2347+
themeData.visualDensity.effectiveConstraints(
2348+
const BoxConstraints(
2349+
minWidth: kMinInteractiveDimension,
2350+
minHeight: kMinInteractiveDimension,
23422351
),
2343-
child: IconTheme.merge(
2344-
data: IconThemeData(
2345-
color: _getSuffixIconColor(themeData, defaults),
2346-
size: iconSize,
23472352
),
2348-
child: Semantics(
2349-
child: decoration.suffixIcon,
2353+
child: IconTheme.merge(
2354+
data: IconThemeData(
2355+
color: _getSuffixIconColor(themeData, defaults),
2356+
size: iconSize,
2357+
),
2358+
child: IconButtonTheme(
2359+
data: IconButtonThemeData(
2360+
style: IconButton.styleFrom(
2361+
foregroundColor: _getSuffixIconColor(themeData, defaults),
2362+
iconSize: iconSize,
2363+
),
2364+
),
2365+
child: Semantics(
2366+
child: decoration.suffixIcon,
2367+
),
2368+
),
23502369
),
23512370
),
23522371
),
2353-
),
2354-
);
2372+
);
23552373

23562374
final Widget helperError = _HelperError(
23572375
textAlign: textAlign,

packages/flutter/test/material/input_decorator_test.dart

+34
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ double getOpacity(WidgetTester tester, String textValue) {
148148
return opacityWidget.opacity.value;
149149
}
150150

151+
TextStyle? getIconStyle(WidgetTester tester, IconData icon) {
152+
final RichText iconRichText = tester.widget<RichText>(
153+
find.descendant(of: find.byIcon(icon), matching: find.byType(RichText)),
154+
);
155+
return iconRichText.text.style;
156+
}
157+
151158
void main() {
152159
for(final bool useMaterial3 in <bool>[true, false]){
153160
testWidgets('InputDecorator input/label text layout', (WidgetTester tester) async {
@@ -1732,6 +1739,33 @@ void main() {
17321739
expect(tester.widget<IconTheme>(find.widgetWithIcon(IconTheme,Icons.close).first).data.color, Colors.red);
17331740
});
17341741

1742+
testWidgets('InputDecorator suffixIconColor in M3 error state', (WidgetTester tester) async {
1743+
final ThemeData theme = ThemeData(
1744+
useMaterial3: true,
1745+
iconButtonTheme: const IconButtonThemeData(
1746+
style: ButtonStyle(
1747+
foregroundColor: MaterialStatePropertyAll<Color>(Colors.blue),
1748+
),
1749+
),
1750+
);
1751+
await tester.pumpWidget(
1752+
MaterialApp(
1753+
theme: theme,
1754+
home: Material(
1755+
child: TextField(
1756+
decoration: InputDecoration(
1757+
suffixIcon: IconButton(icon: const Icon(Icons.close), onPressed: () {}),
1758+
errorText: 'error state',
1759+
filled: true,
1760+
),
1761+
),
1762+
),
1763+
),
1764+
);
1765+
1766+
expect(getIconStyle(tester, Icons.close)?.color, theme.colorScheme.error);
1767+
});
1768+
17351769
testWidgets('InputDecorator prefix/suffix widgets', (WidgetTester tester) async {
17361770
const Key pKey = Key('p');
17371771
const Key sKey = Key('s');

0 commit comments

Comments
 (0)