Component props
<SearchInput
onSearch={handleSearchChange}
/>
export default function SearchInput({ onSearch }: SearchInputStates) {
const { searchInputValue, isLoading, handleSearchInputChange, handleSubmit } = useSearchInput();
return (
<>
<div className={`${styles['search-input-container']} ${styles.fullwidth}`}>
<Paper
className={`${styles.fullwidth} ${styles['search-query-input-form']}`}
component="form"
onSubmit={handleSubmit(onSearch)}
sx={{
opacity: isLoading ? 0.7 : 1,
transition: "opacity 0.2s ease",
}}
>
<IconButton disabled={isLoading} aria-label="menu">
<MenuIcon />
</IconButton>
<InputBase
value={searchInputValue}
onChange={(e) => handleSearchInputChange(e.target.value)}
className={`${styles['search-query-input']} ${styles.fullwidth}`}
placeholder={isLoading ? "Searching..." : "Search..."}
disabled={isLoading}
slotProps={{ input: { "aria-label": "Search for chemicals" } }}
/>
<IconButton type="button" disabled={isLoading} aria-label="search">
<ScienceIcon />
</IconButton>
<Divider orientation="vertical" />
<IconButton
color="primary"
type="submit"
disabled={isLoading || !searchInputValue.trim()}
aria-label="execute search"
>
<SearchIcon />
</IconButton>
</Paper>
{/* Loading indicator */}
{isLoading && (
<div
style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
height: 2,
backgroundColor: "#1976d2",
animation: "pulse 1s infinite",
zIndex: 1000,
}}
>
Loading...
</div>
)}
</div>
</>
);
}
SearchInput component that provides a search interface with a text input and action buttons. It includes a menu button, search input field, and search action buttons.
Refactored version that uses the useSearchInput hook for better code organization.