react-jsonschema-form-validation
Version:
Simple form validation using JSON Schema and AJV
160 lines (140 loc) • 5.67 kB
JavaScript
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/esm/inherits";
/**
* @import {
* ReactNode,
* ElementType,
* ComponentProps,
* } from 'react'
* @import { FormattedError, SafePropsOmit } from '../Form/helpers'
* @import { ErrorMessagesMap, FormContextValue } from '../Form/Context.types'
*/
import classnames from 'classnames';
import memoize from 'memoize-one';
import React, { PureComponent } from 'react';
import { withFormContext } from '../Form/Context';
import getErrorMessage from './getErrorMessage';
/**
* Base props of `<FieldError>` — the validation-specific props handled by
* the component itself. The public, polymorphic `FieldErrorProps<C>` extends
* this with the props of the underlying component `C`.
*
* @typedef {{
* children?: ReactNode,
* className?: string,
* component?: ElementType,
* errorMessages?: ErrorMessagesMap | null,
* name: string,
* }} FieldErrorBaseProps
*/
/**
* Polymorphic props of `<FieldError>`. When `component={X}` is supplied,
* every prop accepted by `X` is also accepted here (with autocomplete and
* typo detection). The default `C = 'div'` matches the runtime default.
*
* - `name` — path of the form field whose first error should be shown.
* - `errorMessages` — optional per-field overrides; they take priority over the
* map declared at the `<Form>` level (see `ErrorMessagesMap`).
* - `component` — element rendered when an error is present (default `'div'`).
* - `children` — replaces the auto-generated message when provided.
*
* @template {ElementType} [C = 'div']
* @typedef {(
* Omit<FieldErrorBaseProps, 'component'>
* & { component?: C }
* & SafePropsOmit<ComponentProps<C>, keyof FieldErrorBaseProps | 'ref'>
* )} FieldErrorProps
*/
/** @extends {PureComponent<FieldErrorBaseProps>} */
var FieldError =
/*#__PURE__*/
function (_PureComponent) {
_inherits(FieldError, _PureComponent);
function FieldError() {
var _getPrototypeOf2;
var _this;
_classCallCheck(this, FieldError);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(FieldError)).call.apply(_getPrototypeOf2, [this].concat(args)));
_this.memoGetClassnames = memoize(function (
/** @type {string | undefined} */
className,
/** @type {boolean} */
isSubmitted,
/** @type {boolean} */
isTouched) {
return classnames('Jfv_FieldError', className, {
isSubmitted: isSubmitted,
isTouched: isTouched
});
});
_this.memoGetFieldErrorMessage = memoize(function (
/** @type {FormattedError} */
error,
/** @type {ErrorMessagesMap | undefined} */
formErrorMessages,
/** @type {ErrorMessagesMap | null | undefined} */
fieldErrorMessages) {
var errorMessages = _objectSpread({}, formErrorMessages, {}, fieldErrorMessages);
return getErrorMessage(error, errorMessages);
});
_this.getClassnames = function (form) {
var _this$props = _this.props,
className = _this$props.className,
name = _this$props.name;
var isFieldTouched = form.isFieldTouched,
isSubmitted = form.isSubmitted;
return _this.memoGetClassnames(className, isSubmitted, isFieldTouched(name));
};
_this.getFieldErrorMessage = function (error, form) {
var fieldErrorMessages = _this.props.errorMessages;
var formErrorMessages = form.errorMessages;
return _this.memoGetFieldErrorMessage(error, formErrorMessages, fieldErrorMessages);
};
return _this;
}
_createClass(FieldError, [{
key: "render",
value: function render() {
var _this2 = this;
var _this$props2 = this.props,
children = _this$props2.children,
className = _this$props2.className,
_this$props2$componen = _this$props2.component,
Component = _this$props2$componen === void 0 ? 'div' : _this$props2$componen,
errorMessages = _this$props2.errorMessages,
name = _this$props2.name,
props = _objectWithoutProperties(_this$props2, ["children", "className", "component", "errorMessages", "name"]);
return withFormContext(function (form) {
var fieldErrors = form.getFieldErrors(name);
if (!fieldErrors.length) return null;
return React.createElement(Component, Object.assign({
className: _this2.getClassnames(form)
}, props), children || _this2.getFieldErrorMessage(fieldErrors[0], form));
});
}
}]);
return FieldError;
}(PureComponent);
FieldError.defaultProps = {
children: null,
component: 'div',
errorMessages: null,
className: ''
}; // Polymorphic re-typing: the class is non-generic internally (uses
// `FieldErrorBaseProps`); the cast on the default export restores the
// generic so consumers get autocomplete and type-checking on `component`'s
// own props.
export default
/** @type {<C extends ElementType = 'div'>(
props: FieldErrorProps<C>
) => JSX.Element | null} */
/** @type {unknown} */
FieldError;