UNPKG

@gowiz/searchbar

Version:

Different search bars powered by Gowiz search engine technology

170 lines 8.22 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = __importDefault(require("react")); const fuse_js_1 = __importDefault(require("fuse.js")); const input_1 = __importDefault(require("./input")); const result_1 = __importDefault(require("./result")); const storage_1 = require("../util/storage"); const component_validation_1 = require("../util/component_validation"); const searchcontainer_util_1 = require("../util/searchcontainer_util"); const hidden_input_1 = require("./hidden_input"); class SearchContainer extends react_1.default.PureComponent { constructor(props) { component_validation_1.searchcontainer_has_valid_props(props); super(props); this.state = { query: this.props.query ? this.props.query : '', results: this.initialResults(), showSearchResults: true, highlight_query_index: -1, hasSearched: false, }; this.handleOnChange = this.handleOnChange.bind(this); this.handleOnCancel = this.handleOnCancel.bind(this); this.handleOnKey = this.handleOnKey.bind(this); this.handleSearchSuggestionRemove = this.handleSearchSuggestionRemove.bind(this); this.handleOnToSearchBarClick = this.handleOnToSearchBarClick.bind(this); this.result_ref = react_1.default.createRef(); } initialResults() { const searchSuggestions = this.props.searchSuggestions === null || this.props.searchSuggestions === undefined ? [] : this.props.searchSuggestions; const maxResults = this.props.maxResults === null || this.props.maxResults === undefined ? searchSuggestions.length : this.props.maxResults; return searchSuggestions.slice(0, maxResults); } getAutoCompleteStatus() { return this.props.useAutoComplete !== false; } handleOnChange(new_query) { const { hasSearched, results } = this.state; const useAutoComplete = this.getAutoCompleteStatus(); let newResults; if (useAutoComplete && navigator.onLine) { newResults = searchcontainer_util_1.getAutoCompleteValues(new_query); } const useFuseSearch = newResults == null || false || newResults.length === 0 ? true : !useAutoComplete || !navigator.onLine; if (useFuseSearch) { const fuse = new fuse_js_1.default(results); newResults = fuse.search(new_query).map(function (x) { return x.item; }); } const updateResults = newResults !== results; let stateUpdate = { hasSearched: !hasSearched, results: updateResults ? newResults : [], query: new_query, showSearchResults: new_query.length !== 0, }; Object.keys(stateUpdate).forEach((key) => { if (stateUpdate[key] === undefined) { delete stateUpdate[key]; } }); this.setState(stateUpdate); } handleOnCancel(event) { event.preventDefault(); const { highlight_query_index } = this.state; if (highlight_query_index != -1) { this.setState({ query: '', highlight_query_index: -1 }); } else { this.setState({ query: '' }); } } handleOnKey(event) { const specialKeys = ['Enter', 'ArrowUp', 'ArrowDown', 'Escape']; if (!specialKeys.includes(event.key)) { return; } switch (event.key) { case 'Enter': event.preventDefault(); switch (event.target.id) { case 'cancel_icon': this.handleOnCancel(event); break; case 'remove_icon': const title = event.target.title; const query = title.split(' ')[1]; this.handleSearchSuggestionRemove(query); break; default: this.props.onSubmit(event); break; } break; case 'ArrowUp': case 'ArrowDown': { event.preventDefault(); const arrow_changes_state = this.state.results.length > 0 && this.state.hasSearched; if (arrow_changes_state) { const max_nr = this.state.results.length - 1; const change = event.key === 'ArrowUp' ? -1 : 1; let current_nr = this.state.highlight_query_index + change; current_nr = current_nr <= -1 || current_nr >= max_nr ? -1 : current_nr; const next_query = current_nr === -1 ? (this.props.query ? this.props.query : '') : this.state.results[current_nr]; this.setState({ highlight_query_index: current_nr, query: next_query, }); } break; } case 'Escape': event.preventDefault(); const should_trigger_state_change = this.state.results.length > 0 && this.state.showSearchResults; if (should_trigger_state_change) { this.setState({ showSearchResults: false }); } break; default: return; } } handleSearchSuggestionRemove(str) { storage_1.removeSearchTermFromLocalStorage(str); const result_component = this.result_ref.current; if (result_component != null) { result_component.forceUpdateMe(); } } handleOnToSearchBarClick(str) { if (this.state.query != str) { this.setState({ query: str, }); } } componentDidMount() { document.addEventListener('keydown', this.handleOnKey, false); } componentWillUnmount() { document.removeEventListener('keydown', this.handleOnKey, false); } render() { const { placeholder = 'Search on Gowiz', useCaching = true, showInputSearchIcon = true, showResultsSearchIcon = true, useAutoFocus = false, useDarkTheme = false, maxResults = 10, onSubmit, } = this.props; let { results, query, hasSearched, showSearchResults } = this.state; const results_should_render = results !== undefined && results.length > 0 && hasSearched && showSearchResults && query.length > 0; const container_class = useDarkTheme ? 'gowiz_searchbar_container dark_container' : 'gowiz_searchbar_container'; const results_class = useDarkTheme ? 'gowiz_searchbar_results dark_gowiz_searchbar_results' : 'gowiz_searchbar_results'; return (react_1.default.createElement("div", { className: container_class }, react_1.default.createElement("form", { onSubmit: (e) => onSubmit(e), id: 'gowiz_searchbox_form' }, react_1.default.createElement("div", { className: "gowiz_searchbar_input" }, react_1.default.createElement(input_1.default, { query: query, placeholder: placeholder, useAutoFocus: useAutoFocus, onChange: this.handleOnChange, onCancel: this.handleOnCancel, showInputSearchIcon: showInputSearchIcon, useDarkTheme: useDarkTheme })), results_should_render && (react_1.default.createElement("div", { className: results_class }, react_1.default.createElement(result_1.default, { ref: this.result_ref, onSelect: this.props.onSubmit, onRemove: this.handleSearchSuggestionRemove, onClick: this.handleOnToSearchBarClick, maxResults: maxResults, results: results, showResultsSearchIcon: showResultsSearchIcon, useCashing: useCaching, query: query, hasSearched: hasSearched, useDarkTheme: useDarkTheme }))), react_1.default.createElement(hidden_input_1.HiddenInput, null)))); } } exports.default = SearchContainer; //# sourceMappingURL=searchcontainer.js.map