Skip to content

Commit

Permalink
feat: add password visibility button to authentication pages (#572)
Browse files Browse the repository at this point in the history
* LoginForm Visibility Feature

* Others Pages Password Visibility Feature

* `register/[uuid].js` Password Visibility Feature

* Ran Formatter

* Created PasswordInput component

* Add cursors-pointer style

* Ran formatter

* GH requested Changes

* Fixed name/id props

* Removing right Props from Input

* Adding ids props and some fixes

* removed type props

* Revert "Removing right Props from Input"

This reverts commit 3ac9ec6.

* InputBase Wrapper Component
  • Loading branch information
Darguima authored Nov 24, 2023
1 parent 0de9a08 commit 4923c9c
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 59 deletions.
92 changes: 60 additions & 32 deletions components/Input/index.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
import { forwardRef, InputHTMLAttributes } from "react";

interface Props extends InputHTMLAttributes<HTMLInputElement> {
export interface InputBaseProps
extends Pick<InputHTMLAttributes<HTMLDivElement>, "id" | "children"> {
text: string;
autocomplete?: string;
fgColor: string;
bgColor: string;
enabled?: boolean;
}

export default forwardRef<HTMLInputElement, Props>(function Input(
{
text,
id,
name,
type,
value,
autocomplete,
fgColor,
bgColor,
onChange,
enabled,
...rest
},
ref
) {
export interface InputDefaultProps
extends InputBaseProps,
InputHTMLAttributes<HTMLInputElement> {}

// A wrapper to the <input> to standardize styles for the container
export function InputBase({
text,
id,
fgColor,
bgColor,
enabled,
children,
}: InputBaseProps) {
let textColor = `text-${fgColor}`;
let backColor = `bg-${bgColor}`;

Expand All @@ -43,21 +40,52 @@ export default forwardRef<HTMLInputElement, Props>(function Input(
>
{text}
</label>
<div className="mt-2">
<input
id={id}
name={name}
type={type}
autoComplete={autocomplete}
value={value}
required
className={`text-iregular ${textColor} ${backColor} block w-full appearance-none rounded-full border border-gray-300 px-3 py-2 pl-6 placeholder-gray-400 shadow-sm focus:outline-none sm:text-sm`}
onChange={onChange}
disabled={enabled == false}
ref={ref}
{...rest}
/>
<div
className={`text-iregular mt-2 flex items-center ${textColor} ${backColor} appearance-none rounded-full border border-gray-300 px-3 py-2 pl-6 placeholder-gray-400 shadow-sm sm:text-sm`}
>
{children}
</div>
</div>
);
}

export default forwardRef<HTMLInputElement, InputDefaultProps>(function Input(
{
text,
id,
name,
type,
value,
autoComplete,
fgColor,
bgColor,
onChange,
enabled,
...rest
},
ref
) {
return (
<InputBase
text={text}
id={id}
fgColor={fgColor}
bgColor={bgColor}
enabled={enabled}
>
<input
id={id}
name={name}
type={type}
autoComplete={autoComplete}
value={value}
required
className="w-full bg-transparent outline-none"
onChange={onChange}
disabled={enabled == false}
ref={ref}
{...rest}
/>
</InputBase>
);
});
45 changes: 45 additions & 0 deletions components/PasswordInput/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { forwardRef, useState } from "react";

import { InputBase, InputDefaultProps } from "@components/Input";

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";

export default forwardRef<HTMLInputElement, InputDefaultProps>(
function PasswordInput(
{ text, id, name, type, fgColor, bgColor, enabled, ...rest },
ref
) {
const [isPasswordVisible, setIsPasswordVisible] = useState(false);

const togglePasswordVisibility = () => {
setIsPasswordVisible(!isPasswordVisible);
};

return (
<InputBase
text={text}
id={id}
fgColor={fgColor}
bgColor={bgColor}
enabled={enabled}
>
<input
id={id}
name={name}
type={isPasswordVisible ? "text" : "password"}
required
className="w-full bg-transparent outline-none"
disabled={enabled == false}
ref={ref}
{...rest}
/>
<FontAwesomeIcon
className="mx-2 cursor-pointer"
onClick={togglePasswordVisibility}
icon={isPasswordVisible ? faEyeSlash : faEye}
/>
</InputBase>
);
}
);
5 changes: 2 additions & 3 deletions layout/Login/components/LoginForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Text from "@layout/moonstone/authentication/Text";

import Form from "@components/Form";
import Input from "@components/Input";
import PasswordInput from "@components/PasswordInput";

export default function LoginForm() {
const { errors, login, isLoading } = useAuth();
Expand Down Expand Up @@ -35,14 +36,12 @@ export default function LoginForm() {
autoComplete="email"
ref={emailRef}
/>
<Input
<PasswordInput
text="YOUR PASSWORD"
id="password"
name="password"
type="password"
fgColor="white"
bgColor="primary"
autoComplete="current-password"
ref={passwordRef}
/>
<Text
Expand Down
10 changes: 3 additions & 7 deletions layout/ResetPassword/components/ResetPasswordForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Button from "@components/Button";
import ImageButton from "@components/ImageButton";

import Form from "@components/Form";
import Input from "@components/Input";
import PasswordInput from "@components/PasswordInput";

export default function ResetPasswordForm() {
const router = useRouter();
Expand Down Expand Up @@ -51,22 +51,18 @@ export default function ResetPasswordForm() {
<>
{success === null && (
<Form onSubmit={onSubmit}>
<Input
<PasswordInput
text="PASSWORD"
id="password"
name="password"
type="password"
autoComplete="current-password"
fgColor="white"
bgColor="primary"
ref={passwordRef}
/>
<Input
<PasswordInput
text="CONFIRM PASSWORD"
id="confirm"
name="confirm"
type="password"
autoComplete="current-password"
fgColor="white"
bgColor="primary"
ref={passwordConfirmationRef}
Expand Down
13 changes: 5 additions & 8 deletions layout/SignUp/components/SignUpForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useAuth } from "@context/Auth";
import Button from "@components/Button";
import Form from "@components/Form";
import Input from "@components/Input";
import PasswordInput from "@components/PasswordInput";

import BarebonesQRScanner from "@components/QRScanner/BarebonesQRScanner";

Expand Down Expand Up @@ -92,22 +93,18 @@ export default function SignUpForm() {
bgColor="primary"
onChange={(e) => updateNickname(e.currentTarget.value)}
/>
<Input
<PasswordInput
text="PASSWORD"
id="password"
name="password"
type="password"
autoComplete="current-password"
fgColor="white"
bgColor="primary"
onChange={(e) => updatePassword(e.currentTarget.value)}
/>
<Input
<PasswordInput
text="CONFIRM PASSWORD"
id="password"
name="password"
type="password"
autoComplete="current-password"
id="confirm"
name="confirm"
fgColor="white"
bgColor="primary"
onChange={(e) => updatePasswordConfirmation(e.currentTarget.value)}
Expand Down
15 changes: 6 additions & 9 deletions pages/register/[uuid].js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Card from "@components/Card";
import Return from "@components/Return";
import Form from "@components/Form";
import Input from "@components/Input";
import PasswordInput from "@components/PasswordInput";

import Title from "@layout/moonstone/authentication/Title";
import Text from "@layout/moonstone/authentication/Text";
Expand Down Expand Up @@ -68,22 +69,18 @@ function Register() {
bgColor="primary"
onChange={(e) => updateNickname(e.currentTarget.value)}
/>
<Input
<PasswordInput
text="PASSWORD"
id="password"
id="confirm"
name="password"
type="password"
autoComplete="current-password"
fgColor="white"
bgColor="primary"
onChange={(e) => updatePassword(e.currentTarget.value)}
/>
<Input
<PasswordInput
text="CONFIRM PASSWORD"
id="password"
name="password"
type="password"
autoComplete="current-password"
id="confirm"
name="confirm"
fgColor="white"
bgColor="primary"
onChange={(e) => updatePasswordConfirmation(e.currentTarget.value)}
Expand Down

0 comments on commit 4923c9c

Please sign in to comment.