Skip to content
48 changes: 48 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 _ModelToViewValueCallback<ModelDataType, ViewDataType> = ViewDataType?
Function(ModelDataType? modelValue);

typedef _ViewToModelValueCallback<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({
_ModelToViewValueCallback<ModelDataType, ViewDataType>? modelToView,
_ViewToModelValueCallback<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,33 @@ abstract class ControlValueAccessor<ModelDataType, ViewDataType> {
}
}
}

class _WrapperValueAccessor<ModelDataType, ViewDataType>
extends ControlValueAccessor<ModelDataType, ViewDataType> {
final _ModelToViewValueCallback<ModelDataType, ViewDataType>?
_modelToViewValue;
final _ViewToModelValueCallback<ModelDataType, ViewDataType>?
_valueToModelValue;

_WrapperValueAccessor({
_ModelToViewValueCallback<ModelDataType, ViewDataType>? modelToViewValue,
_ViewToModelValueCallback<ModelDataType, ViewDataType>? valueToModelValue,
}) : _modelToViewValue = modelToViewValue,
_valueToModelValue = valueToModelValue;

@override
ViewDataType? modelToViewValue(ModelDataType? modelValue) {
if (_modelToViewValue != null && modelValue != null) {
return _modelToViewValue!.call(modelValue);
}
return null;
}

@override
ModelDataType? viewToModelValue(ViewDataType? viewValue) {
if (_valueToModelValue != null) {
return _valueToModelValue?.call(viewValue);
}
return control?.value;
}
}