zy-react-library/src/components/FormBuilder/FormBuilder.js

113 lines
3.0 KiB
JavaScript

import { Button, Col, Form, message, Row, Space, Spin } from "antd";
import { useEffect, useState } from "react";
import FormItemsRenderer from "./FormItemsRenderer";
/**
* 表单构建器组件
*/
const FormBuilder = (props) => {
const {
values,
options,
gutter = 24,
span = 12,
labelCol = { span: 4 },
useAutoGenerateRequired = true,
showActionButtons = true,
submitButtonText = "提交",
cancelButtonText = "取消",
showSubmitButton = true,
showCancelButton = true,
customActionButtons,
extraActionButtons,
loading = false,
...restProps
} = props;
const [pageWidth, setPageWidth] = useState(window.innerWidth);
const getPageWidth = () => {
const pageDom = document.querySelector("#page");
if (!pageDom)
return;
setPageWidth(pageDom.offsetWidth);
};
useEffect(() => {
const timer = setTimeout(() => {
getPageWidth();
}, 0);
if (showActionButtons) {
window.addEventListener("resize", getPageWidth);
}
return () => {
if (showActionButtons) {
window.removeEventListener("resize", getPageWidth);
}
clearTimeout(timer);
};
}, [showActionButtons]);
const handleCancel = () => {
window.history.back();
};
return (
<Spin spinning={loading}>
<Form
labelCol={labelCol}
scrollToFirstError
wrapperCol={{ span: 24 - labelCol.span }}
initialValues={values}
onFinishFailed={() => {
message.error("请补全必填项");
}}
style={{ width: `calc(100% - ${gutter * 2}px)`, margin: `0 auto` }}
{...restProps}
>
<Row gutter={gutter}>
<FormItemsRenderer
options={options}
labelCol={labelCol}
span={span}
gutter={gutter}
useAutoGenerateRequired={useAutoGenerateRequired}
initialValues={values}
/>
</Row>
{showActionButtons && (
<>
<div style={{ height: "32px" }}></div>
<Row
style={{ textAlign: "center", backgroundColor: "rgb(241, 241, 242)", padding: "10px 0", position: "fixed", bottom: "0", width: pageWidth, margin: "0 -44px" }}
>
<Col span={24} style={{ textAlign: "center" }}>
{customActionButtons || (
<Space>
{showSubmitButton && (
<Button type="primary" htmlType="submit">
{submitButtonText}
</Button>
)}
{extraActionButtons}
{showCancelButton && (
<Button onClick={handleCancel}>
{cancelButtonText}
</Button>
)}
</Space>
)}
</Col>
</Row>
</>
)}
</Form>
</Spin>
);
};
FormBuilder.displayName = "FormBuilder";
export default FormBuilder;