Skip to content

Conversation

@gspencergoog
Copy link
Contributor

@gspencergoog gspencergoog commented Feb 15, 2024

Description

Adds defaults that use tokens to define default iconSize and iconColor values. Previously, the Material 3 token values for button icon sizes and colors were not being used as defaults when the ButtonStyleButton.defaultStyleOf function returned the default values.

Adds tests to make sure appropriate ButtonStyle fields are populated when defaultStyle is called on buttons.

Updated documentation for defaultStyleOf to indicated that not all fields need to be non-null, since some fields make sense to be null (e.g. fixedSize) because they would otherwise override the behavior of other fields in the same ButtonStyle.

Tests

  • Added tests to make sure that the appropriate fields are non-null in the default button styles for each type of button.

@github-actions github-actions bot added a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Feb 15, 2024
Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few quick comments. This all looks good.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original text is a little confusing because "the style returned by [themeStyleOf]" sounds like developers are supposed to override themeStyleOf. What we're really saying is that you can override the style with a button-specific theme, like TextButtonTheme or ElevatedButtonTheme.

Copy link
Contributor Author

@gspencergoog gspencergoog Feb 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I'm not quite sure how to revise it, though. How's this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be better to just leave out the info about [themeStyle]. It's enough to say that you can override a button's style with its style parameter or with a button-specific theme like TextButtonTheme or ElevatedButtonTheme.

Copy link
Contributor

@QuncCccccc QuncCccccc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for the fix! For MenuItemButton, we probably also need to add a default size for icon because from carbon it is still using 24 as the icon size:) This can fix the failed unit test in DropdownMenu.

This icon size token in menu is deprecated and we can use the List leading-icon token(it was 18 as well but with the latest token value, it is updated to 24).
Screenshot 2024-02-15 at 1 13 01 PM
Screenshot 2024-02-15 at 1 14 50 PM

@QuncCccccc
Copy link
Contributor

Looks like ToggleButtons are built on top of TextButton, maybe we can also revert the icon size to 24 and icon color here because they are not part of M3. Then we can fix the failures in toggle_button_test.dart.

@gspencergoog gspencergoog force-pushed the fix_button_icons branch 2 times, most recently from ba19c02 to 1f1fb87 Compare February 15, 2024 22:52
@flutter-dashboard
Copy link

This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@gspencergoog
Copy link
Contributor Author

It also looks like there are Google golden file changes to fix.

@gspencergoog gspencergoog force-pushed the fix_button_icons branch 2 times, most recently from ed22511 to 98de292 Compare July 8, 2024 20:00
@gspencergoog
Copy link
Contributor Author

@QuncCccccc (and cc @Piinks ) I don't have time right now to land this: it requires changes in tests and code in Google code, but I do think it should be landed sometime. I did make cl/650377998 and file b/352768033 as a start. Do you or someone on the Framework team have time to look at it?

@QuncCccccc
Copy link
Contributor

I can put it in my queue and fix failures in G3 gradually:)Thanks for letting me know!

@gspencergoog
Copy link
Contributor Author

Okay, the fixes in Google code are complete, so there should be few if any failures there now.

@gspencergoog
Copy link
Contributor Author

Looks like the remaining issues in Google code are iconSize related.

@QuncCccccc
Copy link
Contributor

Update: waiting for cl/655739008 to land:)

@QuncCccccc
Copy link
Contributor

Once cl/658520909 is landed, I think we are good to go!

@QuncCccccc QuncCccccc added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 2, 2024
@gspencergoog
Copy link
Contributor Author

@QuncCccccc Okay looks like the CL has landed. I updated this PR to HEAD. If the tests pass and you approve, then I can commit it!

Copy link
Contributor

@QuncCccccc QuncCccccc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I thought I already approved this PR. LGTM! Thanks for the fix! Just left several same nits:)

Adds defaults that use tokens to define default `iconSize` and `iconColor` values.

Adds tests to make sure appropriate ButtonStyle fields are populated when defaultStyle is called on buttons.
@auto-submit auto-submit bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 2, 2024
@QuncCccccc QuncCccccc added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 2, 2024
@auto-submit auto-submit bot merged commit 51ed348 into flutter:master Aug 2, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 4, 2024
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Aug 4, 2024
Manual roll requested by [email protected]

flutter/flutter@f10a497...cbfb222

2024-08-04 [email protected] Roll Flutter Engine from 980577996f38 to 16012e2f8ccd (1 revision) (flutter/flutter#152824)
2024-08-03 [email protected] Roll Flutter Engine from 2a51c687fd40 to 980577996f38 (1 revision) (flutter/flutter#152821)
2024-08-03 [email protected] Roll Flutter Engine from 4c868ee85616 to 2a51c687fd40 (2 revisions) (flutter/flutter#152818)
2024-08-03 [email protected] Roll Flutter Engine from afb7007298cc to 4c868ee85616 (2 revisions) (flutter/flutter#152814)
2024-08-03 [email protected] Fix device_os requested in linux_build_test tests (flutter/flutter#152808)
2024-08-03 [email protected] Roll Flutter Engine from 516235e4456b to afb7007298cc (3 revisions) (flutter/flutter#152804)
2024-08-03 [email protected] Fix misunderstanding of properties vs. drone_dimensions in Linux_build_tests (flutter/flutter#152796)
2024-08-03 [email protected] Roll Flutter Engine from 3c9d7e3f7c02 to 516235e4456b (3 revisions) (flutter/flutter#152790)
2024-08-03 [email protected] Improve `CupertinoRadio` fidelity (flutter/flutter#149703)
2024-08-03 [email protected] Roll Flutter Engine from 353c6b237b78 to 3c9d7e3f7c02 (3 revisions) (flutter/flutter#152777)
2024-08-02 [email protected] Fix handling of `iconSize` and `iconColor` defaults for `ButtonStyleButton` subclasses. (flutter/flutter#143501)
2024-08-02 [email protected] Use print logging on LUCI. (flutter/flutter#152776)
2024-08-02 [email protected] Reland: Shift Linux_build_test tests from MotoG4 to mokey (flutter/flutter#152756)
2024-08-02 [email protected] Write more on Animation and related docs (flutter/flutter#150727)
2024-08-02 [email protected] Quick Grammar Fixes  (flutter/flutter#152744)
2024-08-02 [email protected] Roll Flutter Engine from 077b6f057b69 to 353c6b237b78 (3 revisions) (flutter/flutter#152762)
2024-08-02 [email protected] [SliderTheme] Fix markdown links for api doc images (flutter/flutter#152748)
2024-08-02 [email protected] Make the App's title optional on web (flutter/flutter#152003)
2024-08-02 [email protected] Add tests for scaffold messenger state (flutter/flutter#152735)
2024-08-02 [email protected] Ignore both unused_element and unused_element_parameter (flutter/flutter#152689)
2024-08-02 [email protected] Update dartdoc to 8.0.12 to fix focusing search field (flutter/flutter#151576)
2024-08-02 [email protected] [wiki] Remove outdated warning about stale coverage data (flutter/flutter#152560)
2024-08-02 [email protected] Roll Packages from 27896d1 to cc9ff47 (8 revisions) (flutter/flutter#152754)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
TytaniumDev pushed a commit to TytaniumDev/flutter that referenced this pull request Aug 7, 2024
…utton` subclasses. (flutter#143501)

## Description

Adds defaults that use tokens to define default `iconSize` and `iconColor` values. Previously, the Material 3 token values for button icon sizes and colors were not being used as defaults when the `ButtonStyleButton.defaultStyleOf` function returned the default values.

Adds tests to make sure appropriate `ButtonStyle` fields are populated when defaultStyle is called on buttons.

Updated documentation for `defaultStyleOf` to indicated that not _all_ fields need to be non-null, since some fields make sense to be null (e.g. `fixedSize`) because they would otherwise override the behavior of other fields in the same `ButtonStyle`.

## Tests
 - Added tests to make sure that the appropriate fields are non-null in the default button styles for each type of button.
Buchimi pushed a commit to Buchimi/flutter that referenced this pull request Sep 2, 2024
…utton` subclasses. (flutter#143501)

## Description

Adds defaults that use tokens to define default `iconSize` and `iconColor` values. Previously, the Material 3 token values for button icon sizes and colors were not being used as defaults when the `ButtonStyleButton.defaultStyleOf` function returned the default values.

Adds tests to make sure appropriate `ButtonStyle` fields are populated when defaultStyle is called on buttons.

Updated documentation for `defaultStyleOf` to indicated that not _all_ fields need to be non-null, since some fields make sense to be null (e.g. `fixedSize`) because they would otherwise override the behavior of other fields in the same `ButtonStyle`.

## Tests
 - Added tests to make sure that the appropriate fields are non-null in the default button styles for each type of button.
@chrisbobbe
Copy link
Contributor

After this change, if you pass a custom foregroundColor but you don't pass an iconColor, then the icon won't be your chosen custom color, right? Is this intended? If so, it seems like we should update the dartdoc on those fields:

-  /// The color for the button's [Text] and [Icon] widget descendants.
+  /// The color for the button's [Text] widget descendants.
   ///
   /// This color is typically used instead of the color of the [textStyle]. All
   /// of the components that compute defaults from [ButtonStyle] values
   /// compute a default [foregroundColor] and use that instead of the
   /// [textStyle]'s color.
   final MaterialStateProperty<Color?>? foregroundColor;
   /// The icon's color inside of the button.
-  ///
-  /// If this is null, the icon color will be [foregroundColor].
   final MaterialStateProperty<Color?>? iconColor;

chrisbobbe added a commit to chrisbobbe/zulip-flutter that referenced this pull request Sep 4, 2024
After sweeping through the message-list screen to implement dark
theme (zulip#843), in late July, the Flutter framework merged
flutter/flutter#143501, in early August. This made it so our
`foregroundColor` no longer controlled the icon color, as promised
in the dartdocs of `foregroundColor` and `iconColor`. I commented
about this on the PR:
  flutter/flutter#143501 (comment)

Fixes: zulip#926
chrisbobbe added a commit to chrisbobbe/zulip-flutter that referenced this pull request Sep 4, 2024
After sweeping through the message-list screen to implement dark
theme (zulip#843), in late July, the Flutter framework merged
flutter/flutter#143501, in early August. This made it so our
`foregroundColor` no longer controlled the icon color, as promised
in the dartdocs of `foregroundColor` and `iconColor`. I commented
about this on that Flutter PR thread just now:
  flutter/flutter#143501 (comment)

Fixes: zulip#926
chrisbobbe added a commit to chrisbobbe/zulip-flutter that referenced this pull request Sep 4, 2024
After sweeping through the message-list screen to implement dark
theme (zulip#843), in late July, the Flutter framework merged
flutter/flutter#143501, in early August. This made it so our
`foregroundColor` no longer controlled the icon color, as promised
in the dartdocs of `foregroundColor` and `iconColor`.

I opened an issue for Flutter about the inconsistency with the doc:
  flutter/flutter#154644
and sent a PR to resolve it, by updating the doc (which the author
of 143501 had said was the right fix):
  flutter/flutter#154646

Fixes: zulip#926
auto-submit bot pushed a commit that referenced this pull request Sep 6, 2024
…154646)

Fixes #154644.

This aligns these dartdocs with the new behavior introduced in PR #143501 / 51ed348, where passing `iconColor: null` would cause the icon to be colored with a hard-coded default instead of with `foregroundColor`.
gnprice pushed a commit to chrisbobbe/zulip-flutter that referenced this pull request Sep 9, 2024
After sweeping through the message-list screen to implement dark
theme (zulip#843), in late July, the Flutter framework merged
flutter/flutter#143501, in early August. This made it so our
`foregroundColor` no longer controlled the icon color, as promised
in the dartdocs of `foregroundColor` and `iconColor`.

I opened an issue for Flutter about the inconsistency with the doc:
  flutter/flutter#154644
and sent a PR to resolve it, by updating the doc (which the author
of 143501 had said was the right fix):
  flutter/flutter#154646

Fixes: zulip#926
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 12, 2024
@rydmike
Copy link
Contributor

rydmike commented Feb 7, 2025

This PR introduced a big regression and breaking change in all past behavior of iconColor respecting foregroundColor if not defined.

Why was it allowed to pass like this so lightly? Introducing the support for defaults could very well have also supported past expected icon color behavior.

This PR broke a lot of styling after upgrading to Flutter 3.27 and was not mentioned as a breaking change, when it clearly was, but did not need to be. See #162839 and fix PR #162880

github-merge-queue bot pushed a commit that referenced this pull request Feb 13, 2025
Fixes [Flutter 3.27 and later breaks past styling and theming of icon
color on buttons with
icons](#162839)

### Description

This PR fixes how the icon color is resolved in `ButtonStyleButton`.
This was regressed in #143501.

### Code Sample (taken from issue)

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

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

void main() => runApp(const MyApp());

final ButtonStyle filledButtonStyle = FilledButton.styleFrom(
  foregroundColor: Colors.red,
  backgroundColor: Colors.grey,
);

final ButtonStyle elevatedButtonStyle = ElevatedButton.styleFrom(
  foregroundColor: Colors.orange.shade600,
  backgroundColor: Colors.blueGrey,
);

final ButtonStyle outlinedButtonStyle = OutlinedButton.styleFrom(
  foregroundColor: Colors.lightBlue,
);

final ButtonStyle textButtonStyle = TextButton.styleFrom(
  foregroundColor: Colors.green,
);

final ButtonStyle segmentedButtonStyle = SegmentedButton.styleFrom(
  selectedForegroundColor: Colors.tealAccent.shade700,
);

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

  @OverRide
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const HomePage(),
      theme: ThemeData(
        filledButtonTheme: FilledButtonThemeData(
          style: filledButtonStyle,
        ),
        elevatedButtonTheme: ElevatedButtonThemeData(
          style: elevatedButtonStyle,
        ),
        outlinedButtonTheme: OutlinedButtonThemeData(
          style: outlinedButtonStyle,
        ),
        textButtonTheme: TextButtonThemeData(
          style: textButtonStyle,
        ),
        segmentedButtonTheme: SegmentedButtonThemeData(
          style: segmentedButtonStyle,
        ),
      ),
    );
  }
}

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

  @OverRide
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Button Icon Color Issue')),
      body: Center(
        child: Column(
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                FilledButton.icon(
                  label: const Text('Filled Themed'),
                  icon: const Icon(Icons.add),
                  onPressed: () {},
                ),
                const SizedBox(width: 8),
                FilledButton.icon(
                  style: filledButtonStyle.copyWith(
                    foregroundColor: WidgetStateProperty.all(Colors.yellow),
                  ),
                  label: const Text('Filled Styled'),
                  icon: const Icon(Icons.add),
                  onPressed: () {},
                ),
              ],
            ),
            const SizedBox(height: 8),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton.icon(
                  label: const Text('Elevated Themed'),
                  icon: const Icon(Icons.add),
                  onPressed: () {},
                ),
                const SizedBox(width: 8),
                ElevatedButton.icon(
                  style: elevatedButtonStyle.copyWith(
                    foregroundColor: WidgetStateProperty.all(Colors.lime),
                  ),
                  label: const Text('Elevated Styled'),
                  icon: const Icon(Icons.add),
                  onPressed: () {},
                ),
              ],
            ),
            const SizedBox(height: 8),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                OutlinedButton.icon(
                  label: const Text('Outlined Themed'),
                  icon: const Icon(Icons.add),
                  onPressed: () {},
                ),
                const SizedBox(width: 8),
                OutlinedButton.icon(
                  style: outlinedButtonStyle.copyWith(
                    foregroundColor: WidgetStateProperty.all(Colors.deepOrange),
                  ),
                  label: const Text('Outlined Styled'),
                  icon: const Icon(Icons.add),
                  onPressed: () {},
                ),
              ],
            ),
            const SizedBox(height: 8),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                TextButton.icon(
                  label: const Text('Text Themed'),
                  icon: const Icon(Icons.add),
                  onPressed: () {},
                ),
                const SizedBox(width: 8),
                TextButton.icon(
                  style: textButtonStyle.copyWith(
                    foregroundColor: WidgetStateProperty.all(Colors.pink),
                  ),
                  label: const Text('Text Styled'),
                  icon: const Icon(Icons.add),
                  onPressed: () {},
                ),
              ],
            ),
            const SizedBox(height: 8),
            const SegmentedButtonShowcase(),
          ],
        ),
      ),
    );
  }
}

class SegmentedButtonShowcase extends StatefulWidget {
  const SegmentedButtonShowcase({this.showOutlinedButton, super.key});
  final bool? showOutlinedButton;

  @OverRide
  State<SegmentedButtonShowcase> createState() =>
      _SegmentedButtonShowcaseState();
}

enum Calendar { day, week, month, year }

class _SegmentedButtonShowcaseState extends State<SegmentedButtonShowcase> {
  Calendar _selected = Calendar.day;

  @OverRide
  Widget build(BuildContext context) {
    return SegmentedButton<Calendar>(
      segments: const <ButtonSegment<Calendar>>[
        ButtonSegment<Calendar>(
          value: Calendar.day,
          label: Text('Day'),
          icon: Icon(Icons.calendar_view_day),
        ),
        ButtonSegment<Calendar>(
          value: Calendar.week,
          icon: Icon(Icons.calendar_view_week),
          label: Text('Week'),
        ),
        ButtonSegment<Calendar>(
          value: Calendar.month,
          icon: Icon(Icons.calendar_view_month),
          label: Text('Mont'),
        ),
        ButtonSegment<Calendar>(
          value: Calendar.year,
          icon: Icon(Icons.calendar_today),
          label: Text('Year'),
        ),
      ],
      selected: <Calendar>{_selected},
      onSelectionChanged: (Set<Calendar> selected) {
        setState(() {
          _selected = selected.first;
        });
      },
    );
  }
}

```

</details>

### Before

<img width="631" alt="Screenshot 2025-02-07 at 17 45 46"
src="https://github.com/user-attachments/assets/d40b1c4b-9952-4e11-8295-8a04bbaa7d74"
/>

### After


<img width="631" alt="Screenshot 2025-02-07 at 17 45 37"
src="https://github.com/user-attachments/assets/d308756e-83f2-42da-bc8d-e958d9f4bec5"
/>

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: text input Entering text in a text field or keyboard related problems autosubmit Merge PR when tree becomes green via auto submit App f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants