Tldraw/packages/ui/src/lib/hooks/useToastsProvider.tsx

75 wiersze
1.7 KiB
TypeScript

import { App, uniqueId } from '@tldraw/editor'
import { createContext, useCallback, useContext, useState } from 'react'
/** @public */
export interface TLToast {
id: string
icon?: string
title?: string
description?: string
actions?: TLToastAction[]
keepOpen?: boolean
closeLabel?: string
}
/** @public */
export interface TLToastAction {
type: 'primary' | 'secondary' | 'warn'
label: string
onClick: () => void
}
/** @public */
export type ToastsContextType = {
addToast: (toast: Omit<TLToast, 'id'> & { id?: string }) => string
removeToast: (id: TLToast['id']) => string
clearToasts: () => void
toasts: TLToast[]
}
/** @public */
export const ToastsContext = createContext({} as ToastsContextType)
/** @public */
export type ToastsProviderProps = {
overrides?: (app: App) => ToastsContextType
children: any
}
/** @public */
export function ToastsProvider({ children }: ToastsProviderProps) {
const [toasts, setToasts] = useState<TLToast[]>([])
const addToast = useCallback((toast: Omit<TLToast, 'id'> & { id?: string }) => {
const id = toast.id ?? uniqueId()
setToasts((d) => [...d.filter((m) => m.id !== toast.id), { ...toast, id }])
return id
}, [])
const removeToast = useCallback((id: string) => {
setToasts((d) => d.filter((m) => m.id !== id))
return id
}, [])
const clearToasts = useCallback(() => {
setToasts(() => [])
}, [])
return (
<ToastsContext.Provider value={{ toasts, addToast, removeToast, clearToasts }}>
{children}
</ToastsContext.Provider>
)
}
/** @public */
export function useToasts() {
const ctx = useContext(ToastsContext)
if (!ctx) {
throw new Error('useToasts must be used within a ToastsProvider')
}
return ctx
}