calendar

A HTML/PHP project for a self-hosted (family)-calendar.
Log | Files | Refs | README

commit f351212acfe37f6a9f5ad5560f6a7c0dbb004779
parent 973d2763f673ea0ceb71df32e0c32530b0012d76
Author: Julian Piribauer <julian.piribauer@gmail.com>
Date:   Fri,  1 May 2026 21:18:45 +0000

Monthly view: min-width hide, max-width 1200px centered, daily fixed width

- Monthly view disappears completely (display:none) when the remaining
  space after the 520px daily panel would fall below 300px; a
  ResizeObserver fires on .calendar-main so it reacts to both window
  resizes and sidebar toggles instantly
- When daily panel is closed, monthly view is capped at max-width 1200px
  and centered with auto margins — achieved via
  .calendar-main:not(.daily-open) .monthly-view selector so the rule
  does not interfere with the split-panel layout
- Removed old mobile media-query that hard-collapsed monthly view to 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Diffstat:
Mstatic/app.js | 20++++++++++++++++++--
Mstatic/style.css | 14+++++++++-----
2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/static/app.js b/static/app.js @@ -265,17 +265,33 @@ document.getElementById('prev-month').addEventListener('click', prevMonth); document.getElementById('next-month').addEventListener('click', nextMonth); // ── Daily view ──────────────────────────────────────────────────────────────── +// ── Monthly view min-width enforcement ─────────────────────────────────────── +const MONTHLY_MIN_W = 300; +const calendarMain = document.querySelector('.calendar-main'); +const monthlyViewEl = document.querySelector('.monthly-view'); + +function updateMonthlyVisibility() { + const open = calendarMain.classList.contains('daily-open'); + const avail = open ? calendarMain.clientWidth - 520 : Infinity; + monthlyViewEl.classList.toggle('monthly-hidden', open && avail < MONTHLY_MIN_W); +} + +new ResizeObserver(updateMonthlyVisibility).observe(calendarMain); + +// ── Daily view open / close ─────────────────────────────────────────────────── function openDailyView(day) { const date = new Date(state.year, state.month, day); document.getElementById('daily-title').textContent = date.toLocaleDateString('en-GB', { weekday: 'long', day: 'numeric', month: 'long', }); renderTimeGrid(); - document.querySelector('.calendar-main').classList.add('daily-open'); + calendarMain.classList.add('daily-open'); + updateMonthlyVisibility(); } function closeDailyView() { - document.querySelector('.calendar-main').classList.remove('daily-open'); + calendarMain.classList.remove('daily-open'); + updateMonthlyVisibility(); state.selectedDay = null; renderMonthly(); } diff --git a/static/style.css b/static/style.css @@ -197,13 +197,17 @@ body { flex-direction: column; flex: 1 1 auto; min-width: 0; - transition: flex-basis 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94), - max-width 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94); overflow: hidden; } -.daily-open .monthly-view { - flex: 1 1 auto; + +/* Symmetric margins + max-width only when the daily panel is closed */ +.calendar-main:not(.daily-open) .monthly-view { + max-width: 1200px; + margin: 0 auto; } + +/* JS adds this class when remaining space < minimum usable width */ +.monthly-hidden { display: none !important; } .monthly-header { display: flex; align-items: center; @@ -712,5 +716,5 @@ select.form-input option { background: var(--polar2); color: var(--snow1); } .sidebar { width: 0; overflow: hidden; } .sidebar.collapsed { width: 0 !important; } .sidebar:not(.collapsed) { width: 220px; } - .daily-open .monthly-view { flex-basis: 0; max-width: 0; overflow: hidden; } + /* monthly-view hide/show when daily open is handled by JS ResizeObserver */ }