UNPKG

@furystack/shades-common-components

Version:

Common UI components for FuryStack Shades

64 lines 2.73 kB
import { debounce, EventHub, ObservableValue } from '@furystack/utils'; export class SuggestManager extends EventHub { getEntries; getSuggestionEntry; isOpened = new ObservableValue(false); isLoading = new ObservableValue(false); term = new ObservableValue(''); selectedIndex = new ObservableValue(0); currentSuggestions = new ObservableValue([]); keyPressListener = ((ev) => { if (ev.key === 'Escape') { this.isOpened.setValue(false); } }).bind(this); element; clickOutsideListener = ((ev) => { if (this.element && this.isOpened.getValue() && ev.target.closest(this.element.tagName) !== this.element) { this.isOpened.setValue(false); } }).bind(this); [Symbol.dispose]() { window.removeEventListener('keyup', this.keyPressListener, true); window.removeEventListener('click', this.clickOutsideListener, true); this.isOpened[Symbol.dispose](); this.isLoading[Symbol.dispose](); this.term[Symbol.dispose](); this.selectedIndex[Symbol.dispose](); this.currentSuggestions[Symbol.dispose](); super[Symbol.dispose](); } selectSuggestion(index = this.selectedIndex.getValue()) { const selectedSuggestion = this.currentSuggestions.getValue()[index]; this.isOpened.setValue(false); this.emit('onSelectSuggestion', selectedSuggestion.entry); } lastGetSuggestionOptions; getSuggestion = debounce(async (options) => { try { if (this.lastGetSuggestionOptions?.term === options.term) { return; } const lastSelectedEntry = JSON.stringify(this.currentSuggestions.getValue()[this.selectedIndex.getValue()]?.entry); this.isLoading.setValue(true); this.lastGetSuggestionOptions = options; const newEntries = await this.getEntries(options.term); this.isOpened.setValue(true); this.currentSuggestions.setValue(newEntries.map((e) => ({ entry: e, suggestion: this.getSuggestionEntry(e) }))); this.selectedIndex.setValue(Math.max(0, this.currentSuggestions.getValue().findIndex((e) => JSON.stringify(e.entry) === lastSelectedEntry))); } finally { this.isLoading.setValue(false); } }, 250); constructor(getEntries, getSuggestionEntry) { super(); this.getEntries = getEntries; this.getSuggestionEntry = getSuggestionEntry; window.addEventListener('keyup', this.keyPressListener, true); window.addEventListener('click', this.clickOutsideListener, true); } } //# sourceMappingURL=suggest-manager.js.map