Skip to content
File

Blob: src/client/components/toast.tsx

typescript27 lines
1import { useSyncExternalStore } from "react";
2import { getToastSnapshot, subscribeToast, type ToastVariant } from "./toast-store";
3 
4const VARIANT_CLASSES: Record<ToastVariant, string> = {
5 success: "border-emerald-500/20 bg-emerald-500/10 text-emerald-400",
6 error: "border-red-500/20 bg-red-500/10 text-red-400",
7 info: "border-accent-500/20 bg-accent-500/10 text-accent-400",
8};
9 
10export function ToastContainer() {
11 const current = useSyncExternalStore(subscribeToast, getToastSnapshot);
12 
13 return (
14 <div className="fixed bottom-4 right-4 z-[100] flex flex-col gap-2" role="status" aria-live="polite">
15 {current.map((t) => (
16 <div
17 key={t.id}
18 aria-live={t.variant === "error" ? "assertive" : undefined}
19 className={`${t.exiting ? "translate-y-2 opacity-0" : "animate-slide-up"} rounded-lg border px-4 py-2.5 text-sm shadow-lg transition-[opacity,transform] duration-200 ${VARIANT_CLASSES[t.variant]}`}
20 >
21 {t.message}
22 </div>
23 ))}
24 </div>
25 );
26}