import 'package:diameter/components/progress_indicator.dart'; import 'package:flutter/material.dart'; class StyledForm extends StatefulWidget { final List? fields; final List? buttons; final GlobalKey? formState; const StyledForm({Key? key, this.formState, this.fields, this.buttons}) : super(key: key); @override _StyledFormState createState() => _StyledFormState(); } class _StyledFormState extends State { @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(10.0), child: Form( key: widget.formState, child: Column( children: [ Column( children: widget.fields ?.map((e) => Padding( padding: const EdgeInsets.symmetric(vertical: 5.0), child: e)) .toList() ?? [], ), Container( padding: const EdgeInsets.only(top: 10.0), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: widget.buttons ?? [], ), ), ], ), ), ); } } class StyledBooleanFormField extends StatefulWidget { final bool value; final String label; final void Function(bool) onChanged; final bool? enabled; const StyledBooleanFormField( {Key? key, required this.value, required this.label, required this.onChanged, this.enabled}) : super(key: key); @override _StyledBooleanFormFieldState createState() => _StyledBooleanFormFieldState(); } class _StyledBooleanFormFieldState extends State { @override Widget build(BuildContext context) { return FormField(builder: (context) { return ListTile( onTap: () => widget.onChanged(!widget.value), trailing: Switch( value: widget.value, onChanged: widget.onChanged, ), title: Text(widget.label), enabled: widget.enabled ?? true, ); }); } } class StyledTimeOfDayFormField extends StatefulWidget { final TimeOfDay time; final TextEditingController controller; final String label; final void Function(TimeOfDay?) onChanged; const StyledTimeOfDayFormField( {Key? key, required this.time, required this.controller, required this.label, required this.onChanged}) : super(key: key); @override _StyledTimeOfDayFormFieldState createState() => _StyledTimeOfDayFormFieldState(); } class _StyledTimeOfDayFormFieldState extends State { @override Widget build(BuildContext context) { return TextFormField( readOnly: true, controller: widget.controller, decoration: InputDecoration( labelText: widget.label, ), onTap: () async { final newTime = await showTimePicker( context: context, initialTime: widget.time, ); widget.onChanged(newTime); }, ); } } class StyledDropdownButton extends StatefulWidget { final String label; final T? selectedItem; final List items; final Widget Function(T item) renderItem; final void Function(T? value) onChanged; const StyledDropdownButton( {Key? key, this.selectedItem, required this.label, required this.items, required this.renderItem, required this.onChanged}) : super(key: key); @override _StyledDropdownButtonState createState() => _StyledDropdownButtonState(); } class _StyledDropdownButtonState extends State> { @override Widget build(BuildContext context) { return DropdownButtonFormField( decoration: InputDecoration( labelText: widget.label, ), value: widget.selectedItem, onChanged: widget.onChanged, items: widget.items .map((item) => DropdownMenuItem( value: item, child: widget.renderItem(item), )) .toList(), ); } } class StyledFutureDropdownButton extends StatefulWidget { final String label; final String? selectedItem; final Future> items; final String? Function(T item) getItemValue; final Widget Function(T item) renderItem; final void Function(String? value) onChanged; const StyledFutureDropdownButton( {Key? key, this.selectedItem, required this.label, required this.items, required this.getItemValue, required this.renderItem, required this.onChanged}) : super(key: key); @override _StyledFutureDropdownButtonState createState() => _StyledFutureDropdownButtonState(); } class _StyledFutureDropdownButtonState extends State> { @override Widget build(BuildContext context) { return FutureBuilder>( future: widget.items, builder: (context, snapshot) { return ViewWithProgressIndicator( snapshot: snapshot, padding: const EdgeInsets.all(10.0), progressIndicatorSize: 44, child: snapshot.data == null || snapshot.data!.isEmpty ? Row( mainAxisAlignment: MainAxisAlignment.center, children: const [ Padding( padding: EdgeInsets.all(10.0), child: Text('No Meal Sources'), ) ], ) : DropdownButtonFormField( decoration: InputDecoration( labelText: widget.label, ), value: widget.selectedItem, onChanged: widget.onChanged, items: snapshot.data! .map((item) => DropdownMenuItem( value: widget.getItemValue(item), child: widget.renderItem(item), )) .toList(), ), ); }, ); } }