veza/apps/web/src/components/ui/content-transition/ContentTransition.tsx

43 lines
1.1 KiB
TypeScript
Raw Normal View History

import { AnimatePresence, motion } from 'framer-motion';
import { ReactNode } from 'react';
interface ContentTransitionProps {
/** Whether content is still loading */
isLoading: boolean;
/** The skeleton/loading placeholder */
skeleton: ReactNode;
/** The actual content */
children: ReactNode;
/** Optional className for the wrapper */
className?: string;
}
export function ContentTransition({ isLoading, skeleton, children, className }: ContentTransitionProps) {
return (
<div className={className}>
<AnimatePresence mode="wait">
{isLoading ? (
<motion.div
key="skeleton"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.15 }}
>
{skeleton}
</motion.div>
) : (
<motion.div
key="content"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.2, delay: 0.05 }}
>
{children}
</motion.div>
)}
</AnimatePresence>
</div>
);
}