const PANEL_COPY = {
search: {
title: "Search",
description: "Search games, apps, and settings across NebulaOS.",
placeholder: "Search NebulaOS…",
},
notifications: {
title: "Notifications",
description: "System alerts and download updates will appear here.",
},
downloads: {
title: "Downloads",
description: "Active and completed downloads will be listed here.",
},
controller: {
title: "Controller Settings",
description: "Map buttons, adjust dead zones, and test input.",
},
};
export const createGuidePanelOverlay = ({ mountRoot }) => {
let openState = false;
let activePanel = null;
let onClose = null;
let overlay = null;
const renderMarkup = () => {
mountRoot.insertAdjacentHTML(
"beforeend",
`
`,
);
overlay = mountRoot.querySelector("[data-guide-panel-overlay]");
};
const getBodyHtml = (panelId) => {
const copy = PANEL_COPY[panelId];
if (!copy) {
return `
This panel is not available yet.
`;
}
if (panelId === "search") {
return `
Results will appear here. (Placeholder)
`;
}
return `
${copy.title}
${copy.description}
Connected to guide quick actions · stub UI
`;
};
const close = () => {
openState = false;
activePanel = null;
if (overlay) {
overlay.hidden = true;
}
onClose?.();
onClose = null;
};
const bindOverlayEvents = () => {
overlay?.addEventListener("click", (event) => {
if (event.target === overlay) {
close();
}
});
overlay?.querySelector(".guide-panel-close")?.addEventListener("click", () => close());
};
const open = (panelId, options = {}) => {
if (!overlay) {
renderMarkup();
bindOverlayEvents();
}
const copy = PANEL_COPY[panelId] ?? { title: "Panel", description: "" };
overlay.querySelector("[data-panel-title]").textContent = copy.title;
overlay.querySelector("[data-panel-desc]").textContent = copy.description ?? "";
overlay.querySelector("[data-panel-body]").innerHTML = getBodyHtml(panelId);
openState = true;
activePanel = panelId;
onClose = options.onClose ?? null;
overlay.hidden = false;
const closeBtn = overlay.querySelector("[data-guide-panel-close], .guide-panel-close");
closeBtn?.focus({ preventScroll: true });
closeBtn?.classList.add("is-focused");
console.log(`[GuidePanel] Opened: ${panelId}`);
};
const handleAction = (action) => {
if (!openState) {
return false;
}
if (action === "accept") {
close();
return true;
}
if (action === "back" || action === "menu") {
close();
return true;
}
return true;
};
return {
open,
close,
isOpen: () => openState,
getActivePanel: () => activePanel,
handleAction,
};
};