Line data Source code
1 : // Copyright 2023 The terCAD team. All rights reserved.
2 : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
3 :
4 : import 'package:app_finance/_classes/controller/focus_controller.dart';
5 : import 'package:app_finance/_classes/herald/app_design.dart';
6 : import 'package:app_finance/_configs/custom_color_scheme.dart';
7 : import 'package:app_finance/_configs/custom_text_theme.dart';
8 : import 'package:app_finance/_configs/theme_helper.dart';
9 : import 'package:app_finance/_ext/build_context_ext.dart';
10 : import 'package:app_finance/design/wrapper/focus_wrapper.dart';
11 : import 'package:material_ui/material_ui.dart';
12 : import 'package:flutter/semantics.dart';
13 : import 'package:flutter/services.dart';
14 :
15 : abstract class SimpleInputFormatter {
16 4 : static TextInputFormatter get filterDouble => TextInputFormatter.withFunction((oldValue, newValue) {
17 0 : final text = newValue.text.replaceAll(',', '.');
18 0 : if (!RegExp(r'^\d*\.?\d*$').hasMatch(text)) {
19 : return oldValue;
20 : }
21 0 : return newValue.copyWith(text: text);
22 : });
23 :
24 0 : static get filterInt => FilteringTextInputFormatter.allow(RegExp(r'\d+'));
25 : }
26 :
27 : class SimpleInput extends StatelessWidget {
28 : final Function? setState;
29 : final String? tooltip;
30 : final TextInputType type;
31 : final FocusController? focusController;
32 : final List<TextInputFormatter>? formatter;
33 : final TextEditingController controller;
34 : final bool obscure;
35 : final bool withLabel;
36 : final bool forceFocus;
37 : final Color? hintColor;
38 : final Function(String)? onFieldSubmitted;
39 :
40 4 : SimpleInput({
41 : super.key,
42 : required this.controller,
43 : this.onFieldSubmitted,
44 : this.focusController,
45 : this.setState,
46 : this.tooltip,
47 : this.formatter,
48 : this.hintColor,
49 : this.type = TextInputType.text,
50 : this.obscure = false,
51 : this.withLabel = false,
52 : this.forceFocus = false,
53 : }) {
54 4 : if (setState != null) {
55 0 : controller.addListener(() => setState!(controller.text));
56 : }
57 : }
58 :
59 4 : @override
60 : Widget build(BuildContext context) {
61 4 : final indent = ThemeHelper.getIndent(1.8);
62 4 : final textTheme = context.textTheme;
63 8 : final focusController = this.focusController ?? FocusWrapper.of(context);
64 4 : return Directionality(
65 4 : textDirection: AppDesign.getAlignment<TextDirection>(),
66 4 : child: Semantics(
67 : container: true,
68 : textField: true,
69 4 : label: tooltip,
70 12 : attributedHint: tooltip != null ? AttributedString(tooltip!) : null,
71 4 : child: TextFormField(
72 4 : controller: controller,
73 4 : inputFormatters: formatter,
74 4 : style: textTheme.numberMedium,
75 8 : keyboardAppearance: context.colorScheme.brightness,
76 4 : obscureText: obscure,
77 : obscuringCharacter: '*',
78 4 : keyboardType: type,
79 6 : focusNode: focusController?.bind(this, context: context, value: controller.text),
80 2 : textInputAction: focusController?.getAction(this),
81 0 : onTap: () => focusController?.onFocus(this),
82 0 : onEditingComplete: () => focusController?.onEditingComplete(this),
83 4 : onFieldSubmitted: onFieldSubmitted,
84 6 : autofocus: forceFocus ? forceFocus : focusController?.isFocused(this) ?? false,
85 4 : decoration: InputDecoration(
86 : filled: true,
87 : border: InputBorder.none,
88 8 : fillColor: context.colorScheme.fieldBackground,
89 12 : contentPadding: EdgeInsets.fromLTRB(indent / 1.5, withLabel ? 1 : indent, 0, indent),
90 8 : hintText: withLabel ? null : tooltip,
91 4 : hintStyle: textTheme.tooltipMedium,
92 4 : labelText: withLabel ? tooltip : null,
93 4 : labelStyle: textTheme.tooltipMedium,
94 : ),
95 : ),
96 : ),
97 : );
98 : }
99 : }
|