From 665e47b873acff81f2d6c27a811b276183c28d39 Mon Sep 17 00:00:00 2001 From: rikhall1515 Date: Fri, 26 Apr 2024 21:54:08 +0200 Subject: [PATCH] feat(form): add inputs, labels, and error indicators This change adds the basic password and email inputs, along with components that can be used to build other inputs. --- components/forms/InputError.tsx | 33 ++++++++++++++++++ components/forms/InputLabel.tsx | 27 +++++++++++++++ components/forms/email.tsx | 29 ++++++++++++++++ components/forms/expandable.tsx | 34 +++++++++++++++++++ components/forms/password.tsx | 60 +++++++++++++++++++++++++++++++++ components/forms/rePassword.tsx | 48 ++++++++++++++++++++++++++ 6 files changed, 231 insertions(+) create mode 100644 components/forms/InputError.tsx create mode 100644 components/forms/InputLabel.tsx create mode 100644 components/forms/email.tsx create mode 100644 components/forms/expandable.tsx create mode 100644 components/forms/password.tsx create mode 100644 components/forms/rePassword.tsx diff --git a/components/forms/InputError.tsx b/components/forms/InputError.tsx new file mode 100644 index 0000000..239911a --- /dev/null +++ b/components/forms/InputError.tsx @@ -0,0 +1,33 @@ +"use client"; +import { useEffect, useState } from "react"; + +import Expandable from "./expandable"; + +export default function FormError({ + name, + error, +}: { + name: string; + error?: string; +}) { + const [frozenError, setError] = useState(); + useEffect(() => { + if (!error) { + const timeout = setTimeout(() => (setError(""), 200)); + return () => { + clearTimeout(timeout); + }; + } else { + setError(error); + } + }, [error]); + return ( + <> + +
+ {frozenError} +
+
+ + ); +} diff --git a/components/forms/InputLabel.tsx b/components/forms/InputLabel.tsx new file mode 100644 index 0000000..ada1ec4 --- /dev/null +++ b/components/forms/InputLabel.tsx @@ -0,0 +1,27 @@ +import { cn } from "@/lib/utils"; + +export default function InputLabel({ + name, + label, + required, + error, +}: { + name: string; + label?: string; + required?: boolean; + error?: string; +}) { + return ( + <> + + + ); +} diff --git a/components/forms/email.tsx b/components/forms/email.tsx new file mode 100644 index 0000000..fba722f --- /dev/null +++ b/components/forms/email.tsx @@ -0,0 +1,29 @@ +"use client"; +import { useState } from "react"; + +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { cn } from "@/lib/utils"; + +export default function EmailInput() { + const [submitActive] = useState(false); + return ( + <> + + + ); +} diff --git a/components/forms/expandable.tsx b/components/forms/expandable.tsx new file mode 100644 index 0000000..7c9ddad --- /dev/null +++ b/components/forms/expandable.tsx @@ -0,0 +1,34 @@ +"use client"; +import React, { useRef } from "react"; + +import { cn } from "@/lib/utils"; + +export default function Expandable({ + id, + expanded, + className, + children, +}: { + id?: string; + className?: string; + expanded: boolean; + children: React.ReactNode; +}) { + const element = useRef(null); + return ( + <> +
+ {children} +
+ + ); +} diff --git a/components/forms/password.tsx b/components/forms/password.tsx new file mode 100644 index 0000000..c3dbe8d --- /dev/null +++ b/components/forms/password.tsx @@ -0,0 +1,60 @@ +"use client"; +import Link from "next/link"; +import { useRef, useState } from "react"; +import { FaEye } from "react-icons/fa6"; + +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { cn } from "@/lib/utils"; + +export default function PasswordInput() { + const [submitActive] = useState(false); + const inputRef = useRef(null); + const [passwordStatus, setPasswordStatus] = useState(false); + const changeInputStatusAndFocus = () => { + setPasswordStatus(!passwordStatus); + inputRef.current!.focus(); + }; + return ( + <> +
+
+ + + Forgot your password? + +
+ + +
+
+
+
+
+
+
+ + ); +} diff --git a/components/forms/rePassword.tsx b/components/forms/rePassword.tsx new file mode 100644 index 0000000..84eff0d --- /dev/null +++ b/components/forms/rePassword.tsx @@ -0,0 +1,48 @@ +"use client"; + +import { useRef, useState } from "react"; +import { FaEye } from "react-icons/fa6"; + +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { cn } from "@/lib/utils"; + +export default function RePasswordInput() { + const [submitActive] = useState(false); + const inputRef = useRef(null); + const [passwordStatus, setPasswordStatus] = useState(false); + const changeInputStatusAndFocus = () => { + setPasswordStatus(!passwordStatus); + inputRef.current!.focus(); + }; + return ( + <> +
+ + + +
+ + ); +}