import { Button, Divider, Flex, Space } from "antd"; import { createStyles } from "antd-style"; import ButtonGroup from "antd/es/button/button-group"; import Search from "antd/es/input/Search"; import React, { useEffect, useRef, useState } from "react"; interface SearchBoxProps { children: React.ReactNode; placeholder?: string; searchKey?: string | undefined; onClear?: () => void; onCancel?: () => void; onConfirm?: () => void; onSearch?: (searchKey: string) => void; visible?: boolean; } const SearchBox: React.FC = ({ children, placeholder = "请输入搜索内容", searchKey, onCancel, onClear, onConfirm, onSearch, visible, }) => { const { styles } = useStyles(); const [operateVisible, setOperateVisible] = useState(false); const clickRef = useRef(null); const handleClickOutside = (event: MouseEvent) => { if (clickRef.current && !clickRef.current.contains(event.target as Node)) { setOperateVisible(false); } }; useEffect(() => { document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); return (
setOperateVisible(true)} value={searchKey} onChange={(e) => onSearch?.(e.target.value)} />
{children}
setOperateVisible(false)}>
); }; export default SearchBox; const useStyles = createStyles(({ token }) => { return { searchBoxContainer: { position: "relative", width: "300px", "& .search": { width: "100%", }, "& .operate": { position: "absolute", left: 0, boxSizing: "border-box", padding: `${token.padding}px ${token.padding}px 0`, zIndex: 999, backgroundColor: token.colorBgContainer, boxShadow: token.boxShadow, borderRadius: token.borderRadius, width: "100%", marginTop: token.marginXXS, height: "300px", overflow: "hidden", }, "& .operate-content": { flex: 1, padding: `${token.paddingContentVertical}px 0`, }, "& .operate-area": { height: "50px", position: "relative", width: "100%", "& .divider": { margin: 0, }, }, "& .button-group": { position: "absolute", transform: "translateY(-50%)", top: 'calc(50% + 2px)', right: 0, display: 'flex', justifyContent: 'space-between', width: '100%' }, }, }; });