@@ -37,6 +37,7 @@ class SearchAnchorControl extends StatefulWidget {
37
37
class _SearchAnchorControlState extends State <SearchAnchorControl > {
38
38
late final SearchController _controller;
39
39
bool _focused = false ;
40
+ TextCapitalization _textCapitalization = TextCapitalization .none;
40
41
late final FocusNode _focusNode;
41
42
String ? _lastFocusValue;
42
43
String ? _lastBlurValue;
@@ -68,15 +69,54 @@ class _SearchAnchorControlState extends State<SearchAnchorControl> {
68
69
}
69
70
70
71
void _searchTextChanged () {
71
- debugPrint ("_searchTextChanged: ${_controller .text }" );
72
+ _textCapitalization = parseTextCapitalization (
73
+ widget.control.attrString ("capitalization" ), TextCapitalization .none)! ;
72
74
_updateValue (_controller.text);
73
75
}
74
76
75
77
void _updateValue (String value) {
76
- debugPrint ("SearchBar.changeValue: $value " );
78
+ value = applyCapitalization (value);
79
+ if (_controller.value.text != value) {
80
+ _controller.value = TextEditingValue (
81
+ text: value,
82
+ selection: TextSelection .collapsed (offset: value.length),
83
+ );
84
+ }
85
+
77
86
widget.backend.updateControlState (widget.control.id, {"value" : value});
78
87
}
79
88
89
+ String applyCapitalization (String text) {
90
+ switch (_textCapitalization) {
91
+ /// Capitalizes the first character of each word.
92
+ case TextCapitalization .words:
93
+ return text
94
+ .split (RegExp (r'\s+' ))
95
+ .map ((word) => word.isNotEmpty
96
+ ? word[0 ].toUpperCase () + word.substring (1 ).toLowerCase ()
97
+ : word)
98
+ .join (' ' );
99
+
100
+ /// Capitalizes the first character of each sentence.
101
+ case TextCapitalization .sentences:
102
+ return text
103
+ .split ('. ' )
104
+ .map ((sentence) => sentence.isNotEmpty
105
+ ? sentence.trimLeft ()[0 ].toUpperCase () +
106
+ sentence.substring (1 ).toLowerCase ()
107
+ : sentence)
108
+ .join ('. ' );
109
+
110
+ /// Capitalizes all characters.
111
+ case TextCapitalization .characters:
112
+ return text.toUpperCase ();
113
+
114
+ /// No change.
115
+ case TextCapitalization .none:
116
+ return text;
117
+ }
118
+ }
119
+
80
120
@override
81
121
Widget build (BuildContext context) {
82
122
debugPrint ("SearchAnchor build: ${widget .control .id }" );
@@ -103,9 +143,6 @@ class _SearchAnchorControlState extends State<SearchAnchorControl> {
103
143
widget.children.where ((c) => c.name == "viewLeading" && c.isVisible);
104
144
var viewTrailingCtrls =
105
145
widget.children.where ((c) => c.name == "viewTrailing" && c.isVisible);
106
-
107
- var textCapitalization = parseTextCapitalization (
108
- widget.control.attrString ("textCapitalization" ));
109
146
TextInputType keyboardType = parseTextInputType (
110
147
widget.control.attrString ("keyboardType" ), TextInputType .text)! ;
111
148
@@ -197,13 +234,13 @@ class _SearchAnchorControlState extends State<SearchAnchorControl> {
197
234
: null ,
198
235
viewSurfaceTintColor:
199
236
widget.control.attrColor ("viewSurfaceTintColor" , context),
200
- textCapitalization: textCapitalization ,
237
+ textCapitalization: _textCapitalization ,
201
238
keyboardType: keyboardType,
202
239
builder: (BuildContext context, SearchController controller) {
203
240
return SearchBar (
204
241
controller: controller,
205
242
keyboardType: keyboardType,
206
- textCapitalization: textCapitalization ,
243
+ textCapitalization: _textCapitalization ,
207
244
autoFocus: widget.control.attrBool ("autoFocus" , false )! ,
208
245
focusNode: _focusNode,
209
246
hintText: widget.control.attrString ("barHintText" ),
0 commit comments