attribution icon tweaks
Hunter
Sunday, August 30th, 2026 at 10:04 PM
74
75 map.getCanvas().setAttribute("tabindex", "-1");
76
- map.addControl(new maplibregl.AttributionControl({ compact: true }), "bottom-left");
- collapseAttribution();
77 + map.addControl(new maplibregl.AttributionControl({ compact: true }), "top-right");
78 + initAttribution();
79
80 var endWheelGesture = initSmoothWheel();
81
238 return settle;
239 }
240
- function collapseAttribution() {
241 + // Collapses the compact attribution once the style names its sources, then takes
242 + // the button over from maplibre so a tap anywhere else can dismiss it.
243 + function initAttribution() {
244 var el = map.getContainer().querySelector(".maplibregl-ctrl-attrib");
245 if (!el) { return; }
246 + var button = el.querySelector(".maplibregl-ctrl-attrib-button");
247 +
248 + function shown() { return el.classList.contains("maplibregl-compact-show"); }
249 +
250 + // maplibre's own handler pre-flips `open` so the native <details> toggle lands
251 + // on the right value; we suppress both, so `open` just tracks the panel
252 + function setShown(show) {
253 + el.classList.toggle("maplibregl-compact-show", show);
254 + if (show) { el.setAttribute("open", ""); } else { el.removeAttribute("open"); }
255 + }
256 +
257 + if (button) {
258 + // capture on the container beats maplibre's own listener on the button;
259 + // preventDefault also keeps the native <details> from double-toggling
260 + el.addEventListener("click", function (e) {
261 + if (!button.contains(e.target)) { return; }
262 + e.preventDefault();
263 + e.stopPropagation();
264 + setShown(!shown());
265 + }, true);
266 + }
267 +
268 + // anything else on the page dismisses it; capture on the document so a
269 + // stopPropagation further in (the event pins do it) can't swallow the tap
270 + document.addEventListener("click", function (e) {
271 + if (button && button.contains(e.target)) { return; }
272 + if (shown()) { setShown(false); }
273 + }, true);
274 +
275 function collapse() {
276 if (!el.classList.contains("maplibregl-compact")) { return; } // no text yet
- el.classList.remove("maplibregl-compact-show");
277 + setShown(false);
278 map.off("sourcedata", collapse);
279 map.off("styledata", collapse);
280 }
254 inset: 0;
255 }
256
257 +.maplibregl-canvas-container {
258 + isolation: isolate;
259 +}
260 +
261 .maplibregl-ctrl-attrib.maplibregl-compact {
262 margin: 12px;
263 background: rgba(255, 255, 255, 0.7);
266 box-shadow: 0 1px 3px #00000040;
267 -webkit-tap-highlight-color: transparent;
268 }
269 +/* the standalone status-bar tint band is the real top edge; sit below it */
270 +@media (display-mode: standalone) {
271 + .maplibregl-ctrl-attrib.maplibregl-compact {
272 + margin-top: calc(12px + var(--status-tint-h));
273 + }
274 +}
275 .maplibregl-ctrl-attrib-button {
276 background-color: transparent;
- background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='%237a7f85' fill-rule='evenodd' viewBox='0 0 20 20'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E");
277 + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='%237a7f85' fill-opacity='0.8' fill-rule='evenodd' viewBox='0 0 20 20'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E");
278 }
279
280 .maplibregl-ctrl-attrib.maplibregl-compact-show .maplibregl-ctrl-attrib-button,
290 box-shadow: 0 0 2px 2px #0096ff;
291 }
292
293 +/* mirrors the compass: pad the tap target out to the map corner */
294 +@media (pointer: coarse) {
295 + .maplibregl-ctrl-attrib-button::after {
296 + content: "";
297 + position: absolute;
298 + top: -12px;
299 + right: -12px;
300 + bottom: 0;
301 + left: 0;
302 + border-radius: 0 0 0 12px;
303 + }
304 +}
305 +
306 #compass {
307 display: none;
308 position: absolute;