fix(map): results map fullscreen falls back to an overlay on iOS #18

Merged
tudor merged 1 commits from fix/results-map-ios-fullscreen into main 2026-07-06 13:33:16 +00:00
Owner

The results-view map (map view on a location search) had the same iOS bug we already fixed on the school detail page's hero map: its fullscreen button called requestFullscreen(), which iOS Safari doesn't implement (fullscreen is video-only there), so tapping it did nothing on iPhones.

I reproduced it on staging by deleting Element.prototype.requestFullscreen — the button becomes a no-op (aria-label stays "View map fullscreen", wrapper stays position: relative).

Fix (SchoolMap.tsx / .module.css)

  • When the Fullscreen API is missing or its promise rejects, fall back to a fixed-position overlay (.fsFallback, position: fixed; inset: 0; z-index: 5000) driven by state, with body scroll locked while open. Native fullscreen (desktop/Android) is unchanged.
  • Leaflet only re-measures on a window resize (its trackResize). Native fullscreen fires one; the CSS overlay doesn't — so I dispatch a resize when fullscreen toggles, otherwise the map tiles fill only part of the screen until the user pans.

Test

New e2e journey deletes Element.requestFullscreen on a 390×844 viewport, switches to the results map view, opens fullscreen, and asserts the exit control appears then releases. It fails against current production (reproducing the bug) and will pass once this deploys — I confirmed it fails exactly at the "Exit fullscreen" assertion on staging, with the Map toggle and fullscreen button both resolving correctly.

Typecheck passes.

🤖 Generated with Claude Code

The results-view map (map view on a location search) had the same iOS bug we already fixed on the school detail page's hero map: its fullscreen button called `requestFullscreen()`, which iOS Safari doesn't implement (fullscreen is video-only there), so tapping it did nothing on iPhones. I reproduced it on staging by deleting `Element.prototype.requestFullscreen` — the button becomes a no-op (aria-label stays "View map fullscreen", wrapper stays `position: relative`). ## Fix (`SchoolMap.tsx` / `.module.css`) - When the Fullscreen API is missing or its promise rejects, fall back to a fixed-position overlay (`.fsFallback`, `position: fixed; inset: 0; z-index: 5000`) driven by state, with body scroll locked while open. Native fullscreen (desktop/Android) is unchanged. - Leaflet only re-measures on a window `resize` (its `trackResize`). Native fullscreen fires one; the CSS overlay doesn't — so I dispatch a `resize` when fullscreen toggles, otherwise the map tiles fill only part of the screen until the user pans. ## Test New e2e journey deletes `Element.requestFullscreen` on a 390×844 viewport, switches to the results map view, opens fullscreen, and asserts the exit control appears then releases. It **fails against current production** (reproducing the bug) and will pass once this deploys — I confirmed it fails exactly at the "Exit fullscreen" assertion on staging, with the Map toggle and fullscreen button both resolving correctly. Typecheck passes. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
tudor added 1 commit 2026-07-06 13:10:06 +00:00
fix(map): results map fullscreen falls back to an overlay on iOS
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m37s
PR Checks / Backend Smoke (pull_request) Successful in 5s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m4s
b2dc4d0779
The results-view map's fullscreen button called requestFullscreen(),
which iOS Safari doesn't implement (fullscreen is video-only there), so
tapping it did nothing on iPhones — the same gap already fixed for the
school hero map.

When the Fullscreen API is missing or its promise rejects, fall back to
a fixed-position overlay (.fsFallback, z-index 5000) driven by state,
locking body scroll while open. Leaflet re-measures on window resize, so
dispatch a resize when fullscreen toggles (the CSS overlay fires none) or
the map would fill only part of the screen. Native fullscreen is
unchanged.

New e2e journey deletes Element.requestFullscreen on a mobile viewport,
opens the results map fullscreen, and asserts the exit control appears
then releases; it fails against current production, reproducing the bug.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

🤖 AI Code Review (Claude Code)

This PR adds an iOS Safari fallback for the results map's fullscreen button, mirroring an existing fix for the hero map: when Element.requestFullscreen is unavailable (or rejects), the component switches to a CSS fixed-position overlay driven by React state instead of the native Fullscreen API, with a matching e2e test and CSS class. The implementation correctly layers native and fallback fullscreen state, restores body scroll on cleanup, and nudges Leaflet to re-measure via a synthetic resize event; only one SchoolMap instance renders at a time so there's no risk of state collisions between instances.

No issues found.

## 🤖 AI Code Review (Claude Code) This PR adds an iOS Safari fallback for the results map's fullscreen button, mirroring an existing fix for the hero map: when Element.requestFullscreen is unavailable (or rejects), the component switches to a CSS fixed-position overlay driven by React state instead of the native Fullscreen API, with a matching e2e test and CSS class. The implementation correctly layers native and fallback fullscreen state, restores body scroll on cleanup, and nudges Leaflet to re-measure via a synthetic resize event; only one SchoolMap instance renders at a time so there's no risk of state collisions between instances. ✅ No issues found.
tudor merged commit 1f8284adfc into main 2026-07-06 13:33:16 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tudor/school_compare#18