Phones: the credit stays in the top corner on a map with the footer sheet, and folds after 3 s

On a map with the legend sheet the engine's credit keeps its top-start
corner, now above the scroll-edge strips, and folds to its (i) 3 s after it
first shows expanded. The full-width sheet, the 'dxmaps:legend-sheet' event
and the hidden MapLibre logo control stay.
This commit is contained in:
Doxa Maps 2026-09-30 08:46:01 +00:00
parent b094df94e4
commit 659bdc372e

View file

@ -29,15 +29,17 @@ useShadowStyles(`
/* Containment root: clamps absolute children to the map area. */
.legend-sheet-root{position:absolute;inset:0;pointer-events:none;overflow:hidden;}
.legend-sheet-root>*{pointer-events:auto;}
/* ★ THE BOTTOM OF A PHONE MAP (mobile pass 2026-09-30, the bottom-of-map standard). From the bottom up: the
sheet, flush at the map's bottom at FULL width; just above it, the round menu button on the start side
(the layout lifts it from the 'dxmaps:legend-sheet' event in the script) and the engine's credit on the
end side, compact: it shows expanded, then folds to its (i) a few seconds after it appears (script:
CREDIT_FOLD_MS). The sheet takes the full width only while the layout lifts the button above it: the
layout says so with --map-fab-sheet-inset:0px. A layout that does not lift it leaves the sheet beside
the button (--map-fab-beside), so the button never sits on the sheet. This replaces the credit at the top, which a map's own top overlays (the info pointer)
ran over, and the sheet inset beside the menu button, which shifted the legend when the drawer opened.
See the @media block after the desktop rules; the desktop notes below are history. */
/* ★ ATTRIBUTION PLACEMENT ON A PHONE MAP WITH THIS FOOTER SHEET (mobile pass 2026-09-30). The engine's credit
sits in the TOP corner on the START side (left; right in RTL), opposite the map's own control column,
compact: it shows expanded, then folds to its (i) 3 s after it first shows (script: CREDIT_FOLD_MS), and a
tap on the (i) opens it again. Its corner sits above the scroll-edge strips, so the tap always lands. The
sheet is flush at the map's bottom at FULL width while the layout lifts its round menu button above the
sheet (the layout says so with --map-fab-sheet-inset:0px, from the 'dxmaps:legend-sheet' event in the
script); a layout that does not lift the button leaves the sheet beside it (--map-fab-beside). MapLibre's
optional logo control goes; the credit, the licence term, stays. Every bottom placement of the credit
failed a reader (covered by the open sheet, floating mid-map, or pushing the legend off the map), which
is why it lives at the top here; a map with no footer sheet keeps it at the bottom-right. See the @media
block after the desktop rules; the desktop notes below are history. */
/* ── Attribution stays visible (bug 2026-09-16) ──
The sheet is a bottom overlay, so the engine's bottom-left logo / bottom-right
attribution corners ended up UNDER it in every state (even the 48px collapsed
@ -76,29 +78,25 @@ useShadowStyles(`
:host(.lm-on) .mapboxgl-ctrl-bottom-right:hover,:host(.lm-on) .maplibregl-ctrl-bottom-right:hover,.lm-on .mapboxgl-ctrl-bottom-right:hover,.lm-on .maplibregl-ctrl-bottom-right:hover{opacity:1;}
:host(.lm-on) .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl,:host(.lm-on) .maplibregl-ctrl-bottom-right .maplibregl-ctrl,.lm-on .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl,.lm-on .maplibregl-ctrl-bottom-right .maplibregl-ctrl{margin:0 6px 6px 0;}
:host(.lm-on) .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl-attrib.mapboxgl-compact,.lm-on .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl-attrib.mapboxgl-compact{margin-right:6px;}
/* ON A PHONE (the bottom-of-map standard): both corners sit just above the sheet (--legend-sheet-h, this
component's own observer). The credit's corner goes to the END side, capped short of the menu button on the
start side (--map-fab-beside, set by the layout only while that button shows); the logo corner (Mapbox's
wordmark) sits beside the button on the start side. !important: a plugin may lift its own corners with a
same-specificity translate, and the old desktop lift must not add to the sheet's height. z-index 4 keeps
the (i) tappable above the scroll-edge strips (z 2) that run the map's full height. MapLibre's own logo
control is optional under its licence and goes; the credit (the licence term) stays. */
/* !important on the move: a plugin may lift its own bottom corners by the round button's height with a
plain rule of the same specificity (a translateY on the corner container), and up here that lift would
push the credit off the top of the map. The corners are not at the bottom on a phone any more. */
/* ★ SCOPED TO .lm-on, a class on the HOST while at least one LegendMobile is mounted (script: LM_HOST_CLASS).
This CSS is injected once into the host's shadow root and never removed, so a map that mounts the sheet
only for a while (Cities with Internet: its phone people-group card) kept its credit at the top after
the sheet went, under the map's own legend (measured at 390: 1 of 11 points visible). Scoped, the move
ends with the last sheet. ".lm-on X" is the same rule for a page with no shadow root. */
@media (max-width:767.98px){
:host(.lm-on) .mapboxgl-ctrl-bottom-left,:host(.lm-on) .mapboxgl-ctrl-bottom-right,:host(.lm-on) .maplibregl-ctrl-bottom-left,:host(.lm-on) .maplibregl-ctrl-bottom-right,.lm-on .mapboxgl-ctrl-bottom-left,.lm-on .mapboxgl-ctrl-bottom-right,.lm-on .maplibregl-ctrl-bottom-left,.lm-on .maplibregl-ctrl-bottom-right{top:auto !important;bottom:var(--legend-sheet-h,48px) !important;transform:none !important;opacity:1;z-index:4;}
:host(.lm-on) .mapboxgl-ctrl-bottom-right,:host(.lm-on) .maplibregl-ctrl-bottom-right,.lm-on .mapboxgl-ctrl-bottom-right,.lm-on .maplibregl-ctrl-bottom-right{inset-inline-end:0 !important;inset-inline-start:auto !important;justify-content:flex-end;max-width:calc(100% - var(--map-fab-beside,0px) - 8px);}
:host(.lm-on) .mapboxgl-ctrl-bottom-right,.lm-on .mapboxgl-ctrl-bottom-right{max-width:calc(100% - var(--map-fab-beside,0px) - 104px);}
:host(.lm-on) .mapboxgl-ctrl-bottom-left,:host(.lm-on) .maplibregl-ctrl-bottom-left,.lm-on .mapboxgl-ctrl-bottom-left,.lm-on .maplibregl-ctrl-bottom-left{inset-inline-start:var(--map-fab-beside,0px) !important;inset-inline-end:auto !important;}
:host(.lm-on) .mapboxgl-ctrl-bottom-left,:host(.lm-on) .mapboxgl-ctrl-bottom-right,:host(.lm-on) .maplibregl-ctrl-bottom-left,:host(.lm-on) .maplibregl-ctrl-bottom-right,.lm-on .mapboxgl-ctrl-bottom-left,.lm-on .mapboxgl-ctrl-bottom-right,.lm-on .maplibregl-ctrl-bottom-left,.lm-on .maplibregl-ctrl-bottom-right{top:0 !important;bottom:auto !important;inset-inline-start:0 !important;inset-inline-end:auto !important;transform:none !important;justify-content:flex-start;max-width:calc(100% - 44px);z-index:4;}
:host(.lm-on) .maplibregl-ctrl-logo,.lm-on .maplibregl-ctrl-logo{display:none !important;}
/* Small type (mobile pass 2026-09-30, S8): expanded, the whole licence text takes at most two short lines
in the room beside the menu button, and then folds to its (i). It wraps rather than clips, so a longer
credit (another style, another engine) still shows whole. */
/* ONE LINE (mobile pass 2026-09-30, S8). Up here the credit shares the top edge with the map's control
column (the end side, 35px at 390), so it is capped short of it, in type small enough that the whole
licence text fits ONE line in the room left beside the column: measured at 390, the MapLibre credit
is 346px on one line at 10px, 312px at 9px and 294px at 8.5px, against about 302px of room (the box
keeps 36px of padding for its (i) toggle). It still wraps rather than clips, so a longer credit
(another style, another engine) shows whole on two lines instead of losing its terms. */
:host(.lm-on) .maplibregl-ctrl-attrib-inner,:host(.lm-on) .mapboxgl-ctrl-attrib-inner,.lm-on .maplibregl-ctrl-attrib-inner,.lm-on .mapboxgl-ctrl-attrib-inner{font-size:8.5px;line-height:12px;}
:host(.lm-on) .mapboxgl-ctrl-bottom-left .mapboxgl-ctrl,:host(.lm-on) .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl,:host(.lm-on) .maplibregl-ctrl-bottom-left .maplibregl-ctrl,:host(.lm-on) .maplibregl-ctrl-bottom-right .maplibregl-ctrl,.lm-on .mapboxgl-ctrl-bottom-left .mapboxgl-ctrl,.lm-on .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl,.lm-on .maplibregl-ctrl-bottom-left .maplibregl-ctrl,.lm-on .maplibregl-ctrl-bottom-right .maplibregl-ctrl{margin:0 0 8px;margin-inline:8px;}
:host(.lm-on) .mapboxgl-ctrl-bottom-left .mapboxgl-ctrl,:host(.lm-on) .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl,:host(.lm-on) .maplibregl-ctrl-bottom-left .maplibregl-ctrl,:host(.lm-on) .maplibregl-ctrl-bottom-right .maplibregl-ctrl,.lm-on .mapboxgl-ctrl-bottom-left .mapboxgl-ctrl,.lm-on .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl,.lm-on .maplibregl-ctrl-bottom-left .maplibregl-ctrl,.lm-on .maplibregl-ctrl-bottom-right .maplibregl-ctrl{margin:8px 0 0;margin-inline:8px 0;}
}
/* In the sheet the legend's rows fill the full width: the clear "x" column does not reserve
space on the right — it floats over the row's right edge only when a row is selected. */
@ -864,12 +862,12 @@ onBeforeUnmount(() => {
})
// ── The credit shows, then folds to its (i) (the bottom-of-map standard) ───
// On a narrow map both engines draw the licence credit compact: expanded at first, folded to an (i) at the
// map's first drag. On a phone that drag may never come, and the expanded credit then sits above the sheet
// for good. So CREDIT_FOLD_MS after it first shows expanded, fold it the way the engine's drag does (drop the
// map's first drag. On a phone that drag may never come, and the expanded credit then runs across the top of
// the map for good, under the map's own top overlays. So CREDIT_FOLD_MS after it first shows expanded, fold it the way the engine's drag does (drop the
// -compact-show class); a tap on the (i) still expands it. The map may still be loading its style when the
// sheet mounts, so look every half second, for up to 30 s; stop once the credit is there and folded (a drag
// or a tap got there first) or is not compact at this width.
const CREDIT_FOLD_MS = 4000
const CREDIT_FOLD_MS = 3000
let _creditTimer = 0
function watchCredit(triesLeft) {
_creditTimer = 0