Created
October 21, 2024 14:56
-
-
Save Masheen88/0f3a8562a5ee3814d1880da370c35577 to your computer and use it in GitHub Desktop.
React Form Validation Component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { useForm, Controller } from "react-hook-form"; | |
| import { useEffect } from "react"; | |
| // Define validation rules | |
| const validationRules = { | |
| required: { | |
| value: true, | |
| message: "This field is required.", | |
| }, | |
| email: { | |
| value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, | |
| message: "Invalid email format.", | |
| }, | |
| phone: { | |
| value: /^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$/, | |
| message: "Invalid phone number format.", | |
| }, | |
| min: (minValue) => ({ | |
| value: minValue, | |
| message: `Minimum ${minValue} characters required.`, | |
| }), | |
| }; | |
| // Define the custom form component | |
| const CustomInput = ({ | |
| name, | |
| type = "text", | |
| placeholder = "", | |
| required = false, | |
| rules = "", | |
| sampleText = "", | |
| options = [], | |
| selectPlaceholder = "Please select an option", | |
| }) => { | |
| const { | |
| control, | |
| register, | |
| formState: { errors }, | |
| } = useForm(); | |
| // Function to dynamically set rules based on type | |
| const getDefaultRulesForType = (type) => { | |
| switch (type) { | |
| case "email": | |
| return validationRules.email; | |
| case "tel": | |
| return validationRules.phone; | |
| case "text": | |
| return validationRules.min(2); | |
| default: | |
| return {}; | |
| } | |
| }; | |
| const combinedRules = { | |
| ...getDefaultRulesForType(type), | |
| ...rules, | |
| ...(required && validationRules.required), | |
| }; | |
| return ( | |
| <div className="mb-4"> | |
| {type === "select" ? ( | |
| <Controller | |
| name={name} | |
| control={control} | |
| rules={combinedRules} | |
| render={({ field }) => ( | |
| <select | |
| {...field} | |
| className="w-full border border-gray-300 dark:border-gray-600 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-gray-300 dark:focus:ring-indigo-300" | |
| > | |
| <option value="" disabled> | |
| {selectPlaceholder} | |
| </option> | |
| {options.map((option, index) => ( | |
| <option key={index} value={option.value}> | |
| {option.label} | |
| </option> | |
| ))} | |
| </select> | |
| )} | |
| /> | |
| ) : ( | |
| <input | |
| type={type} | |
| {...register(name, combinedRules)} | |
| placeholder={placeholder} | |
| className="w-full border border-gray-300 dark:border-gray-600 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-gray-300 dark:focus:ring-indigo-300" | |
| /> | |
| )} | |
| {errors[name] && ( | |
| <span className="text-red-400 text-sm italic"> | |
| {errors[name]?.message} | |
| {sampleText && ` Example: ${sampleText}`} | |
| </span> | |
| )} | |
| </div> | |
| ); | |
| }; | |
| export default CustomInput; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment