Unverified Commit a433f88d authored by Qun Cheng's avatar Qun Cheng Committed by GitHub

`Checkbox.fillColor` should be applied to checkbox's background color when it...

`Checkbox.fillColor` should be applied to checkbox's background color when it is unchecked. (#125643)
parent 50f83fc2
...@@ -20,27 +20,49 @@ class _${blockName}DefaultsM3 extends CheckboxThemeData { ...@@ -20,27 +20,49 @@ class _${blockName}DefaultsM3 extends CheckboxThemeData {
final ColorScheme _colors; final ColorScheme _colors;
@override @override
MaterialStateProperty<Color> get fillColor { MaterialStateBorderSide? get side {
return MaterialStateProperty.resolveWith((Set<MaterialState> states) { return MaterialStateBorderSide.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) { if (states.contains(MaterialState.disabled)) {
return ${componentColor('md.comp.checkbox.selected.disabled.container')}; if (states.contains(MaterialState.selected)) {
} return const BorderSide(width: ${tokens['md.comp.checkbox.unselected.disabled.outline.width']}, color: Colors.transparent);
if (states.contains(MaterialState.error)) { }
return ${componentColor('md.comp.checkbox.unselected.error.outline')}; return BorderSide(width: ${tokens['md.comp.checkbox.unselected.disabled.outline.width']}, color: ${componentColor('md.comp.checkbox.unselected.disabled.outline')}.withOpacity(${tokens['md.comp.checkbox.unselected.disabled.container.opacity']}));
} }
if (states.contains(MaterialState.selected)) { if (states.contains(MaterialState.selected)) {
return ${componentColor('md.comp.checkbox.selected.container')}; return const BorderSide(width: ${tokens['md.comp.checkbox.selected.outline.width']}, color: Colors.transparent);
}
if (states.contains(MaterialState.error)) {
return BorderSide(width: ${tokens['md.comp.checkbox.unselected.disabled.outline.width']}, color: ${componentColor('md.comp.checkbox.unselected.error.outline')});
} }
if (states.contains(MaterialState.pressed)) { if (states.contains(MaterialState.pressed)) {
return ${componentColor('md.comp.checkbox.unselected.pressed.outline')}; return BorderSide(width: ${tokens['md.comp.checkbox.unselected.pressed.outline.width']}, color: ${componentColor('md.comp.checkbox.unselected.pressed.outline')});
} }
if (states.contains(MaterialState.hovered)) { if (states.contains(MaterialState.hovered)) {
return ${componentColor('md.comp.checkbox.unselected.hover.outline')}; return BorderSide(width: ${tokens['md.comp.checkbox.unselected.hover.outline.width']}, color: ${componentColor('md.comp.checkbox.unselected.hover.outline')});
} }
if (states.contains(MaterialState.focused)) { if (states.contains(MaterialState.focused)) {
return ${componentColor('md.comp.checkbox.unselected.focus.outline')}; return BorderSide(width: ${tokens['md.comp.checkbox.unselected.focus.outline.width']}, color: ${componentColor('md.comp.checkbox.unselected.focus.outline')});
}
return BorderSide(width: ${tokens['md.comp.checkbox.unselected.outline.width']}, color: ${componentColor('md.comp.checkbox.unselected.outline')});
});
}
@override
MaterialStateProperty<Color> get fillColor {
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
if (states.contains(MaterialState.selected)) {
return ${componentColor('md.comp.checkbox.selected.disabled.container')};
}
return Colors.transparent;
} }
return ${componentColor('md.comp.checkbox.unselected.outline')}; if (states.contains(MaterialState.selected)) {
if (states.contains(MaterialState.error)) {
return ${componentColor('md.comp.checkbox.selected.error.container')};
}
return ${componentColor('md.comp.checkbox.selected.container')};
}
return Colors.transparent;
}); });
} }
......
...@@ -438,17 +438,21 @@ void main() { ...@@ -438,17 +438,21 @@ void main() {
await tester.pumpWidget(buildFrame(false)); await tester.pumpWidget(buildFrame(false));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), isNot(paints..path())); // checkmark is rendered as a path expect(getCheckboxRenderer(), paints..path(color: Colors.transparent)); // paint transparent border
expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash") expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox
await tester.pumpWidget(buildFrame(true)); await tester.pumpWidget(buildFrame(true));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path()); // checkmark is rendered as a path expect(getCheckboxRenderer(),
paints
..path(color: theme.useMaterial3 ? theme.colorScheme.primary : theme.colorScheme.secondary)
..path(color: theme.useMaterial3 ? theme.colorScheme.onPrimary : const Color(0xFFFFFFFF))
); // checkmark is rendered as a path
await tester.pumpWidget(buildFrame(false)); await tester.pumpWidget(buildFrame(false));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), isNot(paints..path())); // checkmark is rendered as a path expect(getCheckboxRenderer(), paints..path(color: Colors.transparent)); // paint transparent border
expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash") expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox
...@@ -458,7 +462,11 @@ void main() { ...@@ -458,7 +462,11 @@ void main() {
await tester.pumpWidget(buildFrame(true)); await tester.pumpWidget(buildFrame(true));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path()); // checkmark is rendered as a path expect(getCheckboxRenderer(),
paints
..path(color: theme.useMaterial3 ? theme.colorScheme.primary : theme.colorScheme.secondary)
..path(color: theme.useMaterial3 ? theme.colorScheme.onPrimary : const Color(0xFFFFFFFF))
); // checkmark is rendered as a path
await tester.pumpWidget(buildFrame(null)); await tester.pumpWidget(buildFrame(null));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -1493,17 +1501,16 @@ void main() { ...@@ -1493,17 +1501,16 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expectBorder(); expectBorder();
// Checkbox is selected/indeterminate, so the specified BorderSide // Checkbox is selected/indeterminate, so the specified BorderSide is transparent
// does not appear.
await tester.pumpWidget(buildApp(value: true)); await tester.pumpWidget(buildApp(value: true));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), isNot(paints..drrect())); // no border expect(getCheckboxRenderer(), paints..drrect(color: Colors.transparent));
expect(getCheckboxRenderer(), paints..path(color: activeColor)); // checkbox fill expect(getCheckboxRenderer(), paints..path(color: activeColor)); // checkbox fill
await tester.pumpWidget(buildApp()); await tester.pumpWidget(buildApp());
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), isNot(paints..drrect())); // no border expect(getCheckboxRenderer(), paints..drrect(color: Colors.transparent));
expect(getCheckboxRenderer(), paints..path(color: activeColor)); // checkbox fill expect(getCheckboxRenderer(), paints..path(color: activeColor)); // checkbox fill
}); });
...@@ -1827,6 +1834,59 @@ void main() { ...@@ -1827,6 +1834,59 @@ void main() {
expect(find.byType(CupertinoCheckbox), findsNothing); expect(find.byType(CupertinoCheckbox), findsNothing);
} }
}); });
testWidgets('Checkbox respects fillColor when it is unchecked', (WidgetTester tester) async {
const Color activeBackgroundColor = Color(0xff123456);
const Color inactiveBackgroundColor = Color(0xff654321);
Widget buildApp({ bool enabled = true }) {
return MaterialApp(
theme: theme,
home: Material(
child: Center(
child: Checkbox(
fillColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return activeBackgroundColor;
}
return inactiveBackgroundColor;
}),
value: false,
onChanged: enabled ? (bool? newValue) { } : null,
),
),
),
);
}
RenderBox getCheckboxRenderer() {
return tester.renderObject<RenderBox>(find.byType(Checkbox));
}
// Checkbox is unselected, so the default BorderSide appears and fillColor is checkbox's background color.
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expect(
getCheckboxRenderer(),
paints
..drrect(
color: theme.useMaterial3 ? theme.colorScheme.onSurfaceVariant : theme.unselectedWidgetColor,
),
);
expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor));
await tester.pumpWidget(buildApp(enabled: false));
await tester.pumpAndSettle();
expect(
getCheckboxRenderer(),
paints
..drrect(
color: theme.useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : theme.disabledColor,
),
);
expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor));
});
} }
class _SelectedGrabMouseCursor extends MaterialStateMouseCursor { class _SelectedGrabMouseCursor extends MaterialStateMouseCursor {
......
...@@ -142,7 +142,7 @@ void main() { ...@@ -142,7 +142,7 @@ void main() {
// Checkbox. // Checkbox.
await tester.pumpWidget(buildCheckbox()); await tester.pumpWidget(buildCheckbox());
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(_getCheckboxMaterial(tester), paints..drrect(color: defaultFillColor)); expect(_getCheckboxMaterial(tester), paints..path(color: defaultFillColor));
// Size from MaterialTapTargetSize.shrinkWrap with added VisualDensity. // Size from MaterialTapTargetSize.shrinkWrap with added VisualDensity.
expect(tester.getSize(find.byType(Checkbox)), const Size(40.0, 40.0) + visualDensity.baseSizeAdjustment); expect(tester.getSize(find.byType(Checkbox)), const Size(40.0, 40.0) + visualDensity.baseSizeAdjustment);
...@@ -241,7 +241,7 @@ void main() { ...@@ -241,7 +241,7 @@ void main() {
// Checkbox. // Checkbox.
await tester.pumpWidget(buildCheckbox()); await tester.pumpWidget(buildCheckbox());
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(_getCheckboxMaterial(tester), paints..drrect(color: defaultFillColor)); expect(_getCheckboxMaterial(tester), paints..path(color: defaultFillColor));
// Size from MaterialTapTargetSize.shrinkWrap with added VisualDensity. // Size from MaterialTapTargetSize.shrinkWrap with added VisualDensity.
expect(tester.getSize(find.byType(Checkbox)), const Size(40.0, 40.0) + visualDensity.baseSizeAdjustment); expect(tester.getSize(find.byType(Checkbox)), const Size(40.0, 40.0) + visualDensity.baseSizeAdjustment);
...@@ -294,7 +294,7 @@ void main() { ...@@ -294,7 +294,7 @@ void main() {
// Unselected checkbox. // Unselected checkbox.
await tester.pumpWidget(buildCheckbox()); await tester.pumpWidget(buildCheckbox());
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(_getCheckboxMaterial(tester), paints..drrect(color: themeDefaultFillColor)); expect(_getCheckboxMaterial(tester), paints..path(color: themeDefaultFillColor));
// Selected checkbox. // Selected checkbox.
await tester.pumpWidget(buildCheckbox(selected: true)); await tester.pumpWidget(buildCheckbox(selected: true));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment