Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix DropdownButtonFormField overlay colors management #159472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

bleroux
Copy link
Contributor

@bleroux bleroux commented Nov 26, 2024

Description

This PR fixes some DropdownButtonFormField issues where the overlay color overflows.

Before this PR, DropdownButtonFormField was relying on an InkWell to display overlay colors. This resulted in several issues related to the InkWell overflowing because it is not aware of the inner container inside InputDecorator, for instance see #106659.

With this PR, DropdownButtonFormField does not use an InkWell but rely on InputDecorator to paint overlay colors. InputDecorator paints overlay colors only on its internal container, this fixes the color overflowing when using InkWell. With this change users can opt-in for overlay colors to be painted by setting InputDecorator.filled to true (similarly to TextField and accordingly to the Material specification).

Code sample from #106659 with InputDecoration.filled set to true:

Code sample with InputDecoration.filled set to true
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    var items = [
      'Ayo',
      'This',
      'Don',
      'Look',
      'Right',
    ].map((String val) {
      return DropdownMenuItem(
        value: val,
        child: Text(
          val,
        ),
      );
    }).toList();

    return MaterialApp(
      title: _title,
      theme: ThemeData(
        inputDecorationTheme: const InputDecorationTheme(
          border: OutlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(32)),
            borderSide: BorderSide(color: Colors.blue, width: 2),
          ),
        ),
      ),
      home: Scaffold(
        body: Center(
          child: SizedBox(
            width: 500,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Form(
                  key: _formKey,
                  child: DropdownButtonFormField(
                    onTap: () {
                      _formKey.currentState!.validate();
                    },
                    validator: (String? v) => 'Required',
                    onChanged: (String? value) {},
                    items: items,
                    // Set InputDecoration.filled to true if overlays should be visible.
                    // See Material specification for filled vs outlined dropdown button:
                    // https://m2.material.io/components/menus#dropdown-menu.
                    decoration: const InputDecoration(filled: true),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Before:

image

After:

image

After (when filled is not set to true):

image

Related Issue

Fixes DropdownButtonFormField InkWell spreads to error message.
Fixes DropdownButtonFormField input decorator focus/hover is not clipped and appears behind fill color.
First step for DropDownButtonFormField hoverColor has no effect in web and desktop platforms

Tests

Adds 4 tests.
Updates 2 tests (remove checks specific to InkWell usage and use filled: true when checking for hover/focus colors).
Removes 1 test (test specific to InkWell usage, because this PR removes the InkWell the test is obsolete).

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Nov 26, 2024
@bleroux bleroux force-pushed the fix_dropdown_button_form_field_color_overflows branch 3 times, most recently from 0f29816 to 5f9fdfa Compare November 26, 2024 10:03
@TahaTesser TahaTesser self-requested a review November 26, 2024 13:34
Copy link
Member

@TahaTesser TahaTesser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bleroux
Copy link
Contributor Author

bleroux commented Nov 26, 2024

@justinmc
Can you have a look at this PR? Taha approved it to trigger the Google tests and there are some failures, would be interesting to know more about those failures.

This PR introduced a change of behavior: previously overlay colors were always shown because an InkWell was used. With this PR, the overlay colors are shown only when InputDecoration.filled is true.
I think it is worth making this change because:

  • It will comply with the M2 spec: https://m2.material.io/components/menus#dropdown-menu (and M3).
  • It will allow users to choose if the overlay color should be visible or not.
  • It will fix bad issues related to InkWell overflowing. See the 3 issues I listed in the description.

@bleroux bleroux requested a review from justinmc November 26, 2024 15:10
Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change LGTM but as you mentioned we should talk about the Google failures:

They are all visual diff golden tests, and there aren't too many. I see two types of failures:

  • In a few cases, the background color of the field has gone from white or black to grey.
  • In most cases, a few pixels around the corners of the overlay have changed. It doesn't visually look any different to my eye. Do you have idea why that would happen though?

Are both of these expected?

@@ -1586,30 +1592,75 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
},
);

// When an InputDecoration is provided, use it instead of using an InkWell
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not losing an ink splash effect by doing this?

Copy link
Contributor Author

@bleroux bleroux Nov 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we do. Splash effect on DropdownButton is not part of the spec and it was not there until #95906 added the InkWell.

If we want to keep the InkWell, I think the only solution to fix the issues listed in this PR description will be to add an option inside InputDecorator to add an optional InkWell (would be a non-breaking change but adds more complexity to InputDecorator for a specific use case). Otherwise it is almost impossible to properly positioned and sized the InkWell has the InputDecorator container adjust based on several parameters (border style, content padding, ect).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on board with removing the InkWell, thanks for explaining. I double checked the spec and you're right that it's not in there.

@bleroux
Copy link
Contributor Author

bleroux commented Nov 26, 2024

They are all visual diff golden tests, and there aren't too many. I see two types of failures:
In a few cases, the background color of the field has gone from white or black to grey.

Possibly because something is used from the InputDecorationTheme now. Having DropdownButton respecting the InputDecorationTheme is probably the right behavior but I understand it might be too much of a breaking change.
Or maybe it is has to do with overlays? Do you have a way to check if those tests capture an hovered or focused state?

In most cases, a few pixels around the corners of the overlay have changed. It doesn't visually look any different to my eye. Do you have idea why that would happen though?

There were some clipping logic added in #95906 around the InkWell that might explain the change.

@bleroux bleroux force-pushed the fix_dropdown_button_form_field_color_overflows branch from 5f9fdfa to a5ad793 Compare December 5, 2024 14:06
@bleroux
Copy link
Contributor Author

bleroux commented Dec 5, 2024

@justinmc I updated the PR today (replacing MouseRegion.onHover with onEnter as you proposed, and also changing the default color for a filled and focused DropdownButton based on your description of the golden failure).
It would be interesting to know if the golden diff related to "In a few cases, the background color of the field has gone from white or black to grey." are still there.

For the other golden diff you mentionned ("In most cases, a few pixels around the corners of the overlay have changed. It doesn't visually look any different to my eye.")

I think it could also be because, previously the InkWell was overflowing the borders for a focused filled DropdownButton, see #147069 (in the issue the code sample increases the border radius for illustration, but with the default border radius it would be some widgets on each corner).

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Indeed all of the failures related to background color changes are gone! The remaining failures are all the corner overflow that you explained, and all are only a few pixels of difference anyway due to a small border radius.

Good guesswork, thanks!

@@ -1586,30 +1592,75 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
},
);

// When an InputDecoration is provided, use it instead of using an InkWell
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on board with removing the InkWell, thanks for explaining. I double checked the spec and you're right that it's not in there.

@bleroux bleroux added the autosubmit Merge PR when tree becomes green via auto submit App label Dec 6, 2024
@auto-submit auto-submit bot added this pull request to the merge queue Dec 6, 2024
Merged via the queue into flutter:master with commit 5881b13 Dec 6, 2024
80 checks passed
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Dec 6, 2024
@bleroux bleroux deleted the fix_dropdown_button_form_field_color_overflows branch December 6, 2024 13:25
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 6, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 6, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 7, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 7, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 9, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 9, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
@reidbaker reidbaker mentioned this pull request Dec 13, 2024
11 tasks
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 12, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 13, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 13, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 6, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 7, 2025
@AhmedLSayed9 AhmedLSayed9 mentioned this pull request Apr 5, 2025
9 tasks
github-merge-queue bot pushed a commit that referenced this pull request Apr 17, 2025
The `builder` was needed to access `Focus.of(context)` but it's no
longer needed after #159472

## 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.
ash2moon pushed a commit to ash2moon/flutter that referenced this pull request Apr 21, 2025
The `builder` was needed to access `Focus.of(context)` but it's no
longer needed after flutter#159472

## 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
3 participants