import "./ui_template_overlay.css"; import { t } from "./ui_template_locale"; const TITLE_OVERLAY_STATE_KEY = "frd_workflow_title_overlay_open"; const PROGRESS_OVERLAY_STATE_KEY = "frd_workflow_progress_overlay_open"; export interface WorkflowOverlayOptions { title: string; progressContent: HTMLElement; optionsContent?: HTMLElement; showTitlePanel?: boolean; onOptionsOpenChange?: (isOpen: boolean) => void; } export interface WorkflowOverlayHandle { root: HTMLElement; setTitleOpen: (isOpen: boolean) => void; setProgressOpen: (isOpen: boolean) => void; } function readOpenState(key: string): boolean { return sessionStorage.getItem(key) !== "false"; } function createPanel( variant: "title" | "progress", titleText: string, body: HTMLElement, storageKey: string, onOpenChange?: (isOpen: boolean) => void, ): { root: HTMLElement; setOpen: (isOpen: boolean) => void } { const root = document.createElement("aside"); root.className = `ui-workflow-overlay__panel ui-workflow-overlay__panel--${variant}`; // title 패널은 사이드바 도킹형 — 토글이 패널 우측 가장자리 세로 중앙 핸들로 나감 const isSidebar = variant === "title"; const header = document.createElement("div"); header.className = "ui-workflow-overlay__header"; const title = document.createElement("h2"); title.className = "ui-workflow-overlay__title"; title.textContent = titleText; const toggle = document.createElement("button"); toggle.type = "button"; toggle.className = isSidebar ? "ui-workflow-overlay__handle" : "ui-workflow-overlay__toggle"; if (isSidebar) { header.append(title); root.append(header, toggle); } else { header.append(title, toggle); root.append(header); } if (body.childElementCount > 0) { body.classList.add("ui-workflow-overlay__body"); root.append(body); } function setOpen(isOpen: boolean): void { root.classList.toggle("is-collapsed", !isOpen); toggle.textContent = isSidebar ? (isOpen ? "◀" : "▶") : isOpen ? "−" : "+"; toggle.title = t(isOpen ? "Workflow_Overlay_Collapse" : "Workflow_Overlay_Expand"); toggle.setAttribute("aria-label", toggle.title); toggle.setAttribute("aria-expanded", String(isOpen)); sessionStorage.setItem(storageKey, String(isOpen)); onOpenChange?.(isOpen); } function toggleOpen(): void { setOpen(root.classList.contains("is-collapsed")); } title.tabIndex = 0; title.setAttribute("role", "button"); title.addEventListener("click", toggleOpen); title.addEventListener("keydown", (event) => { if (event.key === "Enter" || event.key === " ") { event.preventDefault(); toggleOpen(); } }); toggle.addEventListener("click", toggleOpen); setOpen(readOpenState(storageKey)); return { root, setOpen }; } export function createWorkflowOverlays(options: WorkflowOverlayOptions): WorkflowOverlayHandle { const root = document.createElement("div"); root.className = "ui-workflow-overlay"; const progressBody = document.createElement("div"); progressBody.append(options.progressContent); const progressPanel = createPanel( "progress", t("Workflow_Progress_Title"), progressBody, PROGRESS_OVERLAY_STATE_KEY, ); let setTitleOpen = (_isOpen: boolean): void => {}; if (options.showTitlePanel !== false) { const titleBody = document.createElement("div"); if (options.optionsContent) titleBody.append(options.optionsContent); const titlePanel = createPanel( "title", options.title, titleBody, TITLE_OVERLAY_STATE_KEY, options.onOptionsOpenChange, ); root.append(titlePanel.root); setTitleOpen = titlePanel.setOpen; } root.append(progressPanel.root); return { root, setTitleOpen, setProgressOpen: progressPanel.setOpen, }; }