105 lines
3.2 KiB
TypeScript
Raw Normal View History

2023-01-11 23:44:35 +01:00
/* @refresh reload */
import { Dialog, DialogDescription, DialogPanel, DialogTitle } from "solid-headless";
import { Component, createEffect, createSignal, JSX } from "solid-js";
2023-01-11 23:44:35 +01:00
import { Button } from "./button";
import { Portal } from "solid-js/web";
import { getElementById } from "../utils/dom";
2023-01-11 23:44:35 +01:00
interface MyDialog extends TitleProps {
description?: string,
button?: JSX.Element,
acceptButtonName?: string,
2023-01-11 23:44:35 +01:00
acceptButtonId?: string,
cancelButtonName?: string,
2023-01-11 23:44:35 +01:00
callback?: () => void,
buttonClass?: string,
2023-01-11 23:44:35 +01:00
buttonTitle?: string | null,
}
const MyDialog: Component<MyDialog> = (
2023-01-11 23:44:35 +01:00
{
title,
description,
button,
acceptButtonName = "Ok",
cancelButtonName = "Cancel",
children,
callback,
className,
buttonClass,
2023-01-11 23:44:35 +01:00
buttonTitle,
acceptButtonId,
}) => {
2023-01-11 23:44:35 +01:00
const [isOpen, setIsOpen] = createSignal(false);
function callbackAndClose(): void {
if (callback) {
callback();
}
setIsOpen(false);
}
function setupKeyPress(): () => void {
let isMounted = true;
/**
* Pressing "Enter" when the modal is open, will click the accept button
* @param e KeyboardEvent of keypress
*/
function click(e: KeyboardEvent): void {
if (isMounted && e.key === "Enter" && acceptButtonId) {
getElementById<HTMLButtonElement>(acceptButtonId)?.click();
2023-01-11 23:44:35 +01:00
}
}
if (isOpen()) {
const id = "cl-6"
const el = getElementById(id);
el?.addEventListener("keypress", click);
2023-01-11 23:44:35 +01:00
return () => {
el?.removeEventListener("keypress", click);
2023-01-11 23:44:35 +01:00
isMounted = false;
}
}
else return () => undefined;
2023-01-11 23:44:35 +01:00
}
createEffect(setupKeyPress, isOpen());
return (
<div class={ "w-fit h-fit" }>
<button onClick={ () => setIsOpen(true) } class={ buttonClass } title={ buttonTitle ?? undefined }>
2023-01-11 23:44:35 +01:00
{ button }
</button>
<Portal>
<Dialog isOpen={ isOpen() } onClose={ () => setIsOpen(false) }
class={ `fixed inset-0 flex-row-center justify-center z-50 overflow-auto text-white ${ className }` }>
<div class={ "fixed inset-0 bg-black/40" /*Backdrop*/ } aria-hidden={ true } />
<DialogPanel class={ "w-fit relative bg-default-bg border-rounded border-gray-500 p-2" }>
<DialogTitle class={ "border-b" }>{ title }</DialogTitle>
<DialogDescription class={ "mb-4 mt-1" }>{ description }</DialogDescription>
{ children }
<div class={ "my-3" }>
<Button onClick={ callbackAndClose } className={ "h-10 mr-2" }
id={ acceptButtonId }>{ acceptButtonName }</Button>
<Button onClick={ () => setIsOpen(false) }
className={ "h-10" }>{ cancelButtonName }</Button>
</div>
</DialogPanel>
</Dialog>
</Portal>
</div>
);
}
export default MyDialog;