1. 20 Oct, 2023 1 commit
  2. 19 Oct, 2023 1 commit
  3. 12 Oct, 2023 1 commit
  4. 11 Oct, 2023 1 commit
  5. 20 Sep, 2023 1 commit
  6. 12 Sep, 2023 1 commit
  7. 30 Aug, 2023 2 commits
    • Taha Tesser's avatar
      Add `cancelButtonStyle` & `confirmButtonStyle` to the `DatePickerThemeData` (#132847) · 1e770c38
      Taha Tesser authored
      fixes [Unable to adjust the color for "Cancel" and "Ok" button in datePicker dialog](https://github.com/flutter/flutter/issues/127739)
      
      ### 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(
            debugShowCheckedModeBanner: false,
            theme: ThemeData(
              useMaterial3: true,
              datePickerTheme: DatePickerThemeData(
                cancelButtonStyle: TextButton.styleFrom(
                  shape: const RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(Radius.circular(16)),
                    side: BorderSide(color: Colors.red),
                  ),
                  backgroundColor: Colors.white,
                  foregroundColor: Colors.red,
                  elevation: 3,
                  shadowColor: Colors.red,
                ),
                confirmButtonStyle: TextButton.styleFrom(
                  shape: const RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(Radius.circular(16)),
                  ),
                  backgroundColor: Colors.green[700],
                  foregroundColor: Colors.white,
                  elevation: 3,
                  shadowColor: Colors.green[700],
                ),
              ),
            ),
            home: const Example(),
          );
        }
      }
      
      class Example extends StatelessWidget {
        const Example({super.key});
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            body: Center(
              child: DatePickerDialog(
                initialDate: DateTime.now(),
                firstDate: DateTime(2020),
                lastDate: DateTime(2030),
              ),
            ),
          );
        }
      }
      ``` 
      
      </details>
      
      ### Before 
      
      Not possible to customize action buttons from the `DatePickerThemeData`.
      
      ### After 
      
      ![Screenshot 2023-08-18 at 16 42 00](https://github.com/flutter/flutter/assets/48603081/4ec01e93-c661-491d-9253-d687da8b76f3)
      1e770c38
    • Xilai Zhang's avatar
      [flutter roll] Revert "Fix `Chip.shape`'s side is not used when provided in Material 3" (#133615) · 6fd42536
      Xilai Zhang authored
      Reverts flutter/flutter#132941
      context: b/298110031
      
      The rounded rectangle borders don't appear in some of the internal
      golden image tests.
      6fd42536
  8. 25 Aug, 2023 2 commits
    • Kenzie Davisson's avatar
      Update flutter packages to pick up latest vm_service (#133335) · 61d9f556
      Kenzie Davisson authored
      Generated by running `flutter update-packages --force-upgrade`
      61d9f556
    • Taha Tesser's avatar
      Fix `Chip.shape`'s side is not used when provided in Material 3 (#132941) · 612117a6
      Taha Tesser authored
      fixes [Chip border side color not working in Material3](https://github.com/flutter/flutter/issues/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)
      
      ---
      612117a6
  9. 22 Aug, 2023 1 commit
    • Taha Tesser's avatar
      Update default menu text styles for Material 3 (#131930) · 1bc79169
      Taha Tesser authored
      Related https://github.com/flutter/flutter/issues/131676
      
      ## Description
      
      #### Fix default input text style for `DropdownMenu`
      
      ![dropdown_input](https://github.com/flutter/flutter/assets/48603081/301f8243-155a-4b8f-84a8-5e6b7bebb3bc)
      
      ### Fix default text style for  `MenuAnchor`'s menu items (which `DropdownMenu` uses for menu items)
      
      ![dropdown_item](https://github.com/flutter/flutter/assets/48603081/6b5be81a-72fc-4705-a577-074c7a4cad8f)
      
      ###  Default  `DropdownMenu` Input text style 
      
      ![Screenshot 2023-08-04 at 16 48 28](https://github.com/flutter/flutter/assets/48603081/bcd9da98-e74d-491e-ae64-6268ae0b3893)
      
      ### Default `DropdownMenu` menu item text style
      
      ![Screenshot 2023-08-04 at 16 50 19](https://github.com/flutter/flutter/assets/48603081/9592ca43-2854-45b5-8648-203ab65d9745)
      
      ### Default `MenuAnchor` menu item text style
      
      ![Screenshot 2023-08-04 at 14 34 28](https://github.com/flutter/flutter/assets/48603081/e87e1073-05f8-4dc7-a435-d864e9cce6ab)
      
      ### Code sample
      
      <details> 
      <summary>expand to view the code sample</summary> 
      
      ```dart
      import 'package:flutter/material.dart';
      
      /// Flutter code sample for [DropdownMenu]s. The first dropdown menu has an outlined border.
      
      void main() => runApp(const DropdownMenuExample());
      
      class DropdownMenuExample extends StatefulWidget {
        const DropdownMenuExample({super.key});
      
        @override
        State<DropdownMenuExample> createState() => _DropdownMenuExampleState();
      }
      
      class _DropdownMenuExampleState extends State<DropdownMenuExample> {
        final TextEditingController colorController = TextEditingController();
        final TextEditingController iconController = TextEditingController();
        ColorLabel? selectedColor;
        IconLabel? selectedIcon;
      
        @override
        Widget build(BuildContext context) {
          final List<DropdownMenuEntry<ColorLabel>> colorEntries =
              <DropdownMenuEntry<ColorLabel>>[];
          for (final ColorLabel color in ColorLabel.values) {
            colorEntries.add(
              DropdownMenuEntry<ColorLabel>(
                  value: color, label: color.label, enabled: color.label != 'Grey'),
            );
          }
      
          final List<DropdownMenuEntry<IconLabel>> iconEntries =
              <DropdownMenuEntry<IconLabel>>[];
          for (final IconLabel icon in IconLabel.values) {
            iconEntries
                .add(DropdownMenuEntry<IconLabel>(value: icon, label: icon.label));
          }
      
          return MaterialApp(
            theme: ThemeData(
              useMaterial3: true,
              colorSchemeSeed: Colors.green,
              // textTheme: const TextTheme(
              //   bodyLarge: TextStyle(
              //     fontWeight: FontWeight.bold,
              //     fontStyle: FontStyle.italic,
              //     decoration: TextDecoration.underline,
              //   ),
              // ),
            ),
            home: Scaffold(
              body: SafeArea(
                child: Column(
                  children: <Widget>[
                    const Text('DropdownMenus'),
                    Padding(
                      padding: const EdgeInsets.symmetric(vertical: 20),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          DropdownMenu<ColorLabel>(
                            controller: colorController,
                            label: const Text('Color'),
                            dropdownMenuEntries: colorEntries,
                            onSelected: (ColorLabel? color) {
                              setState(() {
                                selectedColor = color;
                              });
                            },
                          ),
                          const SizedBox(width: 20),
                          DropdownMenu<IconLabel>(
                            controller: iconController,
                            enableFilter: true,
                            leadingIcon: const Icon(Icons.search),
                            label: const Text('Icon'),
                            dropdownMenuEntries: iconEntries,
                            inputDecorationTheme: const InputDecorationTheme(
                              filled: true,
                              contentPadding: EdgeInsets.symmetric(vertical: 5.0),
                            ),
                            onSelected: (IconLabel? icon) {
                              setState(() {
                                selectedIcon = icon;
                              });
                            },
                          ),
                        ],
                      ),
                    ),
                    const Text('Plain TextFields'),
                    Padding(
                      padding: const EdgeInsets.symmetric(vertical: 20),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          SizedBox(
                            width: 150,
                            child: TextField(
                                controller: TextEditingController(text: 'Blue'),
                                decoration: const InputDecoration(
                                  suffixIcon: Icon(Icons.arrow_drop_down),
                                  labelText: 'Color',
                                  border: OutlineInputBorder(),
                                )),
                          ),
                          const SizedBox(width: 20),
                          SizedBox(
                            width: 150,
                            child: TextField(
                                controller: TextEditingController(text: 'Smile'),
                                decoration: const InputDecoration(
                                  prefixIcon: Icon(Icons.search),
                                  suffixIcon: Icon(Icons.arrow_drop_down),
                                  filled: true,
                                  labelText: 'Icon',
                                )),
                          ),
                        ],
                      ),
                    ),
                    if (selectedColor != null && selectedIcon != null)
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Text(
                              'You selected a ${selectedColor?.label} ${selectedIcon?.label}'),
                          Padding(
                            padding: const EdgeInsets.symmetric(horizontal: 5),
                            child: Icon(
                              selectedIcon?.icon,
                              color: selectedColor?.color,
                            ),
                          )
                        ],
                      )
                    else
                      const Text('Please select a color and an icon.')
                  ],
                ),
              ),
            ),
          );
        }
      }
      
      enum ColorLabel {
        blue('Blue', Colors.blue),
        pink('Pink', Colors.pink),
        green('Green', Colors.green),
        yellow('Yellow', Colors.yellow),
        grey('Grey', Colors.grey);
      
        const ColorLabel(this.label, this.color);
        final String label;
        final Color color;
      }
      
      enum IconLabel {
        smile('Smile', Icons.sentiment_satisfied_outlined),
        cloud(
          'Cloud',
          Icons.cloud_outlined,
        ),
        brush('Brush', Icons.brush_outlined),
        heart('Heart', Icons.favorite);
      
        const IconLabel(this.label, this.icon);
        final String label;
        final IconData icon;
      }
      
      ``` 
      	
      </details>
      1bc79169
  10. 16 Aug, 2023 1 commit
  11. 15 Aug, 2023 1 commit
  12. 13 Aug, 2023 1 commit
  13. 10 Aug, 2023 2 commits
    • Polina Cherkasova's avatar
      Upgrade flutter packages. (#132326) · 60634c65
      Polina Cherkasova authored
      60634c65
    • Taha Tesser's avatar
      Fix `PopupMenuItem` & `CheckedPopupMenuItem` has redundant `ListTile` padding... · 96e02c61
      Taha Tesser authored
      Fix `PopupMenuItem` & `CheckedPopupMenuItem` has redundant `ListTile` padding and update default horizontal padding for Material 3 (#131609)
      
      fixes [`PopupMenuItem` adds redundant padding when using `ListItem`](https://github.com/flutter/flutter/issues/128553)
      
      ### Description
      
      - Fixed redundant `ListTile` padding when using `CheckedPopupMenuItem` or  `PopupMenuItem`  with the `ListTile` child for complex popup menu items as suggested in the docs.
      - Updated default horizontal padding for popup menu items.
      
      ### Code sample
      
      <details> 
      <summary>expand to view the code sample</summary> 
      
      ```dart
      import 'package:flutter/material.dart';
      
      /// Flutter code sample for [PopupMenuButton].
      
      // This is the type used by the popup menu below.
      enum SampleItem { itemOne, itemTwo, itemThree }
      
      void main() => runApp(const PopupMenuApp());
      
      class PopupMenuApp extends StatelessWidget {
        const PopupMenuApp({super.key});
      
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            theme: ThemeData(useMaterial3: true),
            home: const PopupMenuExample(),
          );
        }
      }
      
      class PopupMenuExample extends StatefulWidget {
        const PopupMenuExample({super.key});
      
        @override
        State<PopupMenuExample> createState() => _PopupMenuExampleState();
      }
      
      class _PopupMenuExampleState extends State<PopupMenuExample> {
        SampleItem? selectedMenu;
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(title: const Text('PopupMenuButton')),
            body: Center(
              child: SizedBox(
                width: 150,
                height: 100,
                child: Align(
                  alignment: Alignment.topLeft,
                  child: PopupMenuButton<SampleItem>(
                    initialValue: selectedMenu,
                    // Callback that sets the selected popup menu item.
                    onSelected: (SampleItem item) {
                      setState(() {
                        selectedMenu = item;
                      });
                    },
                    itemBuilder: (BuildContext context) =>
                        <PopupMenuEntry<SampleItem>>[
                      const PopupMenuItem<SampleItem>(
                        value: SampleItem.itemOne,
                        child: Text('PopupMenuItem'),
                      ),
                      const CheckedPopupMenuItem<SampleItem>(
                        checked: true,
                        value: SampleItem.itemTwo,
                        child: Text('CheckedPopupMenuItem'),
                      ),
                      const PopupMenuItem<SampleItem>(
                        value: SampleItem.itemOne,
                        child: ListTile(
                          leading: Icon(Icons.cloud),
                          title: Text('ListTile'),
                          contentPadding: EdgeInsets.zero,
                          trailing: Icon(Icons.arrow_right_rounded),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          );
        }
      }
      ``` 
      	
      </details>
      
      ### Before
      
      ![image](https://github.com/flutter/flutter/assets/48603081/aad15ffb-ca11-4997-81d1-b46288161a4e)
      
      - Default horizontal padding is the same as M2 (16.0), while the specs use a smaller value (12.0)
      - `ListTile` nested by default in `CheckedPopupMenuItem` has redundant padding
      - `PopupMenuItem` using `ListTile` as a child for complex menu items contains redundant padding.
      
      ![Screenshot 2023-07-31 at 17 17 08](https://github.com/flutter/flutter/assets/48603081/75ad1fe5-e051-42ba-badf-e20c799dee96)
      
      ### After 
      
      - Default horizontal padding is updated for Material 3.
      - `PopupMenuItem` & `CheckedPopupMenuItem` override `ListTile` padding (similar to how `ExpansionTile` overrides `ListTile` text and icon color.
      
      ![Screenshot 2023-07-31 at 17 17 25](https://github.com/flutter/flutter/assets/48603081/288cf892-5b51-4365-9855-5ef0ed2928e9)
      96e02c61
  14. 09 Aug, 2023 1 commit
  15. 08 Aug, 2023 2 commits
  16. 04 Aug, 2023 1 commit
  17. 03 Aug, 2023 1 commit
  18. 02 Aug, 2023 1 commit
    • Taha Tesser's avatar
      Fix Scrollable `TabBar` for Material 3 (#131409) · 2c71881f
      Taha Tesser authored
      fixes [Material 3 `TabBar` does not take full width when `isScrollable: true`](https://github.com/flutter/flutter/issues/117722)
      
      ### Description
      1. Fixed the divider doesn't stretch to take all the available width in the scrollable tab bar in M3
      2. Added `dividerHeight` property.
      
      ### Code sample
      
      <details> 
      <summary>expand to view the code sample</summary> 
      
      ```dart
      import 'package:flutter/material.dart';
      
      /// Flutter code sample for [TabBar].
      
      void main() => runApp(const TabBarApp());
      
      class TabBarApp extends StatelessWidget {
        const TabBarApp({super.key});
      
        @override
        Widget build(BuildContext context) {
          return const MaterialApp(
            debugShowCheckedModeBanner: false,
            home: TabBarExample(),
          );
        }
      }
      
      class TabBarExample extends StatefulWidget {
        const TabBarExample({super.key});
      
        @override
        State<TabBarExample> createState() => _TabBarExampleState();
      }
      
      class _TabBarExampleState extends State<TabBarExample> {
        bool rtl = false;
        bool customColors = false;
        bool removeDivider = false;
        Color dividerColor = Colors.amber;
        Color indicatorColor = Colors.red;
      
        @override
        Widget build(BuildContext context) {
          return DefaultTabController(
            initialIndex: 1,
            length: 3,
            child: Directionality(
              textDirection: rtl ? TextDirection.rtl : TextDirection.ltr,
              child: Scaffold(
                appBar: AppBar(
                  title: const Text('TabBar Sample'),
                  actions: <Widget>[
                    IconButton.filledTonal(
                      tooltip: 'Switch direction',
                      icon: const Icon(Icons.swap_horiz),
                      onPressed: () {
                        setState(() {
                          rtl = !rtl;
                        });
                      },
                    ),
                    IconButton.filledTonal(
                      tooltip: 'Use custom colors',
                      icon: const Icon(Icons.color_lens),
                      onPressed: () {
                        setState(() {
                          customColors = !customColors;
                        });
                      },
                    ),
                    IconButton.filledTonal(
                      tooltip: 'Show/hide divider',
                      icon: const Icon(Icons.remove_rounded),
                      onPressed: () {
                        setState(() {
                          removeDivider = !removeDivider;
                        });
                      },
                    ),
                  ],
                ),
                body: Column(
                  children: <Widget>[
                    const Spacer(),
                    const Text('Scrollable - TabAlignment.start'),
                    TabBar(
                      isScrollable: true,
                      tabAlignment: TabAlignment.start,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Text('Scrollable - TabAlignment.startOffset'),
                    TabBar(
                      isScrollable: true,
                      tabAlignment: TabAlignment.startOffset,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Text('Scrollable - TabAlignment.center'),
                    TabBar(
                      isScrollable: true,
                      tabAlignment: TabAlignment.center,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Spacer(),
                    const Text('Non-scrollable - TabAlignment.fill'),
                    TabBar(
                      tabAlignment: TabAlignment.fill,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Text('Non-scrollable - TabAlignment.center'),
                    TabBar(
                      tabAlignment: TabAlignment.center,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Spacer(),
                    const Text('Secondary - TabAlignment.fill'),
                    TabBar.secondary(
                      tabAlignment: TabAlignment.fill,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Text('Secondary - TabAlignment.center'),
                    TabBar.secondary(
                      tabAlignment: TabAlignment.center,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Spacer(),
                  ],
                ),
              ),
            ),
          );
        }
      }
      ``` 
      	
      </details>
      
      ### Before
      
      ![Screenshot 2023-07-27 at 14 12 36](https://github.com/flutter/flutter/assets/48603081/1c08a9d2-ac15-4d33-8fa1-c765b4b10f92)
      
      ### After 
      
      ![Screenshot 2023-07-27 at 14 13 12](https://github.com/flutter/flutter/assets/48603081/7e662dfe-9f32-46c9-a128-3024a4782882)
      
      This also contains regression test for https://github.com/flutter/flutter/pull/125974#discussion_r1239089151
      
      ```dart
        // This is a regression test for https://github.com/flutter/flutter/pull/125974#discussion_r1239089151.
        testWidgets('Divider can be constrained', (WidgetTester tester) async {
      ```
      
      ![Screenshot 2023-07-27 at 14 16 37](https://github.com/flutter/flutter/assets/48603081/ac2ef49b-2410-46d0-8ae2-d9b77236abba)
      2c71881f
  19. 01 Aug, 2023 1 commit
  20. 28 Jul, 2023 1 commit
    • Taha Tesser's avatar
      Fix `TimePicker` defaults for `hourMinuteTextStyle` and `dayPeriodTextColor`... · 7d89617a
      Taha Tesser authored
      Fix `TimePicker` defaults for `hourMinuteTextStyle` and `dayPeriodTextColor` for Material 3 (#131253)
      
      fixes [`TimePicker` color and visual issues](https://github.com/flutter/flutter/issues/127035)
      
      ## Description
      
      - fixes default text style for `TimePicker`s  `hourMinuteTextStyle` and added a todo for https://github.com/flutter/flutter/issues/131247
      - fixes correct default color not being accessed for  `dayPeriodTextColor`
      -  Updates tests
      
      ### 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(
            debugShowCheckedModeBanner: false,
            theme: ThemeData(useMaterial3: true),
            home: const Example(),
          );
        }
      }
      
      class Example extends StatelessWidget {
        const Example({super.key});
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: const Text('Sample'),
            ),
            body: Center(
              child: ElevatedButton(
                onPressed: () {
                  showTimePicker(
                    context: context,
                    orientation: Orientation.portrait,
                    initialEntryMode: TimePickerEntryMode.input,
                    initialTime: TimeOfDay.now(),
                    builder: (BuildContext context, Widget? child) {
                      return MediaQuery(
                        data: MediaQuery.of(context)
                            .copyWith(alwaysUse24HourFormat: true),
                        child: child!,
                      );
                    },
                  );
                },
                child: const Text('Open Time Picker'),
              ),
            ),
          );
        }
      }
      
      ``` 
      	
      </details>
      
      ### Before
      
      ![ezgif com-video-to-gif](https://github.com/flutter/flutter/assets/48603081/b791501f-aed3-44f3-8f75-70a1e28038c6)
      
      ### After
      
      ![ezgif com-video-to-gif (1)](https://github.com/flutter/flutter/assets/48603081/1bb32064-a9b1-416d-8290-7d22b0d4fdb9)
      7d89617a
  21. 27 Jul, 2023 1 commit
  22. 24 Jul, 2023 1 commit
  23. 19 Jul, 2023 1 commit
  24. 18 Jul, 2023 1 commit
  25. 17 Jul, 2023 1 commit
    • LongCatIsLooong's avatar
      Replaces `textScaleFactor` with `TextScaler` (#128522) · b2e22d35
      LongCatIsLooong authored
      Deprecate `textScaleFactor` in favor of `textScaler`, in preparation for Android 14 [Non-linear font scaling to 200%](https://developer.android.com/about/versions/14/features#non-linear-font-scaling). The `TextScaler` class can be moved to `dart:ui` in the future, if we decide to use the Android platform API or AndroidX to get the scaling curve instead of hard coding the curve in the framework.
      
      I haven't put the Flutter version in the deprecation message so the analyzer checks are failing. Will do so after I finish the migration guide.
      
      **Why `TextScaler.textScaleFactor`**
      The author of a `TextScaler` subclass should provide a fallback `textScaleFactor`. By making `TextScaler` also contain the `textScaleFactor` information it also makes it easier to migrate: if a widget overrides `MediaQueryData.textScaler` in the tree, for unmigrated widgets in the subtree it would also have to override `MediaQueryData.textScaleFactor`, and that makes it difficult to remove `MediaQueryData.textScaleFactor` in the future.
      
      ## A full list of affected APIs in this PR
      
      Deprecated: The method/getter/setter/argument is annotated with a `@Deprecated()` annotation in this PR, and the caller should replace it with `textScaler` instead. Unless otherwise specified there will be a Flutter fix available to help with migration but it's still recommended to migrate case-by-case.
      **Replaced**:  The method this `textScaleFactor` argument belongs to is rarely called directly by user code and is not overridden by any of the registered custom tests, so the argument is directly replaced by `TextScaler`.
      **To Be Deprecated**:  The method/getter/setter/argument can't be deprecated in this PR because a registered customer test depends on it and a Flutter fix isn't available (or the test was run without applying flutter fixes first). This method/getter/setter/argument will be deprecated in a followup PR once the registered test is migrated.
      
      ### `Painting` Library
      
      | Affected API | State of `textScaleFactor` | Comment | 
      | --- | --- | --- |
      | `InlineSpan.build({ double textScaleFactor = 1.0 })` argument | **Replaced** | | 
      | `TextStyle.getParagraphStyle({ double TextScaleFactor = 1.0 })` argument | **Replaced** | |
      | `TextStyle.getTextStyle({ double TextScaleFactor = 1.0 })`  argument| Deprecated | Can't replace: https://github.com/superlistapp/super_editor/blob/c47fd38dca4b7f43611690913b551a1773c563d7/super_editor/lib/src/infrastructure/super_textfield/desktop/desktop_textfield.dart#L1903-L1905|
      | `TextPainter({ double TextScaleFactor = 1.0 })` constructor argument | Deprecated | |
      | `TextPainter.textScaleFactor` getter and setter | Deprecated | No Flutter Fix, not expressible yet |
      | `TextPainter.computeWidth({ double TextScaleFactor = 1.0 })` argument | Deprecated | |
      | `TextPainter.computeMaxIntrinsicWidth({ double TextScaleFactor = 1.0 })` argument | Deprecated | |
      
      ### `Rendering` Library
      
      | Affected API | State of `textScaleFactor` | Comment | 
      | --- | --- | --- |
      | `RenderEditable({ double TextScaleFactor = 1.0 })` constructor argument | Deprecated | |
      | `RenderEditable.textScaleFactor` getter and setter | Deprecated | No Flutter Fix, not expressible yet |
      | `RenderParagraph({ double TextScaleFactor = 1.0 })` constructor argument | Deprecated | |
      | `RenderParagraph.textScaleFactor` getter and setter | Deprecated | No Flutter Fix, not expressible yet |
      
      ### `Widgets` Library
      
      | Affected API | State of `textScaleFactor` | Comment | 
      | --- | --- | --- |
      | `MediaQueryData({ double TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | https://github.com/flutter/packages/blob/cd7b93532e5cb605a42735e20f1de70fc00adae7/packages/flutter_markdown/test/text_scale_factor_test.dart#LL39C21-L39C35 |
      | `MediaQueryData.textScaleFactor` getter | Deprecated | |
      | `MediaQueryData.copyWith({ double? TextScaleFactor })` argument | Deprecated | |
      | `MediaQuery.maybeTextScaleFactorOf(BuildContext context)` static method | Deprecated | No Flutter Fix, not expressible yet  |
      | `MediaQuery.textScaleFactorOf(BuildContext context)` static method | **To Be Deprecated** | https://github.com/flutter/packages/blob/cd7b93532e5cb605a42735e20f1de70fc00adae7/packages/flutter_markdown/lib/src/_functions_io.dart#L68-L70, No Flutter Fix, not expressible yet |
      | `RichText({ double TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | https://github.com/flutter/packages/blob/cd7b93532e5cb605a42735e20f1de70fc00adae7/packages/flutter_markdown/lib/src/builder.dart#L829-L843 |
      | `RichText.textScaleFactor` getter | **To Be Deprecated** | A constructor argument can't be deprecated right away|
      | `Text({ double? TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | https://github.com/flutter/packages/blob/914d120da12fba458c020210727831c31bd71041/packages/rfw/lib/src/flutter/core_widgets.dart#L647 , No Flutter Fix because of https://github.com/dart-lang/sdk/issues/52664 |
      | `Text.rich({ double? TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | The default constructor has an argument that can't be deprecated right away. No Flutter Fix because of https://github.com/dart-lang/sdk/issues/52664 |
      | `Text.textScaleFactor` getter | **To Be Deprecated** | A constructor argument can't be deprecated right away |
      | `EditableText({ double? TextScaleFactor = 1.0 })` constructor argument | Deprecated | No Flutter Fix because of https://github.com/dart-lang/sdk/issues/52664 |
      | `EditableText.textScaleFactor` getter | Deprecated | |
      
      ### `Material` Library
      
      | Affected API | State of `textScaleFactor` | Comment | 
      | --- | --- | --- |
      | `SelectableText({ double? TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | https://github.com/flutter/packages/blob/cd7b93532e5cb605a42735e20f1de70fc00adae7/packages/flutter_markdown/lib/src/builder.dart#L829-L843, No Flutter Fix because of https://github.com/dart-lang/sdk/issues/52664 |
      | `SelectableText.rich({ double? TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | The default constructor has an argument that can't be deprecated right away. No Flutter Fix because of https://github.com/dart-lang/sdk/issues/52664 |
      | `SelectableText.textScaleFactor` getter | **To Be Deprecated** | A constructor argument can't be deprecated right away |
      
      A lot of material widgets (`Slider`, `RangeSlider`, `TimePicker`, and different types of buttons) also change their layout based on `textScaleFactor`. These need to be handled in a case-by-case fashion and will be migrated in follow-up PRs.
      b2e22d35
  26. 07 Jul, 2023 1 commit
  27. 30 Jun, 2023 1 commit
    • Taha Tesser's avatar
      Fix `NavigationDrawer` selected item has wrong icon color (#129625) · 7cef9661
      Taha Tesser authored
      fixes [NavigationDrawer selected item has wrong icon color [Material3 spec]](https://github.com/flutter/flutter/issues/129572)
      
      ### Description
      This PR fixes a mistake in the `NavigationDrawer` defaults, where generated token value returns a `null`. 
      This issue can be detected when you want to customize the selected icon color for `NavigationDrawerDestination` using a custom color scheme.
      
      ### Code sample
      
      <details> 
      <summary>expanded 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(
            debugShowCheckedModeBanner: false,
            themeMode: ThemeMode.light,
            theme: ThemeData(
              colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue).copyWith(
                onSecondaryContainer: Colors.red,
              ),
              useMaterial3: true,
            ),
            home: const Example(),
          );
        }
      }
      
      class Example extends StatelessWidget {
        const Example({super.key});
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: const Text('NavigationDrawer Sample'),
            ),
            drawer: const NavigationDrawer(
              children: <Widget>[
                NavigationDrawerDestination(
                  icon: Icon(Icons.favorite_outline_rounded),
                  label: Text('Favorite'),
                  selectedIcon: Icon(Icons.favorite_rounded),
                ),
                NavigationDrawerDestination(
                  icon: Icon(Icons.favorite_outline_rounded),
                  label: Text('Favorite'),
                ),
              ],
            ),
          );
        }
      }
      ``` 
      	
      </details>
      
      ### Before
       
      <img width="1053" alt="Screenshot 2023-06-27 at 13 24 38" src="https://github.com/flutter/flutter/assets/48603081/18c13a73-688f-4586-bb60-bddef45d173f">
      
      ### After
      
      <img width="1053" alt="Screenshot 2023-06-27 at 13 24 25" src="https://github.com/flutter/flutter/assets/48603081/8a1427c6-517f-424a-b0bd-24bad7c5fbb0">
      7cef9661
  28. 22 Jun, 2023 2 commits
    • Kate Lovett's avatar
      Revert "Fix Material 3 Scrollable `TabBar`" (#129383) · 087377ea
      Kate Lovett authored
      Reverts flutter/flutter#125974
      087377ea
    • Taha Tesser's avatar
      Fix Material 3 Scrollable `TabBar` (#125974) · 32fde139
      Taha Tesser authored
      fix https://github.com/flutter/flutter/issues/117722
      
      ### Description
      1. Fix the divider doesn't stretch to take all the available width in the scrollable tab bar in M3
      2. Add `dividerHeight` property.
      3. Update the default tab alignment for the scrollable tab bar to match the specs (this is backward compatible for M2 with the new `tabAlignment` property).
      
      ### Bug (default tab alignment)
      
      ![Screenshot 2023-05-05 at 19 04 40](https://user-images.githubusercontent.com/48603081/236509483-1d03af21-a764-4776-acef-2126560f0d51.png)
      
      ### Fix (default tab alignment)
      
      ![Screenshot 2023-05-05 at 19 04 15](https://user-images.githubusercontent.com/48603081/236509513-2426d456-c54f-42bd-9545-a14dc6ee7e69.png)
      
      ### Code sample
      
      <details> 
      <summary>code sample</summary> 
      
      ```dart
      import 'package:flutter/material.dart';
      
      /// Flutter code sample for [TabBar].
      
      void main() => runApp(const TabBarApp());
      
      class TabBarApp extends StatelessWidget {
        const TabBarApp({super.key});
      
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            theme: ThemeData(
              //  tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.start),
                useMaterial3: true,
            ),
            home: const TabBarExample(),
          );
        }
      }
      
      class TabBarExample extends StatefulWidget {
        const TabBarExample({super.key});
      
        @override
        State<TabBarExample> createState() => _TabBarExampleState();
      }
      
      class _TabBarExampleState extends State<TabBarExample> {
        bool rtl = false;
      
        @override
        Widget build(BuildContext context) {
          return DefaultTabController(
            initialIndex: 1,
            length: 3,
            child: Directionality(
              textDirection:  rtl ? TextDirection.rtl : TextDirection.ltr,
              child: Scaffold(
                appBar: AppBar(
                  title: const Text('TabBar Sample'),
                ),
                body: const Column(
                  children: <Widget>[
                    Text('Scrollable-TabAlignment.start'),
                    TabBar(
                      isScrollable: true,
                      tabAlignment: TabAlignment.start,
                      tabs: <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    Text('Scrollable-TabAlignment.startOffset'),
                    TabBar(
                      isScrollable: true,
                      tabAlignment: TabAlignment.startOffset,
                      tabs: <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    Text('Scrollable-TabAlignment.center'),
                    TabBar(
                      isScrollable: true,
                      tabAlignment: TabAlignment.center,
                      tabs: <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    Spacer(),
                    Text('Non-scrollable-TabAlignment.fill'),
                    TabBar(
                      tabAlignment: TabAlignment.fill,
                      tabs: <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    Text('Non-scrollable-TabAlignment.center'),
                    TabBar(
                      tabAlignment: TabAlignment.center,
                      tabs: <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    Spacer(),
                  ],
                ),
                floatingActionButton: FloatingActionButton.extended(
                  onPressed: () {
                    setState(() {
                      rtl = !rtl;
                    });
                  },
                  label: const Text('Switch Direction'),
                  icon: const Icon(Icons.swap_horiz),
                ),
              ),
            ),
          );
        }
      }
      ``` 
      	
      </details>
      
      ![Screenshot 2023-06-06 at 18 06 12](https://github.com/flutter/flutter/assets/48603081/5ee5386d-cc64-4025-a020-ed2222cb6031)
      32fde139
  29. 19 Jun, 2023 1 commit
    • 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
  30. 15 Jun, 2023 1 commit
  31. 12 Jun, 2023 1 commit
  32. 09 Jun, 2023 1 commit
    • Pierre-Louis's avatar
      Improve defaults generation with logging, stats, and token validation (#128244) · 66cda591
      Pierre-Louis authored
      ## Description
      
      This improves defaults generation with logging, stats, and token validation. 
      
      This PR includes these changes:
      * introduce `TokenLogger`, with a verbose mode
        * prints versions and tokens usage to the console
        * outputs `generated/used_tokens.csv`, a list of all used tokens, for use by Google
      * find token files in `data` automatically
      * hide tokens `Map`
        * tokens can be obtained using existing resolvers (e.g. `color`, `shape`), or directly through `getToken`.
        * tokens can be checked for existence with `tokenAvailable`
      * remove version from template, since the tokens are aggregated and multiple versions are possible (as is the case currently), it does not make sense to attribute a single version
      * improve documentation
      
      ## Related Issues
       - Fixes https://github.com/flutter/flutter/issues/122602
      
      ## Tests
       - Added tests for `TokenLogger`
       - Regenerated tokens, no-op except version removal
      
      ## Future work
      A future PR should replace or remove the following invalid tokens usages
      
      <img width="578" alt="image" src="https://github.com/flutter/flutter/assets/6655696/b6f9e5a7-523f-4f72-94f9-1b0bf4cc9f00">
      66cda591
  33. 08 Jun, 2023 1 commit
  34. 06 Jun, 2023 1 commit
  35. 01 Jun, 2023 1 commit