Unverified Commit 069699eb authored by Rami's avatar Rami Committed by GitHub

Add ability to customize drawer shape and color as well as theme drawer properties (#89237)

parent 947034ed
......@@ -65,6 +65,7 @@ export 'src/material/divider.dart';
export 'src/material/divider_theme.dart';
export 'src/material/drawer.dart';
export 'src/material/drawer_header.dart';
export 'src/material/drawer_theme.dart';
export 'src/material/dropdown.dart';
export 'src/material/elevated_button.dart';
export 'src/material/elevated_button_theme.dart';
......
......@@ -7,6 +7,7 @@ import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'debug.dart';
import 'drawer_theme.dart';
import 'list_tile.dart';
import 'material.dart';
import 'material_localizations.dart';
......@@ -139,19 +140,36 @@ class Drawer extends StatelessWidget {
/// The [elevation] must be non-negative.
const Drawer({
Key? key,
this.elevation = 16.0,
this.backgroundColor,
this.elevation,
this.shape,
this.child,
this.semanticLabel,
}) : assert(elevation != null && elevation >= 0.0),
}) : assert(elevation == null || elevation >= 0.0),
super(key: key);
/// Sets the color of the [Material] that holds all of the [Drawer]'s
/// contents.
///
/// If this is null, then [DrawerThemeData.backgroundColor] is used. If that
/// is also null, then it falls back to [Material]'s default.
final Color? backgroundColor;
/// The z-coordinate at which to place this drawer relative to its parent.
///
/// This controls the size of the shadow below the drawer.
///
/// Defaults to 16, the appropriate elevation for drawers. The value is
/// always non-negative.
final double elevation;
/// If this is null, then [DrawerThemeData.elevation] is used. If that
/// is also null, then it defaults to 16.0.
final double? elevation;
/// The shape of the drawer.
///
/// Defines the drawer's [Material.shape].
///
/// If this is null, then [DrawerThemeData.shape] is used. If that
/// is also null, then it falls back to [Material]'s default.
final ShapeBorder? shape;
/// The widget below this widget in the tree.
///
......@@ -175,6 +193,7 @@ class Drawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
final DrawerThemeData drawerTheme = DrawerTheme.of(context);
String? label = semanticLabel;
switch (Theme.of(context).platform) {
case TargetPlatform.iOS:
......@@ -194,7 +213,9 @@ class Drawer extends StatelessWidget {
child: ConstrainedBox(
constraints: const BoxConstraints.expand(width: _kWidth),
child: Material(
elevation: elevation,
color: backgroundColor ?? drawerTheme.backgroundColor,
elevation: elevation ?? drawerTheme.elevation ?? 16.0,
shape: shape ?? drawerTheme.shape,
child: child,
),
),
......@@ -277,9 +298,11 @@ class DrawerController extends StatefulWidget {
/// {@endtemplate}
final DragStartBehavior dragStartBehavior;
/// The color to use for the scrim that obscures primary content while a drawer is open.
/// The color to use for the scrim that obscures the underlying content while
/// a drawer is open.
///
/// By default, the color used is [Colors.black54]
/// If this is null, then [DrawerThemeData.scrimColor] is used. If that
/// is also null, then it defaults to [Colors.black54].
final Color? scrimColor;
/// Determines if the [Drawer] can be opened with a drag gesture.
......@@ -317,7 +340,6 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
@override
void initState() {
super.initState();
_scrimColorTween = _buildScrimColorTween();
_controller = AnimationController(
value: widget.isDrawerOpen ? 1.0 : 0.0,
duration: _kBaseSettleDuration,
......@@ -335,6 +357,12 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
super.dispose();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
_scrimColorTween = _buildScrimColorTween();
}
@override
void didUpdateWidget(DrawerController oldWidget) {
super.didUpdateWidget(oldWidget);
......@@ -492,7 +520,12 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
final GlobalKey _gestureDetectorKey = GlobalKey();
ColorTween _buildScrimColorTween() {
return ColorTween(begin: Colors.transparent, end: widget.scrimColor ?? Colors.black54);
return ColorTween(
begin: Colors.transparent,
end: widget.scrimColor
?? DrawerTheme.of(context).scrimColor
?? Colors.black54,
);
}
AlignmentDirectional get _drawerOuterAlignment {
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'theme.dart';
/// Defines default property values for descendant [Drawer] widgets.
///
/// Descendant widgets obtain the current [DrawerThemeData] object
/// using `DrawerTheme.of(context)`. Instances of [DrawerThemeData] can be
/// customized with [DrawerThemeData.copyWith].
///
/// Typically a [DrawerThemeData] is specified as part of the
/// overall [Theme] with [ThemeData.drawerTheme].
///
/// All [DrawerThemeData] properties are `null` by default.
///
/// See also:
///
/// * [DrawerTheme], an [InheritedWidget] that propagates the theme down its
/// subtree.
/// * [ThemeData], which describes the overall theme information for the
/// application and can customize a drawer using [ThemeData.drawerTheme].
@immutable
class DrawerThemeData with Diagnosticable {
/// Creates a theme that can be used for [ThemeData.drawerTheme] and
/// [DrawerTheme].
const DrawerThemeData({
this.backgroundColor,
this.scrimColor,
this.elevation,
this.shape,
});
/// Overrides the default value of [Drawer.backgroundColor].
final Color? backgroundColor;
/// Overrides the default value of [DrawerController.scrimColor].
final Color? scrimColor;
/// Overrides the default value of [Drawer.elevation].
final double? elevation;
/// Overrides the default value of [Drawer.shape].
final ShapeBorder? shape;
/// Creates a copy of this object with the given fields replaced with the
/// new values.
DrawerThemeData copyWith({
Color? backgroundColor,
Color? scrimColor,
double? elevation,
ShapeBorder? shape,
}) {
return DrawerThemeData(
backgroundColor: backgroundColor ?? this.backgroundColor,
scrimColor: scrimColor ?? this.scrimColor,
elevation: elevation ?? this.elevation,
shape: shape ?? this.shape,
);
}
/// Linearly interpolate between two drawer themes.
///
/// If both arguments are null then null is returned.
///
/// {@macro dart.ui.shadow.lerp}
static DrawerThemeData? lerp(DrawerThemeData? a, DrawerThemeData? b, double t) {
assert(t != null);
if (a == null && b == null)
return null;
return DrawerThemeData(
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
scrimColor: Color.lerp(a?.scrimColor, b?.scrimColor, t),
elevation: lerpDouble(a?.elevation, b?.elevation, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
);
}
@override
int get hashCode {
return hashValues(
backgroundColor,
scrimColor,
elevation,
shape,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is DrawerThemeData
&& other.backgroundColor == backgroundColor
&& other.scrimColor == scrimColor
&& other.elevation == elevation
&& other.shape == shape;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
properties.add(ColorProperty('scrimColor', scrimColor, defaultValue: null));
properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
}
}
/// An inherited widget that defines visual properties for [Drawer]s in this
/// widget's subtree.
///
/// Values specified here are used for [Drawer] properties that are not
/// given an explicit non-null value.
///
/// Using this would allow you to override the [ThemeData.drawerTheme].
class DrawerTheme extends InheritedTheme {
/// Creates a theme that defines the [DrawerThemeData] properties for a
/// [Drawer].
const DrawerTheme({
Key? key,
required this.data,
required Widget child,
}) : assert(data != null), super(key: key, child: child);
/// Specifies the background color, scrim color, elevation, and shape for
/// descendant [Drawer] widgets.
final DrawerThemeData data;
/// The closest instance of this class that encloses the given context.
///
/// If there is no enclosing [DrawerTheme] widget, then
/// [ThemeData.drawerTheme] is used.
///
/// Typical usage is as follows:
///
/// ```dart
/// DrawerTheme theme = DrawerTheme.of(context);
/// ```
static DrawerThemeData of(BuildContext context) {
final DrawerTheme? drawerTheme = context.dependOnInheritedWidgetOfExactType<DrawerTheme>();
return drawerTheme?.data ?? Theme.of(context).drawerTheme;
}
@override
Widget wrap(BuildContext context, Widget child) {
return DrawerTheme(data: data, child: child);
}
@override
bool updateShouldNotify(DrawerTheme oldWidget) => data != oldWidget.data;
}
......@@ -1619,7 +1619,8 @@ class Scaffold extends StatefulWidget {
/// The color to use for the scrim that obscures primary content while a drawer is open.
///
/// By default, the color is [Colors.black54]
/// If this is null, then [DrawerThemeData.scrimColor] is used. If that
/// is also null, then it defaults to [Colors.black54].
final Color? drawerScrimColor;
/// The color of the [Material] widget that underlies the entire Scaffold.
......
......@@ -22,6 +22,7 @@ import 'colors.dart';
import 'data_table_theme.dart';
import 'dialog_theme.dart';
import 'divider_theme.dart';
import 'drawer_theme.dart';
import 'elevated_button_theme.dart';
import 'floating_action_button_theme.dart';
import 'ink_splash.dart';
......@@ -336,6 +337,7 @@ class ThemeData with Diagnosticable {
RadioThemeData? radioTheme,
SwitchThemeData? switchTheme,
ProgressIndicatorThemeData? progressIndicatorTheme,
DrawerThemeData? drawerTheme,
@Deprecated(
'This "fix" is now enabled by default. '
'This feature was deprecated after v2.5.0-1.0.pre.',
......@@ -479,6 +481,7 @@ class ThemeData with Diagnosticable {
radioTheme ??= const RadioThemeData();
switchTheme ??= const SwitchThemeData();
progressIndicatorTheme ??= const ProgressIndicatorThemeData();
drawerTheme ??= const DrawerThemeData();
fixTextFieldOutlineLabel ??= true;
useTextSelectionTheme ??= true;
......@@ -560,6 +563,7 @@ class ThemeData with Diagnosticable {
radioTheme: radioTheme,
switchTheme: switchTheme,
progressIndicatorTheme: progressIndicatorTheme,
drawerTheme: drawerTheme,
fixTextFieldOutlineLabel: fixTextFieldOutlineLabel,
useTextSelectionTheme: useTextSelectionTheme,
androidOverscrollIndicator: androidOverscrollIndicator,
......@@ -693,6 +697,7 @@ class ThemeData with Diagnosticable {
required this.radioTheme,
required this.switchTheme,
required this.progressIndicatorTheme,
required this.drawerTheme,
@Deprecated(
'This "fix" is now enabled by default. '
'This feature was deprecated after v2.5.0-1.0.pre.',
......@@ -777,6 +782,7 @@ class ThemeData with Diagnosticable {
assert(radioTheme != null),
assert(switchTheme != null),
assert(progressIndicatorTheme != null),
assert(drawerTheme != null),
assert(fixTextFieldOutlineLabel != null),
assert(useTextSelectionTheme != null);
......@@ -1337,6 +1343,9 @@ class ThemeData with Diagnosticable {
/// A theme for customizing the appearance and layout of [ProgressIndicator] widgets.
final ProgressIndicatorThemeData progressIndicatorTheme;
/// A theme for customizing the appearance and layout of [Drawer] widgets.
final DrawerThemeData drawerTheme;
/// An obsolete flag to allow apps to opt-out of a
/// [small fix](https://github.com/flutter/flutter/issues/54028) for the Y
/// coordinate of the floating label in a [TextField] [OutlineInputBorder].
......@@ -1496,6 +1505,7 @@ class ThemeData with Diagnosticable {
RadioThemeData? radioTheme,
SwitchThemeData? switchTheme,
ProgressIndicatorThemeData? progressIndicatorTheme,
DrawerThemeData? drawerTheme,
@Deprecated(
'This "fix" is now enabled by default. '
'This feature was deprecated after v2.5.0-1.0.pre.',
......@@ -1586,6 +1596,7 @@ class ThemeData with Diagnosticable {
radioTheme: radioTheme ?? this.radioTheme,
switchTheme: switchTheme ?? this.switchTheme,
progressIndicatorTheme: progressIndicatorTheme ?? this.progressIndicatorTheme,
drawerTheme: drawerTheme ?? this.drawerTheme,
fixTextFieldOutlineLabel: fixTextFieldOutlineLabel ?? this.fixTextFieldOutlineLabel,
useTextSelectionTheme: useTextSelectionTheme ?? this.useTextSelectionTheme,
androidOverscrollIndicator: androidOverscrollIndicator ?? this.androidOverscrollIndicator,
......@@ -1746,6 +1757,7 @@ class ThemeData with Diagnosticable {
radioTheme: RadioThemeData.lerp(a.radioTheme, b.radioTheme, t),
switchTheme: SwitchThemeData.lerp(a.switchTheme, b.switchTheme, t),
progressIndicatorTheme: ProgressIndicatorThemeData.lerp(a.progressIndicatorTheme, b.progressIndicatorTheme, t)!,
drawerTheme: DrawerThemeData.lerp(a.drawerTheme, b.drawerTheme, t)!,
fixTextFieldOutlineLabel: t < 0.5 ? a.fixTextFieldOutlineLabel : b.fixTextFieldOutlineLabel,
useTextSelectionTheme: t < 0.5 ? a.useTextSelectionTheme : b.useTextSelectionTheme,
androidOverscrollIndicator: t < 0.5 ? a.androidOverscrollIndicator : b.androidOverscrollIndicator,
......@@ -1834,6 +1846,7 @@ class ThemeData with Diagnosticable {
&& other.radioTheme == radioTheme
&& other.switchTheme == switchTheme
&& other.progressIndicatorTheme == progressIndicatorTheme
&& other.drawerTheme == drawerTheme
&& other.fixTextFieldOutlineLabel == fixTextFieldOutlineLabel
&& other.useTextSelectionTheme == useTextSelectionTheme
&& other.androidOverscrollIndicator == androidOverscrollIndicator;
......@@ -1921,6 +1934,7 @@ class ThemeData with Diagnosticable {
radioTheme,
switchTheme,
progressIndicatorTheme,
drawerTheme,
fixTextFieldOutlineLabel,
useTextSelectionTheme,
androidOverscrollIndicator,
......@@ -2006,6 +2020,7 @@ class ThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<RadioThemeData>('radioTheme', radioTheme, defaultValue: defaultData.radioTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<SwitchThemeData>('switchTheme', switchTheme, defaultValue: defaultData.switchTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<ProgressIndicatorThemeData>('progressIndicatorTheme', progressIndicatorTheme, defaultValue: defaultData.progressIndicatorTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<DrawerThemeData>('drawerTheme', drawerTheme, defaultValue: defaultData.drawerTheme, level: DiagnosticLevel.debug));
properties.add(EnumProperty<AndroidOverscrollIndicator>('androidOverscrollIndicator', androidOverscrollIndicator, defaultValue: null, level: DiagnosticLevel.debug));
}
}
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('copyWith, ==, hashCode basics', () {
expect(const DrawerThemeData(), const DrawerThemeData().copyWith());
expect(const DrawerThemeData().hashCode, const DrawerThemeData().copyWith().hashCode);
});
testWidgets('Default debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const DrawerThemeData().debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[]);
});
testWidgets('Custom debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
DrawerThemeData(
backgroundColor: const Color(0x00000099),
scrimColor: const Color(0x00000098),
elevation: 5.0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0)),
).debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[
'backgroundColor: Color(0x00000099)',
'scrimColor: Color(0x00000098)',
'elevation: 5.0',
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(2.0))',
]);
});
testWidgets('Default values are used when no Drawer or DrawerThemeData properties are specified', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
key: scaffoldKey,
drawer: const Drawer(),
),
),
);
scaffoldKey.currentState!.openDrawer();
await tester.pumpAndSettle();
expect(_drawerMaterial(tester).color, null);
expect(_drawerMaterial(tester).elevation, 16.0);
expect(_drawerMaterial(tester).shape, null);
expect(_scrim(tester).color, Colors.black54);
});
testWidgets('DrawerThemeData values are used when no Drawer properties are specified', (WidgetTester tester) async {
const Color backgroundColor = Color(0x00000001);
const Color scrimColor = Color(0x00000002);
const double elevation = 7.0;
const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
drawerTheme: const DrawerThemeData(
backgroundColor: backgroundColor,
scrimColor: scrimColor,
elevation: elevation,
shape: shape,
),
),
home: Scaffold(
key: scaffoldKey,
drawer: const Drawer(),
),
),
);
scaffoldKey.currentState!.openDrawer();
await tester.pumpAndSettle();
expect(_drawerMaterial(tester).color, backgroundColor);
expect(_drawerMaterial(tester).elevation, elevation);
expect(_drawerMaterial(tester).shape, shape);
expect(_scrim(tester).color, scrimColor);
});
testWidgets('Drawer values take priority over DrawerThemeData values when both properties are specified', (WidgetTester tester) async {
const Color backgroundColor = Color(0x00000001);
const Color scrimColor = Color(0x00000002);
const double elevation = 7.0;
const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
drawerTheme: const DrawerThemeData(
backgroundColor: Color(0x00000003),
scrimColor: Color(0x00000004),
elevation: 13.0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(29.0))),
),
),
home: Scaffold(
key: scaffoldKey,
drawerScrimColor: scrimColor,
drawer: const Drawer(
backgroundColor: backgroundColor,
elevation: elevation,
shape: shape,
),
),
),
);
scaffoldKey.currentState!.openDrawer();
await tester.pumpAndSettle();
expect(_drawerMaterial(tester).color, backgroundColor);
expect(_drawerMaterial(tester).elevation, elevation);
expect(_drawerMaterial(tester).shape, shape);
expect(_scrim(tester).color, scrimColor);
});
testWidgets('DrawerTheme values take priority over ThemeData.drawerTheme values when both properties are specified', (WidgetTester tester) async {
const Color backgroundColor = Color(0x00000001);
const Color scrimColor = Color(0x00000002);
const double elevation = 7.0;
const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
drawerTheme: const DrawerThemeData(
backgroundColor: Color(0x00000003),
scrimColor: Color(0x00000004),
elevation: 13.0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(29.0))),
),
),
home: DrawerTheme(
data: const DrawerThemeData(
backgroundColor: backgroundColor,
scrimColor: scrimColor,
elevation: elevation,
shape: shape,
),
child: Scaffold(
key: scaffoldKey,
drawer: const Drawer(),
),
),
),
);
scaffoldKey.currentState!.openDrawer();
await tester.pumpAndSettle();
expect(_drawerMaterial(tester).color, backgroundColor);
expect(_drawerMaterial(tester).elevation, elevation);
expect(_drawerMaterial(tester).shape, shape);
expect(_scrim(tester).color, scrimColor);
});
}
Material _drawerMaterial(WidgetTester tester) {
return tester.firstWidget<Material>(
find.descendant(
of: find.byType(Drawer),
matching: find.byType(Material),
),
);
}
// The scrim is a Container within a Semantics node labeled "Dismiss",
// within a DrawerController.
Container _scrim(WidgetTester tester) {
return tester.widget<Container>(
find.descendant(
of: find.descendant(
of: find.byType(DrawerController),
matching: find.byWidgetPredicate((Widget widget) {
return widget is Semantics
&& widget.properties.label == 'Dismiss';
}),
),
matching: find.byType(Container),
),
);
}
......@@ -344,6 +344,7 @@ void main() {
radioTheme: const RadioThemeData(),
switchTheme: const SwitchThemeData(),
progressIndicatorTheme: const ProgressIndicatorThemeData(),
drawerTheme: const DrawerThemeData(),
fixTextFieldOutlineLabel: false,
useTextSelectionTheme: false,
androidOverscrollIndicator: null,
......@@ -439,6 +440,7 @@ void main() {
radioTheme: const RadioThemeData(),
switchTheme: const SwitchThemeData(),
progressIndicatorTheme: const ProgressIndicatorThemeData(),
drawerTheme: const DrawerThemeData(),
fixTextFieldOutlineLabel: true,
useTextSelectionTheme: true,
androidOverscrollIndicator: AndroidOverscrollIndicator.stretch,
......@@ -510,6 +512,12 @@ void main() {
elevatedButtonTheme: otherTheme.elevatedButtonTheme,
outlinedButtonTheme: otherTheme.outlinedButtonTheme,
textSelectionTheme: otherTheme.textSelectionTheme,
dataTableTheme: otherTheme.dataTableTheme,
checkboxTheme: otherTheme.checkboxTheme,
radioTheme: otherTheme.radioTheme,
switchTheme: otherTheme.switchTheme,
progressIndicatorTheme: otherTheme.progressIndicatorTheme,
drawerTheme: otherTheme.drawerTheme,
fixTextFieldOutlineLabel: otherTheme.fixTextFieldOutlineLabel,
);
......@@ -578,6 +586,12 @@ void main() {
expect(themeDataCopy.elevatedButtonTheme, equals(otherTheme.elevatedButtonTheme));
expect(themeDataCopy.outlinedButtonTheme, equals(otherTheme.outlinedButtonTheme));
expect(themeDataCopy.textSelectionTheme, equals(otherTheme.textSelectionTheme));
expect(themeDataCopy.dataTableTheme, equals(otherTheme.dataTableTheme));
expect(themeDataCopy.checkboxTheme, equals(otherTheme.checkboxTheme));
expect(themeDataCopy.radioTheme, equals(otherTheme.radioTheme));
expect(themeDataCopy.switchTheme, equals(otherTheme.switchTheme));
expect(themeDataCopy.progressIndicatorTheme, equals(otherTheme.progressIndicatorTheme));
expect(themeDataCopy.drawerTheme, equals(otherTheme.drawerTheme));
expect(themeDataCopy.fixTextFieldOutlineLabel, equals(otherTheme.fixTextFieldOutlineLabel));
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment