Unverified Commit a8f67ee3 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

[Cupertino] Exclude border for last action item in `CupertinoContextMenu` (#92481)

parent 4327b15b
......@@ -9,10 +9,17 @@ import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'colors.dart';
// The scale of the child at the time that the CupertinoContextMenu opens.
// This value was eyeballed from a physical device running iOS 13.1.2.
const double _kOpenScale = 1.1;
const Color _borderColor = CupertinoDynamicColor.withBrightness(
color: Color(0xFFA9A9AF),
darkColor: Color(0xFF57585A),
);
typedef _DismissCallback = void Function(
BuildContext context,
double scale,
......@@ -1151,8 +1158,8 @@ class _ContextMenuSheet extends StatelessWidget {
// Get the children, whose order depends on orientation and
// contextMenuLocation.
List<Widget> get children {
final Flexible menu = Flexible(
List<Widget> getChildren(BuildContext context) {
final Widget menu = Flexible(
fit: FlexFit.tight,
flex: 2,
child: IntrinsicHeight(
......@@ -1160,7 +1167,22 @@ class _ContextMenuSheet extends StatelessWidget {
borderRadius: const BorderRadius.all(Radius.circular(13.0)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: actions,
children: <Widget>[
actions.first,
for (Widget action in actions.skip(1))
DecoratedBox(
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: CupertinoDynamicColor.resolve(_borderColor, context),
width: 0.5,
)
),
),
position: DecorationPosition.foreground,
child: action,
),
],
),
),
),
......@@ -1195,7 +1217,7 @@ class _ContextMenuSheet extends StatelessWidget {
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: children,
children: getChildren(context),
);
}
}
......
......@@ -115,9 +115,6 @@ class _CupertinoContextMenuActionState extends State<CupertinoContextMenuAction>
child: Container(
decoration: BoxDecoration(
color: _isPressed ? _kBackgroundColorPressed : _kBackgroundColor,
border: const Border(
bottom: BorderSide(color: _kBackgroundColorPressed),
),
),
padding: const EdgeInsets.symmetric(
vertical: 16.0,
......
......@@ -9,7 +9,6 @@ void main() {
final TestWidgetsFlutterBinding binding =
TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
const double _kOpenScale = 1.1;
Widget _getChild() {
return Container(
width: 300.0,
......@@ -66,6 +65,13 @@ void main() {
);
}
Finder _findStaticChildDecoration(WidgetTester tester) {
return find.descendant(
of: _findStatic(),
matching: find.byType(DecoratedBox),
);
}
group('CupertinoContextMenu before and during opening', () {
testWidgets('An unopened CupertinoContextMenu renders child in the same place as without', (WidgetTester tester) async {
// Measure the child in the scene with no CupertinoContextMenu.
......@@ -190,6 +196,65 @@ void main() {
});
group('CupertinoContextMenu when open', () {
testWidgets('Last action does not have border', (WidgetTester tester) async {
final Widget child = _getChild();
await tester.pumpWidget(CupertinoApp(
home: CupertinoPageScaffold(
child: Center(
child: CupertinoContextMenu(
actions: const <CupertinoContextMenuAction>[
CupertinoContextMenuAction(
child: Text('CupertinoContextMenuAction One'),
),
],
child: child,
),
),
),
));
// Open the CupertinoContextMenu
final TestGesture firstGesture = await tester.startGesture(tester.getCenter(find.byWidget(child)));
await tester.pumpAndSettle();
await firstGesture.up();
await tester.pumpAndSettle();
expect(_findStatic(), findsOneWidget);
expect(_findStaticChildDecoration(tester), findsNWidgets(1));
// Close the CupertinoContextMenu.
await tester.tapAt(const Offset(1.0, 1.0));
await tester.pumpAndSettle();
expect(_findStatic(), findsNothing);
await tester.pumpWidget(CupertinoApp(
home: CupertinoPageScaffold(
child: Center(
child: CupertinoContextMenu(
actions: const <CupertinoContextMenuAction>[
CupertinoContextMenuAction(
child: Text('CupertinoContextMenuAction One'),
),
CupertinoContextMenuAction(
child: Text('CupertinoContextMenuAction Two'),
),
],
child: child,
),
),
),
));
// Open the CupertinoContextMenu
final TestGesture secondGesture = await tester.startGesture(tester.getCenter(find.byWidget(child)));
await tester.pumpAndSettle();
await secondGesture.up();
await tester.pumpAndSettle();
expect(_findStatic(), findsOneWidget);
expect(_findStaticChildDecoration(tester), findsNWidgets(3));
});
testWidgets('Can close CupertinoContextMenu by background tap', (WidgetTester tester) async {
final Widget child = _getChild();
await tester.pumpWidget(_getContextMenu(child: child));
......
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