From 0b693679013978d3abe48b132966ba3cdddab941 Mon Sep 17 00:00:00 2001 From: ZDDC Date: Sun, 10 May 2026 19:22:03 -0500 Subject: [PATCH] feat(browse): sort dropdown in the tree toolbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tree's underlying setSort API was carried forward from the old table-with-clickable-headers UI but had no widget driving it after the layout reshape. Adds an explicit dropdown in the toolbar: Sort: [Name (A→Z) ▾] [Name (Z→A) ] [Modified (new→old) ] [Modified (old→new) ] [Size (large→small) ] [Size (small→large) ] [Type (A→Z) ] Implementation: - new tree.setSortExplicit(key, dir) — sets both axes in one call (the existing tree.setSort toggles direction on repeat-clicks, which is the right semantics for column-header clicks but wrong for an explicit dropdown). - events.js parses the dropdown value as ":" and calls setSortExplicit. The dropdown is initialised to reflect the current sort state on mount. Co-Authored-By: Claude Opus 4.7 (1M context) --- browse/css/tree.css | 30 ++++++++++++++++++++++++++++++ browse/js/events.js | 14 ++++++++++++++ browse/js/tree.js | 7 +++++++ browse/template.html | 12 ++++++++++++ zddc/internal/handler/tables.html | 14 +++++++------- 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/browse/css/tree.css b/browse/css/tree.css index 7944993..b2350c1 100644 --- a/browse/css/tree.css +++ b/browse/css/tree.css @@ -476,3 +476,33 @@ html, body { .toc-level-4 a { padding-left: 2.7rem; color: var(--text-muted); } .toc-level-5 a { padding-left: 3.35rem; color: var(--text-muted); font-size: 0.8rem; } .toc-level-6 a { padding-left: 4rem; color: var(--text-muted); font-size: 0.8rem; } + +/* ── Sort control ────────────────────────────────────────────────────────── */ +.sort-control { + display: inline-flex; + align-items: center; + gap: 0.35rem; + font-size: 0.8rem; + color: var(--text-muted); + white-space: nowrap; +} + +.sort-control__label { + user-select: none; +} + +.sort-control__select { + font-family: var(--font); + font-size: 0.8rem; + padding: 0.2rem 0.4rem; + border: 1px solid var(--border); + border-radius: var(--radius); + background: var(--bg); + color: var(--text); + cursor: pointer; +} + +.sort-control__select:focus { + outline: 2px solid var(--primary); + outline-offset: -1px; +} diff --git a/browse/js/events.js b/browse/js/events.js index 7f8abaa..23d4894 100644 --- a/browse/js/events.js +++ b/browse/js/events.js @@ -122,6 +122,20 @@ var refresh = document.getElementById('refreshHeaderBtn'); if (refresh) refresh.addEventListener('click', refreshListing); + // Sort dropdown — change → tree re-renders with the new sort. + // Format of option value: ":". Defaults match + // state.sort initial values (name:asc). + var sortSel = document.getElementById('sortBy'); + if (sortSel) { + sortSel.value = state.sort.key + ':' + (state.sort.dir > 0 ? 'asc' : 'desc'); + sortSel.addEventListener('change', function () { + var parts = sortSel.value.split(':'); + var key = parts[0]; + var dir = parts[1] === 'desc' ? -1 : 1; + tree.setSortExplicit(key, dir); + }); + } + // View-mode toggle (Browse vs Grid) var btnBrowse = document.getElementById('viewModeBrowse'); var btnGrid = document.getElementById('viewModeGrid'); diff --git a/browse/js/tree.js b/browse/js/tree.js index 4d1ae69..a9f902a 100644 --- a/browse/js/tree.js +++ b/browse/js/tree.js @@ -513,6 +513,13 @@ } render(); }, + // Set both key and direction explicitly. dir: 1 (asc) or -1 (desc). + // Used by the toolbar's sort dropdown. + setSortExplicit: function (key, dir) { + state.sort.key = key; + state.sort.dir = (dir === -1 ? -1 : 1); + render(); + }, pathFor: pathFor }; })(); diff --git a/browse/template.html b/browse/template.html index de8e651..fb6804b 100644 --- a/browse/template.html +++ b/browse/template.html @@ -59,6 +59,18 @@ + diff --git a/zddc/internal/handler/tables.html b/zddc/internal/handler/tables.html index 89cf7f7..802fba4 100644 --- a/zddc/internal/handler/tables.html +++ b/zddc/internal/handler/tables.html @@ -53,9 +53,9 @@ /* The [data-theme="light"] selector locks light mode regardless of OS pref. */ @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { - --primary: #4a90c4; - --primary-hover: #5ba3d9; - --primary-active: #6ab5e8; + --primary: #5fa8e0; + --primary-hover: #74b6e6; + --primary-active: #88c4ec; --primary-light: #1a3550; --bg: #1e1e1e; @@ -74,9 +74,9 @@ /* Manual dark override — wins over media query */ [data-theme="dark"] { - --primary: #4a90c4; - --primary-hover: #5ba3d9; - --primary-active: #6ab5e8; + --primary: #5fa8e0; + --primary-hover: #74b6e6; + --primary-active: #88c4ec; --primary-light: #1a3550; --bg: #1e1e1e; @@ -1155,7 +1155,7 @@ body.help-open .app-header {
ZDDC Table - v0.0.17-beta · 2026-05-11 · brass-dolphin-ivory + v0.0.17-alpha · 2026-05-11 00:21:36 · 89d96b7-dirty