1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React, {useState, useEffect} from 'react';
6 import { IconButton, StyleRulesCallback, withStyles, WithStyles, FormControl, InputLabel, Input, InputAdornment, Tooltip } from '@material-ui/core';
7 import SearchIcon from '@material-ui/icons/Search';
9 type CssRules = 'container' | 'input' | 'button';
11 const styles: StyleRulesCallback<CssRules> = theme => {
19 borderRadius: theme.spacing.unit / 4,
20 boxSizing: 'border-box',
21 padding: theme.spacing.unit,
22 paddingRight: theme.spacing.unit * 4,
27 top: theme.spacing.unit / 2,
28 right: theme.spacing.unit / 2,
29 width: theme.spacing.unit * 3,
30 height: theme.spacing.unit * 3
35 interface SearchInputDataProps {
38 selfClearProp: string;
41 interface SearchInputActionProps {
42 onSearch: (value: string) => any;
46 type SearchInputProps = SearchInputDataProps & SearchInputActionProps & WithStyles<CssRules>;
48 export const DEFAULT_SEARCH_DEBOUNCE = 1000;
50 const SearchInputComponent = (props: SearchInputProps) => {
51 const [timeout, setTimeout] = useState(0);
52 const [value, setValue] = useState("");
53 const [label, setLabel] = useState("Search");
54 const [selfClearProp, setSelfClearProp] = useState("");
58 setValue(props.value);
61 setLabel(props.label);
66 clearTimeout(timeout);
68 }, [props.value, props.label]); // eslint-disable-line react-hooks/exhaustive-deps
71 if (selfClearProp !== props.selfClearProp) {
73 setSelfClearProp(props.selfClearProp);
74 handleChange({ target: { value: "" } } as any);
76 }, [props.selfClearProp]); // eslint-disable-line react-hooks/exhaustive-deps
78 const handleSubmit = (event: React.FormEvent<HTMLElement>) => {
79 event.preventDefault();
80 clearTimeout(timeout);
81 props.onSearch(value);
84 const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
85 const { target: { value: eventValue } } = event;
86 clearTimeout(timeout);
89 setTimeout(window.setTimeout(
91 props.onSearch(eventValue);
93 props.debounce || DEFAULT_SEARCH_DEBOUNCE
97 return <form onSubmit={handleSubmit}>
99 <InputLabel>{label}</InputLabel>
102 data-cy="search-input"
104 onChange={handleChange}
106 <InputAdornment position="end">
107 <Tooltip title='Search'>
109 onClick={handleSubmit}>
119 export const SearchInput = withStyles(styles)(SearchInputComponent);