Skip to content

Conversation

@MitchellGoodwin
Copy link
Contributor

@MitchellGoodwin MitchellGoodwin commented Mar 8, 2023

Addresses: #61789.

Adds a macOS/iOS styled checkbox widget to Cupertino. Works with keyboard focus, and keyboard interactions. The goal is to make this widget adaptable with the Material Checkbox.

Notably SwiftUI does not provide checkboxes for iOS development, only macOS, so our comparison tool could not be used. So we have to compare with desktop checkboxes and the checkboxes in the Human Interface Guidelines.

Some screenshots of the checkbox in the macOS settings, and from the Human Interface Guidelines:
Screenshot 2023-03-08 at 3 03 44 PM
Screenshot 2023-03-08 at 3 02 39 PM
Screenshot 2023-03-08 at 3 02 34 PM
Screenshot 2023-03-08 at 3 02 29 PM

Here is the CupertinoCheckbox in action, both with mouse and keyboard interactions:

Screen.Recording.2023-03-08.at.3.06.53.PM.mov

Pre-launch Checklist

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

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

@flutter-dashboard flutter-dashboard bot added f: cupertino flutter/packages/flutter/cupertino repository framework flutter/packages/flutter repository. See also f: labels. labels Mar 8, 2023
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not confident on the wording here. I would like to warn developers of Apple's guidance, without discouraging them from doing what they would like to do.

@MitchellGoodwin MitchellGoodwin marked this pull request as ready for review March 8, 2023 23:52
@guidezpl
Copy link
Member

guidezpl commented Mar 9, 2023

@bernaferrari
Copy link
Contributor

bernaferrari commented Mar 9, 2023

@GroovinChip might be the best person to give feedback on this, he made the macOS checkbox on Flutter.

Copy link
Contributor

@gspencergoog gspencergoog left a comment

Choose a reason for hiding this comment

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

Just made an initial pass. Mostly it looks pretty good.

Comment on lines 26 to 29
Copy link
Contributor

Choose a reason for hiding this comment

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

How about this?

Suggested change
/// Note: in the Apple ecosystem, checkboxes are encouraged to only be used in
/// macOS, not iOS. If a multi-selection component is needed, iOS encourages the
/// developer to use Switches, or [CupertinoSwitch] instead, or find a creative
/// custom solution.
/// In the Apple Human Interface Guidelines (HIG), checkboxes are encouraged for use on macOS, but not on iOS.
/// If a multi-selection component is needed on iOS, the HIG encourages the developer to use switches ([CupertinoSwitch] in Flutter)
/// instead, or to find a creative custom solution.

Does it actively discourage checkboxes on iOS? If not, then I'd just say that "but is silent about their use on iOS".

And probably link the appropriate HIG guidelines. Also note that (lol!) our style guide discourages empty prose like "Note" "Note that", etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

Does it assert? If so, you should mention that it asserts in debug mode.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// true this callback cycle from false to true to null.
/// true this callback cycle from false to true to null and back to false again.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also mention if it asserts in debug mode.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// If this property is null, then the side will be width 1.
/// If this property is null, then the side defaults to a width of 1.

Copy link
Contributor

@gspencergoog gspencergoog Mar 10, 2023

Choose a reason for hiding this comment

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

Why can't these use locations for this use CupertinoCheckbox.width directly? It is also a const, and would show where it comes from.

Copy link
Contributor

@gspencergoog gspencergoog Mar 10, 2023

Choose a reason for hiding this comment

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

These numbers in the offsets should be converted to constants to make it easier to read/understand them. Or you could comment on how the values are derived right here in a comment if this is the only instance of the number.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// A mixin for [StatefulWidget]s that implement ios-themed toggleable
/// A mixin for [StatefulWidget]s that implement iOS-themed toggleable

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// The mixin implements the logic for toggling the control (e.g. when tapped).
/// The mixin implements the logic for toggling the control when tapped.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// This mixin is used to implement the cupertino components for [Checkbox]
/// This mixin is used to implement the Cupertino components for [Checkbox]

Copy link
Contributor

Choose a reason for hiding this comment

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

Remove extra blank line

Copy link
Contributor

Choose a reason for hiding this comment

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

Adaptive widgets don't need to be the same size, and I think it's probably better to have it conform to the standard interactive size for Cupertino, since that should fit better with other Cupertino widgets. It's not much different anyhow.

@MitchellGoodwin MitchellGoodwin force-pushed the create-cupertino-checkbox branch from b501bdf to 9beffb6 Compare March 10, 2023 19:35
Comment on lines 119 to 120
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// The color used if the checkbox is inactive. By default,
/// [CupertinoColors.inactiveGray] is used.
/// The color used if the checkbox is inactive.
///
/// By default, [CupertinoColors.inactiveGray] is used.

The first paragraph is used as a short description in the docs, and should only be one sentence long.

https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#dartdoc-specific-requirements

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// The ratios for the offsets below where found from looking at the checkbox
// The ratios for the offsets below were found from looking at the checkbox

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// A mixin for [StatefulWidget]s that implement iOS-themed toggleable
/// A mixin for [StatefulWidget]s that implements iOS-themed toggleable

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// controls (e.g.[Checkbox]es).
/// controls (e.g. [CupertinoCheckbox]es).

Or describe how this class relates to the Material Checkbox.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// The mixin implements the logic for toggling the control when tapped.
/// This mixin implements the logic for toggling the control when tapped.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// If value is true then the control "active" (checked, on, or selected). If
/// If [value] is true then the control "active" (checked, on, or selected). If

Copy link
Contributor

Choose a reason for hiding this comment

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

You can remove this entire function, since it's only calling super.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// the Toggleable. In their [paint] method subclasses may call
/// the Toggleable. In their [paint] method, subclasses may call

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm going to remove this sentence entirely, because I missed that I had deleted the method this is referring too.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// If true the checkbox's [value] can be true, false, or null.
/// If true, the checkbox's [value] can be true, false, or null.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// If tristate is false (the default), [value] is asseted to not be null.
/// If tristate is false (the default), [value] must not be null, and [onChanged] will only toggle between true and false.

@MitchellGoodwin MitchellGoodwin force-pushed the create-cupertino-checkbox branch from 9beffb6 to 0810582 Compare March 17, 2023 16:48
@MitchellGoodwin
Copy link
Contributor Author

@gspencergoog this is ready for review again 👍

@MitchellGoodwin MitchellGoodwin force-pushed the create-cupertino-checkbox branch from 3916a7b to 9a5eec2 Compare March 20, 2023 16:18
Copy link
Contributor

@gspencergoog gspencergoog left a comment

Choose a reason for hiding this comment

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

32384589-a60f0e74-c078-11e7-9bc1-e5b5287aea9d

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe describe what this is a link to? (or make it into an actual Markdown link to the descriptive text?)

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Creates a macOS styled checkbox.
/// Creates a macOS-style checkbox.

Just a tiny nit: when I read this the first time, I read it as a "styled checkbox" for macOS.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// If this property is null, then the side defaults to a width of 1.
/// If this property is null, then the side defaults to a one pixel wide
/// black, solid border.

Copy link
Contributor

Choose a reason for hiding this comment

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

Too bad we have to cast here (but we do). Someday we should add a asOffset to Size and a asSize to Offset.

@MitchellGoodwin MitchellGoodwin force-pushed the create-cupertino-checkbox branch from 9a5eec2 to f084121 Compare March 20, 2023 21:16
@MitchellGoodwin MitchellGoodwin force-pushed the create-cupertino-checkbox branch from f084121 to 6ccacb8 Compare March 20, 2023 22:59
@MitchellGoodwin MitchellGoodwin added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 21, 2023
@auto-submit auto-submit bot merged commit 1ba3f99 into flutter:master Mar 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 10, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App f: cupertino flutter/packages/flutter/cupertino repository framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants