feat(ux): Toast 通知系统,替换内联错误/成功提示
新增 toast store 和 Toast 组件,风格保存成功/失败显示 toast, 素材生成失败显示 toast,Layout 中全局渲染。
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { create } from 'zustand'
|
||||
|
||||
export type ToastType = 'success' | 'error' | 'info'
|
||||
|
||||
export interface Toast {
|
||||
id: string
|
||||
type: ToastType
|
||||
message: string
|
||||
duration?: number
|
||||
}
|
||||
|
||||
interface ToastState {
|
||||
toasts: Toast[]
|
||||
addToast: (t: Omit<Toast, 'id'>) => void
|
||||
removeToast: (id: string) => void
|
||||
}
|
||||
|
||||
export const useToastStore = create<ToastState>((set) => ({
|
||||
toasts: [],
|
||||
|
||||
addToast: (t) => {
|
||||
const id = Date.now().toString(36) + Math.random().toString(36).slice(2, 6)
|
||||
const toast: Toast = { ...t, id }
|
||||
set((state) => ({ toasts: [...state.toasts, toast] }))
|
||||
|
||||
const duration = t.duration ?? 3000
|
||||
setTimeout(() => {
|
||||
set((state) => ({ toasts: state.toasts.filter((x) => x.id !== id) }))
|
||||
}, duration)
|
||||
},
|
||||
|
||||
removeToast: (id) =>
|
||||
set((state) => ({ toasts: state.toasts.filter((t) => t.id !== id) })),
|
||||
}))
|
||||
Reference in New Issue
Block a user