Skip to content

Conversation

@AlsoShantanuBorkar
Copy link
Contributor

@AlsoShantanuBorkar AlsoShantanuBorkar commented Jul 25, 2025

Added an API to control the FocusNode of DropdownMenu Trailing IconButton.

This is also an improvement to DropdownMenu Focus since introducing the FocusNode to IconButton brings uniformity to the Focus Traversal.

Previously there were two cases

  • If FocusNode is passed to DropdownMenu, 3 tab presses were required to focus the Trailing IconButton
  • If FocusNode is not passed then 3 tab presses were needed for MacOS, Windows & Linux Platforms and 2 for Android, iOS & Fuchsia.

This PR allows Focusing the IconButton by single tab press

Fixes #172687 by passing a FocusNode with skipTraversal:true

Before

  • MacOS

  • Before.Macos.mov
  • IOS without a FocusNode

  • Before.w.o.focusNode.mov
  • IOS with a FocusNode

  • Before.w.FocusNode.mov

After

  • MacOS

  • After.Macos.mov
  • IOS without FocusNode

  • After.w.o.FocusNode.mov
  • IOS with a FocusNode

  • After.w.FocusNode.mov

Pre-launch Checklist

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

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

SalehTZ commented Jul 27, 2025

I think the test Using keyboard navigation to select and without setting the FocusNode parameter in file dropdown_menu_test.dart line:4166 is failing. See how the changes affect this test.

https://github.com/AlsoShantanuBorkar/flutter/blob/6eda6544640d3d488eeebce3d531c38e01170a7b/packages/flutter/test/material/dropdown_menu_test.dart#L4134-L4180

@justinmc
Copy link
Contributor

Weird failure. I wonder if it has to do with the SystemContextMenu test run right before the failure.

01:02 +1559 ~1 -1: C:/b/s/w/ir/x/w/flutter/packages/flutter/test/cupertino/text_field_test.dart: readOnly disallows SystemContextMenu (variant: TargetPlatform.iOS)
01:02 +1559 ~1 -1: C:/b/s/w/ir/x/w/flutter/packages/flutter/test/foundation/isolates_test.dart: compute() closes all ports with invalid error [E]
  Expected: <0>
    Actual: <-1073740791>
  
  package:matcher                                     expect
  package:flutter_test/src/widget_tester.dart 473:18  expect
  test\foundation\isolates_test.dart 107:3            expectFileSuccessfullyCompletes

Have you tried rebasing this PR? I see you've tried pushing merge commits, but sometimes a rebase will reset some things that a merge won't.

@MitchellGoodwin
Copy link
Contributor

When I look at other recent failures for that check, the same isolate test is failing in different PRs, though typically with a different value. I wonder if it's flaky?
https://ci.chromium.org/ui/p/flutter/builders/try/Windows%20framework_tests_libraries

@AlsoShantanuBorkar
Copy link
Contributor Author

AlsoShantanuBorkar commented Jul 29, 2025

Weird failure. I wonder if it has to do with the SystemContextMenu test run right before the failure.

01:02 +1559 ~1 -1: C:/b/s/w/ir/x/w/flutter/packages/flutter/test/cupertino/text_field_test.dart: readOnly disallows SystemContextMenu (variant: TargetPlatform.iOS)
01:02 +1559 ~1 -1: C:/b/s/w/ir/x/w/flutter/packages/flutter/test/foundation/isolates_test.dart: compute() closes all ports with invalid error [E]
  Expected: <0>
    Actual: <-1073740791>
  
  package:matcher                                     expect
  package:flutter_test/src/widget_tester.dart 473:18  expect
  test\foundation\isolates_test.dart 107:3            expectFileSuccessfullyCompletes

Have you tried rebasing this PR? I see you've tried pushing merge commits, but sometimes a rebase will reset some things that a merge won't.

Havent tried to rebase yet, will try this, or should I reopen the PR 🤔

Edit: Rebasing fixed the issues

@AlsoShantanuBorkar AlsoShantanuBorkar force-pushed the feat/dropdown-menu-trailing-icon-focus branch 2 times, most recently from efeb145 to f44ccb1 Compare July 30, 2025 05:31
@dkwingsmt dkwingsmt requested a review from justinmc July 30, 2025 18:06
@AlsoShantanuBorkar AlsoShantanuBorkar force-pushed the feat/dropdown-menu-trailing-icon-focus branch from f44ccb1 to 079ebd9 Compare July 31, 2025 06:49
Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

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

LGTM with a question 👍 . Thanks for the PR!

Comment on lines 3519 to +3529
// Move the focus to the dropdown trailing icon.
primaryFocus!.nextFocus();
await tester.pump();
final Element iconButton = tester.firstElement(find.byIcon(Icons.arrow_drop_down));
expect(Focus.of(iconButton).hasFocus, isTrue);

// Move the focus to the text field.
primaryFocus!.nextFocus();
await tester.pump();
expect(textFieldFocusNode.hasFocus, isTrue);

Copy link
Contributor

Choose a reason for hiding this comment

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

This means the focus order is changed.
Before this PR, the text field received the focus first.
After this PR, the icon receives the focus first.

I don't have a strong opinion on which is better, I just want to point out that the behavior is changed.

Where I have a strong opinion, is that most of the DropdownMenu focus issues are related to the icon being in IconButton. For such a widget, it would be better if the icon was not a button by default.

Copy link
Contributor Author

@AlsoShantanuBorkar AlsoShantanuBorkar Aug 1, 2025

Choose a reason for hiding this comment

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

This means the focus order is changed.
Before this PR, the text field received the focus first.
After this PR, the icon receives the focus first.

  • Yes, before this PR focus traversal behaviour also varied based on platforms, some required 2 tab presses some needed 3.

Where I have a strong opinion, is that most of the DropdownMenu focus issues are related to the icon being in IconButton. For such a widget, it would be better if the icon was not a button by default.

  • I think this is a better approach, will make the widget tree simpler incase IconButton Behaviour is not needed. There's another use-case which might get requested which is to allow customising the entire Trailing Widget, instead of using IconButton/Icon user might want to use something else.

  • Also the current docs dont specify that an IconButton is being created, unless user navigates to the file they wont know that an IconButton is being used.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry to jump in, but most comboboxes in the wild default to an unfocusable "button" that usually only opens the listbox when clicked, so I agree with @bleroux that it shouldn't be focusable by default (if at all).

Some examples:

On MacOS:
https://github.com/user-attachments/assets/7738df66-c144-42aa-b8ee-d4d229915d43

image

From WAI:
"The button has been removed from the tab sequence of the page, but is still important to assistive technologies for mobile devices that use touch events to open the list of options."

Details

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My concern is with the behaviour on Mobile Devices, right now if a focusNode is not passed for the TextField, then the textfield will not be focused when navigating via keyboard, it also not be focused when pressed. For consistent behaviour I think creating a default FocusNode is a better approach.

  • Without FocusNode for TextField

  • Screen.Recording.2025-08-06.at.11.01.10.AM.mov
  • With a FocusNode for TextField

  • Screen.Recording.2025-08-06.at.11.12.28.AM.mov

Copy link
Contributor

@bleroux bleroux Aug 6, 2025

Choose a reason for hiding this comment

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

@davidhicks980 Many thanks for providing those links, I will consider filing an issue to have a place where we can discuss how to align DropdownMenu default behaviors with what is done usually for most comboboxes.
One problem we have is not introducing too much breaking changes.

@AlsoShantanuBorkar

My concern is with the behaviour on Mobile Devices, right now if a focusNode is not passed for the TextField, then the textfield will not be focused when navigating via keyboard, it also not be focused when pressed.

This is controlled by requestFocusOnTap which defaults to false on mobile.
This might not be the most user-friendly API but it gives a way to customize this behavior.
We can probably discuss the pros and cons of this default value (it was probably discussed when it was introduced).

Back to the purpose of this PR, which is about setting a default focus node for the trailing icon.
I'm interested to know if it would make sense to accept this change and later, in a future PR, changing the default behavior:

  • when trailingIconFocusNode is not set, we will no more create an IconButton
  • when trailingIconFocusNode is set, we will create an IconButton.
    This will change the default behavior but make it possible for users to get the old behaviors.

@justinmc Do you think it makes sense? Is it too convoluted?
Same question for @davidhicks980 and @AlsoShantanuBorkar?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • when trailingIconFocusNode is not set, we will no more create an IconButton
  • when trailingIconFocusNode is set, we will create an IconButton.
    This will change the default behavior but make it possible for users to get the old behaviors.

For now I think this approach makes sense, its making the code simpler and users will only need to pass a FocusNode for the IconButton behaviour .

Copy link
Contributor

Choose a reason for hiding this comment

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

I like @bleroux's approach. I agree that we should try to move towards a default where the trailing icon is not focusable by default. It's only convoluted in the case where the user wants to customize this behavior, which should be a small minority.

Would you be able to create an issue for that @bleroux?

Copy link
Contributor Author

@AlsoShantanuBorkar AlsoShantanuBorkar Aug 19, 2025

Choose a reason for hiding this comment

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

I tried making the Icon not-focusable by default, this disables keyboard navigation on mobile devices(Neither TextField nor Trailing Icon are focusable) and changes the keyboard navigation on desktop devices as well(Opening the menu needs typing something in the TextField since TrailingIcon is not focusable).

I think this should be further discussed

Copy link
Contributor

Choose a reason for hiding this comment

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

I filed #174096 where we can further discuss making the trailing icon not-focusable by default.

In the meantime, I think it is ok to validate this PR.

@AlsoShantanuBorkar AlsoShantanuBorkar marked this pull request as draft August 5, 2025 07:32
@AlsoShantanuBorkar AlsoShantanuBorkar marked this pull request as ready for review August 5, 2025 11:22
@AlsoShantanuBorkar AlsoShantanuBorkar changed the title feat: Added Focus Toggle for DropdownMenu TrailingIcon Button feat: Added FocusNode prop for DropdownMenu Trailing Icon Button Aug 5, 2025
Copy link
Contributor

@bleroux bleroux left a comment

Choose a reason for hiding this comment

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

Thanks for the changes, I spotted one problem related to disposal and some minor typos.

@AlsoShantanuBorkar AlsoShantanuBorkar marked this pull request as draft August 11, 2025 17:01
Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

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

FYI there is an analyzer failure.

Copy link
Contributor

@bleroux bleroux 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 for working on this 🙏

@bleroux bleroux added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 20, 2025
@auto-submit auto-submit bot added this pull request to the merge queue Aug 20, 2025
Merged via the queue into flutter:master with commit 7438e54 Aug 20, 2025
78 checks passed
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 20, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 20, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 20, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 20, 2025
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Aug 20, 2025
…9862)

Manual roll Flutter from e65380a22076 to 960d1078f876 (36 revisions)

Manual roll requested by [email protected]

flutter/flutter@e65380a...960d107

2025-08-20 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Reapply "Add set semantics enabled API and wire iOS a11y bridge (#161… (#171198)" (flutter/flutter#174153)
2025-08-20 [email protected] Make sure that a Badge doesn't crash in 0x0 environment (flutter/flutter#172065)
2025-08-20 [email protected] Make sure that CalendarDatePicker & YearPicker don't crash in 0x0 environment (flutter/flutter#173408)
2025-08-20 [email protected] Roll Packages from 953cae0 to 58c02e0 (2 revisions) (flutter/flutter#174142)
2025-08-20 [email protected] Make sure that a CircleAvatar doesn't crash in 0x0 environment (flutter/flutter#173498)
2025-08-20 [email protected] Roll Dart SDK from 0d674ff61e2e to 0d0a0c394381 (1 revision) (flutter/flutter#174126)
2025-08-20 [email protected] [Android] Fix version code override calculation in FlutterPlugin (flutter/flutter#174081)
2025-08-20 [email protected] Make sure that a BackButton doesn't crash in 0x0 environment (flutter/flutter#172817)
2025-08-20 [email protected] Roll Dart SDK from c5f5a32df36c to 0d674ff61e2e (1 revision) (flutter/flutter#174099)
2025-08-20 [email protected] feat: Added FocusNode prop for DropdownMenu Trailing Icon Button (flutter/flutter#172753)
2025-08-20 [email protected] Make component theme data defaults use `WidgetStateProperty` (flutter/flutter#173893)
2025-08-20 [email protected] Fix Menu anchor reduce padding on web and desktop (flutter/flutter#172691)
2025-08-20 [email protected] Roll Skia from 4b788d0e5e63 to 721e68fe652a (2 revisions) (flutter/flutter#174095)
2025-08-20 [email protected] Fix time picker period selector a11y touch targets (flutter/flutter#170060)
2025-08-20 [email protected] Fix SegmentedButton focus issue (flutter/flutter#173953)
2025-08-20 [email protected] Roll Dart SDK from e936404543f1 to c5f5a32df36c (1 revision) (flutter/flutter#174089)
2025-08-20 [email protected] Roll Skia from 953bfc0e2f2a to 4b788d0e5e63 (1 revision) (flutter/flutter#174086)
2025-08-19 [email protected] Roll Skia from 07d71ea4d056 to 953bfc0e2f2a (18 revisions) (flutter/flutter#174072)
2025-08-19 [email protected] Roll Dart SDK from 9105d946af95 to e936404543f1 (5 revisions) (flutter/flutter#174074)
2025-08-19 [email protected] NavigationRail correct traversal order (flutter/flutter#173891)
2025-08-19 [email protected] Update CupertinoSliverNavigationBar.middle (flutter/flutter#173868)
2025-08-19 [email protected] Update the AccessibilityPlugin::Announce method to account for the view (flutter/flutter#172669)
2025-08-19 [email protected] [ Widget Preview ] Report an error if a web device is unavailable (flutter/flutter#174036)
2025-08-19 [email protected] [web] Fix error in ClickDebouncer when using VoiceOver (flutter/flutter#174046)
2025-08-19 [email protected] [ Tool ] Add logging to test_adapter_test.dart (flutter/flutter#174073)
2025-08-19 [email protected] Roll Fuchsia Linux SDK from n0EnLlotF2wczlOq_... to V1A1J6uXZ62Q10i9u... (flutter/flutter#174059)
2025-08-19 [email protected] Cleanup legacy `bringup: true` tasks, either removing or enabling (flutter/flutter#173815)
2025-08-19 [email protected] Add Shift+Enter shortcut example for TextField. (flutter/flutter#167952)
2025-08-19 [email protected] Check that the windows architecture is 64-bit and not the process architecture (flutter/flutter#174019)
2025-08-19 [email protected] Improve Stack widget error message for bounded constraints (flutter/flutter#173352)
2025-08-19 [email protected] [VPAT][A11y] AutoComplete dropdown option is missing button role (flutter/flutter#173297)
2025-08-19 [email protected] fix: Android build fails when minSdk is set below 24 in build.gradle.kts (#173823) (flutter/flutter#173825)
2025-08-19 [email protected] Reapply "Add set semantics enabled API and wire iOS a11y bridge (#161… (flutter/flutter#171198)
2025-08-19 [email protected] fix: only use library props for libraries (flutter/flutter#172704)
2025-08-19 [email protected] Roll Packages from 5c52c55 to 953cae0 (22 revisions) (flutter/flutter#174040)
2025-08-19 [email protected] Add `open_jdk` to `Linux linux_android_emulator.debug_x64` (flutter/flutter#173989)

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] 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
...
SydneyBao pushed a commit to SydneyBao/flutter that referenced this pull request Aug 22, 2025
…tter#172753)

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

Added an API to control the FocusNode of DropdownMenu Trailing
IconButton.

This is also an improvement to [DropdownMenu
Focus](flutter#156412) since
introducing the FocusNode to IconButton brings uniformity to the Focus
Traversal.

Previously there were two cases  
- If FocusNode is passed to DropdownMenu, 3 ```tab``` presses were
required to focus the Trailing IconButton
- If FocusNode is not passed then 3 ```tab``` presses were needed for
MacOS, Windows & Linux Platforms and 2 for Android, iOS & Fuchsia.

This PR allows Focusing the IconButton by single ```tab``` press

Fixes flutter#172687 by passing a FocusNode with ```skipTraversal:true```

### Before

- MacOS
-
https://github.com/user-attachments/assets/d2f6f3dd-e37c-4293-8c0e-6b73650a830b


- IOS without a FocusNode
-
https://github.com/user-attachments/assets/4a03bb98-faac-44b6-809d-9887941972c3


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/9f0f5e0d-6f20-4d21-af9b-52e3cb0014e5

###  After

- MacOS
-
https://github.com/user-attachments/assets/6d9d77be-760c-43f3-b23e-cef0dbdc3f47


- IOS without FocusNode
-
https://github.com/user-attachments/assets/2146dd72-9464-4af4-932d-f88463e6012c


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/035ce567-838d-4ed8-943c-5b508c1fd09f






## Pre-launch Checklist

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

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

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
SydneyBao pushed a commit to SydneyBao/flutter that referenced this pull request Aug 22, 2025
…tter#172753)

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

Added an API to control the FocusNode of DropdownMenu Trailing
IconButton.

This is also an improvement to [DropdownMenu
Focus](flutter#156412) since
introducing the FocusNode to IconButton brings uniformity to the Focus
Traversal.

Previously there were two cases  
- If FocusNode is passed to DropdownMenu, 3 ```tab``` presses were
required to focus the Trailing IconButton
- If FocusNode is not passed then 3 ```tab``` presses were needed for
MacOS, Windows & Linux Platforms and 2 for Android, iOS & Fuchsia.

This PR allows Focusing the IconButton by single ```tab``` press

Fixes flutter#172687 by passing a FocusNode with ```skipTraversal:true```

### Before

- MacOS
-
https://github.com/user-attachments/assets/d2f6f3dd-e37c-4293-8c0e-6b73650a830b


- IOS without a FocusNode
-
https://github.com/user-attachments/assets/4a03bb98-faac-44b6-809d-9887941972c3


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/9f0f5e0d-6f20-4d21-af9b-52e3cb0014e5

###  After

- MacOS
-
https://github.com/user-attachments/assets/6d9d77be-760c-43f3-b23e-cef0dbdc3f47


- IOS without FocusNode
-
https://github.com/user-attachments/assets/2146dd72-9464-4af4-932d-f88463e6012c


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/035ce567-838d-4ed8-943c-5b508c1fd09f






## Pre-launch Checklist

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

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

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
mboetger pushed a commit to mboetger/flutter that referenced this pull request Sep 18, 2025
…tter#172753)

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

Added an API to control the FocusNode of DropdownMenu Trailing
IconButton.

This is also an improvement to [DropdownMenu
Focus](flutter#156412) since
introducing the FocusNode to IconButton brings uniformity to the Focus
Traversal.

Previously there were two cases  
- If FocusNode is passed to DropdownMenu, 3 ```tab``` presses were
required to focus the Trailing IconButton
- If FocusNode is not passed then 3 ```tab``` presses were needed for
MacOS, Windows & Linux Platforms and 2 for Android, iOS & Fuchsia.

This PR allows Focusing the IconButton by single ```tab``` press

Fixes flutter#172687 by passing a FocusNode with ```skipTraversal:true```

### Before

- MacOS
-
https://github.com/user-attachments/assets/d2f6f3dd-e37c-4293-8c0e-6b73650a830b


- IOS without a FocusNode
-
https://github.com/user-attachments/assets/4a03bb98-faac-44b6-809d-9887941972c3


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/9f0f5e0d-6f20-4d21-af9b-52e3cb0014e5

###  After

- MacOS
-
https://github.com/user-attachments/assets/6d9d77be-760c-43f3-b23e-cef0dbdc3f47


- IOS without FocusNode
-
https://github.com/user-attachments/assets/2146dd72-9464-4af4-932d-f88463e6012c


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/035ce567-838d-4ed8-943c-5b508c1fd09f






## Pre-launch Checklist

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

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

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
korca0220 pushed a commit to korca0220/flutter that referenced this pull request Sep 22, 2025
…tter#172753)

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

Added an API to control the FocusNode of DropdownMenu Trailing
IconButton.

This is also an improvement to [DropdownMenu
Focus](flutter#156412) since
introducing the FocusNode to IconButton brings uniformity to the Focus
Traversal.

Previously there were two cases  
- If FocusNode is passed to DropdownMenu, 3 ```tab``` presses were
required to focus the Trailing IconButton
- If FocusNode is not passed then 3 ```tab``` presses were needed for
MacOS, Windows & Linux Platforms and 2 for Android, iOS & Fuchsia.

This PR allows Focusing the IconButton by single ```tab``` press

Fixes flutter#172687 by passing a FocusNode with ```skipTraversal:true```

### Before

- MacOS
-
https://github.com/user-attachments/assets/d2f6f3dd-e37c-4293-8c0e-6b73650a830b


- IOS without a FocusNode
-
https://github.com/user-attachments/assets/4a03bb98-faac-44b6-809d-9887941972c3


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/9f0f5e0d-6f20-4d21-af9b-52e3cb0014e5

###  After

- MacOS
-
https://github.com/user-attachments/assets/6d9d77be-760c-43f3-b23e-cef0dbdc3f47


- IOS without FocusNode
-
https://github.com/user-attachments/assets/2146dd72-9464-4af4-932d-f88463e6012c


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/035ce567-838d-4ed8-943c-5b508c1fd09f






## Pre-launch Checklist

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

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

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Jaineel-Mamtora pushed a commit to Jaineel-Mamtora/flutter_forked that referenced this pull request Sep 24, 2025
…tter#172753)

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

Added an API to control the FocusNode of DropdownMenu Trailing
IconButton.

This is also an improvement to [DropdownMenu
Focus](flutter#156412) since
introducing the FocusNode to IconButton brings uniformity to the Focus
Traversal.

Previously there were two cases  
- If FocusNode is passed to DropdownMenu, 3 ```tab``` presses were
required to focus the Trailing IconButton
- If FocusNode is not passed then 3 ```tab``` presses were needed for
MacOS, Windows & Linux Platforms and 2 for Android, iOS & Fuchsia.

This PR allows Focusing the IconButton by single ```tab``` press

Fixes flutter#172687 by passing a FocusNode with ```skipTraversal:true```

### Before

- MacOS
-
https://github.com/user-attachments/assets/d2f6f3dd-e37c-4293-8c0e-6b73650a830b


- IOS without a FocusNode
-
https://github.com/user-attachments/assets/4a03bb98-faac-44b6-809d-9887941972c3


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/9f0f5e0d-6f20-4d21-af9b-52e3cb0014e5

###  After

- MacOS
-
https://github.com/user-attachments/assets/6d9d77be-760c-43f3-b23e-cef0dbdc3f47


- IOS without FocusNode
-
https://github.com/user-attachments/assets/2146dd72-9464-4af4-932d-f88463e6012c


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/035ce567-838d-4ed8-943c-5b508c1fd09f






## Pre-launch Checklist

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

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

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 12, 2025
lucaantonelli pushed a commit to lucaantonelli/flutter that referenced this pull request Nov 21, 2025
…tter#172753)

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

Added an API to control the FocusNode of DropdownMenu Trailing
IconButton.

This is also an improvement to [DropdownMenu
Focus](flutter#156412) since
introducing the FocusNode to IconButton brings uniformity to the Focus
Traversal.

Previously there were two cases  
- If FocusNode is passed to DropdownMenu, 3 ```tab``` presses were
required to focus the Trailing IconButton
- If FocusNode is not passed then 3 ```tab``` presses were needed for
MacOS, Windows & Linux Platforms and 2 for Android, iOS & Fuchsia.

This PR allows Focusing the IconButton by single ```tab``` press

Fixes flutter#172687 by passing a FocusNode with ```skipTraversal:true```

### Before

- MacOS
-
https://github.com/user-attachments/assets/d2f6f3dd-e37c-4293-8c0e-6b73650a830b


- IOS without a FocusNode
-
https://github.com/user-attachments/assets/4a03bb98-faac-44b6-809d-9887941972c3


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/9f0f5e0d-6f20-4d21-af9b-52e3cb0014e5

###  After

- MacOS
-
https://github.com/user-attachments/assets/6d9d77be-760c-43f3-b23e-cef0dbdc3f47


- IOS without FocusNode
-
https://github.com/user-attachments/assets/2146dd72-9464-4af4-932d-f88463e6012c


- IOS with a FocusNode
-
https://github.com/user-attachments/assets/035ce567-838d-4ed8-943c-5b508c1fd09f






## Pre-launch Checklist

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

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

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
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.

Option to skip DropdownMenu TrailingIcon Focus when navigating via Keyboard

6 participants