🐥
ログイン画面と登録画面の切り替えのUI
はじめに
Next.jsでログイン画面とアカウント登録画面を切り替えるUIを作ったので、メモとして残しておきます。
言語はTypescriptを使用しています。
ポイント
useCallback、useStateを使用する。
今回だと、toggleVariantをspanタグのonClickで指定しているため、
このspanタグのテキストがクリックされたときに、画面を切り替えることが可能になる。
実装例
画像部分は好きなものに置き換えてください。(背景とロゴの部分2箇所)
auth.tsx
import { useCallback, useState } from "react";
import Input from "../components/Input";
const Auth = () => {
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
// ログイン画面、アカウント登録画面の切り替え
const [variant, setVariant] = useState('login')
// このtoggleVariantを、spanタグのonclickと紐づけている。
const toggleVariant = useCallback(() => {
setVariant((currentVariant) => currentVariant === 'login' ? 'register' : 'login')
}, [])
return (
<div className="relative h-full w-full bg-[url('/images/任意の画像ファイル')] bg-no-repeat bg-fixed bg-cover">
<div className="bg-black w-full h-full lg:bg-opacity-50">
<nav className="">
<img src="/images/任意の画像ファイル" alt="Logo" className="h-24 w-auto" />
</nav>
<div className="flex justify-center">
<div className="bg-black bg-opacity-90 px-14 py-14 self-center lg:w-2/5 lg:max-w-md rounded-md">
<h2 className="text-white text-4xl mb-8 font-semibold">
{/* 登録済みの場合、Sign In, 未登録の場合はRegister */}
{variant === 'login' ? 'Sign In' : 'Register'}
</h2>
<div className="flex flex-col gap-4">
{/* 氏名は登録時のみ入力 */}
{variant === 'register' && (
<Input
id="name"
onChange={(event:any) => setName(event.target.value)}
type="name"
label="Name"
value={name}
/>
)}
<Input
id="email"
onChange={(event:any) => setEmail(event.target.value)}
type="email"
label="Email"
value={email}
/>
<Input
id="password"
onChange={(event:any) => setPassword(event.target.value)}
type="password"
label="Password"
// usestateのpassword
value={password}
/>
</div>
<button className="bg-red-600 py-3 text-white rounded-md w-full mt-10 hover:bg-red-700 transition">
{variant === 'login' ? 'Login' : 'Sign Up'}
</button>
<p className="text-neutral-500 mt-7">
{variant === 'login' ? 'First time using Netflix?' : 'Already have an account?'}
{/* このボタンを押したときに、アカウント作成、ログインの画面が切り替わるようにする */}
<span onClick={toggleVariant} className="text-white ml-1 hover:underline cursor-pointer">
{variant === 'login' ? 'Create an account' : 'Sign In'}
</span>
</p>
</div>
</div>
</div>
</div>
);
}
export default Auth;
auth.tsxで使用している、入力フォームのコンポーネント(Input)は以下のような実装
input.tsx
interface InputProps {
id: string;
onChange: any;
value: string;
label: string;
type?: string;
}
const Input: React.FC<InputProps> = ({
id,
onChange,
value,
label,
type,
}) => {
return (
// inputタグとlabelタグの位置を揃えるには、親タグのclassNameにrelativeを指定する
<div className="relative">
<input
id={id}
type={type}
value={value}
onChange={onChange}
className="
block
rounded-md
px-6
pt-7
pb-3
w-full
text-md
text-white
bg-neutral-700
appearance-none
focus:outline-none
focus:ring-0
peer
"
// この空のplaceholderがないと、カーソルを合わせる前から文字が小さくなってしまう。
placeholder=""
/>
<label
// 入力時はplaceholderの文字が上側に表示されるようにする
className="
absolute
text-md
text-zinc-400
duration-150
transform
-translate-y-3
scale-75
top-5
z-10
origin-[0]
left-5
peer-placeholder-shown:scale-100
peer-placeholder-shown:translate-y-0
peer-focus:scale-75
peer-focus:-translate-y-4
"
htmlFor={id}>
{label}
</label>
</div>
)
}
export default Input
ブラウザ画面
背景画像、ロゴともDALL-E3で作ってもらいました。
クオリティ高くて素晴らしいです!!
ログイン画面
アカウント登録画面(Create an accountをクリックすると切り替わる)
終わりに
このようなログイン画面は作る機会多いと思うので、サクッと作れるようにしておきたいですよね。
また初めにNext.jsのプロジェクトを作成する際に、色々と聞かれるのですが、
✔ Would you like to use App Router? (recommended) … No
この問いをNoにしておかないと、pagesディレクトリが作成されず、appディレクトリが作成されてしまうので、気を付けてください。
こちらの記事のおかげで絶望せずに済みました。筆者の@mu_tomoyaさん、ありがとうございます!
参考:https://qiita.com/mu_tomoya/items/7545bea039e82e483f9e
Discussion