memos/web/src/components/SearchBar.tsx

66 lines
2.2 KiB
TypeScript

import { SearchIcon } from "lucide-react";
import { observer } from "mobx-react-lite";
import { useEffect, useRef, useState } from "react";
import { cn } from "@/lib/utils";
import { memoFilterStore } from "@/store";
import { useTranslate } from "@/utils/i18n";
import MemoDisplaySettingMenu from "./MemoDisplaySettingMenu";
import MemoFilterMenu from "./MemoFilterMenu";
const SearchBar = observer(() => {
const t = useTranslate();
const [queryText, setQueryText] = useState("");
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
const handleGlobalShortcut = (event: KeyboardEvent) => {
if ((event.metaKey || event.ctrlKey) && event.key === "/") {
event.preventDefault();
inputRef.current?.focus();
}
};
window.addEventListener("keydown", handleGlobalShortcut);
return () => window.removeEventListener("keydown", handleGlobalShortcut);
}, []);
const onTextChange = (event: React.FormEvent<HTMLInputElement>) => {
setQueryText(event.currentTarget.value);
};
const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
e.preventDefault();
const trimmedText = queryText.trim();
if (trimmedText !== "") {
const words = trimmedText.split(/\s+/);
words.forEach((word) => {
memoFilterStore.addFilter({
factor: "contentSearch",
value: word,
});
});
setQueryText("");
}
}
};
return (
<div className="relative w-full h-auto flex flex-row justify-start items-center">
<SearchIcon className="absolute left-2 w-4 h-auto opacity-40 text-sidebar-foreground" />
<input
className={cn("w-full text-sidebar-foreground leading-6 bg-sidebar border border-border text-sm rounded-lg p-1 pl-8 outline-0")}
placeholder={t("memo.search-placeholder")}
value={queryText}
onChange={onTextChange}
onKeyDown={onKeyDown}
ref={inputRef}
/>
<MemoFilterMenu className="absolute right-8 top-2 text-sidebar-foreground" />
<MemoDisplaySettingMenu className="absolute right-2 top-2 text-sidebar-foreground" />
</div>
);
});
export default SearchBar;