Unverified Commit 04860d72 authored by Kate Lovett's avatar Kate Lovett Committed by GitHub

Step 1 of 3: Add opt-in fixing Dialog border radius to match Material Spec (#56084)

parent e384757f
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// TODO(shihaohong): remove ignoring deprecated member use analysis // TODO(shihaohong-Piinks): remove ignoring deprecated member use analysis
// when AlertDialog.scrollable parameter is removed. See // * when AlertDialog.scrollable parameter is removed. See
// https://flutter.dev/go/scrollable-alert-dialog for more details. // https://flutter.dev/go/scrollable-alert-dialog for more details.
// * when Dialog.useMaterialBorderRadius parameter is removed.
// ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: deprecated_member_use_from_same_package
import 'dart:async'; import 'dart:async';
...@@ -55,7 +56,9 @@ class Dialog extends StatelessWidget { ...@@ -55,7 +56,9 @@ class Dialog extends StatelessWidget {
this.clipBehavior = Clip.none, this.clipBehavior = Clip.none,
this.shape, this.shape,
this.child, this.child,
bool useMaterialBorderRadius,
}) : assert(clipBehavior != null), }) : assert(clipBehavior != null),
useMaterialBorderRadius = useMaterialBorderRadius ?? false,
super(key: key); super(key: key);
/// {@template flutter.material.dialog.backgroundColor} /// {@template flutter.material.dialog.backgroundColor}
...@@ -117,7 +120,8 @@ class Dialog extends StatelessWidget { ...@@ -117,7 +120,8 @@ class Dialog extends StatelessWidget {
/// ///
/// Defines the dialog's [Material.shape]. /// Defines the dialog's [Material.shape].
/// ///
/// The default shape is a [RoundedRectangleBorder] with a radius of 2.0. /// The default shape is a [RoundedRectangleBorder] with a radius of 2.0
/// (temporarily, set [useMaterialBorderRadius] to match Material guidelines).
/// {@endtemplate} /// {@endtemplate}
final ShapeBorder shape; final ShapeBorder shape;
...@@ -126,8 +130,19 @@ class Dialog extends StatelessWidget { ...@@ -126,8 +130,19 @@ class Dialog extends StatelessWidget {
/// {@macro flutter.widgets.child} /// {@macro flutter.widgets.child}
final Widget child; final Widget child;
// TODO(johnsonmh): Update default dialog border radius to 4.0 to match material spec. /// Indicates whether the [Dialog.shape]'s default [RoundedRectangleBorder]
/// should have a radius of 4.0 pixels to match Material Design, or use the
/// prior default of 2.0 pixels.
@Deprecated(
'Set useMaterialBorderRadius to `true`. This parameter will be removed and '
'was introduced to migrate Dialog to the correct border radius by default. '
'This feature was deprecated after v1.18.0.'
)
final bool useMaterialBorderRadius;
static const RoundedRectangleBorder _defaultDialogShape = static const RoundedRectangleBorder _defaultDialogShape =
RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)));
static const RoundedRectangleBorder _oldDefaultDialogShape =
RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0))); RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0)));
static const double _defaultElevation = 24.0; static const double _defaultElevation = 24.0;
...@@ -151,7 +166,11 @@ class Dialog extends StatelessWidget { ...@@ -151,7 +166,11 @@ class Dialog extends StatelessWidget {
child: Material( child: Material(
color: backgroundColor ?? dialogTheme.backgroundColor ?? Theme.of(context).dialogBackgroundColor, color: backgroundColor ?? dialogTheme.backgroundColor ?? Theme.of(context).dialogBackgroundColor,
elevation: elevation ?? dialogTheme.elevation ?? _defaultElevation, elevation: elevation ?? dialogTheme.elevation ?? _defaultElevation,
shape: shape ?? dialogTheme.shape ?? _defaultDialogShape, shape: shape ?? dialogTheme.shape ?? (
useMaterialBorderRadius ?
_defaultDialogShape :
_oldDefaultDialogShape
),
type: MaterialType.card, type: MaterialType.card,
clipBehavior: clipBehavior, clipBehavior: clipBehavior,
child: child, child: child,
...@@ -260,8 +279,10 @@ class AlertDialog extends StatelessWidget { ...@@ -260,8 +279,10 @@ class AlertDialog extends StatelessWidget {
this.clipBehavior = Clip.none, this.clipBehavior = Clip.none,
this.shape, this.shape,
this.scrollable = false, this.scrollable = false,
bool useMaterialBorderRadius,
}) : assert(contentPadding != null), }) : assert(contentPadding != null),
assert(clipBehavior != null), assert(clipBehavior != null),
useMaterialBorderRadius = useMaterialBorderRadius ?? false,
super(key: key); super(key: key);
/// The (optional) title of the dialog is displayed in a large font at the top /// The (optional) title of the dialog is displayed in a large font at the top
...@@ -449,6 +470,16 @@ class AlertDialog extends StatelessWidget { ...@@ -449,6 +470,16 @@ class AlertDialog extends StatelessWidget {
) )
final bool scrollable; final bool scrollable;
/// Indicates whether the [Dialog.shape]'s default [RoundedRectangleBorder]
/// should have a radius of 4.0 pixels to match Material Design, or use the
/// prior default of 2.0 pixels.
@Deprecated(
'Set useMaterialBorderRadius to `true`. This parameter will be removed and '
'was introduced to migrate Dialog to the correct border radius by default. '
'This feature was deprecated after v1.18.0.'
)
final bool useMaterialBorderRadius;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context)); assert(debugCheckHasMaterialLocalizations(context));
...@@ -560,6 +591,7 @@ class AlertDialog extends StatelessWidget { ...@@ -560,6 +591,7 @@ class AlertDialog extends StatelessWidget {
clipBehavior: clipBehavior, clipBehavior: clipBehavior,
shape: shape, shape: shape,
child: dialogChild, child: dialogChild,
useMaterialBorderRadius: useMaterialBorderRadius,
); );
} }
} }
...@@ -719,8 +751,10 @@ class SimpleDialog extends StatelessWidget { ...@@ -719,8 +751,10 @@ class SimpleDialog extends StatelessWidget {
this.elevation, this.elevation,
this.semanticLabel, this.semanticLabel,
this.shape, this.shape,
bool useMaterialBorderRadius,
}) : assert(titlePadding != null), }) : assert(titlePadding != null),
assert(contentPadding != null), assert(contentPadding != null),
useMaterialBorderRadius = useMaterialBorderRadius ?? false,
super(key: key); super(key: key);
/// The (optional) title of the dialog is displayed in a large font at the top /// The (optional) title of the dialog is displayed in a large font at the top
...@@ -789,6 +823,16 @@ class SimpleDialog extends StatelessWidget { ...@@ -789,6 +823,16 @@ class SimpleDialog extends StatelessWidget {
/// {@macro flutter.material.dialog.shape} /// {@macro flutter.material.dialog.shape}
final ShapeBorder shape; final ShapeBorder shape;
/// Indicates whether the [Dialog.shape]'s default [RoundedRectangleBorder]
/// should have a radius of 4.0 pixels to match Material Design, or use the
/// prior default of 2.0 pixels.
@Deprecated(
'Set useMaterialBorderRadius to `true`. This parameter will be removed and '
'was introduced to migrate Dialog to the correct border radius by default. '
'This feature was deprecated after v1.18.0.'
)
final bool useMaterialBorderRadius;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context)); assert(debugCheckHasMaterialLocalizations(context));
...@@ -848,6 +892,7 @@ class SimpleDialog extends StatelessWidget { ...@@ -848,6 +892,7 @@ class SimpleDialog extends StatelessWidget {
elevation: elevation, elevation: elevation,
shape: shape, shape: shape,
child: dialogChild, child: dialogChild,
useMaterialBorderRadius: useMaterialBorderRadius,
); );
} }
} }
......
...@@ -503,6 +503,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> { ...@@ -503,6 +503,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
), ),
), ),
insetPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0), insetPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0),
// TODO(Piinks): remove once border radius migration is complete
// The default dialog shape is radius 2 rounded rect, but the spec has // The default dialog shape is radius 2 rounded rect, but the spec has
// been updated to 4, so we will use that here for the Date Picker, but // been updated to 4, so we will use that here for the Date Picker, but
// only if there isn't one provided in the theme. // only if there isn't one provided in the theme.
......
...@@ -407,9 +407,7 @@ class _DateRangePickerDialogState extends State<_DateRangePickerDialog> { ...@@ -407,9 +407,7 @@ class _DateRangePickerDialogState extends State<_DateRangePickerDialog> {
final DialogTheme dialogTheme = Theme.of(context).dialogTheme; final DialogTheme dialogTheme = Theme.of(context).dialogTheme;
size = orientation == Orientation.portrait ? _inputPortraitDialogSize : _inputLandscapeDialogSize; size = orientation == Orientation.portrait ? _inputPortraitDialogSize : _inputLandscapeDialogSize;
insetPadding = const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0); insetPadding = const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0);
// The default dialog shape is radius 2 rounded rect, but the spec has // TODO(Piinks): remove once border radius migration is complete
// been updated to 4, so we will use that here for the Input Date Range
// Picker, but only if there isn't one provided in the theme.
shape = dialogTheme.shape ?? const RoundedRectangleBorder( shape = dialogTheme.shape ?? const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0)) borderRadius: BorderRadius.all(Radius.circular(4.0))
); );
......
...@@ -23,6 +23,10 @@ import 'theme.dart'; ...@@ -23,6 +23,10 @@ import 'theme.dart';
import 'theme_data.dart'; import 'theme_data.dart';
import 'time.dart'; import 'time.dart';
// TODO(Piinks): remove ignoring deprecated member use analysis
// * when Dialog.useMaterialBorderRadius parameter is removed.
// ignore_for_file: deprecated_member_use_from_same_package
// Examples can assume: // Examples can assume:
// BuildContext context; // BuildContext context;
...@@ -1501,12 +1505,24 @@ class _TimePickerDialog extends StatefulWidget { ...@@ -1501,12 +1505,24 @@ class _TimePickerDialog extends StatefulWidget {
const _TimePickerDialog({ const _TimePickerDialog({
Key key, Key key,
@required this.initialTime, @required this.initialTime,
bool useMaterialBorderRadius,
}) : assert(initialTime != null), }) : assert(initialTime != null),
useMaterialBorderRadius = useMaterialBorderRadius ?? false,
super(key: key); super(key: key);
/// The time initially selected when the dialog is shown. /// The time initially selected when the dialog is shown.
final TimeOfDay initialTime; final TimeOfDay initialTime;
/// Indicates whether the [Dialog.shape]'s default [RoundedRectangleBorder]
/// should have a radius of 4.0 pixels to match Material Design, or use the
/// prior default of 2.0 pixels.
@Deprecated(
'Set useMaterialBorderRadius to `true`. This parameter will be removed and '
'was introduced to migrate Dialog to the correct border radius by default. '
'This feature was deprecated after v1.18.0.'
)
final bool useMaterialBorderRadius;
@override @override
_TimePickerDialogState createState() => _TimePickerDialogState(); _TimePickerDialogState createState() => _TimePickerDialogState();
} }
...@@ -1650,6 +1666,7 @@ class _TimePickerDialogState extends State<_TimePickerDialog> { ...@@ -1650,6 +1666,7 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
); );
final Dialog dialog = Dialog( final Dialog dialog = Dialog(
useMaterialBorderRadius: widget.useMaterialBorderRadius,
child: OrientationBuilder( child: OrientationBuilder(
builder: (BuildContext context, Orientation orientation) { builder: (BuildContext context, Orientation orientation) {
final Widget header = _TimePickerHeader( final Widget header = _TimePickerHeader(
...@@ -1744,6 +1761,11 @@ class _TimePickerDialogState extends State<_TimePickerDialog> { ...@@ -1744,6 +1761,11 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
/// The returned Future resolves to the time selected by the user when the user /// The returned Future resolves to the time selected by the user when the user
/// closes the dialog. If the user cancels the dialog, null is returned. /// closes the dialog. If the user cancels the dialog, null is returned.
/// ///
/// The [useMaterialBorderRadius] parameter specifies whether th default
/// [Dialog.shape] of the time picker, a [RoundedRectangleBorder], should have a
/// radius of 4.0 pixels to match Material Design, or use the prior default of
/// 2.0 pixels.
///
/// {@tool snippet} /// {@tool snippet}
/// Show a dialog with [initialTime] equal to the current time. /// Show a dialog with [initialTime] equal to the current time.
/// ///
...@@ -1806,13 +1828,22 @@ Future<TimeOfDay> showTimePicker({ ...@@ -1806,13 +1828,22 @@ Future<TimeOfDay> showTimePicker({
TransitionBuilder builder, TransitionBuilder builder,
bool useRootNavigator = true, bool useRootNavigator = true,
RouteSettings routeSettings, RouteSettings routeSettings,
@Deprecated(
'Set useMaterialBorderRadius to `true`. This parameter will be removed and '
'was introduced to migrate Dialog to the correct border radius by default. '
'This feature was deprecated after v1.18.0.'
)
bool useMaterialBorderRadius,
}) async { }) async {
assert(context != null); assert(context != null);
assert(initialTime != null); assert(initialTime != null);
assert(useRootNavigator != null); assert(useRootNavigator != null);
assert(debugCheckHasMaterialLocalizations(context)); assert(debugCheckHasMaterialLocalizations(context));
final Widget dialog = _TimePickerDialog(initialTime: initialTime); final Widget dialog = _TimePickerDialog(
initialTime: initialTime,
useMaterialBorderRadius: useMaterialBorderRadius ?? false,
);
return await showDialog<TimeOfDay>( return await showDialog<TimeOfDay>(
context: context, context: context,
useRootNavigator: useRootNavigator, useRootNavigator: useRootNavigator,
......
...@@ -44,7 +44,7 @@ RenderParagraph _getTextRenderObjectFromDialog(WidgetTester tester, String text) ...@@ -44,7 +44,7 @@ RenderParagraph _getTextRenderObjectFromDialog(WidgetTester tester, String text)
return tester.element<StatelessElement>(find.descendant(of: find.byType(AlertDialog), matching: find.text(text))).renderObject as RenderParagraph; return tester.element<StatelessElement>(find.descendant(of: find.byType(AlertDialog), matching: find.text(text))).renderObject as RenderParagraph;
} }
const ShapeBorder _defaultDialogShape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0))); const ShapeBorder _defaultDialogShape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)));
void main() { void main() {
testWidgets('Dialog is scrollable', (WidgetTester tester) async { testWidgets('Dialog is scrollable', (WidgetTester tester) async {
...@@ -94,6 +94,7 @@ void main() { ...@@ -94,6 +94,7 @@ void main() {
title: Text('Title'), title: Text('Title'),
content: Text('Y'), content: Text('Y'),
actions: <Widget>[ ], actions: <Widget>[ ],
useMaterialBorderRadius: true,
); );
await tester.pumpWidget(_buildAppWithDialog(dialog, theme: ThemeData(brightness: Brightness.dark))); await tester.pumpWidget(_buildAppWithDialog(dialog, theme: ThemeData(brightness: Brightness.dark)));
...@@ -189,6 +190,7 @@ void main() { ...@@ -189,6 +190,7 @@ void main() {
const AlertDialog dialog = AlertDialog( const AlertDialog dialog = AlertDialog(
actions: <Widget>[ ], actions: <Widget>[ ],
shape: null, shape: null,
useMaterialBorderRadius: true,
); );
await tester.pumpWidget(_buildAppWithDialog(dialog)); await tester.pumpWidget(_buildAppWithDialog(dialog));
......
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