React

by Abdul Ahmad

HTML

<div id="app"></div>

SCSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

.form-container {
  max-width: 500px;
  margin: 0 auto;
}

.form-actions {
  margin-top: 30px;
}

h3 {
  text-align: center;
  margin-bottom: 50px;
  font-size: 30px;
}

.form-input-container {
  &+.form-input-container {
    margin-top: 25px;
  }
}

.input {
  box-sizing: border-box;
  padding: 10px;
  border-radius: 5px;
  outline: none;
  border: 1px solid #ddd;
  transition: border 0.15s;
  width: 100%;
  
  &:hover {
    border: 1px solid #aaa;
    transition: border 0.15s;
  }
  
  &:focus {
    border: 1px solid teal;
    transition: border 0.15s;
  }
}

.input-label {
  display: block;
  margin-bottom: 10px;
}

.input-message {
  margin-top: 5px;
  font-size: 13px;
}


.button {
  padding: 10px 20px;
  border-radius: 5px;
  border: none;
  font-size: 16px;
  border: 1px solid #ddd;
}

.button-primary {
  background: teal;
  color: white;
  border: 1px solid teal;
}

.button-form {
  width: 100%;
}


.sign-up-checkbox-container {
  display: flex;
  align-items: center;
  
  .form-input-container {
    flex-grow: 1;
    flex-shrink: 1;
  }
}

.sign-up-checkbox-wrapper {
  flex-grow: 0;
  flex-shrink: 0;
  margin-right: 30px;
  
  label {
    margin-right: 10px;
  }
}

React

class FormInputText extends React.Component {
	render() {
  	const { 
    	label,
      onChange,
      placeholder,
      value,
      message,
      type
    } = this.props;
    
  	return (
      <div className='form-input-container'>
        <InputLabel text={label} />
        <input 
          className='input' 
          onChange={onChange}
          type={type || 'text'}
          value={value || ''}
          placeholder={placeholder || ''}
        />
        <InputMessage text={message} />
      </div>
    );
  }
}

function InputLabel({ text }) {
	if (!text) return null;
  
  const titleCasedText = toTitleCase(text);
  return (
    <label className='input-label'>
      { titleCasedText }
    </label>
  );
}

function InputMessage({ text }) {
	if (!text) return null;
  return (
    <p className='input-message'>
      { text }
    </p>
  );
}

class TodoApp extends React.Component {
	state = { checked: false };
  
	toggleConfirmPasswordInput = () => {
  	const { checked } = this.state;
  	this.setState({ checked: !checked });
  }

  render() {
    return (
      <div className='form-container'>
        <h3>
          Welcome
        </h3>
        <FormInputText 
          label='username' 
          // message='this field is required'
        />
        <FormInputText 
          label='password' 
          // message='this field is required'
        />
        <div className='form-input-container sign-up-checkbox-container'>
          <div className='sign-up-checkbox-wrapper'>
            <label>Sign Up</label>
            <input 
              type='checkbox' 
              onChange={this.toggleConfirmPasswordInput} 
              checked={this.state.checked}
              />
          </div>
          {
            !this.state.checked ? null : (
              <FormInputText 
                label='confirm password' 
                // message='this field is required'
                />
            )
          }
        </div>
        <div...