From 709b26d0b34e5fb103fc3144c348f76afa708690 Mon Sep 17 00:00:00 2001 From: Taha Tesser Date: Fri, 29 Apr 2022 22:34:06 +0300 Subject: [PATCH] Add `surfaceTintColor` to `NavigationBar` (#102628) --- .../lib/navigation_bar_template.dart | 8 +++---- .../lib/src/material/navigation_bar.dart | 24 +++++++++++++------ .../src/material/navigation_bar_theme.dart | 10 ++++++++ .../test/material/navigation_bar_test.dart | 4 +++- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/dev/tools/gen_defaults/lib/navigation_bar_template.dart b/dev/tools/gen_defaults/lib/navigation_bar_template.dart index 2dc120388c6..1d153e20fa9 100644 --- a/dev/tools/gen_defaults/lib/navigation_bar_template.dart +++ b/dev/tools/gen_defaults/lib/navigation_bar_template.dart @@ -25,11 +25,9 @@ class _TokenDefaultsM3 extends NavigationBarThemeData { late final ColorScheme _colors = Theme.of(context).colorScheme; late final TextTheme _textTheme = Theme.of(context).textTheme; - // With Material 3, the NavigationBar uses an overlay blend for the - // default color regardless of light/dark mode. This should be handled - // in the Material widget based off of elevation, but for now we will do - // it here in the defaults. - @override Color? get backgroundColor => ElevationOverlay.colorWithOverlay(${componentColor("md.comp.navigation-bar.container")}, _colors.primary, ${elevation("md.comp.navigation-bar.container")}); + @override Color? get backgroundColor => ${componentColor("md.comp.navigation-bar.container")}; + + @override Color? get surfaceTintColor => ${color("md.comp.navigation-bar.container.surface-tint-layer.color")}; @override MaterialStateProperty? get iconTheme { return MaterialStateProperty.resolveWith((Set states) { diff --git a/packages/flutter/lib/src/material/navigation_bar.dart b/packages/flutter/lib/src/material/navigation_bar.dart index 22f7bcbdda8..978bb621baa 100644 --- a/packages/flutter/lib/src/material/navigation_bar.dart +++ b/packages/flutter/lib/src/material/navigation_bar.dart @@ -59,6 +59,7 @@ class NavigationBar extends StatelessWidget { required this.destinations, this.onDestinationSelected, this.backgroundColor, + this.surfaceTintColor, this.elevation, this.height, this.labelBehavior, @@ -95,10 +96,20 @@ class NavigationBar extends StatelessWidget { /// The color of the [NavigationBar] itself. /// /// If null, [NavigationBarThemeData.backgroundColor] is used. If that - /// is also null, the default blends [ColorScheme.surface] and - /// [ColorScheme.onSurface] using an [ElevationOverlay]. + /// is also null, then if [ThemeData.useMaterial3] is true, the value is + /// [ColorScheme.surface]. If that is false, the default blends [ColorScheme.surface] + /// and [ColorScheme.onSurface] using an [ElevationOverlay]. final Color? backgroundColor; + /// The color used as an overlay on [backgroundColor] to indicate elevation. + /// + /// If null, [NavigationBarThemeData.surfaceTintColor] is used. If that + /// is also null, the default value is [ColorScheme.surfaceTint]. + /// + /// See [Material.surfaceTintColor] for more details on how this + /// overlay is applied. + final Color? surfaceTintColor; + /// The elevation of the [NavigationBar] itself. /// /// If null, [NavigationBarThemeData.elevation] is used. If that @@ -152,6 +163,7 @@ class NavigationBar extends StatelessWidget { color: backgroundColor ?? navigationBarTheme.backgroundColor ?? defaults.backgroundColor!, + surfaceTintColor: surfaceTintColor ?? navigationBarTheme.surfaceTintColor ?? defaults.surfaceTintColor, elevation: elevation ?? navigationBarTheme.elevation ?? defaults.elevation!, child: SafeArea( child: SizedBox( @@ -1214,11 +1226,9 @@ class _TokenDefaultsM3 extends NavigationBarThemeData { late final ColorScheme _colors = Theme.of(context).colorScheme; late final TextTheme _textTheme = Theme.of(context).textTheme; - // With Material 3, the NavigationBar uses an overlay blend for the - // default color regardless of light/dark mode. This should be handled - // in the Material widget based off of elevation, but for now we will do - // it here in the defaults. - @override Color? get backgroundColor => ElevationOverlay.colorWithOverlay(_colors.surface, _colors.primary, 3.0); + @override Color? get backgroundColor => _colors.surface; + + @override Color? get surfaceTintColor => _colors.surfaceTint; @override MaterialStateProperty? get iconTheme { return MaterialStateProperty.resolveWith((Set states) { diff --git a/packages/flutter/lib/src/material/navigation_bar_theme.dart b/packages/flutter/lib/src/material/navigation_bar_theme.dart index b758bcbecba..cad96523ced 100644 --- a/packages/flutter/lib/src/material/navigation_bar_theme.dart +++ b/packages/flutter/lib/src/material/navigation_bar_theme.dart @@ -41,6 +41,7 @@ class NavigationBarThemeData with Diagnosticable { const NavigationBarThemeData({ this.height, this.backgroundColor, + this.surfaceTintColor, this.elevation, this.indicatorColor, this.indicatorShape, @@ -55,6 +56,9 @@ class NavigationBarThemeData with Diagnosticable { /// Overrides the default value of [NavigationBar.backgroundColor]. final Color? backgroundColor; + /// Overrides the default value of [NavigationBar.surfaceTintColor]. + final Color? surfaceTintColor; + /// Overrides the default value of [NavigationBar.elevation]. final double? elevation; @@ -85,6 +89,7 @@ class NavigationBarThemeData with Diagnosticable { NavigationBarThemeData copyWith({ double? height, Color? backgroundColor, + Color? surfaceTintColor, double? elevation, Color? indicatorColor, ShapeBorder? indicatorShape, @@ -95,6 +100,7 @@ class NavigationBarThemeData with Diagnosticable { return NavigationBarThemeData( height: height ?? this.height, backgroundColor: backgroundColor ?? this.backgroundColor, + surfaceTintColor: surfaceTintColor ?? this.surfaceTintColor, elevation: elevation ?? this.elevation, indicatorColor: indicatorColor ?? this.indicatorColor, indicatorShape: indicatorShape ?? this.indicatorShape, @@ -116,6 +122,7 @@ class NavigationBarThemeData with Diagnosticable { return NavigationBarThemeData( height: lerpDouble(a?.height, b?.height, t), backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t), + surfaceTintColor: Color.lerp(a?.surfaceTintColor, b?.surfaceTintColor, t), elevation: lerpDouble(a?.elevation, b?.elevation, t), indicatorColor: Color.lerp(a?.indicatorColor, b?.indicatorColor, t), indicatorShape: ShapeBorder.lerp(a?.indicatorShape, b?.indicatorShape, t), @@ -129,6 +136,7 @@ class NavigationBarThemeData with Diagnosticable { int get hashCode => Object.hash( height, backgroundColor, + surfaceTintColor, elevation, indicatorColor, indicatorShape, @@ -146,6 +154,7 @@ class NavigationBarThemeData with Diagnosticable { return other is NavigationBarThemeData && other.height == height && other.backgroundColor == backgroundColor + && other.surfaceTintColor == surfaceTintColor && other.elevation == elevation && other.indicatorColor == indicatorColor && other.indicatorShape == indicatorShape @@ -159,6 +168,7 @@ class NavigationBarThemeData with Diagnosticable { super.debugFillProperties(properties); properties.add(DoubleProperty('height', height, defaultValue: null)); properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null)); + properties.add(ColorProperty('surfaceTintColor', surfaceTintColor, defaultValue: null)); properties.add(DoubleProperty('elevation', elevation, defaultValue: null)); properties.add(ColorProperty('indicatorColor', indicatorColor, defaultValue: null)); properties.add(DiagnosticsProperty('indicatorShape', indicatorShape, defaultValue: null)); diff --git a/packages/flutter/test/material/navigation_bar_test.dart b/packages/flutter/test/material/navigation_bar_test.dart index 43046c2fefc..7491d36a13c 100644 --- a/packages/flutter/test/material/navigation_bar_test.dart +++ b/packages/flutter/test/material/navigation_bar_test.dart @@ -257,6 +257,7 @@ void main() { ); expect(_getMaterial(tester).color, const Color(0xffeaeaea)); + expect(_getMaterial(tester).surfaceTintColor, null); expect(_getMaterial(tester).elevation, 0); expect(tester.getSize(find.byType(NavigationBar)).height, 80); expect(_indicator(tester)?.color, const Color(0x3d2196f3)); @@ -284,7 +285,8 @@ void main() { ), ); - expect(_getMaterial(tester).color, const Color(0xffecf6fe)); + expect(_getMaterial(tester).color, ThemeData().colorScheme.surface); + expect(_getMaterial(tester).surfaceTintColor, ThemeData().colorScheme.surfaceTint); expect(_getMaterial(tester).elevation, 3); expect(tester.getSize(find.byType(NavigationBar)).height, 80); expect(_indicator(tester)?.color, const Color(0xff2196f3));