first commit
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { AlertCircle, CheckCircle2, Info } from "lucide-react";
|
||||
import { subscribe, ToastItem } from "@/lib/toast";
|
||||
|
||||
const STYLE: Record<
|
||||
ToastItem["type"],
|
||||
{ border: string; icon: React.ReactNode }
|
||||
> = {
|
||||
error: { border: "#e5484d", icon: <AlertCircle size={18} color="#ff8a8d" /> },
|
||||
success: { border: "#3fa34d", icon: <CheckCircle2 size={18} color="#7be58a" /> },
|
||||
info: { border: "#e9b949", icon: <Info size={18} color="#e9b949" /> },
|
||||
};
|
||||
|
||||
export default function Toaster() {
|
||||
const [items, setItems] = useState<ToastItem[]>([]);
|
||||
useEffect(() => subscribe(setItems), []);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: "fixed",
|
||||
bottom: 20,
|
||||
left: "50%",
|
||||
transform: "translateX(-50%)",
|
||||
zIndex: 9999,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 10,
|
||||
alignItems: "center",
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
>
|
||||
{items.map((t) => (
|
||||
<div
|
||||
key={t.id}
|
||||
style={{
|
||||
pointerEvents: "auto",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 10,
|
||||
maxWidth: "min(90vw, 460px)",
|
||||
padding: "12px 16px",
|
||||
borderRadius: 12,
|
||||
background: "linear-gradient(180deg, #17345c, #0c2848)",
|
||||
border: `1px solid ${STYLE[t.type].border}`,
|
||||
boxShadow: "0 8px 24px rgba(0,0,0,.5)",
|
||||
color: "#eaf0f8",
|
||||
fontSize: 14,
|
||||
animation: "toastIn .18s ease-out",
|
||||
}}
|
||||
>
|
||||
{STYLE[t.type].icon}
|
||||
<span style={{ flex: 1 }}>{t.msg}</span>
|
||||
</div>
|
||||
))}
|
||||
<style>{`@keyframes toastIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}`}</style>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user