UNPKG

styled-hook-form

Version:

React form library for styled-components based on grommet and react-hook-form

167 lines (166 loc) 8.34 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const react_hook_form_1 = require("react-hook-form"); const use_debounce_1 = require("use-debounce"); const es6_1 = __importDefault(require("fast-deep-equal/es6")); const comp_1 = require("../../components/utils/comp"); const change_event_store_1 = require("./change-event-store"); const internal_form_context_1 = require("./internal-form-context"); const types_1 = require("../../components/utils/types"); const Form = (props) => { const { methodsRef, onSubmit, children, changeHandlers: changeHandlersProp, submitTreshould, autoSubmit: autoSubmitProp, autoSubmitFields: autoSubmitFieldsProp, formMethods, options } = props, rest = __rest(props, ["methodsRef", "onSubmit", "children", "changeHandlers", "submitTreshould", "autoSubmit", "autoSubmitFields", "formMethods", "options"]); //call useForm regardless of formMethods being none null, cause conditionaly calling hook would violate react hook rules let methods = react_hook_form_1.useForm(Object.assign({ mode: "onTouched" }, options)); if (formMethods) { methods = formMethods; } const changeHandlers = react_1.useRef([]); const autoSubmitFields = react_1.useRef([]); const [autoSubmit, updateAutoSubmit] = react_1.useState(autoSubmitProp); const updateChangeHandlers = react_1.useCallback((newHandlers) => (changeHandlers.current = [...changeHandlers.current, ...newHandlers]), []); const updateAutoSubmitFields = react_1.useCallback((newFields) => (autoSubmitFields.current = [...autoSubmitFields.current, ...newFields]), []); react_1.useEffect(() => { if (changeHandlersProp) { updateChangeHandlers(changeHandlersProp); } }, [changeHandlersProp, updateChangeHandlers]); react_1.useEffect(() => { if (autoSubmitFieldsProp) { updateAutoSubmitFields(autoSubmitFieldsProp); } }, [autoSubmitFieldsProp, updateAutoSubmitFields]); react_1.useEffect(() => { updateAutoSubmit(autoSubmitProp); }, [autoSubmitProp]); let refObj = { methods, changeHandlers: new change_event_store_1.ChangeEventStore(), }; const internalMethodsRef = react_1.useRef(refObj); if (methodsRef && methods) { if (typeof methodsRef === "function") { methodsRef(refObj); } else { methodsRef.current = refObj; } } const { handleSubmit, reset, control } = methods; const valuesRef = react_1.useRef(null); let defaultValues = props.options.defaultValues; react_1.useEffect(() => { var _a; const values = methods.getValues(); const newValues = formMethods ? !comp_1.isEmptyObject(values) ? values : defaultValues : defaultValues; if (!methods.formState.isDirty && ((comp_1.isEmptyObject(valuesRef.current) && !comp_1.isEmptyObject(newValues)) || (Object.keys((_a = valuesRef.current) !== null && _a !== void 0 ? _a : {}).length === Object.keys(newValues !== null && newValues !== void 0 ? newValues : {}).length && !es6_1.default(valuesRef.current, newValues)))) { reset(newValues); valuesRef.current = newValues; } }, [defaultValues, formMethods, methods, methods.formState.isDirty, reset]); const onFormSubmit = (values) => { onSubmit && onSubmit(values); return true; }; const debuncedSubmit = use_debounce_1.useDebouncedCallback((values) => { onFormSubmit(values); }, submitTreshould); react_1.useEffect(() => { let watchSubscriptions = control._subjects.watch.subscribe({ next: ({ name: ChangingName }) => { var _a, _b, _c; const getLiveValue = (name, defaultValues) => control._getWatch(name, defaultValues, false); //@ts-ignore if (!control._avoidNotify) { if (autoSubmit) { let shouldSubmit = ChangingName ? !autoSubmitFields.current.length || (autoSubmitFields && autoSubmitFields.current.some((f) => f.name === ChangingName)) : true; if (shouldSubmit) { debuncedSubmit(getLiveValue()); } } const fieldsToNotify = new Set(ChangingName ? [ChangingName] : [ ...((_a = changeHandlers.current.map((h) => h.name)) !== null && _a !== void 0 ? _a : []), ...((_b = internalMethodsRef.current.changeHandlers.getObservers().map((o) => o.name)) !== null && _b !== void 0 ? _b : []), ]).values(); for (const fieldName of fieldsToNotify) { const _value = getLiveValue(fieldName, props.options.defaultValues ? props.options.defaultValues[fieldName] : undefined); if (methodsRef) { (_c = internalMethodsRef.current.changeHandlers) === null || _c === void 0 ? void 0 : _c.emitChange(fieldName, _value); } let listener = changeHandlers.current.find((f) => f.name === fieldName); if (listener) { listener.handler(_value); } } } else { //@ts-ignore control._avoidNotify = null; } }, }); return () => watchSubscriptions.unsubscribe(); }, [ autoSubmit, props.options.defaultValues, changeHandlers, autoSubmitFields, debuncedSubmit, control, refObj.changeHandlers, methodsRef, ]); const handleFormSubmit = (e) => { e.stopPropagation(); handleSubmit(onFormSubmit)(e); }; const registerAutoSubmitField = react_1.useCallback((field) => { const _autoSubmitFields = autoSubmitFields.current; const fieldValues = types_1.makeArray(field).filter((f) => _autoSubmitFields.findIndex((inf) => inf.name === f.name) === -1); if (fieldValues.length) { updateAutoSubmitFields(fieldValues); } }, [updateAutoSubmitFields, autoSubmitFields]); const registerChangeHandler = react_1.useCallback((handler) => { const _changeHandlers = changeHandlers.current; const handlerValues = types_1.makeArray(handler).filter((h) => _changeHandlers.findIndex((inh) => inh.name === h.name) === -1); if (handlerValues.length) { updateChangeHandlers(handlerValues); } }, [changeHandlers, updateChangeHandlers]); return (jsx_runtime_1.jsx("form", Object.assign({ onSubmit: handleFormSubmit }, rest, { children: jsx_runtime_1.jsx(react_hook_form_1.FormProvider, Object.assign({}, methods, { children: jsx_runtime_1.jsx(internal_form_context_1.InternalFormContextProvider, Object.assign({ registerAutoSubmitField: registerAutoSubmitField, registerChangeHandler: registerChangeHandler }, { children: children && children(Object.assign({}, methods)) }), void 0) }), void 0) }), void 0)); }; exports.default = Form; Form.defaultProps = { autoSubmit: false, autoSubmitFields: [], submitTreshould: 500, };