LCOV - code coverage report
Current view: top level - lib/design/form - list_selector.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 41 62 66.1 %
Date: 2024-10-04 11:09:33 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/controller/focus_controller.dart';
       5             : import 'package:app_finance/_classes/herald/app_design.dart';
       6             : import 'package:app_finance/design/form/list_selector_item.dart';
       7             : import 'package:app_finance/_configs/custom_color_scheme.dart';
       8             : import 'package:app_finance/_configs/custom_text_theme.dart';
       9             : import 'package:app_finance/_configs/theme_helper.dart';
      10             : import 'package:app_finance/_ext/build_context_ext.dart';
      11             : import 'package:app_finance/design/form/list_selector_page.dart';
      12             : import 'package:app_finance/design/wrapper/focus_wrapper.dart';
      13             : import 'package:app_finance/design/wrapper/row_widget.dart';
      14             : import 'package:app_finance/design/wrapper/tap_widget.dart';
      15             : import 'package:app_finance/design/wrapper/text_wrapper.dart';
      16             : import 'package:flutter/material.dart';
      17             : 
      18             : typedef FnState = Function(ListSelectorItem? value);
      19             : 
      20             : class ListSelector<K extends ListSelectorItem> extends StatefulWidget {
      21             :   final List<K> options;
      22             :   final K? value;
      23             :   final FnState setState;
      24             :   final String? hintText;
      25             :   final String? tooltip;
      26             :   final TextStyle? hintStyle;
      27             :   final Color? hintColor;
      28             :   final bool withLabel;
      29             : 
      30           2 :   const ListSelector({
      31             :     super.key,
      32             :     required this.options,
      33             :     required this.setState,
      34             :     this.hintText,
      35             :     this.tooltip,
      36             :     this.hintStyle,
      37             :     this.hintColor,
      38             :     this.value,
      39             :     this.withLabel = false,
      40             :   });
      41             : 
      42           2 :   @override
      43           2 :   ListSelectorState createState() => ListSelectorState();
      44             : }
      45             : 
      46             : class ListSelectorState<T extends ListSelector, K extends ListSelectorItem> extends State<T> {
      47             :   final textController = SearchController();
      48             :   late FocusController focusController;
      49           0 :   FntSelectorCallback? getItemBuilder() => null;
      50             : 
      51           0 :   void onTap(BuildContext context) async {
      52           0 :     focusController.blur();
      53             :     FocusController.force = true;
      54           0 :     final result = await Navigator.push(
      55             :       context,
      56           0 :       MaterialPageRoute(
      57           0 :         builder: (context) => ListSelectorPage(
      58           0 :           options: widget.options,
      59           0 :           result: widget.value,
      60           0 :           tooltip: widget.tooltip ?? widget.hintText ?? '...',
      61           0 :           itemBuilder: getItemBuilder(),
      62             :         ),
      63             :       ),
      64             :     );
      65             :     FocusController.force = false;
      66           0 :     widget.setState(result);
      67           0 :     WidgetsBinding.instance.addPostFrameCallback((_) => focusController.onEditingComplete(this));
      68             :   }
      69             : 
      70           2 :   @override
      71             :   Widget build(BuildContext context) {
      72           4 :     focusController = FocusWrapper.of(context) ?? FocusController();
      73           2 :     final indent = ThemeHelper.getIndent(1.5);
      74           6 :     final hintStyle = context.textTheme.tooltipMedium.copyWith(overflow: TextOverflow.ellipsis);
      75           4 :     final labelStyle = context.textTheme.tooltipSmall;
      76          24 :     K? item = widget.value != null ? widget.options.cast().where((e) => e.equal(widget.value?.id)).firstOrNull : null;
      77             : 
      78           2 :     return InkWell(
      79           4 :       autofocus: focusController.isFocused(this),
      80           8 :       focusNode: focusController.bind(this, context: context, value: widget.value),
      81           2 :       child: TapWidget(
      82           4 :         tooltip: widget.tooltip ?? '',
      83           0 :         onTap: () => onTap(context),
      84           0 :         onFocusChange: (v) => v ? focusController.scrollToFocusedElement(this) : null,
      85           2 :         child: Container(
      86             :           width: double.infinity,
      87           4 :           color: context.colorScheme.fieldBackground,
      88           4 :           child: LayoutBuilder(builder: (_, constraints) {
      89           2 :             return RowWidget(
      90           6 :               chunk: [null, ThemeHelper.barHeight - ThemeHelper.getIndent()],
      91           2 :               maxWidth: constraints.maxWidth,
      92             :               indent: 0.0,
      93           2 :               children: [
      94           2 :                 [
      95           2 :                   Container(
      96           2 :                     padding: EdgeInsets.fromLTRB(
      97           2 :                       indent / 1.5,
      98           4 :                       widget.withLabel && item != null ? 1 : indent,
      99           2 :                       AppDesign.isRightToLeft() ? ThemeHelper.getIndent() : 0,
     100           4 :                       widget.withLabel && item != null ? indent / 2 : indent,
     101             :                     ),
     102           6 :                     constraints: BoxConstraints(maxWidth: constraints.maxWidth - ThemeHelper.barHeight),
     103             :                     child: item != null
     104           4 :                         ? widget.withLabel
     105           0 :                             ? Column(
     106           0 :                                 mainAxisAlignment: AppDesign.getAlignment<MainAxisAlignment>(),
     107           0 :                                 crossAxisAlignment: AppDesign.getAlignment(),
     108           0 :                                 children: [
     109           0 :                                   TextWrapper(widget.hintText ?? '...', style: labelStyle),
     110           0 :                                   item.build(context),
     111             :                                 ],
     112             :                               )
     113           2 :                             : item.build(context)
     114           2 :                         : TextWrapper(
     115           4 :                             widget.hintText ?? '...',
     116           4 :                             style: widget.hintStyle ?? hintStyle,
     117             :                           ),
     118             :                   ),
     119             :                 ],
     120           2 :                 [
     121           2 :                   Padding(
     122           4 :                     padding: EdgeInsets.only(top: indent / 3),
     123           2 :                     child: ExcludeFocus(
     124           2 :                       child: IconButton(
     125           4 :                         tooltip: widget.hintText ?? '...',
     126           6 :                         icon: Icon(Icons.arrow_drop_down, color: widget.hintStyle?.color),
     127           0 :                         onPressed: () => onTap(context),
     128             :                       ),
     129             :                     ),
     130             :                   ),
     131             :                 ],
     132             :               ],
     133             :             );
     134             :           }),
     135             :         ),
     136             :       ),
     137             :     );
     138             :   }
     139             : }

Generated by: LCOV version 1.14