Skip to content

Make onChanged optional and add enabled to DropdownButtonFormField - #182419

Closed
Mairramer wants to merge 15 commits into
flutter:masterfrom
Mairramer:feature/remove-required-onchanged
Closed

Mairramer wants to merge 15 commits into
flutter:masterfrom
Mairramer:feature/remove-required-onchanged

Conversation

@Mairramer

@Mairramer Mairramer commented Feb 14, 2026 •

Copy link
Copy Markdown
Contributor

Made onChanged optional and introduced the enabled parameter in DropdownButtonFormField, allowing proper disabled/read-only usage without dummy callbacks.

Breaking change

Previously, setting onChanged: null disabled the widget. This is no longer the case. The disabled state must now be controlled via the enabled property.

Most simple usages are handled by the automated fix tool. Code that conditionally relied on onChanged being null to disable the widget must be updated to use enabled.

If not migrated, the widget will remain interactive but will not trigger a callback.

Closes #57953

Pre-launch Checklist

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

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.

@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 Feb 14, 2026
@Mairramer Mairramer changed the title Feature/remove required onchanged Make onChanged optional and add enabled to DropdownButtonFormField Feb 14, 2026
@Mairramer Mairramer changed the title Make onChanged optional and add enabled to DropdownButtonFormField Make onChanged optional and add enabled to DropdownButtonFormField Feb 14, 2026
@github-actions github-actions Bot added the c: tech-debt Technical debt, code quality, testing, etc. label Feb 14, 2026
@Piinks

Piinks commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Hi @Mairramer! Is this something you would like to move forward with?

@Mairramer

Copy link
Copy Markdown
Contributor Author

Hi @Mairramer! Is this something you would like to move forward with?

Yes, I’d like that, but only if the team genuinely believes it’s something worth pursuing and sees potential for me to move forward with it.

@justinmc justinmc 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'm on board with this approach. I agree that the situation described in #57953 is probably confusing a bunch of people.

My main question is whether this will cause breakages or not. Looks like customer tests are passing, but we should run the Google tests. If there are tons of breakages maybe we can rethink how we do this, but if not then I'm all for landing this.

@justinmc justinmc added the CICD Run CI/CD label Apr 28, 2026
@flutter-dashboard

Copy link
Copy Markdown

This pull request is not mergeable in its current state, likely because of a merge conflict. Pre-submit CI jobs were not triggered. Pushing a new commit to this branch that resolves the issue will result in pre-submit jobs being scheduled.

# Conflicts:
#	packages/flutter/test/material/dropdown_test.dart
@github-actions github-actions Bot removed the CICD Run CI/CD label Apr 29, 2026
@Mairramer
Mairramer marked this pull request as ready for review April 29, 2026 11:42

@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 introduces an enabled property to DropdownButton and DropdownButtonFormField, allowing these widgets to be disabled independently of the onChanged callback. It includes data-driven fixes to migrate existing code that used onChanged: null for disabling the widgets. Review feedback suggests updating the documentation to clarify that an empty items list also disables the button and identifies a potential edge case in the migration logic where an explicit enabled: true alongside a null onChanged callback might not be handled correctly.

@Mairramer

Copy link
Copy Markdown
Contributor Author

I'm on board with this approach. I agree that the situation described in #57953 is probably confusing a bunch of people.

My main question is whether this will cause breakages or not. Looks like customer tests are passing, but we should run the Google tests. If there are tons of breakages maybe we can rethink how we do this, but if not then I'm all for landing this.

In this case, we would only have a small breaking change related to the conditional use of onChanged, such as condition ? (value) { ... } : null (or vice versa), because from what I’ve seen, there’s no straightforward way to migrate this automatically.

@Mairramer
Mairramer requested a review from justinmc April 29, 2026 12:29
justinmc
justinmc previously approved these changes May 1, 2026

@justinmc justinmc 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.

Approving in order to kick off the Google tests.

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 for including a dart fix

@justinmc justinmc added the CICD Run CI/CD label May 1, 2026
@justinmc

justinmc commented May 1, 2026

Copy link
Copy Markdown
Contributor

This will have to be postponed due to the code freeze, though.

@dkwingsmt

Copy link
Copy Markdown
Contributor

There are Google test failures, and they look real.

@dkwingsmt
dkwingsmt requested a review from justinmc May 6, 2026 18:19
@Piinks

Piinks commented May 27, 2026

Copy link
Copy Markdown
Contributor

I will approve to kick of Google testing to see if that is resolved, in the meantime, since this will be a breaking change, can you create a migration guide in flutter/website? We can land it when this is ready, but it will be good to have a look at the guidance and iterate there as well in the meantime. :)

Piinks
Piinks previously approved these changes May 27, 2026
@Mairramer

Copy link
Copy Markdown
Contributor Author

@Piinks Migration guide created: flutter/website#13430

justinmc
justinmc previously approved these changes May 29, 2026

@justinmc justinmc 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 with nits 👍 . But due to the code freeze, we should not land this PR. It will have to be ported to flutter/packages after flutter/packages#11669 lands and we open up material_ui.

Comment on lines +1136 to +1138
/// If [enabled] is false, or the list of [DropdownButton.items] is null or empty,
/// then the dropdown button will be disabled. When disabled, the arrow is
/// displayed in grey and the button does not respond to input.

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.

Should you also explain what happens if enabled is null? Which I think includes the original behavior of disabling when onChanged is null. Or maybe you are trying to encourage people to explicitly set enabled?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In this case, it would be both. However, I’ll include the nullable enabled behavior as well.

@justinmc justinmc added CICD Run CI/CD waiting for code freeze This PR is waiting for a code freeze to resolve. labels May 29, 2026
@Mairramer
Mairramer dismissed stale reviews from justinmc and Piinks via df60fcd May 29, 2026 18:34
@Mairramer
Mairramer requested a review from justinmc May 29, 2026 18:34
@github-actions github-actions Bot removed the CICD Run CI/CD label May 29, 2026
sfshaza2 pushed a commit to flutter/website that referenced this pull request Jun 2, 2026
Description of what this PR is changing or adding, and why:
Adds a breaking change page for the new `enabled` property logic on
`DropdownButton` and `DropdownButtonFormField`. This explains why the
`onChanged` callback is no longer required and clarifies the fallback
behavior for backward compatibility. It also guides developers on how to
properly separate interactive state (`enabled`) from widget behavior
(`onChanged`), highlighting what the `dart fix` covers and what requires
manual migration (like conditional logic).

Issues fixed by this PR (if any):
N/A but related to flutter/flutter#57953

PRs or commits this PR depends on (if any):
Depends on flutter/flutter#182419


## Presubmit checklist

- [x] If you are unwilling, or unable, to sign the CLA, even for a
_tiny_, one-word PR, please file an issue instead of a PR.
- [x] If this PR is not meant to land until a future stable release,
mark it as draft with an explanation.
- [x] This PR follows the [Google Developer Documentation Style
Guidelines](https://developers.google.com/style)—for example, it doesn't
use _i.e._ or _e.g._, and it avoids _I_ and _we_ (first-person
pronouns).
- [x] This PR uses [semantic line
breaks](https://github.com/dart-lang/site-shared/blob/main/doc/writing-for-dart-and-flutter-websites.md#semantic-line-breaks)
  of 80 characters or fewer.

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Parker Lougheed <[email protected]>
@dkwingsmt dkwingsmt added the CICD Run CI/CD label Jun 3, 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.

Trigger google test

@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.

Trigger Google test

@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 June 17, 2026 18:14
@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/cupertino_ui once ready to receive PRs. Thank you!

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Aug 23, 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.

@Mairramer

Mairramer commented Aug 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Ported to flutter/packages#12610.

@Mairramer Mairramer closed this Aug 23, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Oct 13, 2026
Introduced the `enabled` parameter in `DropdownButtonFormField`, allowing proper disabled/read-only usage without needing to pass dummy callbacks or remove existing ones.

Previously, the only way to disable a `DropdownButtonFormField` was to set `onChanged: null`. With this change, developers can explicitly control the interactive state via the `enabled` property. For example, you can set `enabled: false` while keeping `onChanged` defined, or set `enabled: true` to have an interactive field even if `onChanged` is omitted.

This change is fully backward compatible. If the `enabled` property is omitted (left as `null`), the field will fall back to the legacy behavior: it will be enabled if and only if `onChanged` is non-null.

Closes flutter/flutter#57953.

Port of flutter/flutter#182419.

## Pre-Review Checklist

**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

c: tech-debt Technical debt, code quality, testing, etc. 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.

Why is DropdownButtonFormField's onChanged required?

4 participants