diff --git a/example/android/build.gradle b/example/android/build.gradle index 3100ad2..618be9d 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -26,6 +26,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 296b146..cfe88f6 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip diff --git a/example/lib/main.dart b/example/lib/main.dart index 104cb60..f241d82 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -24,14 +24,14 @@ class Animal { final String name; Animal({ - this.id, - this.name, + required this.id, + required this.name, }); } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); final String title; + MyHomePage({Key? key, required this.title}) : super(key: key); @override _MyHomePageState createState() => _MyHomePageState(); } @@ -99,6 +99,10 @@ class _MyHomePageState extends State { // Rounded blue MultiSelectDialogField //################################################################################################ MultiSelectDialogField( + chipDisplay: MultiSelectChipDisplay( + emptyItemWidget: Text("empty"), + hintWidget: Text("data"), + ), items: _items, title: Text("Animals"), selectedColor: Colors.blue, @@ -148,7 +152,7 @@ class _MyHomePageState extends State { title: Text("Animals"), items: _items, onConfirm: (values) { - _selectedAnimals2 = values; + _selectedAnimals2 = values as List; }, chipDisplay: MultiSelectChipDisplay( onTap: (value) { @@ -158,7 +162,7 @@ class _MyHomePageState extends State { }, ), ), - _selectedAnimals2 == null || _selectedAnimals2.isEmpty + _selectedAnimals2.isEmpty ? Container( padding: EdgeInsets.all(10), alignment: Alignment.centerLeft, @@ -196,14 +200,14 @@ class _MyHomePageState extends State { setState(() { _selectedAnimals3 = values; }); - _multiSelectKey.currentState.validate(); + _multiSelectKey.currentState!.validate(); }, chipDisplay: MultiSelectChipDisplay( onTap: (item) { setState(() { _selectedAnimals3.remove(item); }); - _multiSelectKey.currentState.validate(); + _multiSelectKey.currentState!.validate(); }, ), ), @@ -217,7 +221,7 @@ class _MyHomePageState extends State { title: Text("Animals"), headerColor: Colors.blue.withOpacity(0.5), decoration: BoxDecoration( - border: Border.all(color: Colors.blue[700], width: 1.8), + border: Border.all(color: Colors.blue[700]!, width: 1.8), ), selectedChipColor: Colors.blue.withOpacity(0.5), selectedTextStyle: TextStyle(color: Colors.blue[800]), @@ -231,7 +235,7 @@ class _MyHomePageState extends State { //################################################################################################ MultiSelectDialogField( onConfirm: (val) { - _selectedAnimals5 = val; + _selectedAnimals5 = val as List; }, dialogWidth: MediaQuery.of(context).size.width * 0.7, items: _items, diff --git a/example/pubspec.lock b/example/pubspec.lock index 76cd661..75c017f 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,49 +5,48 @@ packages: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + url: "https://pub.dev" source: hosted - version: "1.16.0" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" + version: "1.17.2" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted version: "1.3.1" flutter: @@ -64,23 +63,26 @@ packages: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + url: "https://pub.dev" source: hosted - version: "0.12.12" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.5.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" multi_select_flutter: dependency: "direct main" description: @@ -92,9 +94,10 @@ packages: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" sky_engine: dependency: transitive description: flutter @@ -104,50 +107,65 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + url: "https://pub.dev" source: hosted - version: "0.4.12" + version: "0.6.0" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + web: + dependency: transitive + description: + name: web + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "0.1.4-beta" sdks: - dart: ">=2.17.0-0 <3.0.0" + dart: ">=3.1.0 <4.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 24a1c77..4ac31ef 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -8,7 +8,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: '>=3.1.0 <4.0.0' dependencies: flutter: @@ -18,7 +18,6 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 dev_dependencies: flutter_test: diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 747db1d..6db856c 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:example/main.dart'; +import '../lib/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { diff --git a/lib/chip_display/multi_select_chip_display.dart b/lib/chip_display/multi_select_chip_display.dart index b5a3583..21226ce 100644 --- a/lib/chip_display/multi_select_chip_display.dart +++ b/lib/chip_display/multi_select_chip_display.dart @@ -46,6 +46,12 @@ class MultiSelectChipDisplay extends StatelessWidget { /// Set the width of the chips. final double? chipWidth; + /// Set the hint widget. + final Widget? hintWidget; + + /// Set the empty items hint. + final Widget? emptyItemWidget; + bool? disabled; MultiSelectChipDisplay({ @@ -62,6 +68,8 @@ class MultiSelectChipDisplay extends StatelessWidget { this.scrollBar, this.height, this.chipWidth, + this.hintWidget, + this.emptyItemWidget, }) { this.disabled = false; } @@ -81,48 +89,58 @@ class MultiSelectChipDisplay extends StatelessWidget { this.scrollBar, this.height, this.chipWidth, + this.hintWidget, + this.emptyItemWidget, }); @override Widget build(BuildContext context) { - if (items == null || items!.isEmpty) return Container(); - return Container( - decoration: decoration, - alignment: alignment ?? Alignment.centerLeft, - padding: EdgeInsets.symmetric(horizontal: scroll ? 0 : 10), - child: scroll - ? Container( - width: MediaQuery.of(context).size.width, - height: height ?? MediaQuery.of(context).size.height * 0.08, - child: scrollBar != null - ? Scrollbar( - thumbVisibility: scrollBar!.isAlwaysShown, - controller: _scrollController, - child: ListView.builder( - controller: _scrollController, - scrollDirection: Axis.horizontal, - itemCount: items!.length, - itemBuilder: (ctx, index) { - return _buildItem(items![index]!, context); - }, - ), - ) - : ListView.builder( - controller: _scrollController, - scrollDirection: Axis.horizontal, - itemCount: items!.length, - itemBuilder: (ctx, index) { - return _buildItem(items![index]!, context); - }, - ), - ) - : Wrap( - children: items != null - ? items!.map((item) => _buildItem(item!, context)).toList() - : [ - Container(), - ], - ), + if (items == null || items!.isEmpty) return emptyItemWidget ?? SizedBox(); + + return Column( + children: [ + hintWidget ?? Container(), + Container( + decoration: decoration, + alignment: alignment ?? Alignment.centerLeft, + padding: EdgeInsets.symmetric(horizontal: scroll ? 0 : 10), + child: scroll + ? Container( + width: MediaQuery.of(context).size.width, + height: height ?? MediaQuery.of(context).size.height * 0.08, + child: scrollBar != null + ? Scrollbar( + thumbVisibility: scrollBar!.isAlwaysShown, + controller: _scrollController, + child: ListView.builder( + controller: _scrollController, + scrollDirection: Axis.horizontal, + itemCount: items!.length, + itemBuilder: (ctx, index) { + return _buildItem(items![index]!, context); + }, + ), + ) + : ListView.builder( + controller: _scrollController, + scrollDirection: Axis.horizontal, + itemCount: items!.length, + itemBuilder: (ctx, index) { + return _buildItem(items![index]!, context); + }, + ), + ) + : Wrap( + children: items != null + ? items! + .map((item) => _buildItem(item!, context)) + .toList() + : [ + Container(), + ], + ), + ), + ], ); } diff --git a/lib/dialog/mult_select_dialog.dart b/lib/dialog/mult_select_dialog.dart index 433539f..a64806e 100644 --- a/lib/dialog/mult_select_dialog.dart +++ b/lib/dialog/mult_select_dialog.dart @@ -7,7 +7,6 @@ import '../util/multi_select_list_type.dart'; class MultiSelectDialog extends StatefulWidget with MultiSelectActions { /// List of items to select from. final List> items; - /// The list of selected values before interaction. final List initialValue; diff --git a/lib/dialog/multi_select_dialog_field.dart b/lib/dialog/multi_select_dialog_field.dart index b229a4d..550981f 100644 --- a/lib/dialog/multi_select_dialog_field.dart +++ b/lib/dialog/multi_select_dialog_field.dart @@ -181,7 +181,10 @@ class MultiSelectDialogField extends FormField> { checkColor: checkColor, isDismissible: isDismissible, ); - return _MultiSelectDialogFieldView._withState(field, state); + return _MultiSelectDialogFieldView._withState( + field, + state, + ); }); } @@ -219,6 +222,9 @@ class _MultiSelectDialogFieldView extends StatefulWidget { final bool isDismissible; FormFieldState>? state; + /// Color of the items once selected + final Color? selectedItemBackground; + _MultiSelectDialogFieldView({ required this.items, this.title, @@ -244,6 +250,7 @@ class _MultiSelectDialogFieldView extends StatefulWidget { this.searchIcon, this.closeSearchIcon, this.itemsTextStyle, + this.selectedItemBackground, this.searchTextStyle, this.searchHintStyle, this.selectedItemsTextStyle, @@ -254,10 +261,12 @@ class _MultiSelectDialogFieldView extends StatefulWidget { /// This constructor allows a FormFieldState to be passed in. Called by MultiSelectDialogField. _MultiSelectDialogFieldView._withState( - _MultiSelectDialogFieldView field, FormFieldState> state) - : items = field.items, + _MultiSelectDialogFieldView field, + FormFieldState> state, + ) : items = field.items, title = field.title, buttonText = field.buttonText, + this.selectedItemBackground = field.selectedItemBackground, buttonIcon = field.buttonIcon, listType = field.listType, decoration = field.decoration, @@ -329,6 +338,8 @@ class __MultiSelectDialogFieldViewState return Container(); } else { return MultiSelectChipDisplay( + emptyItemWidget: widget.chipDisplay!.emptyItemWidget, + hintWidget: widget.chipDisplay!.hintWidget, items: chipDisplayItems, colorator: widget.chipDisplay!.colorator ?? widget.colorator, onTap: (item) { @@ -345,7 +356,8 @@ class __MultiSelectDialogFieldViewState } }, decoration: widget.chipDisplay!.decoration, - chipColor: widget.chipDisplay!.chipColor ?? + chipColor: widget.selectedItemBackground ?? + widget.chipDisplay!.chipColor ?? ((widget.selectedColor != null && widget.selectedColor != Colors.transparent) ? widget.selectedColor!.withOpacity(0.35) @@ -363,12 +375,15 @@ class __MultiSelectDialogFieldViewState } else { // user didn't specify a chipDisplay, build the default return MultiSelectChipDisplay( + emptyItemWidget: Container(), + hintWidget: Container(), items: chipDisplayItems, colorator: widget.colorator, - chipColor: (widget.selectedColor != null && - widget.selectedColor != Colors.transparent) - ? widget.selectedColor!.withOpacity(0.35) - : null, + chipColor: widget.selectedItemBackground ?? + ((widget.selectedColor != null && + widget.selectedColor != Colors.transparent) + ? widget.selectedColor!.withOpacity(0.35) + : null), ); } } diff --git a/pubspec.lock b/pubspec.lock index 8a01ee3..f68e0fe 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,42 +5,48 @@ packages: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted version: "1.1.1" collection: dependency: "direct main" description: name: collection - url: "https://pub.dartlang.org" + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.2" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted version: "1.3.1" flutter: @@ -57,30 +63,34 @@ packages: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + url: "https://pub.dev" source: hosted - version: "0.12.12" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.5.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" sky_engine: dependency: transitive description: flutter @@ -90,50 +100,65 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + url: "https://pub.dev" source: hosted - version: "0.4.12" + version: "0.6.0" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + web: + dependency: transitive + description: + name: web + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "0.1.4-beta" sdks: - dart: ">=2.17.0-0 <3.0.0" + dart: ">=3.1.0-185.0.dev <4.0.0"