in packages/next/src/form-drawer/index.tsx [68:168]
export function FormDrawer(
title: IDrawerProps,
renderer: FormDrawerRenderer
): IFormDrawer
export function FormDrawer(
title: DrawerTitle,
id: string,
renderer: FormDrawerRenderer
): IFormDrawer
export function FormDrawer(
title: DrawerTitle,
renderer: FormDrawerRenderer
): IFormDrawer
export function FormDrawer(title: any, id: any, renderer?: any): IFormDrawer {
if (isFn(id) || React.isValidElement(id)) {
renderer = id
id = 'form-drawer'
}
const env = {
host: document.createElement('div'),
form: null,
promise: null,
openMiddlewares: [],
}
const root = createPortalRoot(env.host, id)
const props = getDrawerProps(title)
const drawer = {
width: '40%',
...props,
onClose: (reason: string, e: any) => {
if (props?.onClose?.(reason, e) !== false) {
formDrawer.close()
}
},
afterClose() {
props?.afterClose?.()
root.unmount()
},
}
const DrawerContent = observer(() => {
return <Fragment>{isFn(renderer) ? renderer(env.form) : renderer}</Fragment>
})
const renderDrawer = (visible = true) => {
return (
<ConfigProvider {...getContext()}>
<Observer>
{() => (
<Drawer {...drawer} visible={visible}>
<FormProvider form={env.form}>
<DrawerContent />
</FormProvider>
</Drawer>
)}
</Observer>
</ConfigProvider>
)
}
document.body.appendChild(env.host)
const formDrawer = {
forOpen: (middleware: IMiddleware<IFormProps>) => {
if (isFn(middleware)) {
env.openMiddlewares.push(middleware)
}
return formDrawer
},
open: (props: IFormProps) => {
if (env.promise) return env.promise
env.promise = new Promise(async (resolve, reject) => {
try {
props = await loading(drawer.loadingText, () =>
applyMiddleware(props, env.openMiddlewares)
)
env.form =
env.form ||
createForm({
...props,
effects(form) {
onFormSubmitSuccess(() => {
resolve(toJS(form.values))
formDrawer.close()
})
props?.effects?.(form)
},
})
} catch (e) {
reject(e)
}
root.render(() => renderDrawer(false))
setTimeout(() => {
root.render(() => renderDrawer(true))
}, 16)
})
return env.promise
},
close: () => {
if (!env.host) return
root.render(() => renderDrawer(false))
},
}
return formDrawer
}