LCOV - code coverage report
Current view: top level - lib/design/wrapper - input_wrapper.dart Coverage Total Hit
Test: lcov.info Lines: 70.5 % 95 67
Test Date: 2026-11-14 15:04:37 Functions: - 0 0

            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/herald/app_design.dart';
       5              : import 'package:app_finance/_classes/herald/app_locale.dart';
       6              : import 'package:app_finance/_classes/storage/app_data.dart';
       7              : import 'package:app_finance/design/form/currency_selector_code.dart';
       8              : import 'package:app_finance/design/form/date_input.dart';
       9              : import 'package:app_finance/design/form/list_selector_item.dart';
      10              : import 'package:app_finance/_configs/screen_helper.dart';
      11              : import 'package:app_finance/_configs/theme_helper.dart';
      12              : import 'package:app_finance/_ext/build_context_ext.dart';
      13              : import 'package:app_finance/design/form/color_selector.dart';
      14              : import 'package:app_finance/design/form/currency_selector.dart';
      15              : import 'package:app_finance/design/form/icon_selector.dart';
      16              : import 'package:app_finance/design/form/list_account_selector.dart';
      17              : import 'package:app_finance/design/form/list_budget_selector.dart';
      18              : import 'package:app_finance/design/form/list_selector.dart';
      19              : import 'package:app_finance/design/form/month_year_input.dart';
      20              : import 'package:app_finance/design/form/simple_input.dart';
      21              : import 'package:app_finance/design/wrapper/required_widget.dart';
      22              : import 'package:app_finance/design/wrapper/text_wrapper.dart';
      23              : import 'package:material_ui/material_ui.dart';
      24              : import 'package:flutter/services.dart';
      25              : 
      26              : enum NamedInputType {
      27              :   accountSelector,
      28              :   budgetSelector,
      29              :   colorSelector,
      30              :   currencySelector,
      31              :   currencyShort,
      32              :   iconSelector,
      33              :   listSelector,
      34              :   textInput,
      35              :   ymSelector,
      36              :   dateSelector,
      37              : }
      38              : 
      39              : class InputWrapper extends StatelessWidget {
      40              :   final NamedInputType type;
      41              :   final bool isRequired;
      42              :   final bool isDisabled;
      43              :   final bool showError;
      44              :   final String title;
      45              :   final List<dynamic>? options;
      46              :   final Function? onChange;
      47              :   final String? tooltip;
      48              :   final TextEditingController? controller;
      49              :   final dynamic value;
      50              :   final List<TextInputFormatter>? formatter;
      51              :   final AppData? state;
      52              :   final double? width;
      53              :   final TextInputType? inputType;
      54              : 
      55           24 :   Key getKey() => ValueKey(key?.hashCode ?? '$title $tooltip');
      56              : 
      57            4 :   ({bool min, String? hint, Color? hintColor}) getHintState(BuildContext context) {
      58            4 :     final screenState = ScreenHelper.state();
      59              :     final min = screenState.isRight || screenState.isWearable;
      60            4 :     String? hint = min ? title : tooltip;
      61              :     Color? hintColor;
      62            4 :     if (isRequired && min) {
      63            0 :       if (showError) {
      64            0 :         hint = '$hint [!] ${AppLocale.labels.isRequired}';
      65            0 :         hintColor = context.colorScheme.primary;
      66              :       } else {
      67            0 :         hint = '$hint*';
      68              :       }
      69              :     }
      70              : 
      71              :     return (min: min, hint: hint, hintColor: hintColor);
      72              :   }
      73              : 
      74            4 :   const InputWrapper({
      75              :     super.key,
      76              :     required this.type,
      77              :     required this.title,
      78              :     this.tooltip,
      79              :     this.controller,
      80              :     this.onChange,
      81              :     this.options,
      82              :     this.value,
      83              :     this.formatter,
      84              :     this.isRequired = false,
      85              :     this.isDisabled = false,
      86              :     this.showError = false,
      87              :     this.state,
      88              :     this.width,
      89              :     this.inputType,
      90              :   });
      91              : 
      92            4 :   const InputWrapper.text({
      93              :     super.key,
      94              :     this.type = NamedInputType.textInput,
      95              :     required this.title,
      96              :     required this.controller,
      97              :     this.tooltip,
      98              :     this.isRequired = false,
      99              :     this.isDisabled = false,
     100              :     this.showError = false,
     101              :     this.onChange,
     102              :     this.options,
     103              :     this.value,
     104              :     this.formatter,
     105              :     this.state,
     106              :     this.width,
     107              :     this.inputType,
     108              :   });
     109              : 
     110            2 :   const InputWrapper.select({
     111              :     super.key,
     112              :     this.type = NamedInputType.listSelector,
     113              :     required this.title,
     114              :     required this.options,
     115              :     required this.onChange,
     116              :     required this.value,
     117              :     this.tooltip,
     118              :     this.isRequired = false,
     119              :     this.isDisabled = false,
     120              :     this.showError = false,
     121              :     this.controller,
     122              :     this.formatter,
     123              :     this.state,
     124              :     this.width,
     125              :     this.inputType,
     126              :   });
     127              : 
     128            0 :   const InputWrapper.icon({
     129              :     super.key,
     130              :     this.type = NamedInputType.iconSelector,
     131              :     required this.title,
     132              :     required this.onChange,
     133              :     this.controller,
     134              :     this.tooltip,
     135              :     this.isRequired = false,
     136              :     this.isDisabled = false,
     137              :     this.showError = false,
     138              :     this.options,
     139              :     this.value,
     140              :     this.formatter,
     141              :     this.state,
     142              :     this.width,
     143              :     this.inputType,
     144              :   });
     145              : 
     146            0 :   const InputWrapper.color({
     147              :     super.key,
     148              :     this.type = NamedInputType.colorSelector,
     149              :     required this.title,
     150              :     required this.onChange,
     151              :     this.controller,
     152              :     this.tooltip,
     153              :     this.isRequired = false,
     154              :     this.isDisabled = false,
     155              :     this.showError = false,
     156              :     this.options,
     157              :     this.value,
     158              :     this.formatter,
     159              :     this.state,
     160              :     this.width,
     161              :     this.inputType,
     162              :   });
     163              : 
     164            2 :   const InputWrapper.currency({
     165              :     super.key,
     166              :     this.type = NamedInputType.currencySelector,
     167              :     required this.value,
     168              :     required this.title,
     169              :     required this.onChange,
     170              :     this.controller,
     171              :     this.tooltip,
     172              :     this.isRequired = false,
     173              :     this.isDisabled = false,
     174              :     this.showError = false,
     175              :     this.options,
     176              :     this.formatter,
     177              :     this.state,
     178              :     this.width,
     179              :     this.inputType,
     180              :   });
     181              : 
     182            8 :   Widget buildTextInput({required bool min, required String? hint, Color? hintColor}) => SimpleInput(
     183            4 :         key: getKey(),
     184            4 :         controller: controller!,
     185              :         tooltip: hint,
     186              :         withLabel: min,
     187              :         hintColor: hintColor,
     188            4 :         formatter: formatter,
     189            4 :         type: inputType ?? TextInputType.text,
     190            8 :         obscure: inputType == TextInputType.visiblePassword,
     191              :       );
     192              : 
     193            2 :   Widget buildListSelector({required bool min, required String? hint, Color? hintColor}) =>
     194            2 :       ListSelector<ListSelectorItem>(
     195            2 :         key: getKey(),
     196            6 :         value: value != null ? ListSelectorItem(id: value, name: '') : null,
     197            2 :         tooltip: tooltip,
     198              :         hintText: hint,
     199              :         hintColor: hintColor,
     200            2 :         options: options as List<ListSelectorItem>,
     201            0 :         setState: (ListSelectorItem? v) => onChange?.call(v?.id),
     202              :         withLabel: min,
     203            2 :         isDisabled: isDisabled,
     204              :       );
     205              : 
     206            0 :   Widget buildIconSelector({required bool min, required String? hint}) => IconSelector(
     207            0 :         key: getKey(),
     208            0 :         value: value != null ? IconSelectorItem(value, name: value.toString()) : null,
     209            0 :         setState: (v) => onChange?.call((v as IconSelectorItem?)?.value),
     210              :         hintText: hint,
     211              :         withLabel: min,
     212              :       );
     213              : 
     214            0 :   Widget buildColorSelector({required bool min}) => ColorSelector(
     215            0 :         key: getKey(),
     216            0 :         value: value,
     217            0 :         setState: (v) => onChange?.call(v),
     218              :         withLabel: min,
     219              :       );
     220              : 
     221            0 :   Widget buildCurrencySelector({required bool min, required String? hint}) => BaseCurrencySelector(
     222            0 :         key: getKey(),
     223            0 :         value: value != null ? BaseListSelectorItem(value) : null,
     224            0 :         setState: (v) => onChange?.call((v as BaseListSelectorItem?)?.item),
     225              :         withLabel: min,
     226            0 :         tooltip: tooltip,
     227              :         hintText: hint,
     228              :       );
     229              : 
     230            4 :   Widget buildCurrencyShortSelector({required bool min, required String? hint}) => CodeCurrencySelector(
     231            2 :         key: getKey(),
     232            6 :         value: value != null ? CodeCurrencySelectorItem(value) : null,
     233            0 :         setState: (v) => onChange?.call((v as CodeCurrencySelectorItem?)?.item),
     234              :         withLabel: min,
     235            2 :         tooltip: tooltip,
     236              :         hintText: hint,
     237              :       );
     238              : 
     239            0 :   Widget buildMonthYearSelector({required bool min}) => MonthYearInput(
     240            0 :         key: getKey(),
     241            0 :         value: value,
     242            0 :         setState: onChange!,
     243              :         withLabel: min,
     244            0 :         labelText: title,
     245              :       );
     246              : 
     247            4 :   Widget buildDateSelector({required bool min}) => DateInput(
     248            2 :         value: value,
     249            2 :         setState: onChange!,
     250              :         withLabel: min,
     251              :       );
     252              : 
     253            8 :   Widget buildAccountSelector({required bool min, required String? hint}) => ListAccountSelector(
     254            4 :         key: getKey(),
     255            6 :         value: value != null ? ListAccountSelectorItem(item: value) : null,
     256              :         hintText: hint,
     257            4 :         tooltip: tooltip,
     258            4 :         state: state!,
     259            0 :         setState: (v) => onChange?.call((v as ListAccountSelectorItem?)?.item),
     260            4 :         width: width!,
     261              :         withLabel: min,
     262            8 :         options: options?.cast() ?? [],
     263              :       );
     264              : 
     265            8 :   Widget buildBudgetSelector({required bool min, required String? hint}) => ListBudgetSelector(
     266            4 :         key: getKey(),
     267            6 :         value: value != null ? ListBudgetSelectorItem(item: value) : null,
     268              :         hintText: hint,
     269            4 :         tooltip: tooltip,
     270            4 :         state: state!,
     271            0 :         setState: (v) => onChange?.call((v as ListBudgetSelectorItem?)?.item),
     272            4 :         width: width!,
     273              :         withLabel: min,
     274              :       );
     275              : 
     276            4 :   Widget buildInput({required bool min, required String? hint, Color? hintColor}) {
     277            4 :     return switch (type) {
     278            8 :       NamedInputType.textInput => buildTextInput(min: min, hint: hint, hintColor: hintColor),
     279            6 :       NamedInputType.listSelector => buildListSelector(min: min, hint: hint, hintColor: hintColor),
     280            4 :       NamedInputType.iconSelector => buildIconSelector(min: min, hint: hint),
     281            4 :       NamedInputType.colorSelector => buildColorSelector(min: min),
     282            4 :       NamedInputType.currencySelector => buildCurrencySelector(min: min, hint: hint),
     283            6 :       NamedInputType.currencyShort => buildCurrencyShortSelector(min: min, hint: hint),
     284            4 :       NamedInputType.ymSelector => buildMonthYearSelector(min: min),
     285            6 :       NamedInputType.dateSelector => buildDateSelector(min: min),
     286            8 :       NamedInputType.accountSelector => buildAccountSelector(min: min, hint: hint),
     287            8 :       NamedInputType.budgetSelector => buildBudgetSelector(min: min, hint: hint),
     288              :     };
     289              :   }
     290              : 
     291            4 :   Widget buildTitle(BuildContext context, {required bool min}) {
     292              :     if (min) {
     293              :       return ThemeHelper.emptyBox;
     294              :     }
     295              : 
     296            4 :     return isRequired
     297           12 :         ? RequiredWidget(title: title, showError: showError)
     298           16 :         : TextWrapper(title, style: context.textTheme.bodyLarge);
     299              :   }
     300              : 
     301            4 :   @override
     302              :   Widget build(BuildContext context) {
     303            4 :     final hintState = getHintState(context);
     304              :     final min = hintState.min;
     305            4 :     return Column(
     306            4 :       mainAxisAlignment: AppDesign.getAlignment<MainAxisAlignment>(),
     307            4 :       crossAxisAlignment: AppDesign.getAlignment(),
     308            4 :       children: [
     309            4 :         if (!min) buildTitle(context, min: min),
     310            4 :         buildInput(min: min, hint: hintState.hint, hintColor: hintState.hintColor),
     311            4 :         ThemeHelper.hIndent2x,
     312              :       ],
     313              :     );
     314              :   }
     315              : }
        

Generated by: LCOV version 2.0-1