diff --git a/lib/src/Selectors/selectors.astromic.dart b/lib/src/Selectors/selectors.astromic.dart index dca4e32..a05f684 100644 --- a/lib/src/Selectors/selectors.astromic.dart +++ b/lib/src/Selectors/selectors.astromic.dart @@ -37,6 +37,7 @@ class AstromicSelectors { void Function(List selectedItems)? onChanged, // AstromicSelectorConfiguration? configuration, + bool isCustom = false, // double? itemSpacing = 4, double? runSpacing = 8, @@ -49,18 +50,36 @@ class AstromicSelectors { required List<(T item, bool isEnabled)> items, required Widget Function(T item, {bool isSelected, VoidCallback? onTap, VoidCallback? onClearTapped}) itemBuilder, required Widget Function(T item) disabledItemBuilder, - }) => - AstromicChipSelector( - initialSelectedValues: initialSelectedValues, - onChanged: onChanged, - // - configuration: configuration, - // - itemSpacing: itemSpacing, - runSpacing: runSpacing, - // - items: items, - itemBuilder: itemBuilder, - disabledItemBuilder: disabledItemBuilder, - ); + Widget Function(List items)? groupBuilder, + }) { + assert( + (!isCustom || groupBuilder != null), + "You have to provide the group builder in a custom constructor.", + ); + return isCustom + ? AstromicChipSelector.custom( + initialSelectedValues: initialSelectedValues, + onChanged: onChanged, + // + configuration: configuration, + // + items: items, + itemBuilder: itemBuilder, + disabledItemBuilder: disabledItemBuilder, + groupBuilder: groupBuilder!, + ) + : AstromicChipSelector( + initialSelectedValues: initialSelectedValues, + onChanged: onChanged, + // + configuration: configuration, + // + itemSpacing: itemSpacing, + runSpacing: runSpacing, + // + items: items, + itemBuilder: itemBuilder, + disabledItemBuilder: disabledItemBuilder, + ); + } } diff --git a/lib/src/Selectors/src/chip.selector.dart b/lib/src/Selectors/src/chip.selector.dart index d6adba4..9ca01de 100644 --- a/lib/src/Selectors/src/chip.selector.dart +++ b/lib/src/Selectors/src/chip.selector.dart @@ -25,6 +25,7 @@ class AstromicChipSelector extends StatefulWidget { final List? initialSelectedValues; final Function(List selectedItems)? onChanged; //s1 -- Configuration + final bool isCustom; final AstromicSelectorConfiguration? configuration; //s1 -- Style final double? itemSpacing; @@ -35,6 +36,7 @@ class AstromicChipSelector extends StatefulWidget { // final Widget Function(T item, {bool isSelected, VoidCallback? onTap, VoidCallback? onClearTapped}) itemBuilder; final Widget Function(T item) disabledItemBuilder; + final Widget Function(List items)? groupBuilder; //!SECTION // AstromicChipSelector({ @@ -44,6 +46,7 @@ class AstromicChipSelector extends StatefulWidget { this.onChanged, //s1 -- Configuration this.configuration, + this.isCustom = false, //s1 -- Style this.itemSpacing = 8, this.runSpacing = 8, @@ -51,14 +54,53 @@ class AstromicChipSelector extends StatefulWidget { required this.items, required this.itemBuilder, required this.disabledItemBuilder, + this.groupBuilder, }) : assert( (configuration?.isNullable ?? true) || (initialSelectedValues != null && items.map((i) => i.$1).toList().containsAll(initialSelectedValues)), "Initial values are not all present in the items!", ), + assert( + (!isCustom || groupBuilder != null), + "You have to provide the group builder in a custom constructor.", + ), super( key: key, ); + static AstromicChipSelector custom({ + Key? key, + //s1 -- Functionality + final List? initialSelectedValues, + final Function(List selectedItems)? onChanged, + //s1 -- Configuration + final AstromicSelectorConfiguration? configuration, + //s1 -- Content + required final List<(T item, bool isEnabled)> items, + // + required final Widget Function(T item, {bool isSelected, VoidCallback? onTap, VoidCallback? onClearTapped}) itemBuilder, + required final Widget Function(T item) disabledItemBuilder, + required final Widget Function(List items) groupBuilder, + }) { + assert((configuration?.isNullable ?? true) || (initialSelectedValues != null && items.map((i) => i.$1).toList().containsAll(initialSelectedValues)), + "Initial values are not all present in the items!"); + + // + return AstromicChipSelector( + key: key, + isCustom: true, + // + initialSelectedValues: initialSelectedValues, + onChanged: onChanged, + // + configuration: configuration, + // + items: items, + itemBuilder: itemBuilder, + disabledItemBuilder: disabledItemBuilder, + groupBuilder: groupBuilder, + ); + } + @override State> createState() => _AstromicChipSelectorState(); } @@ -172,34 +214,36 @@ class _AstromicChipSelectorState extends State> { //!SECTION //SECTION - Build Return - return _configuration.isWrap - ? Wrap( - spacing: widget.itemSpacing!, - runSpacing: widget.runSpacing!, - // - alignment: _configuration.wrapMainAllignment, - crossAxisAlignment: _configuration.wrapCrossAllignment, - // - children: baseChildren, - ) - : GridView.builder( - physics: const NeverScrollableScrollPhysics(), - controller: _scrollController, - shrinkWrap: true, - padding: EdgeInsets.zero, - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - mainAxisExtent: _configuration.fixedRowHeight, - // number of items per row - crossAxisCount: widget.configuration?.crossAxisCount ?? 1, - // vertical spacing between the items - mainAxisSpacing: widget.runSpacing!, - // the horizontal spacing between the items - crossAxisSpacing: widget.itemSpacing!, - ), - // number of items in your list - itemCount: baseChildren.length, - itemBuilder: (BuildContext context, int index) => baseChildren[index], - ); + return widget.isCustom && widget.groupBuilder != null + ? widget.groupBuilder!(baseChildren) + : _configuration.isWrap + ? Wrap( + spacing: widget.itemSpacing!, + runSpacing: widget.runSpacing!, + // + alignment: _configuration.wrapMainAllignment, + crossAxisAlignment: _configuration.wrapCrossAllignment, + // + children: baseChildren, + ) + : GridView.builder( + physics: const NeverScrollableScrollPhysics(), + controller: _scrollController, + shrinkWrap: true, + padding: EdgeInsets.zero, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + mainAxisExtent: _configuration.fixedRowHeight, + // number of items per row + crossAxisCount: widget.configuration?.crossAxisCount ?? 1, + // vertical spacing between the items + mainAxisSpacing: widget.runSpacing!, + // the horizontal spacing between the items + crossAxisSpacing: widget.itemSpacing!, + ), + // number of items in your list + itemCount: baseChildren.length, + itemBuilder: (BuildContext context, int index) => baseChildren[index], + ); //!SECTION }