import { useTranslation } from "react-i18next"; import { useControllableValue } from "ahooks"; import { Button, Drawer, type DrawerProps, Form, type FormProps, type ModalProps, Space } from "antd"; import { useAntdForm, useTriggerElement } from "@/hooks"; export interface DrawerFormProps = any> extends Omit, "title" | "onFinish"> { className?: string; style?: React.CSSProperties; children?: React.ReactNode; cancelButtonProps?: ModalProps["cancelButtonProps"]; cancelText?: ModalProps["cancelText"]; defaultOpen?: boolean; drawerProps?: Omit; okButtonProps?: ModalProps["okButtonProps"]; okText?: ModalProps["okText"]; open?: boolean; title?: React.ReactNode; trigger?: React.ReactNode; width?: string | number; onClose?: (e: React.MouseEvent | React.KeyboardEvent) => void | Promise; onFinish?: (values: T) => unknown | Promise; onOpenChange?: (open: boolean) => void; } const DrawerForm = = any>({ className, style, children, cancelText, cancelButtonProps, form, drawerProps, okText, okButtonProps, title, trigger, width, onFinish, ...props }: DrawerFormProps) => { const { t } = useTranslation(); const [open, setOpen] = useControllableValue(props, { valuePropName: "open", defaultValuePropName: "defaultOpen", trigger: "onOpenChange", }); const triggerEl = useTriggerElement(trigger, { onClick: () => { console.log("click"); setOpen(true); console.log(open); }, }); const { form: formInst, formPending, formProps, submit, } = useAntdForm({ form, onSubmit: (values) => { return onFinish?.(values); }, }); const mergedFormProps: FormProps = { clearOnDestroy: drawerProps?.destroyOnClose ? true : undefined, ...formProps, ...props, }; const mergedDrawerProps: DrawerProps = { ...drawerProps, afterOpenChange: (open) => { if (!open && !mergedFormProps.preserve) { formInst.resetFields(); } drawerProps?.afterOpenChange?.(open); }, onClose: async (e) => { if (formPending) return; // 关闭 Drawer 时 Promise.reject 阻止关闭 await drawerProps?.onClose?.(e); setOpen(false); }, }; const handleOkClick = async () => { // 提交表单返回 Promise.reject 时不关闭 Drawer await submit(); setOpen(false); }; const handleCancelClick = () => { if (formPending) return; setOpen(false); }; return ( <> {triggerEl} } forceRender open={open} title={title} width={width} >
{children}
); }; export default DrawerForm;