Step Form
Um provider de formulário com animação passo-a-passo
Código:
//src/components/stepFormProvider/stepFormProvider.tsx 'use client'; import { ReactNode, useEffect, useState } from 'react'; interface FormProviderProps { forms: ReactNode[]; actualForm: number; } export default function StepFormProvider({ forms, actualForm }: FormProviderProps) { const [prevForm, setPrevForm] = useState(actualForm); const [direction, setDirection] = useState(0); const [transitioning, setTransitioning] = useState(false); useEffect(() => { if (actualForm === prevForm) return; setDirection(actualForm > prevForm ? 1 : -1); setTransitioning(true); const timer = setTimeout(() => { setPrevForm(actualForm); setTransitioning(false); }, 300); // deve bater com a duração das animações return () => clearTimeout(timer); }, [actualForm, prevForm]); return ( <div className='relative h-full w-full overflow-hidden'> {/* Form que está saindo */} {transitioning && ( <div className='absolute left-0 top-0 h-full w-full' style={{ animation: `${direction === 1 ? 'slideOutLeft' : 'slideOutRight'} 300ms ease-in-out forwards`, }} > {forms[prevForm]} </div> )} {/* Form que está entrando */} <div className='absolute left-0 top-0 h-full w-full' style={{ animation: transitioning? `${direction === 1 ? 'slideInRight' : 'slideInLeft'} 300ms ease-in-out forwards`: undefined, }} > {forms[transitioning ? actualForm : prevForm]} </div> <style jsx global>{`@keyframes slideOutLeft {from { transform: translateX(0%); opacity: 1; } to { transform: translateX(-100%); opacity: 0; } } @keyframes slideOutRight { from { transform: translateX(0%); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } @keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0%); opacity: 1; } } @keyframes slideInLeft { from { transform: translateX(-100%); opacity: 0; } to { transform: translateX(0%); opacity: 1; } }`}</style></div> ); }
yarn add motion