Skip to content

Commit 7208065

Browse files
authored
Allow Drawer width to be customized (#99777)
* Add ability to customize Drawer width * Fix formatting * More formatting * Formatting again * Add width to DrawerThemeData and add associated tests * Fix test formatting
1 parent b424736 commit 7208065

File tree

4 files changed

+79
-2
lines changed

4 files changed

+79
-2
lines changed

packages/flutter/lib/src/material/drawer.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class Drawer extends StatelessWidget {
144144
this.backgroundColor,
145145
this.elevation,
146146
this.shape,
147+
this.width,
147148
this.child,
148149
this.semanticLabel,
149150
}) : assert(elevation == null || elevation >= 0.0),
@@ -172,6 +173,12 @@ class Drawer extends StatelessWidget {
172173
/// is also null, then it falls back to [Material]'s default.
173174
final ShapeBorder? shape;
174175

176+
/// The width of the drawer.
177+
///
178+
/// If this is null, then [DrawerThemeData.width] is used. If that is also
179+
/// null, then it falls back to the Material spec's default (304.0).
180+
final double? width;
181+
175182
/// The widget below this widget in the tree.
176183
///
177184
/// Typically a [SliverList].
@@ -212,7 +219,7 @@ class Drawer extends StatelessWidget {
212219
explicitChildNodes: true,
213220
label: label,
214221
child: ConstrainedBox(
215-
constraints: const BoxConstraints.expand(width: _kWidth),
222+
constraints: BoxConstraints.expand(width: width ?? drawerTheme.width ?? _kWidth),
216223
child: Material(
217224
color: backgroundColor ?? drawerTheme.backgroundColor,
218225
elevation: elevation ?? drawerTheme.elevation ?? 16.0,

packages/flutter/lib/src/material/drawer_theme.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class DrawerThemeData with Diagnosticable {
3636
this.scrimColor,
3737
this.elevation,
3838
this.shape,
39+
this.width,
3940
});
4041

4142
/// Overrides the default value of [Drawer.backgroundColor].
@@ -50,19 +51,24 @@ class DrawerThemeData with Diagnosticable {
5051
/// Overrides the default value of [Drawer.shape].
5152
final ShapeBorder? shape;
5253

54+
/// Overrides the default value of [Drawer.width].
55+
final double? width;
56+
5357
/// Creates a copy of this object with the given fields replaced with the
5458
/// new values.
5559
DrawerThemeData copyWith({
5660
Color? backgroundColor,
5761
Color? scrimColor,
5862
double? elevation,
5963
ShapeBorder? shape,
64+
double? width,
6065
}) {
6166
return DrawerThemeData(
6267
backgroundColor: backgroundColor ?? this.backgroundColor,
6368
scrimColor: scrimColor ?? this.scrimColor,
6469
elevation: elevation ?? this.elevation,
6570
shape: shape ?? this.shape,
71+
width: width ?? this.width,
6672
);
6773
}
6874

@@ -80,6 +86,7 @@ class DrawerThemeData with Diagnosticable {
8086
scrimColor: Color.lerp(a?.scrimColor, b?.scrimColor, t),
8187
elevation: lerpDouble(a?.elevation, b?.elevation, t),
8288
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
89+
width: lerpDouble(a?.width, b?.width, t),
8390
);
8491
}
8592

@@ -89,6 +96,7 @@ class DrawerThemeData with Diagnosticable {
8996
scrimColor,
9097
elevation,
9198
shape,
99+
width,
92100
);
93101

94102
@override
@@ -101,7 +109,8 @@ class DrawerThemeData with Diagnosticable {
101109
&& other.backgroundColor == backgroundColor
102110
&& other.scrimColor == scrimColor
103111
&& other.elevation == elevation
104-
&& other.shape == shape;
112+
&& other.shape == shape
113+
&& other.width == width;
105114
}
106115

107116
@override
@@ -111,6 +120,7 @@ class DrawerThemeData with Diagnosticable {
111120
properties.add(ColorProperty('scrimColor', scrimColor, defaultValue: null));
112121
properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
113122
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
123+
properties.add(DoubleProperty('width', width, defaultValue: null));
114124
}
115125
}
116126

packages/flutter/test/material/drawer_test.dart

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,4 +445,45 @@ void main() {
445445
await tester.pumpAndSettle();
446446
expect(find.text('endDrawer'), findsNothing);
447447
});
448+
449+
testWidgets('Drawer width defaults to Material spec', (WidgetTester tester) async {
450+
await tester.pumpWidget(
451+
const MaterialApp(
452+
home: Scaffold(
453+
drawer: Drawer(),
454+
),
455+
),
456+
);
457+
458+
final ScaffoldState state = tester.firstState(find.byType(Scaffold));
459+
state.openDrawer();
460+
461+
await tester.pump();
462+
await tester.pump(const Duration(seconds: 1));
463+
464+
final RenderBox box = tester.renderObject(find.byType(Drawer));
465+
expect(box.size.width, equals(304.0));
466+
});
467+
468+
testWidgets('Drawer width can be customized by parameter', (WidgetTester tester) async {
469+
const double smallWidth = 200;
470+
471+
await tester.pumpWidget(
472+
const MaterialApp(
473+
home: Scaffold(
474+
drawer: Drawer(
475+
width: smallWidth,
476+
),
477+
),
478+
),
479+
);
480+
481+
final ScaffoldState state = tester.firstState(find.byType(Scaffold));
482+
state.openDrawer();
483+
484+
await tester.pumpAndSettle();
485+
486+
final RenderBox box = tester.renderObject(find.byType(Drawer));
487+
expect(box.size.width, equals(smallWidth));
488+
});
448489
}

packages/flutter/test/material/drawer_theme_test.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ void main() {
3131
scrimColor: Color(0x00000098),
3232
elevation: 5.0,
3333
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0))),
34+
width: 200.0,
3435
).debugFillProperties(builder);
3536

3637
final List<String> description = builder.properties
@@ -43,6 +44,7 @@ void main() {
4344
'scrimColor: Color(0x00000098)',
4445
'elevation: 5.0',
4546
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(2.0))',
47+
'width: 200.0',
4648
]);
4749
});
4850

@@ -63,13 +65,15 @@ void main() {
6365
expect(_drawerMaterial(tester).elevation, 16.0);
6466
expect(_drawerMaterial(tester).shape, null);
6567
expect(_scrim(tester).color, Colors.black54);
68+
expect(_drawerRenderBox(tester).size.width, 304.0);
6669
});
6770

6871
testWidgets('DrawerThemeData values are used when no Drawer properties are specified', (WidgetTester tester) async {
6972
const Color backgroundColor = Color(0x00000001);
7073
const Color scrimColor = Color(0x00000002);
7174
const double elevation = 7.0;
7275
const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
76+
const double width = 200.0;
7377

7478
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
7579
await tester.pumpWidget(
@@ -80,6 +84,7 @@ void main() {
8084
scrimColor: scrimColor,
8185
elevation: elevation,
8286
shape: shape,
87+
width: width,
8388
),
8489
),
8590
home: Scaffold(
@@ -95,13 +100,15 @@ void main() {
95100
expect(_drawerMaterial(tester).elevation, elevation);
96101
expect(_drawerMaterial(tester).shape, shape);
97102
expect(_scrim(tester).color, scrimColor);
103+
expect(_drawerRenderBox(tester).size.width, width);
98104
});
99105

100106
testWidgets('Drawer values take priority over DrawerThemeData values when both properties are specified', (WidgetTester tester) async {
101107
const Color backgroundColor = Color(0x00000001);
102108
const Color scrimColor = Color(0x00000002);
103109
const double elevation = 7.0;
104110
const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
111+
const double width = 200.0;
105112

106113
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
107114
await tester.pumpWidget(
@@ -112,6 +119,7 @@ void main() {
112119
scrimColor: Color(0x00000004),
113120
elevation: 13.0,
114121
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(29.0))),
122+
width: 400.0,
115123
),
116124
),
117125
home: Scaffold(
@@ -121,6 +129,7 @@ void main() {
121129
backgroundColor: backgroundColor,
122130
elevation: elevation,
123131
shape: shape,
132+
width: width,
124133
),
125134
),
126135
),
@@ -132,13 +141,15 @@ void main() {
132141
expect(_drawerMaterial(tester).elevation, elevation);
133142
expect(_drawerMaterial(tester).shape, shape);
134143
expect(_scrim(tester).color, scrimColor);
144+
expect(_drawerRenderBox(tester).size.width, width);
135145
});
136146

137147
testWidgets('DrawerTheme values take priority over ThemeData.drawerTheme values when both properties are specified', (WidgetTester tester) async {
138148
const Color backgroundColor = Color(0x00000001);
139149
const Color scrimColor = Color(0x00000002);
140150
const double elevation = 7.0;
141151
const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
152+
const double width = 200.0;
142153

143154
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
144155
await tester.pumpWidget(
@@ -149,6 +160,7 @@ void main() {
149160
scrimColor: Color(0x00000004),
150161
elevation: 13.0,
151162
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(29.0))),
163+
width: 400.0
152164
),
153165
),
154166
home: DrawerTheme(
@@ -157,6 +169,7 @@ void main() {
157169
scrimColor: scrimColor,
158170
elevation: elevation,
159171
shape: shape,
172+
width: width,
160173
),
161174
child: Scaffold(
162175
key: scaffoldKey,
@@ -172,6 +185,7 @@ void main() {
172185
expect(_drawerMaterial(tester).elevation, elevation);
173186
expect(_drawerMaterial(tester).shape, shape);
174187
expect(_scrim(tester).color, scrimColor);
188+
expect(_drawerRenderBox(tester).size.width, width);
175189
});
176190
}
177191

@@ -200,3 +214,8 @@ Container _scrim(WidgetTester tester) {
200214
),
201215
);
202216
}
217+
218+
// The RenderBox representing the Drawer.
219+
RenderBox _drawerRenderBox(WidgetTester tester) {
220+
return tester.renderObject(find.byType(Drawer));
221+
}

0 commit comments

Comments
 (0)