120 lines
3.3 KiB
TypeScript
120 lines
3.3 KiB
TypeScript
/*
|
|
* https://github.com/morethanwords/tweb
|
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
|
*/
|
|
|
|
import attachListNavigation from "../../helpers/dom/attachListNavigation";
|
|
import EventListenerBase from "../../helpers/eventListenerBase";
|
|
import { safeAssign } from "../../helpers/object";
|
|
import { isMobile } from "../../helpers/userAgent";
|
|
import rootScope from "../../lib/rootScope";
|
|
import appNavigationController, { NavigationItem } from "../appNavigationController";
|
|
import SetTransition from "../singleTransition";
|
|
import AutocompleteHelperController from "./autocompleteHelperController";
|
|
|
|
export default class AutocompleteHelper extends EventListenerBase<{
|
|
hidden: () => void,
|
|
visible: () => void,
|
|
}> {
|
|
protected hidden = true;
|
|
protected container: HTMLElement;
|
|
protected list: HTMLElement;
|
|
protected resetTarget: () => void;
|
|
protected init?(): void;
|
|
|
|
protected controller: AutocompleteHelperController;
|
|
protected listType: 'xy' | 'x' | 'y';
|
|
protected onSelect: (target: Element) => boolean | void;
|
|
protected waitForKey?: string;
|
|
|
|
constructor(options: {
|
|
appendTo: HTMLElement,
|
|
controller: AutocompleteHelper['controller'],
|
|
listType: AutocompleteHelper['listType'],
|
|
onSelect: AutocompleteHelper['onSelect'],
|
|
waitForKey?: AutocompleteHelper['waitForKey']
|
|
}) {
|
|
super(false);
|
|
|
|
safeAssign(this, options);
|
|
|
|
this.container = document.createElement('div');
|
|
this.container.classList.add('autocomplete-helper', 'z-depth-1');
|
|
|
|
options.appendTo.append(this.container);
|
|
|
|
this.attachNavigation();
|
|
|
|
this.controller.addHelper(this);
|
|
}
|
|
|
|
protected onVisible = () => {
|
|
const list = this.list;
|
|
const {detach, resetTarget} = attachListNavigation({
|
|
list,
|
|
type: this.listType,
|
|
onSelect: this.onSelect,
|
|
once: true,
|
|
waitForKey: this.waitForKey
|
|
});
|
|
|
|
this.resetTarget = resetTarget;
|
|
let navigationItem: NavigationItem;
|
|
if(!isMobile) {
|
|
navigationItem = {
|
|
type: 'autocomplete-helper',
|
|
onPop: () => this.toggle(true),
|
|
noBlurOnPop: true
|
|
};
|
|
|
|
appNavigationController.pushItem(navigationItem);
|
|
}
|
|
|
|
this.addEventListener('hidden', () => {
|
|
this.resetTarget = undefined;
|
|
list.innerHTML = '';
|
|
detach();
|
|
|
|
if(navigationItem) {
|
|
appNavigationController.removeItem(navigationItem);
|
|
}
|
|
}, true);
|
|
};
|
|
|
|
protected attachNavigation() {
|
|
this.addEventListener('visible', this.onVisible);
|
|
}
|
|
|
|
public toggle(hide?: boolean, fromController = false) {
|
|
if(this.init) {
|
|
return;
|
|
}
|
|
|
|
if(hide === undefined) {
|
|
hide = this.container.classList.contains('is-visible') && !this.container.classList.contains('backwards');
|
|
}
|
|
|
|
if(this.hidden === hide) {
|
|
if(!hide && this.resetTarget) {
|
|
this.resetTarget();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
this.hidden = hide;
|
|
|
|
if(!hide) {
|
|
this.controller.hideOtherHelpers(this);
|
|
this.dispatchEvent('visible'); // fire it before so target will be set
|
|
} else if(!fromController) {
|
|
this.controller.hideOtherHelpers();
|
|
}
|
|
|
|
SetTransition(this.container, 'is-visible', !hide, rootScope.settings.animationsEnabled ? 200 : 0, () => {
|
|
this.hidden && this.dispatchEvent('hidden');
|
|
});
|
|
}
|
|
}
|