Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request 'fix(calendar): improve scrolling across all calendar views' (#313) from fix/calendar-scroll-v2 into main

scott 55efba81 a6011b17

+33 -8
+20 -5
src/calendar/main.ts
··· 896 896 }); 897 897 898 898 // --------------------------------------------------------------------------- 899 - // Mouse wheel navigation (month view: scroll months, agenda: scroll weeks) 899 + // Mouse wheel navigation — month view only, at scroll boundaries 900 900 // --------------------------------------------------------------------------- 901 901 902 902 let wheelCooldown = false; 903 903 904 904 calendarGrid.addEventListener('wheel', (e) => { 905 - // Only navigate in month and agenda views — week/day have native scroll 906 - if (state.view !== 'month' && state.view !== 'agenda') return; 905 + // Only navigate months with wheel — week/day/agenda use native scroll 906 + if (state.view !== 'month') return; 907 + 908 + // Find the scrollable month grid 909 + const grid = calendarGrid.querySelector('.cal-month-grid') as HTMLElement | null; 910 + if (!grid) return; 911 + 912 + const atTop = grid.scrollTop <= 0; 913 + const atBottom = grid.scrollTop + grid.clientHeight >= grid.scrollHeight - 1; 914 + const canScroll = grid.scrollHeight > grid.clientHeight + 1; 915 + 916 + // If the grid has scrollable content, let native scroll work. 917 + // Only intercept when content is fully scrolled to the edge. 918 + if (canScroll) { 919 + if (e.deltaY > 0 && !atBottom) return; // scrolling down, not at bottom 920 + if (e.deltaY < 0 && !atTop) return; // scrolling up, not at top 921 + } 907 922 908 - // Debounce to prevent rapid-fire navigation 923 + // At a scroll boundary (or grid fits on screen) → navigate months 909 924 if (wheelCooldown) return; 910 925 wheelCooldown = true; 911 - setTimeout(() => { wheelCooldown = false; }, 300); 926 + setTimeout(() => { wheelCooldown = false; }, 400); 912 927 913 928 e.preventDefault(); 914 929 if (e.deltaY > 0) {
+13 -3
src/css/app.css
··· 9331 9331 min-height: 0; /* allow flex children to shrink below content size */ 9332 9332 } 9333 9333 9334 - /* Calendar grid container — fills remaining space below toolbar */ 9334 + /* Calendar grid container — fills remaining space below toolbar. 9335 + overflow: hidden here so each view child handles its own scroll. */ 9335 9336 .calendar-app .calendar-grid { 9336 9337 flex: 1; 9337 9338 display: flex; 9338 9339 flex-direction: column; 9339 - min-height: 0; /* allow flex children to shrink below content size */ 9340 - overflow: auto; 9340 + min-height: 0; 9341 + overflow: hidden; 9341 9342 } 9342 9343 9343 9344 ··· 9455 9456 grid-auto-rows: minmax(var(--cal-cell-min), 1fr); 9456 9457 flex: 1; 9457 9458 overflow-y: auto; 9459 + scrollbar-width: thin; 9460 + scrollbar-color: var(--color-border) transparent; 9461 + scroll-behavior: smooth; 9458 9462 } 9459 9463 9460 9464 .cal-month-header { ··· 9675 9679 display: grid; 9676 9680 grid-template-columns: var(--cal-gutter-width) repeat(7, 1fr); 9677 9681 overflow-y: auto; 9682 + scrollbar-width: thin; 9683 + scrollbar-color: var(--color-border) transparent; 9678 9684 } 9679 9685 9680 9686 .cal-time-gutter { ··· 9858 9864 display: grid; 9859 9865 grid-template-columns: var(--cal-gutter-width) 1fr; 9860 9866 overflow-y: auto; 9867 + scrollbar-width: thin; 9868 + scrollbar-color: var(--color-border) transparent; 9861 9869 } 9862 9870 9863 9871 /* Reuses .cal-time-gutter, .cal-hour-label, .cal-hour-row, ··· 9871 9879 flex: 1; 9872 9880 overflow-y: auto; 9873 9881 padding: var(--space-md) var(--space-lg); 9882 + scrollbar-width: thin; 9883 + scrollbar-color: var(--color-border) transparent; 9874 9884 } 9875 9885 9876 9886 .cal-date-group {