diff --git a/dev/tools/gen_defaults/lib/chip_template.dart b/dev/tools/gen_defaults/lib/chip_template.dart index 4d9383399d16..cdbe10362c11 100644 --- a/dev/tools/gen_defaults/lib/chip_template.dart +++ b/dev/tools/gen_defaults/lib/chip_template.dart @@ -19,7 +19,6 @@ class _${blockName}DefaultsM3 extends ChipThemeData { _${blockName}DefaultsM3(this.context, this.isEnabled) : super( elevation: ${elevation("$tokenGroup$variant.container")}, - shape: ${shape("$tokenGroup.container")}, showCheckmark: true, ); @@ -47,9 +46,13 @@ class _${blockName}DefaultsM3 extends ChipThemeData { Color? get deleteIconColor => ${color("$tokenGroup.with-icon.selected.icon.color")}; @override - BorderSide? get side => isEnabled - ? ${border('$tokenGroup$variant.outline')} - : ${border('$tokenGroup$variant.disabled.outline')}; + OutlinedBorder? get shape { + return ${shape("$tokenGroup.container")}.copyWith( + side: isEnabled + ? ${border('$tokenGroup$variant.outline')} + : ${border('$tokenGroup$variant.disabled.outline')}, + ); + } @override IconThemeData? get iconTheme => IconThemeData( diff --git a/packages/flutter/lib/src/material/chip.dart b/packages/flutter/lib/src/material/chip.dart index 3e1eb6d7bacf..65ee8909eb0c 100644 --- a/packages/flutter/lib/src/material/chip.dart +++ b/packages/flutter/lib/src/material/chip.dart @@ -997,6 +997,7 @@ class _RawChipState extends State with MaterialStateMixin, TickerProvid final OutlinedBorder resolvedShape = MaterialStateProperty.resolveAs(widget.shape, materialStates) ?? MaterialStateProperty.resolveAs(chipTheme.shape, materialStates) ?? MaterialStateProperty.resolveAs(chipDefaults.shape, materialStates) + // TODO(tahatesser): Remove this fallback when Material 2 is deprecated. ?? const StadiumBorder(); return resolvedShape.copyWith(side: resolvedSide); } @@ -2234,7 +2235,6 @@ class _ChipDefaultsM3 extends ChipThemeData { _ChipDefaultsM3(this.context, this.isEnabled) : super( elevation: 0.0, - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))), showCheckmark: true, ); @@ -2262,9 +2262,13 @@ class _ChipDefaultsM3 extends ChipThemeData { Color? get deleteIconColor => null; @override - BorderSide? get side => isEnabled - ? BorderSide(color: _colors.outline) - : BorderSide(color: _colors.onSurface.withOpacity(0.12)); + OutlinedBorder? get shape { + return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))).copyWith( + side: isEnabled + ? BorderSide(color: _colors.outline) + : BorderSide(color: _colors.onSurface.withOpacity(0.12)), + ); + } @override IconThemeData? get iconTheme => IconThemeData( diff --git a/packages/flutter/test/material/chip_test.dart b/packages/flutter/test/material/chip_test.dart index d098936aa14e..9f369c2ffa3a 100644 --- a/packages/flutter/test/material/chip_test.dart +++ b/packages/flutter/test/material/chip_test.dart @@ -3503,6 +3503,60 @@ void main() { expect(calledDelete, isTrue); }); + testWidgets("Material3 - RawChip.shape's side is used when provided", (WidgetTester tester) async { + Widget buildChip({ OutlinedBorder? shape, BorderSide? side }) { + return MaterialApp( + theme: ThemeData(useMaterial3: true), + home: Material( + child: Center( + child: RawChip( + shape: shape, + side: side, + label: const Text('RawChip'), + ), + ), + ), + ); + } + + // Test [RawChip.shape] with a side. + await tester.pumpWidget(buildChip( + shape: const RoundedRectangleBorder( + side: BorderSide(color: Color(0xffff00ff)), + borderRadius: BorderRadius.all(Radius.circular(7.0)), + )), + ); + + // Chip should have the provided shape and the side from [RawChip.shape]. + expect( + getMaterial(tester).shape, + const RoundedRectangleBorder( + side: BorderSide(color: Color(0xffff00ff)), + borderRadius: BorderRadius.all(Radius.circular(7.0)), + ), + ); + + // Test [RawChip.shape] with a side and [RawChip.side]. + await tester.pumpWidget(buildChip( + shape: const RoundedRectangleBorder( + side: BorderSide(color: Color(0xffff00ff)), + borderRadius: BorderRadius.all(Radius.circular(7.0)), + ), + side: const BorderSide(color: Color(0xfffff000))), + ); + await tester.pumpAndSettle(); + + // Chip use shape from [RawChip.shape] and the side from [RawChip.side]. + // [RawChip.shape]'s side should be ignored. + expect( + getMaterial(tester).shape, + const RoundedRectangleBorder( + side: BorderSide(color: Color(0xfffff000)), + borderRadius: BorderRadius.all(Radius.circular(7.0)), + ), + ); + }); + group('Material 2', () { // These tests are only relevant for Material 2. Once Material 2 // support is deprecated and the APIs are removed, these tests diff --git a/packages/flutter/test/material/chip_theme_test.dart b/packages/flutter/test/material/chip_theme_test.dart index 2303b56478cd..4ff0c5c31773 100644 --- a/packages/flutter/test/material/chip_theme_test.dart +++ b/packages/flutter/test/material/chip_theme_test.dart @@ -928,6 +928,64 @@ void main() { )), ); }); + + testWidgets("Material3 - RawChip.shape's side is used when provided", (WidgetTester tester) async { + Widget buildChip({ OutlinedBorder? shape, BorderSide? side }) { + return MaterialApp( + theme: ThemeData( + useMaterial3: true, + chipTheme: ChipThemeData( + shape: shape, + side: side, + ), + ), + home: const Material( + child: Center( + child: RawChip( + label: Text('RawChip'), + ), + ), + ), + ); + } + + // Test [RawChip.shape] with a side. + await tester.pumpWidget(buildChip( + shape: const RoundedRectangleBorder( + side: BorderSide(color: Color(0xffff00ff)), + borderRadius: BorderRadius.all(Radius.circular(7.0)), + )), + ); + + // Chip should have the provided shape and the side from [RawChip.shape]. + expect( + getMaterial(tester).shape, + const RoundedRectangleBorder( + side: BorderSide(color: Color(0xffff00ff)), + borderRadius: BorderRadius.all(Radius.circular(7.0)), + ), + ); + + // Test [RawChip.shape] with a side and [RawChip.side]. + await tester.pumpWidget(buildChip( + shape: const RoundedRectangleBorder( + side: BorderSide(color: Color(0xffff00ff)), + borderRadius: BorderRadius.all(Radius.circular(7.0)), + ), + side: const BorderSide(color: Color(0xfffff000))), + ); + await tester.pumpAndSettle(); + + // Chip use shape from [RawChip.shape] and the side from [RawChip.side]. + // [RawChip.shape]'s side should be ignored. + expect( + getMaterial(tester).shape, + const RoundedRectangleBorder( + side: BorderSide(color: Color(0xfffff000)), + borderRadius: BorderRadius.all(Radius.circular(7.0)), + ), + ); + }); } class _MaterialStateOutlinedBorder extends StadiumBorder implements MaterialStateOutlinedBorder {