mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-07-18 14:36:18 +00:00
## Summary Fixes #1833 — the `.legend-toggle-btn` (palette icon) on the Live view was hardcoded to `bottom: 1rem`, so on typical desktop viewports it sat underneath the VCR playback bar and was unreachable. The reporter had to hide the legend via `localStorage` to work around it. ## Fix `public/live.css:1313` — one-character-class change: ```diff .legend-toggle-btn { position: fixed; - bottom: 1rem; + bottom: calc(var(--vcr-bar-height, 58px) + 10px); right: 1rem; ``` Mirrors the existing pattern already used by every other bottom-pinned Live overlay: - `.live-feed` (live.css:1204) - `.live-overlay[data-position="br"]` (live.css:1372) - `.feed-show-btn` (live.css:903) `--vcr-bar-height` is maintained by the ResizeObserver on `.vcr-bar`, so the button now tracks bar growth (mobile two-row layout, safe-area-inset) instead of overlapping. Same class of regression as #685 / #1206 / #1107 — an overlay that was missed in the prior sweep. ## TDD - Red commit `f6a938b7`: `test-issue-1833-legend-toggle-vcr-offset.js` asserts `.legend-toggle-btn`'s `bottom` declaration references `var(--vcr-bar-height`. Fails on assertion (not build error) against the hardcoded `1rem`. - Green commit `e399092b`: the CSS one-liner above. All 3 assertions pass. Grep-based CSS assertion per AGENTS.md § "E2E-DOM-grep exemption" — there is no existing Playwright test in this area that measures the toggle-button rect against `--vcr-bar-height`, and standing one up would be disproportionate for a single-property fix that mirrors three existing, tested overlay patterns. ## Preflight `bash ~/.openclaw/skills/pr-preflight/scripts/run-all.sh origin/master` — all hard gates pass, no warnings. ## Browser verified Not required per fix-issue skill (CSS-only, mirrors three existing tested patterns). Staging will pick up the change on merge; visual regression will be caught if the mirrored pattern breaks (grep test in this PR + existing E2E tests on the sister overlays). --------- Co-authored-by: corescope-bot <bot@corescope.local> Co-authored-by: openclaw-bot <bot@openclaw.local>
This commit is contained in:
co-authored by
corescope-bot
openclaw-bot
parent
56fe844871
commit
4f7bb245d4
+1
-1
@@ -1310,7 +1310,7 @@ input.live-node-filter-input:focus {
|
||||
* inside the map container. */
|
||||
.legend-toggle-btn {
|
||||
position: fixed;
|
||||
bottom: 1rem;
|
||||
bottom: calc(var(--vcr-bar-height, 58px) + 10px);
|
||||
right: 1rem;
|
||||
z-index: 500;
|
||||
background: color-mix(in srgb, var(--surface-1) 92%, transparent);
|
||||
|
||||
@@ -90,8 +90,8 @@ if (legendBtn) {
|
||||
'.legend-toggle-btn uses position: fixed (pinned to viewport)'
|
||||
);
|
||||
assert(
|
||||
/bottom\s*:\s*1rem/.test(legendBtn),
|
||||
'.legend-toggle-btn pinned at bottom: 1rem'
|
||||
/bottom\s*:\s*(1rem|max\(1rem|calc\(\s*var\(--vcr-bar-height)/.test(legendBtn),
|
||||
'.legend-toggle-btn pinned at bottom: 1rem / max(1rem,...) / calc(var(--vcr-bar-height,...)+...) (VCR-bar-aware, #1833)'
|
||||
);
|
||||
assert(
|
||||
/right\s*:\s*1rem/.test(legendBtn),
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Regression (#1833): the .legend-toggle-btn on the Live view was hardcoded
|
||||
* to `bottom: 1rem`, so it sat underneath the VCR playback bar and was
|
||||
* unreachable. Sister overlays (.live-feed, .live-overlay[data-position="br"],
|
||||
* .feed-show-btn) all offset their bottom by `var(--vcr-bar-height, ...)`.
|
||||
*
|
||||
* Same class of regression as #685 / #1206 / #1107. Test asserts the CSS rule
|
||||
* uses --vcr-bar-height so bottom-pinned Live overlays stay pinned above the
|
||||
* VCR bar. Grep-based per AGENTS.md E2E-DOM-grep exemption.
|
||||
*
|
||||
* Run: node test-issue-1833-legend-toggle-vcr-offset.js
|
||||
*/
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const cssPath = path.join(__dirname, 'public', 'live.css');
|
||||
const css = fs.readFileSync(cssPath, 'utf8');
|
||||
|
||||
let passed = 0, failed = 0;
|
||||
function step(name, fn) {
|
||||
try { fn(); passed++; console.log(' \u2713 ' + name); }
|
||||
catch (e) { failed++; console.error(' \u2717 ' + name + ': ' + e.message); }
|
||||
}
|
||||
function assert(c, m) { if (!c) throw new Error(m || 'assertion failed'); }
|
||||
|
||||
// Extract a rule body whose selector list is EXACTLY the given selector
|
||||
// (avoids matching compound rules like `.live-feed .panel-content`).
|
||||
function extractRule(source, selector) {
|
||||
const escaped = selector.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
const re = new RegExp('(?:^|})\\s*' + escaped + '\\s*\\{', 'm');
|
||||
const m = re.exec(source);
|
||||
assert(m, 'selector not found (exact match): ' + selector);
|
||||
const open = source.indexOf('{', m.index);
|
||||
const close = source.indexOf('}', open);
|
||||
assert(open !== -1 && close !== -1, 'malformed rule for: ' + selector);
|
||||
return source.slice(open + 1, close);
|
||||
}
|
||||
|
||||
console.log('#1833: .legend-toggle-btn must offset for --vcr-bar-height');
|
||||
|
||||
step('.legend-toggle-btn rule exists', () => {
|
||||
assert(/\.legend-toggle-btn\s*\{/.test(css), '.legend-toggle-btn rule missing from live.css');
|
||||
});
|
||||
|
||||
step('.legend-toggle-btn bottom uses var(--vcr-bar-height)', () => {
|
||||
// There may be several `.legend-toggle-btn { ... }` blocks (media queries,
|
||||
// fullscreen). Only the one that declares `bottom` matters here.
|
||||
const re = /\.legend-toggle-btn\s*\{([^}]*)\}/g;
|
||||
let m, bottomValue = null;
|
||||
while ((m = re.exec(css))) {
|
||||
const bodyMatch = m[1].match(/(?:^|;|\s)bottom\s*:\s*([^;]+);/);
|
||||
if (bodyMatch) { bottomValue = bodyMatch[1].trim(); break; }
|
||||
}
|
||||
assert(bottomValue !== null, 'no .legend-toggle-btn rule declares `bottom`');
|
||||
assert(
|
||||
/var\(\s*--vcr-bar-height/.test(bottomValue),
|
||||
'.legend-toggle-btn bottom does not reference --vcr-bar-height (got: ' + bottomValue + ')'
|
||||
);
|
||||
});
|
||||
|
||||
step('sister overlays still track --vcr-bar-height (guard against regression sweep)', () => {
|
||||
// Sanity check: the pattern we mirror is the same one already used by
|
||||
// .live-feed, .live-overlay[data-position="br"], and .feed-show-btn.
|
||||
// These selectors each have at least one rule whose body sets
|
||||
// `bottom: calc(var(--vcr-bar-height, ...) ...)`.
|
||||
const patterns = [
|
||||
/\.live-feed\s*\{[^}]*var\(\s*--vcr-bar-height/,
|
||||
/\.live-overlay\[data-position="br"\][^{]*\{[^}]*var\(\s*--vcr-bar-height/,
|
||||
/\.feed-show-btn\s*\{[^}]*var\(\s*--vcr-bar-height/,
|
||||
];
|
||||
for (const re of patterns) {
|
||||
assert(re.test(css), 'sister overlay pattern missing: ' + re.source);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('\nResults: ' + passed + ' passed, ' + failed + ' failed');
|
||||
if (failed > 0) process.exit(1);
|
||||
Reference in New Issue
Block a user