Mobile follow on number 2 #75
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
gtfs.zone/coloring-book#75
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Follow-up polish pass for mobile support (#74). Fixes six concrete issues: (1) page overscroll/bounce when dragging the navbar, (2) a ~5-10px gap between the dock and the bottom sheet caused by the dock's actual rendered height differing from the hardcoded
--dock-heightCSS variable, (3) the basemap/projection/shape-toggle buttons partially hidden behind the dock due to incorrect z/y positioning, (4) notifications appearing at the bottom-left (wrong place) instead of below the search area, (5) the search box being in the navbar on mobile (should be a map overlay), and (6) auto-zoom not accounting for the bottom sheet covering half the map.Approach: minimal targeted changes per issue — no refactors beyond what's needed. Prefer DaisyUI classes over bespoke CSS.
Relevant Context
src/styles/main.css— mobile media query (@media (max-width: 767px)) and:root { --dock-height: 4rem }src/index.html:38—<body class="font-sans h-screen overflow-hidden">;navbar-center(mobile search) is lines 64-71;#map-controlsis lines 341-406;#mobile-dockis lines 578-639src/modules/notification-system.ts:35-36— container created with class'fixed bottom-4 left-4 z-50 space-y-2'src/modules/basemap-control.ts:148-156— inlinestyle.cssTextsetsposition: absolute; bottom: 40px; right: 10px; no z-index set inlinesrc/modules/bottom-sheet.ts:27-34— constructor; mobile checkwindow.innerWidth >= 768; resize listener at line 26src/modules/search-controller.ts:33-50— looks for bothmap-searchandmobile-searchinputs;createSearchResults()appends dropdown to#map-controls; click-outside handler checks#mobile-searchon line 61src/modules/map-controller.ts:388—highlightStopcallsflyTowith no padding object;flyToRouteline 515 callsfitBounds({ padding: 80 });fitMapToTripline 453 callsfitBounds({ padding: 50 });fitToRoutesline 561 callsfitBounds({ padding: 50 })MapLibre
paddingoption: bothflyToandfitBoundsacceptpaddingas either a number (uniform) or{ top, bottom, left, right }in pixels. For a single-pointflyTo, bottom padding shifts the center point upward into the visible area above the sheet.Phase 1: Body / Page Stability
Goal: prevent overscroll bounce when dragging the navbar, and prevent the browser chrome from appearing/disappearing during scroll.
src/styles/main.css, add before the media query block: This is the minimal, non-invasive fix for elastic bounce without interfering with map touch events.Gotcha:
touch-action: noneon body would break map panning — do NOT add it.Phase 2: Dock Height Dynamic Measurement (Gap Fix)
Goal: eliminate the ~5-10px gap between the dock top edge and the bottom sheet.
The gap exists because
--dock-height: 4rem(hardcoded CSS) doesn't match the dock's actual rendered height (which includes its border, padding, and DaisyUI-computed height).src/modules/bottom-sheet.ts, add a private method:this.syncDockHeight()at the end of the constructor (after the mobile early-return check), and inside the resize listener (beforethis.setSnap(...)).Gotcha: call
syncDockHeightAFTERsetSnap('closed', false)in the constructor so the panel position is correct from the start.Phase 3: Basemap Control Positioning on Mobile
Goal: move the basemap/projection/shape-toggle buttons above the dock (not hidden behind it), with consistent z-index below the dock/sheet layer.
The
basemap-controldiv is appended to the map container via JS with inline CSSbottom: 40px; right: 10pxand no z-index. On mobile, the dock isz-50and the bottom sheet isz-50. The basemap buttons end up partially or fully behind the dock.src/styles/main.css, inside the@media (max-width: 767px)block, add: The!importantis required to override the inlinestyle.cssTextset inbasemap-control.ts. z-index 40 puts these buttons below the dock/sheet (z-50) so the drawer slides over them naturally.Gotcha:
rebuildControl()callscreateControl()which resetsstyle.cssTexton each basemap change — that's fine because we're overriding via the stylesheet (higher specificity wins when!importantis used vs inline).Phase 4: Search Box to Map Overlay + Notification Placement
Goal: move the search box from the mobile navbar to a map overlay at the top-left, visible on both mobile and desktop. Notifications move from bottom-left to below the search area.
HTML changes (
src/index.html)Remove the entire
navbar-centerdiv (lines 64-71):Replace
#map-controls(lines 344-406) with a new layout:Key changes from current:
left-2 right-2instead ofright-2only — spans full widthmd:breakpoint differences — same layout on all screensflex-1 max-w-sm(~24rem max, ~2× the oldw-48), visible on all screen sizesflex-shrink-0Remove the desktop-only search card that was inside
#map-controls(it's merged into the above)src/modules/search-controller.tsinitialize(), remove themobile-searchlookup entirely — only wiremap-search:syncInputs()method (no longer needed with a single input).syncInputscall sites.src/modules/notification-system.tsinitialize()from: to:top-28(7rem) = 4rem navbar + ~3rem for search/controls height.z-[100]ensures notifications appear above the dock and sheet.Gotcha:
max-w-xs(20rem) keeps notifications from spanning the full width on desktop. On mobile the search ismax-w-sm(24rem); notifications slightly narrower is fine.Phase 5: Auto-Zoom Aware of Bottom Sheet
Goal: when navigating to a stop/route/trip on mobile, the map zooms so the feature appears in the visible area above the half-open sheet (not behind it).
MapLibre
flyToandfitBoundsboth acceptpadding: { top, bottom, left, right }in pixels. Addingbottompadding pushes the viewport center upward, keeping the feature visible above the sheet.src/modules/map-controller.tshighlightStop→flyTocall (line ~388) to use padding:flyToRoute→fitBoundscall (line ~515):fitMapToTrip→fitBoundscall (line ~453):fitToRoutes→fitBoundscall (line ~561):fitAllStops→fitBoundscall (line ~333):src/index.tsbottomSheetsetup block (after line ~247), set the bottom padding on the map controller: This is set once at init. If orientation changes, the resize handler inbottom-sheet.tswill update--dock-heightbut we don't need to update padding dynamically — the half-snap height is proportional so it scales with the viewport naturally.Gotcha:
setBottomPaddingmust be called afterthis.mapControlleris initialized. Check thatthis.mapControlleris set before this call in the init sequence.Original Issue
Follow-up to #74 mobile support. Issues observed after Phase 3 of #74: