From fa51efc2df1347bd006326a0aa060f242804b67f Mon Sep 17 00:00:00 2001 From: Prateek Date: Sun, 28 Dec 2025 12:42:35 +0530 Subject: [PATCH] fix: improve bottom sheet keyboard behavior with dynamic height constraints --- .../home/views/add_task_bottom_sheet_new.dart | 202 ++++++++++-------- 1 file changed, 111 insertions(+), 91 deletions(-) diff --git a/lib/app/modules/home/views/add_task_bottom_sheet_new.dart b/lib/app/modules/home/views/add_task_bottom_sheet_new.dart index 2679b140..44da8d6a 100644 --- a/lib/app/modules/home/views/add_task_bottom_sheet_new.dart +++ b/lib/app/modules/home/views/add_task_bottom_sheet_new.dart @@ -33,108 +33,128 @@ class AddTaskBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { const padding = 12.0; - return Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).viewInsets.bottom, + final screenHeight = MediaQuery.of(context).size.height; + final keyboardHeight = MediaQuery.of(context).viewInsets.bottom; + + // Calculate the max height for the bottom sheet + // When keyboard is closed: 80% of screen height + // When keyboard is open: remaining space with minimum height + final maxHeight = keyboardHeight > 0 + ? screenHeight - + keyboardHeight * + 0.5 // Keep 50% of keyboard from top when keyboard is open + : screenHeight * 0.8; // 80% of screen when keyboard is closed + + return Container( + constraints: BoxConstraints( + maxHeight: maxHeight, ), - child: Form( - key: homeController.formKey, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.all(padding), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - TextButton( - onPressed: () { - Get.back(); - }, - child: Text(SentenceManager( - currentLanguage: - homeController.selectedLanguage.value) - .sentences - .cancel), - ), - Text( - SentenceManager( - currentLanguage: - homeController.selectedLanguage.value) - .sentences - .addTaskTitle, - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, + child: Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom, + ), + child: Form( + key: homeController.formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Fixed header + Padding( + padding: const EdgeInsets.all(padding), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextButton( + onPressed: () { + Get.back(); + }, + child: Text(SentenceManager( + currentLanguage: + homeController.selectedLanguage.value) + .sentences + .cancel), ), - ), - TextButton( - onPressed: () { - if (forTaskC) { - onSaveButtonClickedTaskC(context); - } else if (forReplica) { - debugPrint("Saving to Replica"); - onSaveButtonClickedForReplica(context); - } else { - onSaveButtonClicked(context); - } - }, - child: Text(SentenceManager( - currentLanguage: - homeController.selectedLanguage.value) - .sentences - .save), - ), - ], + Text( + SentenceManager( + currentLanguage: + homeController.selectedLanguage.value) + .sentences + .addTaskTitle, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + TextButton( + onPressed: () { + if (forTaskC) { + onSaveButtonClickedTaskC(context); + } else if (forReplica) { + debugPrint("Saving to Replica"); + onSaveButtonClickedForReplica(context); + } else { + onSaveButtonClicked(context); + } + }, + child: Text(SentenceManager( + currentLanguage: + homeController.selectedLanguage.value) + .sentences + .save), + ), + ], + ), ), - ), - Flexible( - child: SingleChildScrollView( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(padding), - child: TextFormField( - controller: homeController.namecontroller, - validator: (value) => value!.isEmpty - ? SentenceManager( + // Scrollable content + Flexible( + child: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(padding), + child: TextFormField( + controller: homeController.namecontroller, + validator: (value) => value!.isEmpty + ? SentenceManager( + currentLanguage: + homeController.selectedLanguage.value) + .sentences + .descriprtionCannotBeEmpty + : null, + decoration: InputDecoration( + labelText: SentenceManager( currentLanguage: homeController.selectedLanguage.value) .sentences - .descriprtionCannotBeEmpty - : null, - decoration: InputDecoration( - labelText: SentenceManager( - currentLanguage: - homeController.selectedLanguage.value) - .sentences - .enterTaskDescription, - border: OutlineInputBorder(), + .enterTaskDescription, + border: OutlineInputBorder(), + ), ), ), - ), - Padding( + Padding( + padding: const EdgeInsets.all(padding), + child: buildProjectInput(context)), + Padding( + padding: const EdgeInsets.only( + left: padding, right: padding, top: padding), + child: buildDatePicker(context), + ), + Padding( padding: const EdgeInsets.all(padding), - child: buildProjectInput(context)), - Padding( - padding: const EdgeInsets.only( - left: padding, right: padding, top: padding), - child: buildDatePicker(context), - ), - Padding( - padding: const EdgeInsets.all(padding), - child: buildPriority(context), - ), - Padding( - padding: const EdgeInsets.all(padding), - child: buildTagsInput(context), - ), - const Padding(padding: EdgeInsets.all(20)), - ], + child: buildPriority(context), + ), + Padding( + padding: const EdgeInsets.all(padding), + child: buildTagsInput(context), + ), + const Padding(padding: EdgeInsets.all(20)), + ], + ), ), ), - ), - ], + ], + ), ), ), );