import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../core/constants/translation_keys.dart'; import '../../res/app_colors.dart'; import '../custom_dropdown.dart'; import '../custom_text.dart'; import 'input_field.dart'; class CustomDropDownBottomSheet { void showBottomSheet(BuildContext context, List options, String type, Function(DropDown)? onItemSelected) { Get.bottomSheet( Container( decoration: BoxDecoration( color: Colors.white, border: Border.all(color: AppColors.colorGrey500, width: 1), borderRadius: BorderRadius.only( topLeft: Radius.circular(30), topRight: Radius.circular(30))), margin: EdgeInsets.only(left: 20, right: 20), child: DialogDesign(options, type, (selectedOption) { if (onItemSelected != null) { onItemSelected(selectedOption); } }), ), backgroundColor: Colors.transparent, isScrollControlled: true, shape: RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(10), topRight: Radius.circular(10))), ); } } @immutable class DialogDesign extends StatelessWidget { List options = []; String type = ""; Function(DropDown) onSelect; DialogDesign(this.options, this.type, this.onSelect); @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(16.0), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Visibility( visible: type == DropDownType.NORMAL, child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( TranslationKeys.makeTranslation( TranslationKeys.textSelectOption), style: Theme.of(context).textTheme.titleLarge?.copyWith( color: AppColors.colorGrey700, fontSize: 16, fontWeight: FontWeight.w600), ), InkWell( onTap: () { Get.back(); }, child: CircleAvatar( radius: 15, backgroundColor: Colors.transparent, child: Icon(Icons.close, size: 20.0, color: Colors.blue)), ), ], ), SizedBox(height: 10.0), ], )), FilterableBottomSheet( options: options, type: type, onSelect: onSelect), ], ), ); } } class FilterableBottomSheet extends StatefulWidget { final List options; final String type; final Function(DropDown) onSelect; FilterableBottomSheet( {required this.options, required this.onSelect, required this.type}); @override _FilterableBottomSheetState createState() => _FilterableBottomSheetState(); } class _FilterableBottomSheetState extends State { TextEditingController _filterTextController = TextEditingController(); List _filteredOptions = []; @override void initState() { super.initState(); _filteredOptions.addAll(widget.options); } void _updateFilteredList(String query) { setState(() { _filteredOptions.clear(); if (query.isEmpty) { _filteredOptions.addAll(widget.options); } else { query = query.toLowerCase(); _filteredOptions.addAll(widget.options .where((item) => item.label.toLowerCase().contains(query))); } }); } @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(10.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Visibility( visible: widget.type == DropDownType.NORMAL, child: Column( children: [ Container( height: 40, padding: EdgeInsets.symmetric(horizontal: 15.0), decoration: BoxDecoration( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(20.0), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.search, size: 20, color: AppColors.colorGrey700), SizedBox(width: 5.0), Expanded( child: TextField( style: Theme.of(context) .textTheme .bodySmall ?.copyWith( fontWeight: FontWeight.w500, fontSize: 14), decoration: InputDecoration( enabledBorder: InputBorder.none, border: InputBorder.none, focusedBorder: InputBorder.none, hintText: TranslationKeys.makeTranslation( TranslationKeys.textSearch), ), controller: _filterTextController, onChanged: _updateFilteredList, ), ), ], ), ), SizedBox(height: 20.0), ], ), ), Container( height: _filteredOptions.length <= 5 ? (45 * _filteredOptions.length) + (10 * (_filteredOptions.length - 1)) : 300, child: ListView.separated( shrinkWrap: true, physics: const BouncingScrollPhysics(), itemCount: _filteredOptions.length, itemBuilder: (context, index) { return widget.type == DropDownType.SPECIAL ? InkWell( onTap: () { widget.onSelect(_filteredOptions[index]); Navigator.pop(context); }, child: Container( height: 45, decoration: BoxDecoration( color: AppColors.colorGrey100, borderRadius: BorderRadius.all(Radius.circular(10))), child: Padding( padding: EdgeInsets.all(12), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ CustomText(_filteredOptions[index].label, style: Theme.of(context) .textTheme .bodySmall! .copyWith( fontSize: 14, fontWeight: FontWeight.w500, color: AppColors.colorGrey700)), Icon(Icons.arrow_forward_ios, size: 14, color: AppColors.colorNavyBlue), ], ), ), ), ) : Padding( padding: EdgeInsets.only(top: 5, bottom: 5), child: InkWell( onTap: () { widget.onSelect(_filteredOptions[index]); Navigator.pop(context); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ CustomText(_filteredOptions[index].label, style: Theme.of(context) .textTheme .bodySmall! .copyWith( fontSize: 14, fontWeight: FontWeight.w500, color: AppColors.colorGrey700)), SizedBox(height: 5), Visibility( visible: _filteredOptions[index].id.isNotEmpty, child: Column( children: [ CustomText(_filteredOptions[index].id, style: Theme.of(context) .textTheme .bodySmall! .copyWith( fontSize: 12, fontWeight: FontWeight.w500, color: AppColors.colorGrey600)), ], ), ), SizedBox(height: 5), Divider( thickness: 0.2, color: AppColors.colorGrey600), ], ), ), ); }, separatorBuilder: (BuildContext context, int index) { return SizedBox(height: 10); }, ), ), ], ), ); } }