fix(map): Kartenlegende theme-aware (closes #5)

- style.css: .legend nutzt CSS-Variablen (--tblr-bg-surface, --tblr-border-color,
  --tblr-body-color) statt hardcodierter Hex-Farben
- map.js: legendDiv-Referenz, updateLegendTheme() setzt Inline-Styles;
  wird beim onAdd (Init) und im themechange-Listener aufgerufen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ppfeiffer 2026-02-20 22:26:53 +01:00
parent 07676a8c96
commit cbe934ef6e
4 changed files with 34 additions and 15 deletions

View file

@ -1,5 +1,14 @@
# Changelog # Changelog
## [0.08.23] - 2026-02-20
### Fixed
- **Karte: Legende theme-aware** (closes #5): `.legend` nutzt jetzt
`var(--tblr-bg-surface/border-color/body-color)` statt hardcodierter Farben.
`map.js` speichert die Legende als `legendDiv` und aktualisiert per
`updateLegendTheme()` Inline-Styles beim Init und bei jedem `themechange`-Event
zuverlässig auch im Leaflet-Control-Kontext.
## [0.08.22] - 2026-02-20 ## [0.08.22] - 2026-02-20
### Changed ### Changed

View file

@ -1,4 +1,4 @@
version: "0.08.22" version: "0.08.23"
bot: bot:
name: "MeshDD-Bot" name: "MeshDD-Bot"

View file

@ -263,27 +263,20 @@
.node-tooltip-wrap { padding: 0; } .node-tooltip-wrap { padding: 0; }
.legend { .legend {
background: #ffffff; background: var(--tblr-bg-surface, #ffffff);
border: 1px solid rgba(0,0,0,.12); border: 1px solid var(--tblr-border-color, rgba(0,0,0,.12));
border-radius: 6px; border-radius: 6px;
box-shadow: 0 2px 10px rgba(0,0,0,.15); box-shadow: 0 2px 10px rgba(0,0,0,.15);
padding: 7px 10px; padding: 7px 10px;
font-size: 11.5px; font-size: 11.5px;
line-height: 1.4; line-height: 1.4;
min-width: 100px; min-width: 100px;
color: #212529; color: var(--tblr-body-color, #212529);
} }
[data-bs-theme="dark"] .legend { [data-bs-theme="dark"] .legend {
background: #1e2128;
border-color: rgba(255,255,255,.1);
color: #c8d3e1;
box-shadow: 0 2px 12px rgba(0,0,0,.45); box-shadow: 0 2px 12px rgba(0,0,0,.45);
} }
[data-bs-theme="dark"] .legend-section {
color: #6c7a8d;
}
.legend-section { .legend-section {
font-size: 9.5px; font-size: 9.5px;
font-weight: 700; font-weight: 700;

View file

@ -140,9 +140,22 @@ function connectWebSocket() {
} }
// Legend // Legend
let legendDiv = null;
const LEGEND_LIGHT = { bg: 'var(--tblr-bg-surface, #ffffff)', border: 'var(--tblr-border-color, rgba(0,0,0,.12))', color: 'var(--tblr-body-color, #212529)' };
const LEGEND_DARK = { bg: 'var(--tblr-bg-surface, #1e2128)', border: 'var(--tblr-border-color, rgba(255,255,255,.1))', color: 'var(--tblr-body-color, #c8d3e1)' };
function updateLegendTheme(theme) {
if (!legendDiv) return;
const c = theme === 'dark' ? LEGEND_DARK : LEGEND_LIGHT;
legendDiv.style.background = c.bg;
legendDiv.style.borderColor = c.border;
legendDiv.style.color = c.color;
}
const legend = L.control({ position: 'topleft' }); const legend = L.control({ position: 'topleft' });
legend.onAdd = function () { legend.onAdd = function () {
const div = L.DomUtil.create('div', 'legend'); legendDiv = L.DomUtil.create('div', 'legend');
const hopEntries = [ const hopEntries = [
[0, 'Direkt'], [0, 'Direkt'],
[1, '1 Hop'], [1, '1 Hop'],
@ -157,7 +170,7 @@ legend.onAdd = function () {
['rgba(80,80,80,.45)', '2448h'], ['rgba(80,80,80,.45)', '2448h'],
['rgba(80,80,80,.18)', '4872h'], ['rgba(80,80,80,.18)', '4872h'],
]; ];
div.innerHTML = legendDiv.innerHTML =
'<div class="legend-section">Hops</div>' + '<div class="legend-section">Hops</div>' +
hopEntries.map(([hop, label]) => { hopEntries.map(([hop, label]) => {
const color = hop != null ? (hopColors[hop] || hopColorDefault) : hopColorDefault; const color = hop != null ? (hopColors[hop] || hopColorDefault) : hopColorDefault;
@ -167,7 +180,8 @@ legend.onAdd = function () {
ageEntries.map(([color, label]) => ageEntries.map(([color, label]) =>
`<div class="legend-item"><span class="legend-dot" style="background:${color}"></span>${label}</div>` `<div class="legend-item"><span class="legend-dot" style="background:${color}"></span>${label}</div>`
).join(''); ).join('');
return div; updateLegendTheme(localStorage.getItem('theme') || 'dark');
return legendDiv;
}; };
// Init map after layout is ready // Init map after layout is ready
@ -197,7 +211,10 @@ setMapTheme(localStorage.getItem('theme') || 'dark');
legend.addTo(map); legend.addTo(map);
document.addEventListener('themechange', (e) => setMapTheme(e.detail.theme)); document.addEventListener('themechange', (e) => {
setMapTheme(e.detail.theme);
updateLegendTheme(e.detail.theme);
});
// Invalidate size after short delay so sidebar layout settles // Invalidate size after short delay so sidebar layout settles
setTimeout(() => { map.invalidateSize(); }, 200); setTimeout(() => { map.invalidateSize(); }, 200);