use-form-fields
Version:
[Demo](https://vlad88vlad.github.io/use-form-fields)
165 lines (156 loc) • 8.39 kB
JavaScript
import { useReducer, useCallback, useMemo } from 'react';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var getValue = function (type, value, checked) {
if (type === void 0) { type = ''; }
if (value === void 0) { value = ''; }
if (checked === void 0) { checked = false; }
return (type === 'checkbox' ? (checked !== null && checked !== void 0 ? checked : false) : (value !== null && value !== void 0 ? value : ''));
};
var toJSON = function (fields) { return Object.keys(fields).reduce(function (acc, key) {
var _a;
return (__assign(__assign({}, acc), (_a = {}, _a[key] = getValue(fields[key].type, fields[key].value, fields[key].checked), _a)));
}, {}); };
var formTypeFields = {
radio: function (field, name, onChange, fieldProps) {
var _a;
return ({
radioOptions: (_a = field === null || field === void 0 ? void 0 : field.options) === null || _a === void 0 ? void 0 : _a.map(function (radioOption) { return (__assign({ type: 'radio', key: radioOption.option, checked: field.value === radioOption.option, value: radioOption.option, name: name, onChange: onChange }, fieldProps)); }),
});
},
checkbox: function (field, name, onChange, fieldProps) { return ({
fieldProps: __assign({ checked: field.checked, required: field.required, type: 'checkbox', onChange: onChange, name: (field === null || field === void 0 ? void 0 : field.name) || name }, fieldProps),
}); },
};
var getFieldProps = function (_a) {
var _b = _a.type, type = _b === void 0 ? '' : _b, field = _a.field, name = _a.name, onChange = _a.onChange, fieldProps = _a.fieldProps;
return (formTypeFields[type]
? formTypeFields[type](field, name, onChange, fieldProps) : {
fieldProps: __assign({ value: getValue(type, field.value), required: field.required, name: (field === null || field === void 0 ? void 0 : field.name) || name, onChange: onChange, type: type }, fieldProps),
});
};
var getFormFields = function (_a) {
var fields = _a.fields, onChange = _a.onChange, toValid = _a.toValid, setValue = _a.setValue, setError = _a.setError;
return (Object.keys(fields).reduce(function (acc, name) {
var _a;
var _b, _c, _d, _e, _f;
return (__assign(__assign({}, acc), (_a = {}, _a[name] = __assign({ value: getValue((_b = fields[name]) === null || _b === void 0 ? void 0 : _b.type, fields[name].value, (_c = fields[name]) === null || _c === void 0 ? void 0 : _c.checked), error: (_e = (_d = fields[name]) === null || _d === void 0 ? void 0 : _d.error) !== null && _e !== void 0 ? _e : null, toValid: function () { return toValid(name); }, setValue: setValue(name), setError: setError(name) }, getFieldProps({
type: (_f = fields[name]) === null || _f === void 0 ? void 0 : _f.type,
field: fields[name],
name: name,
onChange: onChange(name),
fieldProps: fields[name].fieldProps,
})), _a)));
}, {}));
};
var validateField = function (value, validations, required, minLen, maxLen) {
if (validations === void 0) { validations = []; }
if (required && !value) {
return 'required';
}
if (minLen && minLen > (value === null || value === void 0 ? void 0 : value.length)) {
return "min length " + minLen;
}
if (maxLen && maxLen < (value === null || value === void 0 ? void 0 : value.length)) {
return "max length " + maxLen;
}
// eslint-disable-next-line no-restricted-syntax
for (var _i = 0, validations_1 = validations; _i < validations_1.length; _i++) {
var func = validations_1[_i];
var err = (typeof func === 'function'
? func(value)
: null);
if (err) {
return err;
}
}
return null;
};
function fieldsReducer(state, field) {
var _a;
var _b, _c, _d;
return __assign(__assign({}, state), (_a = {}, _a[field.name] = __assign(__assign({}, state[field.name]), { value: (_b = field.value) !== null && _b !== void 0 ? _b : '', checked: (_c = field.checked) !== null && _c !== void 0 ? _c : false, error: (_d = field.error) !== null && _d !== void 0 ? _d : null }), _a));
}
var useForm = function (formSchema) {
if (formSchema === void 0) { formSchema = {}; }
var _a = useReducer(fieldsReducer, formSchema), fields = _a[0], dispatchField = _a[1];
var onChange = useCallback(function (name) { return function (event) {
var _a = event.target, checked = _a.checked, value = _a.value;
var _b = fields[name], validations = _b.validations, _c = _b.required, required = _c === void 0 ? false : _c, _d = _b.immediatelyValidate, immediatelyValidate = _d === void 0 ? true : _d, type = _b.type, minLen = _b.minLen, maxLen = _b.maxLen;
var errorMessage = immediatelyValidate
? validateField(value, validations, required, minLen, maxLen) : null;
dispatchField({
error: errorMessage,
name: name,
checked: checked,
value: getValue(type, value, checked),
});
}; }, [fields]);
var setError = function (name) { return function (errorMessage) {
dispatchField({
error: errorMessage,
name: name,
});
}; };
var setValue = function (name) { return function (value) {
var _a = fields[name], validations = _a.validations, _b = _a.required, required = _b === void 0 ? false : _b, _c = _a.immediatelyValidate, immediatelyValidate = _c === void 0 ? true : _c, type = _a.type, minLen = _a.minLen, prevValue = _a.value, maxLen = _a.maxLen;
var nextValue = typeof value === 'function' ? value({ prevValue: prevValue }) : value;
var errorMessage = immediatelyValidate
? validateField(nextValue, validations, required, minLen, maxLen) : null;
dispatchField({
error: errorMessage,
name: name,
value: getValue(type, nextValue),
});
}; };
var toValid = function (name) {
var _a = fields[name], value = _a.value, validations = _a.validations, _b = _a.required, required = _b === void 0 ? false : _b, _c = _a.checked, checked = _c === void 0 ? false : _c, minLen = _a.minLen, maxLen = _a.maxLen;
var error = validateField(value, validations, required, minLen, maxLen);
dispatchField({
error: error,
name: name,
value: value,
checked: checked,
});
return error;
};
var form = useMemo(function () { return (getFormFields({
fields: fields,
onChange: onChange,
toValid: toValid,
setValue: setValue,
setError: setError,
})); }, [fields, onChange]);
var toValidate = function () { return (Object.keys(fields)
.map(function (key) { return !!toValid(key); })
.every(function (error) { return !error; })); };
return {
form: {
fields: form,
toJSON: function () { return toJSON(fields); },
toValidate: toValidate,
},
};
};
export { useForm };
//# sourceMappingURL=index.es.js.map