minesweeper/src/main/js/UI.ts

88 lines
2.1 KiB
TypeScript

import {blurActiveElement} from "./Common";
/**
* An overlay displayed in HTML.
*/
export class Overlay {
private readonly overlay: HTMLDivElement;
private readonly submitForm: HTMLFormElement | null;
private readonly cancelForm: HTMLFormElement | null;
/**
* 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 | null,
cancelForm: HTMLFormElement | null,
onSubmit: (() => void) | null = null
) {
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.classList.remove("hidden");
}
/**
* Hides the overlay.
*/
hide(): void {
this.overlay.classList.add("hidden");
blurActiveElement();
}
/**
* Returns `true` if and only if this overlay is currently visible.
*/
isVisible(): boolean {
return this.overlay.classList.contains("hidden");
}
}