8467 Commits

Author SHA1 Message Date
Polina Cherkasova
4b169a81ea
Fix some leaky tests. (#157294) 2024-10-21 21:29:05 +00:00
Parker Lougheed
2336329baf
Resolve pupup menu test TODO (#157251)
Flutter no longer supports versions of Dart that will output the non-reified version.
2024-10-21 19:52:30 +00:00
Parker Lougheed
a0a82f2821
Fix a few typos in framework code and doc comments (#157248) 2024-10-21 19:25:52 +00:00
Taha Tesser
2665a72559
Fix unattached MenuController throws assertion error when calling MenuController.close() (#156588)
Fixes [Closing a menu controller that was never attached throws an assertion error](https://github.com/flutter/flutter/issues/156572)

### Code sample

<details>
<summary>expand to view the code sample</summary> 

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () => Navigator.of(context).push(
            MaterialPageRoute(
              builder: (context) => const MenuControllerPage(),
            ),
          ),
          child: const Text('Press Me'),
        ),
      ),
    );
  }
}

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

  @override
  State<MenuControllerPage> createState() => _MenuControllerPageState();
}

class _MenuControllerPageState extends State<MenuControllerPage> {
  // This menu controller is intentionally left as not attached to a MenuAnchor.
  final MenuController _menuController = MenuController();

  @override
  void dispose() {
    // Close the menu when the page is popped.
    _menuController.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          child: const Text('Go back'),
          onPressed: () => Navigator.of(context).pop(),
        ),
      ),
    );
  }
}
```

</details>
2024-10-21 17:26:09 +00:00
Hannes Hultergård
8621694fdf
Add callbacks for detecting tap up events to TapRegion (#156110)
Adds `onTapUpOutside` and `onTapUpInside` callbacks to `TapRegion`, and `onTapUpOutside` to `EditableText` text fields. This allows users to detect `PointerUpEvent`s, which in turn can be used to differentiate between a tap and pan / scroll gesture (for example by comparing the distance between the down and up events).

Fixes #140271 and potentially  #138190
2024-10-21 16:59:16 +00:00
Yegor
cd0aa2b537
all selectable widgets set the hasSelectedState flag (#157191)
Set the `hasSelectedState` flag in all selectable widgets. This happens automatically because only selectable widgets have `Semantics.selected` set to a non-null value. When the value is propagated to `SemanticsConfiguration.isSelected`, it sets both `hasSelectedState` to true and `isSelected` as appropriate.

More progress towards https://github.com/flutter/flutter/issues/66673
2024-10-18 22:37:51 +00:00
Victor Sanni
83a0b85e43
Snap CupertinoSliverNavigationBar large title and bottom widget (#156381)
## Flutter (with this PR):

https://github.com/user-attachments/assets/b0177c06-e4b5-4981-8ec3-62171a4f2547

## Native:

https://github.com/user-attachments/assets/6efa0825-d26c-4c20-81cc-c9fada6e15fc

Fixes https://github.com/flutter/flutter/issues/126028
Fixes https://github.com/flutter/flutter/issues/23321
2024-10-18 19:18:08 +00:00
FMorschel
c40f418c05
Removing unnecessary parenthesis (#156928)
This is simply removing unnecessary parenthesis from various places. This change is because of a change to the unnecessary_parentesis lint that will trigger there. Here is the CL https://dart-review.googlesource.com/c/sdk/+/390161.

- https://github.com/dart-lang/linter/issues/4996

If anything else is needed please let me know. 

I'd like to ask for this PR to wait a bit until the bots are run again on that CL so that I can be sure nothing else will trigger, I will come back here and update this whenever everything is complete. Thanks!
2024-10-17 23:46:25 +00:00
Emmanuel Bonke
77f88ff78a
add dividerThickness in PaginatedDataTable (#156442)
Transitioned from `DataTable` to `PaginatedDataTable` and noted that the latter is missing the `dividerThickness`,  hence this PR adds `dividerThickness` to `PaginatedDataTable`.
2024-10-17 19:43:20 +00:00
Mairramer
6acc5915b4
Fixes TreeSliver collapsing not working (#153438)
This change addresses bug #153418 by ensuring that nodes are handled correctly when closing their children.

Fixes #153418
2024-10-17 18:12:18 +00:00
Lurchfresser
5ce3ae0241
builder gets executed with AnimationStyle.noAnimation (#156982)
Changed the if-statement nesting, so builder gets executed with AnimationStyle.noAnimation.

Pre-launch Checklist

Issue: https://github.com/flutter/flutter/issues/156959

[✅ ] I read the [Contributor Guide](https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview) and followed the process outlined there for submitting PRs.
[ ✅] I read the [Tree Hygiene](https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) wiki page, which explains my responsibilities.
[ ✅] I read and followed the [Flutter Style Guide](https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md), including [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).
[ ✅] I signed the [CLA](https://cla.developers.google.com/).
[ ✅] 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](https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests).
I followed the [breaking change policy](https://github.com/flutter/flutter/blob/main/docs/contributing/Treehygiene.md#handling-breaking-changes) and added [Data Driven Fixes](https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md) where supported.
[✅ ] All existing and new tests are passing.
2024-10-17 17:04:07 +00:00
Crafti
0ce5285051
Implement actionsPadding for AppBar (#155632)
This pull requests adds a new `actionsPadding` property to AppBar, which controls the padding of the actions row's end. By default, no padding is added.

As it was already discussed in the linked issue below (https://github.com/flutter/flutter/issues/115349#issuecomment-1315582192), it is not feasible to change defaults. This PR is an interim solution to allow developers to change layout across the app, until that change/transition can be made (see: the new TODO line). 

Different to the original code from 2018, this PR only adds padding to the actual actions row, instead of the entire `NavigationToolbar`.

Fixes #155747
2024-10-17 13:03:22 +00:00
Yegor
54bf532305
Temporarily skip CustomPainter SemanticsFlag test to allow new flag to roll in (#157061)
Same as https://github.com/flutter/flutter/pull/157017, but for `CustomPainter`.
2024-10-16 22:35:23 +00:00
Yegor
4a57ce7932
Temporarily skip SemanticsFlag test to allow new flag to roll in (#157017)
This test relies on the enumeration of all engine flags, and it will fail when https://github.com/flutter/engine/pull/55780 adds `SemanticsFlag.hasSelectedState`. So temporarily skip the test to allow the new flag to be added. I will later unskip the test and change it to check for the new flag as well.

A step towards https://github.com/flutter/flutter/issues/66673
2024-10-16 20:46:16 +00:00
Nate Wilson
8d1ea1e9c5
Monomorphic Mapper (#154972)
This class looks like it _should_ give valid equality checks:

```dart
class _WidgetStateColorMapper extends _WidgetStateColorTransparent {
  const _WidgetStateColorMapper(this.map);

  final WidgetStateMap<Color> map;

  _WidgetStateMapper<Color> get _mapper => _WidgetStateMapper<Color>(map);

  @override
  Color resolve(Set<WidgetState> states) => _mapper.resolve(states);

  @override
  bool operator ==(Object other) {
    return other is _WidgetStateColorMapper && other.map == map;
  }

  @override
  int get hashCode => map.hashCode;
}
```

But I made a mistake: I should have used `other._mapper == _mapper` and `_mapper.hashCode`.

<br>

It'd be pretty nice if no copy-pasting was needed in the first place:

```dart
class _WidgetStateColorMapper extends WidgetStateMapper<Color> implements WidgetStateColor {
  const _WidgetStateColorMapper(super.map);
}
```

<br><br>

This PR makes `WidgetStateMapper` a public class, similar to `WidgetStatePropertyAll`. The new API, when used incorrectly, will `throw` with a detailed error message, rather than silently returning irrelevant values.
2024-10-16 20:18:28 +00:00
Victor Sanni
f9eebe0319
Add bottom to CupertinoNavigationBar to allow for a double-row nav bar (#155959)
Fixes [Support segmented controls in nav bars and double row nav bars](https://github.com/flutter/flutter/issues/10469)

<img width="270" height="600"  alt="Screenshot 2024-09-30 at 3 09 04 PM" src="https://github.com/user-attachments/assets/4003116f-69dd-4f8f-a185-6ca151b74d2d">
2024-10-16 19:36:55 +00:00
Victor Sanni
293ae2e5ab
Add bottom to CupertinoSliverNavigationBar (#155841)
Fixes [Support search box inside large title nav bar](https://github.com/flutter/flutter/issues/18103)
Part of [Support segmented controls in nav bars and double row nav bars](https://github.com/flutter/flutter/issues/10469)

## None mode (Current default)

https://github.com/user-attachments/assets/d798314e-940f-4311-9a9a-fe999c65f280

## Always mode

https://github.com/user-attachments/assets/950a85aa-8ca2-42ea-bf8b-3cb8f95e616e

## Automatic mode

https://github.com/user-attachments/assets/c7c7240b-d493-4036-a987-30f61d02bac3

## With CupertinoSlidingSegmentedControl

https://github.com/user-attachments/assets/59f4aec4-8d9c-4223-915b-97b73cb25dc8

<details>
<summary>Sample Code</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/cupertino.dart';

/// Flutter code sample for [CupertinoSliverNavigationBar].

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

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

  @override
  Widget build(BuildContext context) {
    return const CupertinoApp(
      theme: CupertinoThemeData(brightness: Brightness.light),
      home: SliverNavBarExample(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return const CupertinoPageScaffold(
      // A ScrollView that creates custom scroll effects using slivers.
      child: SafeArea(
        child: CustomScrollView(
          // A list of sliver widgets.
          slivers: <Widget>[
            CupertinoSliverNavigationBar(
              leading: SizedBox(
                width: 100,
                child: Row(
                  children: [
                    Icon(CupertinoIcons.back),
                    Text(
                      'Lists',
                      style: TextStyle(color: CupertinoColors.activeBlue),
                    ),
                  ],
                ),
              ),
              trailing: Icon(CupertinoIcons.plus),
              largeTitle: Text('iPhone'),
              // Change to desired mode.
              drawerMode: NavigationDrawerMode.none,
              drawer: Padding(
                padding: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 16.0),
                child: CupertinoSearchTextField(),
              ),
            ),
            SliverFillRemaining(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  Text('Drag me up', textAlign: TextAlign.center),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
```

</details>
2024-10-16 18:25:06 +00:00
Jakub Bogacki
279d30a44f
Add TapOutsideConfiguration widget (#150125)
This PR adds `TapOutsideConfiguration` where you can define a custom default logic for `onTapOutside`.

```dart
TapOutsideConfiguration(
  behavior: AlwaysUnfocusTapOutsideBehavior(),
  // behavior: const NeverUnfocusTapOutsideBehavior(),
  // behavior: const CustomTapOutsideBehavior(),
  child: Column(
    children: [
      // This TextField will use onTapOutside from TapOutsideConfiguration
      TextField(),
      // Of course you can still define onTapOutside
      TextField(onTapOutside: (event) => print('Tapped outside')),
    ],
  ),
)
```

Custom logic can be define like this:

```dart
class CustomTapOutsideBehavior extends TapOutsideBehavior {
  const CustomTapOutsideBehavior();

  @override
  void defaultOnTapOutside(PointerDownEvent event, FocusNode focusNode) {
    // any custom logic here
  }
}
```

This PR implements also two simple `AlwaysUnfocusTapOutsideBehavior` and `NeverUnfocusTapOutsideBehavior`.

Resolves #150123
2024-10-16 13:25:34 +00:00
Bruno Leroux
2430f00a01
fix DropdownMenu keyboard navigation is broken when expandedInsets is set (#156803)
## Description

This PR fixes keyboard navigation when `DropdownMenu.expandedInsets` is used.
Before this PR the Shortcuts widget defining the navigation intents was only added when `DropdownMenu.expandedInsets` was null.
After this PR, the Shortcuts widget is always added.

## Related Issue

Fixes [DropdownMenu keyboard navigation is broken when expandedInsets is set](https://github.com/flutter/flutter/issues/156712).

## Tests

Adds 2 tests.
Replaces several unneeded 'pumpAndSettle'.
2024-10-16 07:30:34 +00:00
Jason Simmons
4f2211b550
Determine the scroll gesture axis based on the effectiveScrollController (#156190)
Fixes https://github.com/flutter/flutter/issues/154520
2024-10-15 20:58:51 +00:00
Rexios
e96aaab5e0
Add padding options to SearchAnchor (#152508)
Cherry-picked padding changes from https://github.com/flutter/flutter/pull/148856

Adds padding configuration options to `SearchAnchor`. This PR adds the following:
- `viewBarPadding`: The padding for items inside the `SearchBar` in the `SearchAnchor` view
- `viewPadding`: The padding to use around the entire `SearchAnchor` view

Working towards https://github.com/flutter/flutter/issues/148852
2024-10-15 20:24:48 +00:00
Victor Sanni
915985ad52
Implement CupertinoSearchTextField opacity fade on scroll (#155025)
## Before:

https://github.com/user-attachments/assets/38cabba1-d002-4a5d-b80b-fd0955b2aad5

## After:

https://github.com/user-attachments/assets/3e73f863-c353-43f3-90b8-fd322b42b5d3

## Native iOS:

https://github.com/user-attachments/assets/daab345e-09ae-44dc-a1a0-461757c13542

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

Needed for https://github.com/flutter/flutter/issues/18103
2024-10-15 17:03:25 +00:00
Taha Tesser
8ea38a7921
Fix AppBar back button doesn't navigate back when using TooltipTriggerMode.tap in the TooltipTheme (#155822)
Fixes [AppBar BackButton Tooltip interferes with clicking button when TooltipThemeData set to TooltipTriggerMode.tap](https://github.com/flutter/flutter/issues/152315)

### Description
`TooltipTheme` with `triggerMode: TooltipTriggerMode.tap` prevents user from navigating back when tapping on the back button. `triggerMode: TooltipTriggerMode.tap` shouldn't interrupted the back button navigation back callback.

### Code sample

<details>
<summary>expand to view the code sample</summary> 

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        tooltipTheme:
            const TooltipThemeData(triggerMode: TooltipTriggerMode.tap),
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Sample'),
        ),
        body: Builder(builder: (context) {
          return Center(
            child: ElevatedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => const SecondScreen(),
                  ),
                );
              },
              child: const Text('Go to Second Screen'),
            ),
          );
        }),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Screen'),
      ),
      body: const Center(
        child: Tooltip(
          message: 'This is the second screen',
          child: Text('Tap to show tooltip'),
        ),
      ),
    );
  }
}
```

</details>

### Before

https://github.com/user-attachments/assets/ed2020f0-aef8-40f9-be05-55ff80e42e5d

### After

https://github.com/user-attachments/assets/8d65f9f8-d15d-453f-955f-e5d92f8a04e8
2024-10-15 12:30:28 +00:00
Hannah Jin
75d93e1c44
Update dropdown menu semantics to fix its a11y issues (#156709)
fixes https://github.com/flutter/flutter/issues/133742 

because the _initialMenu is invisible, we should not add semantics nodes
to it

## 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
2024-10-14 13:36:24 -07:00
Bruno Leroux
a60933551d
Refactor some DropdownMenu tests (#156702)
## Description

This PR adds a utility method, named `isItemHighlighted`, to simplify several `DropdownMenu` tests.
It will help for some inworking changes.
2024-10-14 20:17:09 +00:00
Jatin Nagar
b3491acb0d
RadioListTile: add property to scale the radio (#156292)
Added a property in the RadioListTile to scale the underlying Radio using `Transform.scale`.

Fixes: #81334
2024-10-12 15:50:36 +00:00
Jatin Nagar
63dd042e72
CheckboxListTile: use Transform.scale only when required (#156593)
Make CheckboxListTile use `Transform.scale` only when required.

Fixes: #81334
2024-10-12 05:37:38 +00:00
Taha Tesser
45033a29f9
Introduce DropdownMenu.closeBehavior to control menu closing behavior (#156405)
Fixes [Add option to control whether the root DropdownMenu can be closed or not](https://github.com/flutter/flutter/issues/139269)

This introduces  `DropdownMenu.closeBehavior` to provide control over `DropdownMenu` can be closed in nested menus.

### Code sample

<details>
<summary>expand to view the code sample</summary> 

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

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String selectedValue = "1";

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Column(
                spacing: 16.0,
                mainAxisSize: MainAxisSize.min,
                children: [
                  const Text("DropdownMenuCloseBehavior.none"),
                  MenuAnchor(
                    menuChildren: <Widget>[
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: DropdownMenu(
                          closeBehavior: DropdownMenuCloseBehavior.none,
                          label: const Text('Menu'),
                          initialSelection: selectedValue,
                          onSelected: (String? value) {
                            if (value != null) {
                              setState(() {
                                selectedValue = value;
                              });
                            }
                          },
                          dropdownMenuEntries: ["1", "2", "3"]
                              .map(
                                (it) => DropdownMenuEntry(
                                  value: it,
                                  label: it,
                                ),
                              )
                              .toList(),
                        ),
                      )
                    ],
                    child: const Text('Open Menu'),
                    builder: (context, controller, child) {
                      return ElevatedButton(
                        onPressed: () {
                          controller.open();
                        },
                        child: child,
                      );
                    },
                  ),
                ],
              ),
              Column(
                spacing: 16.0,
                mainAxisSize: MainAxisSize.min,
                children: [
                  const Text("DropdownMenuCloseBehavior.self"),
                  MenuAnchor(
                    menuChildren: <Widget>[
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: DropdownMenu(
                          closeBehavior: DropdownMenuCloseBehavior.self,
                          label: const Text('Menu'),
                          initialSelection: selectedValue,
                          onSelected: (String? value) {
                            if (value != null) {
                              setState(() {
                                selectedValue = value;
                              });
                            }
                          },
                          dropdownMenuEntries: ["1", "2", "3"]
                              .map(
                                (it) => DropdownMenuEntry(
                                  value: it,
                                  label: it,
                                ),
                              )
                              .toList(),
                        ),
                      )
                    ],
                    child: const Text('Open Menu'),
                    builder: (context, controller, child) {
                      return ElevatedButton(
                        onPressed: () {
                          controller.open();
                        },
                        child: child,
                      );
                    },
                  ),
                ],
              ),
              Column(
                spacing: 16.0,
                mainAxisSize: MainAxisSize.min,
                children: [
                  const Text("DropdownMenuCloseBehavior.all"),
                  MenuAnchor(
                    menuChildren: <Widget>[
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: DropdownMenu(
                          closeBehavior: DropdownMenuCloseBehavior.all,
                          label: const Text('Menu'),
                          initialSelection: selectedValue,
                          onSelected: (String? value) {
                            if (value != null) {
                              setState(() {
                                selectedValue = value;
                              });
                            }
                          },
                          dropdownMenuEntries: ["1", "2", "3"]
                              .map(
                                (it) => DropdownMenuEntry(
                                  value: it,
                                  label: it,
                                ),
                              )
                              .toList(),
                        ),
                      )
                    ],
                    child: const Text('Open Menu'),
                    builder: (context, controller, child) {
                      return ElevatedButton(
                        onPressed: () {
                          controller.open();
                        },
                        child: child,
                      );
                    },
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}
```

</details>

### Demo

https://github.com/user-attachments/assets/1f79ea6e-c0c6-4dcf-8180-d9dcca1c22c5
2024-10-11 20:51:18 +00:00
Harry Terkelsen
810c87a2e3
[canvaskit] Unskip cupertino datepicker tests (#156499)
Unskips Cupertino Datepicker tests on CanvasKit.

Addresses https://github.com/flutter/flutter/issues/110785 for CanvasKit. But the tests are still failing for Skwasm.
2024-10-10 15:50:19 +00:00
Qun Cheng
e317860b35
Normalize ThemeData.tabBarTheme (#156253)
Following https://github.com/flutter/flutter/pull/155476, this PR is to normalize `ThemeData.tabBarTheme`; change the `TabBarTheme tabBarTheme` property to `TabBarThemeData tabBarTheme` in `ThemeData`. In `ThemeData()` and `ThemeData.copyWith()`, the `tabBarTheme` parameter type is changed to `Object?` to accept both `TabBarTheme` and `TabBarThemeData` so that we won't cause immediate breaking change and make sure rolling is smooth. Once all component themes are normalized, these `Object?` types should be changed to `xxxThemeData`.

There's no way to create a dart fix because we can't add a "@deprecated" label for TabBarTheme; TabBarTheme is a new InheritedWidget subclass now.

Addresses the "theme normalization" sub project within https://github.com/flutter/flutter/issues/91772
2024-10-08 19:52:38 +00:00
PurplePolyhedron
138144bb2f
Update DropdownMenu tests to remove some dependence on platforms (#156131)
Keyboard navigation in  `DropdownMenu` depends on `focus` instead of platforms.
Updating tests to remove `variant: TargetPlatformVariant.desktop()`  from keyboard navigation tests.
2024-10-08 15:55:18 +00:00
Justin McCandless
22635e19c1
NavigatorPopHandler.onPopWithResult (#155618)
NavigatorPopHandler now includes the return value from Route. Recently some navigation infrastructure was updated to support passing through these return values, but NavigatorPopHandler was missed until now.
2024-10-08 08:19:29 -07:00
Taha Tesser
44f7c6913f
Update flexible_space_bar_test.dart tests for Material 3 (#156226)
Updated unit tests for `FlexibleSpaceBar` to have M2 and M3 versions.

More info in #139076
2024-10-08 07:42:08 +00:00
Mairramer
56a33efd73
Fixes an issue where onTapOutside was incorrectly triggered across routes in TapRegion (#155297)
Fixes https://github.com/flutter/flutter/issues/153093

This PR fixes the issue of onTapOutside being triggered on other routes incorrectly.
2024-10-07 20:48:00 +00:00
Taha Tesser
b3de00ad54
Fix DropdownMenu with expandedInsets always aligned on top (#156214)
Fixes [DropdownMenu can not be center aligned when using expandedInsets
](https://github.com/flutter/flutter/issues/155581)

### Code sample

<details>
<summary>expand to view the code sample</summary> 

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

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

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

  @override
  Widget build(BuildContext context) {
    final List<DropdownMenuEntry<ShortMenu>> shortMenuItems =
        <DropdownMenuEntry<ShortMenu>>[];
    for (final ShortMenu value in ShortMenu.values) {
      final DropdownMenuEntry<ShortMenu> entry =
          DropdownMenuEntry<ShortMenu>(value: value, label: value.label);
      shortMenuItems.add(entry);
    }

    return MaterialApp(
      home: Scaffold(
        body: Row(
          children: <Widget>[
            Expanded(
              child: Center(
                child: DropdownMenu<ShortMenu>(
                  expandedInsets: const EdgeInsets.all(16),
                  initialSelection: ShortMenu.item0,
                  dropdownMenuEntries: shortMenuItems,
                  label: const Text('With expandedInsets'),
                ),
              ),
            ),
            Expanded(
              child: Center(
                child: DropdownMenu<ShortMenu>(
                  initialSelection: ShortMenu.item0,
                  dropdownMenuEntries: shortMenuItems,
                  label: const Text('Without expandedInsets'),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

enum ShortMenu {
  item0('Menu 0'),
  item1('Menu 1'),
  item2('Menu 2');

  const ShortMenu(this.label);
  final String label;
}
```

</details>

### Before 
(`DropdownMenu` without `expandedInsets` cannot be centered)
<img width="770" alt="Screenshot 2024-10-04 at 14 13 58" src="https://github.com/user-attachments/assets/c7520c12-d16a-4867-8fae-38b75dbc4225">

### After
(`DropdownMenu` with `expandedInsets` be centered)

<img width="770" alt="Screenshot 2024-10-04 at 14 13 49" src="https://github.com/user-attachments/assets/82e0b81e-5c85-4e59-99b8-df329459773b">
2024-10-07 13:43:22 +00:00
Jatin Nagar
bae7971431
CheckboxListTile: add property to scale the checkbox (#154806)
Added a property in the CheckboxListTile to scale the underlying Checkbox using `Transform.scale`.

Fixes: #81334
2024-10-06 14:49:20 +00:00
Qun Cheng
534adfbe02
Normalize ThemeData.cardTheme (#153254)
Following https://github.com/flutter/flutter/pull/151914, this PR is to normalize `ThemeData.cardTheme`; change the `CardTheme cardTheme` property to `CardThemeData cardTheme` in `ThemeData`. In `ThemeData()` and `ThemeData.copyWith()`, the `cardTheme` parameter type is changed to `Object?` to accept both `CardTheme` and `CardThemeData` so that we won't cause immediate breaking change and make sure rolling is smooth. Once all component themes are normalized, these `Object?` types should be changed to `xxxThemeData`.

There's no way to create a dart fix because we can't add a "@deprecated" label for `CardTheme` because `CardTheme` is a new InheritedWidget subclass now.

Addresses the "theme normalization" sub project within https://github.com/flutter/flutter/issues/91772
2024-10-04 18:59:05 +00:00
Tong Mu
59e57437db
Allow arrow keys to navigate MenuAnchor independently of global shortcut definition (#155728)
This PR adjusts the implementation of handling navigational shortcuts (i.e. arrow keys) on `MenuAnchor` and `DropdownMenu`.

## Motivation
The direct outcome of this PR is to allow keyboard to enter submenus on Web: When the focus is on a `MenuAnchor` while the menu is open, pressing arrow keys should move the focus to the menu item.
* Before the PR, this works for all platforms but Web, a problem described in https://github.com/flutter/flutter/issues/119532#issuecomment-2274705565.

It is caused by the fact that `MenuAnchor` does not wrap itself with a `Shortcuts`, and therefore key events when the focus is on a `MenuAnchor` has been working only because the event falls back to the `Shortcuts` widget defined by `WidgetsApp`, whose default value happens to satisfy `MenuAnchor`'s needs - except on Web where arrow keys are defined to scroll instead of traverse. 

Instead of defining this problem as "just a patch for Web", I think it's better to define it as a problem of all platforms: `MenuAnchor`'s shortcuts should be independent of `WidgetsApp.shortcuts`. Because even if `WidgetsApp.shortcuts` is redefined as something else, people should probably still expect arrow keys to work on `MenuAnchor`.

Therefore this PR makes `MenuAnchor` produce a `Shortcuts` by itself.

### Dropdown menu
The fix above breaks `DropdownMenu`. `DropdownMenu` uses `MenuAnchor`, while defining its own shortcuts because, when filter is enabled:
* The left and right arrow keys need to move the text carets instead
* The up and down arrow keys need to "fake" directional navigation - the focus needs to stay on the text field, while some menu item is highlighted as if it is focused.

Before the PR, `DropdownMenu` defines these shortcuts out of `MenuAnchor`. In order for the `DropdownMenu`'s shortcuts to take priority, these shortcuts are moved to between `MenuAnchor` and the `Textfield`.

A test is added to verify that the left/right keys move text carets.

Below are psuedo-widget-trees after the PR:
```
MenuAnchor
 |- Shortcuts(arrows->DirectionalFocusIntent)
    |- MenuAnchor.child
    |- menu

DropdownMenu
 |- Actions(DirectionalFocusIntent->_dropdownMenuNavigation)
    |- MenuAnchor
        |- Shortcuts(arrows->DirectionalFocusIntent)
            |- Shortcuts(leftright->ExtendSelectionByCharacterIntent, updown->_dropdownMenuArrowIntent)
            |  |- TextField
            |     |- EditableText
            |        |- Actions(DirectionalFocusIntent->DirectionalFocusAction.forTextField)
            |- menu
```

## Known issues
After this PR, traversing the menu still have quite a few problems, which are left for other PRs.
2024-10-03 20:09:19 +00:00
Nate Wilson
500285d39a
Inherited Theme: zero rebuilds (#155699)
> ### Write Test, Find Bug
>
> When you fix a bug, first write a test that fails, then fix the bug and verify the test passes.

<br>

When `Theme.of(context)` is called in a `build()` method, the widget is rebuilt each frame during an `AnimatedTheme` transition.

I wanted to create a way for `RenderObject`s to be updated directly, so I wrote a test:

```dart
testWidgets('InheritedWidgets can trigger RenderObject updates', (WidgetTester tester) async {
  // ...
});
```

…and it passed.

<br><br>

As it turns out, no change is needed at all!

This PR resolves #155852 by adding the "InheritedWidgets can trigger RenderObject updates" test, to ensure that this awesome capability doesn't break in the future.
2024-10-03 19:24:06 +00:00
Nate Wilson
5ecf10052f
pattern-matching refactor (#154753)
This pull request aims to improve code readability, based on feedback gathered in a recent design doc.

<br>

There are two factors that hugely impact how easy it is to understand a piece of code: **verbosity** and **complexity**.

Reducing **verbosity** is important, because boilerplate makes a project more difficult to navigate. It also has a tendency to make one's eyes gloss over, and subtle typos/bugs become more likely to slip through.

Reducing **complexity** makes the code more accessible to more people. This is especially important for open-source projects like Flutter, where the code is read by those who make contributions, as well as others who read through source code as they debug their own projects.

<hr>

<br>

The following examples show how pattern-matching might affect these two factors:

<details> <summary><h3>Example 1 (GOOD)</h3> [click to expand]</summary>

```dart
if (ancestor case InheritedElement(:final InheritedTheme widget)) {
  themes.add(widget);
}
```

Without using patterns, this might expand to

```dart
if (ancestor is InheritedElement) {
  final InheritedWidget widget = ancestor.widget;
  if (widget is InheritedTheme) {
    themes.add(widget);
  }
}
```

Had `ancestor` been a non-local variable, it would need to be "converted" as well:

```dart
final Element ancestor = this.ancestor;
if (ancestor is InheritedElement) {
  final InheritedWidget inheritedWidget = ancestor.widget;
  if (widget is InheritedTheme) {
    themes.add(theme);
  }
}
```

</details>

<details> <summary><h3>Example 2 (BAD) </h3> [click to expand]</summary>

```dart
if (widget case PreferredSizeWidget(preferredSize: Size(:final double height))) {
  return height;
}
```

Assuming `widget` is a non-local variable, this would expand to:

```dart
final Widget widget = this.widget;
if (widget is PreferredSizeWidget) {
  return widget.preferredSize.height;
}
```

<br>

</details>

In both of the examples above, an `if-case` statement simultaneously verifies that an object meets the specified criteria and performs a variable assignment accordingly.

But there are some differences: Example 2 uses a more deeply-nested pattern than Example 1 but makes fewer useful checks.

**Example 1:**
- checks that `ancestor` is an `InheritedElement`
- checks that the inherited element's `widget` is an `InheritedTheme`

**Example 2:**
- checks that `widget` is a `PreferredSizeWidget`
(every `PreferredSizeWidget` has a `size` field, and every `Size` has a `height` field)

<br>

<hr>

I feel hesitant to try presenting a set of cut-and-dry rules as to which scenarios should/shouldn't use pattern-matching, since there are an abundance of different types of patterns, and an abundance of different places where they might be used.

But hopefully the conversations we've had recently will help us converge toward a common intuition of how pattern-matching can best be utilized for improved readability.

<br><br>

- resolves https://github.com/flutter/flutter/issues/152313
- Design Doc: [flutter.dev/go/dart-patterns](https://flutter.dev/go/dart-patterns)
2024-10-03 18:21:04 +00:00
Thomas Hareau
91eb8d226d
Add autocorrect and enableSuggestions to SearchDelegate (#154932)
Add `autocorrect` and `enableSuggestions` to `SearchDelegate`, so that autocompletion can be disabled in search. 

*List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.*

* https://github.com/flutter/flutter/issues/98241

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
2024-10-03 18:14:51 +00:00
Qun Cheng
64906c28a6
Update ThemeData.dialogTheme type to accept DialogThemeData (#155129)
Following https://github.com/flutter/flutter/pull/153982, this PR is to normalize `ThemeData.dialogTheme`; change the `DialogTheme dialogTheme` property to `DialogThemeData dialogTheme` in ThemeData. In `ThemeData()` and `ThemeData.copyWith()`, the dialogTheme parameter type is changed to `Object?` to accept both `DialogTheme` and `DialogThemeData` so that we won't cause immediate breaking change and make sure rolling is smooth. Once all component themes are normalized, these `Object?` types should be changed to `xxxThemeData`.

There's no way to create a dart fix because we can't add a "@deprecated" label for `DialogTheme`; `DialogTheme` is a new `InheritedWidget` subclass now.

Addresses the "theme normalization" sub project within https://github.com/flutter/flutter/issues/91772
2024-10-02 23:48:13 +00:00
Victor Sanni
d0f2a6887e
Add mouseCursor property to CupertinoCheckbox (#151788)
Part of https://github.com/flutter/flutter/issues/58192
2024-10-02 22:47:18 +00:00
Mitchell Goodwin
d877d2875e
Allow mixing route transitions in one app. (#150031)
Fixes #33799

Allows for a route to inform the route below it in the navigation stack how to animate when the topmost route enters are leaves the stack.

It does this by making a `DelegatedTransition` available for the previous route to look up and use. If available, the route lower in the stack will wrap it's transition builders with that delegated transition and use it instead of it's default secondary transition.

This is what the sample code in this PR shows an app that is able to use both a Material zoom transition and a Cupertino slide transition in one app. It also includes a custom vertical transition. Every page animates off the screen in a way to match up with the incoming page's transition. When popped, the correct transitions play in reverse.

https://github.com/user-attachments/assets/1fc910fa-8cde-4e05-898e-daad8ff4a697

The below video shows this logic making a pseudo iOS styled sheet transition.

https://github.com/flutter/flutter/assets/58190796/207163d8-d87f-48b1-aad9-7e770d1d96c5

All existing page transitions in Flutter will be overwritten by the incoming route if a `delegatedTransition` is provided. This can be opted out of through `canTransitionTo` for a new route widget. Of Flutter's existing page transitions, this PR only adds a `DelegatedTransition` for the Zoom and Cupertino transitions. The other transitions possible in Material will get delegated transitions in a later PR.
2024-10-02 20:08:11 +00:00
PurplePolyhedron
d461426922
fix wrong test in "fixing DropdownMenu keyboard navigation" (#156084)
I accidentally submitted the wrong test in the last commit in https://github.com/flutter/flutter/pull/155252
Re-uploading the correct one.
2024-10-02 19:06:20 +00:00
Navaron Bracke
57d2a20be3
fix ReorderableList not passing in item extent builder (#155994)
This PR fixes the `ReorderableList` in `flutter/widgets.dart` not passing the item extent builder to the underlying SliverReorderableList. I double checked and the material equivalent is working as intended.

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

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
2024-10-02 17:18:21 +00:00
Bruno Leroux
21381d843f
Fix DropdownMenu does not rematch initialSelection when entries have changed (#155757)
## Description

This PR makes DropdownMenu rematching the initialSelection when the entries are updated.
If the new entries contains one entry whose value matches `initialSelection` this entry's label is used to initialize the inner text field, if no entries matches `initialSelection` the text field is emptied.

## Related Issue

Fixes [DropdownMenu.didUpdateWidget should re-match initialSelection when dropdownMenuEntries have changed](https://github.com/flutter/flutter/issues/155660).

## Tests

Adds 3 tests.
2024-10-02 12:03:20 +00:00
PurplePolyhedron
ce2fe59bbb
fix DropdownMenu keyboard navigation when entries are filtered empty (#155252)
fixes https://github.com/flutter/flutter/issues/154532
2024-10-02 05:46:23 +00:00
SuicaLondon
cf20cea508
Add enableSplash parameter to CarouselView (#155214)
This PR fixes #154701 by adding a new parameter to the CarouselView widget that allows developers to control which parts of the carousel are clickable. Currently, an InkWell covers the entire carousel, preventing child widgets from being clickable even when children widget have their clickable widgets.

The new `enableSplash` parameter allows developers to disable this default behavior of `InkWell` without breaking any existing code. If `enableSplash` is `false`, the `onTap` of the `CarouselView` will be disabled. And developer can define their own click behavior likes animation, the clickable widget and so on.
2024-10-02 00:21:23 +00:00
Qun Cheng
33d3e4bda6
Reland TabBarTheme normalization (#155969)
Reland https://github.com/flutter/flutter/pull/155476 with test fix.

The test fix uses the method mentioned in https://github.com/flutter/flutter/pull/155476#issuecomment-2377287606.
2024-10-01 20:13:52 +00:00