X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/5e88476747d9fb0c77ef76d63430192fa4b77f22..9357b8b80868d200d4f7e8091034279f094bc58d:/src/components/search-input/search-input.tsx diff --git a/src/components/search-input/search-input.tsx b/src/components/search-input/search-input.tsx index edc82d55..fbb4f599 100644 --- a/src/components/search-input/search-input.tsx +++ b/src/components/search-input/search-input.tsx @@ -2,12 +2,21 @@ // // SPDX-License-Identifier: AGPL-3.0 -import * as React from 'react'; -import { IconButton, Paper, StyleRulesCallback, withStyles, WithStyles, FormControl, InputLabel, Input, InputAdornment, FormHelperText } from '@material-ui/core'; +import React, {useState, useEffect} from 'react'; +import { + IconButton, + FormControl, + InputLabel, + Input, + InputAdornment, + Tooltip, +} from '@material-ui/core'; import SearchIcon from '@material-ui/icons/Search'; interface SearchInputDataProps { value: string; + label?: string; + selfClearProp: string; } interface SearchInputActionProps { @@ -15,99 +24,75 @@ interface SearchInputActionProps { debounce?: number; } -type SearchInputProps = SearchInputDataProps & SearchInputActionProps & WithStyles; - -interface SearchInputState { - value: string; -} +type SearchInputProps = SearchInputDataProps & SearchInputActionProps; export const DEFAULT_SEARCH_DEBOUNCE = 1000; -class SearchInput extends React.Component { +export const SearchInput = (props: SearchInputProps) => { + const [timeout, setTimeout] = useState(0); + const [value, setValue] = useState(""); + const [label, setLabel] = useState("Search"); + const [selfClearProp, setSelfClearProp] = useState(""); - state: SearchInputState = { - value: "" - }; - - timeout: number; - - render() { - const { classes } = this.props; - return
- - Search - - - - - - } /> - -
; - } - - componentDidMount() { - this.setState({ value: this.props.value }); - } - - componentWillReceiveProps(nextProps: SearchInputProps) { - if (nextProps.value !== this.props.value) { - this.setState({ value: nextProps.value }); + useEffect(() => { + if (props.value) { + setValue(props.value); + } + if (props.label) { + setLabel(props.label); } - } - componentWillUnmount() { - clearTimeout(this.timeout); - } + return () => { + setValue(""); + clearTimeout(timeout); + }; + }, [props.value, props.label]); // eslint-disable-line react-hooks/exhaustive-deps + + useEffect(() => { + if (selfClearProp !== props.selfClearProp) { + setValue(""); + setSelfClearProp(props.selfClearProp); + handleChange({ target: { value: "" } } as any); + } + }, [props.selfClearProp]); // eslint-disable-line react-hooks/exhaustive-deps - handleSubmit = (event: React.FormEvent) => { + const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); - clearTimeout(this.timeout); - this.props.onSearch(this.state.value); - } - - handleChange = (event: React.ChangeEvent) => { - clearTimeout(this.timeout); - this.setState({ value: event.target.value }); - this.timeout = window.setTimeout( - () => this.props.onSearch(this.state.value), - this.props.debounce || DEFAULT_SEARCH_DEBOUNCE - ); - - } - -} - -type CssRules = 'container' | 'input' | 'button'; + clearTimeout(timeout); + props.onSearch(value); + }; -const styles: StyleRulesCallback = theme => { - return { - container: { - position: 'relative', - width: '100%' - }, - input: { - border: 'none', - borderRadius: theme.spacing.unit / 4, - boxSizing: 'border-box', - padding: theme.spacing.unit, - paddingRight: theme.spacing.unit * 4, - width: '100%', - }, - button: { - position: 'absolute', - top: theme.spacing.unit / 2, - right: theme.spacing.unit / 2, - width: theme.spacing.unit * 3, - height: theme.spacing.unit * 3 - } + const handleChange = (event: React.ChangeEvent) => { + const { target: { value: eventValue } } = event; + clearTimeout(timeout); + setValue(eventValue); + + setTimeout(window.setTimeout( + () => { + props.onSearch(eventValue); + }, + props.debounce || DEFAULT_SEARCH_DEBOUNCE + )); }; -}; -export default withStyles(styles)(SearchInput); \ No newline at end of file + return
+ + {label} + + + + + + + + } /> + +
; +};