@altiore/form
Version:
Form helper for building powerful forms
196 lines (195 loc) • 9.04 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useValidateInput = void 0;
var react_1 = require("react");
var isEqual_1 = __importDefault(require("lodash/isEqual"));
var consts_1 = require("../../../../@common/consts");
var use_is_mounted_1 = require("../../../../@common/hooks/use-is-mounted");
var types_1 = require("../../../../@common/types");
var utils_1 = require("../../../../@common/utils");
var DEF_ERRORS = [];
var useValidateInput = function (customRef, validators, hideErrorsInXSeconds, formRef, field, fieldType, nameFromProp) {
var _a, _b, _c;
if (hideErrorsInXSeconds === void 0) { hideErrorsInXSeconds = consts_1.DEF_HIDE_ERROR_IN_X_SEC; }
var _d = (0, react_1.useState)(false), mounted = _d[0], setMounted = _d[1];
(0, react_1.useEffect)(function () {
setMounted(true);
}, [setMounted]);
var name = (0, react_1.useMemo)(function () { return (field === null || field === void 0 ? void 0 : field.name) || nameFromProp; }, [field === null || field === void 0 ? void 0 : field.name, nameFromProp]);
var getMounted = (0, use_is_mounted_1.useIsMounted)();
var inputRef = (0, react_1.useMemo)(function () {
var ERROR_MESSAGE = "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043D\u0430\u0439\u0442\u0438 \u0441\u0441\u044B\u043B\u043A\u0443 \u043D\u0430 \u043F\u043E\u043B\u0435 \u0432\u0432\u043E\u0434\u0430 \"" + name + "\". \u0414\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u043E\u0435 \u0438\u043C\u044F \u0432\u0430\u0448\u0435\u043C\u0443 \u043F\u043E\u043B\u044E" +
' input, или используйте inputRef (используется по-умолчанию внутри inputProps)';
if (customRef.current) {
return customRef;
}
if (mounted && name) {
var ref = (0, utils_1.getNodeByName)(name, formRef);
if (ref) {
return ref;
}
else {
throw new Error(ERROR_MESSAGE);
}
}
return {
current: null,
};
}, [customRef, formRef, mounted, name]);
var getFormValueByName = (0, react_1.useCallback)(function (name) {
return (0, utils_1.getValueByNodeName)(name, formRef);
}, [formRef]);
var _e = (0, react_1.useState)(DEF_ERRORS), errors = _e[0], setErrorsState = _e[1];
var _f = (0, react_1.useState)(DEF_ERRORS), warnings = _f[0], setWarningsState = _f[1];
var setErrors = (0, react_1.useCallback)(function (errors, force, isWarnings) {
var handler = function (s) {
if ((0, isEqual_1.default)(s, errors) && !force) {
return s;
}
if (timeout.current) {
clearTimeout(timeout.current);
}
if (typeof hideErrorsInXSeconds === 'number') {
timeout.current = setTimeout(function () {
setErrorsState([]);
}, hideErrorsInXSeconds * 1000);
}
return errors;
};
if (isWarnings) {
setWarningsState(handler);
}
else {
setErrorsState(handler);
}
}, [hideErrorsInXSeconds, setErrorsState, setWarningsState]);
var handleSetErrors = (0, react_1.useCallback)(function (errors, force, isWarnings) {
if (getMounted()) {
if (field === null || field === void 0 ? void 0 : field.setErrors) {
field.setErrors(errors, force, isWarnings);
}
else {
setErrors(errors, force, isWarnings);
}
}
}, [getMounted, field === null || field === void 0 ? void 0 : field.setErrors, setErrors]);
var timeout = (0, react_1.useRef)();
var handleFieldChanged = (0, react_1.useCallback)(function (e) {
var _a, _b;
e.preventDefault();
var errors = [];
var isMultiSelect = ((_a = e.target) === null || _a === void 0 ? void 0 : _a.tagName) === 'SELECT' &&
Boolean((_b = e.target) === null || _b === void 0 ? void 0 : _b.multiple);
if (isMultiSelect && fieldType !== types_1.FieldType.SELECT_MULTIPLE) {
throw new Error('Вы используете select со свойством multiple. Укажите' +
' FieldType.SELECT_MULTIPLE явно для корректной работы элемента');
}
// TODO: добавить дефолтные валидаторы
var hasValidation = Boolean((validators === null || validators === void 0 ? void 0 : validators.length) && e.target);
if (hasValidation) {
var value_1 = (0, utils_1.getValueByTypeAndTarget)(fieldType, e.target);
validators.forEach(function (validate) {
var result = validate(value_1, name, getFormValueByName);
if (result) {
errors.push(result);
}
});
}
handleSetErrors(errors);
}, [
fieldType,
getFormValueByName,
getMounted,
handleSetErrors,
name,
validators,
]);
var handleFocus = (0, react_1.useCallback)(function (e) {
e.preventDefault();
handleSetErrors([], true);
if (utils_1.warningsByType.has(fieldType)) {
var value = (0, utils_1.getValueByTypeAndTarget)(fieldType, e.target);
handleSetErrors(utils_1.warningsByType.get(fieldType)(value), true, true);
}
}, [handleSetErrors, fieldType]);
var checkWarnings = (0, react_1.useCallback)(function (evt) {
var getWarnings = utils_1.warningsByType.get(fieldType);
var warnings = getWarnings(evt.target.value);
handleSetErrors(warnings, false, true);
}, [fieldType, handleSetErrors]);
var formatValue = (0, react_1.useCallback)(function (evt) {
var formatter = utils_1.formatValueByType.get(fieldType);
evt.target.value = formatter(evt.target.value);
}, [fieldType]);
(0, react_1.useEffect)(function () {
var input = inputRef.current;
var hasEventHandler = Boolean(input);
if (hasEventHandler) {
if (utils_1.warningsByType.has(fieldType)) {
input.addEventListener('keyup', checkWarnings);
}
}
return function () {
if (hasEventHandler) {
if (utils_1.warningsByType.has(fieldType)) {
input.removeEventListener('keyup', checkWarnings);
}
}
};
}, [checkWarnings, inputRef, fieldType]);
(0, react_1.useEffect)(function () {
var input = inputRef.current;
var hasEventHandler = Boolean(input);
if (hasEventHandler) {
if (utils_1.formatValueByType.has(fieldType)) {
input.addEventListener('keyup', formatValue);
}
}
return function () {
if (hasEventHandler) {
if (utils_1.formatValueByType.has(fieldType)) {
input.removeEventListener('keyup', formatValue);
}
}
};
}, [inputRef, fieldType, formatValue]);
(0, react_1.useEffect)(function () {
var _a;
var input = inputRef.current;
var hasEventHandler = Boolean(input);
var isChange = (hasEventHandler && input.tagName.toUpperCase() === 'SELECT') ||
((_a = input) === null || _a === void 0 ? void 0 : _a.type) === 'checkbox';
if (hasEventHandler) {
if (isChange) {
input.addEventListener('change', handleFieldChanged);
}
input.addEventListener('blur', handleFieldChanged);
input.addEventListener('focus', handleFocus);
}
return function () {
if (hasEventHandler) {
if (isChange) {
input.removeEventListener('change', handleFieldChanged);
}
input.removeEventListener('blur', handleFieldChanged);
input.removeEventListener('focus', handleFocus);
}
};
}, [handleFieldChanged, handleFocus, inputRef]);
(0, react_1.useEffect)(function () {
return function () {
if (timeout.current) {
clearTimeout(timeout.current);
}
};
}, [timeout]);
return {
errors: (_a = field === null || field === void 0 ? void 0 : field.errors) !== null && _a !== void 0 ? _a : errors,
setErrors: (_b = field === null || field === void 0 ? void 0 : field.setErrors) !== null && _b !== void 0 ? _b : setErrors,
warnings: (_c = field === null || field === void 0 ? void 0 : field.warnings) !== null && _c !== void 0 ? _c : warnings,
};
};
exports.useValidateInput = useValidateInput;