1import 'package:blood_pressure_app/features/input/forms/form_base.dart';
 2import 'package:blood_pressure_app/features/settings/tiles/color_picker_list_tile.dart';
 3import 'package:flutter/material.dart';
 4import 'package:blood_pressure_app/l10n/app_localizations.dart';
 5
 6/// Form to enter freeform text and select color.
 7class NoteForm extends FormBase<(String?, Color?)> {
 8  /// Create form to enter freeform text and select color.
 9  const NoteForm({super.key,
10    super.initialValue,
11  });
12
13  @override
14  NoteFormState createState() => NoteFormState();
15}
16
17/// State of form to enter freeform text and select color.
18class NoteFormState extends FormStateBase<(String?, Color?), NoteForm> {
19  late final TextEditingController _controller;
20
21  final FocusNode _focusNode = FocusNode();
22
23  Color? _color;
24
25  @override
26  void initState() {
27    super.initState();
28    _controller = TextEditingController(text: widget.initialValue?.$1);
29    _color = widget.initialValue?.$2;
30  }
31
32  @override
33  void dispose() {
34    _focusNode.dispose();
35    _controller.dispose();
36    super.dispose();
37  }
38
39  @override
40  bool validate() => true;
41
42  @override
43  (String?, Color?)? save() {
44    final String? text = _controller.text.isEmpty ? null : _controller.text;
45    if (text == null && _color == null) return null;
46    return (text, _color);
47  }
48
49  @override
50  bool isEmptyInputFocused() => _focusNode.hasFocus && _controller.text.isEmpty;
51
52  @override
53  void fillForm((String?, Color?)? value) => setState(() {
54    if (value == null) {
55      _controller.text = '';
56      _color = null;
57    } else {
58      if (value.$1 != null) _controller.text = value.$1!;
59      if (value.$2 != null) _color = value.$2!;
60    }
61  });
62
63  @override
64  Widget build(BuildContext context) => Column(
65    children: [
66      Padding(
67        padding: const EdgeInsets.symmetric(vertical: 16),
68        child: TextFormField(
69          focusNode: _focusNode,
70          controller: _controller,
71          decoration: InputDecoration(
72            labelText: AppLocalizations.of(context)!.addNote,
73          ),
74          minLines: 1,
75          maxLines: 4,
76        ),
77      ),
78      InputDecorator(
79        decoration: InputDecoration(
80          contentPadding: EdgeInsets.zero,
81        ),
82        child: ColorSelectionListTile(
83          title: Text(AppLocalizations.of(context)!.color, style: Theme.of(context).textTheme.bodyLarge,),
84          onMainColorChanged: (Color value) => setState(() {
85            _color = (value == Colors.transparent) ? null : value;
86          }),
87          initialColor: _color ?? Colors.transparent,
88        ),
89      ),
90    ],
91  );
92}