Files
genieacs/ui/overlay.ts
T
Zaid Humaimidi 4a191afdec feat(ui): redesign UI with Tailwind CSS, CodeMirror 6, and new layout
- Replace all hand-written CSS with Tailwind utility classes
- Upgrade CodeMirror 5 to CodeMirror 6 (scoped @codemirror/* packages)
- Redesign layout with responsive sidebar navigation using JSX/Mithril
- Flatten admin routes (e.g. /admin/presets -> /presets)
- Add "remember me" login option with 2-week persistent cookie
- Add delete confirmation dialogs across admin pages
- Upgrade esbuild from 0.21 to 0.27 and update browser targets
- Add Inter and Roboto Mono variable fonts with subset script
2026-03-12 14:55:10 -07:00

73 lines
2.0 KiB
TypeScript

import m, { Children } from "mithril";
import { dialog, dialogOverlay, icon } from "./tailwind-utility-components.ts";
type OverlayCallback = () => Children;
type CloseCallback = () => boolean;
let overlayCallback: OverlayCallback = null;
let closeCallback: CloseCallback = null;
export function open(
callback: OverlayCallback,
closeCb: CloseCallback = null,
): void {
overlayCallback = callback;
closeCallback = closeCb;
}
export function close(callback: OverlayCallback, force = true): boolean {
if (callback === overlayCallback) {
if (!force && closeCallback && !closeCallback()) return false;
overlayCallback = null;
closeCallback = null;
return true;
}
return false;
}
export function render(): Children {
if (overlayCallback) {
return m(
dialog,
{
as: "div",
class: "fixed z-10 inset-0 overflow-y-auto",
onClose: () => close(overlayCallback, false),
},
m("div.flex items-center justify-center min-h-screen p-4 text-center", [
m(dialogOverlay, {
class: "fixed inset-0 bg-black/50",
}),
m(
"div.relative z-10 bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform max-w-full",
m(
"div.block absolute top-0 right-0 pt-4 pr-4",
m(
"button.bg-white rounded-md text-stone-400 hover:text-stone-500 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-cyan-500",
{
type: "button",
onclick: () => close(overlayCallback, false),
},
m("span.sr-only", "Close"),
m(icon, { name: "close", class: "h-6 w-6" }),
),
),
overlayCallback(),
),
]),
);
}
return null;
}
document.addEventListener("keydown", (e) => {
if (overlayCallback && e.key === "Escape" && close(overlayCallback, false))
m.redraw();
});
window.addEventListener("popstate", () => {
if (close(overlayCallback, false)) m.redraw();
});