65 lines
1.8 KiB
JavaScript
65 lines
1.8 KiB
JavaScript
// components/Modal.js
|
|
import { $html, $watch } from "../sigpro.js";
|
|
import { ui } from "../core/utils.js";
|
|
import { tt } from "../core/i18n.js";
|
|
import { Button } from "./Button.js";
|
|
|
|
/**
|
|
* Modal component
|
|
*
|
|
* daisyUI classes used:
|
|
* - modal, modal-box, modal-action, modal-backdrop
|
|
* - modal-open, modal-middle, modal-top, modal-bottom
|
|
* - text-lg, font-bold, mb-4, py-2
|
|
* - flex, gap-2
|
|
*/
|
|
export const Modal = (props, children) => {
|
|
const { class: className, title, buttons, open, ...rest } = props;
|
|
let dialogElement = null;
|
|
|
|
const handleOpen = () => {
|
|
const isOpen = typeof open === "function" ? open() : open;
|
|
if (!dialogElement) return;
|
|
|
|
if (isOpen) {
|
|
if (!dialogElement.open) dialogElement.showModal();
|
|
} else {
|
|
if (dialogElement.open) dialogElement.close();
|
|
}
|
|
};
|
|
|
|
$watch(() => handleOpen());
|
|
|
|
const close = () => {
|
|
if (typeof open === "function") open(false);
|
|
};
|
|
|
|
return $html("dialog", {
|
|
...rest,
|
|
ref: (el) => {
|
|
dialogElement = el;
|
|
if (el) handleOpen();
|
|
},
|
|
class: ui('modal', className),
|
|
onclose: close,
|
|
oncancel: close
|
|
}, [
|
|
$html("div", { class: "modal-box" }, [
|
|
title ? $html("h3", { class: "text-lg font-bold mb-4" }, () =>
|
|
typeof title === "function" ? title() : title
|
|
) : null,
|
|
$html("div", { class: "py-2" }, [
|
|
typeof children === "function" ? children() : children
|
|
]),
|
|
$html("div", { class: "modal-action" }, [
|
|
$html("form", { method: "dialog", class: "flex gap-2" }, [
|
|
...(Array.isArray(buttons) ? buttons : [buttons]).filter(Boolean),
|
|
Button({ type: "submit" }, tt("close")())
|
|
])
|
|
])
|
|
]),
|
|
$html("form", { method: "dialog", class: "modal-backdrop" }, [
|
|
$html("button", {}, "close")
|
|
])
|
|
]);
|
|
}; |