import React from "react"; import icon from "../icon"; import request from "../../services/request"; import "./search.css"; interface SearchProp { basePath: string; onItemSelected?: Function; } interface SearchState { query: string; result: { name: string; path: string }[]; showSearchLoader: boolean; showSearchBox: boolean; } class Search extends React.Component { state: SearchState = { query: "", result: [], showSearchLoader: false, showSearchBox: false, }; constructor(props: SearchProp) { super(props); } runDebounce = this.debounce(this.doSearch, 1000); debounce(fn: Function, delay: number) { let timer: NodeJS.Timeout; return function () { clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, arguments); }, delay); }; } async doSearch(query: string) { if (!query) { this.setState({ query: "", result: [], showSearchBox: false, showSearchLoader: false, }); return; } const dirPath = this.props.basePath; const result = await request.search(dirPath, query); this.setState({ query, result, showSearchBox: true, showSearchLoader: false, }); } handleChange = (query: string) => { if (!query) { this.setState({ query: "", }); return; } this.setState({ query, showSearchBox: true, showSearchLoader: true, }); }; clearSearch = (event: React.KeyboardEvent) => { const keyCode = event.which || event.keyCode; if (keyCode === 27) { // Clear search this.setState({ query: "", result: [], showSearchBox: false, }); } }; showResults = () => { return (
{this.state.result.map((item) => (
this.props.onItemSelected(item)} key={item.path} className="indent mb search-item" >
{icon.file(item)} {item.name}
{item.path}
))}
); }; emptyResults = () => { return (
{icon.close()} No Matching Results
); }; loadingResults = () => { return
{icon.loading()}
; }; results = () => { if (this.state.showSearchLoader) { return this.loadingResults(); } if (this.state.result.length > 0) { return this.showResults(); } return this.emptyResults(); }; render() { return (
{icon.search()} { this.handleChange(event.target.value); this.runDebounce(); }} onKeyDown={this.clearSearch} value={this.state.query} />
{this.results()}
); } } export default Search;