Let the weigh-in list fold on its own
The Weight panel holds three things, and only one of them grows: the latest figure and the curve stay one screen forever, while the row list gains a line every weigh-in until it pushes everything else off. Folding the panel to get rid of it also takes away the two parts worth keeping. So the fold mechanism now works on any keyed element inside main, not only on a section, and the list moves into a block that folds by its own h3 while the panel keeps folding by its h2. The two nest without special handling — separate keys, and a folded section hides the block along with the rest, so the block's own state is simply there again when the section reopens. The CSS generalises from section.collapsible to a class, but scoped to main: the pedigree tree uses .collapsed for its own branches, and an unscoped selector would have folded every card in it.
This commit is contained in:
+19
-14
@@ -4193,10 +4193,15 @@
|
||||
});
|
||||
|
||||
// ---------- collapsible panels ----------
|
||||
// Each main section carrying a data-panel key can be folded by clicking its
|
||||
// Anything in main carrying a data-panel key can be folded by clicking its
|
||||
// heading; collapsed keys are remembered across reloads. State is device-global
|
||||
// (like the theme), so a single non-namespaced key is fine — it's not per-user
|
||||
// data. Only collapsed panels are stored, so newly added panels default open.
|
||||
//
|
||||
// A whole section heads with an h2, a foldable block inside one with an h3.
|
||||
// The two nest without special handling: each has its own key, and a folded
|
||||
// section hides the block along with everything else it holds, which leaves
|
||||
// the block's own state to reappear as it was when the section reopens.
|
||||
const PANELS_KEY = "puppy-tracker:panels:v1";
|
||||
function loadPanelState() {
|
||||
try {
|
||||
@@ -4209,25 +4214,25 @@
|
||||
}
|
||||
function initPanels() {
|
||||
const state = loadPanelState();
|
||||
document.querySelectorAll("main section[data-panel]").forEach(section => {
|
||||
const key = section.dataset.panel;
|
||||
const h2 = section.querySelector(":scope > h2");
|
||||
if (!h2) return;
|
||||
section.classList.add("collapsible");
|
||||
document.querySelectorAll("main [data-panel]").forEach(panel => {
|
||||
const key = panel.dataset.panel;
|
||||
const head = panel.querySelector(":scope > h2, :scope > h3");
|
||||
if (!head) return;
|
||||
panel.classList.add("collapsible");
|
||||
const collapsed = !!state[key];
|
||||
section.classList.toggle("collapsed", collapsed);
|
||||
h2.setAttribute("role", "button");
|
||||
h2.setAttribute("tabindex", "0");
|
||||
h2.setAttribute("aria-expanded", String(!collapsed));
|
||||
panel.classList.toggle("collapsed", collapsed);
|
||||
head.setAttribute("role", "button");
|
||||
head.setAttribute("tabindex", "0");
|
||||
head.setAttribute("aria-expanded", String(!collapsed));
|
||||
const toggle = () => {
|
||||
const nowCollapsed = section.classList.toggle("collapsed");
|
||||
h2.setAttribute("aria-expanded", String(!nowCollapsed));
|
||||
const nowCollapsed = panel.classList.toggle("collapsed");
|
||||
head.setAttribute("aria-expanded", String(!nowCollapsed));
|
||||
const s = loadPanelState();
|
||||
if (nowCollapsed) s[key] = true; else delete s[key];
|
||||
savePanelState(s);
|
||||
};
|
||||
h2.addEventListener("click", toggle);
|
||||
h2.addEventListener("keydown", (e) => {
|
||||
head.addEventListener("click", toggle);
|
||||
head.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Enter" || e.key === " ") { e.preventDefault(); toggle(); }
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user