Skip to content

Conversation

@bleroux
Copy link
Contributor

@bleroux bleroux commented Nov 27, 2025

Description

This PR adds DropdownMenu.selectOnly. This property allows users to get the DropdownMenu behave as a 'select' component.
It is meant as a future replacement for DropdownMenu.requestFocusOnTap.

Motivation

On mobile, a dropdown menu widget is usually used as a ‘select’ widget because opening the keyboard for searching/filtering is not convenient.

In Flutter, this is currently implemented through DropdownMenu.requestFocusOnTap which defaults to false on mobile and true on desktop.
The DropdownMenu.requestFocusOnTap property is currently used to set FocusNode.canRequestFocus. This leads do difficulties mainly related to focus traversal:

  • Keyboard traversal requires workarounds (for instance relying on the trailing icon to be focusable).
  • Keyboard shortcuts require also a workaround (currently relying on a Focus widget in a Stack).
  • The DropdownMenu decoration does not reflect the focus state.

This PR proposes a new property named DropdownMenu.selectOnly which does not require DropdownMenu.requestFocusOnTap to be false to make the DropdownMenu behave like a select widget.

With this property the DropdownMenu:

In the future this property could be used as a replacement for DropdownMenu.requestFocusOnTap. For the moment, for compatibility, it does not replace DropdownMenu.requestFocusOnTap.

Related Issue

Fixes Allow DropdownMenu to be non-editable and focusable (select control)
Also related to Make DropdownMenu's trailing icon not focusable by default and [Material3] DropdownMenu Keyboard Accessibility.

Tests

  • Adds 9 tests.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Nov 27, 2025
Copy link
Contributor

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

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 a selectOnly property to the DropdownMenu widget, which is a valuable addition for creating 'select'-like behavior, especially on mobile platforms. The implementation is clean and includes a good set of tests to verify the new functionality.

I have two suggestions for improvement:

  1. The documentation for the new selectOnly property could be more explicit about its purpose and how it interacts with focusability.
  2. When selectOnly is true, the left and right arrow keys still allow cursor movement within the text field, which is inconsistent with a 'select' component. I've suggested a change to disable this behavior.

Overall, this is a great enhancement to the DropdownMenu widget.

@bleroux bleroux force-pushed the add_DropdownMenu.selectOnly branch from c21de33 to f75007c Compare November 27, 2025 22:19
@bleroux bleroux requested a review from QuncCccccc November 28, 2025 09:28
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.

Sorry, I'm still a bit confused. What's the difference between this new API and requestFocusOnTap? Feels like super similar:)

@bleroux
Copy link
Contributor Author

bleroux commented Dec 2, 2025

Sorry, I'm still a bit confused. What's the difference between this new API and requestFocusOnTap? Feels like super similar:)

Yes, they are very similar because selectOnly is meant as a future replacement for requestFocusOnTap.
requestFocusOnTap has several drawbacks:

  • Keyboard traversal requires workarounds (for instance relying on the trailing icon to be focusable).
  • Keyboard shortcuts require also a workaround (currently relying on a Focus widget in a Stack).
  • The DropdownMenu decoration does not reflect the focus state.

@bleroux bleroux force-pushed the add_DropdownMenu.selectOnly branch from f75007c to 4b73da3 Compare December 2, 2025 10:24
@bleroux bleroux requested a review from QuncCccccc December 2, 2025 10:26
@QuncCccccc
Copy link
Contributor

requestFocusOnTap has several drawbacks:

Are there a way to just keep the current API (requestFocusOnTap) and add the behaviors by updating the implementation? Just feel deprecating an API and replacing it with a similar one might not be a good practice.

@bleroux
Copy link
Contributor Author

bleroux commented Dec 3, 2025

Are there a way to just keep the current API (requestFocusOnTap) and add the behaviors by updating the implementation?

While both properties target a similar use case: selecting an entry without editing the text field (so without opening the virtual keyboard on mobile), there is a main difference which is that requestFocusOnTap achieves this by not allowing the component to be focused, selectOnly does not prevent the component to be focused (it is mainly mapped to TextField.readOnly).

Maybe We can summarize this with:

requestFocusOnTap = selectOnly + canRequestFocus

(just for illustration because at the boolean level it is not correct 😅 )

Changing the current requestFocusOnTap behaviors would be problematic as the name will directly contradict the implementation (even when false the component will get the focus). Also it will break a lot of existing tests which assume that the DropdownMenu is not focusable at all when requestFocusOnTap is false.

I think both properties can coexist for the moment and at one time we might consider that requestFocusOnTap is only canRequestFocus and that it could be deprecated as one can rely on FocusNode.canRequestFocus. But to do so we first need to separate the behaviors related to the 'select' use case, this is what this PR does by adding this new DropdownMenu.selectOnly property.

@QuncCccccc
Copy link
Contributor

Got it. Yeah, it makes sense to me and requestFocusOnTap = selectOnly + canRequestFocus definitely make it easier to understand XD. Thanks for your explanation!

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.

LGTM:) Thanks!

@bleroux bleroux force-pushed the add_DropdownMenu.selectOnly branch from 4b73da3 to 5b5d726 Compare December 4, 2025 08:23
@bleroux bleroux force-pushed the add_DropdownMenu.selectOnly branch from 5b5d726 to 617c47f Compare December 4, 2025 10:42
@bleroux bleroux added the autosubmit Merge PR when tree becomes green via auto submit App label Dec 4, 2025
@auto-submit auto-submit bot added this pull request to the merge queue Dec 4, 2025
Merged via the queue into flutter:master with commit aa4f528 Dec 4, 2025
71 checks passed
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Dec 4, 2025
@bleroux bleroux deleted the add_DropdownMenu.selectOnly branch December 4, 2025 14:50
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 4, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 4, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 4, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 4, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 4, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 4, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 5, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 5, 2025
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Dec 5, 2025
Roll Flutter from 69d8710 to 5b87203 (42 revisions)

flutter/flutter@69d8710...5b87203

2025-12-05 engine-flutter-autoroll@skia.org Roll Packages from d39e481 to b17d3ff (3 revisions) (flutter/flutter#179505)
2025-12-05 bungeman@chromium.org Move target_cpu into use_rbe block in Fuchsia build (flutter/flutter#179458)
2025-12-05 engine-flutter-autoroll@skia.org Roll Skia from fe6bf18a3f6b to a31411879251 (3 revisions) (flutter/flutter#179499)
2025-12-05 sokolovskyi.konstantin@gmail.com Force WASM single threading in Chrome extensions. (flutter/flutter#179400)
2025-12-05 engine-flutter-autoroll@skia.org Roll Skia from aea282ea0bcd to fe6bf18a3f6b (7 revisions) (flutter/flutter#179489)
2025-12-05 dolt@guide.inc fix: check both pointer count and action before reusing MotionEvent (flutter/flutter#178528)
2025-12-05 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from VtDPX2k1kosHxjKUE... to vDeTl_KBeLJY8nCAx... (flutter/flutter#179478)
2025-12-05 bkonyi@google.com [ Widget Preview ] Add embedded Widget Inspector support (flutter/flutter#178116)
2025-12-05 30870216+gaaclarke@users.noreply.github.com bubble up fragment shader errors (flutter/flutter#179363)
2025-12-05 engine-flutter-autoroll@skia.org Roll Dart SDK from eda82318e193 to 42fe3327abca (1 revision) (flutter/flutter#179472)
2025-12-05 jesswon@google.com [Android 16] Use AVD With New Android Renderer (flutter/flutter#179306)
2025-12-05 bkonyi@google.com Unpin `package:dwds` dependency (flutter/flutter#179462)
2025-12-05 flar@google.com [Impeller] include uniform info in impellerc json reflections (flutter/flutter#179317)
2025-12-05 engine-flutter-autoroll@skia.org Roll Skia from 1591b066f49b to aea282ea0bcd (1 revision) (flutter/flutter#179468)
2025-12-04 engine-flutter-autoroll@skia.org Roll Skia from e1923478562b to 1591b066f49b (3 revisions) (flutter/flutter#179460)
2025-12-04 jacksongardner@google.com Cherry-pick flutter 3.38.4 changelog back to master. (flutter/flutter#179463)
2025-12-04 1961493+harryterkelsen@users.noreply.github.com [web] Add clone method to LayerPicture and dispose pictures in PictureLayer (flutter/flutter#179162)
2025-12-04 30870216+gaaclarke@users.noreply.github.com Fixes merge conflict from high bitrate texture tests (flutter/flutter#179416)
2025-12-04 116356835+AbdeMohlbi@users.noreply.github.com Fix typos in `VirtualDisplayController.java` (flutter/flutter#179411)
2025-12-04 engine-flutter-autoroll@skia.org Roll Dart SDK from 2de44cc08970 to eda82318e193 (1 revision) (flutter/flutter#179453)
2025-12-04 engine-flutter-autoroll@skia.org Roll Skia from 55d94a54f453 to e1923478562b (1 revision) (flutter/flutter#179449)
2025-12-04 engine-flutter-autoroll@skia.org Roll Packages from 8cb4903 to d39e481 (8 revisions) (flutter/flutter#179451)
2025-12-04 bruno.leroux@gmail.com Add DropdownMenu.selectOnly (flutter/flutter#179189)
2025-12-04 engine-flutter-autoroll@skia.org Roll Dart SDK from 7e6bfc6af55c to 2de44cc08970 (6 revisions) (flutter/flutter#179443)
2025-12-04 engine-flutter-autoroll@skia.org Roll Skia from b8f79d7316c0 to 55d94a54f453 (1 revision) (flutter/flutter#179439)
2025-12-04 6655696+guidezpl@users.noreply.github.com Revise README for link updates and terminology changes (flutter/flutter#179357)
2025-12-04 engine-flutter-autoroll@skia.org Roll Skia from ce19122e3982 to b8f79d7316c0 (3 revisions) (flutter/flutter#179436)
2025-12-04 bruno.leroux@gmail.com Update some BottomNavigationBar comments to reflect theme normalization (flutter/flutter#179404)
2025-12-04 robert.ancell@canonical.com Replace use of eglCreateImage with eglCreateImageKHR to reduce EGL requirement (flutter/flutter#179310)
2025-12-04 engine-flutter-autoroll@skia.org Roll Skia from 81a9a0751f00 to ce19122e3982 (5 revisions) (flutter/flutter#179430)
2025-12-04 30870216+gaaclarke@users.noreply.github.com [impellerc] adds entry prefix flag to avoid shader collisions (flutter/flutter#179160)
2025-12-04 jon.i@hotmail.fr [Windows] Allow apps to prefer high power GPUs (flutter/flutter#177653)
2025-12-04 bkonyi@google.com [ Infra ] Shard `Windows tool_tests_commands` (flutter/flutter#179409)
2025-12-04 nshahan@google.com [flutter_tools] Fix filename typo (flutter/flutter#179427)
2025-12-04 fluttergithubbot@gmail.com Marks Linux_pixel_7pro draw_arcs_all_stroke_styles_perf__timeline_summary to be unflaky (flutter/flutter#179392)
2025-12-03 fluttergithubbot@gmail.com Marks Mac_ios draw_arcs_all_fill_styles_perf_ios__timeline_summary to be unflaky (flutter/flutter#179391)
2025-12-03 fluttergithubbot@gmail.com Marks Linux_pixel_7pro draw_arcs_all_fill_styles_perf__timeline_summary to be unflaky (flutter/flutter#179390)
2025-12-03 jason-simmons@users.noreply.github.com Roll Abseil to 564023aa5376 (flutter/flutter#179421)
2025-12-03 30870216+gaaclarke@users.noreply.github.com Made wide gamut tests give more information in their failure (flutter/flutter#179415)
2025-12-03 engine-flutter-autoroll@skia.org Roll Skia from c20f797ab6f9 to 81a9a0751f00 (5 revisions) (flutter/flutter#179417)
2025-12-03 737941+loic-sharma@users.noreply.github.com Migrate samples and docs to RadioGroup (flutter/flutter#179158)
2025-12-03 iinozemtsev@google.com Roll Dart SDK to 3.11.0-200.1.beta (flutter/flutter#179399)

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
...
reidbaker pushed a commit to AbdeMohlbi/flutter that referenced this pull request Dec 10, 2025
## Description

This PR adds `DropdownMenu.selectOnly`. This property allows users to
get the DropdownMenu behave as a 'select' component.
It is meant as a future replacement for
`DropdownMenu.requestFocusOnTap`.

## Motivation

On mobile, a dropdown menu widget is usually used as a ‘select’ widget
because opening the keyboard for searching/filtering is not convenient.

In Flutter, this is currently implemented through
`DropdownMenu.requestFocusOnTap` which defaults to false on mobile and
true on desktop.
The `DropdownMenu.requestFocusOnTap` property is currently used to set
`FocusNode.canRequestFocus`. This leads do difficulties mainly related
to focus traversal:
- Keyboard traversal requires workarounds (for instance relying on the
trailing icon to be focusable).
- Keyboard shortcuts require also a workaround (currently relying on a
Focus widget in a Stack).
- The `DropdownMenu` decoration does not reflect the focus state.

This PR proposes a new property named `DropdownMenu.selectOnly` which
does not require `DropdownMenu.requestFocusOnTap` to be false to make
the `DropdownMenu` behave like a select widget.

With this property the `DropdownMenu`:
- Supports keyboard navigation on mobile and desktop.
- Has a correct decoration when focused.
- Does not rely on the trailing icon to be focusable (see
flutter#174096).

In the future this property could be used as a replacement for
`DropdownMenu.requestFocusOnTap`. For the moment, for compatibility, it
does not replace `DropdownMenu.requestFocusOnTap`.

## Related Issue

Fixes [Allow DropdownMenu to be non-editable and focusable (select
control) ](flutter#178009)
Also related to [Make DropdownMenu's trailing icon not focusable by
default](flutter#174096) and
[[Material3] DropdownMenu Keyboard
Accessibility](flutter#123797).


## Tests

- Adds 9 tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

Allow DropdownMenu to be non-editable and focusable (select control)

2 participants