Skip to content

Commit fa7b547

Browse files
committed
searchBar: improve UX, smoother auto close
1 parent 0fe8eb0 commit fa7b547

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

front-end/components/search-bar.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ interface SearchBarProps {
1111
export function SearchBar({ onSearch, placeholder = "Search examples..." }: SearchBarProps) {
1212
const [isExpanded, setIsExpanded] = React.useState(false);
1313
const [query, setQuery] = React.useState("");
14+
const containerRef = React.useRef<HTMLDivElement>(null);
1415
const inputRef = React.useRef<HTMLInputElement>(null);
1516
const debounceRef = React.useRef<NodeJS.Timeout | null>(null);
1617

@@ -32,12 +33,40 @@ export function SearchBar({ onSearch, placeholder = "Search examples..." }: Sear
3233
inputRef.current?.focus();
3334
}, [onSearch]);
3435

36+
const handleClose = React.useCallback(() => {
37+
if (!query) {
38+
setIsExpanded(false);
39+
}
40+
}, [query]);
41+
3542
React.useEffect(() => {
3643
if (isExpanded && inputRef.current) {
3744
inputRef.current.focus();
3845
}
3946
}, [isExpanded]);
4047

48+
React.useEffect(() => {
49+
if (!isExpanded) return;
50+
51+
const handleClickOutside = (e: MouseEvent) => {
52+
if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
53+
handleClose();
54+
}
55+
};
56+
57+
const handleScroll = () => {
58+
handleClose();
59+
};
60+
61+
document.addEventListener("mousedown", handleClickOutside);
62+
window.addEventListener("scroll", handleScroll, true);
63+
64+
return () => {
65+
document.removeEventListener("mousedown", handleClickOutside);
66+
window.removeEventListener("scroll", handleScroll, true);
67+
};
68+
}, [isExpanded, handleClose]);
69+
4170
React.useEffect(() => {
4271
if (debounceRef.current) {
4372
clearTimeout(debounceRef.current);
@@ -67,7 +96,7 @@ export function SearchBar({ onSearch, placeholder = "Search examples..." }: Sear
6796
}, [query, onSearch]);
6897

6998
return (
70-
<div className="relative flex items-center justify-center">
99+
<div ref={containerRef} className="relative flex items-center justify-center">
71100
<div
72101
className={`
73102
flex items-center gap-2 transition-all duration-300 ease-in-out

0 commit comments

Comments
 (0)