forked from op7418/CodePilot
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtoast.tsx
More file actions
66 lines (59 loc) · 1.9 KB
/
toast.tsx
File metadata and controls
66 lines (59 loc) · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
'use client';
import { X, CheckCircle, XCircle, Warning, Info } from '@/components/ui/icon';
import { Button } from '@/components/ui/button';
import { useToastState, type Toast } from '@/hooks/useToast';
import { cn } from '@/lib/utils';
const ICON_MAP = {
success: CheckCircle,
error: XCircle,
warning: Warning,
info: Info,
};
const STYLE_MAP = {
success: 'border-status-success/30 bg-status-success-muted text-status-success-foreground',
error: 'border-destructive/30 bg-destructive/10 text-destructive',
warning: 'border-status-warning/30 bg-status-warning-muted text-status-warning-foreground',
info: 'border-border bg-muted text-foreground',
};
function ToastItem({ toast, onDismiss }: { toast: Toast; onDismiss: () => void }) {
const Icon = ICON_MAP[toast.type];
return (
<div
className={cn(
'flex items-center gap-2 rounded-lg border px-3 py-2 shadow-lg text-sm animate-in slide-in-from-bottom-2 fade-in duration-200',
STYLE_MAP[toast.type]
)}
>
<Icon size={16} className="shrink-0" />
<span className="flex-1 min-w-0 truncate">{toast.message}</span>
{toast.action && (
<Button
variant="ghost"
size="sm"
className="h-6 px-2 text-xs shrink-0"
onClick={toast.action.onClick}
>
{toast.action.label}
</Button>
)}
<button onClick={onDismiss} className="shrink-0 p-0.5 rounded hover:bg-black/10 dark:hover:bg-white/10">
<X size={12} />
</button>
</div>
);
}
export function Toaster() {
const { toasts, removeToast } = useToastState();
if (toasts.length === 0) return null;
return (
<div className="fixed bottom-4 right-4 z-[100] flex flex-col gap-2 max-w-sm">
{toasts.map(toast => (
<ToastItem
key={toast.id}
toast={toast}
onDismiss={() => removeToast(toast.id)}
/>
))}
</div>
);
}