import { createRef, ref } from 'lit/directives/ref.js'; import type { PlayerEmbed } from '..'; import type { ReactiveController, ReactiveControllerHost } from 'lit'; import type { DirectiveResult } from 'lit/directive.js'; import type { Ref } from 'lit/directives/ref.js'; import { forwardEvent } from '~/utils/events'; type PlayerEmbedHost = ReactiveControllerHost & PlayerEmbed; class EventForwardController implements ReactiveController { host: PlayerEmbedHost; private _events: string[] = []; private _cleanup: (() => void)[] = []; private _forwardElementRef: Ref = createRef(); constructor(host: PlayerEmbedHost, events: string[]) { this.host = host; this._events = events; host.addController(this); } register(): DirectiveResult { return ref(this._forwardElementRef); } hostConnected() { // Guaranteed to have the element ref in the RAF callback because of how the lit lifecycle works requestAnimationFrame(() => { this._events.forEach((event) => { if (this._forwardElementRef.value) { this._cleanup.push(forwardEvent(event, this._forwardElementRef.value, this.host)); } }); }); } hostDisconnected() { this._cleanup.forEach((fn) => { fn(); }); this._cleanup = []; } } export { EventForwardController };