67 lines
2.1 KiB
TypeScript
67 lines
2.1 KiB
TypeScript
import {useState} from "react";
|
|
import {Search, X} from "lucide-react";
|
|
import {defaultIconSize} from "./SvgIcon";
|
|
import clsx from "clsx";
|
|
|
|
/**
|
|
* Custom search field component including a clear search functionality
|
|
*/
|
|
type SearchFieldProps = {
|
|
onSearchStringChanged: (searchString: string) => void
|
|
className?: string
|
|
}
|
|
|
|
/**
|
|
* @param SearchFieldProps consisting of an initial searchString and an onSearchStringChanged handler
|
|
* @returns Custom search field component
|
|
*/
|
|
export default function SearchField({onSearchStringChanged, className = ""}: SearchFieldProps) {
|
|
const [currentSearchString, setCurrentSearchString] = useState<string>("")
|
|
|
|
const changeSearchString = (newSearchString: string) => {
|
|
console.log(newSearchString);
|
|
setCurrentSearchString(newSearchString);
|
|
onSearchStringChanged(newSearchString)
|
|
}
|
|
|
|
const iconStyle: string = "text-gray-400 hover:text-gray-500";
|
|
|
|
return (
|
|
<div className={clsx(
|
|
"relative",
|
|
className)}>
|
|
{/* Input of searchfield
|
|
Defines border and behavior. Requires extra padding at both sides to
|
|
accommodate the icons
|
|
*/}
|
|
<input
|
|
className="pl-10 pr-10"
|
|
type="text"
|
|
placeholder="Search"
|
|
value={currentSearchString}
|
|
onChange={e => changeSearchString(e.target.value)}
|
|
/>
|
|
{/* Right icon: X
|
|
Clears search string on click
|
|
*/}
|
|
<button
|
|
className={clsx(
|
|
"absolute right-0 inset-y-0 flex items-center -ml-1 mr-3",
|
|
iconStyle)}
|
|
onClick={() => changeSearchString("")}
|
|
>
|
|
<X
|
|
size={defaultIconSize}
|
|
/>
|
|
</button>
|
|
{/* Left icon: Looking glass */}
|
|
<div className={clsx(
|
|
"absolute left-0 inset-y-0 flex items-center ml-3",
|
|
iconStyle)}>
|
|
<Search
|
|
size={defaultIconSize}
|
|
/>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|