u
This commit is contained in:
1 parent
6849579652
commit
d60be4a75b
24 files changed
+463
-179
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import type { IToastProps } from '@gluestack-ui/core/lib/esm/toast/creator/types'
|
||||
import React, { useRef } from 'react'
|
||||
import React, { createContext, useContext, useRef } from 'react'
|
||||
import { Toast, ToastDescription, ToastTitle, useToast as useGluestackToast } from '@/components/ui/toast'
|
||||
|
||||
type ToastVariant = 'solid' | 'outline'
|
||||
@@ -12,28 +12,74 @@ interface ShowToastOptions extends IToastProps {
|
||||
action?: ToastAction
|
||||
}
|
||||
|
||||
// 创建全局 toast 实例
|
||||
let globalToast: any = null
|
||||
|
||||
// 创建 Context 用于在组件内部使用
|
||||
const ToastContext = createContext<ReturnType<typeof useGluestackToast> | null>(null)
|
||||
|
||||
export function ToastProviderWrapper({ children }: { children: React.ReactNode }) {
|
||||
const toast = useGluestackToast()
|
||||
const toastRef = useRef(toast)
|
||||
toastRef.current = toast
|
||||
|
||||
return <>{children}</>
|
||||
// 设置全局实例
|
||||
React.useEffect(() => {
|
||||
globalToast = {
|
||||
show: (options: ShowToastOptions) => {
|
||||
const id = Math.random().toString()
|
||||
toast.show({
|
||||
id,
|
||||
placement: options.placement ?? 'top',
|
||||
duration: options.duration !== undefined ? options.duration : 3000,
|
||||
avoidKeyboard: options.avoidKeyboard ?? false,
|
||||
containerStyle: options.containerStyle,
|
||||
onCloseComplete: options.onCloseComplete,
|
||||
render: options.render
|
||||
? () => options.render!({ id })
|
||||
: ({ id }) => (
|
||||
<Toast
|
||||
nativeID={`toast-${id}`}
|
||||
variant={options.variant ?? 'solid'}
|
||||
action={options.action ?? 'muted'}
|
||||
>
|
||||
{options.title && <ToastTitle className="font-blod">{options.title}</ToastTitle>}
|
||||
{options.description && <ToastDescription>{options.description}</ToastDescription>}
|
||||
</Toast>
|
||||
),
|
||||
})
|
||||
return id
|
||||
},
|
||||
close: (id: string) => {
|
||||
toast.close(id)
|
||||
},
|
||||
closeAll: () => {
|
||||
toast.closeAll()
|
||||
},
|
||||
isActive: (id: string) => toast.isActive(id),
|
||||
}
|
||||
}, [toast])
|
||||
|
||||
return (
|
||||
<ToastContext.Provider value={toast}>
|
||||
{children}
|
||||
</ToastContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义 Hook,用法:
|
||||
* const toast = useToast();
|
||||
* toast.show({ ... });
|
||||
* toast.close(id);
|
||||
* toast.closeAll();
|
||||
* 自定义 Hook,用于 React 组件内部
|
||||
*/
|
||||
export function useToast() {
|
||||
const toast = useGluestackToast()
|
||||
const toast = useContext(ToastContext)
|
||||
|
||||
if (!toast) {
|
||||
throw new Error('useToast must be used within a ToastProviderWrapper')
|
||||
}
|
||||
|
||||
return {
|
||||
show: (options: ShowToastOptions) => {
|
||||
const id = Math.random().toString()
|
||||
|
||||
toast.show({
|
||||
id,
|
||||
placement: options.placement ?? 'top',
|
||||
@@ -54,18 +100,40 @@ export function useToast() {
|
||||
</Toast>
|
||||
),
|
||||
})
|
||||
|
||||
return id
|
||||
},
|
||||
|
||||
close: (id: string) => {
|
||||
toast.close(id)
|
||||
},
|
||||
|
||||
closeAll: () => {
|
||||
toast.closeAll()
|
||||
},
|
||||
|
||||
isActive: (id: string) => toast.isActive(id),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局 toast 实例,可在组件外部使用
|
||||
*/
|
||||
export const toast = {
|
||||
show: (options: ShowToastOptions) => {
|
||||
if (!globalToast) {
|
||||
console.warn('Toast not initialized. Make sure ToastProviderWrapper is rendered.')
|
||||
return ''
|
||||
}
|
||||
return globalToast.show(options)
|
||||
},
|
||||
close: (id: string) => {
|
||||
if (globalToast) {
|
||||
globalToast.close(id)
|
||||
}
|
||||
},
|
||||
closeAll: () => {
|
||||
if (globalToast) {
|
||||
globalToast.closeAll()
|
||||
}
|
||||
},
|
||||
isActive: (id: string) => {
|
||||
return globalToast ? globalToast.isActive(id) : false
|
||||
},
|
||||
}
|
||||
Reference in new issue
Block a user