diff --git a/packages/flet/lib/src/controls/search_anchor.dart b/packages/flet/lib/src/controls/search_anchor.dart index 75b6f0f33..500a2ed0d 100644 --- a/packages/flet/lib/src/controls/search_anchor.dart +++ b/packages/flet/lib/src/controls/search_anchor.dart @@ -37,6 +37,7 @@ class SearchAnchorControl extends StatefulWidget { class _SearchAnchorControlState extends State { late final SearchController _controller; bool _focused = false; + TextCapitalization _textCapitalization = TextCapitalization.none; late final FocusNode _focusNode; String? _lastFocusValue; String? _lastBlurValue; @@ -68,15 +69,54 @@ class _SearchAnchorControlState extends State { } void _searchTextChanged() { - debugPrint("_searchTextChanged: ${_controller.text}"); + _textCapitalization = parseTextCapitalization( + widget.control.attrString("capitalization"), TextCapitalization.none)!; _updateValue(_controller.text); } void _updateValue(String value) { - debugPrint("SearchBar.changeValue: $value"); + value = applyCapitalization(value); + if (_controller.value.text != value) { + _controller.value = TextEditingValue( + text: value, + selection: TextSelection.collapsed(offset: value.length), + ); + } + widget.backend.updateControlState(widget.control.id, {"value": value}); } + String applyCapitalization(String text) { + switch (_textCapitalization) { + /// Capitalizes the first character of each word. + case TextCapitalization.words: + return text + .split(RegExp(r'\s+')) + .map((word) => word.isNotEmpty + ? word[0].toUpperCase() + word.substring(1).toLowerCase() + : word) + .join(' '); + + /// Capitalizes the first character of each sentence. + case TextCapitalization.sentences: + return text + .split('. ') + .map((sentence) => sentence.isNotEmpty + ? sentence.trimLeft()[0].toUpperCase() + + sentence.substring(1).toLowerCase() + : sentence) + .join('. '); + + /// Capitalizes all characters. + case TextCapitalization.characters: + return text.toUpperCase(); + + /// No change. + case TextCapitalization.none: + return text; + } + } + @override Widget build(BuildContext context) { debugPrint("SearchAnchor build: ${widget.control.id}"); @@ -103,9 +143,6 @@ class _SearchAnchorControlState extends State { widget.children.where((c) => c.name == "viewLeading" && c.isVisible); var viewTrailingCtrls = widget.children.where((c) => c.name == "viewTrailing" && c.isVisible); - - var textCapitalization = parseTextCapitalization( - widget.control.attrString("textCapitalization")); TextInputType keyboardType = parseTextInputType( widget.control.attrString("keyboardType"), TextInputType.text)!; @@ -197,13 +234,13 @@ class _SearchAnchorControlState extends State { : null, viewSurfaceTintColor: widget.control.attrColor("viewSurfaceTintColor", context), - textCapitalization: textCapitalization, + textCapitalization: _textCapitalization, keyboardType: keyboardType, builder: (BuildContext context, SearchController controller) { return SearchBar( controller: controller, keyboardType: keyboardType, - textCapitalization: textCapitalization, + textCapitalization: _textCapitalization, autoFocus: widget.control.attrBool("autoFocus", false)!, focusNode: _focusNode, hintText: widget.control.attrString("barHintText"),