digidem / digidem/comapeo-cloud-app

bug(map): map pan/zoom controls and area-selection bar render behind map on mobile

Open
#306 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

agent:pr-opened bug difficulty:small lane:pr-review
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

  1. Open the app on a mobile browser (viewport < 768px).
  2. Go to the Alerts screen in map view.
  3. Tap Add Alert → the inline creation sheet opens (InlineAlertCreationPanel).
  4. Tap "Select on map" (onSelectMapMobile).
  5. 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-40 selection 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:64Dialog.Content class: 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

  1. Raise the area-selection bar and the inline alert sheet from z-40 to z-[1000] (or higher) so they clear MapLibre's control stack, including the cooperative-gesture layer (z-index: 99999). z-50 is not sufficient.
  2. Raise the MapScreenLayout top-right slot (z-30 at AlertsScreen.tsx:204) to z-[1000] while isCreatingInline / isSelectingMapOnMobile is active.
  3. Ensure MapContainer's relative overflow-hidden wrapper 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.
  4. Verify touch targets remain ≥44px and that pan/zoom gesture controls remain usable while the bar is visible.
  5. 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 test and npm run test:coverage stay 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.