@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
64 lines • 2.73 kB
JavaScript
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