Lumi/src/web/public/lumi-state-button.js
2026-07-22 10:20:32 +02:00

69 lines
2.2 KiB
JavaScript

(() => {
const buttons = new Set();
const getViews = (button) => Array.from(button.querySelectorAll("[data-state-view]"));
const setState = (button, state, options = {}) => {
if (!button) return;
const requestedState = state || button.dataset.defaultState || "idle";
const availableStates = new Set(getViews(button).map((view) => view.dataset.stateView));
const nextState = availableStates.has(requestedState)
? requestedState
: button.dataset.defaultState || "idle";
const busyState = button.dataset.loadingState || "loading";
const isBusy = nextState === busyState || options.busy === true;
button.dataset.state = nextState;
button.setAttribute("aria-busy", isBusy ? "true" : "false");
getViews(button).forEach((view) => {
const isVisible = view.dataset.stateView === nextState;
view.dataset.stateHidden = isVisible ? "false" : "true";
view.setAttribute("aria-hidden", isVisible ? "false" : "true");
});
if (button.dataset.disableWhileBusy === "true") {
button.disabled = isBusy;
}
};
const reset = (button) => {
setState(button, button?.dataset.defaultState || "idle");
};
const scheduleReset = (button) => {
const delay = Number(button?.dataset.resetDelay || 0);
if (delay > 0) window.setTimeout(() => reset(button), delay);
};
const initButton = (button) => {
if (buttons.has(button)) return;
buttons.add(button);
button.classList.add("lumi-state-btn");
setState(button, button.dataset.state || button.dataset.defaultState || "idle");
};
document.querySelectorAll("[data-lumi-state-button]").forEach(initButton);
document.addEventListener("submit", (event) => {
const submitter = event.submitter;
if (!submitter?.matches?.("[data-lumi-state-button]")) return;
initButton(submitter);
setState(submitter, submitter.dataset.loadingState || "loading", { busy: true });
}, true);
window.LumiStateButton = {
init: initButton,
setState,
reset,
success(button) {
setState(button, button?.dataset.successState || "success");
scheduleReset(button);
},
error(button) {
setState(button, button?.dataset.errorState || "error");
scheduleReset(button);
}
};
})();