import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../core/constants/translation_keys.dart'; import '../res/app_colors.dart'; class OptionData { String label = ""; String code = ""; Object dataObject = {}; OptionData(); OptionData.withData(this.label, this.code, this.dataObject); factory OptionData.fromJson(Map json) { return OptionData.withData( json['label'] ?? "", json['code'] ?? "", json['dataObject'], ); } Map toJson() { return { 'label': label, 'code': code, 'dataObject': dataObject, }; } @override String toString() { return 'OptionData{label: $label, code: $code, dataObject: $dataObject}'; } } class FilterableBottomSheet extends StatefulWidget { final List options; final Function(OptionData) onSelect; FilterableBottomSheet({required this.options, required this.onSelect}); @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(1.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 40, padding: EdgeInsets.symmetric(horizontal: 12.0), decoration: BoxDecoration( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(20.0), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon( Icons.search, size: 15.0, color: Colors.grey[800], ), SizedBox(width: 5.0), Expanded( child: TextField( style: Theme.of(context) .textTheme .bodySmall ?.copyWith(fontWeight: FontWeight.w400, fontSize: 12), 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: 300, child: ListView.builder( physics: const BouncingScrollPhysics(), itemCount: _filteredOptions.length, itemBuilder: (context, index) { return Padding( padding: EdgeInsets.only(top: 5, bottom: 5), child: InkWell( onTap: () { widget.onSelect(_filteredOptions[index]); Navigator.pop(context); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(_filteredOptions[index].label, style: Theme.of(context) .textTheme .titleSmall ?.copyWith(fontSize: 12)), SizedBox(height: 5), Visibility( visible: _filteredOptions[index].code.isNotEmpty, child: Column( children: [ Text(_filteredOptions[index].code, style: Theme.of(context) .textTheme .bodySmall ?.copyWith(fontSize: 10)), ], ), ), SizedBox(height: 5), Divider(thickness: 0.2, color: AppColors.colorText), ], ), ), ); }, ), ), ], ), ); } } class DialogDesign extends StatelessWidget { List options = []; Function(OptionData) onSelect; DialogDesign(this.options, this.onSelect); @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(16.0), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( TranslationKeys.makeTranslation( TranslationKeys.textSelectYourOption), style: Theme.of(context).textTheme.titleLarge?.copyWith( color: AppColors.titleColor, fontSize: 12, fontWeight: FontWeight.w600), ), InkWell( onTap: () { Get.back(); // Close the bottom sheet using Get }, child: CircleAvatar( radius: 12.5, backgroundColor: Colors.transparent, child: Icon( Icons.close, size: 16.0, color: Colors.blue, ), ), ), ], ), SizedBox(height: 10.0), FilterableBottomSheet(options: options, onSelect: onSelect), ], ), ); } }