digidem / digidem/comapeo-cloud-app
bug(map): map pan/zoom controls and area-selection bar render behind map on mobile
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 29
Description
Summary
When selecting or drawing an area on the map screen on mobile, the area-selection bar (the "Tap the map to place the alert point" hint + "Back to form" button) renders behind the map canvas and MapLibre's built-in control widgets (pan/zoom) instead of in front and easily accessible. The selection/editing UI is therefore partially occluded and hard to reach on small touch screens.
Steps to Reproduce
- Open the app on a mobile browser (viewport < 768px).
- Go to the Alerts screen in map view.
- Tap Add Alert → the inline creation sheet opens (
InlineAlertCreationPanel). - Tap "Select on map" (
onSelectMapMobile). - Observe: the "Tap the map to place the alert point" bar at the bottom of the screen and the map's pan/zoom controls are layered behind the map content, partially occluded or un-tappable.
Expected vs Actual Behavior
- Expected: While area selection is active on mobile, the selection bar and map controls sit in front of the map canvas, fully visible and tappable (≥44px touch targets).
- Actual: The
z-40selection bar is painted below MapLibre's map control stack, so it is visually behind the map / hard to interact with.
Root Cause Analysis
AlertsScreen.tsx renders AlertsMap and InlineAlertCreationPanel as siblings inside a relative h-full wrapper:
// src/screens/AlertsScreen.tsx:235
<div className="relative h-full">
<AlertsMap ... /> // renders MapContainer → MapLibre <Map>
{isCreatingInline && (
<InlineAlertCreationPanel ... /> // selection bar, z-40
)}
</div>
The selection UI uses Tailwind z-40 (= 40):
src/components/shared/InlineAlertCreationPanel.tsx:64—Dialog.Contentclass:absolute inset-x-0 bottom-0 z-40 ...src/components/shared/InlineAlertCreationPanel.tsx:117— bottom bar:absolute inset-x-3 bottom-3 z-40 ... md:hidden
MapLibre's <Map> (src/components/shared/MapContainer/MapContainer.tsx) renders the map canvas plus its built-in control/gesture widgets inside a map-internal stacking context. Those control widgets paint above app-level z-40 overlays when the overlay is a sibling of the map container rather than a child. In particular MapLibre's cooperative-gesture layer uses z-index: 99999, so z-40 (and even z-50) cannot clear it.
Additionally, the MapScreenLayout top-right slot is too low while inline creation is active:
src/components/shared/MapScreenLayout/MapScreenLayout.tsx:55— default:'top-4 right-3 z-10 items-center'src/screens/AlertsScreen.tsx:204— override:topRightPositionClassName="top-4 right-3 z-30 items-center"
Note: the app does not render a NavigationControl component; the pan/zoom surface seen during selection comes from MapLibre's built-in control widgets.
Affected Files
| File | Role |
|---|---|
src/components/shared/InlineAlertCreationPanel.tsx |
Dialog.Content (line 64) and bottom selection bar (line 117) both z-40. |
src/screens/AlertsScreen.tsx |
Sibling stacking context (line 235) and top-right z-30 override (line 204) during inline creation. |
src/components/shared/MapScreenLayout/MapScreenLayout.tsx |
Top-right slot default z-10 (line 55); needs raising while inline creation is active. |
src/components/shared/MapContainer/MapContainer.tsx |
MapLibre <Map> hosting the elevated control stack. |
Suggested Fix
- Raise the area-selection bar and the inline alert sheet from
z-40toz-[1000](or higher) so they clear MapLibre's control stack, including the cooperative-gesture layer (z-index: 99999).z-50is not sufficient. - Raise the
MapScreenLayouttop-right slot (z-30atAlertsScreen.tsx:204) toz-[1000]whileisCreatingInline/isSelectingMapOnMobileis active. - Ensure
MapContainer'srelative overflow-hiddenwrapper does not clip the elevated overlay — render the bar as a sibling outside the map container's internal stacking, or give it a high-enough z-index to escape it. - Verify touch targets remain ≥44px and that pan/zoom gesture controls remain usable while the bar is visible.
- Add a Playwright E2E test (mobile viewport) asserting the selection bar is interactable (not obscured) during the area-selection state.
Acceptance Criteria
- On a mobile viewport, with area selection active, the "Tap the map to place the alert point" bar and "Back to form" button render in front of the map canvas.
- The selection bar is fully visible and tappable (minimum 44×44px touch target) without scrolling.
- Pan/zoom gesture controls remain usable while the selection bar is shown.
- A Playwright E2E test (mobile viewport) asserts the selection bar is not obscured during the area-selection state; it passes without manual intervention.
- No regression on the desktop (md+) inline alert sheet layout.
-
npm testandnpm run test:coveragestay green with no dropped coverage below the 80% threshold.
Environment
- CoMapeo Cloud App (web dashboard for the comapeo-cloud server)
- MapLibre GL JS via
react-map-gl/maplibre(react-map-gl 8.1.1, maplibre-gl 5.24.0) - Mobile-first, Cloudflare Pages deployment
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with onSelectMapMobile in src/screens/AlertsScreen.tsx, then inspect the z-index classes in InlineAlertCreationPanel.tsx, the MapScreenLayout top-right slot, and the MapContainer wrapper. Run the relevant Playwright mobile E2E flow; done means the selection bar is visible and tappable, map controls remain usable, and desktop behavior and test commands stay green.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- playwright, react, typescript
- Domain
- frontend, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100