flnxi-Wu/components/ui/DialogProvider.tsx
2025-11-22 17:56:24 +08:00

130 lines
3.5 KiB
TypeScript

/**
* DialogProvider 组件
*
* 全局弹窗提供者组件
* 提供统一的 confirm、alert、prompt 方法
* 通过 Context 让所有子组件可以使用统一弹窗
*
* @created 2025-11-22
* @component
*/
'use client'
import { createContext, useContext, ReactNode } from 'react'
import ConfirmDialog from './ConfirmDialog'
import AlertDialog from './AlertDialog'
import PromptDialog from './PromptDialog'
import { useConfirm, usePrompt } from '@/hooks/useConfirm'
import { useAlert } from '@/hooks/useAlert'
interface DialogContextType {
confirm: (options: {
title?: string
message: string
confirmText?: string
cancelText?: string
variant?: 'default' | 'danger'
}) => Promise<boolean>
alert: (options: {
title?: string
message: string
buttonText?: string
variant?: 'default' | 'success' | 'warning' | 'error'
} | string) => void
prompt: (options: {
title?: string
message: string
defaultValue?: string
placeholder?: string
confirmText?: string
cancelText?: string
}) => Promise<string | null>
}
const DialogContext = createContext<DialogContextType | null>(null)
export function useDialog() {
const context = useContext(DialogContext)
if (!context) {
throw new Error('useDialog must be used within DialogProvider')
}
return context
}
interface DialogProviderProps {
children: ReactNode
}
export function DialogProvider({ children }: DialogProviderProps) {
const confirmHook = useConfirm()
const alertHook = useAlert()
const promptHook = usePrompt()
const confirm = async (options: {
title?: string
message: string
confirmText?: string
cancelText?: string
variant?: 'default' | 'danger'
}): Promise<boolean> => {
return confirmHook.confirm(options)
}
const alert = (options: {
title?: string
message: string
buttonText?: string
variant?: 'default' | 'success' | 'warning' | 'error'
} | string) => {
alertHook.alert(options)
}
const prompt = async (options: {
title?: string
message: string
defaultValue?: string
placeholder?: string
confirmText?: string
cancelText?: string
}): Promise<string | null> => {
return promptHook.prompt(options)
}
return (
<DialogContext.Provider value={{ confirm, alert, prompt }}>
{children}
<ConfirmDialog
isOpen={confirmHook.isOpen}
onClose={confirmHook.handleCancel}
onConfirm={confirmHook.handleConfirm}
title={confirmHook.options.title || '确认'}
message={confirmHook.options.message}
confirmText={confirmHook.options.confirmText}
cancelText={confirmHook.options.cancelText}
variant={confirmHook.options.variant}
/>
<AlertDialog
isOpen={alertHook.isOpen}
onClose={alertHook.close}
title={alertHook.options.title || '提示'}
message={alertHook.options.message}
buttonText={alertHook.options.buttonText}
variant={alertHook.options.variant}
/>
<PromptDialog
isOpen={promptHook.isOpen}
onClose={promptHook.handleCancel}
onConfirm={promptHook.handleConfirm}
title={promptHook.options.title || '输入'}
message={promptHook.options.message}
defaultValue={promptHook.options.defaultValue}
placeholder={promptHook.options.placeholder}
confirmText={promptHook.options.confirmText}
cancelText={promptHook.options.cancelText}
/>
</DialogContext.Provider>
)
}