Skip to content

Add markInsets property to Checkbox - #188258

Closed
Munawer-Ali wants to merge 7 commits into
flutter:masterfrom
Munawer-Ali:checkbox-padding
Closed

Munawer-Ali wants to merge 7 commits into
flutter:masterfrom
Munawer-Ali:checkbox-padding

Conversation

@Munawer-Ali

@Munawer-Ali Munawer-Ali commented Jun 19, 2026 •

Copy link
Copy Markdown

This PR adds an optional padding property to the Checkbox widget.
Currently the check mark always fills the entire checkbox box, with no way to add space between the mark and the box edges (see #188031). This adds a padding field (EdgeInsetsGeometry?) that insets the check mark — and the indeterminate dash — inside the box.

Fixes flutter/flutter#188031

Tests

Added to test/material/checkbox_test.dart:

  • Checkbox.padding defaults to null
  • Checkbox with no padding paints at full stroke width (backward-compat)
  • Checkbox.padding shrinks the check mark and its stroke
  • Checkbox.padding shrinks the indeterminate dash
  • Checkbox.padding larger than the box collapses the mark without crashing
  • Checkbox asserts when padding is negative

Pre-launch Checklist

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

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

@google-cla

google-cla Bot commented Jun 19, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@github-actions github-actions Bot added framework flutter/packages/flutter repository. See also f: labels. p: material_ui material_ui package in flutter/packages labels Jun 19, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request adds a padding property to the Checkbox widget, which insets and proportionally scales the check mark and indeterminate dash. The review feedback suggests documenting that this padding is ignored on iOS and macOS when using Checkbox.adaptive, adding padding to CheckboxThemeData for global styling, correcting the documentation regarding its default value, and exposing the property in debugFillProperties for debugging.

this.side,
this.isError = false,
this.semanticLabel,
this.padding,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Since Checkbox.adaptive delegates to CupertinoCheckbox on iOS and macOS, and CupertinoCheckbox does not currently support a padding property, this padding will be ignored on those platforms. Please document this platform-specific behavior in the padding property's API documentation or the Checkbox.adaptive constructor documentation so developers are aware of this limitation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The documentation update regarding the platform-specific behavior of Checkbox.adaptive is appreciated. I noticed a small issue in packages/flutter/lib/src/material/checkbox_theme.dart: there is a duplicate line in debugFillProperties where side is added twice. Please remove the redundant line.

Suggested change
this.padding,
properties.add(DiagnosticsProperty<BorderSide>('side', side, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

/gemini review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The code changes in this pull request correctly implement the padding property for the Checkbox widget. The implementation properly handles the resolvedPadding against the ambient Directionality, updates the _CheckboxPainter to use the padding for the check mark and indeterminate dash, and includes comprehensive tests covering edge cases and theme interactions. The documentation also correctly addresses the platform-specific limitation for Checkbox.adaptive on iOS and macOS. The redundant line in debugFillProperties has been removed as requested.

/// {@endtemplate}
final String? semanticLabel;

/// The padding around the check mark when the checkbox is checked or

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

To support global styling and consistent theming across the application, the padding property should also be added to CheckboxThemeData in checkbox_theme.dart and resolved here (e.g., widget.padding ?? checkboxTheme.padding ?? EdgeInsets.zero).

Comment on lines +419 to +421
/// Defaults to [EdgeInsets.zero], which renders the check mark at its full
/// size (the same as before this property existed).
final EdgeInsetsGeometry? padding;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The documentation states Defaults to [EdgeInsets.zero], but the actual property value defaults to null (which is then resolved to EdgeInsets.zero internally). To be precise and follow Flutter's documentation standards, please clarify this.

For example:
Defaults to null, which resolves to [EdgeInsets.zero].

  /// Defaults to null, which resolves to [EdgeInsets.zero], rendering the
  /// check mark at its full size (the same as before this property existed).
  final EdgeInsetsGeometry? padding;

@dkwingsmt
dkwingsmt self-requested a review June 24, 2026 18:17
@Piinks Piinks added the Decoupling: Not ready to port yet Instructions will be provided when this is ready to move to flutter/packages. label Jun 24, 2026
@Piinks

Piinks commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

I've marked this PR as not ready to port to flutter/packages yet.
We'll provide instructions to move this change over to material_ui once it is ready to receive PRs. Thank you!

@Piinks
Piinks requested a review from QuncCccccc July 15, 2026 21:11

@QuncCccccc QuncCccccc left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think calling the property padding might be a bit misleading. For example, the existing IconButton.padding and Switch.padding can affect the overall size of IconButton and Switch, however, this PR change seems only adjust the size of the checkmark and location inside the checkbox.

Maybe we can rename it to something like markInsets? Or let me know if there are a better name.

expect(_checkboxRenderer(tester), paints..path(strokeWidth: 1.0));
});

testWidgets('Checkbox.padding shrinks the indeterminate dash too', (WidgetTester tester) async {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit:

Suggested change
testWidgets('Checkbox.padding shrinks the indeterminate dash too', (WidgetTester tester) async {
testWidgets('Checkbox.padding shrinks the indeterminate dash', (WidgetTester tester) async {

Comment on lines +422 to +423
/// Must be non-negative. Padding larger than the box collapses the check
/// mark to nothing.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Must be non-negative. Padding larger than the box collapses the check
/// mark to nothing.
/// Must be non-negative. If the resolved horizontal or vertical padding is
/// greater than or equal to the checkbox size, the check mark or indeterminate
/// dash is not painted..

State<Checkbox> createState() => _CheckboxState();

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Checkbox did not previously expose its existing widget properties through debugFillProperties. Adding an override only for the new padding property makes diagnostics oddly incomplete. I think in this PR, it is okay to not override debugFillProperties.

/// If null, [CheckboxThemeData.padding] is used. If that is also null,
/// it defaults to [EdgeInsets.zero] and the check mark renders at full size.
/// {@endtemplate}
final EdgeInsetsGeometry? padding;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe EdgeInsets? would be enough, so that we don't need .resolve(Directionality.maybeOf(context));? Because I think the most common case would be making the check mark or dash be centered. We don't really need to care about the directionality?

final EdgeInsets resolvedPadding = (widget.padding ?? checkboxTheme.padding ?? EdgeInsets.zero)
.resolve(Directionality.maybeOf(context));

assert(resolvedPadding.isNonNegative, 'Checkbox.padding cannot be negative.');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: I think no need to add this to keep consistency with other EdgeInsets use case.

@Munawer-Ali Munawer-Ali reopened this Jul 22, 2026
@fluttergithubbot

Copy link
Copy Markdown
Contributor

An existing Git SHA, 9847e5163c0bb5f8c90491e13ee97f63e83a4064, was detected, and no actions were taken.

To re-trigger presubmits after closing or re-opeing a PR, or pushing a HEAD commit (i.e. with --force) that already was pushed before, push a blank commit (git commit --allow-empty -m "Trigger Build") or rebase to continue.

@Munawer-Ali

Copy link
Copy Markdown
Author

Thanks for the review, @QuncCccccc ! I've addressed all the comments:

Renamed padding → markInsets (on both Checkbox and CheckboxThemeData) to avoid implying it changes the overall widget size.
Changed the type to EdgeInsets? and removed the .resolve(Directionality...) since directionality isn't needed here.
Removed the assert for consistency with other EdgeInsets usages.
Removed the debugFillProperties override — agreed it's inconsistent to expose only this one property.
Updated the doc wording and the test name as suggested.

Let me know if markInsets works as the final name or if you'd prefer something else. Ready for another look when you have time.

@QuncCccccc
QuncCccccc self-requested a review July 22, 2026 16:52
@QuncCccccc QuncCccccc changed the title Add padding property to Checkbox Add markInsets property to Checkbox Jul 22, 2026

@QuncCccccc QuncCccccc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks a lot for your contribution! Overall it looks really good. Just left a few comments below.

/// effect, because the checkbox delegates to [CupertinoCheckbox], which does
/// not support insets.
///
/// Must be non-negative. If the resolved horizontal or vertical insets are

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Must be non-negative. If the resolved horizontal or vertical insets are
/// Must be non-negative. If the horizontal or vertical insets are

@@ -641,6 +666,7 @@ class _CheckboxState extends State<Checkbox> with TickerProviderStateMixin, Togg
..previousValue = _previousValue
..shape = widget.shape ?? checkboxTheme.shape ?? defaults.shape!
..activeSide = activeSide
..padding = markInsets

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we also consider to rename _CheckboxPainter.padding to markInsets for consistency?

@Munawer-Ali

Copy link
Copy Markdown
Author

@QuncCccccc Thanks! Both addressed in the latest push:

Renamed _CheckboxPainter.padding → markInsets for consistency.
Updated the doc wording (removed "resolved").

Let me know if there's anything else.

dkwingsmt
dkwingsmt previously approved these changes Jul 23, 2026

@dkwingsmt dkwingsmt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. Thank you!

@dkwingsmt dkwingsmt added the CICD Run CI/CD label Jul 23, 2026

@QuncCccccc QuncCccccc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall LGTM with just one more doc comment. Thanks again for your contribution:)!

/// is not affected. The check mark and its stroke shrink to fit the
/// remaining space, so the mark stays proportional.
///
/// On iOS and macOS, when using [Checkbox.adaptive], this property has no

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since this is ignored in Checkbox.adaptive, can we also add this property name in the doc here - it lists all properties that are ignored in Checkbox.adaptive.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done — added markInsets to the list of parameters ignored by Checkbox.adaptive. Please take a look and let me know if anything else is needed. Thanks again!

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Jul 23, 2026
@dkwingsmt dkwingsmt added the CICD Run CI/CD label Jul 23, 2026
dkwingsmt
dkwingsmt previously approved these changes Jul 23, 2026
QuncCccccc
QuncCccccc previously approved these changes Jul 23, 2026

@QuncCccccc QuncCccccc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM! Thanks again for your contribution!

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Jul 23, 2026
@QuncCccccc QuncCccccc added the CICD Run CI/CD label Jul 23, 2026
@Munawer-Ali

Copy link
Copy Markdown
Author

@QuncCccccc @dkwingsmt Thanks for the review and approval! I see the PR is blocked by the Material code freeze (
#184093) since it touches packages/flutter/lib/src/material. Should I port this markInsets change to the material_ui package in flutter/packages? If so, is there anything from this PR I should carry over or link? Happy to open it there.

@Piinks

Piinks commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Hey @Munawer-Ali thanks for the contribution! This will need to be moved over to flutter/packages and the new material_ui package, but we're not quite ready to accept PRs yet. Let's leave this here, and we will let you know when to move it over with instructions when it is ready. :)

@Munawer-Ali

Copy link
Copy Markdown
Author

Thank you! The Flutter team has been really welcoming and supportive throughout — great and sweet people. 🙂 I'll leave the PR here and wait for your instructions to move it over to material_ui when it's ready. Appreciate all the help!

@dkwingsmt

Copy link
Copy Markdown
Contributor

Thanks for your contribution! This PR has reached completion, however we're not able to merge this PR for the moment due to the Material/Cupertino code freeze (#184093). As soon as the decoupling is complete, we will post a way to port this PR to the new packages to land. In the meantime, I'll convert this PR to a draft and apply a label so that we can quickly find it when the freeze is lifted.

@dkwingsmt
dkwingsmt marked this pull request as draft July 29, 2026 18:15
@dkwingsmt dkwingsmt added the waiting for code freeze This PR is waiting for a code freeze to resolve. label Jul 29, 2026
const start = Offset(_kEdgeSize * 0.15, _kEdgeSize * 0.45);
const mid = Offset(_kEdgeSize * 0.4, _kEdgeSize * 0.7);
const end = Offset(_kEdgeSize * 0.85, _kEdgeSize * 0.25);
final double innerW = (_kEdgeSize - _markInsets.horizontal).clamp(0.0, _kEdgeSize);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use clampDouble instead (here and everywhere else in this PR) to pass CI (linux analyze)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Ok sir

@Munawer-Ali

Copy link
Copy Markdown
Author

Hello @Piinks ma’am, can I port those changes to the Material UI package?

@dkwingsmt

dkwingsmt commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Yes, please! (We've been sending port notifications to pending PRs in batches to avoid having too many new PRs at once, but sending yours now is very welcome!) Guidance and instructions for easily porting over can be found in #188444. Thank you!

@Munawer-Ali
Munawer-Ali dismissed stale reviews from dkwingsmt and QuncCccccc via c1be6d9 August 30, 2026 08:57
@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Aug 30, 2026
@github-actions

Copy link
Copy Markdown

This pull request contains changes to Material or Cupertino, which are currently frozen in this repository.

Changes should be made in material_ui and/or cupertino_ui in the flutter/packages repository.

Please refer to #188444 for instructions.

@Munawer-Ali

Copy link
Copy Markdown
Author

I moved my changes to flutter/packages:
flutter/packages#12690
Closing this one. Thanks @QuncCccccc @Piinks @dkwingsmt @victorsanni

auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Oct 27, 2026
This PR ports my changes from flutter/flutter#188258 to
  flutter/packages,
  as part of flutter/flutter#188444          

  Adds `Checkbox.markInsets` and `CheckboxThemeData.markInsets`, which inset the check
  mark and the
  indeterminate dash within the checkbox without changing the size of the box itself. The
  mark and its
  stroke shrink proportionally, and the mark is not painted if the insets leave no room.

  Fixes flutter/flutter#188031                      

  ## Tests

  Added to `packages/material_ui/test/checkbox_test.dart`:
  - `Checkbox.markInsets` defaults to null
  -  Checkbox with no `markInsets` paints the check at full stroke width (backward-compat)
  - `Checkbox.markInsets` shrinks the check mark and its stroke
  - `Checkbox.markInsets` shrinks the indeterminate dash
  - `Checkbox.markInsets` larger than the box collapses the mark without crashing
  - `Checkbox.markInsets` falls back to `CheckboxThemeData.markInsets`
  - `Checkbox.markInsets` overrides `CheckboxThemeData.markInsets`

  ## Pre-Review Checklist

  submitting PRs.
  am not using AI tools.
  brackets, e.g. `[shared_preferences]`
  and the [repository CHANGELOG style], or I have commented below to indicate which
  documented exception this PR falls under[^1].
  indicate which [test exemption] this PR falls under[^1].
  
**Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Decoupling: Not ready to port yet Instructions will be provided when this is ready to move to flutter/packages. framework flutter/packages/flutter repository. See also f: labels. p: material_ui material_ui package in flutter/packages waiting for code freeze This PR is waiting for a code freeze to resolve.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a padding property to Checkbox widget ✅ around check icon ✔.

6 participants