Basic mobile support #67
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#67
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
Adopt a mobile layout modeled on Google Maps: full-screen map with a fixed navbar at top, a map tool bar just below it, and the right panel becoming a draggable bottom sheet that snaps to three heights (peek → half → full). The existing DaisyUI radio tab structure works naturally — in peek mode only the tab labels are visible, forming the bottom dock; pulling the sheet up reveals content. No new UI library is needed; a ~120-line
BottomSheetControllerhandles the snap logic. The breakpoint is Tailwind'smd(768px): everything below is mobile, everything at or above is the current desktop layout.Note on "switch to Browse on map click": This is already implemented via
setupNavigationTabSwitching()insrc/index.ts:291. Verify it feels correct during manual testing and add other tab-switch cases as encountered.Note on "move stop" residue: No explicit "Move Stop" button or mode exists in the codebase. Stop dragging is implemented via
mousedown/mousemove/mouseupininteraction-handler.ts— touch devices don't fire those events, so stop dragging is automatically disabled on mobile with no code changes needed.Relevant Context
src/index.html:37–38—.app-containerwithgrid-cols-[1fr_650px](or the CSS var variant from #35); needs to collapse to single column on mobilesrc/index.html:39–326— Navbar; needs responsive logo, mobile search slot, icon-only buttons on small screenssrc/index.html:332–392—#map-controlsfloating overlay; becomes a horizontal bar below the navbar on mobilesrc/index.html:395–551—.right-panelwith DaisyUI radio tabs; becomes the bottom sheet on mobilesrc/index.html:399–406—#panel-resizer(desktop-only drag handle from #35); must be hidden on mobilesrc/styles/main.css— add one@media (max-width: 767px)block for all bottom sheet CSSsrc/modules/search-controller.ts:33–35— targets#map-searchby ID; needs to also wire#mobile-searchsrc/modules/tab-manager.ts:13—switchToTab(tabName)triggers tab radio changes; BottomSheetController listens to tab changes to expand the sheetsrc/index.ts— GTFSEditor constructor; new module instantiated herePhase 1: HTML & CSS Skeleton
Goal: Make the layout structurally correct on mobile with pure HTML/CSS changes — no interactive JS yet. At the end of this phase, a mobile viewport shows the map full-screen, a compact navbar, a horizontal tool bar, and a fixed 56px strip at the bottom showing the Browse/Files/Changes tab labels.
Navbar changes (
src/index.html)navbar-start, wrap the branding text div (lines 47–57) in<div class="flex-col hidden md:flex">so only the logo avatar shows on mobile<div class="navbar-center flex md:hidden">containing#mobile-search:<span class="hidden md:inline">Load</span>so only the icon shows on mobile<span class="hidden md:inline">Export</span>Right panel changes (
src/index.html)id="right-panel"to.right-paneldiv (currently has no ID; needed for JS to reference it)#panel-resizeron mobile: addhidden md:blockto its class list (line 401).right-panel(before#panel-resizer):Map controls changes (
src/index.html)#map-controls(line 333), replaceabsolute top-4 right-4 flex-col items-end space-y-2with responsive classes:absolute top-2 right-2 md:top-4 md:right-4 flex flex-row md:flex-col items-center md:items-end gap-2 md:space-y-2hidden md:block— search is hidden in the overlay on mobile (it moves to the navbar)shadow-lgon mobile if desired — or leave it (left as-is)CSS (
src/styles/main.css).app-containerrule:Gotchas:
transition: heighton#right-panelconflicts with drag (during drag we should suppress the transition and re-enable it on snap).BottomSheetControllerin Phase 2 removes the transition class during drag and adds it back on release..app-containerCSS variable rule from plan #35 (grid-template-columns: 1fr var(--panel-width, 650px)) is overridden cleanly by the media query above.oklch(var(--b3))is the DaisyUI v5 way to reference theme colors in plain CSS.Phase 2: BottomSheetController + SearchController Update + Wiring
Goal: Make the bottom sheet interactive — draggable with 3 snap heights — and wire up the mobile search input.
Snap heights
Create
src/modules/bottom-sheet.tsBottomSheetControllerclass:Update
src/modules/search-controller.ts#map-searchis queried (around line 33–35). After initializing the desktop input, also wire#mobile-search:private wireInput(input: HTMLInputElement): voiddocument.getElementById('map-search')anddocument.getElementById('mobile-search'), filtering out nullWire
BottomSheetControllerinsrc/index.tsBottomSheetControllerfrom./modules/bottom-sheetGTFSEditorconstructor, aftertabManageris set up: No need to store as a class property.Gotchas:
onTabChangeonTabManagerneeds to fire for programmatic tab switches (viaswitchToTab) not just user clicks. Checktab-manager.ts:40–51— if it only listens to DOMchangeevents,switchToTab(which setscheckeddirectly without dispatching an event) may not trigger it. If so,switchToTabshould dispatch a syntheticchangeevent orTabManagerneeds a callback registration path thatswitchToTabalso calls.document.body.style.userSelect = 'none'should be set to prevent accidental text selection. Restore ontouchend/mouseup.window.innerWidth < 768is checked at constructor time. If the user resizes from desktop to mobile, the controller won't activate. This is acceptable for a v1 — phone browsers don't typically resize.PEEK_PX = 56value must match the actual rendered height of the DaisyUI tab label row. Measure this after implementation and adjust if needed. If DaisyUI tabs render taller, adjust accordingly.Original Issue
Lets do a few things that make it usable on mobile.
I think we can get away with leaving most things the same, just moving the high level things around.
Lets use Google Maps as a model:
Remember to use DaisyUI. Additionally, if there are things we can change in web that improve the experience and reduce differences between the two, lets do it.