Commit Graph

366 Commits

Author SHA1 Message Date
Qun Cheng
a2c7ed95d1
Introduce tone-based surfaces and accent color add-ons - Part 2 (#138521)
This PR is to introduce 19 new color roles and deprecate 3 color roles in `ColorScheme`.
**Tone-based surface colors** (7 colors): 
* surfaceBright
* surfaceDim
* surfaceContainer
* surfaceContainerLowest
* surfaceContainerLow
* surfaceContainerHigh
* surfaceContainerHighest

**Accent color add-ons** (12 colors):
* primary/secondary/tertiary-Fixed
* primary/secondary/tertiary-FixedDim
* onPrimary/onSecondary/onTertiary-Fixed
* onPrimary/onSecondary/onTertiary-FixedVariant

**Deprecated colors**:
* background -> replaced with surface
* onBackground -> replaced with onSurface
* surfaceVariant -> replaced with surfaceContainerHighest

Please checkout this [design doc](https://docs.google.com/document/d/1ODqivpM_6c490T4j5XIiWCDKo5YqHy78YEFqDm4S8h4/edit?usp=sharing) for more information:)

![Screenshot 2024-01-08 at 4 56 51 PM](https://github.com/flutter/flutter/assets/36861262/353cdb4c-6ba9-4435-a518-fd3f67e415f0)
2024-02-20 19:01:50 +00:00
Michael Goderbauer
3f09b23338
cleanup now-irrelevant ignores for deprecated_member_use (#143403)
Follow-up to https://github.com/flutter/flutter/pull/143347.
2024-02-14 21:08:25 +00:00
Bruno Leroux
5c88fbf0b9
Add more documentation for TextEditingController default constructor (#143452)
## Description

This PR adds more documentation for `TextEditingController(String text)` constructor and it adds one example.

https://github.com/flutter/flutter/pull/96245 was a first improvement to the documentation.
https://github.com/flutter/flutter/issues/79495 tried to hide the cursor when an invalid selection is set but it was reverted.
https://github.com/flutter/flutter/pull/123777 mitigated the issue of having a default invalid selection: it takes care of setting a proper selection when a text field is focused and its controller selection is not initialized.

I will try changing the initial selection in another PR, but It will probably break several existing tests.

## Related Issue

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

## Tests

Adds 1 test for the new example.
2024-02-14 20:10:18 +00:00
Taha Tesser
ccf42dde88
Introduce avatarBoxConstraints & deleteIconBoxConstraints for the chips (#143302)
fixes [Chip widget's avatar padding changing if label text is more than 1 line](https://github.com/flutter/flutter/issues/136892)

### Code sample

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

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

List<String> strings = [
  'hello good morning',
  'hello good morning hello good morning',
  'hello good morning hello good morning hello good morning'
];

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  const Text(
                      'avatarBoxConstraints: null \ndeleteIconBoxConstraints: null',
                      textAlign: TextAlign.center),
                  for (String string in strings)
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: RawChip(
                        label: Container(
                          width: 150,
                          color: Colors.amber,
                          child: Text(
                            string,
                            maxLines: 3,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                        avatar: const Icon(Icons.settings),
                        onDeleted: () {},
                      ),
                    ),
                ],
              ),
              Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  const Text(
                      'avatarBoxConstraints: BoxConstraints.tightForFinite() \ndeleteIconBoxConstraints: BoxConstraints.tightForFinite()',
                      textAlign: TextAlign.center),
                  for (String string in strings)
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: RawChip(
                        avatarBoxConstraints:
                            const BoxConstraints.tightForFinite(),
                        deleteIconBoxConstraints:
                            const BoxConstraints.tightForFinite(),
                        label: Container(
                          width: 150,
                          color: Colors.amber,
                          child: Text(
                            string,
                            maxLines: 3,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                        avatar: const Icon(Icons.settings),
                        onDeleted: () {},
                      ),
                    ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

```

</details>

### Preview
![Screenshot 2024-02-12 at 14 58 35](https://github.com/flutter/flutter/assets/48603081/5724bd07-7ac7-4987-b992-fa3ab8488273)

# Example previews
![Screenshot 2024-02-12 at 22 15 14](https://github.com/flutter/flutter/assets/48603081/33af472d-3561-47d4-8d0d-e1628de1e0aa)
![Screenshot 2024-02-12 at 22 15 46](https://github.com/flutter/flutter/assets/48603081/3de78b59-5cb6-4fd8-879b-8e204aacb069)
2024-02-13 20:30:53 +00:00
Tirth
10442399fb
Introduce iconAlignment for the buttons with icon (#137348)
Adds `iconAlignment` property to `ButtonStyleButton` widget.

Fixes #89564

### Example

https://github.com/flutter/flutter/assets/13456345/1b5236c4-5c60-4915-b3c6-0a56c43f8a19
2024-02-12 17:08:20 +00:00
Taha Tesser
c539ded64b
[reland] Add AnimationStyle to showSnackBar (#143052)
[Original was reverted due to uncaught analysis failure 
](https://github.com/flutter/flutter/pull/142825#issuecomment-1930620085)

---

fixes [`showSnackBar` is always replacing `animation` parameter of `SnackBar`](https://github.com/flutter/flutter/issues/141646)

### Code sample preview

![Screenshot 2024-02-02 at 21 10 57](https://github.com/flutter/flutter/assets/48603081/66d808f0-d638-4561-b9a4-96d1b93938f4)
2024-02-07 10:26:27 +00:00
auto-submit[bot]
83aca58fa7
Reverts "Add AnimationStyle to showSnackBar" (#143001)
Reverts flutter/flutter#142825

Initiated by: zanderso

Reason for reverting: Analysis failure closing the engine tree https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8756815302197889649/+/u/Framework_analyze/Framework_analyze/stdout?format=raw

Original PR Author: TahaTesser

Reviewed By: {HansMuller}

This change reverts the following previous change:
Original Description:
fixes [`showSnackBar` is always replacing `animation` parameter of `SnackBar`](https://github.com/flutter/flutter/issues/141646)

### Code sample preview

![Screenshot 2024-02-02 at 21 10 57](https://github.com/flutter/flutter/assets/48603081/66d808f0-d638-4561-b9a4-96d1b93938f4)
2024-02-06 19:35:19 +00:00
Taha Tesser
0cc381da19
Add AnimationStyle to showSnackBar (#142825)
fixes [`showSnackBar` is always replacing `animation` parameter of `SnackBar`](https://github.com/flutter/flutter/issues/141646)

### Code sample preview

![Screenshot 2024-02-02 at 21 10 57](https://github.com/flutter/flutter/assets/48603081/66d808f0-d638-4561-b9a4-96d1b93938f4)
2024-02-06 18:54:41 +00:00
Hans Muller
c6f2cea65e
Reland: Added ButtonStyle.foregroundBuilder and ButtonStyle.backgroundBuilder (#142762)
Reland https://github.com/flutter/flutter/pull/141818 with a fix for a special case: If only `background` is specified for `TextButton.styleFrom` or `OutlinedButton.styleFrom` it applies the button's disabled state, i.e. as if the same value had been specified for disabledBackgroundColor.

The change relative to #141818 is the indicated line below:
```dart
final MaterialStateProperty<Color?>? backgroundColorProp = switch ((backgroundColor, disabledBackgroundColor)) {
  (null, null) => null,
  (_, null) => MaterialStatePropertyAll<Color?>(backgroundColor), // ADDED THIS LINE
  (_, _) => _TextButtonDefaultColor(backgroundColor, disabledBackgroundColor),
};
  ```

This backwards incompatibility cropped up in an internal test, see internal Google issue b/323399158.
2024-02-02 01:48:17 +00:00
auto-submit[bot]
07ca92a69e
Reverts "Added ButtonStyle.foregroundBuilder and ButtonStyle.backgroundBuilder" (#142748)
Reverts flutter/flutter#141818
Initiated by: XilaiZhang
This change reverts the following previous change:
Original Description:
Fixes https://github.com/flutter/flutter/issues/139456, https://github.com/flutter/flutter/issues/130335, https://github.com/flutter/flutter/issues/89563.

Two new properties have been added to ButtonStyle to make it possible to insert arbitrary state-dependent widgets in a button's background or foreground. These properties can be specified for an individual button, using the style parameter, or for all buttons using a button theme's style parameter.

The new ButtonStyle properties are `backgroundBuilder` and `foregroundBuilder` and their (function) types are:

```dart
typedef ButtonLayerBuilder = Widget Function(
  BuildContext context,
  Set<MaterialState> states,
  Widget? child
);
```

The new builder functions are called whenever the button is built and the `states` parameter communicates the pressed/hovered/etc state fo the button.

## `backgroundBuilder`

Creates a widget that becomes the child of the button's Material and whose child is the rest of the button, including the button's `child` parameter.  By default the returned widget is clipped to the Material's ButtonStyle.shape.

The `backgroundBuilder` can be used to add a gradient to the button's background. Here's an example that creates a yellow/orange gradient background:

![opaque-gradient-bg](https://github.com/flutter/flutter/assets/1377460/80df8368-e7cf-49ef-aee7-2776a573644c)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      return DecoratedBox(
        decoration: BoxDecoration(
          gradient: LinearGradient(colors: [Colors.orange, Colors.yellow]),
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

Because the background widget becomes the child of the button's Material, if it's opaque (as it is in this case) then it obscures the overlay highlights which are painted on the button's Material. To ensure that the highlights show through one can decorate the background with an `Ink` widget.  This version also overrides the overlay color to be (shades of) red, because that makes the highlights look a little nicer with the yellow/orange background.

![ink-gradient-bg](https://github.com/flutter/flutter/assets/1377460/68a49733-f30e-44a1-a948-dc8cc95e1716)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    overlayColor: Colors.red,
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      return Ink(
        decoration: BoxDecoration(
          gradient: LinearGradient(colors: [Colors.orange, Colors.yellow]),
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

Now the button's overlay highlights are painted on the Ink widget. An Ink widget isn't needed if the background is sufficiently translucent. This version of the example creates a translucent backround widget. 

![translucent-graident-bg](https://github.com/flutter/flutter/assets/1377460/3b016e1f-200a-4d07-8111-e20d29f18014)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    overlayColor: Colors.red,
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      return DecoratedBox(
        decoration: BoxDecoration(
          gradient: LinearGradient(colors: [
            Colors.orange.withOpacity(0.5),
            Colors.yellow.withOpacity(0.5),
          ]),
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

One can also decorate the background with an image. In this example, the button's background is an burlap texture image. The foreground color has been changed to black to make the button's text a little clearer relative to the mottled brown backround.

![burlap-bg](https://github.com/flutter/flutter/assets/1377460/f2f61ab1-10d9-43a4-bd63-beecdce33b45)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    foregroundColor: Colors.black,
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      return Ink(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(burlapUrl),
            fit: BoxFit.cover,
          ),
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

The background widget can depend on the `states` parameter. In this example the blue/orange gradient flips horizontally when the button is hovered/pressed.

![gradient-flip](https://github.com/flutter/flutter/assets/1377460/c6c6fe26-ae47-445b-b82d-4605d9583bd8)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      final Color color1 = Colors.blue.withOpacity(0.5);
      final Color color2 = Colors.orange.withOpacity(0.5);
      return DecoratedBox(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: switch (states.contains(MaterialState.hovered)) {
              true => <Color>[color1, color2],
              false => <Color>[color2, color1],
            },
          ),
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

The preceeding examples have not included a BoxDecoration border because ButtonStyle already supports `ButtonStyle.shape` and `ButtonStyle.side` parameters that can be uesd to define state-dependent borders. Borders defined with the ButtonStyle side parameter match the button's shape. To add a border that changes color when the button is hovered or pressed, one must specify the side property using `copyWith`, since there's no `styleFrom` shorthand for this case.

![border-gradient-bg](https://github.com/flutter/flutter/assets/1377460/63cffcd3-0dcf-4eb1-aed5-d14adf1e57f6)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    foregroundColor: Colors.indigo,
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      final Color color1 = Colors.blue.withOpacity(0.5);
      final Color color2 = Colors.orange.withOpacity(0.5);
      return DecoratedBox(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: switch (states.contains(MaterialState.hovered)) {
              true => <Color>[color1, color2],
              false => <Color>[color2, color1],
            },
          ),
        ),
        child: child,
      );
    },
  ).copyWith(
    side: MaterialStateProperty.resolveWith<BorderSide?>((Set<MaterialState> states) {
      if (states.contains(MaterialState.hovered)) {
        return BorderSide(width: 3, color: Colors.yellow);
      }
      return null; // defer to the default
    }),
  ),
  child: Text('Text Button'),
)
```

Although all of the examples have created a ButtonStyle locally and only applied it to one button, they could have configured the `ThemeData.textButtonTheme` instead and applied the style to all TextButtons. And, of course, all of this works for all of the ButtonStyleButton classes, not just TextButton.

## `foregroundBuilder`

Creates a Widget that contains the button's child parameter. The returned widget is clipped by the button's [ButtonStyle.shape] inset by the button's [ButtonStyle.padding] and aligned by the button's [ButtonStyle.alignment].

The `foregroundBuilder` can be used to wrap the button's child, e.g. with a border or a `ShaderMask` or as a state-dependent substitute for the child.

This example adds a border that's just applied to the child. The border only appears when the button is hovered/pressed.

![border-fg](https://github.com/flutter/flutter/assets/1377460/687a3245-fe68-4983-a04e-5fcc77f8aa21)

```dart
ElevatedButton(
  onPressed: () {},
  style: ElevatedButton.styleFrom(
    foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      final ColorScheme colorScheme = Theme.of(context).colorScheme;
      return DecoratedBox(
        decoration: BoxDecoration(
          border: states.contains(MaterialState.hovered)
            ? Border(bottom: BorderSide(color: colorScheme.primary))
            : Border(), // essentially "no border"
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

The foregroundBuilder can be used with `ShaderMask` to change the way the button's child is rendered. In this example the ShaderMask's gradient causes the button's child to fade out on top.

![shader_mask_fg](https://github.com/flutter/flutter/assets/1377460/54010f24-e65d-4551-ae58-712135df3d8d)

```dart
ElevatedButton(
  onPressed: () { },
  style: ElevatedButton.styleFrom(
    foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      final ColorScheme colorScheme = Theme.of(context).colorScheme;
      return ShaderMask(
        shaderCallback: (Rect bounds) {
          return LinearGradient(
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
            colors: <Color>[
              colorScheme.primary,
              colorScheme.primaryContainer,
            ],
          ).createShader(bounds);
        },
        blendMode: BlendMode.srcATop,
        child: child,
      );
    },
  ),
  child:  const Text('Elevated Button'),
)
```

A commonly requested configuration for butttons has the developer provide images, one for pressed/hovered/normal state. You can use the foregroundBuilder to create a button that fades between a normal image and another image when the button is pressed. In this case the foregroundBuilder doesn't use the child it's passed, even though we've provided the required TextButton child parameter.

![image-button](https://github.com/flutter/flutter/assets/1377460/f5b1a22f-43ce-4be3-8e70-06de4c958380)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      final String url = states.contains(MaterialState.pressed) ? smiley2Url : smiley1Url;
      return AnimatedContainer(
        width: 100,
        height: 100,
        duration: Duration(milliseconds: 300),
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(url),
            fit: BoxFit.contain,
          ),
        ),
      );
    },
  ),
  child: Text('No Child'),
)
```

In this example the button's default overlay appears when the button is hovered and pressed. Another image can be used to indicate the hovered state and the default overlay can be defeated by specifying `Colors.transparent` for the `overlayColor`:

![image-per-state](https://github.com/flutter/flutter/assets/1377460/7ab9da2f-f661-4374-b395-c2e0c7c4cf13)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    overlayColor: Colors.transparent,
    foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      String url = states.contains(MaterialState.hovered) ? smiley3Url : smiley1Url;
      if (states.contains(MaterialState.pressed)) {
        url = smiley2Url;
      }
      return AnimatedContainer(
        width: 100,
        height: 100,
        duration: Duration(milliseconds: 300),
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(url),
            fit: BoxFit.contain,
          ),
        ),
      );
    },
  ),
  child: Text('No Child'),
)
```
2024-02-01 21:11:26 +00:00
Hans Muller
ff6c8f5d37
Added ButtonStyle.foregroundBuilder and ButtonStyle.backgroundBuilder (#141818)
Fixes https://github.com/flutter/flutter/issues/139456, https://github.com/flutter/flutter/issues/130335, https://github.com/flutter/flutter/issues/89563.

Two new properties have been added to ButtonStyle to make it possible to insert arbitrary state-dependent widgets in a button's background or foreground. These properties can be specified for an individual button, using the style parameter, or for all buttons using a button theme's style parameter.

The new ButtonStyle properties are `backgroundBuilder` and `foregroundBuilder` and their (function) types are:

```dart
typedef ButtonLayerBuilder = Widget Function(
  BuildContext context,
  Set<MaterialState> states,
  Widget? child
);
```

The new builder functions are called whenever the button is built and the `states` parameter communicates the pressed/hovered/etc state fo the button.

## `backgroundBuilder`

Creates a widget that becomes the child of the button's Material and whose child is the rest of the button, including the button's `child` parameter.  By default the returned widget is clipped to the Material's ButtonStyle.shape.

The `backgroundBuilder` can be used to add a gradient to the button's background. Here's an example that creates a yellow/orange gradient background:

![opaque-gradient-bg](https://github.com/flutter/flutter/assets/1377460/80df8368-e7cf-49ef-aee7-2776a573644c)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      return DecoratedBox(
        decoration: BoxDecoration(
          gradient: LinearGradient(colors: [Colors.orange, Colors.yellow]),
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

Because the background widget becomes the child of the button's Material, if it's opaque (as it is in this case) then it obscures the overlay highlights which are painted on the button's Material. To ensure that the highlights show through one can decorate the background with an `Ink` widget.  This version also overrides the overlay color to be (shades of) red, because that makes the highlights look a little nicer with the yellow/orange background.

![ink-gradient-bg](https://github.com/flutter/flutter/assets/1377460/68a49733-f30e-44a1-a948-dc8cc95e1716)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    overlayColor: Colors.red,
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      return Ink(
        decoration: BoxDecoration(
          gradient: LinearGradient(colors: [Colors.orange, Colors.yellow]),
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

Now the button's overlay highlights are painted on the Ink widget. An Ink widget isn't needed if the background is sufficiently translucent. This version of the example creates a translucent backround widget. 

![translucent-graident-bg](https://github.com/flutter/flutter/assets/1377460/3b016e1f-200a-4d07-8111-e20d29f18014)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    overlayColor: Colors.red,
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      return DecoratedBox(
        decoration: BoxDecoration(
          gradient: LinearGradient(colors: [
            Colors.orange.withOpacity(0.5),
            Colors.yellow.withOpacity(0.5),
          ]),
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

One can also decorate the background with an image. In this example, the button's background is an burlap texture image. The foreground color has been changed to black to make the button's text a little clearer relative to the mottled brown backround.

![burlap-bg](https://github.com/flutter/flutter/assets/1377460/f2f61ab1-10d9-43a4-bd63-beecdce33b45)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    foregroundColor: Colors.black,
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      return Ink(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(burlapUrl),
            fit: BoxFit.cover,
          ),
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

The background widget can depend on the `states` parameter. In this example the blue/orange gradient flips horizontally when the button is hovered/pressed.

![gradient-flip](https://github.com/flutter/flutter/assets/1377460/c6c6fe26-ae47-445b-b82d-4605d9583bd8)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      final Color color1 = Colors.blue.withOpacity(0.5);
      final Color color2 = Colors.orange.withOpacity(0.5);
      return DecoratedBox(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: switch (states.contains(MaterialState.hovered)) {
              true => <Color>[color1, color2],
              false => <Color>[color2, color1],
            },
          ),
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

The preceeding examples have not included a BoxDecoration border because ButtonStyle already supports `ButtonStyle.shape` and `ButtonStyle.side` parameters that can be uesd to define state-dependent borders. Borders defined with the ButtonStyle side parameter match the button's shape. To add a border that changes color when the button is hovered or pressed, one must specify the side property using `copyWith`, since there's no `styleFrom` shorthand for this case.

![border-gradient-bg](https://github.com/flutter/flutter/assets/1377460/63cffcd3-0dcf-4eb1-aed5-d14adf1e57f6)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    foregroundColor: Colors.indigo,
    backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      final Color color1 = Colors.blue.withOpacity(0.5);
      final Color color2 = Colors.orange.withOpacity(0.5);
      return DecoratedBox(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: switch (states.contains(MaterialState.hovered)) {
              true => <Color>[color1, color2],
              false => <Color>[color2, color1],
            },
          ),
        ),
        child: child,
      );
    },
  ).copyWith(
    side: MaterialStateProperty.resolveWith<BorderSide?>((Set<MaterialState> states) {
      if (states.contains(MaterialState.hovered)) {
        return BorderSide(width: 3, color: Colors.yellow);
      }
      return null; // defer to the default
    }),
  ),
  child: Text('Text Button'),
)
```

Although all of the examples have created a ButtonStyle locally and only applied it to one button, they could have configured the `ThemeData.textButtonTheme` instead and applied the style to all TextButtons. And, of course, all of this works for all of the ButtonStyleButton classes, not just TextButton.

## `foregroundBuilder`

Creates a Widget that contains the button's child parameter. The returned widget is clipped by the button's [ButtonStyle.shape] inset by the button's [ButtonStyle.padding] and aligned by the button's [ButtonStyle.alignment].

The `foregroundBuilder` can be used to wrap the button's child, e.g. with a border or a `ShaderMask` or as a state-dependent substitute for the child.

This example adds a border that's just applied to the child. The border only appears when the button is hovered/pressed.

![border-fg](https://github.com/flutter/flutter/assets/1377460/687a3245-fe68-4983-a04e-5fcc77f8aa21)

```dart
ElevatedButton(
  onPressed: () {},
  style: ElevatedButton.styleFrom(
    foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      final ColorScheme colorScheme = Theme.of(context).colorScheme;
      return DecoratedBox(
        decoration: BoxDecoration(
          border: states.contains(MaterialState.hovered)
            ? Border(bottom: BorderSide(color: colorScheme.primary))
            : Border(), // essentially "no border"
        ),
        child: child,
      );
    },
  ),
  child: Text('Text Button'),
)
```

The foregroundBuilder can be used with `ShaderMask` to change the way the button's child is rendered. In this example the ShaderMask's gradient causes the button's child to fade out on top.

![shader_mask_fg](https://github.com/flutter/flutter/assets/1377460/54010f24-e65d-4551-ae58-712135df3d8d)

```dart
ElevatedButton(
  onPressed: () { },
  style: ElevatedButton.styleFrom(
    foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      final ColorScheme colorScheme = Theme.of(context).colorScheme;
      return ShaderMask(
        shaderCallback: (Rect bounds) {
          return LinearGradient(
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
            colors: <Color>[
              colorScheme.primary,
              colorScheme.primaryContainer,
            ],
          ).createShader(bounds);
        },
        blendMode: BlendMode.srcATop,
        child: child,
      );
    },
  ),
  child:  const Text('Elevated Button'),
)
```

A commonly requested configuration for butttons has the developer provide images, one for pressed/hovered/normal state. You can use the foregroundBuilder to create a button that fades between a normal image and another image when the button is pressed. In this case the foregroundBuilder doesn't use the child it's passed, even though we've provided the required TextButton child parameter.

![image-button](https://github.com/flutter/flutter/assets/1377460/f5b1a22f-43ce-4be3-8e70-06de4c958380)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      final String url = states.contains(MaterialState.pressed) ? smiley2Url : smiley1Url;
      return AnimatedContainer(
        width: 100,
        height: 100,
        duration: Duration(milliseconds: 300),
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(url),
            fit: BoxFit.contain,
          ),
        ),
      );
    },
  ),
  child: Text('No Child'),
)
```

In this example the button's default overlay appears when the button is hovered and pressed. Another image can be used to indicate the hovered state and the default overlay can be defeated by specifying `Colors.transparent` for the `overlayColor`:

![image-per-state](https://github.com/flutter/flutter/assets/1377460/7ab9da2f-f661-4374-b395-c2e0c7c4cf13)

```dart
TextButton(
  onPressed: () {},
  style: TextButton.styleFrom(
    overlayColor: Colors.transparent,
    foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
      String url = states.contains(MaterialState.hovered) ? smiley3Url : smiley1Url;
      if (states.contains(MaterialState.pressed)) {
        url = smiley2Url;
      }
      return AnimatedContainer(
        width: 100,
        height: 100,
        duration: Duration(milliseconds: 300),
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(url),
            fit: BoxFit.contain,
          ),
        ),
      );
    },
  ),
  child: Text('No Child'),
)
```
2024-02-01 00:02:23 +00:00
LongCatIsLooong
505845c5ac
Remove textScaleFactor references from flutter/flutter (#142271)
These should the the last remaining `MediaQueryData.textScaleFactor` and `TextScaler.textScaleFactor` references.
2024-01-26 19:12:24 +00:00
Justin McCandless
204a8848a6
PopScope example improvements (#142163)
Attempting to help users understand how to build a confirmation dialog when exiting a route.
2024-01-25 10:14:49 -08:00
Anis Alibegić
81d80c587d
Fixed a lot of typos (#141431)
Fair amount of typos spotted and fixed. Some of them are in comments, some of them are in code and some of them are in nondart files.

There is no need for issues since it's a typo fix.

I have doubts about [packages/flutter_tools/lib/src/ios/core_devices.dart](https://github.com/flutter/flutter/compare/master...anisalibegic:flutter:master#diff-fdbc1496b4bbe7e2b445a567fd385677af861c0093774e3d8cc460fdd5b794fa), I have a feeling it might broke some things on the other end, even though it's a typo.
2024-01-12 22:10:25 +00:00
Mairramer
f40a99ce7e
Adds support for StepStyle visual property bundle to the Step widget (#140825)
Fixes  #140770 and #103124

Adds the possibility of passing a height and width to icons. And also a margin for the distance of the lines between the icons.
2024-01-12 16:35:08 +00:00
Taha Tesser
536de5ed91
Update RouteObserver example and fix an error thrown (#141166)
fixes [`RouteObserver` example throws an error](https://github.com/flutter/flutter/issues/141078)

### Description
This updates the `RouteObserver` example from snippet to Dartpad example and fixes the error when running the code snippet
2024-01-09 20:48:56 +00:00
Furkan Acar
83ac76050d
Add SegmentedButton.styleFrom (#137542)
fixes https://github.com/flutter/flutter/issues/138289

---

SegmentedButtom.styleFrom has been added to the segment button, so there is no longer any need to the button style from the beginning. It works like ElevatedButton.styleFrom only I added selectedForegroundColor, selectedBackgroundColor. In this way, the user will be able to change the color first without checking the MaterialState states. I added tests of the same controls.

#129215 I opened this problem myself, but I was rejected because I handled too many items in a PR. For now, I wrote a structure that only handles MaterialStates instead of users.

old (still avaliable)
<img width="626" alt="image" src="https://github.com/flutter/flutter/assets/65075121/9446b13b-c355-4d20-bda2-c47a23d42d4f">

new (just an option for developer)
<img width="483" alt="image" src="https://github.com/flutter/flutter/assets/65075121/0a645257-4c83-4029-9484-bd746c02265f">

### Code sample

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

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

/// Flutter code sample for [SegmentedButton].

void main() {
  runApp(const SegmentedButtonApp());
}

enum Calendar { day, week, month, year }

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

  @override
  State<SegmentedButtonApp> createState() => _SegmentedButtonAppState();
}

class _SegmentedButtonAppState extends State<SegmentedButtonApp> {
  Calendar calendarView = Calendar.day;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(useMaterial3: true),
      home: Scaffold(
        body: Center(
          child: SegmentedButton<Calendar>(
            style: SegmentedButton.styleFrom(
              foregroundColor: Colors.amber,
              visualDensity: VisualDensity.comfortable,
            ),
            // style: const ButtonStyle(
            //   foregroundColor: MaterialStatePropertyAll<Color>(Colors.deepPurple),
            //   visualDensity: VisualDensity.comfortable,
            // ),
            segments: const <ButtonSegment<Calendar>>[
              ButtonSegment<Calendar>(
                  value: Calendar.day,
                  label: Text('Day'),
                  icon: Icon(Icons.calendar_view_day)),
              ButtonSegment<Calendar>(
                  value: Calendar.week,
                  label: Text('Week'),
                  icon: Icon(Icons.calendar_view_week)),
              ButtonSegment<Calendar>(
                  value: Calendar.month,
                  label: Text('Month'),
                  icon: Icon(Icons.calendar_view_month)),
              ButtonSegment<Calendar>(
                  value: Calendar.year,
                  label: Text('Year'),
                  icon: Icon(Icons.calendar_today)),
            ],
            selected: <Calendar>{calendarView},
            onSelectionChanged: (Set<Calendar> newSelection) {
              setState(() {
                calendarView = newSelection.first;
              });
            },
          ),
        ),
      ),
    );
  }
}

```

</details>
2024-01-03 21:26:02 +00:00
Nate
140f5eef4c
Implement switch expressions in examples/ and animation/ (#139882)
Thanks so much for approving the previous PR (#139048) a couple weeks ago!

This one is the same, except it's covering files in `examples/` and `packages/flutter/lib/src/animation/`.

(solving issue #136139)
2023-12-11 22:56:04 +00:00
Greg Spencer
a33dec1a27
Deprecate RawKeyEvent, RawKeyboard, et al. (#136677)
## Description

This starts the deprecation of the `RawKeyEvent`/`RawKeyboard` event system that has been replaced by the `KeyEvent`/`HardwareKeyboard` event system.

Migration guide is available here: https://docs.flutter.dev/release/breaking-changes/key-event-migration

## Related Issues
 - https://github.com/flutter/flutter/issues/136419

## Related PRs
 - https://github.com/flutter/website/pull/9889
2023-12-11 22:19:18 +00:00
Renzo Olivares
f60e54b24c
Fix SelectionArea select-word edge cases (#136920)
This change fixes issues with screen order comparison logic when rects are encompassed within each other. This was causing issues when trying to select text that includes inline `WidgetSpan`s inside of a `SelectionArea`.

* Adds `boundingBoxes` to `Selectable` for a more precise hit testing region.

Fixes #132821
Fixes updating selection edge by word boundary when widget spans are involved.
Fixes crash when sending select word selection event to an unselectable element.
2023-12-11 21:32:55 +00:00
Ian Hickson
c674161404
Animate TextStyle.fontVariations (#138881)
Fixes https://github.com/flutter/flutter/issues/105120

I also exposed the relevant dart:ui types which had the effect of removing a large number of dart:ui imports from examples.
2023-12-08 09:08:26 +00:00
Taha Tesser
f794cf9d97
Add AnimationStyle to ExpansionTile (#139664)
fixes [Expose animation parameters for the [ExpansionTile] widget](https://github.com/flutter/flutter/issues/138047)

### Description
Add `AnimationStyle` to the `ExpansionTile` widget to override the default expand and close animation.

Syntax:
```dart
        child: ExpansionTile(
          title: const Text('Tap to expand'),
          expansionAnimationStyle: AnimationStyle(
            duration: Durations.extralong1,
            curve: Easing.emphasizedAccelerate,
          ),
          children: const <Widget>[FlutterLogo(size: 200)],
        ),
```

### Code sample

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

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

import 'package:flutter/material.dart';

/// Flutter code sample for [ExpansionTile] and [AnimationStyle].

void main() {
  runApp(const ExpansionTileAnimationStyleApp());
}

enum AnimationStyles { defaultStyle, custom, none }
const List<(AnimationStyles, String)> animationStyleSegments = <(AnimationStyles, String)>[
  (AnimationStyles.defaultStyle, 'Default'),
  (AnimationStyles.custom, 'Custom'),
  (AnimationStyles.none, 'None'),
];

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

  @override
  State<ExpansionTileAnimationStyleApp> createState() => _ExpansionTileAnimationStyleAppState();
}

class _ExpansionTileAnimationStyleAppState extends State<ExpansionTileAnimationStyleApp> {
  Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{AnimationStyles.defaultStyle};
  AnimationStyle? _animationStyle;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              SegmentedButton<AnimationStyles>(
                selected: _animationStyleSelection,
                onSelectionChanged: (Set<AnimationStyles> styles) {
                  setState(() {
                    _animationStyleSelection = styles;
                    switch (styles.first) {
                      case AnimationStyles.defaultStyle:
                        _animationStyle = null;
                      case AnimationStyles.custom:
                        _animationStyle = AnimationStyle(
                          curve: Easing.emphasizedAccelerate,
                          duration: Durations.extralong1,
                        );
                      case AnimationStyles.none:
                        _animationStyle = AnimationStyle.noAnimation;
                    }
                  });
                },
                segments: animationStyleSegments
                  .map<ButtonSegment<AnimationStyles>>(((AnimationStyles, String) shirt) {
                    return ButtonSegment<AnimationStyles>(value: shirt.$1, label: Text(shirt.$2));
                  })
                  .toList(),
              ),
              const SizedBox(height: 20),
              ExpansionTile(
                expansionAnimationStyle: _animationStyle,
                title: const Text('ExpansionTile'),
                children: const <Widget>[
                  ListTile(title: Text('Expanded Item 1')),
                  ListTile(title: Text('Expanded Item 2')),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}
```

</details>

Related to https://github.com/flutter/flutter/pull/138721.
2023-12-06 16:40:24 +00:00
Taha Tesser
fc917c7184
[Reland] Introduce AnimationStyle (#138721)
This PR introduces `AnimationStyle`, it is used to override default
animation curves and durations in several widgets.

fixes [Add the ability to customize MaterialApp theme animation
duration](https://github.com/flutter/flutter/issues/78372)
fixes [Allow customization of showMenu transition animation curves and
duration](https://github.com/flutter/flutter/issues/135638)
fixes [`AnimationStyle.noAnimation` needs to replace `AnimatedTheme`
with just `Theme` in the
`MaterialApp`](https://github.com/flutter/flutter/issues/138618)

Here is an example where popup menu curve and transition duration is
overridden:

```dart
          popUpAnimationStyle: AnimationStyle(
            curve: Easing.emphasizedAccelerate,
            duration: Durations.medium4,
          ),
```

Set `AnimationStyle.noAnimation` to disable animation.
```dart
    return MaterialApp(
      themeAnimationStyle: AnimationStyle.noAnimation,
```

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] 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/wiki/Tree-hygiene#overview
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[test-exempt]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/wiki/Chat
2023-11-20 15:24:41 -08:00
Parker Lougheed
096cdc39a9
Update links and surrounding text for new main-api docs (#138602)
Issue reference: https://github.com/flutter/flutter/issues/133877
2023-11-17 22:27:53 +00:00
auto-submit[bot]
0135a3310a
Reverts "Introduce AnimationStyle" (#138628)
Reverts flutter/flutter#137945
Initiated by: HansMuller
This change reverts the following previous change:
Original Description:
This PR introduces `AnimationStyle`, it is used to override default animation curves and durations in several widgets.

fixes  [Add the ability to customize MaterialApp theme animation duration](https://github.com/flutter/flutter/issues/78372)
fixes [Allow customization of showMenu transition animation curves and duration](https://github.com/flutter/flutter/issues/135638)

Here is an example where popup menu curve and transition duration is overriden:

```dart
          popUpAnimationStyle: AnimationStyle(
            curve: Easing.emphasizedAccelerate,
            duration: Durations.medium4,
          ),
```

Set `AnimationStyle.noAnimation` to disable animation.
```dart
    return MaterialApp(
      themeAnimationStyle: AnimationStyle.noAnimation,
```
2023-11-17 16:59:19 +00:00
Taha Tesser
19e284f88f
Introduce AnimationStyle (#137945)
This PR introduces `AnimationStyle`, it is used to override default animation curves and durations in several widgets.

fixes  [Add the ability to customize MaterialApp theme animation duration](https://github.com/flutter/flutter/issues/78372)
fixes [Allow customization of showMenu transition animation curves and duration](https://github.com/flutter/flutter/issues/135638)

Here is an example where popup menu curve and transition duration is overriden:

```dart
          popUpAnimationStyle: AnimationStyle(
            curve: Easing.emphasizedAccelerate,
            duration: Durations.medium4,
          ),
```

Set `AnimationStyle.noAnimation` to disable animation.
```dart
    return MaterialApp(
      themeAnimationStyle: AnimationStyle.noAnimation,
```
2023-11-16 18:33:20 +00:00
huycozy
61c007a3f7
Update DraggableScrollableSheet docs to reflect API change (#136471)
### Description

This PR intends to update `DraggableScrollableSheet` docs for Web and Desktop platforms. On these platforms, the vertical dragging gesture does not provide natural behavior similar to other desktop applications. 

By adding a note before the sample code so users are aware that the sample code will not work as expected on Desktop and Web. Also, refer to the instructions if they still want to implement it on these platforms.

### Related issue

Fixes https://github.com/flutter/flutter/issues/111372
2023-11-13 21:48:03 +00:00
Chinmoy
0bde95dc06
Deprecates onWillAccept and onAccept callbacks in DragTarget. (#133691)
This PR deprecates `onWillAccept` and `onAccept` over `onWillAcceptWithDetails` and `onAcceptWithDetails`.

Fixes: #133347
2023-11-10 22:47:22 +00:00
Hans Muller
84bfe64023
Added an AnimationController API doc example (#137975)
This example shows how to use `AnimationController` and
`SlideTransition` to create an animated digit like you might find on a
digital clock. New digit values slide into place from below, as the old
value slides upwards and out of view. Taps that occur while the
controller is already animating cause the controller's
`AnimationController.duration` to be reduced so that the visuals don't
fall behind.

You can try the example here:
https://dartpad.dev/?id=9553c20fe0fdb0c5447c1293e02400eb
2023-11-07 13:33:20 -08:00
Qun Cheng
ed70f4e248
Adaptive Switch (#130425)
Currently, `Switch.factory` delegates to `CupertinoSwitch` when platform
is iOS or macOS. This PR is to:
* have the factory configure the Material `Switch` for the expected look
and feel.
* introduce `Adaptation` class to customize themes for the adaptive
components.
2023-11-07 10:26:23 -08:00
Michael Goderbauer
8a0f9118ea
Remove unused generic type from BottomSheet (#137791)
Fixes https://github.com/flutter/flutter/issues/137424.

The generic type argument was unused.
2023-11-03 22:25:37 +00:00
Chris Bobbe
e7f99821cc
Tooltip docs: Recommend setting preferBelow to false in theme (#135879)
As discussed at https://github.com/flutter/flutter/pull/133007#issuecomment-1743916183, this is a docs change meant to help people in the absence of a fix for #133006, which is being closed as WONTFIX.
2023-11-03 20:18:36 +00:00
Hans Muller
3479aaba75
Updated the nested navigation NavigationBar example (#137788)
Updated the NavigationBar API doc that describes
examples/api/lib/material/navigation_bar/navigation_bar.2.dart and made
some cosmetic changes to the example to improve its appearance in
Material 3. Also did a little gratuitous reformatting.

Fixes #136125
2023-11-03 10:46:09 -07:00
Qun Cheng
4a0f261b4e
Add Card.filled and Card.outlined factory methods (#136229)
Fixes #119401

This PR is to:
* add `Card.filled` and `Card.outlined` factory methods so that we can use tokens for these two types of cards to generate default theme instead of providing hard-corded values in example.
* update card.2.dart example.
* add test file for card.2.dart example.
* fix some mismatch caused by editing the auto-generated defaults by hand in navigation_bar.dart and navigation_drawer.dart.
2023-11-01 23:29:49 +00:00
Tirth
b62da79190
Fix Typos (#137292)
Fix Small Typos.
2023-10-26 23:55:38 +00:00
cui fliter
c5e71b3e59
fix some typos (#137144)
*Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.*

fix some typos

*List which issues are fixed by this PR. You must list at least one issue.*

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
2023-10-24 15:27:07 +00:00
Greg Spencer
13a0d475f5
Convert menus to use OverlayPortal (#130534)
## Description

This converts the `MenuAnchor` class to use `OverlayPortal` instead of directly using the overlay.

## Related Issues
 - Fixes https://github.com/flutter/flutter/issues/124830

## Tests
 - No tests yet (hence it is a draft)
2023-10-18 20:13:08 +00:00
Gildásio Filho
492b6f7ddf
Add findChildIndexCallback examples (#133469)
The documentation for using `findChildIndexCallback` recommends using `indexOf`, but that causes [this line](05259ca938/packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart (L259)) to throw in debug mode, and when using `SliverList`, it breaks the render.

This PR changes the usage to check if the index is not negative before using it, and changes to return `null` instead if the child wasn't able to be found.

There's the related issue #107123, but this doesn't actually fix it.

-----

This PR has been updated to add the snippets that were used in the `findChildIndexCallback` comment as examples with proper tests, as well as updating the comment to reference the new examples.
2023-10-18 00:26:17 +00:00
Greg Spencer
3ef32f0407
Change some usage of RawKeyEvent to KeyEvent in preparation for deprecation (#136420)
## Description

This converts some usages of `RawKeyEvent` to `KeyEvent` to prepare the repo for deprecation of `RawKeyEvent`, and swaps out the `raw_keyboard.dart` manual test for `hardware_keyboard.dart`.

## Related Issues
 - https://github.com/flutter/flutter/issues/136419

## Tests
 - Just refactoring code, no semantic changes.
2023-10-14 00:25:18 +00:00
Greg Spencer
22b0a62a0c
Allow TapRegion to consume tap events (#136305)
## Description

In order for `MenuAnchor` menus to be able to not pass on the taps that close their menus, `TapRegion` needed a way to consume them.  This change adds a flag to the `TapRegion`, `consumeOutsideTap` that will consume taps that occur outside of the region if the flag is set (it is false by default). The same flag is added to `MenuAnchor` to allow selecting the behavior for menus.

`TapRegion` consumes the tap event by registering with the gesture arena and immediately resolving the tap as accepted if any regions in a group have `consumeOutsideTap` set to true.

This PR also deprecates `MenuAnchor.anchorTapClosesMenu`, since it is a much more limited version of the same feature that only applied to the anchor itself, and even then only applied to closing the menu, not passing along the tap.  The same functionality can now be implemented by handling a tap on the anchor widget and checking to see if the menu is open before closing it.

## Related Issues
 - https://github.com/flutter/flutter/issues/135327

## Tests
 - Added tests for `TapRegion` to make sure taps are consumed properly.
2023-10-12 21:04:41 +00:00
huycozy
e8a0cf3ae8
Fix PageView API doc sample fails on Desktop and Web (#135910)
### Description

This PR aims to improve/fix the PageView API doc sample for Web and Desktop platforms. On these platforms, mouse dragging gestures do not provide natural behavior similar to other desktop applications. This PR will add navigation buttons (indicators) so users can interact with the demo.

### Related issue

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

### Demo video

https://github.com/flutter/flutter/assets/104349824/0f9c60bd-8b18-404e-b5b6-1d594604de31
2023-10-12 17:28:13 +00:00
Michael Goderbauer
b0a90aee17
Enable strict-inference (#135043)
Avoids that dynamic accidentally sneaks in, see https://dart.dev/tools/analysis#enabling-additional-type-checks
2023-09-20 19:59:08 +00:00
Xilai Zhang
6425a3b431
[flutter roll] Revert "LinkedText (Linkify)" (#134955)
Reverts flutter/flutter#125927

context: b/300804374

Looks like a g3 fix might involve changing the names of widget on the customer app, and I am not sure if that would be the right approach forward. Putting up a revert to be safe for now.
2023-09-18 19:49:10 +00:00
huycozy
c2b1e483dd
Improve DropdownMenu sample code for requestFocusOnTap on mobile platforms (#134867)
### Description

This PR is to improve `DropdownMenu` sample code. By default, `requestFocusOnTap` is false on mobile platforms. When users run API sample code on mobile platforms, they can not edit the text field and think it is a bug. Although it is detailed at https://api.flutter.dev/flutter/material/DropdownMenu/requestFocusOnTap.html, users often do not pay attention to it.

### Related issue

Fixes https://github.com/flutter/flutter/issues/127672
2023-09-18 08:33:14 +00:00
Justin McCandless
4db47db177
LinkedText (Linkify) (#125927)
New LinkedText widget and TextLinker class for easily adding hyperlinks to text.
2023-09-13 20:39:58 -07:00
Chinmay Kabi
4a3ab6828a
Fix DataTable example not being scrollable (#131556) 2023-09-11 18:55:53 -05:00
xubaolin
f4707c2b3d
fix a Scrollbar example crash (#127925)
Fix a scrollbar example crash.
https://api.flutter.dev/flutter/material/Scrollbar-class.html#material.Scrollbar.1
2023-09-08 09:40:49 +00:00
Andrea Cioni
400702d1d6
Add an example for InputChip generated by user input (#130645)
New example for `InputChip` that demonstrate how to create/delete them based on user text inputs.

The sample application shows a custom text area where user can enter text. After the user has typed and hits _Enter_ the text will be replaced with an `InputChip` that contains that text. Is it possible to continue typing and add more chips in this way. All of them will be placed in a scrollable horizontal row. Also is it possible to have suggestion displayed below the text input field in case the typed text match some of the available suggestions.

Issue I'm trying to solve:

- https://github.com/flutter/flutter/issues/128247

**Code structure:**

The example app is composed of 2 main components that find places inside `MainScreen`:

 - `ChipsInput`
 - `ListView`

`ChipsInput` emulates a `TextField` where you can enter text. This text field accepts also a list of values of generic type T (`Topping` in my example), that gets rendered as `InputChip` inside the text field, before the text inserted by the user. This widgets is basically an `InputDecorator` widget that implements `TextInputClient` to get `TextEditingValue` events from the user keyboard. At the end of the input field there is another component, the `TextCursor`, that is displayed just when the user give the focus to the field and emulates the carrets that `TextField` has.

There are also some available callbacks that the user can use to capture events in the `ChipsInput` field like: `onChanged`, `onChipTapped`, `onSubmitted` and `onTextChanged`. This last callback is used to build a list of suggestion that will be placed just below the `ChipsInput` field inside the `ListView`.
2023-09-01 00:02:04 +00:00
Kate Lovett
5b6d748cb4
Fix sample code crash, add test (#133812)
Fixes https://github.com/flutter/flutter/issues/133402

On web `1 << 32` crashes, 31 is the maximum.
2023-08-31 22:56:06 +00:00
Hans Muller
336d60d29c
Updated DropdownMenu example and added a test (#133592) 2023-08-30 14:33:54 -07:00