diff --git a/src/app.js b/src/app.js index 71903f7..22a3e7d 100644 --- a/src/app.js +++ b/src/app.js @@ -2486,6 +2486,19 @@ pedZoomIn.addEventListener("click", () => pedZoomBy(0.2)); pedZoomOut.addEventListener("click", () => pedZoomBy(-0.2)); pedZoomReset.addEventListener("click", () => { pedZoom = 1; applyPedZoom(); }); + + // ---- collapse / expand all ---- + const pedFoldAll = document.getElementById("ped-foldall"); + function pedSetAll(collapsed) { + pedTree.querySelectorAll("li").forEach((li) => { + if (!li.querySelector(":scope > ul")) return; // no ancestors to fold + li.classList.toggle("collapsed", collapsed); + const t = li.querySelector(":scope > .ped-card > .ped-toggle"); + if (t) t.textContent = collapsed ? "+" : "−"; + }); + pedFoldAll.textContent = collapsed ? "Expand all" : "Collapse all"; + } + pedFoldAll.addEventListener("click", () => pedSetAll(pedFoldAll.textContent[0] === "C")); // Trackpad/desktop: ctrl or ⌘ + wheel zooms instead of scrolling the page. pedTree.addEventListener("wheel", (e) => { if (!e.ctrlKey && !e.metaKey) return; @@ -2729,6 +2742,7 @@ ul.className = "ped-tree-h"; ul.append(root); pedTree.append(ul); + if (pedFoldAll) pedFoldAll.textContent = "Collapse all"; // fresh tree starts partly open } // Highlight (or unhighlight) every card that is the same dog as `key`. diff --git a/src/changelog.json b/src/changelog.json index 3c1cf1a..e282661 100644 --- a/src/changelog.json +++ b/src/changelog.json @@ -1,4 +1,5 @@ [ + { "date": "2026-07-26", "text": "Added a Collapse all / Expand all toggle to the pedigree, to fold the whole tree down to your dog or open every branch at once" }, { "date": "2026-07-26", "text": "The pedigree is now zoomable — use the +/− buttons, ⌘/Ctrl-scroll, or pinch on a phone — to fit a wide tree on screen or zoom in for detail; your zoom level is remembered" }, { "date": "2026-07-26", "text": "In the pedigree, a dog that fills more than one spot (pedigree collapse, common in a breed's older lines) now carries a ×N badge — tap it to highlight every place that dog appears in the tree" }, { "date": "2026-07-26", "text": "The pedigree now reads top-down like a family tree — your dog on top with its sire and dam branching below — showing three generations at a glance, with each dog expandable to trace the line further back" }, diff --git a/src/index.html b/src/index.html index 9ccd3c7..eeafed2 100644 --- a/src/index.html +++ b/src/index.html @@ -280,10 +280,13 @@

🌳 Pedigree

-
- - - +
+ +
+ + + +
diff --git a/src/style.css b/src/style.css index 1a0b8ad..3f6d1f0 100644 --- a/src/style.css +++ b/src/style.css @@ -1065,9 +1065,17 @@ section.collapsed > :not(h2) { display: none; } gap: 10px; padding: 12px 4px 8px; } +.pedigree-header { flex-wrap: wrap; } .pedigree-header h1 { font-size: 1.4rem; } -.ped-zoom { +.ped-controls { margin-left: auto; + display: flex; + align-items: center; + gap: 8px; + flex-shrink: 0; +} +#ped-foldall { padding: 5px 10px; font-size: 0.8rem; white-space: nowrap; } +.ped-zoom { display: flex; align-items: center; gap: 4px;