Add focus handling to validation

Update the Field component and validation handling to show / hide validation
feedback on focus / blur events.
This commit is contained in:
J. Ryan Stinnett 2019-04-16 18:12:13 +01:00
parent 338d83ab55
commit 87f13cfe55
2 changed files with 51 additions and 9 deletions

View file

@ -53,20 +53,53 @@ export default class Field extends React.PureComponent {
};
}
onChange = (ev) => {
if (this.props.onValidate) {
const result = this.props.onValidate(ev.target.value);
this.setState({
valid: result.valid,
feedback: result.feedback,
});
onFocus = (ev) => {
this.validate({
value: ev.target.value,
focused: true,
});
// Parent component may have supplied its own `onFocus` as well
if (this.props.onFocus) {
this.props.onFocus(ev);
}
};
onChange = (ev) => {
this.validate({
value: ev.target.value,
focused: true,
});
// Parent component may have supplied its own `onChange` as well
if (this.props.onChange) {
this.props.onChange(ev);
}
};
onBlur = (ev) => {
this.validate({
value: ev.target.value,
focused: false,
});
// Parent component may have supplied its own `onBlur` as well
if (this.props.onBlur) {
this.props.onBlur(ev);
}
};
validate({ value, focused }) {
if (!this.props.onValidate) {
return;
}
const { valid, feedback } = this.props.onValidate({
value,
focused,
});
this.setState({
valid,
feedback,
});
}
render() {
const { element, prefix, onValidate, children, ...inputProps } = this.props;
@ -76,7 +109,9 @@ export default class Field extends React.PureComponent {
inputProps.type = inputProps.type || "text";
inputProps.placeholder = inputProps.placeholder || inputProps.label;
inputProps.onFocus = this.onFocus;
inputProps.onChange = this.onChange;
inputProps.onBlur = this.onBlur;
const fieldInput = React.createElement(inputElement, inputProps, children);

View file

@ -34,8 +34,7 @@ import classNames from 'classnames';
* the overall validity and a feedback UI that can be rendered for more detail.
*/
export default function withValidation({ description, rules }) {
return function onValidate(value) {
// TODO: Hide on blur
return function onValidate({ value, focused }) {
// TODO: Re-run only after ~200ms of inactivity
if (!value) {
return {
@ -73,6 +72,14 @@ export default function withValidation({ description, rules }) {
}
}
// Hide feedback when not focused
if (!focused) {
return {
valid,
feedback: null,
};
}
let details;
if (results && results.length) {
details = <ul className="mx_Validation_details">