From e38666ca79c1bf09b2ef3b556f8be31969bbc748 Mon Sep 17 00:00:00 2001 From: Eilidh Southren Date: Thu, 12 Jan 2023 15:34:08 +0000 Subject: [PATCH] [M3] Add error state support for side property of CheckBox (#118386) * Add error state support for side property * lint fixes * lint fixes --- .../flutter/lib/src/material/checkbox.dart | 4 +- .../flutter/test/material/checkbox_test.dart | 79 +++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/material/checkbox.dart b/packages/flutter/lib/src/material/checkbox.dart index 03872f9f5da06..156aebe8c2ce4 100644 --- a/packages/flutter/lib/src/material/checkbox.dart +++ b/packages/flutter/lib/src/material/checkbox.dart @@ -321,6 +321,7 @@ class Checkbox extends StatefulWidget { /// * [MaterialState.hovered]. /// * [MaterialState.focused]. /// * [MaterialState.disabled]. + /// * [MaterialState.error]. /// /// If this property is not a [MaterialStateBorderSide] and it is /// non-null, then it is only rendered when the checkbox's value is @@ -396,7 +397,8 @@ class _CheckboxState extends State with TickerProviderStateMixin, Togg BorderSide? _resolveSide(BorderSide? side) { if (side is MaterialStateBorderSide) { - return MaterialStateProperty.resolveAs(side, states); + final Set sideStates = widget.isError ? (states..add(MaterialState.error)) : states; + return MaterialStateProperty.resolveAs(side, sideStates); } if (!states.contains(MaterialState.selected)) { return side; diff --git a/packages/flutter/test/material/checkbox_test.dart b/packages/flutter/test/material/checkbox_test.dart index ec589841fce9f..131627c06ef88 100644 --- a/packages/flutter/test/material/checkbox_test.dart +++ b/packages/flutter/test/material/checkbox_test.dart @@ -1656,6 +1656,85 @@ void main() { await gestureLongPress.up(); await tester.pump(); }); + + testWidgets('Checkbox MaterialStateBorderSide applies in error states - M3', (WidgetTester tester) async { + final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox'); + final ThemeData themeData = ThemeData(useMaterial3: true); + const Color borderColor = Color(0xffffeb3b); + tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; + bool? value = false; + Widget buildApp({bool autoFocus = true}) { + return MaterialApp( + theme: themeData, + home: Material( + child: Center( + child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) { + return Checkbox( + isError: true, + side: MaterialStateBorderSide.resolveWith((Set states) { + if (states.contains(MaterialState.error)) { + return const BorderSide(color: borderColor, width: 4); + } + return const BorderSide(color: Colors.red, width: 2); + }), + value: value, + onChanged: (bool? newValue) { + setState(() { + value = newValue; + }); + }, + autofocus: autoFocus, + focusNode: focusNode, + ); + }), + ), + ), + ); + } + + void expectBorder() { + expect( + tester.renderObject(find.byType(Checkbox)), + paints + ..drrect( + color: borderColor, + outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)), + inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero), + ), + ); + } + + await tester.pumpWidget(buildApp()); + await tester.pumpAndSettle(); + expectBorder(); + + // Focused + await tester.pumpWidget(buildApp()); + await tester.pumpAndSettle(); + expect(focusNode.hasPrimaryFocus, isTrue); + expectBorder(); + + // Default color + await tester.pumpWidget(Container()); + await tester.pumpWidget(buildApp(autoFocus: false)); + await tester.pumpAndSettle(); + expect(focusNode.hasPrimaryFocus, isFalse); + expectBorder(); + + // Start hovering + final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); + await gesture.addPointer(); + await gesture.moveTo(tester.getCenter(find.byType(Checkbox))); + await tester.pumpAndSettle(); + expectBorder(); + + // Start pressing + final TestGesture gestureLongPress = await tester.startGesture(tester.getCenter(find.byType(Checkbox))); + await tester.pump(); + expectBorder(); + await gestureLongPress.up(); + await tester.pump(); + }); } class _SelectedGrabMouseCursor extends MaterialStateMouseCursor {