From f3410f11362caf02f97c8004a882b74c31efe671 Mon Sep 17 00:00:00 2001 From: josecaseiro Date: Mon, 2 Aug 2021 12:39:37 +0100 Subject: [PATCH] migrate to null-safety --- example/pubspec.lock | 43 +++-- lib/searchable_dropdown.dart | 275 +++++++++++++++-------------- pubspec.lock | 104 ++++------- pubspec.yaml | 2 +- test/searchable_dropdown_test.dart | 34 ++-- 5 files changed, 218 insertions(+), 240 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index 2a1fc0d..24cfe91 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -7,35 +7,42 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.7.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "1.3.1" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.15.0" cupertino_icons: dependency: "direct main" description: @@ -49,7 +56,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" flutter: dependency: "direct main" description: flutter @@ -66,21 +73,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.7.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" searchable_dropdown: dependency: "direct dev" description: @@ -99,55 +106,55 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.1" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.15" + version: "0.4.2" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0" sdks: - dart: ">=2.6.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" diff --git a/lib/searchable_dropdown.dart b/lib/searchable_dropdown.dart index cb9a2f4..b3ce5df 100644 --- a/lib/searchable_dropdown.dart +++ b/lib/searchable_dropdown.dart @@ -14,10 +14,10 @@ class PointerThisPlease { PointerThisPlease(this.value); } -Widget prepareWidget(dynamic object, +Widget? prepareWidget(dynamic object, {dynamic parameter = const NotGiven(), - BuildContext context, - Function stringToWidgetFunction}) { + BuildContext? context, + Function? stringToWidgetFunction}) { if (object == null) { return (null); } @@ -53,9 +53,9 @@ Widget prepareWidget(dynamic object, class SearchableDropdown extends StatefulWidget { final List> items; - final Function onChanged; - final T value; - final TextStyle style; + final Function? onChanged; + final T? value; + final TextStyle? style; final dynamic searchHint; final dynamic hint; final dynamic disabledHint; @@ -65,24 +65,24 @@ class SearchableDropdown extends StatefulWidget { final dynamic label; final dynamic closeButton; final bool displayClearIcon; - final Icon clearIcon; - final Color iconEnabledColor; - final Color iconDisabledColor; + final Icon? clearIcon; + final Color? iconEnabledColor; + final Color? iconDisabledColor; final double iconSize; final bool isExpanded; final bool isCaseSensitiveSearch; - final Function searchFn; - final Function onClear; - final Function selectedValueWidgetFn; + final Function? searchFn; + final Function? onClear; + final Function? selectedValueWidgetFn; final TextInputType keyboardType; - final Function validator; + final Function? validator; final bool multipleSelection; - final List selectedItems; - final Function displayItem; - final bool dialogBox; - final BoxConstraints menuConstraints; - final bool readOnly; - final Color menuBackgroundColor; + final List? selectedItems; + final Function? displayItem; + final bool? dialogBox; + final BoxConstraints? menuConstraints; + final bool? readOnly; + final Color? menuBackgroundColor; /// Search choices Widget with a single choice that opens a dialog or a menu to let the user do the selection conveniently with a search. /// @@ -117,11 +117,11 @@ class SearchableDropdown extends StatefulWidget { /// @param readOnly [bool] whether to let the user choose the value to select or just present the selected value if any. /// @param menuBackgroundColor [Color] background color of the menu whether in dialog box or menu mode. factory SearchableDropdown.single({ - Key key, - @required List> items, - @required Function onChanged, - T value, - TextStyle style, + Key? key, + required List> items, + required Function onChanged, + T? value, + TextStyle? style, dynamic searchHint, dynamic hint, dynamic disabledHint, @@ -132,22 +132,22 @@ class SearchableDropdown extends StatefulWidget { dynamic closeButton = "Close", bool displayClearIcon = true, Icon clearIcon = const Icon(Icons.clear), - Color iconEnabledColor, - Color iconDisabledColor, + Color? iconEnabledColor, + Color? iconDisabledColor, double iconSize = 24.0, bool isExpanded = false, bool isCaseSensitiveSearch = false, - Function searchFn, - Function onClear, - Function selectedValueWidgetFn, + Function? searchFn, + Function? onClear, + Function? selectedValueWidgetFn, TextInputType keyboardType = TextInputType.text, - Function validator, + Function? validator, bool assertUniqueValue = true, - Function displayItem, + Function? displayItem, bool dialogBox = true, - BoxConstraints menuConstraints, + BoxConstraints? menuConstraints, bool readOnly = false, - Color menuBackgroundColor, + Color? menuBackgroundColor, }) { return (SearchableDropdown._( key: key, @@ -216,11 +216,11 @@ class SearchableDropdown extends StatefulWidget { /// @param readOnly [bool] whether to let the user choose the value to select or just present the selected value if any. /// @param menuBackgroundColor [Color] background color of the menu whether in dialog box or menu mode. factory SearchableDropdown.multiple({ - Key key, - @required List> items, - @required Function onChanged, + Key? key, + required List> items, + required Function onChanged, List selectedItems = const [], - TextStyle style, + TextStyle? style, dynamic searchHint, dynamic hint, dynamic disabledHint, @@ -231,21 +231,21 @@ class SearchableDropdown extends StatefulWidget { dynamic closeButton = "Close", bool displayClearIcon = true, Icon clearIcon = const Icon(Icons.clear), - Color iconEnabledColor, - Color iconDisabledColor, + Color? iconEnabledColor, + Color? iconDisabledColor, double iconSize = 24.0, bool isExpanded = false, bool isCaseSensitiveSearch = false, - Function searchFn, - Function onClear, - Function selectedValueWidgetFn, + Function? searchFn, + Function? onClear, + Function? selectedValueWidgetFn, TextInputType keyboardType = TextInputType.text, - Function validator, - Function displayItem, + Function? validator, + Function? displayItem, bool dialogBox = true, - BoxConstraints menuConstraints, + BoxConstraints? menuConstraints, bool readOnly = false, - Color menuBackgroundColor, + Color? menuBackgroundColor, }) { return (SearchableDropdown._( key: key, @@ -283,8 +283,8 @@ class SearchableDropdown extends StatefulWidget { } SearchableDropdown._({ - Key key, - @required this.items, + Key? key, + required this.items, this.onChanged, this.value, this.style, @@ -319,13 +319,13 @@ class SearchableDropdown extends StatefulWidget { assert(iconSize != null), assert(isExpanded != null), assert(!multipleSelection || doneButton != null), - assert(menuConstraints == null || !dialogBox), + assert(menuConstraints == null || !(dialogBox ?? false)), super(key: key); SearchableDropdown({ - Key key, - @required this.items, - @required this.onChanged, + Key? key, + required this.items, + required this.onChanged, this.value, this.style, this.searchHint, @@ -359,7 +359,7 @@ class SearchableDropdown extends StatefulWidget { assert(iconSize != null), assert(isExpanded != null), assert(!multipleSelection || doneButton != null), - assert(menuConstraints == null || !dialogBox), + assert(menuConstraints == null || !(dialogBox ?? false)), super(key: key); @override @@ -367,17 +367,17 @@ class SearchableDropdown extends StatefulWidget { } class _SearchableDropdownState extends State> { - List selectedItems; + List? selectedItems; PointerThisPlease displayMenu = PointerThisPlease(false); TextStyle get _textStyle => widget.style ?? (_enabled && !(widget.readOnly ?? false) - ? Theme.of(context).textTheme.subhead + ? Theme.of(context).textTheme.subtitle1 : Theme.of(context) .textTheme - .subhead - .copyWith(color: _disabledIconColor)); + .subtitle1 + ?.copyWith(color: _disabledIconColor))!; bool get _enabled => widget.items != null && widget.items.isNotEmpty && @@ -385,28 +385,32 @@ class _SearchableDropdownState extends State> { Color get _enabledIconColor { if (widget.iconEnabledColor != null) { - return widget.iconEnabledColor; + return widget.iconEnabledColor!; } switch (Theme.of(context).brightness) { case Brightness.light: return Colors.grey.shade700; case Brightness.dark: return Colors.white70; + + default: + return Colors.grey.shade700; } - return Colors.grey.shade700; } Color get _disabledIconColor { if (widget.iconDisabledColor != null) { - return widget.iconDisabledColor; + return widget.iconDisabledColor!; } switch (Theme.of(context).brightness) { case Brightness.light: return Colors.grey.shade400; case Brightness.dark: return Colors.white10; + + default: + return Colors.grey.shade400; } - return Colors.grey.shade400; } Color get _iconColor { @@ -420,18 +424,18 @@ class _SearchableDropdownState extends State> { if (widget.validator == null) { return (true); } - return (widget.validator(selectedResult) == null); + return (widget.validator!(selectedResult) == null); } bool get hasSelection { - return (selectedItems != null && selectedItems.isNotEmpty); + return (selectedItems != null && selectedItems!.isNotEmpty); } dynamic get selectedResult { return (widget.multipleSelection ? selectedItems : selectedItems?.isNotEmpty ?? false - ? widget.items[selectedItems.first]?.value + ? widget.items[selectedItems!.first].value : null); } @@ -454,7 +458,7 @@ class _SearchableDropdownState extends State> { if (widget.multipleSelection) { selectedItems = List.from(widget.selectedItems ?? []); } else if (widget.value != null) { - int i = indexFromValue(widget.value); + int i = indexFromValue(widget.value!); if (i != null && i != -1) { selectedItems = [i]; } @@ -463,7 +467,7 @@ class _SearchableDropdownState extends State> { } @override - void didUpdateWidget(SearchableDropdown oldWidget) { + void didUpdateWidget(SearchableDropdown oldWidget) { super.didUpdateWidget(oldWidget); _updateSelectedIndex(); } @@ -486,10 +490,10 @@ class _SearchableDropdownState extends State> { menuConstraints: widget.menuConstraints, menuBackgroundColor: widget.menuBackgroundColor, callOnPop: () { - if (!widget.dialogBox && + if (!(widget.dialogBox ?? false) && widget.onChanged != null && selectedItems != null) { - widget.onChanged(selectedResult); + widget.onChanged!(selectedResult); } setState(() {}); }, @@ -500,14 +504,14 @@ class _SearchableDropdownState extends State> { Widget build(BuildContext context) { final List items = _enabled ? List.from(widget.items) : []; - int hintIndex; + int? hintIndex; if (widget.hint != null || (!_enabled && prepareWidget(widget.disabledHint) != null)) { final Widget emplacedHint = _enabled - ? prepareWidget(widget.hint) + ? prepareWidget(widget.hint)! : DropdownMenuItem( child: prepareWidget(widget.disabledHint) ?? - prepareWidget(widget.hint)); + prepareWidget(widget.hint)!); hintIndex = items.length; items.add(DefaultTextStyle( style: _textStyle.copyWith(color: Theme.of(context).hintColor), @@ -518,10 +522,10 @@ class _SearchableDropdownState extends State> { )); } Widget innerItemsWidget; - List list = List(); + List list = []; selectedItems?.forEach((item) { list.add(widget.selectedValueWidgetFn != null - ? widget.selectedValueWidgetFn(widget.items[item].value) + ? widget.selectedValueWidgetFn!(widget.items[item].value) : items[item]); }); if (list.isEmpty && hintIndex != null) { @@ -541,7 +545,7 @@ class _SearchableDropdownState extends State> { onTap: (widget.readOnly ?? false) || !_enabled ? null : () async { - if (widget.dialogBox) { + if (widget.dialogBox ?? false) { await showDialog( context: context, barrierDismissible: true, @@ -549,7 +553,7 @@ class _SearchableDropdownState extends State> { return (menuWidget); }); if (widget.onChanged != null && selectedItems != null) { - widget.onChanged(selectedResult); + widget.onChanged!(selectedResult); } } else { displayMenu.value = true; @@ -584,11 +588,12 @@ class _SearchableDropdownState extends State> { !widget.displayClearIcon ? SizedBox() : InkWell( - onTap: hasSelection && _enabled && !widget.readOnly - ? () { - clearSelection(); - } - : null, + onTap: + hasSelection && _enabled && !(widget.readOnly ?? false) + ? () { + clearSelection(); + } + : null, child: Container( padding: padding.resolve(Directionality.of(context)), child: Row( @@ -597,10 +602,11 @@ class _SearchableDropdownState extends State> { children: [ IconTheme( data: IconThemeData( - color: - hasSelection && _enabled && !widget.readOnly - ? _enabledIconColor - : _disabledIconColor, + color: hasSelection && + _enabled && + !(widget.readOnly ?? false) + ? _enabledIconColor + : _disabledIconColor, size: widget.iconSize, ), child: widget.clearIcon ?? Icon(Icons.clear), @@ -617,7 +623,7 @@ class _SearchableDropdownState extends State> { final double bottom = 8.0; var validatorOutput; if (widget.validator != null) { - validatorOutput = widget.validator(selectedResult); + validatorOutput = widget.validator!(selectedResult); } var labelOutput = prepareWidget(widget.label, parameter: selectedResult, stringToWidgetFunction: (string) { @@ -669,12 +675,12 @@ class _SearchableDropdownState extends State> { } clearSelection() { - selectedItems.clear(); + selectedItems?.clear(); if (widget.onChanged != null) { - widget.onChanged(selectedResult); + widget.onChanged!(selectedResult); } if (widget.onClear != null) { - widget.onClear(); + widget.onClear!(); } setState(() {}); } @@ -682,25 +688,25 @@ class _SearchableDropdownState extends State> { class DropdownDialog extends StatefulWidget { final List> items; - final Widget hint; + final Widget? hint; final bool isCaseSensitiveSearch; final dynamic closeButton; - final TextInputType keyboardType; - final Function searchFn; - final bool multipleSelection; - final List selectedItems; - final Function displayItem; + final TextInputType? keyboardType; + final Function? searchFn; + final bool? multipleSelection; + final List? selectedItems; + final Function? displayItem; final dynamic doneButton; - final Function validator; - final bool dialogBox; - final PointerThisPlease displayMenu; - final BoxConstraints menuConstraints; - final Function callOnPop; - final Color menuBackgroundColor; + final Function? validator; + final bool? dialogBox; + final PointerThisPlease? displayMenu; + final BoxConstraints? menuConstraints; + final Function? callOnPop; + final Color? menuBackgroundColor; DropdownDialog({ - Key key, - this.items, + Key? key, + required this.items, this.hint, this.isCaseSensitiveSearch = false, this.closeButton, @@ -727,20 +733,20 @@ class _DropdownDialogState extends State { TextStyle defaultButtonStyle = new TextStyle(fontSize: 16, fontWeight: FontWeight.w500); List shownIndexes = []; - Function searchFn; + Function? searchFn; _DropdownDialogState(); dynamic get selectedResult { - return (widget.multipleSelection + return (widget.multipleSelection ?? false ? widget.selectedItems : widget.selectedItems?.isNotEmpty ?? false - ? widget.items[widget.selectedItems.first]?.value + ? widget.items[widget.selectedItems!.first].value : null); } void _updateShownIndexes(String keyword) { - shownIndexes = searchFn(keyword, widget.items); + shownIndexes = searchFn!(keyword, widget.items); } @override @@ -786,8 +792,8 @@ class _DropdownDialogState extends State { child: new Card( color: widget.menuBackgroundColor, margin: EdgeInsets.symmetric( - vertical: widget.dialogBox ? 10 : 5, - horizontal: widget.dialogBox ? 10 : 4), + vertical: widget.dialogBox ?? false ? 10 : 5, + horizontal: widget.dialogBox ?? false ? 10 : 4), child: new Container( constraints: widget.menuConstraints, padding: EdgeInsets.symmetric(vertical: 15, horizontal: 15), @@ -811,13 +817,13 @@ class _DropdownDialogState extends State { if (widget.validator == null) { return (true); } - return (widget.validator(selectedResult) == null); + return (widget.validator!(selectedResult) == null); } Widget titleBar() { var validatorOutput; if (widget.validator != null) { - validatorOutput = widget.validator(selectedResult); + validatorOutput = widget.validator!(selectedResult); } Widget validatorOutputWidget = valid @@ -830,20 +836,24 @@ class _DropdownDialogState extends State { : validatorOutput; Widget doneButtonWidget = - widget.multipleSelection || widget.doneButton != null + widget.multipleSelection ?? false || widget.doneButton != null ? prepareWidget(widget.doneButton, parameter: selectedResult, context: context, stringToWidgetFunction: (string) { - return (FlatButton.icon( + return (ElevatedButton( onPressed: !valid ? null : () { pop(); setState(() {}); }, - icon: Icon(Icons.close), - label: Text(string))); - }) + child: Row( + children: [ + Icon(Icons.close), + Text(string), + ], + ))); + })! : SizedBox.shrink(); return widget.hint != null ? new Container( @@ -851,7 +861,7 @@ class _DropdownDialogState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - prepareWidget(widget.hint), + prepareWidget(widget.hint)!, Column( children: [doneButtonWidget, validatorOutputWidget], ), @@ -925,12 +935,12 @@ class _DropdownDialogState extends State { } pop() { - if (widget.dialogBox) { + if (widget.dialogBox ?? false) { Navigator.pop(context); } else { - widget.displayMenu.value = false; + widget.displayMenu?.value = false; if (widget.callOnPop != null) { - widget.callOnPop(); + widget.callOnPop!(); } } } @@ -943,17 +953,18 @@ class _DropdownDialogState extends State { DropdownMenuItem item = widget.items[shownIndexes[index]]; return new InkWell( onTap: () { - if (widget.multipleSelection) { + if (widget.multipleSelection ?? false) { setState(() { - if (widget.selectedItems.contains(shownIndexes[index])) { - widget.selectedItems.remove(shownIndexes[index]); + if (widget.selectedItems?.contains(shownIndexes[index]) ?? + false) { + widget.selectedItems?.remove(shownIndexes[index]); } else { - widget.selectedItems.add(shownIndexes[index]); + widget.selectedItems?.add(shownIndexes[index]); } }); } else { - widget.selectedItems.clear(); - widget.selectedItems.add(shownIndexes[index]); + widget.selectedItems?.clear(); + widget.selectedItems?.add(shownIndexes[index]); if (widget.doneButton == null) { pop(); } else { @@ -961,11 +972,13 @@ class _DropdownDialogState extends State { } } }, - child: widget.multipleSelection + child: widget.multipleSelection ?? false ? widget.displayItem == null ? (Row(children: [ Icon( - widget.selectedItems.contains(shownIndexes[index]) + widget.selectedItems + ?.contains(shownIndexes[index]) ?? + false ? Icons.check_box : Icons.check_box_outline_blank, ), @@ -974,11 +987,11 @@ class _DropdownDialogState extends State { ), Flexible(child: item), ])) - : widget.displayItem(item, - widget.selectedItems.contains(shownIndexes[index])) + : widget.displayItem!(item, + widget.selectedItems?.contains(shownIndexes[index])) : widget.displayItem == null ? item - : widget.displayItem(item, item.value == selectedResult), + : widget.displayItem!(item, item.value == selectedResult), ); }, itemCount: shownIndexes.length, @@ -995,7 +1008,7 @@ class _DropdownDialogState extends State { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.end, children: [ - FlatButton( + ElevatedButton( onPressed: () { pop(); }, diff --git a/pubspec.lock b/pubspec.lock index 67a7df1..de6ee41 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,62 +1,55 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.2" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "2.7.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" - collection: + version: "1.3.1" + clock: dependency: transitive description: - name: collection + name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" - convert: + version: "1.1.0" + collection: dependency: transitive description: - name: convert + name: collection url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" - crypto: + version: "1.15.0" + fake_async: dependency: transitive description: - name: crypto + name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "1.2.0" flutter: dependency: "direct main" description: flutter @@ -67,55 +60,27 @@ packages: description: flutter source: sdk version: "0.0.0" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.7.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" + version: "1.8.0" sky_engine: dependency: transitive description: flutter @@ -127,62 +92,55 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.8.1" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.11" + version: "0.4.2" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.5.0" + version: "2.1.0" sdks: - dart: ">=2.4.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3565d75..a2c0073 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,7 +6,7 @@ repository: https://github.com/icemanbsi/searchable_dropdown issue_tracker: https://github.com/icemanbsi/searchable_dropdown/issues environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: diff --git a/test/searchable_dropdown_test.dart b/test/searchable_dropdown_test.dart index 0b96a8d..4d1c04b 100644 --- a/test/searchable_dropdown_test.dart +++ b/test/searchable_dropdown_test.dart @@ -26,7 +26,7 @@ class ExampleNumber { }; String get numberString { - return (map.containsKey(number) ? map[number] : "unknown"); + return (map.containsKey(number) ? map[number] : "unknown") ?? ''; } ExampleNumber(this.number); @@ -46,7 +46,7 @@ void main() { testWidgets( 'single dialog open dialog, search keyword, select single value, clear', (WidgetTester tester) async { - String selectedValue; + String? selectedValue; String searchKeyword = "4"; List items = []; for (int i = 0; i < 20; i++) { @@ -93,7 +93,7 @@ void main() { final listViewFinder = find.byType(ListView); expect(listViewFinder, findsNWidgets(1), reason: "List of items displayed"); - ListView listView = tester.element(listViewFinder).widget; + ListView listView = tester.element(listViewFinder).widget as ListView; final textFieldFinder = find.byType(TextField); expect(textFieldFinder, findsNWidgets(1), reason: "Search field displayed"); @@ -101,7 +101,7 @@ void main() { reason: "List of items is complete"); await tester.enterText(textFieldFinder, searchKeyword); await tester.pump(); - listView = tester.element(listViewFinder).widget; + listView = tester.element(listViewFinder).widget as ListView; int expectedNbResults = items.where((it) { return (it.value.toString().contains(searchKeyword)); }).length; @@ -142,7 +142,7 @@ void main() { testWidgets( 'single menu open menu, search keyword, select single value, clear', (WidgetTester tester) async { - String selectedValue; + String? selectedValue; String searchKeyword = "4"; List items = []; for (int i = 0; i < 20; i++) { @@ -191,7 +191,7 @@ void main() { final listViewFinder = find.byType(ListView); expect(listViewFinder, findsNWidgets(1), reason: "List of items displayed"); - ListView listView = tester.element(listViewFinder).widget; + ListView listView = tester.element(listViewFinder).widget as ListView; final textFieldFinder = find.byType(TextField); expect(textFieldFinder, findsNWidgets(1), reason: "Search field displayed"); @@ -199,7 +199,7 @@ void main() { reason: "List of items is complete"); await tester.enterText(textFieldFinder, searchKeyword); await tester.pump(); - listView = tester.element(listViewFinder).widget; + listView = tester.element(listViewFinder).widget as ListView; int expectedNbResults = items.where((it) { return (it.value.toString().contains(searchKeyword)); }).length; @@ -240,7 +240,7 @@ void main() { testWidgets( 'single object dialog open dialog, search keyword, select single value, clear', (WidgetTester tester) async { - ExampleNumber selectedNumber; + ExampleNumber? selectedNumber; String searchKeyword = "4"; List items = ExampleNumber.list.map((exNum) { return (DropdownMenuItem( @@ -283,7 +283,7 @@ void main() { final listViewFinder = find.byType(ListView); expect(listViewFinder, findsNWidgets(1), reason: "List of items displayed"); - ListView listView = tester.element(listViewFinder).widget; + ListView listView = tester.element(listViewFinder).widget as ListView; final textFieldFinder = find.byType(TextField); expect(textFieldFinder, findsNWidgets(1), reason: "Search field displayed"); @@ -291,7 +291,7 @@ void main() { reason: "List of items is complete"); await tester.enterText(textFieldFinder, searchKeyword); await tester.pump(); - listView = tester.element(listViewFinder).widget; + listView = tester.element(listViewFinder).widget as ListView; int expectedNbResults = items.where((it) { return (it.value.toString().contains(searchKeyword)); }).length; @@ -331,7 +331,7 @@ void main() { 'single dialog text no overflow because expanded', (WidgetTester tester) async { String searchKeyword = "at"; - String selectedValue; + String? selectedValue; List items = [ DropdownMenuItem( child: Text( @@ -374,7 +374,7 @@ void main() { final listViewFinder = find.byType(ListView); expect(listViewFinder, findsNWidgets(1), reason: "List of items displayed"); - ListView listView = tester.element(listViewFinder).widget; + ListView listView = tester.element(listViewFinder).widget as ListView; final textFieldFinder = find.byType(TextField); expect(textFieldFinder, findsNWidgets(1), reason: "Search field displayed"); @@ -382,7 +382,7 @@ void main() { reason: "List of items is complete"); await tester.enterText(textFieldFinder, searchKeyword); await tester.pump(); - listView = tester.element(listViewFinder).widget; + listView = tester.element(listViewFinder).widget as ListView; int expectedNbResults = items.where((it) { return (it.value.toString().contains(searchKeyword)); }).length; @@ -423,7 +423,7 @@ void main() { testWidgets( 'multi dialog open dialog, search keyword, select multiple values, clear', (WidgetTester tester) async { - List selectedItems = []; + List? selectedItems = []; String searchKeyword = "4"; List items = []; for (int i = 0; i < 20; i++) { @@ -470,7 +470,7 @@ void main() { final listViewFinder = find.byType(ListView); expect(listViewFinder, findsNWidgets(1), reason: "List of items displayed"); - ListView listView = tester.element(listViewFinder).widget; + ListView listView = tester.element(listViewFinder).widget as ListView; final textFieldFinder = find.byType(TextField); expect(textFieldFinder, findsNWidgets(1), reason: "Search field displayed"); @@ -478,7 +478,7 @@ void main() { reason: "List of items is complete"); await tester.enterText(textFieldFinder, searchKeyword); await tester.pump(); - listView = tester.element(listViewFinder).widget; + listView = tester.element(listViewFinder).widget as ListView; int expectedNbResults = items.where((it) { return (it.value.toString().contains(searchKeyword)); }).length; @@ -499,7 +499,7 @@ void main() { } } await tester.pump(); - final doneButtonFinder = find.widgetWithText(FlatButton, "Close"); + final doneButtonFinder = find.widgetWithText(ElevatedButton, "Close"); expect(doneButtonFinder, findsNWidgets(1), reason: "Done button"); await tester.tap(doneButtonFinder); await tester.pump();