@n8d/htwoo-core
Version:
hTWOo is a Fluent Design Framework purely in HTML and CSS
163 lines (117 loc) • 4.37 kB
JavaScript
export class HOODialog {
#launcher;
#dialog;
#dialogType;
#closer;
#options = {
closer: null,
backdropCloser: true,
escCloser: true
};
/** Options for modal dialog */
static options = {
closer: null,
backdropCloser: true,
escCloser: true
}
/**
* Enum of available dialog types
*/
static dialogType = {
DIALOG: 'dialog',
MODAL: 'modal'
}
/**
* Open the dialog
*/
#showDialog = () => {
console.debug('-> Fired showDialog -- ', this.#dialog);
if (this.#dialogType === HOODialog.dialogType.DIALOG) {
this.#dialog.show();
} else if (this.#dialogType === HOODialog.dialogType.MODAL) {
this.#dialog.showModal();
// FIX: Make backdrop click optional
// Capture click on backdrop
this.#dialog.addEventListener('click', this.#backdropClick);
} else {
throw new Error(`Invalid dialog type specified for ${this.#dialog}`);
}
if (this.#closer) {
this.#closer.addEventListener('click', this.#closeDialog);
}
const autofocus = this.#dialog.querySelector('[autofocus]');
if (autofocus) {
console.debug('No Autofocus');
dialogElement.focus();
}
// Capture close on ESC click
this.#dialog.addEventListener('keydown', this.#keyboardClose);
}
#backdropClick = (event) => {
var rect = this.#dialog.getBoundingClientRect();
var isInDialog = (rect.top <= event.clientY && event.clientY <= rect.top + rect.height &&
rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
// console.debug('Event Target', event.target);
// console.debug(
// 'Rect Top', rect.top,'\n',
// 'Rect Height', rect.height,'\n',
// 'Client Top', event.clientY,'\n',
// 'Rect Left', rect.left,'\n',
// 'Rect Width', rect.width,'\n',
// 'Client Left', event.clientX,'\n',
// )
//
// console.debug(
// 'Rect Top', rect.top, event.clientY, rect.top+rect.height,'\n',
// 'Rect left', rect.left, event.clientX, rect.left+rect.width,'\n',
// )
if (!isInDialog && event.target === this.#dialog) {
this.#dialog.close();
}
}
/**
* Close the dialog on keyCode ESC
*/
#keyboardClose = (event) => {
if (event.keyCode === 27) {
this.#dialog.close();
}
}
/**
* Close the dialog used for custom event or close button
*/
#closeDialog = (event) => {
console.debug('closing dialog');
this.#dialog.close();
}
constructor(launcher, dialog, dialogType = HOODialog.dialogType.DIALOG,
options = HOODialog.options) {
console.debug("Register dialog", dialogType);
// query DOM elements
const launchElement = document.querySelector(launcher),
dialogElement = document.querySelector(dialog);
if (!launchElement) {
throw new Error(`Launcher '${launcher}' Element cannot be found`);
}
this.#launcher = launchElement;
if (!dialogElement) {
throw new Error(`Dialog '${dialog}' Element not found`);
}
this.#dialog = dialogElement;
this.#launcher.addEventListener('click', this.#showDialog);
this.#dialogType = dialogType;
options.closer === undefined? this.#options.closer = null : options.closer;
options.backdropCloser === undefined? this.#options.backdropCloser = true : options.backdropCloser;
options.escCloser === undefined? this.#options.escCloser = true : options.escCloser;
this.#options = options;
// in case a close button is defined fo the dialog
if (options.closer !== null) {
const closerElement = dialogElement.querySelector(options.closer);
this.#options.closer = options.closer;
if (closerElement) {
this.#closer = closerElement;
}
}
console.debug('AFTER LAUNCH ::: ', this.#dialogType, this.#launcher, this.#dialog, this.#closer);
}
}