1
0
Fork 0
mirror of https://github.com/codex-team/codex.docs.git synced 2025-07-21 22:29:40 +02:00

search implementation

This commit is contained in:
Taly 2022-08-11 18:28:15 +03:00
parent f05eb15b72
commit 79592f0a1d
12 changed files with 440 additions and 28 deletions

View file

@ -0,0 +1,137 @@
import { debounce } from '../utils/decorators';
import Shortcut from '@codexteam/shortcuts';
import axios from 'axios';
export default class Search {
constructor() {
this.nodes = {
overlay: null,
searchWrapper: null,
searchInput: null,
searchResultsWrapper: null
};
this.isVisible = false;
this.shortcut = null;
this.TOGGLER_SHORTCUT = 'CMD+SHIFT+F';
this.debouncedSearch = null;
this.DEBOUNCE_TIME = 500;
}
init(settings = {}, moduleEl) {
console.log('search init');
this.createSearchOverlay();
this.createDebouncedSearch();
this.enableShortcutListening();
// ! force open search overlay
// this.toggleSearchOverlay(true);
}
createSearchOverlay() {
this.nodes.overlay = document.createElement('div');
this.nodes.overlay.classList.add('search-overlay');
this.nodes.overlay.addEventListener('click', this.searchOverlayClickProcessor.bind(this));
this.nodes.searchWrapper = document.createElement('div');
this.nodes.searchWrapper.classList.add('search-wrapper');
this.nodes.searchInput = document.createElement('input');
this.nodes.searchInput.classList.add('search-input');
this.nodes.searchInput.setAttribute('type', 'search');
this.nodes.searchInput.setAttribute('placeholder', 'Find in documents...');
this.nodes.searchInput.setAttribute('autocomplete', 'off');
this.nodes.searchInput.addEventListener('input', this.searchInputOnchangeProcessor.bind(this));
this.nodes.searchWrapper.appendChild(this.nodes.searchInput);
this.nodes.searchResultsWrapper = document.createElement('div');
this.nodes.searchResultsWrapper.classList.add('search-results-wrapper');
this.nodes.searchWrapper.appendChild(this.nodes.searchResultsWrapper);
this.nodes.overlay.appendChild(this.nodes.searchWrapper);
document.body.appendChild(this.nodes.overlay);
}
searchOverlayClickProcessor(event) {
if (event.target !== this.nodes.overlay) {
return;
}
this.toggleSearchOverlay(false);
}
searchInputOnchangeProcessor(event) {
// close search overlay if ESC key is pressed
if (event.keyCode === 27) {
this.toggleSearchOverlay(false);
event.preventDefault();
}
console.log(event.target.value);
this.debouncedSearch(event.target.value);
}
enableShortcutListening() {
this.shortcut = new Shortcut({
name : this.TOGGLER_SHORTCUT,
on : document.body,
callback: (event) => {
this.toggleSearchOverlay();
}
});
}
toggleSearchOverlay(force) {
this.isVisible = force || !this.isVisible;
this.nodes.overlay.classList.toggle('search-overlay--visible', this.isVisible);
document.body.classList.toggle('noscroll', this.isVisible);
this.nodes.searchInput.focus();
}
createDebouncedSearch() {
this.debouncedSearch = debounce(this.getSearchResults, this.DEBOUNCE_TIME);
}
getSearchResults(text) {
// this.showSearchResult(text);
// call api to get search results
axios.get('/api/search', {
params: {
text: text
}
})
.then(this.showSearchResult.bind(this));
}
showSearchResult({ data }) {
console.log(data);
this.nodes.searchResultsWrapper.innerHTML = '';
data.result.pages.forEach(page => {
const result = document.createElement('a');
result.classList.add('search-results-item');
result.setAttribute('href', `/${page.uri}`);
const title = document.createElement('div');
title.classList.add('search-results-item__title');
title.innerHTML = page.title;
result.appendChild(title);
// const description = document.createElement('div');
// description.classList.add('search-results-item__description');
// result.appendChild(description);
this.nodes.searchResultsWrapper.appendChild(result);
});
}
}