in packages/next/src/form-dialog/index.tsx [66:242]
export function FormDialog(
title: IDialogProps,
renderer: FormDialogRenderer
): IFormDialog
export function FormDialog(
title: ModalTitle,
id: string,
renderer: FormDialogRenderer
): IFormDialog
export function FormDialog(
title: ModalTitle,
renderer: FormDialogRenderer
): IFormDialog
export function FormDialog(title: any, id: any, renderer?: any): IFormDialog {
if (isFn(id) || React.isValidElement(id)) {
renderer = id
id = 'form-dialog'
}
const env = {
host: document.createElement('div'),
form: null,
promise: null,
openMiddlewares: [],
confirmMiddlewares: [],
cancelMiddlewares: [],
}
const root = createPortalRoot(env.host, id)
const props = getModelProps(title)
const modal = {
...props,
style: {
width: '40%',
...props.style,
},
afterClose: () => {
props?.afterClose?.()
root.unmount()
},
}
const DialogContent = observer(() => {
return <Fragment>{isFn(renderer) ? renderer(env.form) : renderer}</Fragment>
})
const renderDialog = (
visible = true,
resolve?: () => any,
reject?: () => any
) => {
const ctx = getContext()
const prefix = modal.prefix || ctx.prefix || 'next'
const okProps = {
children: ctx?.locale?.Dialog?.ok || '确定',
...(ctx?.defaultPropsConfig?.Dialog?.okProps || {}),
...(modal.okProps || {}),
}
const cancelProps = {
children: ctx?.locale?.Dialog?.cancel || '取消',
...(ctx?.defaultPropsConfig?.Dialog?.cancelProps || {}),
...(modal.cancelProps || {}),
}
const buttonMap = {
ok: (
<Button
key="ok"
type="primary"
className={prefix + '-dialog-btn'}
loading={env.form.submitting}
onClick={(e) => {
if (modal?.onOk?.(e) !== false) {
resolve()
}
}}
{...okProps}
/>
),
cancel: (
<Button
key="cancel"
className={prefix + '-dialog-btn'}
onClick={(e) => {
if (modal?.onCancel?.(e) !== false) {
reject()
}
}}
{...cancelProps}
/>
),
}
const footerActions = ctx?.defaultPropsConfig?.Dialog?.footerActions ||
modal.footerActions || ['cancel', 'ok']
return (
<ConfigProvider {...ctx}>
<Observer>
{() => (
<Dialog
{...modal}
visible={visible}
footer={
<Fragment>
{footerActions.map((item) => buttonMap[item])}
</Fragment>
}
onClose={(trigger, e) => {
modal?.onClose?.(trigger, e)
reject()
}}
>
<FormProvider form={env.form}>
<DialogContent />
</FormProvider>
</Dialog>
)}
</Observer>
</ConfigProvider>
)
}
document.body.appendChild(env.host)
const formDialog = {
forOpen: (middleware: IMiddleware<IFormProps>) => {
if (isFn(middleware)) {
env.openMiddlewares.push(middleware)
}
return formDialog
},
forConfirm: (middleware: IMiddleware<Form>) => {
if (isFn(middleware)) {
env.confirmMiddlewares.push(middleware)
}
return formDialog
},
forCancel: (middleware: IMiddleware<Form>) => {
if (isFn(middleware)) {
env.cancelMiddlewares.push(middleware)
}
return formDialog
},
open: async (props: IFormProps) => {
if (env.promise) return env.promise
env.promise = new Promise(async (resolve, reject) => {
try {
props = await loading(modal.loadingText, () =>
applyMiddleware(props, env.openMiddlewares)
)
env.form = env.form || createForm(props)
} catch (e) {
reject(e)
}
root.render(() =>
renderDialog(
true,
() => {
env.form
.submit(async () => {
await applyMiddleware(env.form, env.confirmMiddlewares)
resolve(toJS(env.form.values))
formDialog.close()
})
.catch(() => {})
},
async () => {
await loading(modal.loadingText, () =>
applyMiddleware(env.form, env.cancelMiddlewares)
)
formDialog.close()
}
)
)
})
return env.promise
},
close: () => {
if (!env.host) return
root.render(() => renderDialog(false))
},
}
return formDialog
}