From bbb75a87af00635c2622c7c525c119fa4e7258e3 Mon Sep 17 00:00:00 2001 From: ZDDC Date: Sun, 3 May 2026 22:17:02 -0500 Subject: [PATCH] chore(headers): standardize across all 7 tools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring every tool's header in line with archive's pattern: [logo] [title] [version] [Add Local Directory] [⟳] ............... [◐] [?] ------------- header-left --------------- ----- header-right - Changes per tool: * browse: rename "Select Directory" → "Add Local Directory"; add the red-non-stable wrap to the build label (was missing); add a help panel + bundle shared/help.js. * classifier: rename selectDirectoryBtn → addDirectoryBtn, refreshBtn → refreshHeaderBtn for consistency. Update all JS callers and welcome-screen copy to the new label. * mdedit: same id rename. Move the previously-in-pane refresh button into the header. Stop renaming the dir button to "Directory: " once a folder is loaded — instead use the shared btn--subtle variant to de-emphasize while keeping the standard label. * transmittal: convert non-standard
with spacer/icons containers to
with the canonical header-left/header-right pair. Move the publish split- button into header-left (Transmittal-specific primary action). Remove dead .app-header__spacer/__icons/header-icon-btn CSS now that nothing references those classes. * landing, form: add help-btn + help-panel + bundle shared/help.js. Each panel is tool-specific (project picker docs for landing, schema-driven form docs for form). Cross-cutting: * shared/base.css: promote .btn--subtle from browse/css/tree.css so any tool with an online mode can de-emphasize Add Local Directory consistently. Verified all 7 tools in headless Chromium: header structure correct, build label red on non-stable cuts, help panel opens + closes via button + Esc. --- browse/build.sh | 17 +++++++- browse/css/tree.css | 16 ------- browse/template.html | 87 ++++++++++++++++++++++++++++++++++++-- classifier/js/app.js | 12 +++--- classifier/template.html | 8 ++-- form/build.sh | 1 + form/template.html | 46 ++++++++++++++++++++ landing/build.sh | 1 + landing/template.html | 47 ++++++++++++++++++++ mdedit/js/app.js | 2 +- mdedit/js/events.js | 8 ++-- mdedit/js/file-system.js | 29 +++++++++---- mdedit/js/main.js | 2 +- mdedit/template.html | 8 ++-- shared/base.css | 18 ++++++++ transmittal/css/layout.css | 31 -------------- transmittal/template.html | 45 +++++++++++--------- 17 files changed, 277 insertions(+), 101 deletions(-) diff --git a/browse/build.sh b/browse/build.sh index c492c47..03e7f20 100755 --- a/browse/build.sh +++ b/browse/build.sh @@ -34,6 +34,7 @@ concat_files \ "../shared/zddc.js" \ "../shared/zddc-filter.js" \ "../shared/theme.js" \ + "../shared/help.js" \ "../shared/preview-lib.js" \ "js/init.js" \ "js/loader.js" \ @@ -51,8 +52,13 @@ tool=browse compute_build_label "$tool" "$@" # Replace template placeholders with concatenated CSS/JS + label. +# Non-stable build labels (alpha/beta/dev-dirty) are wrapped in a red +# span — same convention as every other tool (compute_build_label +# sets $is_red=1 for non-stable cuts). Keeps the visual cue +# consistent across tool headers. awk -v css_file="$css_temp" -v js_file="$js_temp" \ - -v build_label="$build_label" -v favicon="$favicon_data_uri" ' + -v build_label="$build_label" -v is_red="$is_red" \ + -v favicon="$favicon_data_uri" ' /\{\{CSS_PLACEHOLDER\}\}/ { while ((getline line < css_file) > 0) print line close(css_file); next @@ -61,8 +67,15 @@ awk -v css_file="$css_temp" -v js_file="$js_temp" \ while ((getline line < js_file) > 0) print line close(js_file); next } + /\{\{BUILD_LABEL\}\}/ { + if (is_red == "1") { + gsub(/\{\{BUILD_LABEL\}\}/, "" build_label "") + } else { + gsub(/\{\{BUILD_LABEL\}\}/, build_label) + } + print; next + } { - gsub(/\{\{BUILD_LABEL\}\}/, build_label) gsub(/\{\{FAVICON\}\}/, favicon) print } diff --git a/browse/css/tree.css b/browse/css/tree.css index f093223..d1c2401 100644 --- a/browse/css/tree.css +++ b/browse/css/tree.css @@ -142,22 +142,6 @@ outline-offset: -1px; } -/* Subtle button variant — used for "Select Directory" when the page - is server-backed (the user usually doesn't need to switch to a - local folder; we keep the option visible but quiet). */ -.btn.btn--subtle { - background: transparent; - color: var(--text-muted); - border-color: var(--border); - box-shadow: none; - font-weight: normal; -} - -.btn.btn--subtle:hover { - color: var(--text); - background: var(--bg-hover, rgba(0,0,0,0.04)); -} - /* Table — folders + files in a tree */ .browse-table { diff --git a/browse/template.html b/browse/template.html index f240265..1ee3c04 100644 --- a/browse/template.html +++ b/browse/template.html @@ -24,8 +24,8 @@ ZDDC Browse {{BUILD_LABEL}}
- - + +
@@ -42,7 +42,7 @@
  • Online — when this page is served by zddc-server, the listing for the current directory loads automatically.
  • -
  • Local — click Select Directory to pick any folder +
  • Local — click Add Local Directory to pick any folder on your computer (Chromium-based browsers).

Once loaded: click a folder to expand it, shift-click @@ -103,6 +103,87 @@

+ + + diff --git a/classifier/js/app.js b/classifier/js/app.js index 4af13a5..dc33ed7 100644 --- a/classifier/js/app.js +++ b/classifier/js/app.js @@ -60,7 +60,7 @@ */ function showBrowserWarning() { const warning = document.getElementById('browserWarning'); - const selectBtn = document.getElementById('selectDirectoryBtn'); + const selectBtn = document.getElementById('addDirectoryBtn'); if (warning) { warning.classList.remove('hidden'); } @@ -80,8 +80,8 @@ mainApp: document.getElementById('mainApp'), // Header buttons - selectDirectoryBtn: document.getElementById('selectDirectoryBtn'), - refreshBtn: document.getElementById('refreshBtn'), + addDirectoryBtn: document.getElementById('addDirectoryBtn'), + refreshHeaderBtn: document.getElementById('refreshHeaderBtn'), saveAllBtn: document.getElementById('saveAllBtn'), cancelAllBtn: document.getElementById('cancelAllBtn'), exportHashesBtn: document.getElementById('exportHashesBtn'), @@ -115,8 +115,8 @@ */ function setupEventListeners() { // Directory selection - app.dom.selectDirectoryBtn.addEventListener('click', handleSelectDirectory); - app.dom.refreshBtn.addEventListener('click', handleRefresh); + app.dom.addDirectoryBtn.addEventListener('click', handleSelectDirectory); + app.dom.refreshHeaderBtn.addEventListener('click', handleRefresh); // Drag and drop on welcome screen setupWelcomeDragDrop(); @@ -278,7 +278,7 @@ await app.modules.scanner.scanDirectory(dirHandle); // Show refresh button now that a directory is loaded - if (app.dom.refreshBtn) { app.dom.refreshBtn.classList.remove('hidden'); } + if (app.dom.refreshHeaderBtn) { app.dom.refreshHeaderBtn.classList.remove('hidden'); } } /** diff --git a/classifier/template.html b/classifier/template.html index c805bb3..2e90273 100644 --- a/classifier/template.html +++ b/classifier/template.html @@ -29,8 +29,8 @@ ZDDC Classifier {{BUILD_LABEL}}
- - + +
@@ -149,7 +149,7 @@
  • Rename one file or all modified files at once
  • -

    Click Select Directory to begin.

    +

    Click Add Local Directory to begin.

    This application works entirely in your browser. No data is transmitted to any server.

    @@ -168,7 +168,7 @@

    Getting Started

      -
    1. Click Select Directory to open a folder containing files to rename.
    2. +
    3. Click Add Local Directory to open a folder containing files to rename.
    4. The folder tree on the left shows all sub-folders. Click a folder to load its files.
    5. Edit cells in the spreadsheet to set the new filename components.
    6. Click Save All (or save individual rows) to rename the files on disk.
    7. diff --git a/form/build.sh b/form/build.sh index 63be63e..49cf4aa 100755 --- a/form/build.sh +++ b/form/build.sh @@ -24,6 +24,7 @@ concat_files \ concat_files \ "../shared/theme.js" \ + "../shared/help.js" \ "js/app.js" \ "js/context.js" \ "js/util.js" \ diff --git a/form/template.html b/form/template.html index c3d8de4..e5b167f 100644 --- a/form/template.html +++ b/form/template.html @@ -27,6 +27,7 @@
      +
      @@ -38,6 +39,51 @@ + + + + + diff --git a/mdedit/js/app.js b/mdedit/js/app.js index 6a3251a..61ba7c3 100644 --- a/mdedit/js/app.js +++ b/mdedit/js/app.js @@ -37,7 +37,7 @@ const SCRATCHPAD_WELCOME = [ 'Use this **Scratchpad** for quick notes. Download it any time with the ⬇', 'button on the Scratchpad row in the file list.', '', - 'Click **Select Directory** above to open a folder of Markdown files,', + 'Click **Add Local Directory** above to open a folder of Markdown files,', 'or just start typing here.', '', ].join('\n'); diff --git a/mdedit/js/events.js b/mdedit/js/events.js index 54ee81a..0112a19 100644 --- a/mdedit/js/events.js +++ b/mdedit/js/events.js @@ -6,14 +6,14 @@ * Set up all event listeners for the application */ function setupEventListeners() { - // Select directory button - const selectDirectoryBtn = document.getElementById('select-directory'); + // Add Local Directory button (was id="select-directory" / "refresh-directory") + const selectDirectoryBtn = document.getElementById('addDirectoryBtn'); if (selectDirectoryBtn) { selectDirectoryBtn.addEventListener('click', openDirectory); } - // Refresh directory button - const refreshDirectoryBtn = document.getElementById('refresh-directory'); + // Refresh button (now in header, was in file-nav pane) + const refreshDirectoryBtn = document.getElementById('refreshHeaderBtn'); if (refreshDirectoryBtn) { refreshDirectoryBtn.addEventListener('click', refreshDirectory); } diff --git a/mdedit/js/file-system.js b/mdedit/js/file-system.js index c83e7e5..0de6094 100644 --- a/mdedit/js/file-system.js +++ b/mdedit/js/file-system.js @@ -171,12 +171,19 @@ async function openDirectory() { * @param {string} directoryName - Name of the selected directory */ function updateDirectoryStatus(directoryName) { - const selectDirectoryBtn = document.getElementById('select-directory'); + // Standardized header pattern (across all ZDDC tools): the button + // keeps the label "Add Local Directory"; de-emphasize it once a + // directory is loaded (the user can still click to pick another) + // by applying the shared btn--subtle variant. The directory name + // is shown in the file-nav pane, not on the button. + const selectDirectoryBtn = document.getElementById('addDirectoryBtn'); if (selectDirectoryBtn) { - selectDirectoryBtn.textContent = `Directory: ${directoryName}`; + selectDirectoryBtn.classList.remove('btn-primary'); + selectDirectoryBtn.classList.add('btn--subtle'); + selectDirectoryBtn.title = `Loaded: ${directoryName} — click to switch`; } - const refreshBtn = document.getElementById('refresh-directory'); + const refreshBtn = document.getElementById('refreshHeaderBtn'); if (refreshBtn) { refreshBtn.classList.remove('hidden'); } @@ -677,8 +684,8 @@ async function loadServerDirectory() { // Only enter server-source mode if the host actually serves JSON directory // listings (zddc-server / Caddy). On a plain static host the probe fails - // and we must leave "Select Directory" visible so the user can still load - // local files. + // and we must leave "Add Local Directory" visible so the user can still + // load local files. try { const resp = await fetch(baseUrl, { headers: { 'Accept': 'application/json' }, cache: 'no-cache' }); if (!resp.ok) return; @@ -703,12 +710,18 @@ async function loadServerDirectory() { entries: {}, }; - // Surface refresh, hide write-only controls. "Select Directory" stays - // visible so the user can switch to a local folder at any time. - const refreshBtn = document.getElementById('refresh-directory'); + // Surface refresh, hide write-only controls. "Add Local Directory" + // stays visible (de-emphasized via btn--subtle) so the user can + // switch to a local folder at any time. + const refreshBtn = document.getElementById('refreshHeaderBtn'); if (refreshBtn) refreshBtn.classList.remove('hidden'); const newFileRootBtn = document.getElementById('new-file-root'); if (newFileRootBtn) newFileRootBtn.classList.add('hidden'); + const addDirBtn = document.getElementById('addDirectoryBtn'); + if (addDirBtn) { + addDirBtn.classList.remove('btn-primary'); + addDirBtn.classList.add('btn--subtle'); + } const stats = await readServerDirectory(baseUrl, fileTree, 0); renderFileTree(); diff --git a/mdedit/js/main.js b/mdedit/js/main.js index 30ce42e..79c5446 100644 --- a/mdedit/js/main.js +++ b/mdedit/js/main.js @@ -32,7 +32,7 @@ document.addEventListener('DOMContentLoaded', function () { * Initialize UI based on File System API availability */ function initializeApiAvailability() { - const selectDirectoryBtn = document.getElementById('select-directory'); + const selectDirectoryBtn = document.getElementById('addDirectoryBtn'); const welcomeHint = document.getElementById('welcome-hint'); const welcomeFirefox = document.getElementById('welcome-firefox'); diff --git a/mdedit/template.html b/mdedit/template.html index 48808fb..63e008e 100644 --- a/mdedit/template.html +++ b/mdedit/template.html @@ -29,7 +29,8 @@ ZDDC Markdown {{BUILD_LABEL}} - + +
      @@ -45,7 +46,6 @@ Files
      -
      @@ -59,7 +59,7 @@
      @@ -103,7 +103,7 @@

      Getting Started

        -
      1. Click Select Directory to open a folder. The file tree on the left will populate with all files in that folder.
      2. +
      3. Click Add Local Directory to open a folder. The file tree on the left will populate with all files in that folder.
      4. Click any Markdown file (.md) in the tree to open it in the editor.
      5. Use the Scratchpad entry (always visible at the top of the tree) for temporary notes without saving to disk.
      diff --git a/shared/base.css b/shared/base.css index a3ac5b7..5c96dd7 100644 --- a/shared/base.css +++ b/shared/base.css @@ -210,6 +210,24 @@ a:hover { background: var(--bg-secondary); } +/* Subdued / de-emphasized variant. + Used on the "Add Local Directory" button when a tool is operating + in server (online) mode — the local-dir affordance is still + available but visually quieter, since the typical user already + has the directory loaded from the server. */ +.btn.btn--subtle { + background: transparent; + color: var(--text-muted); + border-color: var(--border); + box-shadow: none; + font-weight: normal; +} + +.btn.btn--subtle:not(:disabled):hover { + color: var(--text); + background: var(--bg-secondary); +} + .btn-success { background: var(--success); color: var(--text-light); diff --git a/transmittal/css/layout.css b/transmittal/css/layout.css index e2696a7..8100fe3 100644 --- a/transmittal/css/layout.css +++ b/transmittal/css/layout.css @@ -372,37 +372,6 @@ box-sizing: content-box; } - .app-header__spacer { - flex: 1; - } - - .app-header__icons { - display: flex; - align-items: center; - gap: 0.5rem; - } - - .header-icon-btn { - display: inline-flex; - align-items: center; - justify-content: center; - width: 28px; - height: 28px; - border-radius: 0.25rem; - border: none; - background: transparent; - color: var(--text-muted); - cursor: pointer; - padding: 0; - text-decoration: none; - transition: color 0.15s, background 0.15s; - } - - .header-icon-btn:hover { - color: var(--primary-hover); - background: var(--primary-light); - } - /* ── Fixed footer status bar at viewport bottom ───────── */ .page-footer { position: fixed; diff --git a/transmittal/template.html b/transmittal/template.html index fdeeb51..17d2153 100644 --- a/transmittal/template.html +++ b/transmittal/template.html @@ -27,31 +27,34 @@ conventions at https://codeberg.org/VARASYS/ZDDC#file-naming-convention. -
      -