224 Commits

Author SHA1 Message Date
Huy
fec18f6e4a
Fix draggable scrollable sheet example drag speed is off (#179179)
- Fix https://github.com/flutter/flutter/issues/179102
- In this PR:
- Fix the sheet position so that it will follow the pointer, even when
dragging mouse beyond the window then returns inside.
    - Some improvement for coding convention:
- declare minChildSize and maxChildSize const(s) then use them in the
hardcoded positions
- move `_isOnDesktopAndWeb` out of Grabber, so it's easier to see
Grabber widget purpose when reading the code

<details open>
<summary>Demo</summary>

| before | after |
| --------------- | --------------- |
<img width="360"
src="https://github.com/user-attachments/assets/5f4f507d-1491-47a2-90a6-c2a32ecdf6b5">
| <img width="360"
src="https://github.com/user-attachments/assets/b2eb9ede-572e-4fcb-81c1-2269b8db2140">

</details>

## 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.
- [ ] 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].
- [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].

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

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

---------

Signed-off-by: huycozy <huy@nevercode.io>
2025-12-12 06:29:20 +00:00
Pacific
2c4e7ebfd9
Fixed RenderFlex overflow in RouteObserver Example (#170980)
Fixed RenderOverflow in RouteObserver Example:
https://api.flutter.dev/flutter/widgets/RouteObserver-class.html

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

This PR is about solving render overflow issue in Route Observer Example
in Live Website. I've wrapped the body with a Scrollable View to solve
this issue

| | |
| --- | --- |
| B |
![image](https://github.com/user-attachments/assets/c8fa78e7-62ca-4bd1-9798-588c636cd61a)
|
| A |
![image](https://github.com/user-attachments/assets/3a2b4697-121a-43e3-9c85-b1379a575af1)
|

## 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].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] 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].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.


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

---------

Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
2025-12-10 20:53:33 +00:00
Mohellebi abdessalem
15f944a9d6
Enhance documentation for LocalHistoryEntry class (#179223)
Fixes : #11660

## 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 `///`).
- [ ] 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].

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

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

---------

Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
2025-12-09 22:14:21 +00:00
Loïc Sharma
d248a651b6
Add flutter_lints to samples (#179091)
I recommend reviewing each commit individually.

The following were suppressed instead of migrated to minimize the time
the tree is closed:

1. The [`Radio` -> `RadioGroup`
migration](https://docs.flutter.dev/release/breaking-changes/radio-api-redesign).
Tracked by: https://github.com/flutter/flutter/issues/179088.

Part of: https://github.com/flutter/flutter/issues/178827

## 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].

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

<!-- 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
2025-11-26 22:11:20 +00:00
Matthew Kosarek
084deda0ba
Add tooltip windows to the windowing API alongside the window positioning logic (#177404)
## What's new?
- Added tooltips to the windowing API, but they have no implementation
for the time being
- Added the `WindowPostiioner` logic to the windowing API
- Wrote a lot of tests 🧪 

## 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.
2025-11-25 15:23:04 +00:00
Bernardo Ferrari
1814874c2d
Add a RepeatingAnimationBuilder API (#174014)
Implements / Close https://github.com/flutter/flutter/issues/174011

Probably there are 400 LOC of comments + tests, so this removes more
code than adds.

<img width="1509" height="649" alt="diff"
src="https://github.com/user-attachments/assets/cd961ddc-3b79-4ffd-8e9a-a806d5743f17"
/>
2025-11-15 05:17:26 +00:00
Camille Simon
7fd228f31d
[Material] Change default mouse cursor of buttons to basic arrow instead of click (except on web) (#171796)
Changes default mouse cursor of Material buttons to basic arrow instead
of click as per updated Android guidance.

For each Material button, I did the following:

1. Changed the default mouse cursor to the basic arrow.
2. Added a way to configure the mouse cursor of the button if a method
did not exist before.
3. Added a test to ensure that the default mouse cursor is now the basic
arrow (or modified an existing one if applicable).
4. Added a test to ensure that the customization of button mouse cursors
still works (if currently untested).

The list of Material buttons I modified (supposed to be all of them):

- RawMaterialButton
- DropdownButton
- FloatingActionButton
- ToggleButtons
- ElevatedButton
- IconButton
- FilledButton
- OutlinedButton
- PopupMenuItem
- InkWell
- TextButton
- MaterialButton
- DropdownMenuItem
- DropdownButtonFormField
- BackButton
- CloseButton
- DrawerButton
- EndDrawerButton
- PopupMenuButton
- MenuItemButton
- CheckboxMenuButton
- RadioMenuButton
- MenuBar
- SubmenuButton
- SegmentedButton
- FilterChip
- ChoiceChip
- ActionChip
- InputChip

Fixes https://github.com/flutter/flutter/issues/170296.

## 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].
- [ ] 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

---------

Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
2025-10-23 22:24:00 +00:00
Mohellebi abdessalem
28a1d0b9be
Update image.error_builder.0.dart to replace the emoji with some text (#176886)
fixes #174805
after some investigation i found that `dart doc ` only understands
`utf-8 encoding` so providing an `emoji` for example breaks it(no crash
but not the intended behavior).

## 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 `///`).
- [ ] 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].

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

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

---------

Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
2025-10-20 20:40:09 +00:00
Valentin Vignal
f973b2f13c
Migrate to WidgetStateOutlinedBorder (#176270)
Follow up https://github.com/flutter/flutter/pull/176164

Migrate the remaining files from `MaterialStateOutlinedBorder ` to
`WidgetStateOutlinedBorder `. This PR only focus on
`WidgetStateOutlinedBorder`.

- This minimizes conflicts and reduces the size of the PR for easier
reviews and follow up
- I'll work on the other elements of
`packages/flutter/lib/src/material/material_state.dart` into other PRs

## 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].
- [ ] 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].

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

<!-- 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
2025-10-01 18:54:58 +00:00
Kishan Rathore
de932b3e09
Refactor: Migrate page transition builder class to widgets (#174321)
Changes
* Move PageTransitionsBuilder from
`material/page_transitions_theme.dart` to
`widget/page_transitions_builder.dart`

part of: #172929

## 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 `///`).
- [ ] 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.
2025-09-17 17:50:04 +00:00
Jing Shao
cb04accbf2
[iOS][Secure Paste] Custom edit menu actions (#171825)
<!--
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
-->

This PR implements support for custom action items in the native edit
menu on iOS, with changes to both framework and engine. This PR will be
updated incrementally until the full feature is complete.

Phase 1: Add hardcoded custom menu item for iOS edit menu.
Phase 2: Add Framework API for custom iOS context menu items.
Phase 3: Add Optimization, Testing, and Documentation. 

Part of https://github.com/flutter/flutter/issues/103163 

Part of https://github.com/flutter/flutter/issues/140184

*If you had to change anything in the [flutter/tests] repo, include a
link to the migration guide as per the [breaking change policy].*

## 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].
- [ ] 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
2025-08-26 05:11:45 +00:00
Justin McCandless
2c031ed023
Reland predictive back route transitions by default (#173860)
Relands https://github.com/flutter/flutter/pull/165832 by reverting
flutter/flutter#173809.
2025-08-15 22:40:14 +00:00
auto-submit[bot]
0e57a627f5
Reverts "Predictive back route transitions by default (#165832)" (#173809)
<!-- start_original_pr_link -->
Reverts: flutter/flutter#165832
<!-- end_original_pr_link -->
<!-- start_initiating_author -->
Initiated by: matanlurey
<!-- end_initiating_author -->
<!-- start_revert_reason -->
Reason for reverting: Breaks `Linux_pixel_7pro
embedded_android_views_integration_test`:

-
https://ci.chromium.org/ui/p/flutter/builders/prod/Linux_pixel_7pro%20embedded_android_views_integration_test/8918/overview
-
https://ci.chromium.org/ui/p/flutter/builders/prod/Linux_pixel_7pro%20embedded_android_views_integration_test/8917/overview

```txt
[2025-08-14 16:01:17.600761] [STDOUT] stdout: [   +1 ms]   Expecte
<!-- end_revert_reason -->
<!-- start_original_pr_author -->
Original PR Author: justinmc
<!-- end_original_pr_author -->

<!-- start_reviewers -->
Reviewed By: {QuncCccccc}
<!-- end_reviewers -->

<!-- start_revert_body -->
This change reverts the following previous change:
This PR turns on predictive back route transitions by default on supported Android devices.

With https://github.com/flutter/flutter/pull/154718, the default (PredictiveBackPageTransitionsBuilder) is the [shared element transition](https://developer.android.com/design/ui/mobile/guides/patterns/predictive-back#shared-element-transition). The [full screen transition](https://developer.android.com/design/ui/mobile/guides/patterns/predictive-back#full-screen-surfaces) is also available by using PredictiveBackFullScreenPageTransitionsBuilder.

Original PR: https://github.com/flutter/flutter/pull/146788

Depends on: https://github.com/flutter/flutter/pull/154718

When this lands in stable, the docs should be updated: https://docs.flutter.dev/platform-integration/android/predictive-back
<!-- end_revert_body -->

Co-authored-by: auto-submit[bot] <flutter-engprod-team@google.com>
2025-08-14 23:38:48 +00:00
Justin McCandless
d1e2019a94
Predictive back route transitions by default (#165832)
This PR turns on predictive back route transitions by default on
supported Android devices.

With https://github.com/flutter/flutter/pull/154718, the default
(PredictiveBackPageTransitionsBuilder) is the [shared element
transition](https://developer.android.com/design/ui/mobile/guides/patterns/predictive-back#shared-element-transition).
The [full screen
transition](https://developer.android.com/design/ui/mobile/guides/patterns/predictive-back#full-screen-surfaces)
is also available by using
PredictiveBackFullScreenPageTransitionsBuilder.

Original PR: https://github.com/flutter/flutter/pull/146788

Depends on: https://github.com/flutter/flutter/pull/154718

When this lands in stable, the docs should be updated:
https://docs.flutter.dev/platform-integration/android/predictive-back
2025-08-14 20:39:12 +00:00
Loïc Sharma
443f6760b1
Add a SliverList code sample (#172986)
This adds a code sample to `SliverList`. It shows off the
`SliverList.builder` convenience constructor. Hopefully this will guide
LLMs to using this instead of manually creating a delegate.

## 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].
- [ ] 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].

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

<!-- 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
2025-07-31 16:14:07 +00:00
Justin McCandless
9b93519698
Route transition duration (#171109)
We need a robust way to get the duration of a route transition in tests,
so that tests can remain independent of the type of route transition and
its duration.

With this PR, this will be the canonical way to pump until a page
transition has finished:

```dart
testWidgets('example', (WidgetTester tester) async {
  final TransitionDurationObserver observer = TransitionDurationObserver();

  await tester.pumpWidget(
    MaterialApp(
      navigatorObservers: <NavigatorObserver>[observer],
      onGenerateRoute: (RouteSettings settings) { ... },
    ),
  );

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsNothing);

  // Pump through the whole transition.
  await tester.tap(find.text('Next'));
  await observer.pumpPastTransition(tester);

  expect(find.text('Page 1'), findsNothing);
  expect(find.text('Page 2'), findsOneWidget);

  // Or, pump through part of a transition with the duration.
  await tester.tap(find.text('Back'));
  await tester.pump(observer.transitionDuration ~/ 2);

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsOneWidget);
});
```

This was spun out of https://github.com/flutter/flutter/pull/165832,
where updating the default route transition and its duration broke tests
in the framework, in customer tests, and in Google tests.

FYI @chrisbobbe

---------

Co-authored-by: Jing Shao <87506348+jingshao-code@users.noreply.github.com>
2025-07-14 22:49:04 +00:00
Kate Lovett
a04fb324be
Bump Dart to 3.8 and reformat (#171703)
Bumps the Dart version to 3.8 across the repo (excluding
engine/src/flutter/third_party) and applies formatting updates from Dart
3.8.

## 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].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] 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
2025-07-07 17:58:32 +00:00
davidhicks980
86767f6663
[widgets/raw_menu_anchor.3.dart] Replace arrow character with Icon in RawMenuAnchor submenu example (#171218)
Replaces the arrow character with an icon on the RawMenuAnchor animated
submenu example. Currently, submenu arrows render as gibberish.
Apologies to chunhtai since this is the second time I've done this.

<img width="500" alt="image"
src="https://github.com/user-attachments/assets/866220e3-3d09-4502-9aee-211dc333822d"
/>

## 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
2025-06-27 07:29:28 +00:00
davidhicks980
dfadc91433
Add RawMenuAnchor animation callbacks (#167806)
Alternative to https://github.com/flutter/flutter/pull/163481,
https://github.com/flutter/flutter/pull/167537,
https://github.com/flutter/flutter/pull/163481 that uses callbacks.

@dkwingsmt - you inspired me to simplify the menu behavior. I didn't end
up using Actions, mainly because nested behavior was unwieldy and
capturing BuildContext has drawbacks. This uses a basic callback
mechanism to animate the menu open and closed. Check out the examples.

<hr />

### The problem
RawMenuAnchor synchronously shows or hides an overlay menu in response
to `MenuController.open()` and `MenuController.close`, respectively.
Because animations cannot be run on a hidden overlay, there currently is
no way for developers to add animations to RawMenuAnchor and its
subclasses (MenuAnchor, DropdownMenuButton, etc).

### The solution
This PR:
- Adds two callbacks -- `onOpenRequested` and `onCloseRequested` -- to
RawMenuAnchor.
- onOpenRequested is called with a position and a showOverlay callback,
which opens the menu when called.
- onCloseRequested is called with a hideOverlay callback, which hides
the menu when called.

When `MenuController.open()` and `MenuController.close()` are called,
onOpenRequested and onCloseRequested are invoked, respectively.

Precursor for https://github.com/flutter/flutter/pull/143416,
https://github.com/flutter/flutter/issues/135025,
https://github.com/flutter/flutter/pull/143712

## Demo


https://github.com/user-attachments/assets/bb14abca-af26-45fe-8d45-289b5d07dab2

```dart
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: public_member_api_docs

import 'dart:ui' as ui;

import 'package:flutter/material.dart' hide MenuController, RawMenuAnchor, RawMenuOverlayInfo;

import 'raw_menu_anchor.dart';

/// Flutter code sample for a [RawMenuAnchor] that animates a simple menu using
/// [RawMenuAnchor.onOpenRequested] and [RawMenuAnchor.onCloseRequested].
void main() {
  runApp(const App());
}

class Menu extends StatefulWidget {
  const Menu({super.key});

  @override
  State<Menu> createState() => _MenuState();
}

class _MenuState extends State<Menu> with SingleTickerProviderStateMixin {
  late final AnimationController animationController;
  final MenuController menuController = MenuController();

  @override
  void initState() {
    super.initState();
    animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 300),
    );
  }

  @override
  void dispose() {
    animationController.dispose();
    super.dispose();
  }

  void _handleMenuOpenRequest(Offset? position, void Function({Offset? position}) showOverlay) {
    // Mount or reposition the menu before animating the menu open.
    showOverlay(position: position);

    if (animationController.isForwardOrCompleted) {
      // If the menu is already open or opening, the animation is already
      // running forward.
      return;
    }

    // Animate the menu into view. This will cancel the closing animation.
    animationController.forward();
  }

  void _handleMenuCloseRequest(VoidCallback hideOverlay) {
    if (!animationController.isForwardOrCompleted) {
      // If the menu is already closed or closing, do nothing.
      return;
    }

    // Animate the menu out of view.
    //
    // Be sure to use `whenComplete` so that the closing animation
    // can be interrupted by an opening animation.
    animationController.reverse().whenComplete(() {
      if (mounted) {
        // Hide the menu after the menu has closed
        hideOverlay();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return RawMenuAnchor(
      controller: menuController,
      onOpenRequested: _handleMenuOpenRequest,
      onCloseRequested: _handleMenuCloseRequest,
      overlayBuilder: (BuildContext context, RawMenuOverlayInfo info) {
        final ui.Offset position = info.anchorRect.bottomLeft;
        return Positioned(
          top: position.dy + 5,
          left: position.dx,
          child: TapRegion(
            groupId: info.tapRegionGroupId,
            child: Material(
              color: ColorScheme.of(context).primaryContainer,
              shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
              elevation: 3,
              child: SizeTransition(
                sizeFactor: animationController,
                child: const SizedBox(
                  height: 200,
                  width: 150,
                  child: Center(child: Text('Howdy', textAlign: TextAlign.center)),
                ),
              ),
            ),
          ),
        );
      },
      builder: (BuildContext context, MenuController menuController, Widget? child) {
        return FilledButton(
          onPressed: () {
            if (animationController.isForwardOrCompleted) {
              menuController.close();
            } else {
              menuController.open();
            }
          },
          child: const Text('Toggle Menu'),
        );
      },
    );
  }
}

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue)),
      home: const Scaffold(body: Center(child: Menu())),
    );
  }
}

```

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

---------

Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
2025-06-24 17:46:50 +00:00
chunhtai
d0058ec361
Adds radio group widget r2 (#168161)
<!--
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
-->

previous https://github.com/flutter/flutter/pull/167363

I have to factor out abstract class for RadioGroupRegistry and
RadioClient which are subclassed by RadioGroupState and RawRadio
respectively.

I have to do this because the RadioListTile that has 2 focusnode one for
listTile and one for the radio it builds. The issue is that RadioGroup's
keyboard shortcut has to tightly couples with the focus node of each
radio, but the radioListtile has to mute the radio's focusnode so it can
act as one control under keyboard shortcut

d582b35809/packages/flutter/lib/src/material/radio_list_tile.dart (L484)

Therefore i abstract the out the logic of RadioGroup so that another
widget can participate by implementing the interface.

fixes https://github.com/flutter/flutter/issues/113562

migration guide: https://github.com/flutter/website/pull/12080/files

## 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].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] 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
2025-06-02 19:03:51 +00:00
Valentin Vignal
c6ceffa2e7
Add documentation examples to KeepAlive AutomaticKeepAlive and AutomaticKeepAliveClientMixin (#168137)
Part of https://github.com/flutter/flutter/issues/153860



https://github.com/user-attachments/assets/8fd233da-d1b1-417a-8854-8d16c3ad195b



https://github.com/user-attachments/assets/93197949-b962-483e-bb8f-02db5206674c



https://github.com/user-attachments/assets/ad4f4091-6ed3-4a13-bcf3-f8572ce87481



## 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
2025-05-02 07:03:35 +00:00
Renzo Olivares
fc12bec5ec
Reland "SliverEnsureSemantics (#165589)" (#166889)
This reverts commit 2fc716d, and updates the cross-axis size of the
`_scrollOverflowElement` to be 1px (non-zero), so it is taken into
account by the scrollable elements scrollHeight.

Fixes #160217

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

---------

Co-authored-by: Renzo Olivares <roliv@google.com>
2025-04-11 00:51:26 +00:00
auto-submit[bot]
2fc716dbeb
Reverts "SliverEnsureSemantics (#165589)" (#166870)
<!-- start_original_pr_link -->
Reverts: flutter/flutter#165589
<!-- end_original_pr_link -->
<!-- start_initiating_author -->
Initiated by: Renzo-Olivares
<!-- end_initiating_author -->
<!-- start_revert_reason -->
Reason for reverting: breaking internal tests
<!-- end_revert_reason -->
<!-- start_original_pr_author -->
Original PR Author: Renzo-Olivares
<!-- end_original_pr_author -->

<!-- start_reviewers -->
Reviewed By: {Piinks}
<!-- end_reviewers -->

<!-- start_revert_body -->
This change reverts the following previous change:
Currently when using a `CustomScrollView`, screen readers cannot list or
move focus to elements that are outside the current Viewport and cache
extent because we do not create semantic nodes for these elements.

This change introduces `SliverEnsureSemantics` which ensures its sliver
child is included in the semantics tree, whether or not it is currently
visible on the screen or within the cache extent. This way screen
readers are aware the elements are there and can navigate to them /
create accessibility traversal menus with this information.
* Under the hood a new flag has been added to `RenderSliver` called
`ensureSemantics`. `RenderViewportBase` uses this in its
`visitChildrenForSemantics` to ensure a sliver is visited when creating
the semantics tree. Previously a sliver was not visited if it was not
visible or within the cache extent. `RenderViewportBase` also uses this
in `describeSemanticsClip` and `describeApproximatePaintClip` to ensure
a sliver child that wants to "ensure semantics" is not clipped out if it
is not currently visible in the viewport or outside the cache extent.
* `RenderSliverMultiBoxAdaptor.semanticBounds` now leverages its first
child as an anchor for assistive technologies to be able to reach it if
the Sliver is a child of `SliverEnsureSemantics`. If not it will still
be dropped from the semantics tree.
* `RenderProxySliver` now considers child overrides of `semanticBounds`.

On the engine side we move from using a joystick method to scroll with
`SemanticsAction.scrollUp` and `SemanticsAction.scrollDown` to using
`SemanticsAction.scrollToOffset` completely letting the browser drive
the scrolling with its current dom scroll position "scrollTop" or
"scrollLeft". This is possible by calculating the total quantity of
content under the scrollable and sizing the scroll element based on
that.

<details open><summary>Code sample</summary>

```dart
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

/// Flutter code sample for [SliverEnsureSemantics].

void main() => runApp(const SliverEnsureSemanticsExampleApp());

class SliverEnsureSemanticsExampleApp extends StatelessWidget {
  const SliverEnsureSemanticsExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: SliverEnsureSemanticsExample());
  }
}

class SliverEnsureSemanticsExample extends StatefulWidget {
  const SliverEnsureSemanticsExample({super.key});

  @override
  State<SliverEnsureSemanticsExample> createState() =>
      _SliverEnsureSemanticsExampleState();
}

class _SliverEnsureSemanticsExampleState
    extends State<SliverEnsureSemanticsExample> {
  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    return Scaffold(
      appBar: AppBar(
        backgroundColor: theme.colorScheme.inversePrimary,
        title: const Text('SliverEnsureSemantics Demo'),
      ),
      body: Center(
        child: CustomScrollView(
          semanticChildCount: 106,
          slivers: <Widget>[
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 0,
                  child: Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Steps to reproduce',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                          const Text('Issue description'),
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Expected Results',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Actual Results',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Code Sample',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Screenshots',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Logs',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ),
            ),
            SliverFixedExtentList(
              itemExtent: 44.0,
              delegate: SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                  return Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text('Item $index'),
                    ),
                  );
                },
                childCount: 50,
                semanticIndexOffset: 1,
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 51,
                  child: Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Semantics(
                        header: true,
                        child: const Text('Footer 1'),
                      ),
                    ),
                  ),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 52,
                  child: Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Semantics(
                        header: true,
                        child: const Text('Footer 2'),
                      ),
                    ),
                  ),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 53,
                  child: Semantics(link: true, child: const Text('Link #1')),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 54,
                  child: OverflowBar(
                    children: <Widget>[
                      TextButton(
                        onPressed: () {},
                        child: const Text('Button 1'),
                      ),
                      TextButton(
                        onPressed: () {},
                        child: const Text('Button 2'),
                      ),
                    ],
                  ),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 55,
                  child: Semantics(link: true, child: const Text('Link #2')),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverSemanticsList(
                sliver: SliverFixedExtentList(
                  itemExtent: 44.0,
                  delegate: SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                      return Semantics(
                        role: SemanticsRole.listItem,
                        child: Card(
                          child: Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text('Second List Item $index'),
                          ),
                        ),
                      );
                    },
                    childCount: 50,
                    semanticIndexOffset: 56,
                  ),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 107,
                  child: Semantics(link: true, child: const Text('Link #3')),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// A sliver that assigns the role of SemanticsRole.list to its sliver child.
class SliverSemanticsList extends SingleChildRenderObjectWidget {
  const SliverSemanticsList({super.key, required Widget sliver})
    : super(child: sliver);

  @override
  RenderSliverSemanticsList createRenderObject(BuildContext context) =>
      RenderSliverSemanticsList();
}

class RenderSliverSemanticsList extends RenderProxySliver {
  @override
  void describeSemanticsConfiguration(SemanticsConfiguration config) {
    super.describeSemanticsConfiguration(config);
    config.role = SemanticsRole.list;
  }
}
```
</details>

Fixes: #160217

## 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.
<!-- end_revert_body -->

Co-authored-by: auto-submit[bot] <flutter-engprod-team@google.com>
2025-04-09 18:27:48 +00:00
Renzo Olivares
3fa9b38705
SliverEnsureSemantics (#165589)
Currently when using a `CustomScrollView`, screen readers cannot list or
move focus to elements that are outside the current Viewport and cache
extent because we do not create semantic nodes for these elements.

This change introduces `SliverEnsureSemantics` which ensures its sliver
child is included in the semantics tree, whether or not it is currently
visible on the screen or within the cache extent. This way screen
readers are aware the elements are there and can navigate to them /
create accessibility traversal menus with this information.
* Under the hood a new flag has been added to `RenderSliver` called
`ensureSemantics`. `RenderViewportBase` uses this in its
`visitChildrenForSemantics` to ensure a sliver is visited when creating
the semantics tree. Previously a sliver was not visited if it was not
visible or within the cache extent. `RenderViewportBase` also uses this
in `describeSemanticsClip` and `describeApproximatePaintClip` to ensure
a sliver child that wants to "ensure semantics" is not clipped out if it
is not currently visible in the viewport or outside the cache extent.
* `RenderSliverMultiBoxAdaptor.semanticBounds` now leverages its first
child as an anchor for assistive technologies to be able to reach it if
the Sliver is a child of `SliverEnsureSemantics`. If not it will still
be dropped from the semantics tree.
* `RenderProxySliver` now considers child overrides of `semanticBounds`.

On the engine side we move from using a joystick method to scroll with
`SemanticsAction.scrollUp` and `SemanticsAction.scrollDown` to using
`SemanticsAction.scrollToOffset` completely letting the browser drive
the scrolling with its current dom scroll position "scrollTop" or
"scrollLeft". This is possible by calculating the total quantity of
content under the scrollable and sizing the scroll element based on
that.

<details open><summary>Code sample</summary>

```dart
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

/// Flutter code sample for [SliverEnsureSemantics].

void main() => runApp(const SliverEnsureSemanticsExampleApp());

class SliverEnsureSemanticsExampleApp extends StatelessWidget {
  const SliverEnsureSemanticsExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: SliverEnsureSemanticsExample());
  }
}

class SliverEnsureSemanticsExample extends StatefulWidget {
  const SliverEnsureSemanticsExample({super.key});

  @override
  State<SliverEnsureSemanticsExample> createState() =>
      _SliverEnsureSemanticsExampleState();
}

class _SliverEnsureSemanticsExampleState
    extends State<SliverEnsureSemanticsExample> {
  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    return Scaffold(
      appBar: AppBar(
        backgroundColor: theme.colorScheme.inversePrimary,
        title: const Text('SliverEnsureSemantics Demo'),
      ),
      body: Center(
        child: CustomScrollView(
          semanticChildCount: 106,
          slivers: <Widget>[
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 0,
                  child: Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Steps to reproduce',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                          const Text('Issue description'),
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Expected Results',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Actual Results',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Code Sample',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Screenshots',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                          Semantics(
                            header: true,
                            headingLevel: 3,
                            child: Text(
                              'Logs',
                              style: theme.textTheme.headlineSmall,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ),
            ),
            SliverFixedExtentList(
              itemExtent: 44.0,
              delegate: SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                  return Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text('Item $index'),
                    ),
                  );
                },
                childCount: 50,
                semanticIndexOffset: 1,
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 51,
                  child: Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Semantics(
                        header: true,
                        child: const Text('Footer 1'),
                      ),
                    ),
                  ),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 52,
                  child: Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Semantics(
                        header: true,
                        child: const Text('Footer 2'),
                      ),
                    ),
                  ),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 53,
                  child: Semantics(link: true, child: const Text('Link #1')),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 54,
                  child: OverflowBar(
                    children: <Widget>[
                      TextButton(
                        onPressed: () {},
                        child: const Text('Button 1'),
                      ),
                      TextButton(
                        onPressed: () {},
                        child: const Text('Button 2'),
                      ),
                    ],
                  ),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 55,
                  child: Semantics(link: true, child: const Text('Link #2')),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverSemanticsList(
                sliver: SliverFixedExtentList(
                  itemExtent: 44.0,
                  delegate: SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                      return Semantics(
                        role: SemanticsRole.listItem,
                        child: Card(
                          child: Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text('Second List Item $index'),
                          ),
                        ),
                      );
                    },
                    childCount: 50,
                    semanticIndexOffset: 56,
                  ),
                ),
              ),
            ),
            SliverEnsureSemantics(
              sliver: SliverToBoxAdapter(
                child: IndexedSemantics(
                  index: 107,
                  child: Semantics(link: true, child: const Text('Link #3')),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// A sliver that assigns the role of SemanticsRole.list to its sliver child.
class SliverSemanticsList extends SingleChildRenderObjectWidget {
  const SliverSemanticsList({super.key, required Widget sliver})
    : super(child: sliver);

  @override
  RenderSliverSemanticsList createRenderObject(BuildContext context) =>
      RenderSliverSemanticsList();
}

class RenderSliverSemanticsList extends RenderProxySliver {
  @override
  void describeSemanticsConfiguration(SemanticsConfiguration config) {
    super.describeSemanticsConfiguration(config);
    config.role = SemanticsRole.list;
  }
}
```
</details>

Fixes: #160217

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

---------

Co-authored-by: Renzo Olivares <roliv@google.com>
2025-04-09 01:58:11 +00:00
Hannes Hultergård
6958d086bc
Add action for configuring default action of EditableText.onTapUpOutside (#162575)
This PR adds an `Action` for configuring a default action of
`EditableText.onTapUpOutside`. This is the equivalent to what
https://github.com/flutter/flutter/pull/150125 did for
`EditableText.onTapOutside`.

Fixes https://github.com/flutter/flutter/issues/162212

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

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

---------

Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
2025-02-28 19:01:33 +00:00
davidhicks980
d48820528c
[raw_menu_anchor.0.dart] Remove misdrawn emojis. (#162807)
This PR removes the leading emojis displayed on the RawMenuAnchor
example. I knew emojis usually showed up monochrome on web, but code
samples also appear to incorrectly display the emoji source.

Because this change doesn't affect the menu's functionality, I didn't
include additional tests, but I'd be happy to add tests if needed. One
test was modified to account for menu items no longer having a leading
icon.

<img width="1247" alt="image"
src="https://github.com/user-attachments/assets/58a338c8-c882-4ad1-af44-596d91e9f382"
/>

Fixes https://github.com/flutter/flutter/issues/162806

## 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 `///`).
- [ ] 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

---------

Co-authored-by: Tirth <pateltirth454@gmail.com>
2025-02-07 20:45:35 +00:00
davidhicks980
b29f8f7fb9
Implement RawMenuAnchor (#158255)
This PR adds a `RawMenuAnchor()` widget to widgets.dart. The purpose of
this widget is to provide a menu primitive for the Material and
Cupertino libraries (and others) to build upon. Additionally, this PR
makes MenuController an inherited widget to simplify nested access to
the menu (e.g. if you want to launch a context menu from a deeply-nested
widget).

This PR:
* Centralizes core menu logic to a private class,` _RawMenuAnchor()`, 
  * Provides the internals for interacting with menus:
    * TapRegion interop
    * DismissMenuAction handler
    * Close on scroll/resize
    * Focus traversal information, if applicable
* Subclasses override `_open`, `_close`, `_isOpen`, `_buildAnchor`, and
`_menuScopeNode`
* State is accessible by descendents via
`MenuController.maybeOf(context)._anchor`
* Adds 2 public constructors, backed by a `_RawMenuAnchor()` that
contains shared logic.
  * `RawMenuAnchor()`
    * Users build the overlay from scratch.
* Provides anchor/overlay position information and TapRegionGroupId to
builder
    * Does not provide FocusScope management. 
  * `RawMenuAnchorGroup()`
    * A primitive for menus that do not have overlays (menu bars). 
* This was previously called RawMenuAnchor.node(), but @dkwingsmt made a
good case for splitting out the constructor.

<s>Documentation examples have been added, and can be viewed at
https://menu-anchor.web.app/</s>


<s>https://github.com/user-attachments/assets/25d35f23-2aad-4d07-9172-5c3fd65d53cf</s>

@dkwingsmt 

List which issues are fixed by this PR.
https://github.com/flutter/flutter/pull/143712

Some issues that need to be addressed:

Semantics:
<img width="1027" alt="image"
src="https://github.com/user-attachments/assets/d69661c9-8435-4d9c-b200-474968cb57eb">
I'm basing the menu semantics off of the comment
[here](ef3ca70db2/lib/web_ui/lib/src/engine/semantics/semantics.dart (L382)),
but I'm unsure whether the route should be given a name. There is no
menubar/menu/menuitem role in Flutter, so I'm assuming the menu should
be composed of nested dialogs

<s>Unlike the menubar pattern from
[W3C](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-navigation/),
the RawMenuAnchor

- does not close on tab/shift-tab. I left this behavior out of the menu
so that users could customize tab behavior, but I'm not opinionated
either way
- does not open on ArrowUp/ArrowDown, because this could interfere with
user focus behavior in unconventional menu setups (e.g. a vertical
menu).
- does not automatically focus the first item in a menu overlay when
activated via enter/spacebar, but does focus the first item when
horizontal traversal opens a submenu. Automatically focusing the first
item whenever an overlay opens interferes with hover traversal, and I
couldn't think of a good way to only focus the first item when an
overlay is triggered via enter/spacebar.
- doesn't focus disabled items (I wasn't sure how to address this
without editing MenuItemButton)

While it is possible to nest menus -- for example, a dropdown anchor
within a full-app context menu area -- nested menus behave as a single
group. I was considering adding an additional parameter that separates
nested root menus from their parents, and am interested to hear your
feedback.</s>

*If you had to change anything in the [flutter/tests] repo, include a
link to the migration guide as per the [breaking change policy].*

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

---------

Co-authored-by: Bruno Leroux <bruno.leroux@gmail.com>
Co-authored-by: chunhtai <47866232+chunhtai@users.noreply.github.com>
2025-02-03 23:55:03 +00:00
Michael Goderbauer
5491c8c146
Auto-format Framework (#160545)
This auto-formats all *.dart files in the repository outside of the
`engine` subdirectory and enforces that these files stay formatted with
a presubmit check.

**Reviewers:** Please carefully review all the commits except for the
one titled "formatted". The "formatted" commit was auto-generated by
running `dev/tools/format.sh -a -f`. The other commits were hand-crafted
to prepare the repo for the formatting change. I recommend reviewing the
commits one-by-one via the "Commits" tab and avoiding Github's "Files
changed" tab as it will likely slow down your browser because of the
size of this PR.

---------

Co-authored-by: Kate Lovett <katelovett@google.com>
Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
2024-12-19 20:06:21 +00:00
yim
7b262d926d
Test SliverMainAxisGroup offstage child (#159406)
```dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('my test', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: LayoutBuilder(
          builder: (context, view) {
            return CustomScrollView(
              slivers: [
                SliverMainAxisGroup(
                  slivers: [
                    SliverToBoxAdapter(child: SizedBox(height: view.maxHeight)),
                    const SliverToBoxAdapter(child: Text('1')),
                  ],
                )
              ],
            );
          },
        ),
      ),
    );
    expect(find.text('1'), findsNothing);
  });
}
```
The above test should have passed, but it failed. This PR fixes the
issue.

## 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.
- [ ] 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
2024-12-11 00:58:59 +00:00
Nate Wilson
dc5809309a
Fix SafeArea DartPad sample (#159344)
This pull request fixes a bug I introduced in
https://github.com/flutter/flutter/pull/158019.

<br>

<h3 align="center">Before</h3>
<p align="center">
  <img 

src="https://github.com/user-attachments/assets/fcb68fac-9c63-445d-8d2b-afc28c685053"
    alt="RenderFlex overflowed"
    width="523px"
  />
</p>

<h3 align="center">After</h3>
<p align="center">
  <img 

src="https://github.com/user-attachments/assets/82091c6a-b3c5-4994-978e-5e76cbb7edfd"
    alt="RenderFlex overflowed"
    width="523px"
  />
</p>

<br><br>

- fixes https://github.com/flutter/flutter/issues/159340
2024-12-09 19:54:08 +00:00
Anis Alibegić
e2ada1c939
Fixed typos (#159331)
Here's another one of my PRs where I hunt for typos across `flutter`
repo.

## 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].
- [ ] 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].
- [x] All existing and new tests are passing.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#overview
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[test-exempt]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#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/wiki/Tree-hygiene#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/wiki/Chat
2024-12-05 16:54:09 +00:00
Neutrino2711
4b818b56c2
Updated document to clarify Clip Behaviour (#157719)
Revised comments to clarify that clipping of child depends on clipBehavior of the parent widget, typically scrollable widgets that default to Clips.hard.
Noted that decoration features such as shadows , which render outside the widget boundary, may lead to undesirable effects.
Recommended using Clips.none in scenarios where shadow effects are used to avoid clipping issues.
Fixing Issue #156819
2024-11-14 20:21:09 +00:00
Nate Wilson
1eaf1f9525
Add SafeArea DartPad sample (#158019)
Follow-up from #157228
2024-11-11 01:00:21 +00:00
Valentin Vignal
0c97067f80
Add test for image.frame_builder.0.dart (#158247)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/image/image.frame_builder.0.dart`
2024-11-06 16:40:14 +00:00
Valentin Vignal
73546b3b71
Add test for image.loading_builder.0.dart (#158248)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/image/image.loading_builder.0.dart`
2024-11-06 14:26:28 +00:00
Bruno Leroux
22a7afd99a
Fix RawScrollbar examples and desktop test (#158237)
## Description

Fix the formatting of some `RawScrollbar` examples.
Fix and rename one test file (name without `_test` suffix).
2024-11-06 08:34:36 +00:00
Valentin Vignal
ffe81f0354
Add test for raw_scrollbar.2.dart (#158161)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/scrollbar/raw_scrollbar.2.dart`
2024-11-05 23:07:57 +00:00
Valentin Vignal
86fc1fd479
Add test for raw_scrollbar.shape.0.dart (#158094)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/scrollbar/raw_scrollbar.shape.0.dart`
2024-11-05 08:21:20 +00:00
Valentin Vignal
ed91ba1ba5
Add test for raw_scrollbar.1.dart (#158069)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/scrollbar/raw_scrollbar.1.dart`
2024-11-04 07:33:22 +00:00
Valentin Vignal
a1fbc839e2
Add test for interactive_viewer.constrained.0.dart (#158044)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/interactive_viewer/interactive_viewer.constrained.0.dart`
2024-11-04 01:47:30 +00:00
Valentin Vignal
574b7e765d
Add test for raw_scrollbar.0.dart (#157989)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/scrollbar/raw_scrollbar.0.dart`
2024-11-02 03:57:29 +00:00
Valentin Vignal
fd259714d4
Add test for interactive_viewer.transformation_controller.0.dart (#157986)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/interactive_viewer/interactive_viewer.transformation_controller.0.dart`
2024-11-01 10:37:59 +00:00
Valentin Vignal
43bb6186d2
Add test for notification.0.dart (#157909)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/notification_listener/notification.0.dart`
2024-11-01 06:41:13 +00:00
Valentin Vignal
16622e67a0
Add test for media_query_data.system_gesture_insets.0.dart (#157854)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/media_query/media_query_data.system_gesture_insets.0.dart`
2024-10-31 10:47:14 +00:00
miechoo
2d2ebbe263
Fix GlowingOverscrollIndicator examples (#155203)
Part of https://github.com/flutter/flutter/issues/130459

This pull request adds tests for the example files shown in the [GlowingOverscrollIndicator](https://api.flutter.dev/flutter/widgets/GlowingOverscrollIndicator-class.html) Flutter API reference documentation.
2024-10-30 20:50:00 +00:00
Valentin Vignal
f9c130abf0
Add test for interactive_viewer.0.dart (#157773)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/interactive_viewer/interactive_viewer.0.dart`
2024-10-30 05:46:24 +00:00
Valentin Vignal
1ec1c59d47
Add test for scroll_metrics_notification.0.dart (#157768)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/scroll_position/scroll_metrics_notification.0.dart`
2024-10-30 05:46:21 +00:00
yim
c051b69e2a
Add boundary feature to the drag gesture. (#147521)
Inspired by the review on #146182.

This PR adds boundary feature to the drag gestures, including `MultiDragGestureRecognizer` and `DragGestureRecognizer`. The `GestureDetector` widget will also benefit from this.
2024-10-30 03:01:18 +00:00
Valentin Vignal
2de487308a
Add test for focus_scope.0.dart (#157772)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/focus_scope/focus_scope.0.dart`
2024-10-29 09:02:01 +00:00
Valentin Vignal
55fa5ae07f
Add test for page_storage.0.dart (#157770)
Contributes to https://github.com/flutter/flutter/issues/130459

It adds a test for
- `examples/api/lib/widgets/page_storage/page_storage.0.dart`
2024-10-29 09:01:59 +00:00