Files
openpylon/src/components/toast/ToastContainer.tsx

33 lines
1.1 KiB
TypeScript

import { AnimatePresence, motion } from "framer-motion";
import { springs } from "@/lib/motion";
import { useToastStore } from "@/stores/toast-store";
const TYPE_STYLES = {
success: "bg-pylon-accent/10 text-pylon-accent border-pylon-accent/20",
error: "bg-pylon-danger/10 text-pylon-danger border-pylon-danger/20",
info: "bg-pylon-surface text-pylon-text border-border",
} as const;
export function ToastContainer() {
const toasts = useToastStore((s) => s.toasts);
return (
<div className="pointer-events-none fixed bottom-4 right-4 z-[100] flex flex-col gap-2">
<AnimatePresence>
{toasts.map((toast) => (
<motion.div
key={toast.id}
initial={{ opacity: 0, y: 20, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: 20, scale: 0.9 }}
transition={springs.wobbly}
className={`pointer-events-auto rounded-lg border px-4 py-2 text-sm shadow-md ${TYPE_STYLES[toast.type]}`}
>
{toast.message}
</motion.div>
))}
</AnimatePresence>
</div>
);
}