Phones: the legend's credit folds on every map, and the open sheet has a grab lip

The credit fold was guarded by uiStore.isMobile, which only uiStore.init()
sets; a host that never calls it (UPG-100's map) kept the credit expanded.
The fold now tests the phone breakpoint itself, with the phone CSS block's
own query.

A finger aimed at the open sheet's top edge often landed on the hint pill
just above it, and a drag there scrolled the pane instead of resizing the
sheet. A transparent 12px lip above the open sheet takes that gesture with
the sheet's own handlers (their grab zone is measured from the sheet's top),
above the pill; it exists only while the sheet is open.
This commit is contained in:
Doxa Maps 2026-09-30 12:33:39 +00:00
parent d45b765bd6
commit 04a97f604c

View file

@ -133,6 +133,13 @@ useShadowStyles(`
title rows, and the whole sheet while collapsed) tells the browser not to pan from there; the sheet's own
touch handlers do the resizing, and a tap still reaches the caret. */
.sheet-drag-strip,.legend-mobile-sheet.collapsed,.legend-mobile-sheet .stl-titlebar,.legend-mobile-sheet .lrg-title-row,.legend-mobile-sheet .collapsed-detail-footer{touch-action:none;}
/* ★ A GRAB LIP ABOVE THE OPEN SHEET (mobile pass 2026-09-30, #9). A finger aimed at the open sheet's top edge often
landed just above it, on the hint pill (shown only while nothing is selected), and a drag there scrolled the
pane instead of resizing the sheet. This transparent 12px strip sits right above the sheet's top edge (it follows
--legend-sheet-h), above the pill, takes the pan (touch-action:none) and hands the gesture to the sheet's own
handlers, whose grab zone is measured from the sheet's top and so includes it. It is outside the sheet because
the sheet clips its children (overflow:hidden), and it exists only while the sheet is open. */
.sheet-grab-lip{position:absolute;inset-inline:0;bottom:var(--legend-sheet-h,0px);height:12px;z-index:1001;touch-action:none;}
.pull-tab-handle{width:40px;height:4px;background:#ccc;border-radius:2px;}
/* Collapse caret — in-flow, injected via #title-caret slot into the title
@ -879,7 +886,10 @@ function watchCredit(triesLeft) {
if (!root || !root.querySelector) return
const shown = root.querySelector('.maplibregl-ctrl-attrib.maplibregl-compact-show, .mapboxgl-ctrl-attrib.mapboxgl-compact-show')
if (shown) {
_creditTimer = setTimeout(() => { _creditTimer = 0; if (uiStore.isMobile) shown.classList.remove('maplibregl-compact-show', 'mapboxgl-compact-show') }, CREDIT_FOLD_MS)
// The phone test is the breakpoint itself, the phone CSS block's own query: uiStore.isMobile is set only by
// uiStore.init(), which a host may never call (UPG-100's map does not), and then the fold never ran there.
const phone = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(max-width: 767.98px)').matches
_creditTimer = setTimeout(() => { _creditTimer = 0; if (phone) shown.classList.remove('maplibregl-compact-show', 'mapboxgl-compact-show') }, CREDIT_FOLD_MS)
return
}
const credit = root.querySelector('.maplibregl-ctrl-attrib, .mapboxgl-ctrl-attrib')
@ -911,6 +921,16 @@ onBeforeUnmount(() => { if (_creditTimer) { clearTimeout(_creditTimer); _creditT
/>
</div>
<!-- The grab lip above the open sheet (see .sheet-grab-lip): the same handlers as the sheet. -->
<div
v-if="legendState !== 'collapsed'"
class="sheet-grab-lip"
aria-hidden="true"
@touchstart="onSheetTouchStart"
@touchmove="onSheetTouchMove"
@touchend="onSheetTouchEnd"
@touchcancel="onSheetTouchEnd"
></div>
<!-- Touch resize handlers sit on the SHEET: a drag may start anywhere in the
top GRAB_ZONE_PX (strip + title row) — and, in detail mode, on the content
when it can't scroll that way. See onSheetTouchStart for the model. -->