Skip to content

Commit fe9a9b9

Browse files
committed
feat: enhance PasswordInput with validation feedback and dynamic error messages
1 parent 5d94283 commit fe9a9b9

1 file changed

Lines changed: 65 additions & 10 deletions

File tree

src/components/form/PasswordInput.tsx

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import React, {RefObject} from "react";
22
import {Input, InputProps} from "./Input";
3-
import {IconEye, IconX} from "@tabler/icons-react";
3+
import {IconCheck, IconEye, IconX} from "@tabler/icons-react";
44
import {Button} from "../button/Button";
55
import {clearInputElement} from "./Input.utils";
6+
import {Flex} from "../flex/Flex";
7+
import {Text} from "../text/Text";
68

79
interface PasswordInputProps extends Omit<InputProps<string | null>, "wrapperComponent" | "type"> {
810
clearable?: boolean,
@@ -18,6 +20,7 @@ export const PasswordInput: React.ForwardRefExoticComponent<PasswordInputProps>
1820
clearable = true,
1921
visible = true,
2022
right,
23+
formValidation,
2124
...rest
2225
} = props
2326

@@ -39,16 +42,68 @@ export const PasswordInput: React.ForwardRefExoticComponent<PasswordInputProps>
3942
}
4043

4144
const rightAction = [right]
42-
visible && rightAction.push(<Button variant={"none"} onClick={(event) => toVisible(event)}><IconEye size={13}/></Button>)
43-
clearable && rightAction.push(<Button variant={"none"} onClick={(event) => toClearable(event)}><IconX size={13}/></Button>)
45+
visible && rightAction.push(<Button variant={"none"} onClick={(event) => toVisible(event)}><IconEye
46+
size={13}/></Button>)
47+
clearable && rightAction.push(<Button variant={"none"} onClick={(event) => toClearable(event)}><IconX
48+
size={13}/></Button>)
4449

4550

46-
return <Input
47-
right={rightAction}
48-
rightType={"action"}
49-
type={"password"}
50-
ref={ref as RefObject<HTMLInputElement>}
51-
{...rest}
52-
/>
51+
return <>
52+
<Input
53+
right={rightAction}
54+
rightType={"action"}
55+
type={"password"}
56+
ref={ref as RefObject<HTMLInputElement>}
57+
{...(formValidation ? {
58+
formValidation: {
59+
setValue: formValidation.setValue,
60+
valid: formValidation.valid,
61+
}
62+
} : {})}
63+
{...rest}
64+
/>
65+
{
66+
!formValidation?.valid && (
67+
<Flex mt={0.7} style={{flexDirection: "column"}}>
68+
<Flex align={"center"} style={{gap: "0.35rem"}}>
69+
{formValidation?.notValidMessage?.includes("1") ? <IconX color={"#D90429"} size={16}/> :
70+
<IconCheck color={"#29BF12"} size={16}/>}
71+
<Text>Must be at least 8 characters</Text>
72+
</Flex>
73+
<Flex align={"center"} style={{gap: "0.35rem"}}>
74+
{formValidation?.notValidMessage?.includes("2") ? <IconX color={"#D90429"} size={16}/> :
75+
<IconCheck color={"#29BF12"} size={16}/>}
76+
<Text>Must include a lowercase letter</Text>
77+
</Flex>
78+
<Flex align={"center"} style={{gap: "0.35rem"}}>
79+
{formValidation?.notValidMessage?.includes("3") ? <IconX color={"#D90429"} size={16}/> :
80+
<IconCheck color={"#29BF12"} size={16}/>}
81+
<Text>Must include an uppercase letter</Text>
82+
</Flex>
83+
<Flex align={"center"} style={{gap: "0.35rem"}}>
84+
{formValidation?.notValidMessage?.includes("4") ? <IconX color={"#D90429"} size={16}/> :
85+
<IconCheck color={"#29BF12"} size={16}/>}
86+
<Text>Must include a number</Text>
87+
</Flex>
88+
<Flex align={"center"} style={{gap: "0.35rem"}}>
89+
{formValidation?.notValidMessage?.includes("5") ? <IconX color={"#D90429"} size={16}/> :
90+
<IconCheck color={"#29BF12"} size={16}/>}
91+
<Text>Must include a special character</Text>
92+
</Flex>
93+
</Flex>
94+
)
95+
}
96+
</>
5397

5498
})
99+
100+
export const passwordValidation = (value: string | null): string | null => {
101+
if (!value) return "12345"
102+
let message: null | string = null
103+
if (value.length < 8) message = (message ?? "") + "1"
104+
if (!/[a-z]/.test(value)) message = (message ?? "") + "2"
105+
if (!/[A-Z]/.test(value)) message = (message ?? "") + "3"
106+
if (!/[0-9]/.test(value)) message = (message ?? "") + "4"
107+
if (!/[^A-Za-z0-9]/.test(value)) message = (message ?? "") + "5"
108+
return message
109+
}

0 commit comments

Comments
 (0)