diff --git a/packages/flutter/lib/src/cupertino/text_selection.dart b/packages/flutter/lib/src/cupertino/text_selection.dart index 52393d525e..a4db8dbb77 100644 --- a/packages/flutter/lib/src/cupertino/text_selection.dart +++ b/packages/flutter/lib/src/cupertino/text_selection.dart @@ -115,6 +115,10 @@ class _TextSelectionToolbar extends StatelessWidget { items.add(onePhysicalPixelVerticalDivider); items.add(_buildToolbarButton(localizations.selectAllButtonLabel, handleSelectAll)); } + // If there is no option available, build an empty widget. + if (items.isEmpty) { + return Container(width: 0.0, height: 0.0); + } const Widget padding = Padding(padding: EdgeInsets.only(bottom: 10.0)); diff --git a/packages/flutter/lib/src/material/text_selection.dart b/packages/flutter/lib/src/material/text_selection.dart index 31b3a4dc01..f3601b136c 100644 --- a/packages/flutter/lib/src/material/text_selection.dart +++ b/packages/flutter/lib/src/material/text_selection.dart @@ -49,6 +49,11 @@ class _TextSelectionToolbar extends StatelessWidget { if (handleSelectAll != null) items.add(FlatButton(child: Text(localizations.selectAllButtonLabel), onPressed: handleSelectAll)); + // If there is no option available, build an empty widget. + if (items.isEmpty) { + return Container(width: 0.0, height: 0.0); + } + return Material( elevation: 1.0, child: Container( diff --git a/packages/flutter/test/material/text_field_test.dart b/packages/flutter/test/material/text_field_test.dart index 941266ba26..32e8297193 100644 --- a/packages/flutter/test/material/text_field_test.dart +++ b/packages/flutter/test/material/text_field_test.dart @@ -854,6 +854,55 @@ void main() { expect(find.text('CUT'), findsNothing); }); + testWidgets('text field build empty tool bar when no options available ios', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + theme: ThemeData(platform: TargetPlatform.iOS), + home: const Material( + child: TextField( + readOnly: true, + ), + ), + ) + ); + + await tester.tap(find.byType(TextField)); + await tester.pump(const Duration(milliseconds: 50)); + + await tester.tap(find.byType(TextField)); + // Wait for context menu to be built. + await tester.pumpAndSettle(); + final RenderBox container = tester.renderObject(find.descendant( + of: find.byType(FadeTransition), + matching: find.byType(Container), + )); + expect(container.size, Size.zero); + }); + + testWidgets('text field build empty tool bar when no options available android', (WidgetTester tester) async { + await tester.pumpWidget( + const MaterialApp( + home: Material( + child: TextField( + readOnly: true, + ), + ), + ) + ); + + await tester.tap(find.byType(TextField)); + await tester.pump(const Duration(milliseconds: 50)); + + await tester.tap(find.byType(TextField)); + // Wait for context menu to be built. + await tester.pumpAndSettle(); + final RenderBox container = tester.renderObject(find.descendant( + of: find.byType(FadeTransition), + matching: find.byType(Container), + )); + expect(container.size, Size.zero); + }); + testWidgets('Sawping controllers should update selection', (WidgetTester tester) async { TextEditingController controller = TextEditingController(text: 'readonly'); final OverlayEntry entry = OverlayEntry(