UNPKG

react-form-with-constraints

Version:
138 lines (137 loc) 6.26 kB
import * as React from 'react'; import { instanceOf } from 'prop-types'; import { Async } from './Async'; import { FieldFeedbacks } from './FieldFeedbacks'; import { FieldFeedbackType } from './FieldFeedbackType'; import { FieldFeedbackWhenValid } from './FieldFeedbackWhenValid'; import { FormWithConstraints } from './FormWithConstraints'; export class FieldFeedback extends React.Component { constructor(props, context) { var _a; super(props, context); this.validate = (input) => { const { when } = this.props; const { form, fieldFeedbacks } = this.context; const field = form.fieldsStore.getField(input.name); const validation = { ...this.state.validation }; if ((fieldFeedbacks.props.stop === 'first' && field.hasFeedbacks(fieldFeedbacks.key)) || (fieldFeedbacks.props.stop === 'first-error' && field.hasErrors(fieldFeedbacks.key)) || (fieldFeedbacks.props.stop === 'first-warning' && field.hasWarnings(fieldFeedbacks.key)) || (fieldFeedbacks.props.stop === 'first-info' && field.hasInfos(fieldFeedbacks.key))) { validation.show = undefined; } else { validation.show = false; if (typeof when === 'function') { validation.show = when(input.value); } else if (typeof when === 'string') { if (when === 'valid') { validation.show = undefined; } else { const { validity } = input; if (!validity.valid) { if (when === '*') { validation.show = true; } else if ((validity.badInput && when === 'badInput') || (validity.patternMismatch && when === 'patternMismatch') || (validity.rangeOverflow && when === 'rangeOverflow') || (validity.rangeUnderflow && when === 'rangeUnderflow') || (validity.stepMismatch && when === 'stepMismatch') || (validity.tooLong && when === 'tooLong') || (validity.tooShort && when === 'tooShort') || (validity.typeMismatch && when === 'typeMismatch') || (validity.valueMissing && when === 'valueMissing')) { validation.show = true; } } } } else { throw new TypeError(`Invalid FieldFeedback 'when' type: ${typeof when}`); } } field.addOrReplaceValidation(validation); this.setState({ validation, validationMessage: input.validationMessage }); return validation; }; this.fieldDidReset = (field) => { if (field.name === this.context.fieldFeedbacks.fieldName) { this.setState(prevState => ({ validation: { ...prevState.validation, show: undefined }, validationMessage: '' })); } }; this.key = context.fieldFeedbacks.addFieldFeedback(); const { error, warning, info, when } = props; let type = FieldFeedbackType.Error; if (when === 'valid') type = FieldFeedbackType.WhenValid; else if (warning) type = FieldFeedbackType.Warning; else if (info) type = FieldFeedbackType.Info; if (type === FieldFeedbackType.WhenValid && ((_a = error !== null && error !== void 0 ? error : warning) !== null && _a !== void 0 ? _a : info)) { throw new Error('Cannot have an attribute (error, warning...) with FieldFeedback when="valid"'); } this.state = { validation: { key: this.key, type, show: undefined }, validationMessage: '' }; } componentDidMount() { const { form, fieldFeedbacks, async } = this.context; if (async) async.addValidateFieldEventListener(this.validate); else fieldFeedbacks.addValidateFieldEventListener(this.validate); form.addFieldDidResetEventListener(this.fieldDidReset); } componentWillUnmount() { const { form, fieldFeedbacks, async } = this.context; if (async) async.removeValidateFieldEventListener(this.validate); else fieldFeedbacks.removeValidateFieldEventListener(this.validate); form.removeFieldDidResetEventListener(this.fieldDidReset); } render() { const { when, error, warning, info, className, classes, style, children, ...otherProps } = this .props; const { validation, validationMessage } = this.state; const fieldFeedbackClassName = classes[validation.type]; const classNames = className !== undefined ? `${className} ${fieldFeedbackClassName}` : fieldFeedbackClassName; if (validation.type === FieldFeedbackType.WhenValid) { return (React.createElement(FieldFeedbackWhenValid, { "data-feedback": this.key, style: style, className: classNames, ...otherProps }, children)); } if (validation.show) { const feedback = children !== undefined ? children : validationMessage; return (React.createElement("span", { "data-feedback": this.key, className: classNames, style: { display: 'block', ...style }, ...otherProps }, feedback)); } return null; } } FieldFeedback.defaultProps = { when: () => true, classes: { error: 'error', warning: 'warning', info: 'info', whenValid: 'when-valid' } }; FieldFeedback.contextTypes = { form: instanceOf(FormWithConstraints).isRequired, fieldFeedbacks: instanceOf(FieldFeedbacks).isRequired, async: instanceOf(Async) };