import 'dart:collection'; import 'package:flutter/material.dart'; Future> openMultiSelectOptions( BuildContext context, { required String label, bool allowMultiSelection = false, bool forceAtleastOne = true, required List selected, required List items, Function(List values)? onChanged, required Widget Function(T type, bool selected, Function onTap) itemBuilder, }) async { Set currentSelection = selected.toSet(); await showDialog( context: context, builder: (context) => StatefulBuilder( builder: (context, setState) => AlertDialog( title: Text(label), content: SizedBox( width: MediaQuery.of(context).size.width * 0.85, child: ListView( physics: const AlwaysScrollableScrollPhysics(), shrinkWrap: true, children: items.map((item) { bool isSelected = currentSelection.contains(item); return itemBuilder( item, isSelected, () { setState(() { if (allowMultiSelection) { if (isSelected) { if (!forceAtleastOne || currentSelection.length > 1) { currentSelection.remove(item); } } else { currentSelection.add(item); } } else { currentSelection = {item}; } }); currentSelection = SplayTreeSet.of( currentSelection, (a, b) => items.indexOf(a).compareTo(items.indexOf(b)), ); onChanged?.call(currentSelection.toList()); }, ); }).toList(), ), ), ), ), ); return currentSelection.toList(); }