UNPKG

reakit

Version:

Toolkit for building accessible rich web apps with React

314 lines (282 loc) 9.38 kB
import { _ as _objectWithoutPropertiesLoose, a as _objectSpread2 } from '../_rollupPluginBabelHelpers-1f0bf8c2.js'; import { useReducer, useCallback, useEffect } from 'react'; import { useLiveRef } from 'reakit-utils/useLiveRef'; import { useSealedState } from 'reakit-utils/useSealedState'; import { useUpdateEffect } from 'reakit-utils/useUpdateEffect'; import '../Id/IdProvider.js'; import { unstable_useIdState } from '../Id/IdState.js'; import { isEmpty } from 'reakit-utils/isEmpty'; import { unstable_getIn } from './utils/getIn.js'; import { isPromise } from 'reakit-utils/isPromise'; import { isPlainObject } from 'reakit-utils/isPlainObject'; import { isObject } from 'reakit-utils/isObject'; import { unstable_setAllIn } from './utils/setAllIn.js'; import 'reakit-utils/toArray'; import 'reakit-utils/isInteger'; import { unstable_setIn } from './utils/setIn.js'; function filterAllEmpty(object) { if (Array.isArray(object)) { return object.filter(function (value) { if (isPlainObject(value) || Array.isArray(value)) { return filterAllEmpty(value); } return true; }); } var result = {}; var keys = Object.keys(object); for (var _i = 0, _keys = keys; _i < _keys.length; _i++) { var key = _keys[_i]; var k = key; var value = object[k]; result[k] = isPlainObject(value) || Array.isArray(value) ? filterAllEmpty(value) : object[k]; } return result; } function hasMessages(errors) { return isObject(errors) && !isEmpty(errors); } function getMessages(stateMessages, actionMessages) { return !isEmpty(actionMessages) ? actionMessages : isEmpty(stateMessages) ? stateMessages : {}; } function reducer(state, action) { switch (action.type) { case "reset": { return _objectSpread2(_objectSpread2({}, state), {}, { values: state.initialValues, touched: {}, errors: {}, messages: {}, valid: true, validating: false, submitting: false, submitFailed: 0, submitSucceed: 0 }); } case "startValidate": { return _objectSpread2(_objectSpread2({}, state), {}, { validating: true }); } case "endValidate": { return _objectSpread2(_objectSpread2({}, state), {}, { validating: false, errors: getMessages(state.errors, action.errors), messages: getMessages(state.messages, action.messages), valid: !hasMessages(action.errors) }); } case "startSubmit": { return _objectSpread2(_objectSpread2({}, state), {}, { // @ts-ignore TS bug touched: unstable_setAllIn(state.values, true), submitting: true }); } case "endSubmit": { var valid = !hasMessages(action.errors); return _objectSpread2(_objectSpread2({}, state), {}, { valid: valid, submitting: false, errors: getMessages(state.errors, action.errors), messages: getMessages(state.messages, action.messages), submitSucceed: valid ? state.submitSucceed + 1 : state.submitSucceed, submitFailed: valid ? state.submitFailed : state.submitFailed + 1 }); } case "update": { var _name = action.name, _value = action.value; var nextValue = typeof _value === "function" ? _value(unstable_getIn(state.values, _name)) : _value; return _objectSpread2(_objectSpread2({}, state), {}, { values: unstable_setIn(state.values, _name, nextValue != null ? nextValue : "") }); } case "blur": { return _objectSpread2(_objectSpread2({}, state), {}, { touched: unstable_setIn(state.touched, action.name, true) }); } case "push": { var array = unstable_getIn(state.values, action.name, []); return _objectSpread2(_objectSpread2({}, state), {}, { values: unstable_setIn(state.values, action.name, [].concat(array, [action.value])) }); } case "remove": { var _array = unstable_getIn(state.values, action.name, []).slice(); delete _array[action.index]; return _objectSpread2(_objectSpread2({}, state), {}, { values: unstable_setIn(state.values, action.name, _array) }); } default: { throw new Error(); } } } function unstable_useFormState(initialState) { if (initialState === void 0) { initialState = {}; } var _useSealedState = useSealedState(initialState), _useSealedState$value = _useSealedState.values, initialValues = _useSealedState$value === void 0 ? {} : _useSealedState$value, _useSealedState$valid = _useSealedState.validateOnBlur, validateOnBlur = _useSealedState$valid === void 0 ? true : _useSealedState$valid, _useSealedState$valid2 = _useSealedState.validateOnChange, validateOnChange = _useSealedState$valid2 === void 0 ? true : _useSealedState$valid2, _useSealedState$reset = _useSealedState.resetOnSubmitSucceed, resetOnSubmitSucceed = _useSealedState$reset === void 0 ? false : _useSealedState$reset, _useSealedState$reset2 = _useSealedState.resetOnUnmount, resetOnUnmount = _useSealedState$reset2 === void 0 ? true : _useSealedState$reset2, onValidate = _useSealedState.onValidate, onSubmit = _useSealedState.onSubmit, sealed = _objectWithoutPropertiesLoose(_useSealedState, ["values", "validateOnBlur", "validateOnChange", "resetOnSubmitSucceed", "resetOnUnmount", "onValidate", "onSubmit"]); var onValidateRef = useLiveRef(typeof initialState !== "function" ? initialState.onValidate : onValidate); var onSubmitRef = useLiveRef(typeof initialState !== "function" ? initialState.onSubmit : onSubmit); var id = unstable_useIdState(sealed); var _React$useReducer = useReducer(reducer, { initialValues: initialValues, values: initialValues, touched: {}, errors: {}, messages: {}, valid: true, validating: false, submitting: false, submitFailed: 0, submitSucceed: 0 }), _React$useReducer$ = _React$useReducer[0], _ = _React$useReducer$.initialValues, state = _objectWithoutPropertiesLoose(_React$useReducer$, ["initialValues"]), dispatch = _React$useReducer[1]; var validate = useCallback(function (vals) { if (vals === void 0) { vals = state.values; } return new Promise(function (resolve) { if (onValidateRef.current) { var response = onValidateRef.current(vals); if (isPromise(response)) { dispatch({ type: "startValidate" }); } resolve(Promise.resolve(response).then(function (messages) { dispatch({ type: "endValidate", messages: messages }); return messages; })); } else { resolve(undefined); } }).catch(function (errors) { dispatch({ type: "endValidate", errors: errors }); throw errors; }); }, [state.values]); useUpdateEffect(function () { if (validateOnChange) { validate().catch(function () {}); } }, [validate, validateOnChange]); useEffect(function () { if (resetOnUnmount) { return function () { dispatch({ type: "reset" }); }; } return undefined; }, [resetOnUnmount]); return _objectSpread2(_objectSpread2(_objectSpread2({}, id), state), {}, { values: state.values, validate: validate, reset: useCallback(function () { return dispatch({ type: "reset" }); }, []), submit: useCallback(function () { dispatch({ type: "startSubmit" }); return validate().then(function (validateMessages) { if (onSubmitRef.current) { return Promise.resolve(onSubmitRef.current(filterAllEmpty(state.values))).then(function (submitMessages) { var messages = _objectSpread2(_objectSpread2({}, validateMessages), submitMessages); dispatch({ type: "endSubmit", messages: messages }); }); } return dispatch({ type: "endSubmit", messages: validateMessages }); }).then(function () { if (resetOnSubmitSucceed) { dispatch({ type: "reset" }); } }).catch(function (errors) { dispatch({ type: "endSubmit", errors: errors }); }); }, [validate]), update: useCallback(function (name, value) { return dispatch({ type: "update", name: name, value: value }); }, []), blur: useCallback(function (name) { dispatch({ type: "blur", name: name }); if (validateOnBlur) { validate().catch(function () {}); } }, [validate]), push: useCallback(function (name, value) { return dispatch({ type: "push", name: name, value: value }); }, []), remove: useCallback(function (name, index) { return dispatch({ type: "remove", name: name, index: index }); }, []) }); } export { unstable_useFormState };