Profile memory
Comment cleanup
This commit is contained in:
fraxle
2026-05-18 23:02:41 +01:00
parent dded468bec
commit 85c415d1f5
16 changed files with 504 additions and 581 deletions
+19 -19
View File
@@ -1,13 +1,13 @@
// ════════════════════════════════════════════════════════════════════════
// useTableScroll owns the horizontal scroll behaviour of the hourly
// ------------------------------------------------------------------------
// useTableScroll - owns the horizontal scroll behaviour of the hourly
// table (sticky header + body scroller layout).
//
// Responsibilities:
// 1. SCROLL INDICATORS track whether the body can scroll left/right so
// 1. SCROLL INDICATORS - track whether the body can scroll left/right so
// the table edges can show fade + chevron indicators.
// 2. DRAG-TO-SCROLL pointer-event drag on the body scroller for
// 2. DRAG-TO-SCROLL - pointer-event drag on the body scroller for
// desktop users.
// 3. SCROLL SYNC keep the sticky header track shifted horizontally to
// 3. SCROLL SYNC - keep the sticky header track shifted horizontally to
// match the body's scrollLeft, and keep header cell widths in lock-
// step with body cell widths even as columns toggle / window resizes.
//
@@ -15,12 +15,12 @@
// refs: { headTableRef, bodyTableRef, bodyScrollRef, headTrackRef }
// deps: { forecast, visibleCols, selectedDay, skinType, vehicleType,
// indoorMode, indoorManaged }
// anything that should cause a re-sync when it changes.
// - anything that should cause a re-sync when it changes.
//
// Outputs:
// tableCanScrollLeft, tableCanScrollRight drive the fade/chevron CSS
// handleBodyScroll attach to body onScroll
// ════════════════════════════════════════════════════════════════════════
// tableCanScrollLeft, tableCanScrollRight - drive the fade/chevron CSS
// handleBodyScroll - attach to body onScroll
// ------------------------------------------------------------------------
import { useState, useEffect, useLayoutEffect } from '../../vendor/preact-hooks.js';
@@ -37,7 +37,7 @@ export function useTableScroll({
indoorMode,
indoorManaged,
}) {
// ─── SCROLL INDICATORS ─────────────────────────────────────────────
// --- SCROLL INDICATORS ---------------------------------------------
const [tableCanScrollLeft, setTableCanScrollLeft] = useState(false);
const [tableCanScrollRight, setTableCanScrollRight] = useState(false);
@@ -48,7 +48,7 @@ export function useTableScroll({
setTableCanScrollRight(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
};
// ─── DRAG-TO-SCROLL ────────────────────────────────────────────────
// --- DRAG-TO-SCROLL ------------------------------------------------
useEffect(() => {
const el = bodyScrollRef.current;
if (!el) return;
@@ -103,7 +103,7 @@ export function useTableScroll({
updateTableScrollIndicators();
}, [forecast, visibleCols, selectedDay]);
// ─── BODY SCROLL HANDLER (called from JSX onScroll) ───────────────
// --- BODY SCROLL HANDLER (called from JSX onScroll) ---------------
const handleBodyScroll = () => {
const track = headTrackRef.current;
const body = bodyScrollRef.current;
@@ -112,7 +112,7 @@ export function useTableScroll({
updateTableScrollIndicators();
};
// ─── COLUMN-WIDTH SCROLL SYNC (layout effect) ─────────────────────
// --- COLUMN-WIDTH SCROLL SYNC (layout effect) ---------------------
// Synchronise the head and body table column widths with a
// "shrink-to-fit then distribute" strategy. See the comments inside
// sync() for the algorithm.
@@ -132,7 +132,7 @@ export function useTableScroll({
// Step 1: clear any previously-forced cell widths and switch the
// tables to natural sizing so the measurement reflects the true
// content-fit width independent of how wide the container is.
// content-fit width - independent of how wide the container is.
headCells.forEach(c => { c.style.width = ''; c.style.minWidth = ''; c.style.maxWidth = ''; });
bodyCells.forEach(c => { c.style.width = ''; c.style.minWidth = ''; c.style.maxWidth = ''; });
headTable.style.width = 'max-content';
@@ -141,7 +141,7 @@ export function useTableScroll({
bodyTable.style.tableLayout = 'auto';
// Step 2: read each cell's natural width. getBoundingClientRect
// forces synchronous layout that's what we want.
// forces synchronous layout - that's what we want.
const naturalW = new Array(n);
let naturalTotal = 0;
for (let i = 0; i < n; i++) {
@@ -157,7 +157,7 @@ export function useTableScroll({
const finalW = new Array(n);
let totalWidth;
if (naturalTotal > 0 && naturalTotal < containerW) {
// Spare space distribute proportionally across columns so they
// Spare space - distribute proportionally across columns so they
// fan out to fill the scroller (no awkward right-hand gap).
const scale = containerW / naturalTotal;
let running = 0;
@@ -170,7 +170,7 @@ export function useTableScroll({
finalW[n - 1] = containerW - running;
totalWidth = containerW;
} else {
// Naturals don't fit use them as-is and let the body scroll.
// Naturals don't fit - use them as-is and let the body scroll.
for (let i = 0; i < n; i++) finalW[i] = naturalW[i];
totalWidth = naturalTotal;
}
@@ -192,7 +192,7 @@ export function useTableScroll({
bodyCells[i].style.maxWidth = px;
}
// Make both tables exactly totalWidth wide so they share the same
// horizontal extent column N in the header sits directly above
// horizontal extent - column N in the header sits directly above
// column N in the body, no drift as you scroll right.
headTable.style.width = `${totalWidth}px`;
bodyTable.style.width = `${totalWidth}px`;
@@ -202,7 +202,7 @@ export function useTableScroll({
// Run once after layout
sync();
// Re-sync when the scroll container's width changes (window resize,
// sidebar opens, etc). We observe the scroller not the body table
// sidebar opens, etc). We observe the scroller - not the body table -
// because the body table's width is now driven by sync itself, which
// would otherwise create a feedback loop.
let ro = null;