1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { IconButton, Paper, StyleRulesCallback, withStyles, WithStyles, FormControl, InputLabel, Input, InputAdornment, FormHelperText } from '@material-ui/core';
7 import SearchIcon from '@material-ui/icons/Search';
9 interface SearchInputDataProps {
13 interface SearchInputActionProps {
14 onSearch: (value: string) => any;
18 type SearchInputProps = SearchInputDataProps & SearchInputActionProps & WithStyles<CssRules>;
20 interface SearchInputState {
24 export const DEFAULT_SEARCH_DEBOUNCE = 1000;
26 class SearchInput extends React.Component<SearchInputProps> {
28 state: SearchInputState = {
35 const { classes } = this.props;
36 return <form onSubmit={this.handleSubmit}>
38 <InputLabel>Search</InputLabel>
41 value={this.state.value}
42 onChange={this.handleChange}
44 <InputAdornment position="end">
46 onClick={this.handleSubmit}>
56 this.setState({ value: this.props.value });
59 componentWillReceiveProps(nextProps: SearchInputProps) {
60 if (nextProps.value !== this.props.value) {
61 this.setState({ value: nextProps.value });
65 componentWillUnmount() {
66 clearTimeout(this.timeout);
69 handleSubmit = (event: React.FormEvent<HTMLElement>) => {
70 event.preventDefault();
71 clearTimeout(this.timeout);
72 this.props.onSearch(this.state.value);
75 handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
76 clearTimeout(this.timeout);
77 this.setState({ value: event.target.value });
78 this.timeout = window.setTimeout(
79 () => this.props.onSearch(this.state.value),
80 this.props.debounce || DEFAULT_SEARCH_DEBOUNCE
87 type CssRules = 'container' | 'input' | 'button';
89 const styles: StyleRulesCallback<CssRules> = theme => {
97 borderRadius: theme.spacing.unit / 4,
98 boxSizing: 'border-box',
99 padding: theme.spacing.unit,
100 paddingRight: theme.spacing.unit * 4,
104 position: 'absolute',
105 top: theme.spacing.unit / 2,
106 right: theme.spacing.unit / 2,
107 width: theme.spacing.unit * 3,
108 height: theme.spacing.unit * 3
113 export default withStyles(styles)(SearchInput);