import 'package:flutter/material.dart'; class IntStepperField extends StatelessWidget { final String label; final TextEditingController controller; final int min; final int max; const IntStepperField({ super.key, required this.label, required this.controller, this.min = 0, this.max = 24, }); @override Widget build(BuildContext context) { int value = int.tryParse(controller.text) ?? 0; return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.only(bottom: 2.0), child: Text( label, textAlign: TextAlign.center, style: const TextStyle( fontSize: 13, color: Colors.black87, fontWeight: FontWeight.w500), ), ), Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon(Icons.remove_circle_outline, size: 20), splashRadius: 18, onPressed: value > min ? () { value--; controller.text = value.toString(); (context as Element).markNeedsBuild(); } : null, ), SizedBox( width: 60, height: 36, child: TextFormField( controller: controller, keyboardType: TextInputType.number, textAlign: TextAlign.center, style: const TextStyle(fontSize: 15), decoration: const InputDecoration( border: OutlineInputBorder(), contentPadding: EdgeInsets.symmetric(vertical: 6, horizontal: 6), ), onChanged: (val) { int? v = int.tryParse(val); if (v == null || v < min) { controller.text = min.toString(); } else if (v > max) { controller.text = max.toString(); } }, ), ), IconButton( icon: const Icon(Icons.add_circle_outline, size: 20), splashRadius: 18, onPressed: value < max ? () { value++; controller.text = value.toString(); (context as Element).markNeedsBuild(); } : null, ), ], ), ], ); } }