UNPKG

react-bfm

Version:

A basic field / form manager for React using hooks

90 lines 4.36 kB
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 }); };