Improve multi month polls
This commit is contained in:
+42
-8
@@ -4,6 +4,8 @@
|
||||
// canClick(dateStr) -> bool which days are interactive
|
||||
// isPicked(dateStr) -> bool draw the highlighter ring
|
||||
// isOffered(dateStr) -> bool soft marker background (poll page)
|
||||
// months() -> Map "YYYY-MM"->n render month pills instead of arrows;
|
||||
// only these months are reachable (poll page)
|
||||
// decorate(dateStr, cell) add badges/chips
|
||||
// onToggle(dateStr) click handler
|
||||
// })
|
||||
@@ -70,15 +72,47 @@ class Calendar {
|
||||
const title = document.createElement("div");
|
||||
title.className = "cal-title";
|
||||
title.textContent = first.toLocaleDateString(undefined, { month: "long", year: "numeric" });
|
||||
const months = o.months ? o.months() : null;
|
||||
const nav = document.createElement("div");
|
||||
nav.className = "cal-nav";
|
||||
for (const [sym, delta, label] of [["\u2190", -1, "Previous month"], ["\u2192", 1, "Next month"]]) {
|
||||
const b = document.createElement("button");
|
||||
b.type = "button";
|
||||
b.textContent = sym;
|
||||
b.setAttribute("aria-label", label);
|
||||
b.addEventListener("click", () => this.shift(delta));
|
||||
nav.appendChild(b);
|
||||
if (months && months.size > 0) {
|
||||
// Fixed set of months containing options: pills, no free navigation.
|
||||
nav.className = "cal-months";
|
||||
const keys = [...months.keys()].sort();
|
||||
const multiYear = new Set(keys.map((k) => k.slice(0, 4))).size > 1;
|
||||
for (const key of keys) {
|
||||
const [y, m] = key.split("-").map(Number);
|
||||
const d = new Date(y, m - 1, 1);
|
||||
const n = months.get(key);
|
||||
const b = document.createElement("button");
|
||||
b.type = "button";
|
||||
b.className = "pill";
|
||||
b.append(
|
||||
d.toLocaleDateString(undefined, multiYear ? { month: "short", year: "2-digit" } : { month: "short" }),
|
||||
);
|
||||
const count = document.createElement("span");
|
||||
count.className = "n";
|
||||
count.textContent = n;
|
||||
b.appendChild(count);
|
||||
b.setAttribute("aria-label",
|
||||
d.toLocaleDateString(undefined, { month: "long", year: "numeric" }) +
|
||||
`, ${n} ${n === 1 ? "date" : "dates"} offered`);
|
||||
if (y === this.year && m - 1 === this.month) {
|
||||
b.classList.add("active");
|
||||
b.setAttribute("aria-current", "true");
|
||||
}
|
||||
b.addEventListener("click", () => this.goTo(key + "-01"));
|
||||
nav.appendChild(b);
|
||||
}
|
||||
} else {
|
||||
nav.className = "cal-nav";
|
||||
for (const [sym, delta, label] of [["\u2190", -1, "Previous month"], ["\u2192", 1, "Next month"]]) {
|
||||
const b = document.createElement("button");
|
||||
b.type = "button";
|
||||
b.textContent = sym;
|
||||
b.setAttribute("aria-label", label);
|
||||
b.addEventListener("click", () => this.shift(delta));
|
||||
nav.appendChild(b);
|
||||
}
|
||||
}
|
||||
head.append(title, nav);
|
||||
this.el.appendChild(head);
|
||||
|
||||
Reference in New Issue
Block a user