Skip to content
Open
Changes from 4 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
20 changes: 12 additions & 8 deletions examples/travel_app/lib/src/catalog/text_input_chip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,23 +75,27 @@ class _TextInputChip extends StatefulWidget {
}

class _TextInputChipState extends State<_TextInputChip> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The changes look good and correctly implement the desired functionality. However, I noticed that tests for this new behavior are missing. The repository's style guide states that code should be tested.1

Please consider adding a widget test for _TextInputChip to verify:

  • The chip displays the label when no value is provided.
  • The chip displays the initialValue when provided.
  • The chip displays the user-entered text after submission.
  • The chip reverts to displaying the label when the user clears the text.

Style Guide References

Footnotes

  1. Code should be tested. (link)

late String _currentValue;
final TextEditingController _textController = TextEditingController();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The TextEditingController _textController is initialized here but never disposed of, which will cause a memory leak. You should override the dispose method in _TextInputChipState and call _textController.dispose() inside it.

For example:

@override
void dispose() {
  _textController.dispose();
  super.dispose();
}


@override
void initState() {
super.initState();
_currentValue = widget.initialValue ?? widget.label;
_textController.text = widget.initialValue ?? '';
if (widget.values[widget.widgetId] == null && widget.initialValue != null) {
widget.values[widget.widgetId] = widget.initialValue;
}
}

@override
Widget build(BuildContext context) {
final value = widget.values[widget.widgetId];
final currentValue = value is String ? value : null;
final text = currentValue ?? widget.label;
return FilterChip(
label: Text(_currentValue),
label: Text(text),
selected: false,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
onSelected: (bool selected) {
_textController.text = currentValue ?? '';
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
Expand All @@ -110,11 +114,11 @@ class _TextInputChipState extends State<_TextInputChip> {
final newValue = _textController.text;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The new value from the text controller should be trimmed before checking if it's empty. This handles cases where a user might input only whitespace, which would currently result in an empty-looking chip instead of it reverting to the label text.

Suggested change
final newValue = _textController.text;
final newValue = _textController.text.trim();

if (newValue.isNotEmpty) {
widget.values[widget.widgetId] = newValue;
setState(() {
_currentValue = newValue;
});
Navigator.pop(context);
} else {
widget.values.remove(widget.widgetId);
}
setState(() {});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For better readability and to follow idiomatic Flutter code style, it's recommended to wrap state-mutating logic inside the setState call. This makes it clearer which changes are intended to trigger a UI rebuild.

Suggested change
if (newValue.isNotEmpty) {
widget.values[widget.widgetId] = newValue;
setState(() {
_currentValue = newValue;
});
Navigator.pop(context);
} else {
widget.values.remove(widget.widgetId);
}
setState(() {});
setState(() {
if (newValue.isNotEmpty) {
widget.values[widget.widgetId] = newValue;
} else {
widget.values.remove(widget.widgetId);
}
});

Navigator.pop(context);
},
child: const Text('Done'),
),
Expand Down
Loading