Restyle location-picker map: themed CARTO basemap + branded pin
Replace the plain gray OpenStreetMap raster in the location picker with a theme-aware CARTO basemap (no API key): sleek "dark matter" tiles under the dark theme, colorful "voyager" tiles under the light theme, so the map matches whichever is active. Swap Leaflet's default blue marker for an accent-colored teardrop pin (the same glyph the Find button uses), and theme the zoom controls + attribution to sit in the app's surfaces. - mappicker.js: theme-aware CARTO tileLayer (retina, CARTO attribution); L.divIcon "mp-pin" used for the marker - style.css: .mp-pin styling, themed .leaflet-bar / attribution, map shadow Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B3Q2EkHHnTUX2BfhV5q1Zc
This commit is contained in:
parent
4b23fda4ec
commit
dade6c3cb4
2 changed files with 38 additions and 5 deletions
|
|
@ -9,7 +9,7 @@
|
|||
// itself is created lazily the first time the picker opens (and reused after), so
|
||||
// pages that never open it pay nothing.
|
||||
(function () {
|
||||
let overlay, mapEl, map, marker, pin = null, onPickCb = null;
|
||||
let overlay, mapEl, map, marker, pin = null, onPickCb = null, pinIcon = null;
|
||||
let searchForm, searchInput, sugEl, confirmBtn, hintEl;
|
||||
|
||||
const PIN_ICON = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>`;
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
function setPin(lat, lon, zoom) {
|
||||
pin = { lat, lon };
|
||||
if (marker) marker.setLatLng([lat, lon]);
|
||||
else marker = L.marker([lat, lon]).addTo(map);
|
||||
else marker = L.marker([lat, lon], pinIcon ? { icon: pinIcon } : undefined).addTo(map);
|
||||
map.setView([lat, lon], zoom || map.getZoom());
|
||||
confirmBtn.disabled = false;
|
||||
hintEl.textContent = "Pin set — confirm below, or tap elsewhere to move it.";
|
||||
|
|
@ -117,10 +117,23 @@
|
|||
overlay.hidden = false;
|
||||
|
||||
if (!map) {
|
||||
map = L.map(mapEl, { worldCopyJump: true }).setView([44.5, -95], 4);
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
maxZoom: 18, attribution: "© OpenStreetMap contributors",
|
||||
map = L.map(mapEl, { worldCopyJump: true, zoomControl: true }).setView([44.5, -95], 4);
|
||||
// Themed CARTO basemap (no key needed) instead of the plain gray OSM raster:
|
||||
// sleek "dark matter" tiles under the app's dark theme, colorful "voyager"
|
||||
// tiles under the light theme, so the picker matches whichever is active.
|
||||
const dark = matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
const tiles = dark
|
||||
? "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png"
|
||||
: "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png";
|
||||
L.tileLayer(tiles, {
|
||||
subdomains: "abcd", maxZoom: 20, detectRetina: true,
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> © <a href="https://carto.com/attributions">CARTO</a>',
|
||||
}).addTo(map);
|
||||
// Branded accent teardrop pin (the same glyph the Find button uses), styled
|
||||
// in style.css — replaces Leaflet's default blue raster marker.
|
||||
pinIcon = L.divIcon({
|
||||
className: "mp-pin", html: PIN_ICON, iconSize: [32, 32], iconAnchor: [16, 30],
|
||||
});
|
||||
map.on("click", (e) => setPin(e.latlng.lat, e.latlng.lng));
|
||||
}
|
||||
// Leaflet measures the container on creation; it's zero-sized while hidden, so
|
||||
|
|
|
|||
|
|
@ -680,7 +680,27 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
|
|||
.mp-map {
|
||||
flex: 1 1 auto; min-height: 300px; margin: 4px 16px; z-index: 0;
|
||||
border-radius: 12px; overflow: hidden; border: 1px solid var(--border);
|
||||
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .25), 0 6px 18px rgba(0, 0, 0, .25);
|
||||
}
|
||||
.mp-map .leaflet-container { background: var(--surface-2); }
|
||||
/* Branded accent teardrop pin (an L.divIcon wrapping the Find-button glyph),
|
||||
replacing Leaflet's default blue raster marker. */
|
||||
.mp-pin { background: none; border: none; filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .45)); }
|
||||
.mp-pin svg { width: 32px; height: 32px; display: block; }
|
||||
.mp-pin path { fill: var(--accent); stroke: rgba(0, 0, 0, .35); stroke-width: 1.25; }
|
||||
.mp-pin circle { fill: #fff; stroke: none; }
|
||||
/* Theme the Leaflet zoom buttons + attribution to sit in the app's surfaces
|
||||
instead of Leaflet's stock white chrome. */
|
||||
.mp-map .leaflet-bar { border: none; box-shadow: 0 2px 8px rgba(0, 0, 0, .3); }
|
||||
.mp-map .leaflet-bar a {
|
||||
background: var(--surface); color: var(--text); border-bottom-color: var(--border);
|
||||
}
|
||||
.mp-map .leaflet-bar a:hover { background: var(--surface-2); color: var(--accent); }
|
||||
.mp-map .leaflet-control-attribution {
|
||||
background: color-mix(in srgb, var(--surface) 80%, transparent);
|
||||
color: var(--muted); backdrop-filter: blur(2px); border-top-left-radius: 6px;
|
||||
}
|
||||
.mp-map .leaflet-control-attribution a { color: var(--accent); }
|
||||
.mp-foot {
|
||||
display: flex; align-items: center; justify-content: space-between; gap: 12px;
|
||||
padding: 12px 16px 16px; flex-wrap: wrap;
|
||||
|
|
|
|||
Loading…
Reference in a new issue