small fix, don't worry about it

This commit is contained in:
Tomas Dvorak
2026-04-10 12:05:40 +02:00
parent 7b7ed0083f
commit 5ab2773f98
55 changed files with 3240 additions and 483 deletions
@@ -0,0 +1,180 @@
import 'package:flutter/material.dart';
import '../utils/unit_conversion_utils.dart';
class UnitInputField extends StatefulWidget {
final String labelText;
final IconData prefixIcon;
final String helperText;
final bool enabled;
final ValueChanged<double?> onValueChanged;
final ValueChanged<dynamic>? onUnitChanged;
final double? initialValue;
final bool isHeight;
const UnitInputField({
super.key,
required this.labelText,
required this.prefixIcon,
required this.helperText,
this.enabled = true,
required this.onValueChanged,
this.onUnitChanged,
this.initialValue,
required this.isHeight,
});
@override
State<UnitInputField> createState() => _UnitInputFieldState();
}
class _UnitInputFieldState extends State<UnitInputField> {
late TextEditingController _controller;
late HeightUnit _selectedHeightUnit;
late WeightUnit _selectedWeightUnit;
@override
void initState() {
super.initState();
_controller = TextEditingController();
_selectedHeightUnit = HeightUnit.metric;
_selectedWeightUnit = WeightUnit.metric;
// Set initial value if provided
if (widget.initialValue != null) {
if (widget.isHeight) {
_controller.text = widget.initialValue!.toStringAsFixed(1);
} else {
_controller.text = widget.initialValue!.toStringAsFixed(1);
}
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _onUnitChanged(dynamic unit) {
setState(() {
if (widget.isHeight) {
_selectedHeightUnit = unit as HeightUnit;
} else {
_selectedWeightUnit = unit as WeightUnit;
}
});
// Notify parent widget of unit change
widget.onUnitChanged?.call(unit);
_convertAndNotify();
}
void _showUnitSelector() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Select Unit'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: (widget.isHeight ? HeightUnit.values : WeightUnit.values).map((unit) {
return RadioListTile<dynamic>(
title: Text(widget.isHeight ? (unit as HeightUnit).displayName : (unit as WeightUnit).displayName),
value: unit,
groupValue: widget.isHeight ? _selectedHeightUnit : _selectedWeightUnit,
onChanged: widget.enabled ? (value) {
_onUnitChanged(value);
Navigator.of(context).pop();
} : null,
);
}).toList(),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Cancel'),
),
],
);
},
);
}
void _onTextChanged(String text) {
_convertAndNotify();
}
void _convertAndNotify() {
final text = _controller.text.trim();
if (text.isEmpty) {
widget.onValueChanged(null);
return;
}
double? valueInCmOrKg;
if (widget.isHeight) {
valueInCmOrKg = UnitConversionUtils.parseHeight(text, _selectedHeightUnit);
} else {
valueInCmOrKg = UnitConversionUtils.parseWeight(text, _selectedWeightUnit);
}
widget.onValueChanged(valueInCmOrKg);
}
String get _unitDisplayText {
if (widget.isHeight) {
return _selectedHeightUnit.displayName;
} else {
return _selectedWeightUnit.displayName;
}
}
@override
Widget build(BuildContext context) {
return Row(
children: [
// Input field
Expanded(
flex: 3,
child: TextFormField(
controller: _controller,
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: widget.labelText,
prefixIcon: Icon(widget.prefixIcon),
helperText: widget.helperText,
suffixText: _unitDisplayText,
isDense: true, // Make the input field more compact
),
enabled: widget.enabled,
onChanged: widget.enabled ? _onTextChanged : null,
),
),
const SizedBox(width: 8),
// Unit selector - custom button
Container(
width: 45,
height: 32,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(4),
),
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(4),
onTap: widget.enabled ? () => _showUnitSelector() : null,
child: Center(
child: Text(
_unitDisplayText,
style: const TextStyle(fontSize: 12),
),
),
),
),
),
],
);
}
}