Remove DialogVant/NotifyVant and add Toast and Sheet components with useToast, useReveal, and usePageTransition composables. Rework Navigation, RegisterView, and styles across both apps; rebuild dist assets. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
73 lines
2.0 KiB
TypeScript
73 lines
2.0 KiB
TypeScript
import { reactive } from 'vue'
|
|
|
|
/**
|
|
* App-wide toasts. One shared queue, rendered by <ToastHost> (mounted once in
|
|
* App.vue), so any view or store can call `toast.success(...)` without placing
|
|
* a component in its own template.
|
|
*/
|
|
|
|
export type ToastType = 'success' | 'error' | 'info' | 'warning'
|
|
|
|
export interface ToastOptions {
|
|
title?: string
|
|
/** ms before it closes by itself; 0 keeps it until the user dismisses it. */
|
|
duration?: number
|
|
/** Custom icon name; defaults to one per type. */
|
|
icon?: string
|
|
}
|
|
|
|
export interface ToastItem {
|
|
id: number
|
|
type: ToastType
|
|
message: string
|
|
title?: string
|
|
icon: string
|
|
duration: number
|
|
}
|
|
|
|
const DEFAULT_DURATION = 3200
|
|
// Older toasts beyond this are dropped so the stack never covers the screen.
|
|
const MAX_VISIBLE = 3
|
|
|
|
const ICONS: Record<ToastType, string> = {
|
|
success: 'vuesax-linear:tick-circle',
|
|
error: 'vuesax-linear:close-circle',
|
|
info: 'vuesax-linear:info-circle',
|
|
warning: 'vuesax-linear:warning-2',
|
|
}
|
|
|
|
const state = reactive<{ items: ToastItem[] }>({ items: [] })
|
|
let nextId = 1
|
|
|
|
function show(type: ToastType, message: string, options: ToastOptions = {}): number {
|
|
const id = nextId++
|
|
state.items.push({
|
|
id,
|
|
type,
|
|
message,
|
|
title: options.title,
|
|
icon: options.icon ?? ICONS[type],
|
|
duration: options.duration ?? DEFAULT_DURATION,
|
|
})
|
|
if (state.items.length > MAX_VISIBLE) state.items.splice(0, state.items.length - MAX_VISIBLE)
|
|
return id
|
|
}
|
|
|
|
function dismiss(id: number) {
|
|
const i = state.items.findIndex((t) => t.id === id)
|
|
if (i !== -1) state.items.splice(i, 1)
|
|
}
|
|
|
|
export const toast = {
|
|
show,
|
|
dismiss,
|
|
success: (message: string, options?: ToastOptions) => show('success', message, options),
|
|
error: (message: string, options?: ToastOptions) => show('error', message, options),
|
|
info: (message: string, options?: ToastOptions) => show('info', message, options),
|
|
warning: (message: string, options?: ToastOptions) => show('warning', message, options),
|
|
}
|
|
|
|
export function useToast() {
|
|
return { toasts: state.items, ...toast }
|
|
}
|