

Facebook Sign Up Form Tutorial | React Binden💪👑 x Tailwindcss❤️
source link: https://dev.to/krtirtho/facebook-sign-up-form-tutorial-react-binden-x-tailwindcss-25cn
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.


Posted on Nov 2
Facebook Sign Up Form Tutorial | React Binden💪👑 x Tailwindcss❤️
React is an awesome FrontEnd UI library created by Facebook. But forms in React always been a little hard. This is what the library react-binden solves. It's a fairly new form handling library for React. It's extremely easy to learn & use
Get a deep dive on React Binden or visit the Docs
Tailwindcss is my most favorite css framework❤️ & by far the most awesome library I've ever found
This article only shows how to build a Signup form using React, react-binden & tailwindcss. I'm assuming one will be familiar with above tools & technologies
What are we Building?
We're making a simple, regular & boring old Sign Up Form inspired by Facebook's Sign Up Form with React, react-binden & tailwindcss. But there's a twist. The form will still be a Sign Up Form but we'll be honest for the placeholders, labels & license agreement etc.. texts🙃😆
Creating the project
For bootstraping the project, we'll use vite. An extraordinary frontend build tool that is super fast & also supports various frontend frameworks
Initiating the project
$ npm init vite
It'll ask a few questions, including project name & which frontend framework to use. Write the name of your choice & select the react
option
Now open the project into VSCode/your favorite code editor. Then in the terminal, inside the project root run
$ npm install
Then remove all the non required files e.g src/App.css
, src/logo.svg
. Remove the all the boilerplate code inside src/App.jsx
Now install the following dependencies:
$ npm install react-binden tailwindcss postcss autoprefixer nanoid clsx
Now run the following command to initiate TailwindCSS inside your project
$ npx tailwindcss init -p
This will create the following files tailwind.config.js
, postcss.config.js
Now add the following to src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
Let's enable JIT (Just in Time) mode for the tailwindcss compiler. Add mode: "jit"
inside the code tailwind.config.js
's export config object. Then the file should look like below:
module.exports = {
// added jit mode
mode: "jit",
// purge Array
purge: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
darkMode: "class", // or 'media' for automatic dark mode detection
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
Now run following command to start the vite dev server
$ npm run dev
Custom Themed Input
Now that we've done initializing the project, it's time to create a awesome & beautiful Input
component with our favorite tailwindcss
Create a file as src/ModInput.jsx
then do the following
import { Input } from 'react-binden'
import clsx from "clsx"
import { nanoid } from "nanoid"
function ModInput(props) {
const id = props.id ?? nanoid()
return (
<div>
{props.model.error && <p>{props.model.error}</p>}
<Input id={id} {...props} />
<label htmlFor={id}>{props.label}</label>
</div>
)
}
export default ModInput
May be you're thinking why did I put the label & the error hint in the wrong order. Well, there's a reason. But now, let's style these components. I'll be using clsx for handling multiple & conditional classes efficiently
import { Input } from 'react-binden'
import clsx from "clsx"
import { nanoid } from "nanoid"
function ModInput(props) {
const inputStyle = clsx(
props.className,
"peer transition-all p-1 border-2 border-solid rounded outline-none",
{
// conditional classes
["border-red-400"]: props.model.touched && !!props.model.error,
["border-gray-500 focus:border-blue-400"]: !props.model.error
},
)
const id = props.id ?? nanoid()
// radio & checkboxes are different than text fields thus they need
// a bit differently adjusted styles
const rowTypes = ["checkbox", "radio"]
const secondDivStyles = clsx(
"inline-flex",
// corrects the wrong order of label & error-hint
!rowTypes.includes(props.type) ? "flex-col-reverse" : "flex-row items-center"
)
const labelStyles = clsx(
"transition-all select-none peer-focus:text-blue-500 font-semibold",
{
["font-normal peer-focus:text-black ml-2"]: rowTypes.includes(props.type),
["peer-focus:text-red-500"]: props.model.touched && !!props.model.error
}
)
return (
<div className={secondDivStyles}>
{props.model.error && (
<p className="text-red-500 text-sm ml-2 group-focus">
{props.model.error}
</p>)
}
<Input id={id} className={inputStyle} {...props} />
<label htmlFor={id} className={labelStyles}>{props.label}</label>
</div>
)
}
export default ModInput
Now, let's answer why the order of error-hint & label are in reverse in the JSX. This is because of tailwind's peer
class & peer-focus:
prefix/variant. TailwindCSS provides an awesome way to handle css's styles based on sibling's state. peer
prefix works as the CSS's +
operator for selectors. But peer
only works when the upper most element/sibling has the peer
class. Downwards siblings can use upward siblings states but not vice-versa
Learn more about TailwindCSS Sibling Select Variant
Basic Form
Let's use the newly created ModInput
. Now in src/App.jsx
we've to create our basic form using react-binden's Form
, useModel
& regex
. We'll style the form later. Now only focus on Logic
import { Form, regex, useModel } from "react-binden"
import ModInput from "./ModInput"
function App() {
// models of each field
const email = useModel("")
const password = useModel("")
const confirmPassword = useModel("")
const username = useModel("")
const birthday = useModel("")
// since we're using radio-group a common name for all the
// radio-button is required to make it function
const gender = useModel("", { name: "gender", required: true })
function handleSubmit(_e, _states, { setSubmitting, resetForm }) {
// resetting the form
setInterval(() => {
resetForm();
setSubmitting(false);
}, 500);
}
return (
<div>
<h1>Honest Facebook Sign Up</h1>
<p><b>Disclaimer!:</b> This is just a parody of Facebook. Nothing related to actual Facebook corp. Made just for fun & entertainment</p>
<Form onSubmit={handleSubmit}>
<ModInput
model={username}
label="Username"
// only allows lowercase letters
pattern={[/^[a-z]+$/, "only lower case name is allowed"]}
required
/>
<ModInput
type="email"
label="Email"
model={email}
pattern={[regex.email, "Should be a valid email"]}
required
/>
<ModInput
type="password"
label="Password"
model={password}
pattern={[regex.moderatePassword, "Write a stronger password"]}
required
/>
<ModInput
type="password"
model={confirmPassword}
imprint-model={password}
label="Confirm Password"
required
/>
<ModInput
type="datetime"
label="Birthday"
model={birthday}
pattern={[regex.date_dd_MM_yyyy, "should follow the `ddmmyy` format"]}
required
/>
<div>
<p>Gender</p>
<div>
<ModInput
type="radio"
model={gender}
value="male"
label="Male"
/>
<ModInput
type="radio"
model={gender}
value="female"
label="Female"
/>
<ModInput
type="radio"
model={gender}
value="other"
label="Other"
/>
</div>
</div>
<div>
<button type="submit">Get Ruined</button>
</div>
</Form>
</div>
)
}
export default App
If you feel overwhelmed with all of the code above you can learn about react-binden here
Now, that we've all the fields Facebook requires to Signup, let's style & structure them as following
// ... import stuffs
function App() {
// ... other stuff (models, handlers etc..)
return (
<div className="flex flex-col items-center">
<h1 className="m-2 text-3xl text-center font-bold">
Honest Facebook Sign Up
</h1>
<p className="text-center">
<b>Disclaimer!:</b> This is just a parody of Facebook. Nothing related
actual Facebook corp. Made just for fun & entertainment
</p>
<Form
className="inline-flex flex-col p-5 space-y-2 max-w-xl"
onSubmit={handleSubmit}
>
<div>
<h2 className="text-2xl text-gray-900 font-semibold">Sign Up</h2>
<p className="text-xs text-gray-600">
It's quick & easy
</p>
</div>
<hr />
<ModInput
model={username}
label="Username"
pattern={[/^[a-z]+$/, "only lower case name is allowed"]}
required
/>
<ModInput
type="email"
label="Email"
model={email}
pattern={[regex.email, "Should be a valid email"]}
required
/>
<div className="flex space-x-5">
<ModInput
type="password"
label="Password"
model={password}
pattern={[regex.moderatePassword, "Write a stronger password"]}
required
/>
<ModInput
type="password"
model={confirmPassword}
imprint-model={password}
label="Confirm Password"
required
/>
</div>
<ModInput
type="datetime"
model={birthday}
pattern={[regex.date_dd_MM_yyyy, "should follow the `ddmmyy` format"]}
required
/>
<div>
<p className="font-bold">Gender</p>
<div className="flex items-center justify-between w-1/2">
<ModInput type="radio" model={gender} value="male" label="Male" />
<ModInput
type="radio"
model={gender}
value="female"
label="Female"
/>
<ModInput type="radio" model={gender} value="other" label="Other" />
</div>
</div>
<p className="text-gray-600 text-xs pb-5">
By clicking Sign Up, you agree to our Terms, Data Policy and Cookie Policy. You may receive SMS notifications from us and can opt out at any time.
</p>
<div className="flex justify-center">
<button
type="submit"
className="bg-[#00a400] py-2 px-10 text-white font-bold rounded"
>
Get Ruined
</button>
</div>
</Form>
</div>
);
}
export default App;
The Fun Part
I hope it'd now look visually appealing but that's boring. Nothing fun & interesting. Of course, I could add awesome animations, weirdest scroll effect or various CSS animations. But we're developers & we do hard work "occasionally"🤥. So let's use our "joke power" (which I obviously don't have but still trying) with texts. Let's just pretend we're actual Facebook developer & we, for some reason have to be slightly honest with what we build🙃
FUN GENERATING
import { Form, regex, useModel } from "react-binden";
import ModInput from "./ModInput";
function App() {
const email = useModel("");
const password = useModel("");
const confirmPassword = useModel("");
const username = useModel("");
const birthday = useModel("");
const gender = useModel("", { name: "gender", required: true });
function handleSubmit(_e, { errors }, { setSubmitting, resetForm }) {
setInterval(() => {
resetForm();
setSubmitting(false);
}, 500);
}
return (
<div className="flex flex-col items-center">
<h1 className="m-2 text-3xl text-center font-bold">
Honest Facebook Sign Up
</h1>
<p className="text-center">
<b>Disclaimer!:</b> This is just a parody of Facebook. Nothing related
actual Facebook corp. Made just for fun & entertainment
</p>
<Form
className="inline-flex flex-col p-5 space-y-2 max-w-xl"
onSubmit={handleSubmit}
>
<div>
<h2 className="text-2xl text-gray-900 font-semibold">Sign Up</h2>
<p className="text-xs text-gray-600">
It's quick & easy (profit for us)
</p>
</div>
<hr />
<ModInput
model={username}
label="Username"
placeholder="Credit Card Pin. Oops, Username"
pattern={[/^[a-z]+$/, "only lower case name is allowed"]}
required
/>
<ModInput
type="email"
label="Email"
model={email}
pattern={[regex.email, "Should be a valid email"]}
placeholder="Password. Oh sorry, Email"
required
/>
<div className="flex space-x-5">
<ModInput
type="password"
label="Password"
model={password}
pattern={[regex.moderatePassword, "Write a stronger password"]}
placeholder="Why not use, Hail Zuckerberg?"
required
/>
<ModInput
type="password"
model={confirmPassword}
imprint-model={password}
label="Confirm Password"
placeholder="Isn't it, Hail Zuckerberg?"
required
/>
</div>
<ModInput
type="datetime"
label="Birthday (Makes it easier for your friends to beg treats from you)"
model={birthday}
pattern={[regex.date_dd_MM_yyyy, "should follow the `ddmmyy` format"]}
required
/>
<div>
<p className="font-bold">Gender</p>
<div className="flex items-center justify-between w-1/2">
<ModInput type="radio" model={gender} value="male" label="Male" />
<ModInput
type="radio"
model={gender}
value="female"
label="Female"
/>
<ModInput type="radio" model={gender} value="other" label="Other" />
</div>
</div>
<p className="text-gray-600 text-xs pb-5">
By clicking Get Ruined, you agree that you're our product, we can do
whatever we want with & we own you (for free). You may receive SMS
notifications from us and can opt out at any time (not actually).
</p>
<div className="flex justify-center">
<button
type="submit"
className="bg-[#00a400] py-2 px-10 text-white font-bold rounded"
>
Get Ruined
</button>
</div>
</Form>
</div>
);
}
export default App;
Glad that it's finished. For a moment, it was feeling like it'd never end. But don't go way. There's a catch in the project. I created the entire website without taking care of responsiveness. So you can now make it responsive by yourself. Do this as a home-work
Results
After writing 2 million lines (200 actually) of code we're finally done. Let's see what have we built so far & let's hope there's no bug
Source Code: https://github.com/KRTirtho/fb-parody-signup
Social
Follow me on twitter
Follow me on Reddit
Give react-binden a ⭐ on Github
Recommend
-
10
Tailwindcss is a utility-first CSS framework loaded with classes that help you design almost any design without leaving the HTML. In this article, we are going to learn how to integrate the tailwindcss with React.Getting Started
-
18
Getting StartedInstallationVechaiUI works out of the box with create-react-app (including TypeScript version), Preact cli (with compat), Next.js, Gatsby and any other environment.To install the VechaiUI run the follow...
-
4
@raivikasVikas RaiCollege student at Maharaja Agrasen Institute of Technology||Web Developer || Next.js Lover || React.js || TailwindCSSThis blog...
-
9
TailwindCSS 3.0 Setup with Remix This is a super quick tutorial to get TailwindCSS up and running in Remix! I wrote this when TailwindCSS3.0 was released on Remix V1.1.1 This tutorial assumes you have already created...
-
6
tailwindcss-react-native Use Tailwindcss in your cross platform React Native applications. This library is currently under active devel...
-
7
In this series, we have explored the web for all the cool tailwindCSS components that one can find for free and brought it to you. Today, we are exploring the form elements available on the web for free. Login Form, Signup forms and much more...
-
8
Tailwind CSS TailwindCSS-inspired styling library for React Native Jun 18, 2022 1 min read
-
9
How to Configure a React App with TypeScript, TailwindCSS, Yarn and Storybook
-
5
-
5
How To Create Dynamic Donut Charts With TailwindCSS And ReactIn this article, Paul Scanlon shares a super lightweight approach to creating a Donut chart using conic-gradient()...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK