diff --git a/lib/widgets/nt4_widgets/multi-topic/combo_box_chooser.dart b/lib/widgets/nt4_widgets/multi-topic/combo_box_chooser.dart index 381c34b7..2089a03e 100644 --- a/lib/widgets/nt4_widgets/multi-topic/combo_box_chooser.dart +++ b/lib/widgets/nt4_widgets/multi-topic/combo_box_chooser.dart @@ -1,3 +1,4 @@ +import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:elastic_dashboard/services/nt4.dart'; import 'package:elastic_dashboard/services/nt4_connection.dart'; import 'package:elastic_dashboard/widgets/nt4_widgets/nt4_widget.dart'; @@ -13,6 +14,8 @@ class ComboBoxChooser extends StatelessWidget with NT4Widget { late String activeTopicName; late String defaultTopicName; + TextEditingController searchController = TextEditingController(); + String? selectedChoice; StringChooserData? _previousData; @@ -169,14 +172,17 @@ class ComboBoxChooser extends StatelessWidget with NT4Widget { return Row( mainAxisSize: MainAxisSize.min, children: [ - _StringChooserDropdown( - selected: selectedChoice, - options: options, - onValueChanged: (String? value) { - publishSelectedValue(value); - - selectedChoice = value; - }, + Flexible( + child: _StringChooserDropdown( + selected: selectedChoice, + options: options, + textController: searchController, + onValueChanged: (String? value) { + publishSelectedValue(value); + + selectedChoice = value; + }, + ), ), const SizedBox(width: 5), (showWarning) @@ -227,25 +233,94 @@ class _StringChooserDropdown extends StatelessWidget { final List options; final String? selected; final Function(String? value) onValueChanged; + final TextEditingController textController; const _StringChooserDropdown({ required this.options, required this.onValueChanged, + required this.textController, this.selected, }); @override Widget build(BuildContext context) { return ExcludeFocus( - child: DropdownButton( + child: Tooltip( + message: selected ?? '', + waitDuration: const Duration(milliseconds: 250), + child: DropdownButton2( + isExpanded: true, value: selected, + selectedItemBuilder: (context) => [ + ...options.map((String option) { + return Container( + alignment: AlignmentDirectional.centerStart, + child: Text( + option, + style: Theme.of(context).textTheme.bodyLarge, + overflow: TextOverflow.ellipsis, + ), + ); + }).toList(), + ], + dropdownStyleData: DropdownStyleData( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15.0), + ), + maxHeight: 250, + width: 250, + ), + dropdownSearchData: DropdownSearchData( + searchController: textController, + searchMatchFn: (item, searchValue) { + return item.value + .toString() + .toLowerCase() + .contains(searchValue.toLowerCase()); + }, + searchInnerWidgetHeight: 50, + searchInnerWidget: Container( + color: Theme.of(context).colorScheme.surface, + height: 50, + padding: const EdgeInsets.only( + top: 8, + bottom: 4, + right: 8, + left: 8, + ), + child: TextFormField( + expands: true, + maxLines: null, + controller: textController, + decoration: InputDecoration( + isDense: true, + contentPadding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 8, + ), + label: const Text('Search'), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ), items: options.map((String option) { return DropdownMenuItem( value: option, - child: Text(option), + child: + Text(option, style: Theme.of(context).textTheme.bodyMedium), ); }).toList(), - onChanged: onValueChanged), + onMenuStateChange: (isOpen) { + if (!isOpen) { + textController.clear(); + } + }, + onChanged: onValueChanged, + ), + ), ); } } diff --git a/lib/widgets/nt4_widgets/multi-topic/split_button_chooser.dart b/lib/widgets/nt4_widgets/multi-topic/split_button_chooser.dart index e49d35e6..3e3fa155 100644 --- a/lib/widgets/nt4_widgets/multi-topic/split_button_chooser.dart +++ b/lib/widgets/nt4_widgets/multi-topic/split_button_chooser.dart @@ -151,21 +151,27 @@ class SplitButtonChooser extends StatelessWidget with NT4Widget { return Row( mainAxisSize: MainAxisSize.min, children: [ - ToggleButtons( - onPressed: (index) { - selectedChoice = options[index]; - - publishSelectedValue(selectedChoice!); - }, - isSelected: options.map((String option) { - if (option == selectedChoice) { - return true; - } - return false; - }).toList(), - children: options.map((String option) { - return Text(option); - }).toList(), + Flexible( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + physics: const AlwaysScrollableScrollPhysics(), + child: ToggleButtons( + onPressed: (index) { + selectedChoice = options[index]; + + publishSelectedValue(selectedChoice!); + }, + isSelected: options.map((String option) { + if (option == selectedChoice) { + return true; + } + return false; + }).toList(), + children: options.map((String option) { + return Text(option); + }).toList(), + ), + ), ), const SizedBox(width: 5), (showWarning) diff --git a/pubspec.lock b/pubspec.lock index d97ee538..e531c847 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -249,6 +249,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.8" + dropdown_button2: + dependency: "direct main" + description: + name: dropdown_button2 + sha256: b0fe8d49a030315e9eef6c7ac84ca964250155a6224d491c1365061bc974a9e1 + url: "https://pub.dev" + source: hosted + version: "2.3.9" elegant_notification: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 5b7589b9..f63944fb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,6 +10,7 @@ dependencies: animations: ^2.0.7 collection: ^1.17.1 contextmenu: ^3.0.0 + dropdown_button2: ^2.3.9 elegant_notification: ^1.11.0 file_selector: ^0.9.3 flutter: