element-vir
Version:
Heroic. Reactive. Declarative. Type safe. Web components without compromise.
49 lines (48 loc) • 1.98 kB
JavaScript
import { directive, Directive, noChange, } from '../../lit-exports/all-lit-exports.js';
import { extractElement } from './directive-helpers.js';
export function listen(eventType, listener) {
return listenDirective(eventType, listener);
}
/**
* The directive generics here are not strong enough to maintain their values. Thus, the directive
* call is wrapped in the function above.
*/
const listenDirective = directive(class extends Directive {
element;
lastListenerMetaData;
constructor(partInfo) {
super(partInfo);
this.element = extractElement(partInfo, 'listen');
}
resetListener(listenerMetaData) {
if (this.lastListenerMetaData) {
this.element.removeEventListener(this.lastListenerMetaData.eventType, this.lastListenerMetaData.listener);
}
this.element.addEventListener(listenerMetaData.eventType, listenerMetaData.listener);
this.lastListenerMetaData = listenerMetaData;
}
createListenerMetaData(eventType, callback) {
return {
eventType,
callback,
listener: (event) => this.lastListenerMetaData?.callback(event),
};
}
render(eventTypeInput, callback) {
const eventType = typeof eventTypeInput === 'string' ? eventTypeInput : eventTypeInput.type;
if (typeof eventType !== 'string') {
throw new TypeError(`Cannot listen to an event with a name that is not a string. Given event name: '${String(eventType)}'`);
}
if (this.lastListenerMetaData && this.lastListenerMetaData.eventType === eventType) {
/**
* Store the callback here so we don't have to update the attached listener every
* time the callback is updated.
*/
this.lastListenerMetaData.callback = callback;
}
else {
this.resetListener(this.createListenerMetaData(eventType, callback));
}
return noChange;
}
});