UNPKG

@onesy/ui-react

Version:
201 lines (193 loc) 7.45 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import React from 'react'; import { capitalize, copy, is, setObjectValue } from '@onesy/utils'; import { useOnesyTheme } from '@onesy/style-react'; import validateModel from './validate'; const useForm = props => { const { values: values_ = {}, validate: validate_, rerenderOnUpdate = true, autoValidate, valueDefault, validDefault } = props; const theme = useOnesyTheme(); const l = theme.l; const [form, setForm] = React.useState({ value: valueDefault !== undefined ? valueDefault : {}, values: copy(values_ || {}), valid: validDefault !== undefined ? validDefault : false }); const refs = { form: React.useRef(form), value: React.useRef(copy(valueDefault !== undefined ? valueDefault : {})), values: React.useRef(copy(values_ || {})), valid: React.useRef(validDefault !== undefined ? validDefault : false) }; refs.form.current = form; const init = () => { const formNew = _objectSpread({}, refs.form.current); const { values } = formNew; const value = {}; const properties = Object.keys(values); properties.forEach(item => { const valueProperty = values[item]; if (valueProperty?.value !== undefined) { setObjectValue(value, item, copy(valueProperty.value)); } }); // update refs.value.current = value; setForm(previous => { return _objectSpread(_objectSpread({}, previous), {}, { value }); }); }; React.useEffect(() => { // init init(); }, []); const onChange = async (...args) => { const formNew_0 = _objectSpread({}, refs.form.current); const value_0 = {}; const valuesArgs = is('array', args[0]) ? args[0] : [args]; const options = valuesArgs[0][3] || {}; const rerenderOnUpdate_ = options.rerenderOnUpdate !== undefined ? options.rerenderOnUpdate : rerenderOnUpdate; const values_0 = refs.values.current; for (const arg of valuesArgs) { const [property_, value_, propertyNested] = arg; let property = values_0[property_]; if (!property) { values_0[property_] = { name: (propertyNested || property_)?.split('.')?.slice(-1)[0], touched: true }; property = values_0[property_]; } if (!propertyNested) property.value = value_;else setObjectValue(property.value, propertyNested, value_); property.touched = true; if (autoValidate) { // Validate the property if (property.required && property.value === undefined) { const name = is('function', property.propertyNameUpdate) ? property.propertyNameUpdate(property.name) : property.capitalize !== false ? capitalize(property.name) : property.name; property.error = `${l(name)} ${l('is required')}`; } else { property.error = undefined; // validations try { await validateModel(property, property_, formNew_0, { l }); } catch (error) { property.error = error.message; } } } } const properties_0 = Object.keys(values_0); let valid = autoValidate ? properties_0.every(item_0 => { const prop = values_0[item_0]; return !prop.error && (!prop.required || prop.value !== undefined); }) : refs.valid.current; if (autoValidate && is('function', validate_)) valid = valid && validate_(values_0, formNew_0); properties_0.forEach(item_1 => { const valueProperty_0 = values_0[item_1]; if (valueProperty_0?.value !== undefined) { setObjectValue(value_0, item_1, copy(valueProperty_0.value)); } }); // update refs.value.current = value_0; refs.values.current = values_0; refs.valid.current = valid; if (rerenderOnUpdate_) { setForm(previous_0 => { return _objectSpread(_objectSpread({}, previous_0), {}, { value: value_0, values: values_0, valid }); }); } }; const validate = async () => { const formNew_1 = _objectSpread({}, refs.form.current); const values_1 = refs.values.current; const value_1 = {}; const properties_1 = Object.keys(values_1); for (const item_2 of properties_1) { const property_0 = values_1[item_2]; // Validate the property if (property_0.required && property_0.value === undefined) { const name_0 = is('function', property_0.propertyNameUpdate) ? property_0.propertyNameUpdate(property_0.name) : property_0.capitalize !== false ? capitalize(property_0.name) : property_0.name; property_0.error = `${l(name_0)} ${l('is required')}`; } else { property_0.error = undefined; // validations try { await validateModel(property_0, item_2, formNew_1, { l }); property_0.error = undefined; } catch (error_0) { property_0.error = error_0.message; } } } let valid_0 = properties_1.every(item_3 => { const prop_0 = values_1[item_3]; return !prop_0.error && (!prop_0.required || prop_0.value !== undefined); }); if (is('function', validate_)) valid_0 = valid_0 && validate_(values_1, formNew_1); // value properties_1.forEach(item_4 => { const valueProperty_1 = values_1[item_4]; if (valueProperty_1?.value !== undefined) { setObjectValue(value_1, item_4, copy(valueProperty_1.value)); } }); // update refs.value.current = value_1; refs.values.current = values_1; refs.valid.current = valid_0; setForm(previous_1 => { return _objectSpread(_objectSpread({}, previous_1), {}, { value: value_1, values: values_1, valid: valid_0 }); }); return valid_0; }; const clear = () => { const formNew_2 = _objectSpread(_objectSpread({}, refs.form.current), {}, { value: copy(valueDefault !== undefined ? valueDefault : {}), values: copy(values_ || {}), valid: validDefault !== undefined ? validDefault : false }); // update refs.value.current = formNew_2.value; refs.values.current = formNew_2.values; refs.valid.current = formNew_2.valid; setForm(previous_2 => { return _objectSpread(_objectSpread({}, previous_2), formNew_2); }); }; return _objectSpread(_objectSpread({}, form), {}, { value: rerenderOnUpdate ? form.value : refs.value.current, values: rerenderOnUpdate ? form.values : refs.values.current, valid: rerenderOnUpdate ? form.valid : refs.valid.current, init, validate, onChange, clear, updateForm: setForm }); }; export default useForm;