Files
maxwarden/ui/modals.go
2025-03-07 14:13:25 -05:00

115 lines
1.9 KiB
Go

package ui
import (
. "maragu.dev/gomponents"
. "maragu.dev/gomponents/html"
)
// DIALOG / MODAL
func ModalActuator(id string, contents Node) Node {
return Span(
InlineScriptf(`
let act = me();
let dialog = me("#%s_dialog");
act.on("click", () => { dialog.showModal(); });
`, id),
contents,
)
}
func ModalCloser() Node {
return Class("modal-close-el")
}
func Modal(id string, header Node, body Node, closeElements []Node) Node {
return Dialog(
ID(id+"_dialog"),
InlineStyle(`
$me {
top: 50%;
left: 50%;
translate: -50% -50%;
z-index: 10;
background: $color(white);
box-shadow: var(--shadow-md);
font-size: var(--text-sm);
}
$me::backdrop {
background: $color(black/30);
}
`),
// Header
Div(
InlineStyle(`
$me {
display: flex;
align-items: center;
justify-content: space-between;
padding: $6 $8 $1 $8;
font-size: var(--text-xl);
font-weight: var(--font-weight-bold);
}
`),
IfElse(header == nil,
InlineStyle(`
$me {
flex-direction: row-reverse;
}
`),
header,
),
Div(
Class("modal-close-el"),
InlineStyle("$me { cursor: pointer; }"),
Icon(ICON_X_DIALOG_CLOSE, 24),
),
),
//Modal contents
Div(
ID(id), // we use the passed id here so that swapping the content is easier
InlineStyle(`
$me {
padding: $3 $8 $8 $8;
color: $color(neutral-700);
}
`),
body,
),
// footer
If(len(closeElements) > 0,
Div(
InlineStyle(`
$me {
padding: $3 $8 $3 $8;
display: flex;
flex-direction: row-reverse;
gap: $2;
}
`),
Group(closeElements),
),
),
InlineScript(`
let dialog = me();
let close_buttons = any(".modal-close-el", me())
dialog.on("click", (ev) => {
if (ev.target === dialog) {
dialog.close();
}
});
close_buttons.on("click", () => { dialog.close(); });
`),
)
}