• 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
.github Loading commit data...
.vscode Loading commit data...
bin Loading commit data...
dev Loading commit data...
examples Loading commit data...
packages Loading commit data...
.ci.yaml Loading commit data...
.cirrus.yml Loading commit data...
.gitattributes Loading commit data...
.gitignore Loading commit data...
AUTHORS Loading commit data...
CODEOWNERS Loading commit data...
CODE_OF_CONDUCT.md Loading commit data...
CONTRIBUTING.md Loading commit data...
LICENSE Loading commit data...
PATENT_GRANT Loading commit data...
README.md Loading commit data...
TESTOWNERS Loading commit data...
analysis_options.yaml Loading commit data...
dartdoc_options.yaml Loading commit data...
flutter_console.bat Loading commit data...