Skip to content

Commit 127e26a

Browse files
committed
chore: added custom error message to passwordInput component
1 parent 96d11eb commit 127e26a

File tree

4 files changed

+51
-7
lines changed

4 files changed

+51
-7
lines changed

src/components/PasswordInput/PasswordConstants.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export type TScore = 0 | 1 | 2 | 3 | 4;
1+
export type TScore = 0 | 1 | 2 | 3 | 4 | 5;
22

33
export type passwordKeys =
44
| "common"

src/components/PasswordInput/PasswordUtils.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ export const isPasswordStrong = (password: string) => {
3131
);
3232
};
3333

34-
export const calculateScore = (password: string) => {
34+
export const calculateScore = (password: string, customErrorMessage="") => {
3535
if (password?.length === 0) return 0;
36+
if (customErrorMessage) return 5;
3637
if (!isPasswordValid(password)) return 1;
3738
if (
3839
!isPasswordStrong(password) &&

src/components/PasswordInput/index.tsx

+19-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, {
33
ComponentProps,
44
FocusEvent,
55
useCallback,
6+
useEffect,
67
useMemo,
78
useState,
89
} from "react";
@@ -22,8 +23,8 @@ import { EyeIcon, EyeIconSlash } from "./PasswordIcon";
2223
import { PasswordMeter } from "./PasswordMeter";
2324
import "./PasswordInput.scss";
2425

25-
export const validatePassword = (password: string) => {
26-
const score = calculateScore(password);
26+
export const validatePassword = (password: string, customErrorMessage="") => {
27+
const score = calculateScore(password, customErrorMessage);
2728
let errorMessage = "";
2829

2930
const options = { dictionary: { ...dictionary } };
@@ -36,9 +37,14 @@ export const validatePassword = (password: string) => {
3637
errorMessage = passwordErrorMessage.invalidLength;
3738
} else if (!isPasswordValid(password)) {
3839
errorMessage = passwordErrorMessage.missingCharacter;
39-
} else {
40+
}
41+
else if( customErrorMessage){
42+
errorMessage = customErrorMessage;
43+
}
44+
else {
4045
errorMessage = warningMessages[feedback.warning as passwordKeys] ?? "";
4146
}
47+
4248
return { errorMessage, score };
4349
};
4450

@@ -47,6 +53,7 @@ type InputProps = ComponentProps<typeof Input>;
4753
interface PasswordInputProps extends Omit<InputProps, "rightPlaceholder"> {
4854
hidePasswordMeter?: boolean;
4955
hint?: string;
56+
customErrorMessage?: string;
5057
}
5158

5259
const PasswordVariant: Record<TScore, InputProps["variant"]> = {
@@ -55,6 +62,7 @@ const PasswordVariant: Record<TScore, InputProps["variant"]> = {
5562
2: "warning",
5663
3: "success",
5764
4: "success",
65+
5: "error",
5866
};
5967

6068
/**
@@ -86,19 +94,25 @@ export const PasswordInput = ({
8694
onBlur,
8795
onChange,
8896
value,
97+
customErrorMessage="",
8998
...rest
9099
}: PasswordInputProps) => {
100+
useEffect(() => {
101+
setBackendErrorMessage(customErrorMessage);
102+
}, [customErrorMessage]);
91103
const [isTouched, setIsTouched] = useState(false);
92104
const [showPassword, setShowPassword] = useState(false);
105+
const [backendErrorMessage, setBackendErrorMessage] = useState(customErrorMessage);
93106

94107
const { errorMessage, score } = useMemo(
95-
() => validatePassword(value as string),
96-
[value],
108+
() => validatePassword(value as string, backendErrorMessage),
109+
[value, backendErrorMessage],
97110
);
98111

99112
const handleChange = useCallback(
100113
(e: ChangeEvent<HTMLInputElement>) => {
101114
onChange?.(e);
115+
setBackendErrorMessage("");
102116
if (!isTouched) {
103117
setIsTouched(true);
104118
}

stories/PasswordInput.stories.tsx

+29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { StoryObj, Meta } from "@storybook/react";
22
import { PasswordInput } from "../src/main";
33
import { useState } from "react";
4+
import {Button} from "../src/main";
45

56
const meta = {
67
title: "Components/PasswordInput",
@@ -121,3 +122,31 @@ export const HidePasswordMeter: Story = {
121122
);
122123
},
123124
};
125+
126+
export const customErrorMessage: Story = {
127+
name: "Password Input with custom error message",
128+
args: {
129+
label: "Enter Password",
130+
value: "",
131+
onChange: () => {},
132+
hidePasswordMeter: true,
133+
hint: "This is a hint message",
134+
},
135+
render: (args) => {
136+
const [value, setValue] = useState(args.value);
137+
const [errorMessage, setErrorMessage] = useState("");
138+
139+
140+
return (
141+
<div className="theme--light" style={{display:"flex", flexDirection:"column"}}>
142+
<PasswordInput
143+
{...args}
144+
value={value}
145+
customErrorMessage={errorMessage}
146+
onChange={(e) => setValue(e.target.value)}
147+
/>
148+
<Button onClick={() => setErrorMessage("This is a custom error message")}>submit</Button>
149+
</div>
150+
);
151+
},
152+
};

0 commit comments

Comments
 (0)