/** * An overlay displayed in HTML. */ export class Overlay { private readonly overlay: HTMLDivElement; private readonly submitForm: HTMLFormElement | undefined; private readonly cancelForm: HTMLFormElement | undefined; /** * Constructs a new overlay. * * @param overlay the overlay element to show and hide * @param submitForm the form that invokes `onSubmit` and closes the overlay when submitted * @param cancelForm the form that closes the overlay when submitted * @param onSubmit the callback to invoke when the form is submit */ constructor( overlay: HTMLDivElement, submitForm: HTMLFormElement | undefined, cancelForm: HTMLFormElement | undefined, onSubmit: (() => void) | undefined = undefined ) { this.overlay = overlay; overlay.addEventListener( "mousedown", event => { if (event.target === overlay) this.hide(); } ); document.addEventListener( "keydown", event => { if (event.key === "Escape" && this.isVisible()) this.hide(); } ); this.submitForm = submitForm; submitForm?.addEventListener( "submit", event => { event.preventDefault(); this.hide(); onSubmit?.(); } ); this.cancelForm = cancelForm; cancelForm?.addEventListener( "submit", event => { event.preventDefault(); this.hide(); } ); } /** * Shows the overlay. */ show(): void { this.overlay.style.visibility = "unset"; } /** * Hides the overlay. */ hide(): void { this.overlay.style.visibility = "hidden"; } /** * Returns `true` if and only if this overlay is currently visible. */ isVisible(): boolean { return this.overlay.style.visibility !== "hidden"; } }