feat: 添加注释
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
export interface ToastItem {
|
||||
id: number;
|
||||
message: string;
|
||||
type: 'success' | 'error' | 'info';
|
||||
}
|
||||
|
||||
interface ToastProps { toasts: ToastItem[]; }
|
||||
|
||||
export function Toast({ toasts }: ToastProps) {
|
||||
return (
|
||||
<div className="fixed bottom-4 left-1/2 -translate-x-1/2 z-[100] flex flex-col gap-2 items-center pointer-events-none">
|
||||
{toasts.map(t => (
|
||||
<div key={t.id}
|
||||
className={`px-4 py-2 rounded-xl text-[12px] font-medium shadow-xl border animate-toast-in
|
||||
${t.type === 'success' ? 'bg-green-500/20 text-green-300 border-green-500/30' :
|
||||
t.type === 'error' ? 'bg-red-500/20 text-red-300 border-red-500/30' :
|
||||
'bg-white/10 text-white/70 border-white/15'}`}>
|
||||
{t.type === 'success' ? '✓ ' : t.type === 'error' ? '✕ ' : 'ℹ '}{t.message}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let _toastId = 0;
|
||||
|
||||
export function useToast() {
|
||||
const [toasts, setToasts] = useState<ToastItem[]>([]);
|
||||
const timerRef = useRef<Map<number, ReturnType<typeof setTimeout>>>(new Map());
|
||||
|
||||
const showToast = useCallback((message: string, type: ToastItem['type'] = 'success', duration = 2500) => {
|
||||
const id = ++_toastId;
|
||||
setToasts(prev => [...prev, { id, message, type }]);
|
||||
const timer = setTimeout(() => {
|
||||
setToasts(prev => prev.filter(t => t.id !== id));
|
||||
timerRef.current.delete(id);
|
||||
}, duration);
|
||||
timerRef.current.set(id, timer);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const timers = timerRef.current;
|
||||
return () => { timers.forEach(t => clearTimeout(t)); };
|
||||
}, []);
|
||||
|
||||
return { toasts, showToast };
|
||||
}
|
||||
Reference in New Issue
Block a user