Unverified Commit 18b239fb authored by Tirth's avatar Tirth Committed by GitHub

Added keyboardType & textInputAction props to SearchBar, SearchAnchor & SearchAnchor.bar (#138553)

Added `keyboardType` & `textInputAction` props to `SearchBar`, `SearchAnchor` & `SearchAnchor.bar`

Fixes #138483
parent 89edac40
......@@ -131,6 +131,8 @@ class SearchAnchor extends StatefulWidget {
this.viewOnSubmitted,
required this.builder,
required this.suggestionsBuilder,
this.textInputAction,
this.keyboardType,
});
/// Create a [SearchAnchor] that has a [SearchBar] which opens a search view.
......@@ -174,7 +176,9 @@ class SearchAnchor extends StatefulWidget {
bool? isFullScreen,
SearchController searchController,
TextCapitalization textCapitalization,
required SuggestionsBuilder suggestionsBuilder
required SuggestionsBuilder suggestionsBuilder,
TextInputAction? textInputAction,
TextInputType? keyboardType,
}) = _SearchAnchorWithSearchBar;
/// Whether the search view grows to fill the entire screen when the
......@@ -323,6 +327,14 @@ class SearchAnchor extends StatefulWidget {
/// To get a different layout, use [viewBuilder] to override.
final SuggestionsBuilder suggestionsBuilder;
/// {@macro flutter.widgets.TextField.textInputAction}
final TextInputAction? textInputAction;
/// The type of action button to use for the keyboard.
///
/// Defaults to the default value specified in [TextField].
final TextInputType? keyboardType;
@override
State<SearchAnchor> createState() => _SearchAnchorState();
}
......@@ -396,6 +408,8 @@ class _SearchAnchorState extends State<SearchAnchor> {
suggestionsBuilder: widget.suggestionsBuilder,
textCapitalization: widget.textCapitalization,
capturedThemes: InheritedTheme.capture(from: context, to: navigator.context),
textInputAction: widget.textInputAction,
keyboardType: widget.keyboardType,
));
}
......@@ -469,6 +483,8 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
required this.searchController,
required this.suggestionsBuilder,
required this.capturedThemes,
this.textInputAction,
this.keyboardType,
});
final ValueChanged<String>? viewOnChanged;
......@@ -494,6 +510,8 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
final SearchController searchController;
final SuggestionsBuilder suggestionsBuilder;
final CapturedThemes capturedThemes;
final TextInputAction? textInputAction;
final TextInputType? keyboardType;
@override
Color? get barrierColor => Colors.transparent;
......@@ -637,6 +655,8 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
searchController: searchController,
suggestionsBuilder: suggestionsBuilder,
textCapitalization: textCapitalization,
textInputAction: textInputAction,
keyboardType: keyboardType,
),
),
);
......@@ -673,6 +693,8 @@ class _ViewContent extends StatefulWidget {
required this.viewRect,
required this.searchController,
required this.suggestionsBuilder,
this.textInputAction,
this.keyboardType,
});
final ValueChanged<String>? viewOnChanged;
......@@ -697,6 +719,8 @@ class _ViewContent extends StatefulWidget {
final Rect viewRect;
final SearchController searchController;
final SuggestionsBuilder suggestionsBuilder;
final TextInputAction? textInputAction;
final TextInputType? keyboardType;
@override
State<_ViewContent> createState() => _ViewContentState();
......@@ -876,6 +900,8 @@ class _ViewContentState extends State<_ViewContent> {
},
onSubmitted: widget.viewOnSubmitted,
textCapitalization: widget.textCapitalization,
textInputAction: widget.textInputAction,
keyboardType: widget.keyboardType,
),
),
),
......@@ -939,7 +965,9 @@ class _SearchAnchorWithSearchBar extends SearchAnchor {
super.textCapitalization,
ValueChanged<String>? onChanged,
ValueChanged<String>? onSubmitted,
required super.suggestionsBuilder
required super.suggestionsBuilder,
super.textInputAction,
super.keyboardType,
}) : super(
viewHintText: viewHintText ?? barHintText,
headerTextStyle: viewHeaderTextStyle,
......@@ -970,6 +998,8 @@ class _SearchAnchorWithSearchBar extends SearchAnchor {
leading: barLeading ?? const Icon(Icons.search),
trailing: barTrailing,
textCapitalization: textCapitalization,
textInputAction: textInputAction,
keyboardType: keyboardType,
);
}
);
......@@ -1086,6 +1116,8 @@ class SearchBar extends StatefulWidget {
this.hintStyle,
this.textCapitalization,
this.autoFocus = false,
this.textInputAction,
this.keyboardType,
});
/// Controls the text being edited in the search bar's text field.
......@@ -1210,6 +1242,14 @@ class SearchBar extends StatefulWidget {
/// {@macro flutter.widgets.editableText.autofocus}
final bool autoFocus;
/// {@macro flutter.widgets.TextField.textInputAction}
final TextInputAction? textInputAction;
/// The type of action button to use for the keyboard.
///
/// Defaults to the default value specified in [TextField].
final TextInputType? keyboardType;
@override
State<SearchBar> createState() => _SearchBarState();
}
......@@ -1349,6 +1389,8 @@ class _SearchBarState extends State<SearchBar> {
isDense: true,
)),
textCapitalization: effectiveTextCapitalization,
textInputAction: widget.textInputAction,
keyboardType: widget.keyboardType,
),
),
),
......
......@@ -419,10 +419,12 @@ class TextField extends StatefulWidget {
/// {@macro flutter.widgets.editableText.keyboardType}
final TextInputType keyboardType;
/// {@template flutter.widgets.TextField.textInputAction}
/// The type of action button to use for the keyboard.
///
/// Defaults to [TextInputAction.newline] if [keyboardType] is
/// [TextInputType.multiline] and [TextInputAction.done] otherwise.
/// {@endtemplate}
final TextInputAction? textInputAction;
/// {@macro flutter.widgets.editableText.textCapitalization}
......
......@@ -2762,6 +2762,190 @@ void main() {
).first);
expect(suggestionMaterial.color, localTheme.cardTheme.color);
});
testWidgetsWithLeakTracking('SearchBar respects keyboardType property', (WidgetTester tester) async {
Widget buildSearchBar(TextInputType keyboardType) {
return MaterialApp(
home: Center(
child: Material(
child: SearchBar(
keyboardType: keyboardType,
),
),
),
);
}
await tester.pumpWidget(buildSearchBar(TextInputType.number));
await tester.pump();
TextField textField = tester.widget(find.byType(TextField));
expect(textField.keyboardType, TextInputType.number);
await tester.pumpWidget(buildSearchBar(TextInputType.phone));
await tester.pump();
textField = tester.widget(find.byType(TextField));
expect(textField.keyboardType, TextInputType.phone);
});
testWidgetsWithLeakTracking('SearchAnchor respects keyboardType property', (WidgetTester tester) async {
Widget buildSearchAnchor(TextInputType keyboardType) {
return MaterialApp(
home: Center(
child: Material(
child: SearchAnchor(
keyboardType: keyboardType,
builder: (BuildContext context, SearchController controller) {
return IconButton(
icon: const Icon(Icons.ac_unit),
onPressed: () {
controller.openView();
},
);
},
suggestionsBuilder: (BuildContext context, SearchController controller) {
return <Widget>[];
},
),
),
),
);
}
await tester.pumpWidget(buildSearchAnchor(TextInputType.number));
await tester.pump();
await tester.tap(find.widgetWithIcon(IconButton, Icons.ac_unit));
await tester.pumpAndSettle();
TextField textField = tester.widget(find.byType(TextField));
expect(textField.keyboardType, TextInputType.number);
await tester.tap(find.widgetWithIcon(IconButton, Icons.arrow_back));
await tester.pump();
await tester.pumpWidget(buildSearchAnchor(TextInputType.phone));
await tester.pump();
await tester.tap(find.widgetWithIcon(IconButton, Icons.ac_unit));
await tester.pumpAndSettle();
textField = tester.widget(find.byType(TextField));
expect(textField.keyboardType, TextInputType.phone);
});
testWidgetsWithLeakTracking('SearchAnchor.bar respects keyboardType property', (WidgetTester tester) async {
Widget buildSearchAnchor(TextInputType keyboardType) {
return MaterialApp(
home: Center(
child: Material(
child: SearchAnchor.bar(
keyboardType: keyboardType,
suggestionsBuilder: (BuildContext context, SearchController controller) {
return <Widget>[];
},
),
),
),
);
}
await tester.pumpWidget(buildSearchAnchor(TextInputType.number));
await tester.pump();
await tester.tap(find.byType(SearchBar)); // Open search view.
await tester.pumpAndSettle();
final Finder textFieldFinder = find.descendant(of: findViewContent(), matching: find.byType(TextField));
final TextField textFieldInView = tester.widget<TextField>(textFieldFinder);
expect(textFieldInView.keyboardType, TextInputType.number);
// Close search view.
await tester.tap(find.widgetWithIcon(IconButton, Icons.arrow_back));
await tester.pumpAndSettle();
final TextField textField = tester.widget(find.byType(TextField));
expect(textField.keyboardType, TextInputType.number);
});
testWidgetsWithLeakTracking('SearchBar respects textInputAction property', (WidgetTester tester) async {
Widget buildSearchBar(TextInputAction textInputAction) {
return MaterialApp(
home: Center(
child: Material(
child: SearchBar(
textInputAction: textInputAction,
),
),
),
);
}
await tester.pumpWidget(buildSearchBar(TextInputAction.previous));
await tester.pump();
TextField textField = tester.widget(find.byType(TextField));
expect(textField.textInputAction, TextInputAction.previous);
await tester.pumpWidget(buildSearchBar(TextInputAction.send));
await tester.pump();
textField = tester.widget(find.byType(TextField));
expect(textField.textInputAction, TextInputAction.send);
});
testWidgetsWithLeakTracking('SearchAnchor respects textInputAction property', (WidgetTester tester) async {
Widget buildSearchAnchor(TextInputAction textInputAction) {
return MaterialApp(
home: Center(
child: Material(
child: SearchAnchor(
textInputAction: textInputAction,
builder: (BuildContext context, SearchController controller) {
return IconButton(
icon: const Icon(Icons.ac_unit),
onPressed: () {
controller.openView();
},
);
},
suggestionsBuilder: (BuildContext context, SearchController controller) {
return <Widget>[];
},
),
),
),
);
}
await tester.pumpWidget(buildSearchAnchor(TextInputAction.previous));
await tester.pump();
await tester.tap(find.widgetWithIcon(IconButton, Icons.ac_unit));
await tester.pumpAndSettle();
TextField textField = tester.widget(find.byType(TextField));
expect(textField.textInputAction, TextInputAction.previous);
await tester.tap(find.widgetWithIcon(IconButton, Icons.arrow_back));
await tester.pump();
await tester.pumpWidget(buildSearchAnchor(TextInputAction.send));
await tester.pump();
await tester.tap(find.widgetWithIcon(IconButton, Icons.ac_unit));
await tester.pumpAndSettle();
textField = tester.widget(find.byType(TextField));
expect(textField.textInputAction, TextInputAction.send);
});
testWidgetsWithLeakTracking('SearchAnchor.bar respects textInputAction property', (WidgetTester tester) async {
Widget buildSearchAnchor(TextInputAction textInputAction) {
return MaterialApp(
home: Center(
child: Material(
child: SearchAnchor.bar(
textInputAction: textInputAction,
suggestionsBuilder: (BuildContext context, SearchController controller) {
return <Widget>[];
},
),
),
),
);
}
await tester.pumpWidget(buildSearchAnchor(TextInputAction.previous));
await tester.pump();
await tester.tap(find.byType(SearchBar)); // Open search view.
await tester.pumpAndSettle();
final Finder textFieldFinder = find.descendant(of: findViewContent(), matching: find.byType(TextField));
final TextField textFieldInView = tester.widget<TextField>(textFieldFinder);
expect(textFieldInView.textInputAction, TextInputAction.previous);
// Close search view.
await tester.tap(find.widgetWithIcon(IconButton, Icons.arrow_back));
await tester.pumpAndSettle();
final TextField textField = tester.widget(find.byType(TextField));
expect(textField.textInputAction, TextInputAction.previous);
});
}
Future<void> checkSearchBarDefaults(WidgetTester tester, ColorScheme colorScheme, Material material) async {
......
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