1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React, {useState, useEffect} from 'react';
13 } from '@mui/material';
14 import SearchIcon from '@mui/icons-material/Search';
16 interface SearchInputDataProps {
19 selfClearProp: string;
23 interface SearchInputActionProps {
24 onSearch: (value: string) => any;
28 type SearchInputProps = SearchInputDataProps & SearchInputActionProps;
30 export const DEFAULT_SEARCH_DEBOUNCE = 1000;
32 export const SearchInput = (props: SearchInputProps) => {
33 const [timeout, setTimeout] = useState(0);
34 const [value, setValue] = useState("");
35 const [label, setLabel] = useState("Search");
36 const [selfClearProp, setSelfClearProp] = useState("");
40 setValue(props.value);
43 setLabel(props.label);
48 clearTimeout(timeout);
50 // eslint-disable-next-line react-hooks/exhaustive-deps
51 }, [props.value, props.label]);
54 if (selfClearProp !== props.selfClearProp) {
56 setSelfClearProp(props.selfClearProp);
57 handleChange({ target: { value: "" } } as any);
59 // eslint-disable-next-line react-hooks/exhaustive-deps
60 }, [props.selfClearProp]);
62 const handleSubmit = (event: React.FormEvent<HTMLElement>) => {
63 event.preventDefault();
64 clearTimeout(timeout);
65 props.onSearch(value);
68 const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
69 const { target: { value: eventValue } } = event;
70 clearTimeout(timeout);
73 setTimeout(window.setTimeout(
75 props.onSearch(eventValue);
77 props.debounce || DEFAULT_SEARCH_DEBOUNCE
82 <form onSubmit={handleSubmit}>
83 <FormControl variant="standard" style={{ width: props.width || '14rem'}}>
84 <InputLabel>{label}</InputLabel>
87 data-cy="search-input"
89 onChange={handleChange}
91 <InputAdornment position="end" style={{marginRight: '-0.6rem'}}>
92 <Tooltip title='Search'>
93 <IconButton onClick={handleSubmit} size="large">