[feat](trx-frontend-http): centre the radio controls, split off the mode row
CI / lint (push) Successful in 2m19s
CI / test (push) Successful in 8m13s
CI / frontend (push) Failing after 32s
CI / reuse (push) Successful in 3s

The controls every rig has — mode, wheel, tune step, transmit — now sit
as a centred block rather than packed against the left edge.

What the current mode adds moves out from among them: WFM's six controls
stretched the row sideways whenever it was active, pushing the wheel and
the step pickers off centre, and SAM did the same on a smaller scale.
They get a row of their own below a divider, which appears and leaves
with them — an empty one would still take a track and a gap in the tray
and draw its divider under controls it has nothing to do with.

Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
sjg
2026-08-03 22:29:31 +02:00
parent e70e82c8c0
commit f95f3d0104
5 changed files with 41 additions and 8 deletions
@@ -5145,6 +5145,7 @@ const wfmCciValEl = document.getElementById("wfm-cci-val");
const wfmAciFillEl = document.getElementById("wfm-aci-fill");
const wfmAciValEl = document.getElementById("wfm-aci-val");
const samControlsCol = document.getElementById("sam-controls-col");
const modeControlsRow = document.getElementById("mode-controls-row");
const samStereoWidthEl = document.getElementById("sam-stereo-width") as HTMLInputElement | null;
const samCarrierSyncEl = document.getElementById("sam-carrier-sync") as HTMLSelectElement | null;
const sdrSquelchWrapEl = document.getElementById("sdr-squelch-wrap");
@@ -5463,6 +5464,9 @@ function updateWfmControls() {
const mode = (modeEl && modeEl.value ? modeEl.value : "").toUpperCase();
if (wfmControlsCol) wfmControlsCol.style.display = mode === "WFM" ? "" : "none";
if (samControlsCol) samControlsCol.style.display = mode === "SAM" ? "" : "none";
// The row holds only these two, so it goes with them — an empty one would
// still take a track and a gap in the tray, and draw its divider.
if (modeControlsRow) modeControlsRow.style.display = (mode === "WFM" || mode === "SAM") ? "" : "none";
}
// Show compatibility warning for non-Chromium browsers
@@ -49,6 +49,23 @@ try {
assert.equal(modeAfter.active, target, "the clicked mode is not the marked one");
assert.ok(modeAfter.selectWidth <= 2, `the hidden select still occupies ${modeAfter.selectWidth}px`);
// Mode-specific controls live on their own row, which has to leave with them:
// an empty one would still take a track and a gap in the tray and draw its
// divider under the controls every rig has.
const modeRowState = async () => page.evaluate(() => {
const row = document.getElementById("mode-controls-row");
return { display: getComputedStyle(row).display, height: Math.round(row.getBoundingClientRect().height) };
});
await page.locator('#mode-picker button[data-mode="WFM"]').click();
await page.waitForTimeout(250);
const withWfm = await modeRowState();
assert.notEqual(withWfm.display, "none", "WFM controls did not bring their row up");
assert.ok(withWfm.height > 0, `WFM row has no height (${withWfm.height}px)`);
await page.locator('#mode-picker button[data-mode="FM"]').click();
await page.waitForTimeout(250);
const withoutWfm = await modeRowState();
assert.equal(withoutWfm.display, "none", "the mode row stayed behind with nothing in it");
// Scheduler controls read left to right: step, hand back, then the entry on
// air. The separator is drawn by the current-entry block, so it can only sit
// in the right place if that block is last.