Как сделать отображение валидации раздельной react hook form?

Суть: хочу сделать так, что бы валидация поля выглядила так как на скрине, тоесть есть форма, которая сделана с помощью хука useForm из react hook form, при вводе текса в строку, снизу строки должны отображатьcя 3 строки (как на скрине) и эти строки должны менять цвет текса и галочку в зависимости от результата валидации. Как можно сделать такое отображение валидации используя react hook form? Или всё же нужно написать функцию, которая принимает строку и проверяет для каждого вида валидации условия и возвращает true или false?

введите сюда описание изображения введите сюда описание изображения

useView.ts

import { useForm, UseFormReturn } from 'react-hook-form'
import { emailFormScheme, EmailFormScheme } from '../constants/emailFormScheme'
import { useState } from 'react'
import { passwordFormScheme, PasswordFormScheme } from '../constants/passwordFormScheme'
import { zodResolver } from '@hookform/resolvers/zod';
import { useNavigate } from 'react-router-dom';


export type stages = 'email' | 'password' | 'about'

export const useView = () => {

    const navigate = useNavigate()
    const [stage, setStage] = useState<stages>('email')
    const signUpForm = useForm<EmailFormScheme | PasswordFormScheme>({
        mode: 'onBlur',
        defaultValues: {
            email: '',
            password: ''
        },
        resolver: zodResolver(stage === 'email' ? emailFormScheme : stage === 'password' ? passwordFormScheme : emailFormScheme)
    })

    const onSubmit = signUpForm.handleSubmit(value => {
        if(stage === 'email' && 'email' in value) {
            navigate('step=1')
            setStage('password')
            return
        }
    })

    const back = () => {
        switch(stage) {
            case 'password': {
                setStage('email')
                navigate(-1)
                break
            }
        }
    }

    return {
        form: signUpForm,
        stage,
        functions: { onSubmit, back }
    }
}

passwordFormScheme.ts

import { z } from "zod";



export const passwordFormScheme = z.object({
    password: z
        .string()
        .min(10)
})

export type PasswordFormScheme = z.infer<typeof passwordFormScheme>
import { Box, Button, Fade, IconButton, InputAdornment, List, ListItem, ListItemAvatar, ListItemButton, ListItemIcon, ListItemText, MenuItem, MenuList, OutlinedInput, Stack, TextField, Typography } from '@mui/material'
import React from 'react'
import { TextFieldWithLabel } from '../../components/input/textFieldWithLabel'
import Visibility from '@mui/icons-material/Visibility';
import VisibilityOff from '@mui/icons-material/VisibilityOff';
import { Controller } from 'react-hook-form'
import { ContextType } from '../../signUp'
import { useOutletContext } from 'react-router-dom'
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import PanoramaFishEyeIcon from '@mui/icons-material/PanoramaFishEye';
import styles from './passwordStage.module.scss'

export const PasswordStage = () => {
  const { form, functions, stage } = useOutletContext<ContextType>()
  const [showPassword, setShowPassword] = React.useState(false);
  const handleClickShowPassword = () => setShowPassword((show) => !show);
  const handleMouseDownPassword = (event: React.MouseEvent<HTMLButtonElement>) => {
    event.preventDefault();
  };
  
  return (
    <Box
      width='324px'
      mt={5}
    >
      <Fade in timeout={400} >
        <Box>
          <Controller
            name='password'
            control={form.control}
            render={({ field, fieldState }) => (
              <Box>
                <TextFieldWithLabel
                  size='small'
                  inputLabel='Password'
                  type={showPassword ? 'text' : 'password'}
                  value={field.value}
                  onChange={(e) => field.onChange(e.target.value)}
                  error={!!fieldState.error}
                  endAdornment={
                    <InputAdornment position="end">
                      <IconButton
                        sx={{ color: '#a0a0a0' }}
                        aria-label="toggle password visibility"
                        onClick={handleClickShowPassword}
                        onMouseDown={handleMouseDownPassword}
                        edge="end"
                      >
                        {showPassword ? <Visibility /> : <VisibilityOff />}
                      </IconButton>
                    </InputAdornment>
                  }
                />
                <Box mt={1}>
                  <Typography variant='body2' color='white' fontWeight='600'>
                    The password must contain at least:
                  </Typography>
                  <Stack spacing={1} mt={1} fontWeight='700' color='white'>
                    <Stack direction='row' spacing={0.7} alignItems='baseline'>
                      <PanoramaFishEyeIcon sx={{ color: '#a0a0a0', fontSize: '13px' }} />
                      <Typography sx={{ fontSize: '0.8125rem' }}>1 letter</Typography>
                    </Stack>
                    <Stack direction='row' spacing={0.7} alignItems='baseline'>
                      <PanoramaFishEyeIcon sx={{ color: '#a0a0a0', fontSize: '13px' }} />
                      <Typography sx={{ fontSize: '0.8125rem' }}>1 number or 1 special character (for example: # ? ! &)</Typography>
                    </Stack>
                    <Stack direction='row' spacing={0.7} alignItems='baseline'>
                      <PanoramaFishEyeIcon sx={{ color: '#a0a0a0', fontSize: '13px' }} />
                      <Typography sx={{ fontSize: '0.8125rem' }}>10 symbols</Typography>
                    </Stack>
                  </Stack>
                </Box>
              </Box>
            )}
          />
        </Box>
      </Fade>
      <Button fullWidth className={styles.submitButton}>
        Further
      </Button>
    </Box>
  )
}



Ответы (0 шт):