Component Preview
Click to trigger toast
'use client';
import {cn} from '@/lib/utils';
import {motion, AnimatePresence} from 'framer-motion';
import {useEffect} from 'react';
type ToastProps = {
message: string;
open: boolean;
duration?: number;
onClose?: () => void;
dr: 'br' | 'b' | 'bl' | 'tr' | 't' | 'tl';
};
const positionStyles: Record<ToastProps['dr'], {container: string; motion: any}> = {
br: {
container: 'bottom-6 right-6',
motion: {opacity: 1},
},
bl: {
container: 'bottom-6 left-6',
motion: {opacity: 1},
},
b: {
container: 'bottom-6 left-1/2 -translate-x-1/2',
motion: {opacity: 1},
},
tr: {
container: 'top-6 right-6',
motion: {opacity: 1},
},
tl: {
container: 'top-6 left-6',
motion: {opacity: 1},
},
t: {
container: 'top-6 left-1/2 -translate-x-1/2',
motion: {opacity: 1},
},
};
export function Toast({message, open, duration = 3000, onClose, dr = 'b'}: ToastProps) {
const pos = positionStyles[dr];
useEffect(() => {
if (!open) return;
const timer = setTimeout(() => {
onClose?.();
}, duration);
return () => clearTimeout(timer);
}, [open, duration, onClose]);
return (
<>
<div className={cn('fixed z-100', pos.container)}>
<AnimatePresence>
{open && (
<motion.div
initial={{opacity: 0}}
animate={{opacity: 1}}
exit={{opacity: 0}}
transition={{
duration: 0.2,
ease: 'easeOut',
}}
className="
min-w-50 max-w-sm
px-4 py-2.5
rounded-lg
bg-neutral-900 text-white
text-sm font-medium tracking-tight
shadow-md
backdrop-blur
"
>
{message}
</motion.div>
)}
</AnimatePresence>
</div>
</>
);
}
Toast Notification
A flexible, motion-enhanced notification system with support for multiple screen positions and smooth entry/exit animations.
Framer MotionNotificationFeedback UI