1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
14 } from '@material-ui/core';
15 import SearchIcon from '@material-ui/icons/Search';
17 type CssRules = 'container' | 'input';
19 const styles: StyleRulesCallback<CssRules> = theme => {
27 borderRadius: theme.spacing.unit / 4,
28 padding: `${theme.spacing.unit / 2}px ${theme.spacing.unit}px`
33 interface SearchBarDataProps {
37 interface SearchBarActionProps {
38 onSearch: (value: string) => any;
42 type SearchBarProps = SearchBarDataProps & SearchBarActionProps & WithStyles<CssRules>;
44 interface SearchBarState {
48 export const DEFAULT_SEARCH_DEBOUNCE = 1000;
50 export const SearchBar = withStyles(styles)(
51 class extends React.Component<SearchBarProps> {
52 state: SearchBarState = {
59 const { classes } = this.props;
60 return <Paper className={classes.container}>
61 <form onSubmit={this.handleSubmit}>
63 className={classes.input}
64 onChange={this.handleChange}
66 value={this.state.value}
68 disableUnderline={true}
70 <InputAdornment position="end">
71 <Tooltip title='Search'>
83 this.setState({ value: this.props.value });
86 componentWillReceiveProps(nextProps: SearchBarProps) {
87 if (nextProps.value !== this.props.value) {
88 this.setState({ value: nextProps.value });
92 componentWillUnmount() {
93 clearTimeout(this.timeout);
96 handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
97 event.preventDefault();
98 clearTimeout(this.timeout);
99 this.props.onSearch(this.state.value);
102 handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
103 clearTimeout(this.timeout);
104 this.setState({ value: event.target.value });
105 this.timeout = window.setTimeout(
106 () => this.props.onSearch(this.state.value),
107 this.props.debounce || DEFAULT_SEARCH_DEBOUNCE