8515 Commits

Author SHA1 Message Date
Bruno Leroux
39dad9946d
Add one MenuAnchor alignment test (#158915)
This PR adds a `MenuAnchor` test to check that `MenuAnchor.alignmentOffset` is correctly applied when `MenuAnchor.layerlink` is provided.
While reviewing https://github.com/flutter/flutter/pull/158255, I found that this new test would be useful.
2024-11-14 09:52:18 +00:00
Rexios
cc6ee0cc32
Add constraint options to SearchAnchor suggestions builder (#148856)
Refactors the `SearchAnchor` suggestions builder to not take up the whole screen

https://github.com/flutter/flutter/issues/148852
2024-11-14 01:19:09 +00:00
hgraceb
5f0f18d739
Fix update order of SliverAppBar (#158159)
Fixes #158158

Similar to 154484, but addressing more fundamental causes. We should call the child's `didUpdateWidget` before the child's `build` when states change.

1. Remove redundant code but keep the old test because we don't need it after this fix.
2. Add getters of `lastShrinkOffset` and `lastOverlapsContent` that are needed when `SliverAppBar.update`.
3. Add a test with a custom TabBar to avoid breaking when some changes to the default TabBar.
2024-11-14 00:08:22 +00:00
Srivats Venkataraman
1a31e396db
#154792 - CupertinoActionSheetAction cursor doesn't change to clickable on desktop (#158470)
This PR is for issue #154792 
The Video recording shows the before and after
The first button with the text "Go" uses the default cursor
The second button with the text "With Cursor" uses a custom cursor that has been passed in the parameters
https://github.com/user-attachments/assets/e82ecd42-42b1-42c9-aa30-a6f3daddb436

Here is the code for the second button
```dart
CupertinoButton(
    onPressed: () {
        showCupertinoModalPopup<void>(
            context: context,
            builder: (BuildContext context) {
                return CupertinoActionSheet(
                    title: const Text('The title'),
                    message: const Text('Message'),
                    actions: <Widget>[
                        CupertinoActionSheetAction(
                            cursor: SystemMouseCursors.forbidden,
                            child: const Text('One'),
                            onPressed: () {},
                        ),
                    ],
                );
            },
        );
    },
    child: const Text('With Cursor'),
),
```

Fixes https://github.com/flutter/flutter/issues/154792
2024-11-13 23:34:08 +00:00
Hannah Jin
9992e9bc5c
Support materialTapTargetSize in PopupMenuButton (#158357)
fix https://github.com/flutter/flutter/issues/128697 

PopupMenuButton can take customized child, in that case if `
widgt.style.tapTargetSize` is set to `padded`, PopupMenuButton should
support it.

if child is null, default child is an iconButton, which is already
48x48.


## 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-11-12 12:19:46 -08:00
Jiten Patel
9a2e249025
Made Cupertino dialog more like a native dialog in dark mode (#157218)
This PR addresses an issue where the `CupertinoAlertDialog` was not fully visible in dark mode. The dialog now adapts better to dark mode themes, ensuring proper contrast and readability across different UI elements. 

Fixes: #80921
2024-11-12 17:59:48 +00:00
Taha Tesser
148be5f894
Fix NavigationBar label style customization on the widget level (#158510)
Fixes [`NavigationBar` only allows `labelTextStyle` from `NavigationBarTheme` ](https://github.com/flutter/flutter/issues/158508)

### 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) {
    const TextStyle selectedTextStyle =
        TextStyle(fontSize: 15, color: Color(0xFF00FF00));
    const TextStyle unselectedTextStyle =
        TextStyle(fontSize: 15, color: Color(0xFF0000FF));
    const TextStyle disabledTextStyle =
        TextStyle(fontSize: 16, color: Color(0xFFFF0000));

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
          navigationBarTheme: NavigationBarThemeData(
        labelTextStyle: WidgetStatePropertyAll(
          TextStyle(
            fontSize: 14,
            fontWeight: FontWeight.bold,
            color: Theme.of(context).colorScheme.primary,
          ),
        ),
      )),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('NavigationBar Sample'),
        ),
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Text(
              "NavigationBar labels are customized using NavigationBar.labelTextStyle",
              style: Theme.of(context).textTheme.headlineSmall,
              textAlign: TextAlign.center,
            ),
          ),
        ),
        bottomNavigationBar: NavigationBar(
          labelTextStyle: const WidgetStateProperty<TextStyle?>.fromMap(
            <WidgetStatesConstraint, TextStyle?>{
              WidgetState.disabled: disabledTextStyle,
              WidgetState.selected: selectedTextStyle,
              WidgetState.any: unselectedTextStyle,
            },
          ),
          onDestinationSelected: null,
          destinations: const <Widget>[
            NavigationDestination(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            NavigationDestination(
              icon: Icon(Icons.favorite_rounded),
              label: 'Favorites',
            ),
            NavigationDestination(
              enabled: false,
              icon: Icon(Icons.settings),
              label: 'Settings',
            ),
          ],
        ),
      ),
    );
  }
}
```

</details>

### Preview

<img width="719" alt="Screenshot 2024-11-12 at 17 18 00" src="https://github.com/user-attachments/assets/2b489bfa-78a3-4766-bc22-9273d76eadcd">
2024-11-12 16:33:51 +00:00
Taha Tesser
68fa653e59
Fix Chip draws InkWell.hoverColor is drawn on top of the provided background color with hovered state (#158454)
Fixes [Setting hoverColor on ThemeData breaks Chip hover functionality](https://github.com/flutter/flutter/issues/157622)

### Description

The bug is caused by `InkWell.hoverColor`. When `ThemeData.hoverColor` is provided, its drawn on top. To fix this, we can override `InkWell.hoverColor` when Chip state color is provided.

### 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(
        hoverColor: const Color(0xFFFF0000),
      ),
      home: Scaffold(
        body: Center(
            child: RawChip(
          color: WidgetStateProperty.resolveWith((states) {
            if (states.contains(WidgetState.hovered)) {
              return const Color(0xFF00fF00);
            }

            return const Color(0xFF0000FF);
          }),
          label: const Text('RawChip'),
          onPressed: () {},
        )),
      ),
    );
  }
}
```

</details>

### Before

https://github.com/user-attachments/assets/f8974af6-5af3-4d7d-9dbe-65bf170d5fa3

### After

https://github.com/user-attachments/assets/89a5315c-c7bd-4456-8594-e2092e43952d
2024-11-11 19:48:32 +00:00
André Stein
1511370a92
[TextInput] Add TextInputType.webSearch (#15762) (#158323)
This PR  adds `TextInputType.webSearch` that allows to show a keyboard with ready access to a "." key on iOS. On Android this is re-mapped to `url` which shows the same behaviour as `webSearch` on iOS. This fixes issue #157562.

There also is a [corresponding *engine* PR](https://github.com/flutter/engine/pull/56428).

Screenshot from iOS demo app:

![image](https://github.com/user-attachments/assets/94d48752-4cfe-4113-acf9-b3a981952dc7)
2024-11-08 18:26:05 +00:00
Taha Tesser
7abb083ae2
Add ability to override NavigationDestination.label padding for NavigationBar (#158260)
Fixes [Long NavigationBar tab titles can't be padded from the sides of the screen](https://github.com/flutter/flutter/issues/158130)

### 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(
          navigationBarTheme: const NavigationBarThemeData(
        labelTextStyle:
            WidgetStatePropertyAll(TextStyle(overflow: TextOverflow.ellipsis)),
        labelPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 4),
      )),
      home: Scaffold(
        body: Center(
          child: Text(
            'Custom NavigationBar label padding',
            style: Theme.of(context).textTheme.titleMedium,
          ),
        ),
        bottomNavigationBar: NavigationBar(
          destinations: const [
            NavigationDestination(
              icon: Icon(Icons.favorite_rounded),
              label: 'Long Label Text',
            ),
            NavigationDestination(
              // icon: SizedBox.shrink(),
              icon: Icon(Icons.favorite_rounded),
              label: 'Long Label Text',
            ),
            NavigationDestination(
              icon: Icon(Icons.favorite_rounded),
              label: 'Long Label Text',
            ),
          ],
        ),
      ),
    );
  }
}

```

</details>

### Default `NavigationDestination.label` padding  with long label

<img width="458" alt="Screenshot 2024-11-06 at 14 30 52" src="https://github.com/user-attachments/assets/637e5e66-e05f-49fa-a4ae-72083b6ff884">

### Custom `NavigationDestination.label` padding with long label

<img width="458" alt="Screenshot 2024-11-06 at 14 32 02" src="https://github.com/user-attachments/assets/23ebf715-30d3-433c-92cd-c8f0fdb1571b">
2024-11-08 14:19:18 +00:00
Renzo Olivares
97eef6afc5
Make _SelectableRegionSelectionContainerDelegate public (#147080)
This change makes `_SelectableRegionContainerDelegate` public so it can be reused and extended by users of `SelectionContainer`. Extending `MultiSelectableRegionContainerDelegate` does not by default provide selection managing across multiple selectables, so often users will copy the implementation found in `_SelectableRegionContainerDelegate`.

`_SelectableRegionContainerDelegate` -> `StaticSelectionContainerDelegate`.
2024-11-07 23:00:52 +00:00
Paul Salmon
1ad0db51ae
Added cusor control properties to CupertinoSearchTextField and tests (#158240)
Adding control over the cursor to CupertinoSearchTextField: cursorWidth, cursorHeight, cursorRadius, cursorOpacityAnimates and cursorColor.

fixes https://github.com/flutter/flutter/issues/158239
2024-11-06 23:04:55 +00:00
Bruno Leroux
66e8f53ba0
Cleanup MenuAnchor and Improve DropdownMenu tests readability (#158175)
## Description

This PR fixes some typos on `MenuAnchor` and improve the readability of a `DropdownMenu` test utility function.

@justinmc I'm still considering creating a test utils file for DropdownMenu but there are few utilities and I'm worried that helper functions in utils file will cripple completion results (not a big deal because it is just for people working on the framework) but I think this should be used carefully. For instance the function `getButtonMaterial` would have to be renamed to something less generic if exposed more broadly (`getMenuItemButtonMaterial` for instance).
2024-11-06 07:14:05 +00:00
Aparin Kirill
7a57b69fcf
fix: ensure draggable_scrollable_sheet respects shouldCloseOnMinExten… (#156338)
This PR fixes the `shouldCloseOnMinExtent` flag in `draggable_scrollable_sheet.dart`.

*The `shouldCloseOnMinExtent` flag was not functioning correctly in the `DraggableScrollableSheet` widget. This PR ensures that the flag is properly handled, preventing the sheet from closing when it reaches the minimum extent if the flag is set to false. Before/after screenshots are not applicable for this change.*

In the code sample below, before my fix, the sheet would close when scrolled down. After my fix, it behaves as expected by respecting the `shouldCloseOnMinExtent` parameter.

### Code Sample
```dart

import 'package:flutter/material.dart';

Future<void> main() async {
  runApp(const MaterialApp(
    home: Home(),
  ));
}

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

  @override
  Widget build(BuildContext context) => Scaffold(
        body: Center(
          child: FilledButton(
            onPressed: () async => showModalBottomSheet(
              context: context,
              isScrollControlled: true,
              isDismissible: false,
              builder: (context) => DraggableScrollableSheet(
                expand: false,
                maxChildSize: 0.9,
                minChildSize: 0.25,
                initialChildSize: 0.5,
                shouldCloseOnMinExtent: false,
                builder: (context, scrollController) => Navigator(
                  onGenerateRoute: (settings) => MaterialPageRoute(
                    settings: settings,
                    builder: (context) => ListView.builder(
                      controller: scrollController,
                      itemExtent: 100,
                      itemCount: 100,
                      itemBuilder: (context, index) => Center(
                        child: Text('$index'),
                      ),
                    ),
                  ),
                ),
              ),
            ),
            child: const Text('Open sheet'),
          ),
        ),
      );
}
```
2024-11-06 00:55:06 +00:00
Matan Lurey
7a6c81a294
Forward fix CupertinoDynamicColor by adding toARGB32(). (#158145)
Unblocks landing https://github.com/flutter/engine/pull/56329.

@jtmcdole monorepo can't come soon enough...
2024-11-06 00:07:08 +00:00
Nate Wilson
b46fb32f48
Factor out "shaker" class (#157748)
I saw that there was a private `_Shaker` class in input_decorator.dart that does the exact same thing as the [MatrixTransition](https://main-api.flutter.dev/flutter/widgets/MatrixTransition-class.html) API.

("hide whitespace" for tiny diffs!)
2024-11-05 23:38:51 +00:00
Kishan Rathore
c1b7740ea4
Fix: Gap between prefix and suffix icon and input field in input deco… (#152069)
Adjust the gap between TextField prefix/suffix and its content. Results in a small visual change for TextFields that use prefix and/or suffix.
2024-11-05 10:54:33 -08:00
Bruno Leroux
338555b764
Refactor DropdownMenu tests (#157913)
## Description

This PR introduces some utility functions to simplify some DropdownMenu tests.
The main purpose is to centralize and document how tests should find menu items, because it is tricky as there are two occurrences of each widgets and using '.last' is mandatory:

```dart
  Finder findMenuItemButton(String label) {
    // For each menu items there are two MenuItemButton widgets.
    // The last one is the real button item in the menu.
    // The first one is not visible, it is part of _DropdownMenuBody
    // which is used to compute the dropdown width.
    return find.widgetWithText(MenuItemButton, label).last;
  }
```

## Related Issue

This is extracted from https://github.com/flutter/flutter/pull/157496.

## Tests

Refactors many existing tests.
2024-11-05 06:11:32 +00:00
Nate Wilson
9ee00ae168
Fix NestedScrollView inner position logic (#157756)
closes #40740

<p align="center">
  <img 
    src="https://github.com/user-attachments/assets/8a48abd0-466b-4e06-90f3-dd05869bac27"
    alt="NestedScrollController fix"
    height="720px"
  />
</p>

<details> <summary><h4>Demo source code</h4> (click to expand)</summary>

(this is a slightly more concise version of the code sample from #40740)

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

void main() {
  runApp(
    const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(body: NewsScreen()),
    ),
  );
}

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

  static const List<String> _tabs = <String>['Featured', 'Popular', 'Latest'];

  static final List<Widget> _tabViews = <Widget>[
    for (final String name in _tabs)
      SafeArea(
        top: false,
        bottom: false,
        child: Builder(builder: (BuildContext context) {
          final handle = NestedScrollView.sliverOverlapAbsorberHandleFor(context);

          return NotificationListener<ScrollNotification>(
            onNotification: (ScrollNotification notification) => true,
            child: CustomScrollView(
              key: PageStorageKey<String>(name),
              slivers: <Widget>[
                SliverOverlapInjector(handle: handle),
                SliverPadding(
                  padding: const EdgeInsets.all(8.0),
                  sliver: SliverList(
                    delegate: SliverChildBuilderDelegate(
                      childCount: 30,
                      (BuildContext context, int index) => Container(
                        margin: const EdgeInsets.only(bottom: 8),
                        width: double.infinity,
                        height: 150,
                        color: const Color(0xFFB0A4C8),
                        alignment: Alignment.center,
                        child: Text(
                          '$name $index',
                          style: const TextStyle(fontWeight: FontWeight.w600),
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          );
        }),
      ),
  ];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: _tabs.length,
      child: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => <Widget>[
          SliverOverlapAbsorber(
            handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
            sliver: SliverSafeArea(
              top: false,
              sliver: SliverAppBar(
                title: const Text('Tab Demo'),
                floating: true,
                pinned: true,
                snap: true,
                forceElevated: innerBoxIsScrolled,
                bottom: TabBar(
                  tabs: _tabs.map((String name) => Tab(text: name)).toList(),
                ),
              ),
            ),
          ),
        ],
        body: TabBarView(children: _tabViews),
      ),
    );
  }
}
```

<br>

</details>

<br>

This bug can be traced to a return statement inside `_NestedScrollPosition`:

```dart
double applyClampedDragUpdate(double delta) {
  // ...
  return delta + offset;
}
```

Thanks to some quirks of floating-point arithmetic, `applyClampedDragUpdate` would sometimes return a tiny non-zero value, which ends up ruining one of the scroll coordinator's equality checks.

8990ed6538/packages/flutter/lib/src/widgets/nested_scroll_view.dart (L658-L664)
2024-11-04 16:42:06 +00:00
Paolo Lammens
d836ca5a68
performance: Override .elementAt in CachingIterable (#152477)
Add a more efficient override of `Iterable.elementAt` in `CachingIterable`.

Closes #152476
2024-11-01 04:50:17 +00:00
Sarbagya Dhaubanjar
19d8fbc6f4
Made insetPadding configurable for Date Picker Dialog (#155651)
This PR adds following properties to the **DatePickerDialog**:
- `insetPadding`
2024-10-31 21:07:08 +00:00
Bruno Leroux
5f65bd06c0
Fix showSnackBar can't access useMaterial3 from the theme (#157707)
## Description

This PR makes it possible for the `MaterialApp` built in `ScaffoldMessenger` state to access the ambient theme.

Before this PR, the built in messenger was above the theme.
After this PR, the build in messenger is below the theme.

## Related Issue

Fixes [Can't access useMaterial3 from the theme in the showSnackBar method](https://github.com/flutter/flutter/issues/115924)

## Tests

Adds 1 test.
2024-10-31 21:04:57 +00:00
chunhtai
b2f72e08ef
Hides added routes before top-most route finishes pushing (#156104)
fixes https://github.com/flutter/flutter/issues/156033
2024-10-31 16:47:55 +00:00
Benji Farquhar
b01558c1cd
Fix cursor on hover expand/collapse icon (#155207) (#155209)
@TahaTesser Fix undesirable side effects of your refactor away from my solution to add `IgnorePointer` during your code review of my PR https://github.com/flutter/flutter/pull/147098. I don't have time to implement my whole initial fix a second time, and update the tests that were added to verify your disabled color change. The issue is resolved with only adding the IgnorePointer.

See [155207](https://github.com/flutter/flutter/issues/155207).
2024-10-31 16:09:18 +00:00
Taha Tesser
b8dcb0c3c5
Update Material 3 LinearProgressIndicator for new visual style (#154817)
Related to [Update both `ProgressIndicator` for Material 3 redesign](https://github.com/flutter/flutter/issues/141340)

### 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> {
  bool isRTL = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(

        body: Directionality(
          textDirection: isRTL ? TextDirection.rtl : TextDirection.ltr,
          child: Center(
            child: Column(
              spacing: 2.0,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text('Default LinearProgressIndicator'),
                const Padding(
                  padding: EdgeInsets.all(16.0),
                  child: LinearProgressIndicator(
                    value: 0.45,
                  ),
                ),
                const Text('Default indefinite LinearProgressIndicator'),
                const Padding(
                  padding: EdgeInsets.all(16.0),
                  child: LinearProgressIndicator(),
                ),
                const Text('Updated height and border radius'),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: LinearProgressIndicator(
                    value: 0.25,
                    minHeight: 16.0,
                    borderRadius: BorderRadius.circular(16.0),
                  ),
                ),
                const Text('Updated stop indicator color and radius'),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: LinearProgressIndicator(
                    value: 0.74,
                    minHeight: 16.0,
                    borderRadius: BorderRadius.circular(16.0),
                    stopIndicatorColor: Theme.of(context).colorScheme.error,
                    stopIndicatorRadius: 32.0,
                  ),
                ),
                const Text('Track gap and stop indicator radius set to 0'),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: LinearProgressIndicator(
                    value: 0.50,
                    minHeight: 16.0,
                    borderRadius: BorderRadius.circular(16.0),
                    trackGap: 0,
                    stopIndicatorRadius: 0,
                  ),
                ),
              ],
            ),
          ),
        ),
        floatingActionButton: FloatingActionButton.extended(
          onPressed: () {
            setState(() {
              isRTL = !isRTL;
            });
          },
          label:  const Text('Toggle Direction'),
        ),
      ),
    );
  }
}
```

</details>

### Preview

<img width="824" alt="Screenshot 2024-09-09 at 13 53 10" src="https://github.com/user-attachments/assets/d12e56a5-f196-4011-8266-c7ab96be96b2">
2024-10-30 18:14:11 +00:00
Taha Tesser
40c22749f5
Add ability to customize the default Slider padding (#156143)
Fixes [Ability to change Sliders padding](https://github.com/flutter/flutter/issues/40098)

Add ability to override default padding so the Slider can fit better in a layout.

### 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> {
  double _sliderValue = 0.5;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        sliderTheme: const SliderThemeData(
          padding: EdgeInsets.symmetric(vertical: 4.0),
          thumbColor: Colors.red,
          inactiveTrackColor: Colors.amber,
        ),
      ),
      home: Scaffold(
        body: Directionality(
          textDirection: TextDirection.ltr,
          child: Center(
            child: Card(
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(4.0)),
              ),
              color: Theme.of(context).colorScheme.surfaceContainerHighest,
              margin: const EdgeInsets.symmetric(horizontal: 16.0),
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    const Placeholder(fallbackHeight: 100.0),
                    Slider(
                      value: _sliderValue,
                      onChanged: (double value) {
                        setState(() {
                          _sliderValue = value;
                        });
                      },
                    ),
                    const Placeholder(fallbackHeight: 100.0),

                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
```

</details>

### Before
(Cannot adjust default `Slider` padding to fill the horizontal space in a `Column` and reduce the padded height)

<img width="717" alt="Screenshot 2024-10-03 at 15 45 18" src="https://github.com/user-attachments/assets/e9d9a4d1-3087-45b4-8607-b94411e2bd23">

### After 
Can adjust default `Slider` padding via `SliderTheme`)

<img width="717" alt="Screenshot 2024-10-03 at 15 46 25" src="https://github.com/user-attachments/assets/cd455881-6d52-46cb-8ac6-cc33f50a13ff">
2024-10-30 10:16:23 +00:00
YeungKC
ec50578982
Fix menu anchor state handling (#157612)
This commit refactors the `_MenuAnchorState` class in `menu_anchor.dart` to include a check for the mounted state and the scheduler phase before calling `setState()`. This ensures that UI updates are only performed when the widget is still mounted and not during the persistent callbacks phase. Additionally, a new test case is added in `menu_anchor_test.dart` to verify that the `isOpen` state of the `MenuAnchor` widget is updated correctly when the button is pressed.

Fix: #157606

*Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.*

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

*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-30 09:42:00 +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
Taha Tesser
97596e5895
Fix TabBar tab icons not respecting custom IconTheme (#157724)
Fixes [TabBar ignores Theme's iconTheme.size](https://github.com/flutter/flutter/issues/155518)

### Description

When `ThemeData.IconTheme`  with color and size, is provided, it can override the default `Tab` icon color and size. 

### 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(
      theme: ThemeData(
        iconTheme: const IconThemeData(color: Colors.amber, size: 40),
      ),
      home: const Scaffold(
        body: SafeArea(
          child: DefaultTabController(
            length: 2,
            child: Column(
              children: [
                TabBar(
                  tabs: [
                    Tab(icon: Icon(Icons.backpack_outlined), text: 'Backpack'),
                    Tab(icon: Icon(Icons.map_outlined), text: 'Map'),
                  ],
                  overlayColor: WidgetStatePropertyAll(Colors.transparent),
                ),
                Expanded(
                  child: TabBarView(
                    children: [
                      Icon(Icons.backpack_outlined),
                      Icon(Icons.map_outlined),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
```

</details>

---

<img width="666" alt="Screenshot 2024-10-28 at 16 25 06" src="https://github.com/user-attachments/assets/56d31115-7ee9-4378-9811-75a3a2a4ce0f">

<img width="666" alt="Screenshot 2024-10-28 at 16 24 52" src="https://github.com/user-attachments/assets/ab8a3e4b-e912-40ac-b249-6358492581e0">
2024-10-29 10:51:38 +00:00
aniq
c83cf967cf
Allow customizing entry mode icons in TimePicker (#157151)
This PR adds two new properties to the Material Design `TimePicker`: `switchToInputEntryModeIcon` and `switchToTimerEntryModeIcon`. These allow developers to customize the icons for toggling between dial and input modes, with default icons (`Icons.keyboard_outlined` and `Icons.access_time`) used if none are provided.

Fixes #156942
2024-10-29 10:25:20 +00:00
yim
04bcfe9281
Fix Scaffold extend body (#157441)
Fixes: #157316
2024-10-27 04:54:30 +00:00
Polina Cherkasova
9cf98f7273
Create flutter specific leak troubleshooting guidance. (#157396) 2024-10-25 13:25:34 -07:00
Kate Lovett
2c20325af4
Update CupertinoNavigationBar to support large layout (#157133)
Fixes https://github.com/flutter/flutter/issues/149625

This adds a new constructor CupertinoNavigationBar.large for the large style navigation bar. CupertinoSliverNavigationBar enables dynamically changing between the smaller and larger layouts for native iOS headers in response to scrolling, this change makes it possible to configure the static navigation bar in one style or the other.
2024-10-25 19:08:12 +00:00
Jonah Williams
c4c545215a
Support backdrop key in flutter framework. (#157278)
The backdrop key functionality allows multiple backdrop filters to share the same input filter, dramatically improving raster performance. This is only supported on the Impeller backend.

The backdrop key class allocates a new int from a static and passes this to the engine layer. with 64 bit integers, we can allocate many backdrop filter ids per frame and never run out.

See also: https://github.com/flutter/flutter/issues/156455

```dart
import 'dart:math';
import 'dart:ui';

import 'package:flutter/material.dart';

final _random = Random();

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

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

  static final listKey = BackdropKey();
  static final overlayKey = BackdropKey();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        body: Stack(
          children: [
            ListView.builder(
              itemCount: 120, // 60 pairs of red and blue containers
              itemBuilder: (context, index) {
                return Container(
                  height: 100,
                  color: index % 2 == 0 ? Colors.red : Colors.blue,
                );
              },
            ),
            Center(
              child: Container(
                width: 400,
                height: 400,
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.black),
                ),
                child: Image.network('https://picsum.photos/400'),
              ),
            ),
            ListView.separated(
              separatorBuilder: (_, __) => const SizedBox(height: 8),
              itemBuilder: (context, index) => BlurEffect(
                backdropKey: listKey,
                child: SizedBox(
                  height: 50,
                  child: Center(
                    child: Text(index.toString(),
                        style: const TextStyle(color: Colors.white)),
                  ),
                ),
              ),
              itemCount: 200,
            ),
            Positioned.fill(
              bottom: null,
              child: BlurEffect(
                backdropKey: overlayKey,
                child: Padding(
                  padding: EdgeInsets.only(
                    top: MediaQuery.of(context).viewPadding.top,
                  ),
                  child: const SizedBox(height: 45),
                ),
              ),
            ),
            Positioned.fill(
              top: null,
              child: BlurEffect(
                backdropKey: overlayKey,
                child: Padding(
                  padding: EdgeInsets.only(
                    top: MediaQuery.of(context).viewPadding.bottom,
                  ),
                  child: const SizedBox(height: 50),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class BlurEffect extends StatelessWidget {
  final Widget child;

  const BlurEffect({
    required this.child,
    required this.backdropKey,
    super.key,
  });

  final BackdropKey backdropKey;

  @override
  Widget build(BuildContext context) {
    return ClipRect(
      child: BackdropFilter(
        backdropKey: backdropKey,
        filter: ImageFilter.blur(
          sigmaX: 40,
          sigmaY: 40,
          // tileMode: TileMode.mirror,
        ),
        child: DecoratedBox(
          decoration: BoxDecoration(color: Colors.black.withOpacity(.65)),
          child: child,
        ),
      ),
    );
  }
}
```

### Skia

<img src="https://github.com/user-attachments/assets/4c08e92d-f0ba-42b2-a4c4-fc44efbcfae0" width="200"/>

### Impeller

<img src="https://github.com/user-attachments/assets/21e95efd-5e0c-4f41-8f84-af3f0e47d1aa" width="200"/>
2024-10-25 16:27:51 +00:00
Mairramer
8cc862c727
Changes the offset computation to first item for RenderSliverMainAxisGroup (#154688)
Fixes https://github.com/flutter/flutter/issues/154615
When scrolling back to the top, the position of the first visible item should have its scrollExtent subtracted. Otherwise, the accumulated position may be retained, which may result in the first visible item being hidden in some cases.
2024-10-24 19:23:07 +00:00
Huy
fa5254331f
Add ability to disable CupertinoSegmentedControl (#152813)
### Summary

Add the ability to configure enabled or disabled segments in CupertinoSegmentedControl. The idea is to pass a `segmentStates` map, where the user can set the state according to segment key. User can also set background and text colors when the segment is disabled.

### Demo

https://github.com/user-attachments/assets/4a02da02-a0fb-4ded-a271-033a8dc79ac3

### Related issue
Fixes https://github.com/flutter/flutter/issues/52105
2024-10-24 12:05:35 +00:00
LongCatIsLooong
2d3697216b
Turn brieflyShowPassword back on on iOS (#157466)
Fixes https://github.com/flutter/flutter/issues/115359

This patch should restore the `brieflyShowPassword` behavior on iOS before https://github.com/flutter/flutter/pull/104335.

On iOS new characters are still temporarily revealed if the user is entering using the software keyboard (potentially because it's easy to fat finger using on screen keyboards?).
2024-10-23 23:22:15 +00:00
Elliott Brooks
802bae0111
Allow requesting a reduced widget tree with getRootWidgetTree service extension (#157309) 2024-10-23 12:30:55 -07:00
Bruno Leroux
b9c889d7d0
Reland "Fix TextField selects all content after the application is resumed" (#157399)
## Description

Relands https://github.com/flutter/flutter/pull/156968 wich was reverted in https://github.com/flutter/flutter/pull/157378 

This PR makes `EditableText` aware of the lifecycle 'resumed' state to let the current selection unchanged when the application is resumed (on web and desktop, 'resumed' means the Flutter app window regained focus).

Before this PR, on web and desktop, the whole content of a `TextField` was selected whenever a `TextField` gained focus. This is the correct behavior when tabbing between fields but it is not when a field regains focus after the application is resumed 

## Related Issue

Fixes [When switching to another browser tab or window and then going back, all text on TextField is selected automatically](https://github.com/flutter/flutter/issues/156078).

## Tests

Adds 1 test.
2024-10-23 15:13:35 +00:00
Nate Wilson
ea0fda51ef
WidgetStateInputBorder (#157190)
**Changes**
- Add `WidgetStateInputBorder` class, with `.resolveWith()` and `.fromMap()` constructors
- Deprecate `MaterialStateOutlineInputBorder` and `MaterialStateUnderlineInputBorder` and provide data-driven fixes

<br>

**Other changes** based on https://github.com/flutter/flutter/pull/154972#pullrequestreview-2344092821
- Fix documentation copy-paste typo ("OutlinedBorder" → "InputBorder")
- Add test to ensure borders are painted correctly
- Add DartPad sample & relevant test
2024-10-22 23:45:41 +00:00
auto-submit[bot]
60d4c9b741
Reverts "Fix TextField selects all content after the application is resumed (#156968)" (#157378)
Reverts: flutter/flutter#156968
Initiated by: jacobsimionato
Reason for reverting: Google3 roll failing - see b/375019489
Original PR Author: bleroux

Reviewed By: {justinmc, gspencergoog}

This change reverts the following previous change:
## Description

This PR makes `EditableText` aware of the lifecycle 'resumed' state to let the current selection unchanged when the application is resumed (on web and desktop, 'resumed' means the Flutter app window regained focus).

Before this PR, on web and desktop, the whole content of a `TextField` was selected whenever a `TextField` gained focus. This is the correct behavior when tabbing between fields but it is not when a field regains focus after the application is resumed 

## Related Issue

Fixes [When switching to another browser tab or window and then going back, all text on TextField is selected automatically](https://github.com/flutter/flutter/issues/156078).

## Tests

Adds 1 test.
2024-10-22 19:59:22 +00:00
João Victor Schramm
1d5087eb30
fix: CupertinoDatePicker.DateAndTime using showDayOfWeek (#155260)
As mentioned in the issue https://github.com/flutter/flutter/issues/153576, even if we declare the 'showDayOfWeek' value as false, when using the mode CupertinoDatePickerMode.dateAndTime, the days of week still shows in the screen.

This PR is about making an assert that prevent developers from using `DateTimePicker.DateAndTime` with `showDayOfWeek` as false (because it only works on date mode) as suggested by @Piinks.
2024-10-22 19:37:19 +00:00
romain.gyh
21814805c1
fix: Considers strokeAlign to compute border dimensions (#155495)
Fixes #155491 

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

There are 3 golden tests that don't pass on my computer, but they were
already not passing before my changes.

<!-- 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>
2024-10-22 12:02:02 -07:00
Bruno Leroux
260bee4d08
Fix MenuController.isOpen throws when unattached (#157331)
## Description

This PR change `MenuController.isOpen` to return false when the `MenuController` is not attached.
Previously `MenuController.isOpen` thrown an assert error when the menu controller was unattached.
With this PR, it is now possible to have some widgets outside the `MenuAnchor` body depending on the menu controller state.

## Related Issue

Fixes [Querying isOpen state for a menu controller that was never attached throws an assertion error](https://github.com/flutter/flutter/issues/157329).

## Tests

Adds 1 test.
2024-10-22 18:49:15 +00:00
Mouad Debbar
e9fb545c05
[web] Allow control of hitTestBehavior of Platform Views (#157189)
Hit testing behavior is currently hardcoded to `opaque`  in `HtmlElementView` which causes the platform view to swallow pointer events when it's a descendant of a `GestureDetector` (see this [example](https://dartpad.dev/?id=5348fbf82be5eeb7d995f953437f0ce6)).

In order to fix this, we need to make `hitTestBehavior` configurable in `HtmlElementView`. This way users can decide to make their platform views `transparent` for hit testing purposes.

**_Note_**: this specific case isn't fixable by `PointerInterceptor` because the framework is already receiving the pointer events, so there's nothing that `PointerInterceptor` can do. This issue is all happening on the framework side since it treats the rectangle occupied by the platform view as an opaque rectangle for hit testing.

**_Workaround_**: in the meantime, users can work around this limitation by surrounding the `HtmlElementView` with an `IgnorePointer` widget.
2024-10-22 17:53:17 +00:00
Jiten Patel
5fa5a64842
[#155269] Platform adaptive showAboutDialog and AboutDialog feature c… (#155377)
This PR introduces a new `showAdaptiveAboutDialog` function, ensuring that the About dialog matches the platform’s design (Material for Android, Fuchsia, Linux, Windows, and, Cupertino for iOS & macOS), providing a more consistent user experience across platforms.

Fixes #155269 

- [] I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
2024-10-22 17:32:05 +00:00
Polina Cherkasova
9edd1ae008
Fix leaks in some image tests and explain hackyness of opted-out. (#154481) 2024-10-22 10:22:01 -07:00
Bruno Leroux
383a221cf3
Fix TextField selects all content after the application is resumed (#156968)
## Description

This PR makes `EditableText` aware of the lifecycle 'resumed' state to let the current selection unchanged when the application is resumed (on web and desktop, 'resumed' means the Flutter app window regained focus).

Before this PR, on web and desktop, the whole content of a `TextField` was selected whenever a `TextField` gained focus. This is the correct behavior when tabbing between fields but it is not when a field regains focus after the application is resumed 

## Related Issue

Fixes to [When switching to another browser tab or window and then going back, all text on TextField is selected automatically](https://github.com/flutter/flutter/issues/156078).

## Tests

To be done
2024-10-22 04:41:31 +00:00
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