import { createUiBindings } from "./ui-runtime.js"; function selectControl(root, selector, attribute, selected) { root.querySelectorAll(selector).forEach((button) => { button.setAttribute( "aria-pressed", String(button.dataset[attribute] === selected), ); }); } function revealColumn(root, name) { const viewport = root.querySelector(".pano-scroll"); const column = root.querySelector(`.pano-col-${name}`); if (!viewport || !column || viewport.scrollWidth <= viewport.clientWidth) return; const offset = column.getBoundingClientRect().left - viewport.getBoundingClientRect().left; viewport.scrollLeft += offset; } function initializeProgression(root, ui) { root.querySelectorAll("[data-progress-choice]").forEach((button) => { ui.listen(button, "click", (event) => { const selected = button.dataset.progressChoice; if (!["see", "review", "move"].includes(selected)) return; root.dataset.flowMotion = String(ui.allowsMotion(event)); root.dataset.progressStage = selected; selectControl(root, "[data-progress-choice]", "progressChoice", selected); }); }); } function setPanoramaFocus(root, selected, event, ui) { root.dataset.flowMotion = String(ui.allowsMotion(event)); root.dataset.panoFocus = selected; selectControl(root, "[data-pano-choice]", "panoChoice", selected); revealColumn(root, selected === "waiting" ? "waiting" : "todo"); } function moveExample(root, event, ui) { const card = root.querySelector("#pano-moving-task"); const next = root.dataset.panoState === "waiting" ? "done" : "waiting"; const destination = root.querySelector(`[data-pano-destination="${next}"]`); if (!card || !destination) return; const animate = ui.allowsMotion(event); card.getAnimations().forEach((animation) => animation.cancel()); const before = card.getBoundingClientRect(); root.dataset.panoState = next; root.dataset.flowMotion = String(animate); root.dataset.panoFocus = "all"; selectControl(root, "[data-pano-choice]", "panoChoice", "all"); destination.prepend(card); updatePanoramaText(root, next === "done"); revealColumn(root, next); if (animate) { const after = card.getBoundingClientRect(); const distance = Math.max(-320, Math.min(320, before.left - after.left)); ui.animate( card, event, [ { transform: `translate(${distance}px, 4px)`, opacity: 0.65 }, { transform: "translate(0, 0)", opacity: 1 }, ], { duration: 220, easing: "cubic-bezier(.2,.7,.2,1)" }, ); } } function updatePanoramaText(root, done) { const values = [ ['[data-pano-count="waiting"]', done ? "1" : "2"], ['[data-pano-count="control"]', done ? "1" : "2"], ['[data-pano-count="done"]', done ? "2" : "1"], ["[data-pano-button-label]", done ? "Reset" : "Move to Done"], [ "[data-pano-task-title]", done ? "Review complete." : "Run ready for review.", ], ["[data-pano-task-badge]", done ? "Reviewed" : "Ready to review"], [ "[data-pano-status]", done ? "Task moved to Done. One task still needs review." : "Task returned to review.", ], ]; values.forEach(([selector, text]) => { const element = root.querySelector(selector); if (element) element.textContent = text; }); const emptyState = root.querySelector("[data-pano-empty]"); if (emptyState) emptyState.hidden = !done; } function initializePanorama(root, ui) { root.querySelectorAll("[data-pano-choice]").forEach((button) => { ui.listen(button, "click", (event) => { const selected = button.dataset.panoChoice; if (["all", "waiting"].includes(selected)) setPanoramaFocus(root, selected, event, ui); }); }); ui.listen(root.querySelector("[data-pano-move]"), "click", (event) => moveExample(root, event, ui), ); } export function initializeFlowScenes(document, env = window) { const ui = createUiBindings(document, env); document .querySelectorAll("[data-progress-stage]") .forEach((root) => initializeProgression(root, ui)); document .querySelectorAll("[data-pano-state]") .forEach((root) => initializePanorama(root, ui)); return () => ui.dispose(); }