Skip to content
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

NavigationDrawerDestination items do not follow theme background #219

Open
mavriq-dev opened this issue Feb 26, 2024 · 3 comments
Open

NavigationDrawerDestination items do not follow theme background #219

mavriq-dev opened this issue Feb 26, 2024 · 3 comments
Assignees
Labels
bug Flutter This issue can be repeated with Flutter without using this package wontfix This issue will not be worked on, a reason for why not is provided in the response.

Comments

@mavriq-dev
Copy link

mavriq-dev commented Feb 26, 2024

The background color of NavigationDrawerDestination items do not follow the theme and the simulator.

This is how the them appears:
image

In the simlator it looks like this:
image

I took the theme code directly from the playground.

Example Code:

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: theme(),
      home: Scaffold(
        appBar: AppBar(),
        drawer: getNavDrawer(),
        body: const Center(
          child: Text('Hello World!'),
        ),
      ),
    );
  }
}

NavigationDrawer getNavDrawer() {
  return const NavigationDrawer(children: [
    NavigationDrawerDestination(icon: Icon(Icons.close), label: Text('Destination 1')),
    NavigationDrawerDestination(icon: Icon(Icons.close), label: Text('Destination 2')),
    NavigationDrawerDestination(icon: Icon(Icons.close), label: Text('Destination 3'))
  ]);
}

// Theme config for FlexColorScheme version 7.3.x. Make sure you use
// same or higher package version, but still same major version. If you
// use a lower package version, some properties may not be supported.
// In that case remove them after copying this theme to your app.
ThemeData theme() => FlexThemeData.light(
      scheme: FlexScheme.materialBaseline,
      surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
      blendLevel: 7,
      subThemesData: const FlexSubThemesData(
        blendOnLevel: 10,
        blendOnColors: false,
        useTextTheme: true,
        useM2StyleDividerInM3: true,
        alignedDropdown: true,
        useInputDecoratorThemeInDialogs: true,
      ),
      visualDensity: FlexColorScheme.comfortablePlatformDensity,
      useMaterial3: true,
      swapLegacyOnMaterial3: true,
      // To use the Playground font, add GoogleFonts package and uncomment
      // fontFamily: GoogleFonts.notoSans().fontFamily,
    );
@rydmike rydmike self-assigned this Feb 29, 2024
@rydmike rydmike added the in triage The issue is being tested and verified by replicating it. label Feb 29, 2024
@rydmike
Copy link
Owner

rydmike commented Feb 29, 2024

Hi @mavriq-dev,

Thanks for this report. It is indeed a correct observation, it is also sadly expected behavior with current and latest Flutter version 3.19.2.

Let's study it and find out more.

We can repeat the same issue without FlexThemeData with Flutter stable 3.19.2. Btw thanks for an excellent and to the point reproduction sample, that I can now easily change to vanilla Flutter and we get the same result:

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: theme(),
      home: Scaffold(
        appBar: AppBar(),
        drawer: getNavDrawer(),
        body: const Center(
          child: Text('Hello World!'),
        ),
      ),
    );
  }
}

NavigationDrawer getNavDrawer() {
  return const NavigationDrawer(children: [
    NavigationDrawerDestination(
        icon: Icon(Icons.close), label: Text('Destination 1')),
    NavigationDrawerDestination(
        icon: Icon(Icons.close), label: Text('Destination 2')),
    NavigationDrawerDestination(
        icon: Icon(Icons.close), label: Text('Destination 3'))
  ]);
}

ColorScheme scheme = ColorScheme.fromSeed(seedColor: Color(0xFF6750A4));

ThemeData theme() => ThemeData(
      colorScheme: scheme,
      navigationDrawerTheme: NavigationDrawerThemeData(
        backgroundColor: scheme.surface,
      ),
    );

And it looks the same:

Screenshot 2024-02-29 at 22 24 00

So why does this happen?

It is because the Drawer uses elevation 1 by default in M3 and the colorScheme.surface color that it uses as background on the Material it is built from, gets elevation tint based on elevation 1.

However, the NavigationDrawerDestination now use the same background color colorScheme.surface, but its items are not elevated, so they are using the closer to white version of unelevated colorScheme.surface. If you set the NavigationDrawerThemeData.evelation to 0, you can see that the colors match.

ThemeData theme() => ThemeData(
      colorScheme: scheme,
      navigationDrawerTheme: NavigationDrawerThemeData(
        backgroundColor: scheme.surface,
        elevation: 0,
      ),
    );

The colors match:

Screenshot 2024-02-29 at 22 33 11

But what if I want to use e.g. elevation 12? It would then look like this:

Screenshot 2024-02-29 at 22 34 13

Not pretty and probably not what was expected either!

The simple workaround is to make the NavigationDrawerDestination item backgrounds transparent

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: theme(),
      home: Scaffold(
        appBar: AppBar(),
        drawer: getNavDrawer(),
        body: const Center(
          child: Text('Hello World!'),
        ),
      ),
    );
  }
}

NavigationDrawer getNavDrawer() {
  return const NavigationDrawer(children: [
    NavigationDrawerDestination(
        backgroundColor: Colors.transparent,
        icon: Icon(Icons.close),
        label: Text('Destination 1')),
    NavigationDrawerDestination(
        backgroundColor: Colors.transparent,
        icon: Icon(Icons.close),
        label: Text('Destination 2')),
    NavigationDrawerDestination(
        backgroundColor: Colors.transparent,
        icon: Icon(Icons.close),
        label: Text('Destination 3'))
  ]);
}

ColorScheme scheme = ColorScheme.fromSeed(seedColor: const Color(0xFF6750A4));

ThemeData theme() => ThemeData(
      colorScheme: scheme,
      navigationDrawerTheme: NavigationDrawerThemeData(
        backgroundColor: scheme.surface,
        elevation: 12,
      ),
    );

Screenshot 2024-02-29 at 22 36 06

But we are using themes and should not need to think about such things.

Here is a really interesting part. The published Themes Playground app does not do this with the NavigationDrawerDestination items.

It looks like you showed:

Screenshot 2024-02-29 at 22 48 39

and I double checked, I don't do any transparent color on the destinations in its code.

Wait, what is going on here?

Well Themes Playground live version was built back with Flutter SDK 3.13.1:

Screenshot 2024-02-29 at 22 50 38

If I build it with latest Flutter SDK 3.19.2:

I get the same result and yes imo issue too!

Screenshot 2024-02-29 at 22 52 17

As we already established this is what it looks like now with vanilla Flutter 3.19.2 as well. So it is not a FlexColorScheme issue.

What has happened?

Between Flutter version 3.13.1 and 3.19.2, somewhere along the way there was a change that caused this issue. It is perhaps an intentional change, but potentially also a regression.

The change has probably been caused by the color being transparent on the NavigationDrawerDestination before, to it now being defined by the Material-3 spec token that has it at surface color.

https://m3.material.io/components/navigation-drawer/specs

Well actually the spec says it should be token md.sys.color.surface-container-low as background when it is a modal Drawer. Which is a new color that does not exist in Flutter yet, but it is equivalent to the elevation level-1 tinted one.

All the elevation tints are going away in Material3 and Flutter too, in favor of precomputed surface shades for different usages. The token md.sys.color.surface-container-low is one of those that should be on the modal Drawer and as background on its unselected items.

So if we would have that token color as background color and no elevation tint anymore, the new theme defaults would work and the colors would match, but since we don't, one gets elevation tint (drawer) and the destinations do not, and hence the colors do not match.

So yes, I think it is a Flutter bug/regression with too eager implementation of component theme behavior from token db, before Flutter actually support the needed new colors and behavior.

There is PR in Flutter SDK that is preparing the theme for massive changes. I tweeted about it here: https://x.com/RydMike/status/1761057220047909295?s=20

Conclusion

Sadly since this is a Flutter SDK issue and regression, there is not much I can do about it to fix it in FlexColorScheme. I will check if the issue has been reported in Flutter issues and report it as regression, if does not exist. I need to find the stable Flutter version where it broke.

I have not seen any breaking change notification about this, so it should at least be considered a regression.

BTW, thanks for the report, a very good find! 👍🏻 😄 💙

@rydmike rydmike added bug Flutter This issue can be repeated with Flutter without using this package wontfix This issue will not be worked on, a reason for why not is provided in the response. and removed in triage The issue is being tested and verified by replicating it. labels Feb 29, 2024
@rydmike
Copy link
Owner

rydmike commented Feb 29, 2024

Even if this is "Flutter SDK" sourced and there is not much I can do about it here. I will keep it open so other can discover and learn about it too.

And I will link issue and progress in Flutter repo as well. I will also add it as known Flutter theming issues on my FlexColorScheme docs site.

@mavriq-dev
Copy link
Author

Cool. At least I know why it happens and how to work around it. Thanks for the great explanation!

@rydmike rydmike changed the title NavigationDrawerDestination items do not follow theme backgrouund Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Flutter This issue can be repeated with Flutter without using this package wontfix This issue will not be worked on, a reason for why not is provided in the response.
2 participants