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 {
38 selfClearProp: string;
41 interface SearchInputActionProps {
42 onSearch: (value: string) => any;
46 type SearchInputProps = SearchInputDataProps & SearchInputActionProps & WithStyles<CssRules>;
48 interface SearchInputState {
51 selfClearProp: string;
54 export const DEFAULT_SEARCH_DEBOUNCE = 1000;
56 export const SearchInput = withStyles(styles)(
57 class extends React.Component<SearchInputProps> {
58 state: SearchInputState = {
67 return <form onSubmit={this.handleSubmit}>
69 <InputLabel>{this.state.label}</InputLabel>
72 data-cy="search-input"
73 value={this.state.value}
74 onChange={this.handleChange}
76 <InputAdornment position="end">
77 <Tooltip title='Search'>
79 onClick={this.handleSubmit}>
91 value: this.props.value,
92 label: this.props.label || 'Search'
96 componentWillReceiveProps(nextProps: SearchInputProps) {
97 if (nextProps.value !== this.props.value) {
98 this.setState({ value: nextProps.value });
100 if (this.state.value !== '' && nextProps.selfClearProp && nextProps.selfClearProp !== this.state.selfClearProp) {
101 this.props.onSearch('');
102 this.setState({ selfClearProp: nextProps.selfClearProp });
106 componentWillUnmount() {
107 clearTimeout(this.timeout);
110 handleSubmit = (event: React.FormEvent<HTMLElement>) => {
111 event.preventDefault();
112 clearTimeout(this.timeout);
113 this.props.onSearch(this.state.value);
116 handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
117 clearTimeout(this.timeout);
118 this.setState({ value: event.target.value });
119 this.timeout = window.setTimeout(
120 () => this.props.onSearch(this.state.value),
121 this.props.debounce || DEFAULT_SEARCH_DEBOUNCE