I made a nice and unobtrusive animation for form validation with redux-form:
To implement it, I made a FormInput
component:
import React, { Component } from "react";
export default class FormInput extends Component {
render() {
const inputState = field => {
if (this.props.field.error) {
return "error";
} else if (this.props.field.touched && this.props.field.value) {
return "pass";
} else {
return "";
}
};
const inputType = this.props.type || "text";
return (
<div>
<label>{this.props.label}</label>
<input
className={inputState(this.props.field)}
type={inputType}
{...this.props.field}
/>
</div>
);
}
}
The CSS for the component is surprisingly simple:
input {
border: 1px solid #ddd;
padding-left: 5px;
width: 300px;
transition: 0.2s cubic-bezier(0.68, -0.55, 0.265, 1.55) all;
}
input.error {
border-left: 8px solid #d0021b;
}
input.pass {
border-left: 8px solid #7ed321;
}
input:focus {
border-left: 8px solid #449cfa;
}
The border
style is for overriding the browser’s default border styling, and can be left out if you already have existing border styles for your inputs. The padding-left
gives a bit of spacing between the indicator and the text in the input.
It’s important to note that, for the width of the input to stay fixed even as the border is transitioned in, you need to make sure that your box-sizing
is set to border-box
. Paul Irish’s CSS snippet works like a charm:
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
Now we can use it in a redux-form component like so:
const validate = values => {
const errors = {};
if (!values.email || !values.email.trim()) {
errors.email = "Email required";
}
return errors;
};
@reduxForm({
form: "login",
fields: ["email", "password"],
validate,
})
class LoginForm extends Component {
static propTypes = {
fields: PropTypes.object,
handleSubmit: PropTypes.func,
};
render() {
const {
fields: { email, password },
handleSubmit,
} = this.props;
return (
<form onSubmit={handleSubmit}>
<FormInput label="Email" field={email} />
<FormInput type="password" label="Password" field={password} />
<button type="submit" onClick={handleSubmit}>
Login
</button>
</form>
);
}
}
🙌