Skip to content

Commit

Permalink
Fix Chip.shape's side is not used when provided in Material 3 (#132…
Browse files Browse the repository at this point in the history
…941)

fixes [Chip border side color not working in Material3](flutter/flutter#132922)

### Code sample

<details> 
<summary>expand to view the code sample</summary> 

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @OverRide
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        useMaterial3: true,
        chipTheme: const ChipThemeData(
            // shape: RoundedRectangleBorder(
            //   side: BorderSide(color: Colors.amber),
            //   borderRadius: BorderRadius.all(Radius.circular(12)),
            // ),
            // side: BorderSide(color: Colors.red),
            ),
      ),
      home: const Example(),
    );
  }
}

class Example extends StatelessWidget {
  const Example({super.key});

  @OverRide
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: RawChip(
          shape: RoundedRectangleBorder(
            side: BorderSide(color: Colors.amber),
            borderRadius: BorderRadius.all(Radius.circular(12)),
          ),
          // side: BorderSide(color: Colors.red),
          label: Text('Chip'),
        ),
      ),
    );
  }
}

``` 

</details>

---

### Before

When `RawChip.shape` is provided with a `BorderSide`.

```dart
      body: Center(
        child: RawChip(
          shape: RoundedRectangleBorder(
            side: BorderSide(color: Colors.amber),
            borderRadius: BorderRadius.all(Radius.circular(12)),
          ),
          label: Text('Chip'),
        ),
      ),
```

![Screenshot 2023-08-24 at 17 54 54](https://github.com/flutter/flutter/assets/48603081/89e2c9b5-44c2-432e-97ff-8bb95b0d0fb1)

When `RawChip.shape` is provided with a `BorderSide` and also `RawChip.side` is provided. The  `RawChip.side` overrides the shape's side.

```dart
      body: Center(
        child: RawChip(
          shape: RoundedRectangleBorder(
            side: BorderSide(color: Colors.amber),
            borderRadius: BorderRadius.all(Radius.circular(12)),
          ),
          side: BorderSide(color: Colors.red),
          label: Text('Chip'),
        ),
      ),
```

![Screenshot 2023-08-24 at 17 55 37](https://github.com/flutter/flutter/assets/48603081/938803cc-d514-464b-b06b-e4841b9ad040)

---

### After

When `RawChip.shape` is provided with a `BorderSide`.

```dart
      body: Center(
        child: RawChip(
          shape: RoundedRectangleBorder(
            side: BorderSide(color: Colors.amber),
            borderRadius: BorderRadius.all(Radius.circular(12)),
          ),
          label: Text('Chip'),
        ),
      ),
```

![Screenshot 2023-08-24 at 17 51 29](https://github.com/flutter/flutter/assets/48603081/d6fcaaa9-8f5d-4180-ad14-062dd459ec45)

When `RawChip.shape` is provided with a `BorderSide` and also `RawChip.side` is provided. The  `RawChip.side` overrides the shape's side.

```dart
      body: Center(
        child: RawChip(
          shape: RoundedRectangleBorder(
            side: BorderSide(color: Colors.amber),
            borderRadius: BorderRadius.all(Radius.circular(12)),
          ),
          side: BorderSide(color: Colors.red),
          label: Text('Chip'),
        ),
      ),
```

![Screenshot 2023-08-24 at 17 52 31](https://github.com/flutter/flutter/assets/48603081/3fa46341-43f0-4fe7-a922-f1d8ba34028c)

---
  • Loading branch information
TahaTesser authored Aug 25, 2023
1 parent 5c17a37 commit 612117a
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 8 deletions.
11 changes: 7 additions & 4 deletions dev/tools/gen_defaults/lib/chip_template.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
Expand Down Expand Up @@ -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(
Expand Down
12 changes: 8 additions & 4 deletions packages/flutter/lib/src/material/chip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,7 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
final OutlinedBorder resolvedShape = MaterialStateProperty.resolveAs<OutlinedBorder?>(widget.shape, materialStates)
?? MaterialStateProperty.resolveAs<OutlinedBorder?>(chipTheme.shape, materialStates)
?? MaterialStateProperty.resolveAs<OutlinedBorder?>(chipDefaults.shape, materialStates)
// TODO(tahatesser): Remove this fallback when Material 2 is deprecated.
?? const StadiumBorder();
return resolvedShape.copyWith(side: resolvedSide);
}
Expand Down Expand Up @@ -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,
);

Expand Down Expand Up @@ -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(
Expand Down
54 changes: 54 additions & 0 deletions packages/flutter/test/material/chip_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
58 changes: 58 additions & 0 deletions packages/flutter/test/material/chip_theme_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 612117a

Please sign in to comment.