From ef00fe3adb9acfdc590fcade3ba60a9f5d690f30 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Sun, 27 Sep 2026 02:04:41 +0800 Subject: [PATCH 1/2] fix: restore hidden group headings when navigating to a jump link After sorting by a column, or while a search hid a group, category page group headings stayed hidden, so the header's jump links (and any use-case heading link) pointed at a hidden element and did nothing. Co-Authored-By: Claude --- website/static/main.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/website/static/main.js b/website/static/main.js index 919aefd4..30871c9f 100644 --- a/website/static/main.js +++ b/website/static/main.js @@ -364,6 +364,24 @@ sortHeaders.forEach(function (th) { }); }); +// Group headings are hidden while sorted flat or filtered out by search, so a link to one must restore them first +document.addEventListener("click", function (e) { + const link = e.target.closest('a[href*="#"]'); + if (!link || link.pathname !== location.pathname) return; + const heading = document.getElementById(decodeURIComponent(link.hash.slice(1))); + const groupRow = heading ? heading.closest(".group-row") : null; + if (!groupRow) return; + if (activeSort.col !== "editorial") { + activeSort = defaultSort; + sortRows(); + updateSortIndicators(); + } + if (groupRow.hidden && searchInput) { + searchInput.value = ""; + applyFilters(); + } +}); + if (searchInput) { let searchTimer; searchInput.addEventListener("input", function () { From 77b1b70df5d88e1098a10cc23f3b8e9a33ab0efa Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Sun, 27 Sep 2026 02:04:57 +0800 Subject: [PATCH 2/2] fix: hide use-case and page tags that repeat the group heading On section and subcategory pages, every row repeated its use case and current page as tags (and as the label under the name on phones), right under a heading that already said the same thing. They are now hidden in editorial order and shown again when a column sort flattens the groups. Co-Authored-By: Claude --- website/static/main.js | 1 + website/static/style.css | 5 +++++ website/templates/category.html | 9 ++++++--- website/tests/test_build.py | 2 ++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/website/static/main.js b/website/static/main.js index 30871c9f..93eac711 100644 --- a/website/static/main.js +++ b/website/static/main.js @@ -288,6 +288,7 @@ function sortRows() { const sortHeaders = document.querySelectorAll("th[data-sort]"); function updateSortIndicators() { + if (table) table.classList.toggle("sorted", activeSort.col !== "editorial"); sortHeaders.forEach(function (th) { th.classList.remove("sort-asc", "sort-desc"); if (th.dataset.sort === activeSort.col) { diff --git a/website/static/style.css b/website/static/style.css index 4e067c06..12ff6cdf 100644 --- a/website/static/style.css +++ b/website/static/style.css @@ -868,6 +868,11 @@ kbd { text-underline-offset: 0.2em; } +/* main.js adds .sorted once a column sort flattens the groups */ +.table:not(.sorted) .repeats-heading { + display: none; +} + .group-count { font-family: var(--font-body); font-size: var(--text-sm); diff --git a/website/templates/category.html b/website/templates/category.html index 7528da00..e8d05860 100644 --- a/website/templates/category.html +++ b/website/templates/category.html @@ -76,6 +76,9 @@ {% endblock %} {% block content %} {% macro entry_rows(entry, index) %} + {# On section and subcategory pages the group heading already names the row's use case #} + {% set grouped_page = entry_groups and not group_categories %} + {% set section_path = "/categories/" ~ parent_category.slug ~ "/" if parent_category else current_path %} {{ entry.name }} - {% if entry.subcategories %}{{ entry.subcategories[0].name }}{% else %}{{ category.name }}{% endif %} @@ -123,13 +126,13 @@ {% for subcat in entry.subcategories %} - + {{ subcat.name }} {% endfor %} {% for cat in entry.categories %} {{ cat }} diff --git a/website/tests/test_build.py b/website/tests/test_build.py index a322f1c2..78495fa8 100644 --- a/website/tests/test_build.py +++ b/website/tests/test_build.py @@ -991,6 +991,7 @@ class TestBuild: assert positions == sorted(positions) assert 'Small' in html assert 'Small' in html + assert '' in html assert '' in html subcategory_html = (site / "widgets" / "small" / "index.html").read_text(encoding="utf-8") @@ -1033,6 +1034,7 @@ class TestBuild: dl_heading = html.index('Deep Learning') assert ml_heading < html.index(">ml1dl1ml1