zy-react-library/components/Search/index.js

127 lines
3.3 KiB
JavaScript
Raw Normal View History

2025-10-22 14:43:42 +08:00
import { DownOutlined, UpOutlined } from "@ant-design/icons";
import { Button, Col, Form, Row } from "antd";
import { useEffect, useRef, useState } from "react";
import FormItemsRenderer from "../FormBuilder/FormItemsRenderer";
/**
* 搜索表单组件
*/
const Search = (props) => {
const {
labelCol = { span: 4 },
options = [],
values,
onFinish,
onSubmit,
onReset,
searchText = "搜索",
resetText = "重置",
showSearchButton = true,
showResetButton = true,
extraButtons,
form,
...restProps
} = props;
const [collapse, setCollapse] = useState(true);
const [span, setSpan] = useState(6);
const [showCollapseButton, setShowCollapseButton] = useState(false);
const classNameRef = useRef(`search-${Date.now()}`);
// 计算是否需要显示展开/收起按钮
useEffect(() => {
if (!options || options.length === 0)
return;
const calculateLayout = () => {
const colEl = document.querySelectorAll(
`.${classNameRef.current}>.${window.process.env.app.antd["ant-prefix"]}-col`,
);
const colElLength = colEl.length;
const excludeLast = colElLength - (extraButtons ? 2 : 1);
const spanMap = { 0: 24, 1: 18, 2: 12, 3: 6 };
setSpan(spanMap[excludeLast % 4] || 6);
setShowCollapseButton(excludeLast > 3);
};
// 延迟执行以确保 DOM 已渲染
setTimeout(calculateLayout, 0);
}, [options, extraButtons]);
// 处理表单提交
const handleSubmit = () => {
const values = form.getFieldsValue();
onFinish?.(values, "submit");
onSubmit?.(values);
};
// 处理重置
const handleReset = () => {
form.resetFields();
const values = form.getFieldsValue();
onFinish?.(values, "reset");
onReset?.(values);
};
// 切换展开/收起
const toggleCollapse = () => {
setCollapse(!collapse);
};
return (
<Form
form={form}
labelCol={labelCol}
initialValues={values}
{...restProps}
>
<Row className={classNameRef.current}>
<FormItemsRenderer
options={options}
2025-10-28 12:30:57 +08:00
labelCol={labelCol}
2025-10-22 14:43:42 +08:00
span={6}
collapse={collapse}
useAutoGenerateRequired={false}
/>
<Col span={showCollapseButton ? (collapse ? 6 : span) : span}>
<Form.Item label=" " colon={false} style={{ textAlign: "right" }}>
{showSearchButton && (
<Button type="primary" onClick={handleSubmit}>
{searchText}
</Button>
)}
{showResetButton && (
<Button style={{ marginLeft: 8 }} onClick={handleReset}>
{resetText}
</Button>
)}
{showCollapseButton && (
<Button
type="link"
icon={collapse ? <DownOutlined /> : <UpOutlined />}
onClick={toggleCollapse}
style={{ marginLeft: 8 }}
>
{collapse ? "展开" : "收起"}
</Button>
)}
</Form.Item>
</Col>
{extraButtons && (
<Col span={24}>
<Form.Item label=" " colon={false} labelCol={{ span: 0 }}>
{extraButtons}
</Form.Item>
</Col>
)}
</Row>
</Form>
);
};
Search.displayName = "Search";
export default Search;