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 { ...@@ -131,6 +131,8 @@ class SearchAnchor extends StatefulWidget {
this.viewOnSubmitted, this.viewOnSubmitted,
required this.builder, required this.builder,
required this.suggestionsBuilder, required this.suggestionsBuilder,
this.textInputAction,
this.keyboardType,
}); });
/// Create a [SearchAnchor] that has a [SearchBar] which opens a search view. /// Create a [SearchAnchor] that has a [SearchBar] which opens a search view.
...@@ -174,7 +176,9 @@ class SearchAnchor extends StatefulWidget { ...@@ -174,7 +176,9 @@ class SearchAnchor extends StatefulWidget {
bool? isFullScreen, bool? isFullScreen,
SearchController searchController, SearchController searchController,
TextCapitalization textCapitalization, TextCapitalization textCapitalization,
required SuggestionsBuilder suggestionsBuilder required SuggestionsBuilder suggestionsBuilder,
TextInputAction? textInputAction,
TextInputType? keyboardType,
}) = _SearchAnchorWithSearchBar; }) = _SearchAnchorWithSearchBar;
/// Whether the search view grows to fill the entire screen when the /// Whether the search view grows to fill the entire screen when the
...@@ -323,6 +327,14 @@ class SearchAnchor extends StatefulWidget { ...@@ -323,6 +327,14 @@ class SearchAnchor extends StatefulWidget {
/// To get a different layout, use [viewBuilder] to override. /// To get a different layout, use [viewBuilder] to override.
final SuggestionsBuilder suggestionsBuilder; 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 @override
State<SearchAnchor> createState() => _SearchAnchorState(); State<SearchAnchor> createState() => _SearchAnchorState();
} }
...@@ -396,6 +408,8 @@ class _SearchAnchorState extends State<SearchAnchor> { ...@@ -396,6 +408,8 @@ class _SearchAnchorState extends State<SearchAnchor> {
suggestionsBuilder: widget.suggestionsBuilder, suggestionsBuilder: widget.suggestionsBuilder,
textCapitalization: widget.textCapitalization, textCapitalization: widget.textCapitalization,
capturedThemes: InheritedTheme.capture(from: context, to: navigator.context), capturedThemes: InheritedTheme.capture(from: context, to: navigator.context),
textInputAction: widget.textInputAction,
keyboardType: widget.keyboardType,
)); ));
} }
...@@ -469,6 +483,8 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> { ...@@ -469,6 +483,8 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
required this.searchController, required this.searchController,
required this.suggestionsBuilder, required this.suggestionsBuilder,
required this.capturedThemes, required this.capturedThemes,
this.textInputAction,
this.keyboardType,
}); });
final ValueChanged<String>? viewOnChanged; final ValueChanged<String>? viewOnChanged;
...@@ -494,6 +510,8 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> { ...@@ -494,6 +510,8 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
final SearchController searchController; final SearchController searchController;
final SuggestionsBuilder suggestionsBuilder; final SuggestionsBuilder suggestionsBuilder;
final CapturedThemes capturedThemes; final CapturedThemes capturedThemes;
final TextInputAction? textInputAction;
final TextInputType? keyboardType;
@override @override
Color? get barrierColor => Colors.transparent; Color? get barrierColor => Colors.transparent;
...@@ -637,6 +655,8 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> { ...@@ -637,6 +655,8 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
searchController: searchController, searchController: searchController,
suggestionsBuilder: suggestionsBuilder, suggestionsBuilder: suggestionsBuilder,
textCapitalization: textCapitalization, textCapitalization: textCapitalization,
textInputAction: textInputAction,
keyboardType: keyboardType,
), ),
), ),
); );
...@@ -673,6 +693,8 @@ class _ViewContent extends StatefulWidget { ...@@ -673,6 +693,8 @@ class _ViewContent extends StatefulWidget {
required this.viewRect, required this.viewRect,
required this.searchController, required this.searchController,
required this.suggestionsBuilder, required this.suggestionsBuilder,
this.textInputAction,
this.keyboardType,
}); });
final ValueChanged<String>? viewOnChanged; final ValueChanged<String>? viewOnChanged;
...@@ -697,6 +719,8 @@ class _ViewContent extends StatefulWidget { ...@@ -697,6 +719,8 @@ class _ViewContent extends StatefulWidget {
final Rect viewRect; final Rect viewRect;
final SearchController searchController; final SearchController searchController;
final SuggestionsBuilder suggestionsBuilder; final SuggestionsBuilder suggestionsBuilder;
final TextInputAction? textInputAction;
final TextInputType? keyboardType;
@override @override
State<_ViewContent> createState() => _ViewContentState(); State<_ViewContent> createState() => _ViewContentState();
...@@ -876,6 +900,8 @@ class _ViewContentState extends State<_ViewContent> { ...@@ -876,6 +900,8 @@ class _ViewContentState extends State<_ViewContent> {
}, },
onSubmitted: widget.viewOnSubmitted, onSubmitted: widget.viewOnSubmitted,
textCapitalization: widget.textCapitalization, textCapitalization: widget.textCapitalization,
textInputAction: widget.textInputAction,
keyboardType: widget.keyboardType,
), ),
), ),
), ),
...@@ -939,7 +965,9 @@ class _SearchAnchorWithSearchBar extends SearchAnchor { ...@@ -939,7 +965,9 @@ class _SearchAnchorWithSearchBar extends SearchAnchor {
super.textCapitalization, super.textCapitalization,
ValueChanged<String>? onChanged, ValueChanged<String>? onChanged,
ValueChanged<String>? onSubmitted, ValueChanged<String>? onSubmitted,
required super.suggestionsBuilder required super.suggestionsBuilder,
super.textInputAction,
super.keyboardType,
}) : super( }) : super(
viewHintText: viewHintText ?? barHintText, viewHintText: viewHintText ?? barHintText,
headerTextStyle: viewHeaderTextStyle, headerTextStyle: viewHeaderTextStyle,
...@@ -970,6 +998,8 @@ class _SearchAnchorWithSearchBar extends SearchAnchor { ...@@ -970,6 +998,8 @@ class _SearchAnchorWithSearchBar extends SearchAnchor {
leading: barLeading ?? const Icon(Icons.search), leading: barLeading ?? const Icon(Icons.search),
trailing: barTrailing, trailing: barTrailing,
textCapitalization: textCapitalization, textCapitalization: textCapitalization,
textInputAction: textInputAction,
keyboardType: keyboardType,
); );
} }
); );
...@@ -1086,6 +1116,8 @@ class SearchBar extends StatefulWidget { ...@@ -1086,6 +1116,8 @@ class SearchBar extends StatefulWidget {
this.hintStyle, this.hintStyle,
this.textCapitalization, this.textCapitalization,
this.autoFocus = false, this.autoFocus = false,
this.textInputAction,
this.keyboardType,
}); });
/// Controls the text being edited in the search bar's text field. /// Controls the text being edited in the search bar's text field.
...@@ -1210,6 +1242,14 @@ class SearchBar extends StatefulWidget { ...@@ -1210,6 +1242,14 @@ class SearchBar extends StatefulWidget {
/// {@macro flutter.widgets.editableText.autofocus} /// {@macro flutter.widgets.editableText.autofocus}
final bool 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 @override
State<SearchBar> createState() => _SearchBarState(); State<SearchBar> createState() => _SearchBarState();
} }
...@@ -1349,6 +1389,8 @@ class _SearchBarState extends State<SearchBar> { ...@@ -1349,6 +1389,8 @@ class _SearchBarState extends State<SearchBar> {
isDense: true, isDense: true,
)), )),
textCapitalization: effectiveTextCapitalization, textCapitalization: effectiveTextCapitalization,
textInputAction: widget.textInputAction,
keyboardType: widget.keyboardType,
), ),
), ),
), ),
......
...@@ -419,10 +419,12 @@ class TextField extends StatefulWidget { ...@@ -419,10 +419,12 @@ class TextField extends StatefulWidget {
/// {@macro flutter.widgets.editableText.keyboardType} /// {@macro flutter.widgets.editableText.keyboardType}
final TextInputType keyboardType; final TextInputType keyboardType;
/// {@template flutter.widgets.TextField.textInputAction}
/// The type of action button to use for the keyboard. /// The type of action button to use for the keyboard.
/// ///
/// Defaults to [TextInputAction.newline] if [keyboardType] is /// Defaults to [TextInputAction.newline] if [keyboardType] is
/// [TextInputType.multiline] and [TextInputAction.done] otherwise. /// [TextInputType.multiline] and [TextInputAction.done] otherwise.
/// {@endtemplate}
final TextInputAction? textInputAction; final TextInputAction? textInputAction;
/// {@macro flutter.widgets.editableText.textCapitalization} /// {@macro flutter.widgets.editableText.textCapitalization}
......
...@@ -2762,6 +2762,190 @@ void main() { ...@@ -2762,6 +2762,190 @@ void main() {
).first); ).first);
expect(suggestionMaterial.color, localTheme.cardTheme.color); 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 { 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