feat: lvt-fx:viewport-report directive for read-progress reporting#144
feat: lvt-fx:viewport-report directive for read-progress reporting#144adnaan wants to merge 1 commit into
Conversation
Adds a debounced viewport-report directive: on a scroll container,
`lvt-fx:viewport-report="<action>"` reports the data-key of the topmost and
bottommost tracked descendant (chosen by data-lvt-viewport-items, default
"[data-key]") currently intersecting the container's viewport, via
send({action, data:{topKey, bottomKey}}).
Deliberately a dumb reporter — it emits keys only; all read-range accumulation,
high-water-mark and restore logic live server-side, which keeps it a general
primitive and makes the consuming behaviour unit-testable without a browser.
Reports on scroll (250ms debounce), once on attach (initial viewport), and on
resize; suppresses reports while the visible extremes are unchanged. Armed once
per container (idempotent re-arm), swept on disconnect / attribute removal —
mirrors the text-select / area-select directive lifecycle.
Consumed by prereview's read-progress feature (livetemplate/prereview#128).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ey41dRwDpRgLtVHZjhYLKt
|
Reviewed the Stale reports after DOM re-render (likely bug) Every other stateful directive in this file re-syncs on each render even when an element is already armed — e.g. Since this is explicitly the primitive behind a live-updating read-progress feature, the tracked container's content will routinely change via server-pushed re-renders (new items inserted/removed/reordered) without any The test suite doesn't cover this case either (all 5 tests only vary via Everything else (cleanup/teardown on disconnect, attribute-removal sweep, debounce, idempotent re-arm) looks correct and consistent with the existing |
Adds a debounced viewport-report directive so a scroll container can report which tracked descendants are visible back to the server — the primitive behind prereview's read-progress feature (livetemplate/prereview#128).
What
lvt-fx:viewport-report="<action>"on a scroll container reports, debounced, thedata-keyof the topmost and bottommost tracked descendant currently intersecting the container's viewport:data-lvt-viewport-items(a CSS selector, default"[data-key]"); each must carry adata-key.Design: deliberately a dumb reporter
It emits keys only — all logic (read-range accumulation, high-water mark, restore-target selection) lives server-side in the consumer. This keeps it a general primitive and, crucially, makes the behaviour unit-testable without a browser (the consumer feeds synthetic report actions to its controller). Armed once per container (idempotent re-arm), swept on disconnect / attribute removal — mirrors the existing
text-select/area-selectdirective lifecycle.Tests
tests/viewport-report.test.ts(5 cases): reports the top/bottom visible keys; suppresses unchanged repeats; reports again on a real range change; idempotent re-arm (no duplicate listeners); teardown stops reporting. Geometry is mocked (jsdom has no layout); the live scroll is covered end-to-end by the prereview chromedp test.Full suite: 38 suites / 800 tests green.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Ey41dRwDpRgLtVHZjhYLKt