From 43345c21d2b28d3e821f190685d02208e3fd6057 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Sat, 21 Dec 2024 17:41:11 +0100 Subject: [PATCH] tut_spa: improve code editor tabs style & fix code loading --- tutorial/justfile | 4 ++ .../resources_singlepage/code_editor.js | 49 +++++++---------- .../resources_singlepage/style.css | 55 ++++++++++++------- 3 files changed, 58 insertions(+), 50 deletions(-) diff --git a/tutorial/justfile b/tutorial/justfile index 8d079dc8..9589856a 100644 --- a/tutorial/justfile +++ b/tutorial/justfile @@ -15,6 +15,10 @@ gpt_files_content: tutorial-json_toc: python scripts/convert_toc.py + +tutorial_prepare: tutorial-json_toc + cd single_page_book_app && npm install + tutorial_book: cd jbook && rm -rf _build && export PYTHONPATH=$(pwd)/sphinx_ext_imgui && jupyter-book build . diff --git a/tutorial/single_page_book_app/resources_singlepage/code_editor.js b/tutorial/single_page_book_app/resources_singlepage/code_editor.js index 147bcbe9..8e951645 100644 --- a/tutorial/single_page_book_app/resources_singlepage/code_editor.js +++ b/tutorial/single_page_book_app/resources_singlepage/code_editor.js @@ -18,25 +18,10 @@ async function _processCodesIncludeInMarkdown(mdText, baseUrlPath) { if (line.trim().startsWith("```{codes_include}")) { const match = line.match(/```{codes_include}\s+(.*)/); if (match) { - console.log("Found codes_include directive:", match[1]); // Log matched directive + // console.log("Found codes_include directive:", match[1]); // Log matched directive const baseName = match[1].trim(); // Generate HTML as a string -// const tabsHtml = ` -//
-//
-// -// -//
-//
-//
-//
-//
-// -//
-//
`; const tabsHtml = `
@@ -52,9 +37,7 @@ async function _processCodesIncludeInMarkdown(mdText, baseUrlPath) {
`; - - - console.log("Generated HTML for tabs:", tabsHtml); // Debug log + // console.log("Generated HTML for tabs:", tabsHtml); // Debug log processedLines.push(tabsHtml); } insideCodesIncludeBlock = true; @@ -68,31 +51,37 @@ async function _processCodesIncludeInMarkdown(mdText, baseUrlPath) { return processedLines.join("\n"); } + async function _initializeCodeMirrorEditors(baseUrlPath) { const containers = document.querySelectorAll(".code-editor-tab-container"); - console.log("Found Code Editor Containers:", containers.length); // Debug log + // console.log("Found Code Editor Containers:", containers.length); // Debug log for (const container of containers) { const tabPanes = container.querySelectorAll(".code-editor-tab-pane"); - console.log("Found Tab Panes:", tabPanes.length); // Debug log + // console.log("Found Tab Panes:", tabPanes.length); // Debug log for (const tabPane of tabPanes) { const filePath = tabPane.dataset.file; const language = tabPane.dataset.language.toLowerCase(); - console.log(`Initializing CodeMirror for file: ${filePath}, language: ${language}`); // Debug log + // console.log(`Initializing CodeMirror for file: ${filePath}, language: ${language}`); // Debug log try { - const fileResponse = await fetch(`${baseUrlPath}${filePath}`); + // Correctly handle baseUrlPath and filePath to avoid duplication + // Relative path; combine with baseUrlPath + let fullPath = new URL(filePath, `${window.location.origin}/${baseUrlPath}/`).toString(); + // console.log(`Full Path for Fetch: ${fullPath}`); // Debug log + + const fileResponse = await fetch(fullPath); if (!fileResponse.ok) { - console.warn(`File not found: ${baseUrlPath}${filePath}`); + console.warn(`File not found: ${fullPath}`); continue; } const codeContent = await fileResponse.text(); - console.log(`Fetched Code Content for ${filePath}:\n`, codeContent); // Debug log + // console.log(`Fetched Code Content for ${filePath}:\n`, codeContent); // Debug log const cmPlaceholder = tabPane.querySelector(".codemirror-placeholder"); @@ -129,16 +118,17 @@ async function _initializeCodeMirrorEditors(baseUrlPath) { _setupCodeEditorTabs(containers); // Ensure tab setup is called } + function _setupCodeEditorTabs(containers) { containers.forEach((container) => { const buttons = container.querySelectorAll(".code-editor-tab-button"); const panes = container.querySelectorAll(".code-editor-tab-pane"); buttons.forEach((button) => { - console.log(`Attaching click event to button: ${button.dataset.tab}`); // Debugging log + // console.log(`Attaching click event to button: ${button.dataset.tab}`); // Debugging log button.addEventListener("click", () => { const targetTab = button.dataset.tab; - console.log(`Tab clicked: ${targetTab}`); // Debugging log + // console.log(`Tab clicked: ${targetTab}`); // Debugging log // Deactivate all buttons and panes buttons.forEach((btn) => btn.classList.remove("active")); @@ -191,12 +181,13 @@ export async function prepareCodeEditors(mdText, baseUrlPath) { const renderedHtml = marked(processedMdText); // Debug log: Final rendered HTML - console.log("Final Rendered HTML:", renderedHtml); + // console.log("Final Rendered HTML:", renderedHtml); // Update the content area with the rendered HTML const contentArea = document.getElementById("content-area"); contentArea.innerHTML = renderedHtml; // Initialize CodeMirror editors for the placeholders - await _initializeCodeMirrorEditors(baseUrlPath); + //await _initializeCodeMirrorEditors(baseUrlPath); + await _initializeCodeMirrorEditors("jbook"); } diff --git a/tutorial/single_page_book_app/resources_singlepage/style.css b/tutorial/single_page_book_app/resources_singlepage/style.css index 921c0aa7..116c4d56 100644 --- a/tutorial/single_page_book_app/resources_singlepage/style.css +++ b/tutorial/single_page_book_app/resources_singlepage/style.css @@ -248,60 +248,73 @@ body { /* ========================== Code Editor Tabs ========================== */ + .code-editor-tab-container { - border: 1px solid #ccc; + border: 1px solid #007bff; /* Blue border for the container */ border-radius: 4px; overflow: hidden; margin-bottom: 1rem; - background-color: #f9f9f9; + background-color: #ffffff; } .code-editor-tab-buttons { display: flex; - background-color: #f9f9f9; + justify-content: flex-start; /* Align tabs to the left */ + padding: 0.2rem; /* Small padding around tabs */ + background-color: #f9f9f9; /* Light gray for the tab bar */ border-bottom: 1px solid #ccc; + gap: 0.2rem; /* Add small gap between tabs */ } .code-editor-tab-button { - flex: 1; - padding: 0.5rem; - text-align: center; - background-color: #e9ecef; + padding: 0.5rem 1rem; /* Adjust padding for a compact look */ border: none; + border-radius: 4px 4px 0 0; /* Rounded top corners */ + background-color: #e9ecef; /* Light gray background for inactive tabs */ cursor: pointer; - font-size: 1rem; + font-size: 0.9rem; font-weight: bold; + color: #333; /* Neutral dark text for inactive tabs */ + transition: background-color 0.3s, color 0.3s; } .code-editor-tab-button.active { + background-color: #007bff; /* Blue background for active tab */ + color: white; /* White text for active tab */ font-weight: bold; - background-color: #007bff; - color: white; - border-bottom: 2px solid white; + border-bottom: 2px solid #ffffff; /* Seamless transition to the content area */ } .code-editor-tab-button:hover { - background-color: #0056b3; + background-color: #0056b3; /* Darker blue on hover */ color: white; } .code-editor-tab-content { - padding: 0; - background-color: white; + padding: 1rem; + background-color: #ffffff; /* White background for content area */ + border-top: none; } .code-editor-tab-pane { - display: none; /* All panes are hidden by default */ - padding: 1rem; + display: block; + animation: fadeIn 0.2s ease-in; /* Smooth fade-in animation for content */ } -.code-editor-tab-pane:not(.hidden) { - display: block; /* Only the active pane is shown */ +.code-editor-tab-pane.hidden { + display: none; } -.code-editor-tab-button.active { - background-color: #007bff; - color: white; +/* Subtle animation for tab switching */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(5px); + } + to { + opacity: 1; + transform: translateY(0); + } } /* ==========================