Skip to content

Conversation

@kerberjg
Copy link
Contributor

@kerberjg kerberjg commented Aug 4, 2024

This PR fixes #92525 and introduces the following changes according to latest iOS HIG:

  • CupertinoButton now has a size property (type enum CupertinoButtonSize, values sm/md/lg, default lg) that allows the devs to apply new iOS 15+ button styles
  • Previously CupertinoButton had a larger padding when no background color was specified. With the new HIG, that is no longer the case
  • CupertinoButton now has a .tinted constructor that renders a translucent background (transparency % is brightness-dependent) and uses a different foreground color compared to .filled
  • CupertinoButton now uses the actionTextStyle TextStyle from the given theme
  • CupertinoButton's child IconTheme's size will always be x1.2 the given TextStyle's size
  • CupertinoTextThemeData now has a actionSmallTextStyle property to use with small buttons (including a default _kDefaultActionSmallTextStyle TextStyle)

Preview & example:

image

NOTE: there is a discrepancy in dark mode button foreground color between the default CupertinoTheme and the HIG. A separate issue will be opened for this.

EDIT: issue reported here #152846
EDIT2: fixed by #153039 !

image

Example

import 'package:flutter/cupertino.dart';

const Widget body = Row(
  mainAxisSize: MainAxisSize.min,
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Icon(
      CupertinoIcons.play_fill,
    ),
    Text("Play"),
  ],
);

void main() =>
  runApp(
    CupertinoApp(
      home: Container(
        child: Wrap(
        direction: Axis.horizontal,
        children: <Widget>[
          // header
          Text(''),
          Text('Plain'),
          Text('Grey'),
          Text('Tinted'),
          Text('Filled'),
          // small
          Text('Small'),
          CupertinoButton(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
            color: CupertinoColors.systemGrey,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
          ),
          CupertinoButton.filled(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
          ),
          // medium
          Text('Medium'),
          CupertinoButton(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
            color: CupertinoColors.systemGrey,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
          ),
          CupertinoButton.filled(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
          ),
          // large
          Text('Large'),
          CupertinoButton(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.large,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            color: CupertinoColors.systemGrey,
            size: CupertinoButtonSize.large,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.large,
          ),
          CupertinoButton.filled(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.large,
          ),
        ].map((Widget w) => SizedBox(width: 110, height: 70, child: Center(child: w))).toList(),
      ),
      )
    ),
  );

List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.

If you had to change anything in the flutter/tests repo, include a link to the migration guide as per the breaking change policy.

Pre-launch Checklist

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

@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: cupertino flutter/packages/flutter/cupertino repository labels Aug 4, 2024
@kerberjg kerberjg marked this pull request as draft August 4, 2024 22:53
@flutter-dashboard
Copy link

This pull request has been changed to a draft. The currently pending flutter-gold status will not be able to resolve until a new commit is pushed or the change is marked ready for review again.

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.

@MitchellGoodwin MitchellGoodwin self-requested a review August 5, 2024 17:05
@Piinks Piinks added the a: fidelity Matching the OEM platforms better label Aug 5, 2024
Copy link
Contributor

@MitchellGoodwin MitchellGoodwin left a comment

Choose a reason for hiding this comment

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

These look great! I did a first pass at the implementation without going too deep into the details, and made some comments.

I like all of the styling values be in maps for the different size styles at the top. It makes it easy to look through and update the values later if HIGs changes. Just throwing an idea out here, but I wonder if instead of splitting up maps by property type, like _kCupertinoButtonSizeBorderRadius and _kCupertinoButtonMinSize, we instead of have something like Material's ButtonStyle, and we have something like a CupertinoButtonStyle class that contains all of the properties for each configuration in one place, for the different sizes as well as filled, outlined and so on. It might be a little bit easier to search through or use in other widgets if needed. The button could then have a _style property that gets set based on the constructor and properties. For instance for a filled button of medium size, it does something like this

_style = CupertinoButtonStyle.filled.mergeWith(CupertinoButtonStyle.medium)

Then throughout the code it can just check with the one _style collection rather than having to do multiple checks for the button type.

final Color? backgroundColor =  _style.backgroundColor

@kerberjg
Copy link
Contributor Author

kerberjg commented Aug 7, 2024

@MitchellGoodwin Thanks for the review! I agree it would be good to have a CupertinoButtonStyle, also because that's be closer to how iOS' UIButton works - I think it'd be worthwhile to open a separate issue/PR to handle that properly, and for now just introduce a minimal HIG-compliant version of the new properties in this one.

I addressed some of your feedback in the latest commits and left you some questions on others

Copy link
Contributor

@MitchellGoodwin MitchellGoodwin left a comment

Choose a reason for hiding this comment

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

Looks like at least one test is failing for the button, and there's some analyzer issues. Take a look at the 'Linux Analyze' check for the analyzer. That check isn't too bad to look through, but let me know if you have issues finding other errors. The checks can be a slog to look through until you are used to it.

@MitchellGoodwin
Copy link
Contributor

for now just introduce a minimal HIG-compliant version of the new properties in this one.

Let's do that. On a second look, I think this implementation is more than sufficient.

@github-actions github-actions bot added d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos labels Aug 7, 2024
@kerberjg kerberjg marked this pull request as ready for review August 7, 2024 19:11
@flutter-dashboard
Copy link

Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change).

If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review.

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.

Changes reported for pull request #152845 at sha ee97f83

@flutter-dashboard flutter-dashboard bot added the will affect goldens Changes to golden files label Aug 7, 2024
this.sizeStyle = CupertinoButtonSize.large,
this.padding,
this.color,
this.disabledColor = CupertinoColors.quaternarySystemFill,
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this default disabled color also match native iOS in dark mode? If not, consider using CupertinoDynamicColor.resolve to make it resolve differently in light vs. dark modes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Screenshot 2024-08-08 at 11 15 50 AM

If I'm understanding figma correctly, it looks like they are different.

Copy link
Contributor

@MitchellGoodwin MitchellGoodwin left a comment

Choose a reason for hiding this comment

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

Thank you for the update! Left some comments.

@kerberjg kerberjg force-pushed the feature/cupertino-buttons-ios15 branch 2 times, most recently from 42fe7d8 to 22f8f75 Compare August 9, 2024 12:29
Copy link
Contributor

@MitchellGoodwin MitchellGoodwin left a comment

Choose a reason for hiding this comment

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

Left some nits. This is getting close. Sorry if this is a slog, there's a lot of process around public style changes like this.

CupertinoButton now takes a [size] property that allows it to be sized small/medium/large as per iOS 17 style guidelines

This obsoletes the previous behavior where, if a CupertinoButton had no background, it would have a larger padding.
Now padding is set based on the [size] property as derived from iOS HIG.
Adds a 'tinted' variant to CupertinoButton as per iOS 17 HIG.
@kerberjg kerberjg force-pushed the feature/cupertino-buttons-ios15 branch from 22f8f75 to c882e0c Compare August 9, 2024 21:37
@kerberjg
Copy link
Contributor Author

kerberjg commented Aug 9, 2024

@MitchellGoodwin no worries! It's a good opportunity to learn, now I know what to watch out for next time :)

I rebased on main and pushed the latest changes based on your feedback.

Earlier the CI reported a mismatch with the goldens due to the default icon size change, shall I go ahead and just update them?

@MitchellGoodwin
Copy link
Contributor

Earlier the CI reported a mismatch with the goldens due to the default icon size change, shall I go ahead and just update them?

I think you need to be a member of flutter-hackers to be able to approve golden file differences, so one of us will approve them. Typically I like to wait until the PR is in a done state before I approve them. When I looked at them before the differences were all as expected.

@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

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.

Changes reported for pull request #152845 at sha c882e0c

Copy link
Contributor

@victorsanni victorsanni left a comment

Choose a reason for hiding this comment

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

A couple of nits, but this is close to landing. Thanks once again for the patience.

@kerberjg
Copy link
Contributor Author

kerberjg commented Aug 9, 2024

Nits addressed

Deploy Fridays, let's go!

@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

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.

Changes reported for pull request #152845 at sha be4ddb9

Figma file for:
- `_kDefaultActionTextStyle`
- `_kDefaultActionSmallTextStyle`
@kerberjg kerberjg force-pushed the feature/cupertino-buttons-ios15 branch from be4ddb9 to 3bf246a Compare August 11, 2024 16:49
@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

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.

Changes reported for pull request #152845 at sha 3bf246a

Copy link
Contributor

@MitchellGoodwin MitchellGoodwin left a comment

Choose a reason for hiding this comment

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

LGTM as well! Thank you very much!

@MitchellGoodwin
Copy link
Contributor

Golden file differences were as expected from the different default styling.

@MitchellGoodwin MitchellGoodwin added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 12, 2024
@auto-submit auto-submit bot merged commit dae3a87 into flutter:master Aug 12, 2024
@kerberjg
Copy link
Contributor Author

Thank you too! It was good practice to get this one merged, on to the next one! 😊

engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 13, 2024
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Aug 13, 2024
Manual roll requested by [email protected]

flutter/flutter@814e49b...2afc452

2024-08-13 [email protected] Roll Flutter Engine from adb1fa9fdbcf to 9054eb43aa26 (2 revisions) (flutter/flutter#153338)
2024-08-13 [email protected] Roll Flutter Engine from af68e772d298 to adb1fa9fdbcf (2 revisions) (flutter/flutter#153336)
2024-08-13 [email protected] Roll Flutter Engine from 07ecd90b7755 to af68e772d298 (3 revisions) (flutter/flutter#153332)
2024-08-13 [email protected] Add fake dependency on flutter_gpu for the docs (flutter/flutter#153325)
2024-08-13 [email protected] Roll Flutter Engine from 5d8ee52e985b to 07ecd90b7755 (7 revisions) (flutter/flutter#153326)
2024-08-12 [email protected] Make CupertinoButton interactive by keyboard shortcuts (flutter/flutter#153126)
2024-08-12 [email protected] Added FlutterEngineGroups to engine architecture doc (flutter/flutter#153100)
2024-08-12 [email protected] Roll Flutter Engine from bcf2dcc09a13 to 5d8ee52e985b (4 revisions) (flutter/flutter#153313)
2024-08-12 [email protected] Disable DevTools when running the hot restart integration test in flutter_tools (flutter/flutter#153247)
2024-08-12 [email protected] Implemented CupertinoButton new styles/sizes (fixes #92525) (flutter/flutter#152845)
2024-08-12 [email protected] Roll pub packages (flutter/flutter#153297)
2024-08-12 [email protected] Refactor: Deprecate inactiveColor from cupertino checkbox (flutter/flutter#152981)

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],[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
DBowen33 pushed a commit to DBowen33/flutter that referenced this pull request Aug 16, 2024
…lutter#152845)

This PR fixes flutter#92525 and introduces the following changes according to [latest iOS HIG](https://developer.apple.com/design/human-interface-guidelines/buttons#iOS-iPadOS):

- `CupertinoButton` now has a `size` property (type `enum CupertinoButtonSize`, values sm/md/lg, default `lg`) that allows the devs to apply new iOS 15+ button styles
- Previously `CupertinoButton` had a larger padding when no background color was specified. With the new HIG, that is no longer the case
- `CupertinoButton` now has a `.tinted` constructor that renders a translucent background (transparency % is brightness-dependent) and uses a different foreground color compared to `.filled`
- `CupertinoButton` now uses the `actionTextStyle` TextStyle from the given theme
- `CupertinoButton`'s child IconTheme's size will always be x1.2 the given TextStyle's size
- `CupertinoTextThemeData` now has a `actionSmallTextStyle` property to use with small buttons (including a default `_kDefaultActionSmallTextStyle` TextStyle)

Preview & example:

![image](https://github.com/user-attachments/assets/0985eb19-c091-41f5-bd98-0de196b7e403)

> **NOTE**: there is a discrepancy in dark mode button foreground color between the default CupertinoTheme and the HIG. A separate issue will be opened for this.

~EDIT: issue reported here flutter#152846
EDIT2: fixed by flutter#153039 !

![image](https://github.com/user-attachments/assets/d671d7b4-bb2f-4b38-9464-ee1b04927304)

## Example
```dart
import 'package:flutter/cupertino.dart';

const Widget body = Row(
  mainAxisSize: MainAxisSize.min,
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Icon(
      CupertinoIcons.play_fill,
    ),
    Text("Play"),
  ],
);

void main() =>
  runApp(
    CupertinoApp(
      home: Container(
        child: Wrap(
        direction: Axis.horizontal,
        children: <Widget>[
          // header
          Text(''),
          Text('Plain'),
          Text('Grey'),
          Text('Tinted'),
          Text('Filled'),
          // small
          Text('Small'),
          CupertinoButton(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
            color: CupertinoColors.systemGrey,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
          ),
          CupertinoButton.filled(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
          ),
          // medium
          Text('Medium'),
          CupertinoButton(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
            color: CupertinoColors.systemGrey,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
          ),
          CupertinoButton.filled(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
          ),
          // large
          Text('Large'),
          CupertinoButton(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.large,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            color: CupertinoColors.systemGrey,
            size: CupertinoButtonSize.large,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.large,
          ),
          CupertinoButton.filled(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.large,
          ),
        ].map((Widget w) => SizedBox(width: 110, height: 70, child: Center(child: w))).toList(),
      ),
      )
    ),
  );

```

*List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.*

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
Buchimi pushed a commit to Buchimi/flutter that referenced this pull request Sep 2, 2024
…lutter#152845)

This PR fixes flutter#92525 and introduces the following changes according to [latest iOS HIG](https://developer.apple.com/design/human-interface-guidelines/buttons#iOS-iPadOS):

- `CupertinoButton` now has a `size` property (type `enum CupertinoButtonSize`, values sm/md/lg, default `lg`) that allows the devs to apply new iOS 15+ button styles
- Previously `CupertinoButton` had a larger padding when no background color was specified. With the new HIG, that is no longer the case
- `CupertinoButton` now has a `.tinted` constructor that renders a translucent background (transparency % is brightness-dependent) and uses a different foreground color compared to `.filled`
- `CupertinoButton` now uses the `actionTextStyle` TextStyle from the given theme
- `CupertinoButton`'s child IconTheme's size will always be x1.2 the given TextStyle's size
- `CupertinoTextThemeData` now has a `actionSmallTextStyle` property to use with small buttons (including a default `_kDefaultActionSmallTextStyle` TextStyle)

Preview & example:

![image](https://github.com/user-attachments/assets/0985eb19-c091-41f5-bd98-0de196b7e403)

> **NOTE**: there is a discrepancy in dark mode button foreground color between the default CupertinoTheme and the HIG. A separate issue will be opened for this.

~EDIT: issue reported here flutter#152846
EDIT2: fixed by flutter#153039 !

![image](https://github.com/user-attachments/assets/d671d7b4-bb2f-4b38-9464-ee1b04927304)

## Example
```dart
import 'package:flutter/cupertino.dart';

const Widget body = Row(
  mainAxisSize: MainAxisSize.min,
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Icon(
      CupertinoIcons.play_fill,
    ),
    Text("Play"),
  ],
);

void main() =>
  runApp(
    CupertinoApp(
      home: Container(
        child: Wrap(
        direction: Axis.horizontal,
        children: <Widget>[
          // header
          Text(''),
          Text('Plain'),
          Text('Grey'),
          Text('Tinted'),
          Text('Filled'),
          // small
          Text('Small'),
          CupertinoButton(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
            color: CupertinoColors.systemGrey,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
          ),
          CupertinoButton.filled(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.small,
          ),
          // medium
          Text('Medium'),
          CupertinoButton(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
            color: CupertinoColors.systemGrey,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
          ),
          CupertinoButton.filled(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.medium,
          ),
          // large
          Text('Large'),
          CupertinoButton(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.large,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            color: CupertinoColors.systemGrey,
            size: CupertinoButtonSize.large,
          ),
          CupertinoButton.tinted(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.large,
          ),
          CupertinoButton.filled(
            child: body,
            onPressed: () {},
            size: CupertinoButtonSize.large,
          ),
        ].map((Widget w) => SizedBox(width: 110, height: 70, child: Center(child: w))).toList(),
      ),
      )
    ),
  );

```

*List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.*

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: fidelity Matching the OEM platforms better a: text input Entering text in a text field or keyboard related problems autosubmit Merge PR when tree becomes green via auto submit App d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: cupertino flutter/packages/flutter/cupertino repository framework flutter/packages/flutter repository. See also f: labels. will affect goldens Changes to golden files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Cupertino] Add new iOS 15 button styles for CupertinoButton

4 participants