diff --git a/package.json b/package.json index f490201..a350147 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.76.1", + "version": "1.76.2", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/app/globals.css b/src/app/globals.css index aa070de..52f9430 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -2703,9 +2703,8 @@ h3 { flex: none !important; } - /* Ensure grid respects viewDays columns on mobile landscape */ + /* time-grid-wrapper is the single scroll container — keep overflow-y from inline style */ .time-grid-wrapper { - overflow: visible; min-width: 0; } .time-grid-wrapper .weekly-days-grid { @@ -3161,11 +3160,10 @@ h3 { } -/* Make day columns scrollable when using time grid */ +/* Day columns: no overflow — scroll is handled by time-grid-wrapper (single scroll container) */ .time-grid-wrapper .weekly-days-grid { flex: 1; - overflow-y: auto; /* Unified scroll container */ - overflow-x: hidden; + overflow: visible; } .time-grid-wrapper .weekly-day-column { @@ -4974,17 +4972,10 @@ h3 { } @media (max-width: 768px) { - /* Day headers are not sticky on mobile — CSS sticky doesn't work in a CSS grid scroll container. - The mobile-sticky-day-bar overlay (fixed position) handles this instead. */ - .time-grid-on .weekly-day-header { - position: relative !important; - top: auto !important; - } - /* On mobile, time-column-header should NOT be sticky — it wastes vertical space */ + /* time-grid-wrapper is now the single scroll container, so position:sticky works. + time-column-header is hidden on mobile to save vertical space. */ .time-grid-on .time-column-header { - position: relative !important; - top: auto !important; - z-index: auto !important; + display: none; } } diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index 6f9b241..acd1bb1 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -2492,8 +2492,7 @@ export default function WeeklyView() { // Translation helper const t = translations[language] || translations["en"]; - // Refs for scroll synchronization - const timeColumnRef = useRef(null); + // Refs for scroll const dayColumnsRef = useRef([]); const isScrollSyncing = useRef(false); const isInitialScrollDone = useRef(false); @@ -2538,30 +2537,11 @@ export default function WeeklyView() { const somedaySectionRef = useRef(null); // Unified scroll sync handlers - const handleTimeColumnScroll = (e: React.UIEvent) => { - const scrollTop = e.currentTarget.scrollTop; - if (isScrollSyncing.current) return; - isScrollSyncing.current = true; - - if (gridRef.current) { - gridRef.current.scrollTop = scrollTop; - } - setTimeout(() => { - isScrollSyncing.current = false; - }, 50); - }; + // handleTimeColumnScroll no longer needed — single scroll container via time-grid-wrapper - const handleGridScroll = (e: React.UIEvent) => { - const scrollTop = e.currentTarget.scrollTop; - if (isScrollSyncing.current) return; - isScrollSyncing.current = true; - - if (timeColumnRef.current) { - timeColumnRef.current.scrollTop = scrollTop; - } - setTimeout(() => { - isScrollSyncing.current = false; - }, 50); + const handleGridScroll = (_e: React.UIEvent) => { + // Single scroll container — no sync needed + // Mobile sticky day is handled by the native scroll listener in the useEffect }; const jumpToHour = (hour: number) => { @@ -2577,9 +2557,7 @@ export default function WeeklyView() { intendedScrollTop.current = scrollOffset; const perform = () => { - if (timeGridWrapperRef.current) timeGridWrapperRef.current.scrollTop = scrollOffset; if (gridRef.current) gridRef.current.scrollTop = scrollOffset; - if (timeColumnRef.current) timeColumnRef.current.scrollTop = scrollOffset; }; // Repeated enforcement @@ -3140,20 +3118,15 @@ export default function WeeklyView() { const slotHeight = getSlotHeight(cellDuration); const scrollOffset = workingHoursStart * slotsPerHour * slotHeight; - // Scroll the time-grid-wrapper (the scrollable viewport) - if (timeGridWrapperRef.current) timeGridWrapperRef.current.scrollTop = scrollOffset; - // Also scroll inner refs as fallback + // Single scroll container: gridRef points to time-grid-wrapper if (gridRef.current) gridRef.current.scrollTop = scrollOffset; - if (timeColumnRef.current) timeColumnRef.current.scrollTop = scrollOffset; intendedScrollTop.current = scrollOffset; // On initial load, re-enforce for 2s to fight browser auto-scroll restoration if (!isInitialScrollDone.current) { const interval = setInterval(() => { - if (timeGridWrapperRef.current) timeGridWrapperRef.current.scrollTop = scrollOffset; if (gridRef.current) gridRef.current.scrollTop = scrollOffset; - if (timeColumnRef.current) timeColumnRef.current.scrollTop = scrollOffset; }, 50); setTimeout(() => { @@ -4523,7 +4496,6 @@ export default function WeeklyView() { // Navigation handlers with CSS class-based slide animation (works in all browsers) const gridRef = useRef(null); - const timeGridWrapperRef = useRef(null); const allSlideClasses = ["slide-animate-next", "slide-animate-prev", "slide-animate-week-next", "slide-animate-week-prev"]; const navigate = ( newDate: Date, @@ -7641,19 +7613,18 @@ export default function WeeklyView() { {/* Main Grid with Time Column */} {viewStyle !== "kanban" &&
-
} onScroll={handleGridScroll} style={showTimeGrid ? { + height: '100%', + overflowY: 'auto', + overflowX: 'hidden', + WebkitOverflowScrolling: 'touch' as any, } : undefined}> {/* Time Column */} {showTimeGrid && ( -
1 ? "week" : "day"} - onScroll={handleGridScroll} style={showTimeGrid ? { height: `${24 * (60 / effectiveCellDuration) * getSlotHeight(effectiveCellDuration) + getHeaderHeight(effectiveCellDuration)}px`, - maxHeight: `${24 * (60 / effectiveCellDuration) * getSlotHeight(effectiveCellDuration) + getHeaderHeight(effectiveCellDuration)}px`, flex: 1, alignSelf: "flex-start", - overflowY: 'auto' } : { flex: 1, }}