Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: SearchBar.capitalization doesn't work as expected #5070

Merged
merged 1 commit into from
Apr 2, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 44 additions & 7 deletions packages/flet/lib/src/controls/search_anchor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class SearchAnchorControl extends StatefulWidget {
class _SearchAnchorControlState extends State<SearchAnchorControl> {
late final SearchController _controller;
bool _focused = false;
TextCapitalization _textCapitalization = TextCapitalization.none;
late final FocusNode _focusNode;
String? _lastFocusValue;
String? _lastBlurValue;
Expand Down Expand Up @@ -68,15 +69,54 @@ class _SearchAnchorControlState extends State<SearchAnchorControl> {
}

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}");
Expand All @@ -103,9 +143,6 @@ class _SearchAnchorControlState extends State<SearchAnchorControl> {
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)!;

Expand Down Expand Up @@ -197,13 +234,13 @@ class _SearchAnchorControlState extends State<SearchAnchorControl> {
: 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"),
Expand Down