@@ -34,8 +34,14 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
34
34
const [ passwordRules , setPasswordRules ] = useState < PasswordRules | null > ( null ) ;
35
35
const [ isPasswordValid , setIsPasswordValid ] = useState < boolean > ( false ) ;
36
36
const allRulesPassed = passwordRules && Object . values ( passwordRules ) . every ( ( passed ) => passed === true ) ;
37
+ const [ hasStartedTyping , setHasStartedTyping ] = useState ( false ) ;
37
38
const navigate = useNavigate ( ) ;
38
39
40
+ const handleInputChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
41
+ setHasStartedTyping ( true ) ;
42
+ handlePasswordChange ( e ) ;
43
+ } ;
44
+
39
45
// Username availability check with debounce
40
46
useEffect ( ( ) => {
41
47
const checkUsernameAvailability = async ( ) => {
@@ -234,6 +240,7 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
234
240
< Label className = "sr-only" htmlFor = "password" >
235
241
Password
236
242
</ Label >
243
+
237
244
< div className = "relative flex items-center" >
238
245
< Input
239
246
id = "password"
@@ -242,42 +249,46 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
242
249
autoComplete = "current-password"
243
250
disabled = { isLoading }
244
251
value = { password }
245
- onChange = { handlePasswordChange }
246
- className = "dark:bg-zinc-900 pr-10"
252
+ onChange = { handleInputChange }
253
+ className = "dark:bg-zinc-900 pr-10"
247
254
required
248
255
/>
249
- { allRulesPassed && (
250
- < HoverCard >
251
- < HoverCardTrigger asChild >
252
- < Check className = "absolute right-3 text-green-500" />
253
- </ HoverCardTrigger >
254
- < HoverCardContent className = "text-green-500 text-sm bg-zinc-900" >
255
- { passwordRules &&
256
- Object . entries ( passwordRules ) . map ( ( [ rule , passed ] ) => (
257
- < p key = { rule } className = { passed ? "text-green-500" : "text-red-500" } >
258
- { passwordRuleMessages [ rule as keyof typeof passwordRuleMessages ] }
259
- </ p >
260
- ) ) }
261
- </ HoverCardContent >
262
- </ HoverCard >
263
- ) }
264
- { ! allRulesPassed && (
265
- < HoverCard >
266
- < HoverCardTrigger asChild >
267
- < X className = "absolute right-3 text-red-500" />
268
- </ HoverCardTrigger >
269
- < HoverCardContent className = "text-red-500 text-sm bg-zinc-900" >
270
- { passwordRules &&
271
- Object . entries ( passwordRules ) . map ( ( [ rule , passed ] ) => (
272
- < p key = { rule } className = { passed ? "text-green-500" : "text-red-500" } >
273
- { passwordRuleMessages [ rule as keyof typeof passwordRuleMessages ] }
274
- </ p >
275
- ) ) }
276
- </ HoverCardContent >
277
- </ HoverCard >
256
+
257
+ { /* Show the validation only after user has started typing */ }
258
+ { hasStartedTyping && (
259
+ < >
260
+ { allRulesPassed ? (
261
+ < HoverCard >
262
+ < HoverCardTrigger asChild >
263
+ < Check className = "absolute right-3 text-green-500" />
264
+ </ HoverCardTrigger >
265
+ < HoverCardContent className = "text-green-500 text-sm bg-zinc-900" >
266
+ { passwordRules &&
267
+ Object . entries ( passwordRules ) . map ( ( [ rule , passed ] ) => (
268
+ < p key = { rule } className = { passed ? "text-green-500" : "text-red-500" } >
269
+ { passwordRuleMessages [ rule as keyof typeof passwordRuleMessages ] }
270
+ </ p >
271
+ ) ) }
272
+ </ HoverCardContent >
273
+ </ HoverCard >
274
+ ) : (
275
+ < HoverCard >
276
+ < HoverCardTrigger asChild >
277
+ < X className = "absolute right-3 text-red-500" />
278
+ </ HoverCardTrigger >
279
+ < HoverCardContent className = "text-red-500 text-sm bg-zinc-900" >
280
+ { passwordRules &&
281
+ Object . entries ( passwordRules ) . map ( ( [ rule , passed ] ) => (
282
+ < p key = { rule } className = { passed ? "text-green-500" : "text-red-500" } >
283
+ { passwordRuleMessages [ rule as keyof typeof passwordRuleMessages ] }
284
+ </ p >
285
+ ) ) }
286
+ </ HoverCardContent >
287
+ </ HoverCard >
288
+ ) }
289
+ </ >
278
290
) }
279
291
</ div >
280
-
281
292
</ div >
282
293
< Button
283
294
disabled = {
0 commit comments