Skip to content

Charts: season slider on the nurseries map (#172) - #177

Merged
Luen merged 3 commits into
mainfrom
feat/172-season-slider
Nov 12, 2026
Merged

Luen merged 3 commits into
mainfrom
feat/172-season-slider

Conversation

@Luen

@Luen Luen commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator

Closes #172.

What

  • Season slider + Play above the map on /nurseries. The last stop is "All seasons" (today's view); Play steps through seasons every 1.2 s and stops at 2025–26. Dragging the slider pauses playback.
  • Circles use one catch-rate scale for every frame (the largest nursery-season value), so sizes compare across seasons.
  • Nurseries not sampled with timed sets that season are dashed rings; the popup says "Not sampled this season" or "N sets, none timed".
  • InteractiveMap now redraws its layers when the layers prop changes, keeping the view and any overlays the reader switched off. New optional MapLayer.max fixes the size scale.
  • Slider is a native range input with aria-valuetext; the SSR fallback is unchanged.

Checks

pnpm lint, pnpm check, pnpm test, pnpm build, pnpm test:e2e (38 passed). Checked against the real data in the dev server: the slider, Play and the dashed rings work, and there is one layer control.

#173 and #174 are stacked on this branch (they extend InteractiveMap too), so merge this first.

🤖 Generated with Claude Code

The map can step through the 13 seasons, or play them in turn, with
circles on one catch-rate scale so frames are comparable. Nurseries
not sampled with timed sets that season show as dashed rings.
InteractiveMap now redraws its layers when they change, keeping the
view and any layers the reader switched off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Luen

Luen commented Nov 11, 2026

Copy link
Copy Markdown
Collaborator Author

Reviewed the three changed files and pushed a fix.

[P2] Restore text-only map tooltips. The redraw loop in InteractiveMap.svelte passed p.label directly to Leaflet's bindTooltip, which parses strings as HTML. Adult names come from workbooks, so markup in a name became DOM on hover. This undid the explicit textContent protection already in main (#144). CSP limits script execution but does not prevent HTML injection.

Fixed in 045cf04, with the browser test corrected in cfe1404: labels now use a DOM element populated with textContent. A browser regression injects a synthetic markup-containing label and verifies literal text with no injected element. Added the Leaflet caveat to AGENTS.md.

The season indexing, shared scale, redraw lifecycle and overlay retention otherwise look consistent. This branch passed lint, type checks, build, unit tests (118 passed; 2 real-data tests skipped), and the tooltip browser regression. The full combined stack additionally passed 41 browser tests. Fix propagated through #178, #179 and #184 without force-pushing. No spreadsheets changed.

@Luen

Luen commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator Author

Re-reviewed current head cfe1404, including the earlier tooltip fix. No additional actionable findings. Checked season/row alignment, pooled versus per-season catch rates, shared size domain, missing-value rings, playback cleanup, CSV registration, and overlay redraw/visibility retention.

Fresh validation on this branch: pnpm lint; pnpm check (0 errors/warnings); pnpm test (118 passed, 2 opt-in real-data tests skipped); pnpm build; pnpm test:e2e (39 passed, including the tooltip regression and light/dark axe checks). No further code changes needed. Review complete; proceeding to #178.

@Luen
Luen merged commit 0c83900 into main Nov 12, 2026
6 checks passed
@Luen
Luen deleted the feat/172-season-slider branch November 12, 2026 01:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Charts: season slider on the nurseries map

1 participant