import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import '../../../themes/app_dimension.dart'; import '../../../models/item_dropdown.dart'; import '../../../themes/app_colors.dart'; import '../../../themes/styles_text.dart'; import '../../../utils/app_images.dart'; import '../../../utils/validators.dart'; class DropdownBottomSheet extends StatefulWidget { final String? initValue; final List dataSources; final Function(ItemDropDown) onSelected; final Color? borderColor; final String hint; final double? height; final String? errorText; final bool isDisable; final EdgeInsetsGeometry? contentPadding; final Color? disabledColor; const DropdownBottomSheet({ Key? key, required this.dataSources, required this.onSelected, required this.hint, this.initValue, this.borderColor, this.height, this.errorText, this.isDisable = false, this.contentPadding, this.disabledColor, }) : super(key: key); @override _DropdownBottomSheetState createState() => _DropdownBottomSheetState(); } class _DropdownBottomSheetState extends State { var dataSources = ValueNotifier([]); var selectValue = ValueNotifier(ItemDropDown()); int _selectedIndex = 0; FixedExtentScrollController? scrollController; final _searchCtl = TextEditingController(); @override void initState() { super.initState(); } @override void dispose() { _searchCtl.dispose(); super.dispose(); } @override Widget build(BuildContext context) { _selectedIndex = widget.dataSources.indexWhere((element) { return element.key == widget.initValue; }); if (_selectedIndex >= 0) { selectValue.value = widget.dataSources[_selectedIndex]; } else { selectValue.value = ItemDropDown(key: '', value: ''); } return InkWell( onTap: () { FocusScope.of(context).requestFocus(FocusNode()); widget.isDisable ? null : _modalBottomSheetMenu(); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: widget.contentPadding ?? EdgeInsets.symmetric( horizontal: 12.w, vertical: 16.h, ), decoration: BoxDecoration( color: widget.isDisable ? (widget.disabledColor ?? AppColors.background1) : AppColors.white, borderRadius: BorderRadius.circular(12), border: Border.all( color: AppColors.neutral4, width: 1, ), ), child: Row( children: [ Expanded( child: ValueListenableBuilder( valueListenable: selectValue, builder: (context, selected, _) { if (Validators.stringNotNullOrEmpty(selected.key)) { return Text( selected.value ?? '', style: StylesText.body6, maxLines: 1, ); } else { return Text( widget.hint, style: StylesText.body6.copyWith( color: AppColors.neutral3, ), ); } }, ), ), SvgPicture.asset(AssetSVG.icArrowDown), ], ), ), if (widget.errorText != null) ...[ SizedBox( height: 4.h, ), Text( widget.errorText ?? '', style: StylesText.caption1.copyWith( color: AppColors.semantic2, ), ) ], ], ), ); } void _modalBottomSheetMenu() { _searchCtl.clear(); dataSources.value = List.of(widget.dataSources); showDialog( context: context, builder: (context) { return AlertDialog( contentPadding: const EdgeInsets.all(8), content: Container( width: double.maxFinite, child: Column( mainAxisSize: MainAxisSize.min, children: [ Expanded( child: ValueListenableBuilder>( valueListenable: dataSources, builder: (context, sources, _) { return ListView.builder( shrinkWrap: true, itemBuilder: ((context, index) { var item = sources[index]; return InkWell( onTap: () {}, child: RadioListTile( value: item, title: Text( item.value ?? '', style: StylesText.body6, ), groupValue: item.key == selectValue.value.key ? item : null, onChanged: (val) { Get.back(); widget.onSelected(val!); }, ), ); }), itemCount: sources.length, ); }, ), ) ], ), ), ); }, ); } }