From 28a85880512b48aacbbfe8c35e5c4141b9131889 Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Wed, 30 Jul 2025 22:05:25 +0200 Subject: [PATCH] refactor size calculation --- .../widgets/auto_suggest_text_field.dart | 59 ++++++------------- app/lib/utils/text_field_line_count.dart | 30 ++++++++++ 2 files changed, 49 insertions(+), 40 deletions(-) create mode 100644 app/lib/utils/text_field_line_count.dart diff --git a/app/lib/presentation/widgets/auto_suggest_text_field.dart b/app/lib/presentation/widgets/auto_suggest_text_field.dart index 9707bcf2..9736f29c 100644 --- a/app/lib/presentation/widgets/auto_suggest_text_field.dart +++ b/app/lib/presentation/widgets/auto_suggest_text_field.dart @@ -21,6 +21,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:nullability/nullability.dart'; +import 'package:weblibre/utils/text_field_line_count.dart'; class AutoSuggestTextField extends HookWidget { final TextEditingController controller; @@ -83,54 +84,26 @@ class AutoSuggestTextField extends HookWidget { controller.text.isNotEmpty && suggestion!.startsWith(controller.text); - static int _getLineCountUsingBoxes( - String text, - TextStyle style, - double maxWidth, - ) { - final textSpan = TextSpan(text: text, style: style); - - final textPainter = TextPainter( - text: textSpan, - textDirection: TextDirection.ltr, - ); - - textPainter.layout(maxWidth: maxWidth); - - // Select all text - final selection = TextSelection(baseOffset: 0, extentOffset: text.length); - - // Each box represents one line - final lines = textPainter.getBoxesForSelection(selection); - return lines.length; - } - @override Widget build(BuildContext context) { final textFieldKey = useMemoized(() => GlobalKey()); final showSuggestion = useListenableSelector(controller, () { if (maxLines != 1) { - final box = textFieldKey.currentContext?.findRenderObject(); - if (box case final RenderBox box) { - final width = box.size.width; - - final lines = _getLineCountUsingBoxes( - controller.text, + final lines = getTextFieldLineCount( + textFieldKey, + controller.text, + style ?? Theme.of(context).textTheme.bodyLarge!, + ); + final suggestionLines = suggestion.mapNotNull( + (suggestion) => getTextFieldLineCount( + textFieldKey, + suggestion, style ?? Theme.of(context).textTheme.bodyLarge!, - width, - ); + ), + ); - final suggestionLines = suggestion.mapNotNull( - (suggestion) => _getLineCountUsingBoxes( - suggestion, - style ?? Theme.of(context).textTheme.bodyLarge!, - width, - ), - ); - - return lines == 1 && suggestionLines == 1; - } + return lines == 1 && suggestionLines == 1; } return true; @@ -149,6 +122,12 @@ class AutoSuggestTextField extends HookWidget { decoration: baseDecoration.copyWith( floatingLabelBehavior: FloatingLabelBehavior.never, border: InputBorder.none, + suffixIcon: baseDecoration.suffixIcon.mapNotNull( + (_) => const SizedBox.square(dimension: 48), + ), + prefixIcon: baseDecoration.prefixIcon.mapNotNull( + (_) => const SizedBox.square(dimension: 48), + ), label: HookBuilder( builder: (context) { final text = useListenableSelector( diff --git a/app/lib/utils/text_field_line_count.dart b/app/lib/utils/text_field_line_count.dart new file mode 100644 index 00000000..271adae0 --- /dev/null +++ b/app/lib/utils/text_field_line_count.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; + +int _getLineCountUsingBoxes(String text, TextStyle style, double maxWidth) { + final textSpan = TextSpan(text: text, style: style); + + final textPainter = TextPainter( + text: textSpan, + textDirection: TextDirection.ltr, + ); + + textPainter.layout(maxWidth: maxWidth); + + // Select all text + final selection = TextSelection(baseOffset: 0, extentOffset: text.length); + + // Each box represents one line + final lines = textPainter.getBoxesForSelection(selection); + return lines.length; +} + +int? getTextFieldLineCount(GlobalKey key, String text, TextStyle style) { + final box = key.currentContext?.findRenderObject(); + if (box case final RenderBox box) { + final width = box.size.width; + + return _getLineCountUsingBoxes(text, style, width); + } + + return null; +}