imetting/frontend/src/components/ExpandSearchBox.jsx

121 lines
3.0 KiB
React
Raw Normal View History

import React, { useState, useEffect, useRef } from 'react';
import { Input } from 'antd';
import { Search } from 'lucide-react';
import './ExpandSearchBox.css';
const ExpandSearchBox = ({
searchQuery = '',
onSearchChange = null,
placeholder = '搜索会议名称或发起人...',
collapsedText = '会议搜索',
showIcon = true,
realTimeSearch = false, // 改为默认false避免频繁刷新
debounceDelay = 500 // 防抖延迟时间(毫秒)
}) => {
const [isExpanded, setIsExpanded] = useState(false);
const [inputValue, setInputValue] = useState(searchQuery);
const debounceTimerRef = useRef(null);
// 同步外部 searchQuery 的变化
useEffect(() => {
setInputValue(searchQuery);
}, [searchQuery]);
const handleInputChange = (e) => {
const value = e.target.value;
setInputValue(value);
// 如果启用实时搜索,使用防抖触发回调
if (realTimeSearch && onSearchChange) {
// 清除之前的定时器
if (debounceTimerRef.current) {
clearTimeout(debounceTimerRef.current);
}
// 设置新的定时器
debounceTimerRef.current = setTimeout(() => {
onSearchChange(value.trim());
}, debounceDelay);
}
};
const handleSearch = () => {
// 立即清除防抖定时器
if (debounceTimerRef.current) {
clearTimeout(debounceTimerRef.current);
}
if (onSearchChange) {
onSearchChange(inputValue.trim());
}
};
const handleKeyPress = (e) => {
if (e.key === 'Enter') {
handleSearch();
}
};
const handleClear = () => {
// 清除防抖定时器
if (debounceTimerRef.current) {
clearTimeout(debounceTimerRef.current);
}
setInputValue('');
if (onSearchChange) {
onSearchChange('');
}
};
// 组件卸载时清除定时器
useEffect(() => {
return () => {
if (debounceTimerRef.current) {
clearTimeout(debounceTimerRef.current);
}
};
}, []);
// 如果没有提供搜索回调函数,显示只读标题
if (!onSearchChange) {
return (
<div className="expand-search-readonly">
{showIcon && <Search size={18} />}
<h3>{collapsedText}</h3>
</div>
);
}
return (
<div
className={`expand-search-box ${isExpanded ? 'expanded' : ''}`}
onClick={() => !isExpanded && setIsExpanded(true)}
>
{showIcon && <Search size={18} className="search-icon" />}
{isExpanded ? (
<Input
placeholder={placeholder}
value={inputValue}
onChange={handleInputChange}
onPressEnter={handleSearch}
onKeyPress={handleKeyPress}
onBlur={() => {
if (!inputValue) setIsExpanded(false);
}}
allowClear={{
clearIcon: <span onClick={handleClear}>×</span>
}}
onClear={handleClear}
autoFocus
className="search-input-antd"
/>
) : (
<span className="search-placeholder">{collapsedText}</span>
)}
</div>
);
};
export default ExpandSearchBox;