This commit is contained in:
2026-03-29 14:26:48 +03:00
parent 31dc972e52
commit 0020c65d1e
2 changed files with 233 additions and 193 deletions
+30 -8
View File
@@ -37,6 +37,7 @@ class AddTransactionScreen extends ConsumerStatefulWidget {
class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
with SingleTickerProviderStateMixin {
final _formKey = GlobalKey<FormState>();
final _stackKey = GlobalKey();
final _amountController = TextEditingController();
final _noteController = TextEditingController();
final _fromAccountIndicatorKey = GlobalKey();
@@ -507,6 +508,7 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
child: Form(
key: _formKey,
child: Stack(
key: _stackKey,
children: [
ListView(
padding: const EdgeInsets.all(20),
@@ -685,6 +687,7 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
onClose: () =>
setState(() => _showFromAccountDropdown = false),
triggerKey: _fromAccountIndicatorKey,
stackKey: _stackKey,
),
if (_showToAccountDropdown)
Positioned.fill(
@@ -699,6 +702,7 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
initial: widget.initial,
onClose: () => setState(() => _showToAccountDropdown = false),
triggerKey: _toAccountIndicatorKey,
stackKey: _stackKey,
),
],
),
@@ -839,11 +843,13 @@ class _ToAccountDropdownOverlay extends ConsumerWidget {
final Transaction? initial;
final VoidCallback onClose;
final GlobalKey? triggerKey;
final GlobalKey? stackKey;
const _ToAccountDropdownOverlay({
required this.initial,
required this.onClose,
this.triggerKey,
this.stackKey,
});
@override
@@ -857,20 +863,33 @@ class _ToAccountDropdownOverlay extends ConsumerWidget {
// Calculate position from trigger key
double top = 340;
double left = 20;
double triggerWidth = 200; // fallback width
if (triggerKey?.currentContext != null) {
final renderBox =
final triggerBox =
triggerKey!.currentContext!.findRenderObject() as RenderBox;
final offset = renderBox.localToGlobal(Offset.zero);
final size = renderBox.size;
top = offset.dy + size.height + 4;
left = offset.dx;
final triggerOffset = triggerBox.localToGlobal(Offset.zero);
final triggerSize = triggerBox.size;
triggerWidth = triggerSize.width;
double stackDy = 0;
double stackDx = 0;
if (stackKey?.currentContext != null) {
final stackBox =
stackKey!.currentContext!.findRenderObject() as RenderBox;
final stackOffset = stackBox.localToGlobal(Offset.zero);
stackDy = stackOffset.dy;
stackDx = stackOffset.dx;
}
top = triggerOffset.dy - stackDy + triggerSize.height + 4;
left = triggerOffset.dx - stackDx;
}
return Positioned(
top: top,
left: left,
child: IntrinsicWidth(
width: triggerWidth,
child: Material(
elevation: 8,
borderRadius: BorderRadius.circular(12),
@@ -930,6 +949,8 @@ class _ToAccountDropdownOverlay extends ConsumerWidget {
Expanded(
child: Text(
account.name,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(
fontSize: 14,
fontWeight: isSelected
@@ -941,13 +962,15 @@ class _ToAccountDropdownOverlay extends ConsumerWidget {
),
),
),
if (isSelected)
if (isSelected) ...[
const SizedBox(width: 10),
const Icon(
Icons.check_rounded,
size: 16,
color: Color(0xFF7C6DED),
),
],
],
),
),
);
@@ -959,7 +982,6 @@ class _ToAccountDropdownOverlay extends ConsumerWidget {
),
),
),
),
);
}
}
@@ -120,12 +120,14 @@ class AccountDropdownOverlay extends ConsumerWidget {
final Transaction? initial;
final VoidCallback onClose;
final GlobalKey? triggerKey;
final GlobalKey? stackKey;
const AccountDropdownOverlay({
super.key,
required this.initial,
required this.onClose,
this.triggerKey,
this.stackKey,
});
@override
@@ -136,20 +138,33 @@ class AccountDropdownOverlay extends ConsumerWidget {
// Calculate position from trigger key
double top = 76;
double left = 20;
double triggerWidth = 200; // fallback width
if (triggerKey?.currentContext != null) {
final renderBox =
final triggerBox =
triggerKey!.currentContext!.findRenderObject() as RenderBox;
final offset = renderBox.localToGlobal(Offset.zero);
final size = renderBox.size;
top = offset.dy + size.height + 4;
left = offset.dx;
final triggerOffset = triggerBox.localToGlobal(Offset.zero);
final triggerSize = triggerBox.size;
triggerWidth = triggerSize.width;
double stackDy = 0;
double stackDx = 0;
if (stackKey?.currentContext != null) {
final stackBox =
stackKey!.currentContext!.findRenderObject() as RenderBox;
final stackOffset = stackBox.localToGlobal(Offset.zero);
stackDy = stackOffset.dy;
stackDx = stackOffset.dx;
}
top = triggerOffset.dy - stackDy + triggerSize.height + 4;
left = triggerOffset.dx - stackDx;
}
return Positioned(
top: top,
left: left,
child: IntrinsicWidth(
width: triggerWidth,
child: Material(
elevation: 8,
borderRadius: BorderRadius.circular(12),
@@ -226,6 +241,8 @@ class AccountDropdownOverlay extends ConsumerWidget {
Expanded(
child: Text(
account.name,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(
fontSize: 14,
fontWeight: isSelected
@@ -237,13 +254,15 @@ class AccountDropdownOverlay extends ConsumerWidget {
),
),
),
if (isSelected)
if (isSelected) ...[
const SizedBox(width: 10),
const Icon(
Icons.check_rounded,
size: 16,
color: Color(0xFF7C6DED),
),
],
],
),
),
);
@@ -255,7 +274,6 @@ class AccountDropdownOverlay extends ConsumerWidget {
),
),
),
),
);
}
}