react-bfm
Version:
A basic field / form manager for React using hooks
90 lines • 4.36 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
var _excluded = ["validator", "dirtyCheck", "transformValueToInput", "transformEventToValue", "onChange", "onFocus", "onBlur"],
_excluded2 = ["namespace", "fieldName", "initialValue"];
import { useCallback, useContext, useEffect, useRef } from 'react';
import { BFMHooksContext } from './context';
import { defaultEventToValue, defaultValueToInput } from './helpers';
import { useFieldValue } from './field/hooks';
export var useConnectField = function useConnectField(props) {
var _useContext = useContext(BFMHooksContext),
blurField = _useContext.blurField,
changeField = _useContext.changeField,
initialValueField = _useContext.initialValueField,
focusField = _useContext.focusField,
initField = _useContext.initField,
removeField = _useContext.removeField;
var validator = props.validator,
dirtyCheck = props.dirtyCheck,
_props$transformValue = props.transformValueToInput,
transformValueToInput = _props$transformValue === void 0 ? defaultValueToInput : _props$transformValue,
transformEventToValue = props.transformEventToValue,
onChange = props.onChange,
onFocus = props.onFocus,
onBlur = props.onBlur,
staticProps = _objectWithoutPropertiesLoose(props, _excluded);
// For storing static props see bellow.
var propsRef = useRef(staticProps);
// Hook specific props.
var namespace = staticProps.namespace,
fieldName = staticProps.fieldName,
initialValue = staticProps.initialValue,
otherProps = _objectWithoutPropertiesLoose(staticProps, _excluded2);
// Throw an error if namespace and/or fieldName changes after first rendering, because it's not supported
// Dynamically changing these values can result in strange side effects. It's better to render a new component.
var namesRef = useRef({
namespace: namespace,
fieldName: fieldName
});
useEffect(function () {
if (namesRef.current.namespace !== namespace || namesRef.current.fieldName !== fieldName) {
throw new Error('Changing the namespace and/or fieldName of an already rendered component is not supported.');
}
}, [namespace, fieldName]);
// Store static props for use in the validator callback.
// This way you can (re-)use for example: required, minlength, maxlength, etc. in the validator
// eslint-disable-next-line react-hooks/refs -- Intentional: avoid recreating getError on every render
propsRef.current = staticProps;
var getError = useCallback(function (_value) {
return validator && validator(_value, propsRef.current);
}, [validator]);
var value = useFieldValue(namespace, fieldName);
useEffect(function () {
// init field on mount
initField(namespace, fieldName, initialValue, getError(initialValue));
// remove field on unmount
return function () {
removeField(namespace, fieldName);
};
}, []); // eslint-disable-line react-hooks/exhaustive-deps
// update initialValue on change, see `initialValueField` function for more info
useEffect(function () {
initialValueField(namesRef.current.namespace, namesRef.current.fieldName, initialValue, getError(initialValue));
}, [initialValueField, getError, initialValue]);
var handleFocus = useCallback(function (event) {
focusField(namesRef.current.namespace, namesRef.current.fieldName);
if (onFocus) {
onFocus(event);
}
}, [onFocus, focusField]);
var handleChange = useCallback(function (arg1, arg2, arg3, arg4, arg5) {
var value = transformEventToValue ? transformEventToValue(arg1, arg2, arg3, arg4, arg5) : defaultEventToValue(arg1);
var error = getError(value);
changeField(namesRef.current.namespace, namesRef.current.fieldName, value, error, dirtyCheck);
if (onChange) {
onChange(arg1, arg2, arg3, arg4, arg5);
}
}, [transformEventToValue, getError, changeField, dirtyCheck, onChange]);
var handleBlur = useCallback(function (event) {
blurField(namesRef.current.namespace, namesRef.current.fieldName);
if (onBlur) {
onBlur(event);
}
}, [onBlur, blurField]);
return _extends({}, otherProps, {
value: transformValueToInput(value),
onFocus: handleFocus,
onChange: handleChange,
onBlur: handleBlur
});
};