app/menus.mjs (50 lines of code) (raw):
import { _, __ } from "util";
/* global tippy */
export function initOptionsMenu(
$container,
$optionsTemplate,
valueGetter,
valueSetter,
) {
const $button = _($container, "button");
tippy($button, {
trigger: "click",
interactive: true,
arrow: false,
placement: "bottom",
offset: [0, 2],
allowHTML: true,
content: () => {
const $content = $optionsTemplate.cloneNode(true);
$content.id = "";
$content.classList.add("options-menu");
$content.classList.remove("hidden");
return $content.outerHTML;
},
onShow(instance) {
for (const $li of __(instance.popper, ".options-menu li")) {
$li.classList.remove("selected");
}
const value = valueGetter();
_(
instance.popper,
`.options-menu li[data-value="${value}"]`,
)?.classList.add("selected");
},
onShown(instance) {
if (!instance.popper.dataset.initialised) {
instance.popper.addEventListener("click", (event) => {
event.preventDefault();
event.stopPropagation();
instance.hide();
valueSetter(event.target.dataset.value, event.target.textContent);
});
instance.popper.dataset.initialised = "1";
}
},
});
$button.addEventListener("click", (event) => {
event.preventDefault();
event.stopPropagation();
});
}