A
Anonymous

Form Container - Copy this React, Mui Component to your project

Here is an example of the component using Tailwind CSS. Mirror the styling and effects in MUI, but with the exact same CSS output as the following: import { useState } from "react"; import { useForm } from "react-hook-form"; import { motion, AnimatePresence } from "framer-motion"; import * as yup from "yup"; import { yupResolver } from "@hookform/resolvers/yup"; import { FiUser, FiCheckCircle, FiAlertCircle, FiArrowRight, FiArrowLeft } from "react-icons/fi"; const schema = yup.object().shape({ fullName: yup.string().required("Full name is required").min(2, "Name must be at least 2 characters"), position: yup.string(), companyName: yup.string().required("Company name is required"), companySize: yup.string().required("Company size is required"), email: yup.string().email("Invalid email format").required("Email is required"), phone: yup.string(), businessSector: yup.string().required("Business sector is required"), businessActivity: yup.string().min(20, "Please provide at least 20 characters"), annualRevenue: yup.string(), employeeCount: yup.string().required("Number of employees is required"), currentPlatform: yup.string(), challenges: yup.array(), challengeDescription: yup.string().min(30, "Please provide at least 30 characters"), timeline: yup.string() }); const LeadCaptureForm = () => { const [step, setStep] = useState(1); const [isSubmitting, setIsSubmitting] = useState(false); const { register, handleSubmit, formState: { errors }, trigger, watch } = useForm({ resolver: yupResolver(schema), mode: "onBlur" }); const onSubmit = async (data) => { setIsSubmitting(true); try { await new Promise(resolve => setTimeout(resolve, 2000)); console.log("Form submitted:", data); setStep(4); } catch (error) { console.error("Submission error:", error); } finally { setIsSubmitting(false); } }; const nextStep = async () => { const fields = getFieldsByStep(step); const isStepValid = await trigger(fields); if (isStepValid) { setStep(step + 1); } }; const getFieldsByStep = (step) => { switch (step) { case 1: return ["fullName", "position", "companyName", "companySize", "email", "phone"]; case 2: return ["businessSector", "businessActivity", "annualRevenue", "employeeCount"]; case 3: return ["currentPlatform", "challenges", "challengeDescription", "timeline"]; default: return []; } }; const FormStep1 = () => ( <motion.div initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -20 }} className="space-y-4" > <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Full Name *</label> <input {...register("fullName")} type="text" className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 ${errors.fullName ? 'border-red-500' : 'border-gray-300'}`} /> {errors.fullName && ( <span className="text-sm text-red-500">{errors.fullName.message}</span> )} </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Position</label> <input {...register("position")} type="text" className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 border-gray-300" /> </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Company Name *</label> <input {...register("companyName")} type="text" className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 ${errors.companyName ? 'border-red-500' : 'border-gray-300'}`} /> {errors.companyName && ( <span className="text-sm text-red-500">{errors.companyName.message}</span> )} </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Company Size *</label> <select {...register("companySize")} className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 ${errors.companySize ? 'border-red-500' : 'border-gray-300'}`} > <option value="">Select Size</option> <option value="1-10">1-10 employees</option> <option value="11-50">11-50 employees</option> <option value="51-200">51-200 employees</option> <option value="201-500">201-500 employees</option> <option value="501+">501+ employees</option> </select> {errors.companySize && ( <span className="text-sm text-red-500">{errors.companySize.message}</span> )} </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Email *</label> <input {...register("email")} type="email" className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 ${errors.email ? 'border-red-500' : 'border-gray-300'}`} /> {errors.email && ( <span className="text-sm text-red-500">{errors.email.message}</span> )} </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Phone</label> <input {...register("phone")} type="tel" className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 border-gray-300" /> </div> </motion.div> ); const FormStep2 = () => ( <motion.div initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -20 }} className="space-y-4" > <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Business Sector *</label> <select {...register("businessSector")} className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 ${errors.businessSector ? "border-red-500" : "border-gray-300"}`} > <option value="">Select Sector</option> <option value="technology">Technology</option> <option value="healthcare">Healthcare</option> <option value="finance">Finance</option> <option value="retail">Retail</option> </select> {errors.businessSector && ( <span className="text-sm text-red-500">{errors.businessSector.message}</span> )} </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Business Activity</label> <textarea {...register("businessActivity")} className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 ${errors.businessActivity ? "border-red-500" : "border-gray-300"}`} /> {errors.businessActivity && ( <span className="text-sm text-red-500">{errors.businessActivity.message}</span> )} </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Annual Revenue</label> <input {...register("annualRevenue")} type="text" className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 border-gray-300" /> </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Number of Employees *</label> <input {...register("employeeCount")} type="text" className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 ${errors.employeeCount ? "border-red-500" : "border-gray-300"}`} /> {errors.employeeCount && ( <span className="text-sm text-red-500">{errors.employeeCount.message}</span> )} </div> </motion.div> ); const FormStep3 = () => ( <motion.div initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -20 }} className="space-y-4" > <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Current Platform</label> <input {...register("currentPlatform")} type="text" className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 border-gray-300" /> </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Challenges</label> <input {...register("challenges")} type="text" className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 border-gray-300" /> </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Challenge Description</label> <input {...register("challengeDescription")} type="text" className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 border-gray-300" /> </div> <div className="space-y-2"> <label className="block text-sm font-medium text-gray-700">Timeline</label> <input {...register("timeline")} type="text" className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 border-gray-300" /> </div> </motion.div> ); const SuccessStep = () => ( <motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} className="text-center space-y-4" > <FiCheckCircle className="mx-auto text-6xl text-green-500" /> <h2 className="text-2xl font-bold text-gray-800">Thank You!</h2> <p className="text-gray-600">We'll be in touch with you shortly.</p> </motion.div> ); return ( <div className="min-h-screen bg-gradient-to-br from-purple-50 to-white py-12 px-4 sm:px-6 lg:px-8"> <div className="max-w-2xl mx-auto bg-white rounded-xl shadow-lg p-8"> <div className="mb-8"> <div className="flex justify-center space-x-2 mb-4"> {[1, 2, 3].map((i) => ( <div key={i} className={`w-3 h-3 rounded-full ${step >= i ? 'bg-purple-600' : 'bg-gray-200'}`} /> ))} </div> <h2 className="text-center text-3xl font-bold text-gray-900"> {step === 4 ? "Success!" : `Step ${step} of 3`} </h2> </div> <form onSubmit={handleSubmit(onSubmit)} className="space-y-6"> <AnimatePresence mode="wait"> {step === 1 && <FormStep1 />} {step === 2 && <FormStep2 />} {step === 3 && <FormStep3 />} {step === 4 && <SuccessStep />} </AnimatePresence> {step < 4 && ( <div className="flex justify-between pt-4"> {step > 1 && ( <button type="button" onClick={() => setStep(step - 1)} className="flex items-center px-6 py-2 text-purple-600 hover:text-purple-700" > <FiArrowLeft className="mr-2" /> Back </button> )} {step < 3 ? ( <button type="button" onClick={nextStep} className="flex items-center px-6 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 ml-auto" > Next <FiArrowRight className="ml-2" /> </button> ) : ( <button type="submit" disabled={isSubmitting} className="flex items-center px-8 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 ml-auto disabled:opacity-50" > {isSubmitting ? "Submitting..." : "Get Started"} </button> )} </div> )} </form> </div> </div> ); }; export default LeadCaptureForm;

Prompt

About

FormContainer - A sleek, responsive form layout mimicking Tailwind CSS styles, built with React and MUI. Perfect for modern applications. Start coding now!

Share

Last updated 1 month ago