46 Commits

Author SHA1 Message Date
Kate Lovett
9d96df2364
Modernize framework lints (#179089)
WIP

Commits separated as follows:
- Update lints in analysis_options files
- Run `dart fix --apply`
- Clean up leftover analysis issues 
- Run `dart format .` in the right places.

Local analysis and testing passes. Checking CI now.

Part of https://github.com/flutter/flutter/issues/178827
- Adoption of flutter_lints in examples/api coming in a separate change
(cc @loic-sharma)

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

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2025-11-26 01:10:39 +00:00
Huy
ab919febb3
Fix VoiceOver does not announce state of ButtonSegment (#175635)
- Fix https://github.com/flutter/flutter/issues/146987
- As explained at
https://github.com/flutter/flutter/issues/146987#issuecomment-3294737075:
this PR proposes _replacing_ `checked` with `selected` here:
 

f4de70c647/packages/flutter/lib/src/material/segmented_button.dart (L634)
 
Then VoiceOver can indicate when the button segment is selected. It's
_replacing_ action but not _adding_ because _adding_ (keep both
`checked` and `selected`) will cause the button to be read with both
checked and selected states with Android TalkBack reader that may cause
confusion to users (watch demo videos). I also did test with iOS
segmented control (storyboard) and Android Jetpack Compose to compare:
on these native platforms, it announces `selected` state (watch demo
videos).

<details>
<summary>Demo Flutter app - after the fix</summary>

| Flutter Android | Flutter iOS |
| --------------- | --------------- |
<video
src="https://github.com/user-attachments/assets/458c9b78-8275-45db-83cb-b2581505d240"/>
| <video
src="https://github.com/user-attachments/assets/1c69694d-67f8-4f8c-a453-2cf7696e43b5"/>

</details>

<details>
<summary>Demo native platforms</summary>

| Android Jetpack Compose | iOS segmented control (storyboard) |
| --------------- | --------------- |
<video
src="https://github.com/user-attachments/assets/5b682c7e-4c50-49be-a613-58673154aa88"/>
| <video
src="https://github.com/user-attachments/assets/9faba9ea-d373-4756-953a-cde510871247"/>

</details>

## Pre-launch Checklist

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

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

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

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

Signed-off-by: huycozy <huy@nevercode.io>
Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
2025-11-10 22:43:23 +00:00
Ahmed Mohamed Sameh
46c3f84370
Make sure that a SegmentedButton doesn't crash in 0x0 environment (#177773)
This is my attempt to handle
https://github.com/flutter/flutter/issues/6537 for the SegmentedButton
widget.
2025-11-02 19:53:57 +00:00
Camille Simon
7fd228f31d
[Material] Change default mouse cursor of buttons to basic arrow instead of click (except on web) (#171796)
Changes default mouse cursor of Material buttons to basic arrow instead
of click as per updated Android guidance.

For each Material button, I did the following:

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

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

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

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

## Pre-launch Checklist

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

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

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

---------

Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
2025-10-23 22:24:00 +00:00
Valentin Vignal
28a286dfe9
Migrate to WidgetState (#175396)
Follow up of https://github.com/flutter/flutter/pull/175242

Migrate the remaining files from `MaterialState` to `WidgetState`. This
PR only focus on WidgetState for a subset of files.

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

## Pre-launch Checklist

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

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

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2025-09-18 03:16:22 +00:00
Bruno Leroux
9d4db1d5dd
Fix SegmentedButton focus issue (#173953)
## Description

This PR fixes SegmentedButton focus traversal.

# Before

When a focused segment (with no icon) is selected or unselected, the
focus moves to another segment.

[Capture vidéo du 2025-08-11
15-28-03.webm](https://github.com/user-attachments/assets/11c29194-6b96-4ea4-9245-dcbd36dc424f)

In this recording, tab key is used to set the focus on 'Month' segment,
then enter is used to select the segment. The focus move unexpectedly to
'Week' segment.

# After

When a focused segment (with no icon) is selected or unselected, the
focus stays on this same segment and the InkWell animations are
correctly painted.

[Capture vidéo du 2025-08-11
15-27-30.webm](https://github.com/user-attachments/assets/e09056d0-b572-462b-8ad8-c23eddcc4bfd)


<details><summary>Code sample for recordings</summary>

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

/// Flutter code sample for [SegmentedButton].

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(body: Center(child: SingleChoice())),
    );
  }
}

enum Calendar { day, week, month, year }

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

  @override
  State<SingleChoice> createState() => _SingleChoiceState();
}

class _SingleChoiceState extends State<SingleChoice> {
  Calendar calendarView = Calendar.day;

  @override
  Widget build(BuildContext context) {
    return SegmentedButton<Calendar>(
      segments: const <ButtonSegment<Calendar>>[
        ButtonSegment<Calendar>(value: Calendar.day, label: Text('Day')),
        ButtonSegment<Calendar>(value: Calendar.week, label: Text('Week')),
        ButtonSegment<Calendar>(value: Calendar.month, label: Text('Month')),
        ButtonSegment<Calendar>(value: Calendar.year, label: Text('Year')),
      ],
      selected: <Calendar>{calendarView},
      onSelectionChanged: (Set<Calendar> newSelection) {
        setState(() {
          // By default there is only a single segment that can be
          // selected at one time, so its value is always the first
          // item in the selected set.
          calendarView = newSelection.first;
        });
      },
    );
  }
}

``` 
</details> 

## Related Issue

Fixes [SegmentedButton keyboard navigation incorrectly moves focus on
click](https://github.com/flutter/flutter/issues/161922)


## Implementation choice

The root of this issue is TextButton.icon which creates a different
widget tree depending on the icon.
See https://github.com/flutter/flutter/issues/173944 for more context.

The proposed solution is to maintain the same widget tree when possible.
To do TextButton.icon is not used. This PR uses on TextButton and build
a child containing both the icon (when present) and the label.
In order to keep the same rendering as before, some internal logic from
TextButton.icon is duplicated.

## Tests

Adds 1 test.
Updates 1 test.
2025-08-20 06:10:07 +00:00
Ricardo Dalarme
56d5389456
Migrate to null aware elements - Part 5 (#172418)
## Description

Continuing the work from @jamilsaadeh97 to replace verbose null checks
with modern
[null_aware_elements](https://dart.dev/tools/linter-rules/use_null_aware_elements)
syntax.

This PR cleans up the remaining files not covered in the previous parts,
making the code more concise.

## Related PRs

- https://github.com/flutter/flutter/pull/172198
- https://github.com/flutter/flutter/pull/172306
- https://github.com/flutter/flutter/pull/172307
- https://github.com/flutter/flutter/pull/172322

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
2025-07-30 18:40:09 +00:00
Bruno Leroux
c825031ba2
Fix SegmentedButton border doesn't reflect states (#172754)
## Description

This PR fixes `SegmentedButton` border side not depending on the current
state.

It's based on one @TahaTesser 's great PR: see
https://github.com/flutter/flutter/pull/161942. 🙏
I updated some logic related to disabled border which led to Taha’s PR
failing internal Google tests.
I also added a test to verify the disabled border.

<details><summary>Code sample for screenshots</summary>

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

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;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        segmentedButtonTheme: SegmentedButtonThemeData(
          style: ButtonStyle(
            side: WidgetStateProperty.fromMap(<WidgetStatesConstraint, BorderSide?>{
              WidgetState.disabled: const BorderSide(color: Colors.grey, width: 2),
              WidgetState.selected & WidgetState.hovered: const BorderSide(
                color: Colors.blue,
                width: 2,
              ),
              WidgetState.selected & WidgetState.focused: const BorderSide(
                color: Colors.pinkAccent,
                width: 2,
              ),
              WidgetState.hovered: const BorderSide(color: Colors.green, width: 2),
              WidgetState.focused: const BorderSide(color: Colors.purple, width: 2),
              WidgetState.any: const BorderSide(color: Colors.amber, width: 2),
            }),
          ),
        ),
      ),
      home: Scaffold(
        body: Center(
          child: SegmentedButton<Calendar>(
            segments: const <ButtonSegment<Calendar>>[
              ButtonSegment<Calendar>(
                value: Calendar.day,
                label: Text('Day'),
                icon: Icon(Icons.calendar_view_day),
                enabled: false,
              ),
              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},
            emptySelectionAllowed: true,
            onSelectionChanged: (Set<Calendar> newSelection) {
              setState(() {
                calendarView = newSelection.isEmpty ? null : newSelection.first;
              });
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(onPressed: () {}, child: const Icon(Icons.add)),
      ),
    );
  }
}

``` 

</details> 

# Before


https://github.com/user-attachments/assets/1581f431-f87a-4af3-8ef6-f1f0d170e54a


# After


https://github.com/user-attachments/assets/156a8a64-3d9f-4323-9a1d-60624f5ac5d4


## Related Issue

Fixes [SegmentedButton does not set its MaterialState for side
](https://github.com/flutter/flutter/issues/159884)

## Tests

Adds 2 tests.
2025-07-29 23:53:22 +00:00
Kate Lovett
a04fb324be
Bump Dart to 3.8 and reformat (#171703)
Bumps the Dart version to 3.8 across the repo (excluding
engine/src/flutter/third_party) and applies formatting updates from Dart
3.8.

## Pre-launch Checklist

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

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

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2025-07-07 17:58:32 +00:00
Taha Tesser
a8a61a1c06
Add button icon support for animation duration (#162667)
Fixes [Default foreground color animation duration doesn't apply on icon
of `Button` widgets](https://github.com/flutter/flutter/issues/162301)
Fixes [Implement similar widget to``AnimatedDefaultTextStyle`` but for
child ``Icon``](https://github.com/flutter/flutter/issues/137251)

### Description

This PR adds``AnimatedTheme` to `ButtonStyleButton` which is extended by
buttons. It animates the button icon when changing icon color and size,
similar to button text.

### 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 const MaterialApp(
      home: HomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          spacing: 20,
          children: <Widget>[
            ElevatedButton.icon(
              icon: const Icon(Icons.favorite_rounded, size: 50),
              label: const Text('Button', style: TextStyle(fontSize: 36)),
              onPressed: () {},
              style: const ButtonStyle(
                iconColor: WidgetStateProperty<Color>.fromMap(
                  <WidgetStatesConstraint, Color>{
                    WidgetState.pressed: Color(0XFFFF0000),
                    WidgetState.any: Color(0XFF000000),
                  },
                ),
                foregroundColor: WidgetStateProperty<Color>.fromMap(
                  <WidgetStatesConstraint, Color>{
                    WidgetState.pressed: Color(0XFFFF0000),
                    WidgetState.any: Color(0XFF000000),
                  },
                ),
              ),
            ),
            ElevatedButton.icon(
              icon: const Icon(Icons.favorite_rounded, size: 50),
              label: const Text('Button', style: TextStyle(fontSize: 36)),
              onPressed: () {},
              style: const ButtonStyle(
                animationDuration: Duration(seconds: 2),
                iconColor: WidgetStateProperty<Color>.fromMap(
                  <WidgetStatesConstraint, Color>{
                    WidgetState.pressed: Color(0XFFFF0000),
                    WidgetState.any: Color(0XFF000000),
                  },
                ),
                foregroundColor: WidgetStateProperty<Color>.fromMap(
                  <WidgetStatesConstraint, Color>{
                    WidgetState.pressed: Color(0XFFFF0000),
                    WidgetState.any: Color(0XFF000000),
                  },
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

```

</details>

### Before


https://github.com/user-attachments/assets/86fcab94-1147-4c49-b362-12f804a5d540

### After


https://github.com/user-attachments/assets/12a49de8-06d6-46c5-976f-5ce182d60423

## 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].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

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

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

Co-authored-by: Qun Cheng <36861262+QuncCccccc@users.noreply.github.com>
2025-04-15 23:52:25 +00:00
Sangam Shrestha
d261411b4c
Remove redundant useMaterial3: true (#163376)
<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

This PR removes redundant useMaterial3: true as described in
https://github.com/flutter/flutter/issues/162818

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

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

## Pre-launch Checklist

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

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

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

---------

Co-authored-by: Qun Cheng <36861262+QuncCccccc@users.noreply.github.com>
2025-03-14 17:50:20 +00:00
Mouad Debbar
3755fd1f6e
[web] Remove HTML renderer from framework tests (#162038)
- Cleanup many HTML special cases and skips in framework tests.
- Update some dartdocs that referred to the HTML renderer.

For reviewers: it may help if you set `Hide whitespace` to true in
Github. It will help you skip through all the formatting/indentation
changes.
2025-01-24 21:33:27 +00:00
Michael Goderbauer
5491c8c146
Auto-format Framework (#160545)
This auto-formats all *.dart files in the repository outside of the
`engine` subdirectory and enforces that these files stay formatted with
a presubmit check.

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

---------

Co-authored-by: Kate Lovett <katelovett@google.com>
Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
2024-12-19 20:06:21 +00:00
Taha Tesser
d5e843eca3
Fix missing icon props in button styleFrom methods (#154821)
Fixes [Add missing icon props in button `styleFrom`  methods.](https://github.com/flutter/flutter/issues/154798)

### Description

Add missing icon propers in the following widgets:

- `ElevatedButton.styleFrom` (missing `iconSize`)
- `FilledButton.styleFrom` (missing `iconSize`)
- `OutlinedButton.styleFrom` (missing `iconSize`)
- `TextButton.styleFrom` (missing `iconSize`)
- `MenuItemButton.styleFrom` (missing `iconSize` and `disabledIconColor`)
- `SubmenuButton.styleFrom` (missing `iconSize` and `disabledIconColor`)
- `SegmentedButton.styleFrom` (missing `iconSize`, `iconColor`, and `disabledIconColor`)

### Code sample

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

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

enum Calendar { day, week, month, year }

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

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

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

class _MyAppState extends State<MyApp> {
  Calendar calendarView = Calendar.week;
  bool isEnabled = true;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Column(
            spacing: 10.0,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton.icon(
                style: ElevatedButton.styleFrom(
                  iconSize: 30,
                  iconColor: Colors.red,
                  disabledIconColor: Colors.red.withValues(alpha: 0.5),
                ),
                onPressed: isEnabled ? () {} : null,
                icon: const Icon(Icons.add),
                label: const Text('ElevatedButton'),
              ),
              FilledButton.icon(
                style: ElevatedButton.styleFrom(
                  iconSize: 30,
                  iconColor: Colors.red,
                  disabledIconColor: Colors.red.withValues(alpha: 0.5),
                ),
                onPressed: isEnabled ? () {} : null,
                icon: const Icon(Icons.add),
                label: const Text('FilledButton'),
              ),
              FilledButton.tonalIcon(
                style: ElevatedButton.styleFrom(
                  iconSize: 30,
                  iconColor: Colors.red,
                  disabledIconColor: Colors.red.withValues(alpha: 0.5),
                ),
                onPressed: isEnabled ? () {} : null,
                icon: const Icon(Icons.add),
                label: const Text('Add'),
              ),
              OutlinedButton.icon(
                style: ElevatedButton.styleFrom(
                  iconSize: 30,
                  iconColor: Colors.red,
                  disabledIconColor: Colors.red.withValues(alpha: 0.5),
                ),
                onPressed: isEnabled ? () {} : null,
                icon: const Icon(Icons.add),
                label: const Text('OutlinedButton'),
              ),
              TextButton.icon(
                style: ElevatedButton.styleFrom(
                  iconSize: 30,
                  iconColor: Colors.red,
                  disabledIconColor: Colors.red.withValues(alpha: 0.5),
                ),
                onPressed: isEnabled ? () {} : null,
                icon: const Icon(Icons.add),
                label: const Text('TextButton'),
              ),
              SizedBox(
                width: 200,
                child: MenuItemButton(
                  style: MenuItemButton.styleFrom(
                    iconSize: 30,
                    iconColor: Colors.red,
                    disabledIconColor: Colors.red.withValues(alpha: 0.5),
                  ),
                  trailingIcon: const Icon(Icons.arrow_forward_ios),
                  onPressed: isEnabled ? () {} : null,
                  child: const Text('MenuItemButton'),
                ),
              ),
              SizedBox(
                width: 200,
                child: SubmenuButton(
                  style: SubmenuButton.styleFrom(
                    iconSize: 30,
                    iconColor: Colors.red,
                    disabledIconColor: Colors.red.withValues(alpha: 0.5),
                  ),
                  trailingIcon: const Icon(Icons.arrow_forward_ios),
                  menuChildren: <Widget>[
                    if (isEnabled) const Text('Item'),
                  ],
                  child: const Text('SubmenuButton'),
                ),
              ),
              SegmentedButton<Calendar>(
                style: SegmentedButton.styleFrom(
                  iconColor: Colors.red,
                  iconSize: 30,
                  disabledIconColor: Colors.red.withValues(alpha: 0.5),
                ),
                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:
                    isEnabled ? (Set<Calendar> newSelection) {} : null,
              )
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton.extended(
          onPressed: () {
            setState(() {
              isEnabled = !isEnabled;
            });
          },
          label: Text(isEnabled ? 'Enabled' : 'Disabled'),
        ),
      ),
    );
  }
}
```

</details>

### Preview (Customized using icon props in `styleFrom`  methods)

<img width="838" alt="Screenshot 2024-09-09 at 16 27 19" src="https://github.com/user-attachments/assets/551d328b-307f-4f63-b0e8-1358a12877f9">
2024-09-18 00:19:40 +00:00
abdalmonem
3e4d59eae1
Add 'direction' allow to 'SegmentedButton' oriented vertically (#150903)
This PR add the ability to change buttons of 'SegmentedButton' directionality (In the vertical and horizontal axis) to be 'vertical' or 'horizontal' instead of just horizontally position by adding "direction" argument.

`direction: Axis.horizontal` :
![Simulator Screenshot - iPhone 15 - 2024-06-26 at 13 37 26](https://github.com/flutter/flutter/assets/9139030/4936b7f8-246b-41ae-ac1c-7c75bc2d4f2d)

`direction: Axis.vertical` :
![Simulator Screenshot - iPhone 15 - 2024-06-26 at 13 43 07](https://github.com/flutter/flutter/assets/9139030/5aecf229-34d8-4608-a0f7-aee5c130257f)

Notice: in this example i used:
`style: ButtonStyle( shape: MaterialStateProperty.all<RoundedRectangleBorder>( const RoundedRectangleBorder( borderRadius: BorderRadius.zero, ), ), ) `
To change the Radius of `SegmentedButton`, and the default shape will be like:
![Simulator Screenshot - iPhone 15 - 2024-06-26 at 13 51 46](https://github.com/flutter/flutter/assets/9139030/24833153-02c8-4f5c-8c50-5a0effa19e9e)
I keep it as it is right now, cause its not the main purpose of this BR.

*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].*
Fixes: #150416
2024-09-11 17:59:36 +00:00
Greg Spencer
d68e05bf36
Reland: Request focus if accessibility focus is given to a Focus widget (#142942) (#149840)
## Description

This attempts to re-land #142942 after being reverted in https://github.com/flutter/flutter/pull/149741 because it broke the iOS [platform view UI integration test](https://github.com/flutter/flutter/blob/master/dev/integration_tests/ios_platform_view_tests/ios/PlatformViewUITests/PlatformViewUITests.m?rgh-link-date=2024-06-06T19%3A47%3A27Z).

The changes here from the original are that in the Focus widget we no longer set the `onFocus` for the `Semantics` if the platform is iOS.  It was not intended to do anything on iOS anyhow.

Also, I updated the matchers to not actually do anything yet with the SemanticsAction.focus matching, so that this can be landed without breaking customer tests, and once they have been updated to correctly look for the focus action, we can land a PR that will turn it on.

## Related Issues
 - https://github.com/flutter/flutter/issues/149838
 - https://github.com/flutter/flutter/issues/83809
 - https://github.com/flutter/flutter/issues/149842

## Tests
 - Updated framework tests to look for the appropriate things using the matchers, even though it doesn't actually test for them yet.
2024-06-12 20:05:10 +00:00
Taha Tesser
04dc553e83
[Reland] Fix SegmentedButton clipping when drawing segments (#149739) (#150090)
Relands https://github.com/flutter/flutter/pull/149739 which was reverted due to https://github.com/flutter/flutter/issues/149851

--- 

fixes [`SegmentedButton` doesn't clip properly when one of the segments has `ColorFiltered`](https://github.com/flutter/flutter/issues/144990)

### 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(
      home: Scaffold(
        body: Center(
          child: SegmentedButton<int>(
            segments: const <ButtonSegment<int>>[
              ButtonSegment<int>(
                value: 0,
                label: ColorFiltered(
                  colorFilter:
                      ColorFilter.mode(Colors.amber, BlendMode.colorBurn),
                  child: Text('Option 1'),
                ),
              ),
              ButtonSegment<int>(
                value: 1,
                label: Text('Option 2'),
              ),
            ],
            onSelectionChanged: (Set<int> selected) {},
            selected: const <int>{0},
          ),
        ),
      ),
    );
  }
}
```

</details>

### Before

![before](https://github.com/flutter/flutter/assets/48603081/b402fc51-d575-4208-8a71-f798ef2b2bf5)

### After

![after](https://github.com/flutter/flutter/assets/48603081/77a5cac2-ecef-4381-a043-dbb5c91407ec)

*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-06-12 18:41:11 +00:00
auto-submit[bot]
b5697a0c6d
Reverts "Fix SegmentedButton clipping when drawing segments (#149739)" (#149927)
Reverts: flutter/flutter#149739
Initiated by: QuncCccccc
Reason for reverting: the newly-added unit test might cause the red tree
Original PR Author: TahaTesser

Reviewed By: {QuncCccccc}

This change reverts the following previous change:
fixes [`SegmentedButton` doesn't clip properly when one of the segments has `ColorFiltered`](https://github.com/flutter/flutter/issues/144990)

### 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(
      home: Scaffold(
        body: Center(
          child: SegmentedButton<int>(
            segments: const <ButtonSegment<int>>[
              ButtonSegment<int>(
                value: 0,
                label: ColorFiltered(
                  colorFilter:
                      ColorFilter.mode(Colors.amber, BlendMode.colorBurn),
                  child: Text('Option 1'),
                ),
              ),
              ButtonSegment<int>(
                value: 1,
                label: Text('Option 2'),
              ),
            ],
            onSelectionChanged: (Set<int> selected) {},
            selected: const <int>{0},
          ),
        ),
      ),
    );
  }
}
```

</details>

### Before

![before](https://github.com/flutter/flutter/assets/48603081/b402fc51-d575-4208-8a71-f798ef2b2bf5)

### After

![after](https://github.com/flutter/flutter/assets/48603081/77a5cac2-ecef-4381-a043-dbb5c91407ec)
2024-06-07 19:30:18 +00:00
Taha Tesser
fc19ecfc58
Fix SegmentedButton clipping when drawing segments (#149739)
fixes [`SegmentedButton` doesn't clip properly when one of the segments has `ColorFiltered`](https://github.com/flutter/flutter/issues/144990)

### 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(
      home: Scaffold(
        body: Center(
          child: SegmentedButton<int>(
            segments: const <ButtonSegment<int>>[
              ButtonSegment<int>(
                value: 0,
                label: ColorFiltered(
                  colorFilter:
                      ColorFilter.mode(Colors.amber, BlendMode.colorBurn),
                  child: Text('Option 1'),
                ),
              ),
              ButtonSegment<int>(
                value: 1,
                label: Text('Option 2'),
              ),
            ],
            onSelectionChanged: (Set<int> selected) {},
            selected: const <int>{0},
          ),
        ),
      ),
    );
  }
}
```

</details>

### Before

![before](https://github.com/flutter/flutter/assets/48603081/b402fc51-d575-4208-8a71-f798ef2b2bf5)

### After

![after](https://github.com/flutter/flutter/assets/48603081/77a5cac2-ecef-4381-a043-dbb5c91407ec)
2024-06-07 18:34:24 +00:00
auto-submit[bot]
ec9965bd89
Reverts "Request focus if SemanticsAction.focus is sent to a focusable widget (#142942)" (#149741)
Reverts: flutter/flutter#142942
Initiated by: zanderso
Reason for reverting: Seems to have affected iOS platform view focus: https://ci.chromium.org/ui/p/flutter/builders/prod/Mac_ios%20native_platform_view_ui_tests_ios/10626/overview
Original PR Author: gspencergoog

Reviewed By: {yjbanov, goderbauer, chunhtai}

This change reverts the following previous change:
## Description

This causes the `Focus` widget to request focus on its focus node if the accessibility system (screen reader) focuses a widget via the `SemanticsAction.focus` action.

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

## Tests
 - Added a test to make sure that focus is requested when `SemanticsAction.focus` is sent by the engine.
2024-06-05 14:54:18 +00:00
Greg Spencer
dd700e6d7c
Request focus if SemanticsAction.focus is sent to a focusable widget (#142942)
## Description

This causes the `Focus` widget to request focus on its focus node if the accessibility system (screen reader) focuses a widget via the `SemanticsAction.focus` action.

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

## Tests
 - Added a test to make sure that focus is requested when `SemanticsAction.focus` is sent by the engine.
2024-06-05 00:42:59 +00:00
Taha Tesser
fa85f69e47
Add missing overlayColor property in styleFrom methods (#146685)
fixes [Add missing `overlayColor` property  in `styleFrom` methods](https://github.com/flutter/flutter/issues/146636)

### Code sample

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

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

enum Sizes { extraSmall, small, medium, large, extraLarge }

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: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Text('styleFrom(overlayColor: Colors.red)', style: Theme.of(context).textTheme.titleLarge),
              TextButton(
                style: TextButton.styleFrom(overlayColor: Colors.red),
                onPressed: () {},
                child: const Text('TextButton'),
              ),
              IconButton(
                style: IconButton.styleFrom(
                  overlayColor: Colors.red,
                ),
                onPressed: () {},
                icon: const Icon(Icons.add),
              ),
              MenuBar(
                children: [
                  MenuItemButton(
                    style: MenuItemButton.styleFrom(overlayColor: Colors.red),
                    child: const Text('MenuItemButton'),
                    onPressed: () {},
                  ),
                  SubmenuButton(
                    style: SubmenuButton.styleFrom(overlayColor: Colors.red),
                    menuChildren: [
                      MenuItemButton(
                        child: const Text('MenuItemButton'),
                        onPressed: () {},
                      ),
                    ],
                    child: const Text('SubmenuButton'),
                  ),
                ],
              ),
              SegmentedButton<Sizes>(
                style:
                    SegmentedButton.styleFrom(overlayColor: Colors.red),
                segments: const <ButtonSegment<Sizes>>[
                  ButtonSegment<Sizes>(
                      value: Sizes.extraSmall, label: Text('XS')),
                  ButtonSegment<Sizes>(value: Sizes.small, label: Text('S')),
                  ButtonSegment<Sizes>(value: Sizes.medium, label: Text('M')),
                  ButtonSegment<Sizes>(
                    value: Sizes.large,
                    label: Text('L'),
                  ),
                  ButtonSegment<Sizes>(
                      value: Sizes.extraLarge, label: Text('XL')),
                ],
                selected: const {Sizes.medium},
                onSelectionChanged: (Set<Sizes> newSelection) {},
                multiSelectionEnabled: true,
              ),
            ],
          ),
        ),
      ),
    );
  }
}
```

</details>

### Preview

![ScreenRecording2024-04-12at15 25 58-ezgif com-video-to-gif-converter](https://github.com/flutter/flutter/assets/48603081/89b9638d-f369-4ef1-b501-17c9c74b2541)
2024-04-24 11:56:32 +00:00
Furkan Acar
e868e2b383
Add SegmentedButton expand feature (#142804)
fix #139486

The `expandedInsets` property enhancement for the `SegmentedButton` widget introduces flexibility in button layout design within Flutter applications. When `expandedInsets` is not null, this property allows the `SegmentedButton` to expand, filling the available horizontal space of its parent container and also have the specified insets, thus ensuring a uniform distribution of segment widths across the button. Conversely, with `expandedInsets` is null, the widget sizes itself based on the intrinsic sizes of its segments, preserving the natural width of each segment. This addition enhances the adaptability of the `SegmentedButton` to various UI designs, enabling developers to achieve both expansive and compact button layouts seamlessly.

### Setting expandedInsets = null
<img width="724" alt="image" src="https://github.com/flutter/flutter/assets/65075121/f173b327-a34b-49f0-a7b1-a212a376c5e3">

### Setting expandedInsets = EdgeInsets.zero
<img width="724" alt="image" src="https://github.com/flutter/flutter/assets/36861262/f141a3d3-80e3-4aeb-b7c8-d56ca77ca049">
2024-04-03 16:16:52 +00:00
Qun Cheng
0d8eafb006
Reland "Reland - Introduce tone-based surfaces and accent color add-ons - Part 2" (#144273) 2024-02-28 13:55:50 -08:00
auto-submit[bot]
2eee0b5750
Reverts "Reland - Introduce tone-based surfaces and accent color add-ons - Part 2 (#144001)" (#144262)
Reverts flutter/flutter#144001

Initiated by: Piinks

Reason for reverting: Failing goldens at the tip of tree

Original PR Author: QuncCccccc

Reviewed By: {HansMuller}

This change reverts the following previous change:
Original Description:
Reverts flutter/flutter#143973

This is a reland for #138521 with an updated g3fix(cl/605555997). Local test: cl/609608958.
2024-02-27 22:04:18 +00:00
Qun Cheng
871d59221c
Reland - Introduce tone-based surfaces and accent color add-ons - Part 2 (#144001)
Reverts flutter/flutter#143973

This is a reland for #138521 with an updated g3fix(cl/605555997). Local test: cl/609608958.
2024-02-27 20:21:14 +00:00
Qun Cheng
4715216c01
Revert "Introduce tone-based surfaces and accent color add-ons - Part 2" (#143973)
Reverts flutter/flutter#138521
2024-02-22 14:51:28 -08:00
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
Qun Cheng
7ff5f81a2e
Fix SegmentedButton default size and default tappable size (#142243)
fix https://github.com/flutter/flutter/issues/121493

`SegmentedButton` uses `TextButton` for each segments. When we have `MaterialTapTargetSize.padded` for `TextButton`, we make sure the minimum tap target size is 48.0( this value can be adjusted by visual density), even tough the actual button size is smaller. When `SegmentedButton` paints segments by using `MultiChildRenderObjectWidget`, it also includes the tap target size so the button that it actually draws always has the same height as the height of the tap target size.

To fix it, this PR firstly calculate the actual height of a text button in `SegmentedButton` class, then we can get the height delta if there is. Then the the value of (Segmented button render box height - the delta) would be the actual button size that we should see.

For now, we are not able to customize the min, max, fixed size in [`SegmentedButton` style](https://api.flutter.dev/flutter/material/SegmentedButton/style.html). So the standard button height is always 40 and can only be customized by `style.visualDensity` and `style.tapTargetSize`; `SegmentedButton` only simulates the `TextButton` behavior when `TextButton`'s height is its default value.

![Screenshot 2024-01-25 at 11 45 42 AM](https://github.com/flutter/flutter/assets/36861262/7451fa96-6d45-4cd3-a894-ca71e776c8ef)

https://github.com/flutter/flutter/assets/36861262/15ca6034-e6e0-4cc6-8fe3-808b4bd6a920
2024-01-26 00:20:21 +00:00
Sharabiddin Ahmayev
2ae39c0cc0
Fix SegmentedButton states update logic (#140772)
This PR fixes: #140746

Desc: Style state update logic fix on SegmentedButton
2024-01-04 17:57:06 +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
Polina Cherkasova
baf739c8e6
Remove usage of testWidgetsWithLeakTracking. (#140239) 2023-12-15 14:13:31 -08:00
Dan Field
2df7244f74
Do not hold on to stale canvas reference in _RenderSegmentedButton (#136658)
Fixes https://github.com/flutter/flutter/issues/135747

Before this change, the render object was storing the `context.canvas` and using it after painting children. If those children were composited (e.g. because of an `Opacity` layer), the canvas it stored was disposed and not valid for use anymore.
2023-10-16 21:03:59 +00:00
Polina Cherkasova
219efce7f1
Cover more tests with leak tracking. (#134363) 2023-09-11 09:42:27 -07:00
Polina Cherkasova
237ddcc339
Remove non needed controllers in SegmentedButton. (#134064) 2023-09-07 17:50:23 -07:00
Polina Cherkasova
0d198c7ba6
SearchDelegate should dispose resources. (#133948) 2023-09-07 11:13:55 -07:00
Polina Cherkasova
cb0a613ec6
SegmentedButton should not create new MaterialStatesController in every build. (#133949) 2023-09-05 11:00:22 -07:00
Polina Cherkasova
a7b69b069f
Unpin leak_tracker and handle breaking changes in API. (#132352) 2023-08-14 10:05:20 -07:00
Zachary Anderson
f4c25bbb35
Revert "Handle breaking changes in leak_tracker." (#132223)
Reverts flutter/flutter#131998

Reverting for https://github.com/flutter/flutter/issues/132222
2023-08-09 08:14:39 -07:00
Polina Cherkasova
acd636f7ba
Handle breaking changes in leak_tracker. (#131998) 2023-08-08 09:39:19 -07:00
Kate Lovett
f054f5aa09
Move mock canvas to flutter_test (#131631)
Fixes https://github.com/flutter/flutter/issues/59413

This relocates `mock_canvas.dart` and `recording_canvas.dart` from `flutter/test/rendering` to `flutter_test`. 

The testing functionality afforded by mock_canvas should be available to everyone, not just the framework. :)

mock_canvas.dart needed a bit of cleanup - things like formatting and super parameters.
2023-08-07 23:43:03 +00:00
Polina Cherkasova
d5e7f407e1
Test cover some leak-free code. (#130543) 2023-07-14 10:14:04 -07:00
ZhulanovAA
e84fa2ce47
Add tooltips for SegmentedButton (#128501) 2023-06-09 11:06:21 -07:00
Qun Cheng
4e7e4512b6
Reorder materialStateProperty defaults (#125905)
Fixes #122250. This PR is to make sure all the MaterialStateProperty defaults are able to correctly resolve different states. 
* When a widget is pressed, it is also hovered, so we need to put the `MaterialState.pressed` check before `MaterialState.hovered`. 
* When a widget is focused, the widget should still be able to be hovered, so we should check `MaterialState.hovered` before `MaterialState.focused`.
* There are also cases like in _InputDecoratorDefaultsM3, the `MaterialState.disabled` should be checked before `MaterialState.error`.

 the order should be disabled, (error), pressed, hovered, focused.
2023-05-11 00:03:09 +00:00
Rydmike
be5a84295d
FIX: SegmentedButton segments background cannot be made transparent (#123293) 2023-04-04 15:38:20 -07:00
Darren Austin
6ec2bd0a80
M3 Segmented Button widget (#113723) 2022-11-11 22:13:57 -08:00