mirror of
https://github.com/Dictionarry-Hub/profilarr.git
synced 2026-01-22 10:51:02 +01:00
feat: enhance SearchBar component with enter key functionality and active search display
This commit is contained in:
@@ -34,6 +34,8 @@ const DataBar = ({
|
||||
className
|
||||
}) => {
|
||||
const [isFloating, setIsFloating] = useState(false);
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [activeSearch, setActiveSearch] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
@@ -44,12 +46,22 @@ const DataBar = ({
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
const handleSearch = term => {
|
||||
setActiveSearch(term);
|
||||
onSearch(term);
|
||||
};
|
||||
|
||||
const controls = (
|
||||
<>
|
||||
<SearchBar
|
||||
onSearch={onSearch}
|
||||
onSearch={handleSearch}
|
||||
placeholder={searchPlaceholder}
|
||||
className='flex-1'
|
||||
requireEnter
|
||||
searchTerm={searchTerm}
|
||||
setSearchTerm={setSearchTerm}
|
||||
activeSearch={activeSearch}
|
||||
setActiveSearch={setActiveSearch}
|
||||
/>
|
||||
|
||||
<div className='flex items-center gap-3'>
|
||||
|
||||
@@ -4,14 +4,14 @@ import {Search, X} from 'lucide-react';
|
||||
const SearchBar = ({
|
||||
onSearch,
|
||||
placeholder = 'Search...',
|
||||
value = '',
|
||||
className = ''
|
||||
className = '',
|
||||
requireEnter = false,
|
||||
searchTerm,
|
||||
setSearchTerm,
|
||||
activeSearch,
|
||||
setActiveSearch
|
||||
}) => {
|
||||
const [searchTerm, setSearchTerm] = useState(value);
|
||||
|
||||
useEffect(() => {
|
||||
setSearchTerm(value);
|
||||
}, [value]);
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = e => {
|
||||
@@ -31,32 +31,72 @@ const SearchBar = ({
|
||||
const handleChange = e => {
|
||||
const newValue = e.target.value;
|
||||
setSearchTerm(newValue);
|
||||
onSearch(newValue);
|
||||
if (!requireEnter) {
|
||||
onSearch(newValue);
|
||||
setActiveSearch(newValue);
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyPress = e => {
|
||||
if (requireEnter && e.key === 'Enter' && searchTerm.trim()) {
|
||||
onSearch(searchTerm);
|
||||
setActiveSearch(searchTerm);
|
||||
setSearchTerm('');
|
||||
}
|
||||
};
|
||||
|
||||
const clearSearch = () => {
|
||||
setSearchTerm('');
|
||||
setActiveSearch('');
|
||||
onSearch('');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`relative flex-1 min-w-0 ${className}`}>
|
||||
<Search className='absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400' />
|
||||
<input
|
||||
type='text'
|
||||
value={searchTerm}
|
||||
onChange={handleChange}
|
||||
placeholder={placeholder}
|
||||
className='w-full h-10 pl-9 pr-8 rounded-md border border-gray-300
|
||||
bg-white dark:bg-gray-800 dark:border-gray-700
|
||||
text-gray-900 dark:text-gray-100
|
||||
placeholder:text-gray-500 dark:placeholder:text-gray-400
|
||||
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
|
||||
transition-colors'
|
||||
/>
|
||||
{searchTerm && (
|
||||
|
||||
<div
|
||||
className={`
|
||||
w-full h-10 pl-9 pr-8 rounded-md border
|
||||
${
|
||||
isFocused
|
||||
? 'ring-2 ring-blue-500 border-transparent'
|
||||
: 'border-gray-300 dark:border-gray-700'
|
||||
}
|
||||
bg-white dark:bg-gray-800
|
||||
flex items-center
|
||||
transition-colors
|
||||
`}>
|
||||
{activeSearch ? (
|
||||
<div className='flex items-center gap-1.5 px-2 py-0.5 bg-blue-500/10 text-blue-500 dark:bg-blue-500/20 dark:text-blue-400 rounded'>
|
||||
<span className='text-sm font-medium leading-none'>
|
||||
{activeSearch}
|
||||
</span>
|
||||
<button
|
||||
onClick={clearSearch}
|
||||
className='p-0.5 hover:bg-blue-500/20 rounded'>
|
||||
<X className='h-3 w-3' />
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<input
|
||||
type='text'
|
||||
value={searchTerm}
|
||||
onChange={handleChange}
|
||||
onKeyPress={handleKeyPress}
|
||||
onFocus={() => setIsFocused(true)}
|
||||
onBlur={() => setIsFocused(false)}
|
||||
placeholder={placeholder}
|
||||
className='w-full bg-transparent text-gray-900 dark:text-gray-100
|
||||
placeholder:text-gray-500 dark:placeholder:text-gray-400
|
||||
focus:outline-none'
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{searchTerm && !activeSearch && (
|
||||
<button
|
||||
onClick={clearSearch}
|
||||
onClick={() => setSearchTerm('')}
|
||||
className='absolute right-3 top-1/2 -translate-y-1/2 p-1 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700'>
|
||||
<X className='h-4 w-4 text-gray-400' />
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user