ListField<T> constructor

ListField<T>({
  1. ListFieldController<T>? controller,
  2. FocusNode? focusNode,
  3. Widget? getLeading(
    1. BuildContext context,
    2. T model, {
    3. required bool enabled,
    })?,
  4. Widget? getTitle(
    1. BuildContext context,
    2. T model, {
    3. required bool enabled,
    })?,
  5. Widget? getSubtitle(
    1. BuildContext context,
    2. T model, {
    3. required bool enabled,
    })?,
  6. String? labelPrefix,
  7. String? label,
  8. Widget? labelWidget,
  9. FormFieldValidator<List<T>?>? validator,
  10. FormFieldSetter<List<T>>? onSaved,
  11. List<T>? initialValue,
  12. bool enabled = true,
  13. AutovalidateMode? autovalidateMode = AutovalidateMode.disabled,
  14. InputDecoration? decoration,
  15. EdgeInsets padding = const EdgeInsets.all(8),
  16. EdgeInsets? contentPadding,
  17. bool showAddButton = true,
  18. IconData addButtonIcon = FontAwesomeIcons.plus,
  19. String addButtonLabel = 'Adicionar',
  20. Future<List<T>?> addButtonOnTap(
    1. BuildContext context,
    2. List<T> data
    )?,
  21. bool canDelete(
    1. T model
    )?,
  22. IconData deleteIcon = FontAwesomeIcons.trashCan,
  23. String deleteMessage(
    1. BuildContext context,
    2. T model
    )?,
  24. String deleteDefaultMessage = 'Deseja excluir o ítem?',
  25. Future<T?> itemOnTap(
    1. BuildContext context,
    2. T model
    )?,
  26. int? sizeExtraSmall,
  27. int? sizeSmall,
  28. int? sizeMedium,
  29. int? sizeLarge,
  30. int? sizeExtraLarge,
  31. double? minHeight,
  32. Key? key,
})

Implementation

ListField({
  this.controller,
  this.focusNode,
  this.getLeading,
  this.getTitle,
  this.getSubtitle,
  String? labelPrefix,
  String? label,
  Widget? labelWidget,
  FormFieldValidator<List<T>?>? validator,
  super.onSaved,
  List<T>? initialValue,
  super.enabled,
  super.autovalidateMode = AutovalidateMode.disabled,
  InputDecoration? decoration,
  EdgeInsets padding = const EdgeInsets.all(8),
  EdgeInsets? contentPadding,
  bool showAddButton = true,
  this.addButtonIcon = FontAwesomeIcons.plus,
  this.addButtonLabel = 'Adicionar',
  this.addButtonOnTap,
  this.canDelete,
  this.deleteIcon = FontAwesomeIcons.trashCan,
  this.deleteMessage,
  this.deleteDefaultMessage = 'Deseja excluir o ítem?',
  this.itemOnTap,
  super.sizeExtraSmall,
  super.sizeSmall,
  super.sizeMedium,
  super.sizeLarge,
  super.sizeExtraLarge,
  super.minHeight,
  super.key,
}) : assert(
       initialValue == null || controller == null,
       'initialValue or controller must be null.',
     ),
     assert(
       label == null || labelWidget == null,
       'label or labelWidget must be null.',
     ),
     super(
       initialValue: controller != null ? controller.value : initialValue,
       validator: enabled ? validator : null,
       builder: (FormFieldState<List<T>?> field) {
         final _ListFieldState<T> state = field as _ListFieldState<T>;

         final ThemeData theme = Theme.of(state.context);

         final bool hasFocus = state._effectiveFocusNode.hasFocus;

         final InputDecoration effectiveDecoration =
             (decoration ??
                     InputDecoration(
                       border: const OutlineInputBorder(),
                       counterText: '',
                       label: labelWidget,
                       labelText: <String?>[
                         labelPrefix,
                         label,
                       ].nonNulls.join(' - '),
                       contentPadding: contentPadding,
                     ))
                 .applyDefaults(theme.inputDecorationTheme)
                 .copyWith(enabled: enabled, errorText: state.errorText);

         return Padding(
           padding: padding,
           child: Focus(
             focusNode: state._effectiveFocusNode,
             canRequestFocus: enabled,
             skipTraversal: !enabled,
             child: MouseRegion(
               cursor: enabled
                   ? SystemMouseCursors.click
                   : SystemMouseCursors.basic,
               onEnter: (_) => state.hovering(enter: true),
               onExit: (_) => state.hovering(enter: false),
               child: InputDecorator(
                 decoration: effectiveDecoration,
                 isFocused: hasFocus,
                 isHovering: state._isHovering,
                 child: ValueListenableBuilder<List<T>>(
                   valueListenable: state._effectiveController,
                   builder: (_, List<T> value, _) {
                     return Column(
                       mainAxisSize: MainAxisSize.min,
                       crossAxisAlignment: CrossAxisAlignment.stretch,
                       children: <Widget>[
                         /// Add Button
                         if (showAddButton)
                           _ListAddButton<T>(state, enabled: enabled),

                         /// List Items
                         ...value.map(
                           (T model) => _ListItem<T>(
                             context: state.context,
                             widget: state.widget,
                             focusNode: state._effectiveFocusNode,
                             model: model,
                             enabled: enabled,
                             onRemove: (T model) =>
                                 state.didChange(state.value?..remove(model)),
                             onTap: state.widget.itemOnTap == null
                                 ? null
                                 : (T model) async {
                                     final T? newModel = await state
                                         .widget
                                         .itemOnTap
                                         ?.call(state.context, model);

                                     if (newModel == null) return;

                                     state.didChange(state.value);
                                   },
                           ),
                         ),
                       ].intersperse(const Divider()),
                     );
                   },
                 ),
               ),
             ),
           ),
         );
       },
     );