Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | 1x 1x 90x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 3x 3x 36x 36x 90x 7x 7x 90x 4x 4x 90x 3x 3x 90x 3x 3x 90x 7x 7x 6x 6x 6x 6x 5x 5x 5x 5x 5x 6x 6x 6x 7x 90x 55x 35x 55x 55x 54x 54x 55x 55x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 1x 1x 3x 3x | /**
* Toast Notification Composable
* @description Manages toast notifications state and methods
* Provides a simple API to show/hide toast messages
*/
export interface Toast {
id: string
variant: 'info' | 'success' | 'warning' | 'error'
message: string
actionLabel?: string
duration?: number
visible: boolean
}
// Shared state across all components
const toasts = ref<Toast[]>([])
export const useToast = () => {
/**
* Show a toast notification
*/
const show = (
message: string,
options: {
variant?: Toast['variant']
actionLabel?: string
duration?: number
onAction?: () => void
} = {}
): string => {
const id = `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
const toast: Toast = {
id,
variant: options.variant || 'info',
message,
actionLabel: options.actionLabel,
duration: options.duration ?? 5000,
visible: true
}
toasts.value.push(toast)
// Store action callback if provided
if (options.onAction) {
toastActions.set(id, options.onAction)
}
return id
}
/**
* Show info toast
*/
const info = (message: string, options?: Omit<Parameters<typeof show>[1], 'variant'>) => {
return show(message, { ...options, variant: 'info' })
}
/**
* Show success toast
*/
const success = (message: string, options?: Omit<Parameters<typeof show>[1], 'variant'>) => {
return show(message, { ...options, variant: 'success' })
}
/**
* Show warning toast
*/
const warning = (message: string, options?: Omit<Parameters<typeof show>[1], 'variant'>) => {
return show(message, { ...options, variant: 'warning' })
}
/**
* Show error toast
*/
const error = (message: string, options?: Omit<Parameters<typeof show>[1], 'variant'>) => {
return show(message, { ...options, variant: 'error' })
}
/**
* Dismiss a specific toast
*/
const dismiss = (id: string) => {
const index = toasts.value.findIndex(t => t.id === id)
if (index !== -1) {
const toast = toasts.value[index]
if (toast) {
toast.visible = false
// Remove from array after transition completes
setTimeout(() => {
const currentIndex = toasts.value.findIndex(t => t.id === id)
if (currentIndex !== -1) {
toasts.value.splice(currentIndex, 1)
toastActions.delete(id)
}
}, 300) // Match transition duration
}
}
}
/**
* Dismiss all toasts
*/
const dismissAll = () => {
toasts.value.forEach(toast => {
toast.visible = false
})
setTimeout(() => {
toasts.value = []
toastActions.clear()
}, 300)
}
return {
toasts: readonly(toasts),
show,
info,
success,
warning,
error,
dismiss,
dismissAll
}
}
// Store action callbacks
const toastActions = new Map<string, () => void>()
/**
* Get action callback for a toast
*/
export const getToastAction = (id: string): (() => void) | undefined => {
return toastActions.get(id)
}
|