Unverified Commit 6501f1b5 authored by Daniel Edrisian's avatar Daniel Edrisian Committed by GitHub

Allow modifying barrier color and barrier dismissible for Cupertino Modal Popup (#66692)

parent 3c321ac8
...@@ -933,6 +933,7 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> { ...@@ -933,6 +933,7 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
required this.barrierColor, required this.barrierColor,
required this.barrierLabel, required this.barrierLabel,
required this.builder, required this.builder,
bool? barrierDismissible,
bool? semanticsDismissible, bool? semanticsDismissible,
required ImageFilter? filter, required ImageFilter? filter,
RouteSettings? settings, RouteSettings? settings,
...@@ -940,10 +941,14 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> { ...@@ -940,10 +941,14 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
filter: filter, filter: filter,
settings: settings, settings: settings,
) { ) {
_barrierDismissible = barrierDismissible;
_semanticsDismissible = semanticsDismissible; _semanticsDismissible = semanticsDismissible;
} }
final WidgetBuilder builder; final WidgetBuilder builder;
bool? _barrierDismissible;
bool? _semanticsDismissible; bool? _semanticsDismissible;
@override @override
...@@ -953,7 +958,7 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> { ...@@ -953,7 +958,7 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
final Color? barrierColor; final Color? barrierColor;
@override @override
bool get barrierDismissible => true; bool get barrierDismissible => _barrierDismissible ?? true;
@override @override
bool get semanticsDismissible => _semanticsDismissible ?? false; bool get semanticsDismissible => _semanticsDismissible ?? false;
...@@ -1012,6 +1017,13 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> { ...@@ -1012,6 +1017,13 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
/// It is only used when the method is called. Its corresponding widget can be /// It is only used when the method is called. Its corresponding widget can be
/// safely removed from the tree before the popup is closed. /// safely removed from the tree before the popup is closed.
/// ///
/// The `barrierColor` argument determines the [Color] of the barrier underneath
/// the popup. When unspecified, the barrier color defaults to a light opacity
/// black scrim based on iOS's dialog screens.
///
/// The `barrierDismissible` argument determines whether clicking outside the
/// popup results in dismissal. It is `true` by default.
///
/// The `useRootNavigator` argument is used to determine whether to push the /// The `useRootNavigator` argument is used to determine whether to push the
/// popup to the [Navigator] furthest from or nearest to the given `context`. It /// popup to the [Navigator] furthest from or nearest to the given `context`. It
/// is `false` by default. /// is `false` by default.
...@@ -1038,13 +1050,16 @@ Future<T> showCupertinoModalPopup<T>({ ...@@ -1038,13 +1050,16 @@ Future<T> showCupertinoModalPopup<T>({
required BuildContext context, required BuildContext context,
required WidgetBuilder builder, required WidgetBuilder builder,
ImageFilter? filter, ImageFilter? filter,
Color barrierColor = _kModalBarrierColor,
bool barrierDismissible = true,
bool useRootNavigator = true, bool useRootNavigator = true,
bool? semanticsDismissible, bool? semanticsDismissible,
}) { }) {
assert(useRootNavigator != null); assert(useRootNavigator != null);
return Navigator.of(context, rootNavigator: useRootNavigator)!.push( return Navigator.of(context, rootNavigator: useRootNavigator)!.push(
_CupertinoModalPopupRoute<T>( _CupertinoModalPopupRoute<T>(
barrierColor: CupertinoDynamicColor.resolve(_kModalBarrierColor, context), barrierColor: CupertinoDynamicColor.resolve(barrierColor, context),
barrierDismissible: barrierDismissible,
barrierLabel: 'Dismiss', barrierLabel: 'Dismiss',
builder: builder, builder: builder,
filter: filter, filter: filter,
......
...@@ -1375,6 +1375,137 @@ void main() { ...@@ -1375,6 +1375,137 @@ void main() {
debugDefaultTargetPlatformOverride = null; debugDefaultTargetPlatformOverride = null;
}); });
testWidgets('showCupertinoModalPopup transparent barrier color is transparent', (WidgetTester tester) async {
const Color _kTransparentColor = Color(0x00000000);
await tester.pumpWidget(CupertinoApp(
home: CupertinoPageScaffold(
child: Builder(builder: (BuildContext context) {
return GestureDetector(
onTap: () async {
await showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) => const SizedBox(),
barrierColor: _kTransparentColor,
);
},
child: const Text('tap'),
);
}),
),
));
await tester.tap(find.text('tap'));
await tester.pumpAndSettle();
expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, null);
});
testWidgets('showCupertinoModalPopup null barrier color must be default gray barrier color', (WidgetTester tester) async {
// Barrier color for a Cupertino modal barrier.
// Extracted from https://developer.apple.com/design/resources/.
const Color kModalBarrierColor = CupertinoDynamicColor.withBrightness(
color: Color(0x33000000),
darkColor: Color(0x7A000000),
);
await tester.pumpWidget(CupertinoApp(
home: CupertinoPageScaffold(
child: Builder(builder: (BuildContext context) {
return GestureDetector(
onTap: () async {
await showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) => const SizedBox(),
);
},
child: const Text('tap'),
);
}),
),
));
await tester.tap(find.text('tap'));
await tester.pumpAndSettle();
expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, kModalBarrierColor);
});
testWidgets('showCupertinoModalPopup custom barrier color', (WidgetTester tester) async {
const Color customColor = Color(0x11223344);
await tester.pumpWidget(CupertinoApp(
home: CupertinoPageScaffold(
child: Builder(builder: (BuildContext context) {
return GestureDetector(
onTap: () async {
await showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) => const SizedBox(),
barrierColor: customColor);
},
child: const Text('tap'),
);
}),
),
));
await tester.tap(find.text('tap'));
await tester.pumpAndSettle();
expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, customColor);
});
testWidgets('showCupertinoModalPopup barrier dismissible', (WidgetTester tester) async {
await tester.pumpWidget(CupertinoApp(
home: CupertinoPageScaffold(
child: Builder(builder: (BuildContext context) {
return GestureDetector(
onTap: () async {
await showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) => const Text('Visible'),
barrierDismissible: true);
},
child: const Text('tap'),
);
}),
),
));
await tester.tap(find.text('tap'));
await tester.pumpAndSettle();
await tester.tapAt(tester.getTopLeft(find.ancestor(of: find.text('tap'), matching: find.byType(CupertinoPageScaffold))));
await tester.pumpAndSettle();
expect(find.text('Visible'), findsNothing);
});
testWidgets('showCupertinoModalPopup barrier not dismissible', (WidgetTester tester) async {
await tester.pumpWidget(CupertinoApp(
home: CupertinoPageScaffold(
child: Builder(builder: (BuildContext context) {
return GestureDetector(
onTap: () async {
await showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) => const Text('Visible'),
barrierDismissible: false);
},
child: const Text('tap'),
);
}),
),
));
await tester.tap(find.text('tap'));
await tester.pumpAndSettle();
await tester.tapAt(tester.getTopLeft(find.ancestor(of: find.text('tap'), matching: find.byType(CupertinoPageScaffold))));
await tester.pumpAndSettle();
expect(find.text('Visible'), findsOneWidget);
});
testWidgets('CupertinoPage works', (WidgetTester tester) async { testWidgets('CupertinoPage works', (WidgetTester tester) async {
final LocalKey pageKey = UniqueKey(); final LocalKey pageKey = UniqueKey();
final TransitionDetector detector = TransitionDetector(); final TransitionDetector detector = TransitionDetector();
......
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