import { useControllableValue } from "ahooks"; import { Form, type FormProps, Modal, type ModalProps } from "antd"; import { useAntdForm, useTriggerElement } from "@/hooks"; export interface ModalFormProps = any> extends Omit, "title" | "onFinish"> { className?: string; style?: React.CSSProperties; children?: React.ReactNode; cancelButtonProps?: ModalProps["cancelButtonProps"]; cancelText?: ModalProps["cancelText"]; defaultOpen?: boolean; modalProps?: Omit< ModalProps, | "cancelButtonProps" | "cancelText" | "confirmLoading" | "defaultOpen" | "forceRender" | "okButtonProps" | "okText" | "okType" | "open" | "title" | "width" | "onCancel" | "onOk" | "onOpenChange" >; okButtonProps?: ModalProps["okButtonProps"]; okText?: ModalProps["okText"]; open?: boolean; title?: ModalProps["title"]; trigger?: React.ReactNode; width?: ModalProps["width"]; onClose?: (e: React.MouseEvent | React.KeyboardEvent) => void | Promise; onFinish?: (values: T) => unknown | Promise; onOpenChange?: (open: boolean) => void; } const ModalForm = = any>({ className, style, children, cancelButtonProps, cancelText, form, modalProps, okButtonProps, okText, title, trigger, width, onFinish, ...props }: ModalFormProps) => { const [open, setOpen] = useControllableValue(props, { valuePropName: "open", defaultValuePropName: "defaultOpen", trigger: "onOpenChange", }); const triggerEl = useTriggerElement(trigger, { onClick: () => setOpen(true) }); const { form: formInst, formPending, formProps, submit: submitForm, } = useAntdForm({ form, onSubmit: (values) => { return onFinish?.(values); }, }); const mergedFormProps: FormProps = { clearOnDestroy: modalProps?.destroyOnHidden ? true : undefined, ...formProps, ...props, }; const mergedModalProps: ModalProps = { ...modalProps, afterClose: () => { if (!mergedFormProps.preserve) { formInst.resetFields(); } modalProps?.afterClose?.(); }, }; const handleOkClick = async () => { // 提交表单返回 Promise.reject 时不关闭 Modal await submitForm(); setOpen(false); }; const handleCancelClick = () => { if (formPending) return; setOpen(false); }; return ( <> {triggerEl}
{children}
); }; export default ModalForm;