@gowiz/searchbar
Version:
Different search bars powered by Gowiz search engine technology
170 lines • 8.22 kB
JavaScript
"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