• Taha Tesser's avatar
    Introduce MaterialState `color` property for chips (#128584) · 467c970b
    Taha Tesser authored
    fixes https://github.com/flutter/flutter/issues/115827
    fixes https://github.com/flutter/flutter/issues/101325
    
    ### Description
    1. This PR adds a new MaterialState `color` property to all the chips (this makes it possible to customize chips in all states from the M3 specs).
    2. Updated defaults to use the new  MaterialState `color` property.
    3. Updated and added new tests to all the chip test classes.
    
    <details> 
    <summary>code sample</summary> 
    
    ```dart
    import 'package:flutter/material.dart';
    
    const Color disabledColor = Colors.black26;
    const Color backgroundColor = Colors.cyan;
    final Color disabledSelectedColor = Colors.red.shade100;
    const Color selectedColor = Colors.amber;
    final MaterialStateProperty<Color> color =
        MaterialStateProperty.resolveWith((Set<MaterialState> states) {
      if (states.contains(MaterialState.disabled) &&
          states.contains(MaterialState.selected)) {
        return disabledSelectedColor;
      }
      if (states.contains(MaterialState.disabled)) {
        return disabledColor;
      }
      if (states.contains(MaterialState.selected)) {
        return selectedColor;
      }
      return backgroundColor;
    });
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            useMaterial3: true,
            // chipTheme: ChipThemeData(color: color),
          ),
          home: const Example(),
        );
      }
    }
    
    class Example extends StatefulWidget {
      const Example({super.key});
    
      @override
      State<Example> createState() => _ExampleState();
    }
    
    class _ExampleState extends State<Example> {
      bool enabled = false;
      bool selected = true;
    
      @override
      Widget build(BuildContext context) {
        const Widget verticalSpace = SizedBox(height: 20);
    
        return Scaffold(
          body: Center(
            child: Column(
              children: <Widget>[
                const SizedBox(height: 25),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    const Card(
                      elevation: 0.0,
                      color: disabledColor,
                      child: Padding(
                        padding: EdgeInsets.all(8.0),
                        child: Text('disabledColor'),
                      ),
                    ),
                    const Card(
                      elevation: 0.0,
                      color: backgroundColor,
                      child: Padding(
                        padding: EdgeInsets.all(8.0),
                        child: Text('backgroundColor'),
                      ),
                    ),
                    Card(
                      elevation: 0.0,
                      color: disabledSelectedColor,
                      child: const Padding(
                        padding: EdgeInsets.all(8.0),
                        child: Text('disabledSelectedColor'),
                      ),
                    ),
                    const Card(
                      elevation: 0.0,
                      color: selectedColor,
                      child: Padding(
                        padding: EdgeInsets.all(8.0),
                        child: Text('selectedColor'),
                      ),
                    ),
                  ],
                ),
                const Spacer(),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    Column(
                      mainAxisSize: MainAxisSize.min,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        RawChip(
                          selected: selected,
                          selectedColor: selectedColor,
                          color: color,
                          label: const Text('RawChip'),
                          isEnabled: enabled,
                          onSelected: enabled ? (bool value) {} : null,
                        ),
                        verticalSpace,
                        InputChip(
                          isEnabled: enabled,
                          selected: selected,
                          selectedColor: selectedColor,
                          color: color,
                          label: const Text('InputChip'),
                          onSelected: enabled ? (bool value) {} : null,
                        ),
                      ],
                    ),
                    Column(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        FilterChip(
                          selected: selected,
                          selectedColor: selectedColor,
                          color: color,
                          label: const Text('FilterChip'),
                          onSelected: enabled ? (bool value) {} : null,
                        ),
                        verticalSpace,
                        FilterChip.elevated(
                          selected: selected,
                          selectedColor: selectedColor,
                          color: color,
                          label: const Text('FilterChip.elevated'),
                          onSelected: enabled ? (bool value) {} : null,
                        ),
                      ],
                    ),
                    Column(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        ChoiceChip(
                          selected: selected,
                          selectedColor: selectedColor,
                          color: color,
                          label: const Text('ChoiceChip'),
                          onSelected: enabled ? (bool value) {} : null,
                        ),
                        verticalSpace,
                        ChoiceChip.elevated(
                          selected: selected,
                          selectedColor: selectedColor,
                          color: color,
                          label: const Text('ChoiceChip.elevated'),
                          onSelected: enabled ? (bool value) {} : null,
                        ),
                      ],
                    ),
                  ],
                ),
                const Spacer(),
                Row(
                  children: <Widget>[
                    Flexible(
                      child: SwitchListTile(
                        title: const Text('Enabled'),
                        value: enabled,
                        onChanged: (bool value) {
                          setState(() => enabled = value);
                        },
                      ),
                    ),
                    Flexible(
                      child: SwitchListTile(
                        title: const Text('Selected'),
                        value: selected,
                        onChanged: (bool value) {
                          setState(() => selected = value);
                        },
                      ),
                    ),
                  ],
                )
              ],
            ),
          ),
        );
      }
    }
    
    ``` 
    	
    </details>
    
    ### Before (not possible to customize disabled and selected chips)
    
    ![Screenshot 2023-06-13 at 16 27 13](https://github.com/flutter/flutter/assets/48603081/633f09f7-16a1-469e-b326-b9cc0ed59242)
    
    ### After (using disabled and selected chips using the new  MaterialState `color` property)
    
    ![Screenshot 2023-06-13 at 16 26 53](https://github.com/flutter/flutter/assets/48603081/7f5dffb7-4074-4268-87c0-c059c2da67a8)
    467c970b
Name
Last commit
Last update
..
animation Loading commit data...
cupertino Loading commit data...
dart Loading commit data...
examples Loading commit data...
foundation Loading commit data...
gestures Loading commit data...
harness Loading commit data...
material Loading commit data...
painting Loading commit data...
physics Loading commit data...
rendering Loading commit data...
scheduler Loading commit data...
semantics Loading commit data...
services Loading commit data...
widgets Loading commit data...
_goldens_io.dart Loading commit data...
_goldens_web.dart Loading commit data...
analysis_options.yaml Loading commit data...
flutter_test_config.dart Loading commit data...
image_data.dart Loading commit data...