• 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
..
automated_tests Loading commit data...
benchmarks Loading commit data...
bots Loading commit data...
ci Loading commit data...
conductor Loading commit data...
customer_testing Loading commit data...
devicelab Loading commit data...
docs Loading commit data...
forbidden_from_release_tests Loading commit data...
integration_tests Loading commit data...
manual_tests Loading commit data...
missing_dependency_tests Loading commit data...
snippets/config Loading commit data...
tools Loading commit data...
tracing_tests Loading commit data...
README.md Loading commit data...
analysis_options.yaml Loading commit data...