created clearing dropdown menus

This commit is contained in:
2025-02-11 16:23:02 +01:00
parent 6afab33d49
commit 3186ec8780

View File

@@ -0,0 +1,81 @@
import 'package:flutter/material.dart';
class ClearingDropdownMenu<T> extends StatefulWidget {
final List<DropdownMenuEntry<T>> entries;
final T? initialValue;
final void Function(T? item)? onSelected;
final String? label;
const ClearingDropdownMenu({
super.key,
required this.entries,
this.initialValue,
this.onSelected,
this.label,
});
@override
State<ClearingDropdownMenu<T>> createState() =>
_ClearingDropdownMenuState<T>();
}
class _ClearingDropdownMenuState<T> extends State<ClearingDropdownMenu<T>> {
late final TextEditingController _controller;
final FocusNode _focusNode = FocusNode();
T? _selectedValue;
@override
void initState() {
super.initState();
_selectedValue = widget.initialValue;
_controller = TextEditingController(
text: _selectedValue != null
? widget.entries
.firstWhere((entry) => entry.value == _selectedValue)
.label
: '');
_focusNode.addListener(_onFocusChange);
}
void _onFocusChange() {
if (!_focusNode.hasFocus) {
// Check if the current text matches any entry
final validEntry = widget.entries.any((entry) =>
entry.label.toLowerCase() == _controller.text.toLowerCase());
if (!validEntry) {
// Clear the text and selection
_controller.clear();
setState(() {
_selectedValue = null;
});
widget.onSelected?.call(null);
}
}
}
@override
Widget build(BuildContext context) {
return DropdownMenu<T>(
controller: _controller,
focusNode: _focusNode,
initialSelection: widget.initialValue,
onSelected: (T? value) {
setState(() {
_selectedValue = value;
});
widget.onSelected?.call(value);
},
dropdownMenuEntries: widget.entries,
label: widget.label != null ? Text(widget.label!) : null,
);
}
@override
void dispose() {
_controller.dispose();
_focusNode.dispose();
super.dispose();
}
}