Create an Elegant Login and Register Form on React

List Of Content

ADS Area (CARBON)

ADS Area (CARBON)

 

Getting Started

If you're new to React or still not really experienced with most aspects of react plus you may need to get more familiar with designing User Interfaces on React so in this tutorial we will go through the process of creating an elegant Login/Register form box on React we will be using create-react-app for easy setup and project configuration so we can quickly get up and running.

You can grab the full source code of the application from this Github Repo.

If you're not familiar with create-react-app here is basic Tutorial shows how you can get started with it.

You may wanna grap the CSS Style files from the Github Repo for easier follow up

If you would like to use SASS in your create-react-app generated application you need to install node sass as a dependency and change the style filename extension to either (.sass|.scss).

npm install node-sass --save-dev

Create Login and Register Box

Login and Register boxes are going to be a separate Components so later we can easily manipulate them and decide which one to render or not depending on the application state plus it is going to make it much easier for applying some cool animation while transitioning between states.

So create a components/ folder inside src/ and put inside it the login/ component folder this will hold the login and register standalone components.

/* login.jsx */
import React from "react";
import loginImg from "../../login.svg";

export class Login extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className="base-container" ref={this.props.containerRef}>
        <div className="header">Login</div>
        <div className="content">
          <div className="image">
            <img src={loginImg} />
          </div>
          <div className="form">
            <div className="form-group">
              <label htmlFor="username">Username</label>
              <input type="text" name="username" placeholder="username" />
            </div>
            <div className="form-group">
              <label htmlFor="password">Password</label>
              <input type="password" name="password" placeholder="password" />
            </div>
          </div>
        </div>
        <div className="footer">
          <button type="button" className="btn">
            Login
          </button>
        </div>
      </div>
    );
  }
}

Also, make sure to grab the login logo used in this example you can grab it alongside many other open-source SVG Illustrations from undraw

I will be putting it under src/login.svg.

You can use any other structure for adding or either removing useless content from the login form depending on your needs.

For the Login class component, it renders a basic container and a form the style will be contained in login/style.scss 

We also need to put the Register.jsx.

/* Register.jsx */
import React from "react";
import loginImg from "../../login.svg";

export class Register extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className="base-container" ref={this.props.containerRef}>
        <div className="header">Register</div>
        <div className="content">
          <div className="image">
            <img src={loginImg} />
          </div>
          <div className="form">
            <div className="form-group">
              <label htmlFor="username">Username</label>
              <input type="text" name="username" placeholder="username" />
            </div>
            <div className="form-group">
              <label htmlFor="email">Email</label>
              <input type="text" name="email" placeholder="email" />
            </div>
            <div className="form-group">
              <label htmlFor="password">Password</label>
              <input type="text" name="password" placeholder="password" />
            </div>
          </div>
        </div>
        <div className="footer">
          <button type="button" className="btn">
            Register
          </button>
        </div>
      </div>
    );
  }
}

We only needed to add email filed for the registration process.

Now let's create the style for the login/register components.

.base-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;

  .header {
    font-size: 24px;
    font-family: "Open Sans", sans-serif;
  }

  .content {
    display: flex;
    flex-direction: column;

    .image {
      width: 21em;
      img {
        width: 100%;
        height: 100%;
      }
    }

    .form {
      margin-top: 2em;
      display: flex;
      flex-direction: column;
      align-items: center;

      .form-group {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        width: fit-content;
        label {
          font-size: 20px;
        }
        input {
          margin-top: 6px;
          min-width: 18em;
          height: 37px;
          padding: 0px 10px;
          font-size: 16px;
          font-family: "Open Sans", sans-serif;
          background-color: #f3f3f3;
          border: 0;
          border-radius: 4px;
          margin-bottom: 31px;
          transition: all 250ms ease-in-out;
          &:hover {
            //background-color: #ffffff;
            //box-shadow: 0px 0px 14px 0.3px #0e81ce96;
          }

          &:focus {
            outline: none;
            box-shadow: 0px 0px 12px 0.8px #3474dbb2;
          }
        }
      }
    }
  }
  .footer {
    margin-top: 3em;
  }
}

The best thing about SASS or any other pre-processor is you can use nested child elements to make sure only that child element under it's a specified parent will have the style applied. However, this can also be dangerous if you're trying to applying custom style names to elements that don't meet the nested structure.

We also used flex-box for easily aligning children alongside the x and y-axis both vertically and horizontally since we need to fully centre the login box container (base-container children).

Now, let's try to re-export the Login and Register components using ES6 re-exporting power so we could easily import them from the App.jsx 

So simply create index.tsx under login/ and re-export login/register from there.

/* index.tsx */
import "./style.scss";
//Import and Re-export Login/Register Components
export { Login } from "./login";
export { Register } from "./register";

 

Render & Change State

Now under App.jsx we will be rendering the Login/Admin components and we need to tweak the state to apply an animated transition between both components.

/* App.jsx */

import React from "react";
import "./App.scss";
import { Login, Register } from "./components/login/index";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isLogginActive: true
    };
  }

  render() {
    const { isLogginActive } = this.state;
    const current = isLogginActive ? "Register" : "Login";
    return (
      <div className="App">
        <div className="login">
          <div className="container" ref={ref => (this.container = ref)}>
            {isLogginActive && (
              <Login containerRef={ref => (this.current = ref)} />
            )}
            {!isLogginActive && (
              <Register containerRef={ref => (this.current = ref)} />
            )}
          </div>
        </div>
      </div>
    );
  }
}

We use isLogginActive state to check if we login component is currently being rendered or not (Register component is being rendered) so this way we can transition between login and register components.

We also reference the container div so we can easily use it later to apply some cool transition between moving from login to register and vice-versa.

Toggle with Animation

We need to add the right side component which will allow us to toggle between the two states of login/register components and apply to its cool moving transition.

So let's create a simple RFC (React Functional Component).

/* App.jsx */
/*We also add custom container ref to pass ref to the App Component so we can easily manipulate the right-side container*/
const RightSide = props => {
  return (
    <div
      className="right-side"
      ref={props.containerRef}
      onClick={props.onClick}
    >
      <div className="inner-container">
        <div className="text">{props.current}</div>
      </div>
    </div>
  );
};

We pass in the current prop which holds either Login or Register as the next state (Component) we want to transition to.

...
render() {
    const { isLogginActive } = this.state;
    const current = isLogginActive ? "Register" : "Login";
    return (
      <div className="App">
        <div className="login">
          <div className="container" ref={ref => (this.container = ref)}>
            {isLogginActive && (
              <Login containerRef={ref => (this.current = ref)} />
            )}
            {!isLogginActive && (
              <Register containerRef={ref => (this.current = ref)} />
            )}
          </div>
          <RightSide
            current={current}
            containerRef={ref => (this.rightSide = ref)}
          />
        </div>
      </div>
    );
  }
...

We detect the current (the next component to move to) simply by looking at the isLogginActive.

We also set the containerRef to hold the right-side container ref on the App class.

Now, we need to detect the click event on the right-side container so we could toggle the other component by applying some cool transition.

So add a new method on the App class that will handle the click that occurs on the right side component (make sure to pass the onClick event inside the component otherwise the event listener won't be registered).

changeState() {
  //ES6 Object Destructuring
  const { isLogginActive } = this.state;

  //We togglet component classes depending on the current active state 
  if (isLogginActive) {
    //Right side for login
    this.rightSide.classList.remove("right");
    this.rightSide.classList.add("left");
  } else {
    //Left side for Register 
    this.rightSide.classList.remove("left");
    this.rightSide.classList.add("right");
  }
  //Of course we need to toggel the isLogginActive by inversing it's previous state 
  this.setState(prevState => ({ isLogginActive: !prevState.isLogginActive }));
}

We simply check for the current active state which is either loggin is active or register component is active and we apply custom classes so the rightSide component could apply custom styles and transition animations, you can check the App.scss for more information on the applied style.

And most importantly we need to make sure we toggle the current state so we inverse it depending on the previous state value.

Finally, make sure to bind the click event to the current method.

...
<RightSide
  current={current}
  currentActive={currentActive}
  containerRef={ref => (this.rightSide = ref)}
  onClick={this.changeState.bind(this)}
/>
...

Make sure to bind the current class context.

and onComponentWillMount hook set a default value.

componentDidMount() {
  //Add .right by default
  this.rightSide.classList.add("right");
}

Save and reload the page you should get the cool transition playing when toggling between states.

 

 

Share Tutorial

Made With By

Ipenywis Founder, Game/Web Developer, Love Play Games