1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React 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 {
40 interface SearchInputActionProps {
41 onSearch: (value: string) => any;
45 type SearchInputProps = SearchInputDataProps & SearchInputActionProps & WithStyles<CssRules>;
47 interface SearchInputState {
52 export const DEFAULT_SEARCH_DEBOUNCE = 1000;
54 export const SearchInput = withStyles(styles)(
55 class extends React.Component<SearchInputProps> {
56 state: SearchInputState = {
64 return <form onSubmit={this.handleSubmit}>
66 <InputLabel>{this.state.label}</InputLabel>
69 value={this.state.value}
70 onChange={this.handleChange}
72 <InputAdornment position="end">
73 <Tooltip title='Search'>
75 onClick={this.handleSubmit}>
87 value: this.props.value,
88 label: this.props.label || 'Search'
92 componentWillReceiveProps(nextProps: SearchInputProps) {
93 if (nextProps.value !== this.props.value) {
94 this.setState({ value: nextProps.value });
98 componentWillUnmount() {
99 clearTimeout(this.timeout);
102 handleSubmit = (event: React.FormEvent<HTMLElement>) => {
103 event.preventDefault();
104 clearTimeout(this.timeout);
105 this.props.onSearch(this.state.value);
108 handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
109 clearTimeout(this.timeout);
110 this.setState({ value: event.target.value });
111 this.timeout = window.setTimeout(
112 () => this.props.onSearch(this.state.value),
113 this.props.debounce || DEFAULT_SEARCH_DEBOUNCE