Fix wave: dropdown keyboard/focus, appearance resets, inline key editors, content-sized slider
- MenuShell: after placement, focus lands in the search when the menu has one, else the body (tabIndex -1) — the lists' mount-time focus ran during the hidden measuring pass and silently failed, so no dropdown ever opened focused. The body owns the arrow machine for searchless menus: ArrowDown/Up cycle options with wrap (first/last entry from the body, native-select convention), Home/End, Enter activates, preventDefault so arrows never scroll the page. - Appearance: the CSS-var applier only ever setProperty'd — a later write omitting a var left the stale inline value forever (empty background never reset, serif toggle-back looked dead). appliedNamesRef tracks what was set; staleVarNames (pure, exported) returns what to removeProperty. - CommitInput: controlled — after a commit the field snaps to the stored record, so the clamp on a -5 prose size is visible (12), Esc reverts. - Keys: Add-provider dropdown closes on pick; the paste row is inline (label | input | Save | Cancel); existing-row editors go inline with an explicit Cancel beside Save/Delete — folding is visible, not Esc-only. - Graph context: readout is content-sized (tabular-nums) — no fixed-width dead gap when "off"; the dictation strip fills whatever space remains. Gates: tsc clean, 866/866 tests (new staleVarNames suite), lint 0, build ok. Live-verified via Playwright: dropdown focus+arrow cycles+wrap+Enter pick, background set→empty reset, serif round-trip, visible clamp to 12, provider pick closes menu, inline editor + Cancel + Esc fold, slider width 270→277px.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
import { appearanceVars, derivedPalette, resolveAppearance } from "../components/settings/appearance.tsx";
|
||||
import { appearanceVars, derivedPalette, resolveAppearance, staleVarNames } from "../components/settings/appearance.tsx";
|
||||
import {
|
||||
composePromptSwitch,
|
||||
composeSearchEngine,
|
||||
@@ -105,6 +105,42 @@ describe("appearanceVars — the mapping the provider applies", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("staleVarNames — the removal half of application (owner repro: resets never reverted)", () => {
|
||||
it("a full delta applied, then factory: every delta-only name goes stale", () => {
|
||||
const fullDelta = appearanceVars(
|
||||
resolveAppearance({
|
||||
background: "#101820",
|
||||
fontFamily: "Georgia",
|
||||
sessionNameSerif: false,
|
||||
mdRendering: { headingWeight: 700, boldColor: "#ff0000", italicColor: "#00ff00" },
|
||||
}),
|
||||
);
|
||||
const applied = Object.keys(fullDelta);
|
||||
const factory = appearanceVars(resolveAppearance(undefined));
|
||||
const stale = staleVarNames(applied, factory);
|
||||
assert.ok(stale.includes("--background"));
|
||||
assert.ok(stale.includes("--font-prose"));
|
||||
assert.ok(stale.includes("--font-title"), "serif toggle back ON must clear the title override");
|
||||
assert.ok(stale.includes("--lh-ink-strong"));
|
||||
assert.ok(stale.includes("--lh-ink-italic"));
|
||||
assert.ok(!stale.includes("--lh-prose-size"), "always-applied tokens never go stale");
|
||||
assert.ok(!stale.includes("--lh-heading-weight"), "always-applied tokens never go stale");
|
||||
});
|
||||
|
||||
it("an empty background commit (null = factory) frees the palette vars", () => {
|
||||
const withBg = appearanceVars(resolveAppearance({ background: "#101010" }));
|
||||
const emptied = appearanceVars(resolveAppearance({ background: null }));
|
||||
const stale = staleVarNames(Object.keys(withBg), emptied);
|
||||
assert.ok(stale.includes("--background"));
|
||||
assert.ok(stale.includes("--card"), "the derived palette follows the background out");
|
||||
assert.equal(emptied["--background"], undefined);
|
||||
});
|
||||
|
||||
it("no previous applications → nothing stale", () => {
|
||||
assert.deepEqual(staleVarNames([], appearanceVars(resolveAppearance(undefined))), []);
|
||||
});
|
||||
});
|
||||
|
||||
describe("agent section compose helpers — the replace-whole PUT body", () => {
|
||||
it("composeTool carries the rest of the section verbatim", () => {
|
||||
const before = { tools: { demo: false }, prompts: { "system-prompt.md": true } };
|
||||
|
||||
Reference in New Issue
Block a user