UNPKG

vtseditor

Version:
217 lines (174 loc) 5.26 kB
import './Searchbar.css'; import {EditorIcons} from '../Base/EditorIcons.js'; /** * Searchbar result entry */ export type SearchbarResultEntry = { objectId: string; path: string; name: string; isSchema: boolean; description: string; }; /** * Interface of searchbar */ export interface ISearchbar { /** * show results * @param {SearchbarResultEntry[]} items */ showResults(items: SearchbarResultEntry[]): void; } /** * Searchbar on search */ export type SearchbarOnSearch = (search: string, searchbar: ISearchbar) => void; /** * Searchbar on result click */ export type SearchbarOnResultClick = (entry: SearchbarResultEntry) => void; /** * Searchbar */ export class Searchbar implements ISearchbar { /** * container * @protected */ protected _container: HTMLDivElement; /** * input * @protected */ protected _input: HTMLInputElement; /** * results * @protected */ protected _results: HTMLUListElement; /** * on search * @protected */ protected _onSearch: SearchbarOnSearch|null = null; /** * on result click * @protected */ protected _onResultClick: SearchbarOnResultClick|null = null; /** * Constructor */ public constructor() { this._container = document.createElement('div'); this._container.classList.add('searchbar-container'); this._input = document.createElement('input'); this._input.type = 'text'; this._input.classList.add('searchbar'); this._input.placeholder = '🔍 Search...'; this._results = document.createElement('ul'); this._results.classList.add('search-results'); this._results.style.display = 'none'; this._input.addEventListener('input', () => { const value = this._input.value.trim(); if (value.length > 0) { if (this._onSearch !== null) { this._onSearch(value, this); } else { this.showResults([]); } } else { this.hideResults(); } }); this._input.addEventListener('blur', () => { // kleine Verzögerung, damit Klicks noch gehen setTimeout(() => this.hideResults(), 200); }); // ------------------------------------------------------------------------------------------------------------- this._container.appendChild(this._input); this._container.appendChild(this._results); } /** * Return the element * @return HTMLDivElement */ public getElement(): HTMLDivElement { return this._container; } /** * show results * @param {SearchbarResultEntry[]} items */ public showResults(items: SearchbarResultEntry[]): void { this._results.innerHTML = ''; if (items.length === 0) { const li = document.createElement('li'); li.classList.add('search-result-empty'); li.textContent = 'None results found!'; this._results.appendChild(li); this._results.style.display = 'block'; return; } items.forEach(entry => { const li = document.createElement('li'); li.classList.add('search-result-item'); const pathEl = document.createElement('div'); pathEl.classList.add('result-path'); pathEl.textContent = entry.path; li.appendChild(pathEl); const nameEl = document.createElement('div'); nameEl.classList.add('result-name'); nameEl.textContent = (entry.isSchema ? ` ${EditorIcons.schema}` : EditorIcons.enum) + ` ${entry.name}`; li.appendChild(nameEl); if (entry.description) { const descEl = document.createElement('div'); descEl.classList.add('result-description'); descEl.textContent = entry.description; li.appendChild(descEl); } li.addEventListener('click', () => { this._input.value = ''; if (this._onResultClick !== null) { this._onResultClick(entry); } this.hideResults(); }); this._results.appendChild(li); }); this._results.style.display = 'block'; } /** * hide results */ public hideResults(): void { this._results.style.display = 'none'; } /** * set on search * @param {SearchbarOnSearch|null} onSearch */ public setOnSearch(onSearch: SearchbarOnSearch|null): void { this._onSearch = onSearch; } /** * Set on result click * @param {SearchbarOnResultClick|null} onResultClick */ public setOnResultClick(onResultClick: SearchbarOnResultClick|null): void { this._onResultClick = onResultClick; } /** * Hide */ public hide(): void { this._container.style.display = 'none'; } /** * Show */ public show(): void { this._container.style.display = ''; } }