I’m using react-hot-toast to show alerts & animate it while changing pages.
The animation plays fades in twice when page changes.
I’m using tailwindcss-animate in my tailwind.config.js
to add animation classes.
I’m only using 4 animation classes: animate-in
, animate-out
, fade-in
, & fade-out
I am animating a custom Success
alert box.
Success.tsx
import toast, { ToastOptions } from 'react-hot-toast'; import { CheckCircleIcon } from '@heroicons/react/outline'; import clsx from 'clsx'; interface ISuccess { message: string; options?: ToastOptions; } export const Success = ({ message, options }: ISuccess) => { toast.custom( (t) => ( <div className={clsx( 'flex rounded-lg bg-gray-900 py-2.5 px-3 shadow-lg ring-1 ring-black ring-opacity-5', { 'animate-in fade-in': t.visible, 'fade-out animate-out': !t.visible, } )} > <CheckCircleIcon className="h-6 w-6 text-gray-700" /> <div className="ml-2 text-gray-300">{message}</div> </div> ), { duration: 250, ...options, } ); };
If you click the link in the demo below, then you should see the animation play twice like the gif below:
How do I fix it so it only plays once?
Stackblitz Demo → https://stackblitz.com/edit/animate-in-tailwind
Github Repo → https://github.com/deadcoder0904/animate-in-tailwind/
Advertisement
Answer
When you switch the animation using t.visible
, the fadeIn
and fadeOut
css properties of the finishing keyframe will not preserve. In other words, the Opacity: 0
will be removed, causing the node appear again. You can try to add style={{ animationFillMode: 'forwards' }}
to retain the computed values set by the last keyframe.
Example:
<div style={{ animationFillMode: 'forwards' }} className={clsx( 'flex rounded-lg bg-gray-900 py-2.5 px-3 shadow-lg ring-1 ring-black ring-opacity-5', { 'animate-in fade-in': t.visible, 'fade-out animate-out': !t.visible, } )} >
You can also change the animation fill mode by adding class name fill-mode-forwards
if you are using tailwind-animation.
Example:
<div className={clsx( 'flex rounded-lg bg-gray-900 py-2.5 px-3 shadow-lg ring-1 ring-black ring-opacity-5', { 'animate-in fade-in fill-mode-forwards': t.visible, 'fade-out animate-out fill-mode-forwards': !t.visible, } )} >