JSFiddle - React, Tailwind, and code Playground
by Abdul Ahmad
HTML
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
SCSS
body {
font-family: sans-serif;
color: #444444;
margin: 0;
background: #cfd3d6;
}
input {
outline: none;
box-sizing: border-box;
padding: 20px 15px;
border-radius: 3px;
border: 1px solid #ddd;
font-size: 16px;
}
button {
border: none;
padding: 15px 20px;
border-radius: 5px;
box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.3);
outline: none;
background: white;
font-size: 16px;
}
.app {
}
.form-box {
position: fixed;
top: 20px;
opacity: 1;
left: calc(50% - 150px);
padding: 40px;
border-radius: 3px;
box-sizing: border-box;
width: 300px;
background: white;
margin: 20px;
box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.3);
transition: top 0.3s ease, opacity 0.3s ease;
&.hidden {
top: -100px;
opacity: 0;
transition: top 0.3s ease, opacity 0.3s ease;
}
}
.form-input-box {
margin-top: 30px;
&:first-of-type {
margin-top: 0;
}
}
.form-input-label {
display: block;
font-size: 16px;
font-weight: bold;
}
.form-input {
margin-top: 8px;
width: 100%;
}
.form-input-message {
font-size: 14px;
margin-top: 3px;
&.error {
color: #e8186b;
}
&.success {
color: #24c384;
}
}
.submit-button-box {
margin-top: 30px;
text-align: center;
}
.submit-button {
@extend button;
background: #24c384;
color: white;
box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.3);
&:active {
background: darken(#24c384, 15%);
}
}
Babel + JSX
class App extends React.Component {
render() {
return <div className='app'>
<Form />
</div>;
}
}
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
formClass: 'hidden',
nameInput: {
name: 'name',
label: 'Name',
value: '',
message: '',
messageClass: '',
},
emailInput: {
name: 'email',
label: 'Email',
value: '',
message: '',
messageClass: '',
},
messageInput: {
name: 'message',
label: 'Message',
value: '',
message: '',
messageClass: '',
},
};
setTimeout(() => { this.setState({ formClass: '' }); }, 1000);
this.submit = this.submit.bind(this);
this.onInputChange = this.onInputChange.bind(this);
}
submit() {
let inputsAreValid = true;
const { nameInput, emailInput, messageInput } = this.state;
const inputs = [nameInput, emailInput, messageInput];
inputs.forEach((input) => {
if (!input.value) {
this.setState({
[input.name + 'Input']: {
...input,
message: 'This field is required',
messageClass: 'error',
}
});
inputsAreValid = false;
}
});
if (!inputsAreValid) return;
this.setState({ formClass: 'hidden' });
}
onInputChange(e) {
const { name, value } = e.target;
const input = this.state[name + 'Input'];
this.setState({
[name + 'Input']: {
...input,
value: value,
message: '',
messageClass: '',
}
});
}
render() {
const { nameInput, emailInput, messageInput, formClass } = this.state;
return (
<div className={`form-box ${formClass}`}>
<FormInput
label={nameInput.label}
value={nameInput.value}
onChange={this.onInputChange}
name={nameInput.name}
...