66 forwardRef ,
77 LegacyRef ,
88 InputHTMLAttributes ,
9+ useState ,
910} from 'react' ;
1011import { FieldError } from 'react-hook-form' ;
1112
@@ -19,16 +20,27 @@ export function Form({
1920interface FormLabelProps
2021 extends DetailedHTMLProps < LabelHTMLAttributes < HTMLLabelElement > , HTMLLabelElement > {
2122 name : string ;
23+ asideComponent ?: JSX . Element ;
2224}
2325
24- function FormLabel ( { name, className, children, ...props } : FormLabelProps ) : JSX . Element {
26+ function FormLabel ( {
27+ name,
28+ asideComponent,
29+ className,
30+ children,
31+ ...props
32+ } : FormLabelProps ) : JSX . Element {
2533 return (
26- < label className = "form-label" { ...props } >
27- < span className = "form-label-text" > { name } </ span >
34+ < label className = { clsx ( 'form-label' , className ) } { ...props } >
35+ < div className = "flex w-full justify-between items-center" >
36+ < span className = "form-label-text" > { name } </ span >
37+ { asideComponent }
38+ </ div >
2839 { children }
2940 </ label >
3041 ) ;
3142}
43+ Form . Label = FormLabel ;
3244
3345interface FormErrorProps {
3446 message ?: string ;
@@ -44,8 +56,6 @@ function FormError({ message }: FormErrorProps): JSX.Element | null {
4456
4557Form . Error = FormError ;
4658
47- Form . Label = FormLabel ;
48-
4959interface FormInputProps
5060 extends DetailedHTMLProps < InputHTMLAttributes < HTMLInputElement > , HTMLInputElement > {
5161 className ?: string ;
@@ -58,15 +68,74 @@ const FormInput = forwardRef(function FormInput(
5868 ref
5969) {
6070 return (
61- < div className = { clsx ( 'form-input' , { 'focus-within:form-input-error' : error } , className ) } >
62- { icon && icon }
71+ < div
72+ className = { clsx (
73+ 'form-input-container' ,
74+ { 'focus-within:form-input-error' : error } ,
75+ className
76+ ) }
77+ >
78+ { icon && < div className = "form-input-icon-container" > { icon } </ div > }
79+
6380 < input
6481 { ...props }
6582 ref = { ref as LegacyRef < HTMLInputElement > | undefined }
66- className = { clsx ( 'w-full bg-transparent' , { 'pl-2' : icon } ) }
83+ type = "text"
84+ className = { clsx ( 'form-input' , {
85+ 'ml-1' : icon ,
86+ } ) }
6787 />
6888 </ div >
6989 ) ;
7090} ) ;
7191
7292Form . Input = FormInput ;
93+
94+ interface FormPasswordProps
95+ extends DetailedHTMLProps < InputHTMLAttributes < HTMLInputElement > , HTMLInputElement > {
96+ className ?: string ;
97+ icon ?: JSX . Element ;
98+ showPasswordIcon ?: JSX . Element ;
99+ hidePasswordIcon ?: JSX . Element ;
100+ error ?: FieldError ;
101+ }
102+
103+ const FormPassword = forwardRef ( function FormPassword (
104+ { className, icon, showPasswordIcon, hidePasswordIcon, error, ...props } : FormPasswordProps ,
105+ ref
106+ ) {
107+ const [ showPassword , setShowPassword ] = useState ( false ) ;
108+
109+ return (
110+ < div
111+ className = { clsx (
112+ 'form-input-container' ,
113+ { 'focus-within:form-input-error' : error } ,
114+ className
115+ ) }
116+ >
117+ { icon && < div className = "form-input-icon-container" > { icon } </ div > }
118+
119+ < input
120+ { ...props }
121+ ref = { ref as LegacyRef < HTMLInputElement > | undefined }
122+ type = { showPassword ? 'text' : 'password' }
123+ className = { clsx ( 'form-input' , {
124+ 'ml-1' : icon ,
125+ 'mr-1' : showPasswordIcon && hidePasswordIcon ,
126+ } ) }
127+ />
128+
129+ { showPasswordIcon && hidePasswordIcon && (
130+ < div
131+ className = "form-show-password-container"
132+ onClick = { ( ) => setShowPassword ( ! showPassword ) }
133+ >
134+ { showPassword ? showPasswordIcon : hidePasswordIcon }
135+ </ div >
136+ ) }
137+ </ div >
138+ ) ;
139+ } ) ;
140+
141+ Form . Password = FormPassword ;
0 commit comments