Skip to content
38 changes: 38 additions & 0 deletions lib/src/value_accessors/control_value_accessor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,31 @@ import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:reactive_forms/reactive_forms.dart';

typedef ModelToViewCallback<ModelDataType, ViewDataType> = ViewDataType?
Function(ModelDataType? modelValue);

typedef ViewToModelCallback<ModelDataType, ViewDataType> = ModelDataType?
Function(ViewDataType? modelValue);

/// Type of the function to be called when the control emits a value changes
/// event.
typedef ChangeFunction<K> = dynamic Function(K? value);

/// Defines an interface that acts as a bridge between [FormControl] and a
/// reactive native widget.
abstract class ControlValueAccessor<ModelDataType, ViewDataType> {
ControlValueAccessor();

/// Create simple [ControlValueAccessor] that maps the [FormControl] value
factory ControlValueAccessor.create({
required ModelToViewCallback<ModelDataType, ViewDataType> modelToView,
required ViewToModelCallback<ModelDataType, ViewDataType> valueToModel,
}) =>
_WrapperValueAccessor<ModelDataType, ViewDataType>(
modelToViewValue: modelToView,
valueToModelValue: valueToModel,
);

FormControl<ModelDataType>? _control;
ChangeFunction<ViewDataType>? _onChange;
bool _viewToModelChange = false;
Expand Down Expand Up @@ -91,3 +109,23 @@ abstract class ControlValueAccessor<ModelDataType, ViewDataType> {
}
}
}

class _WrapperValueAccessor<ModelDataType, ViewDataType>
extends ControlValueAccessor<ModelDataType, ViewDataType> {
final ModelToViewCallback<ModelDataType, ViewDataType> _modelToViewValue;
final ViewToModelCallback<ModelDataType, ViewDataType> _valueToModelValue;

_WrapperValueAccessor({
required ModelToViewCallback<ModelDataType, ViewDataType> modelToViewValue,
required ViewToModelCallback<ModelDataType, ViewDataType> valueToModelValue,
}) : _modelToViewValue = modelToViewValue,
_valueToModelValue = valueToModelValue;

@override
ViewDataType? modelToViewValue(ModelDataType? modelValue) =>
_modelToViewValue(modelValue);

@override
ModelDataType? viewToModelValue(ViewDataType? viewValue) =>
_valueToModelValue(viewValue);
}