fix(ui): give the rail its own short labels instead of the sheet's sentences
The corner rail rendered `Shortcut.meaning`, which is written for the `?` sheet where a full sentence is exactly right because somebody is reading a reference. The rail is a glance over a moving 3D board with room for one line, and it is a `flex-wrap` container: the sentence wrapped, and the wrapped line drew straight through the chip beneath it. On the deployed build "Fly to a chapter of the tour, or to a viewpoint inside a studio" and "Walk into the studio, or step back out to the city" overlapped and neither could be read, over a bright sky with no background to hide it. Nothing errored — it just looked broken, on every screen. Two labels for two jobs. `Shortcut.rail` carries the two-or-three-word form for the nine ids `railHints` can select; `meaning` keeps the sentence for the sheet. `.hint` also had no `line-height`, so it inherited the body's and a wrapped chip had nowhere to go, and no `max-width`, so the rail grew leftward until it met the mode pill. Chips are now `white-space: nowrap`: wrapping belongs between chips, which the flex container already does, not inside one. Tested, because this is a defect a test can hold: every id the rail can return must have a `rail` label, it must fit on a line, and it must not contain a clause. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -244,3 +244,60 @@ describe("the rail hint", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* The rail is a glance, not a reference.
|
||||
*
|
||||
* Every hint the rail can show reused `meaning` — a full sentence written for
|
||||
* the `?` sheet. In a `flex-wrap` container over a live 3D board that wrapped,
|
||||
* and the wrapped line drew straight through the chip beneath it: on the
|
||||
* deployed build "Fly to a chapter of the tour, or to a viewpoint inside a
|
||||
* studio" and "Walk into the studio, or step back out to the city" overlapped
|
||||
* and neither could be read. Nothing failed; it just looked broken.
|
||||
*
|
||||
* So: every id `railHints` is capable of returning must carry a short `rail`
|
||||
* label, and it must be short enough to stay on one line.
|
||||
*/
|
||||
describe("rail hint labels", () => {
|
||||
/** Every mode the rail is asked about, from `controlMode.ts`. */
|
||||
const MODES = [
|
||||
"overview",
|
||||
"drive",
|
||||
"actor",
|
||||
"aircraft",
|
||||
"office-overview",
|
||||
"office-walk",
|
||||
] as const;
|
||||
|
||||
it("gives every rail-selectable shortcut a short label of its own", () => {
|
||||
for (const mode of MODES) {
|
||||
for (const entry of railHints(mode, false)) {
|
||||
assert.ok(
|
||||
entry.rail !== undefined,
|
||||
`${mode}: shortcut "${entry.id}" can reach the rail with no rail label, ` +
|
||||
`so it would fall back to its ${entry.meaning.length}-character sentence`,
|
||||
);
|
||||
assert.ok(
|
||||
entry.rail.length <= 16,
|
||||
`${mode}: rail label "${entry.rail}" is ${entry.rail.length} characters; ` +
|
||||
`the rail has room for a glance, not a clause`,
|
||||
);
|
||||
assert.ok(
|
||||
!entry.rail.includes(","),
|
||||
`${mode}: rail label "${entry.rail}" carries a clause; that belongs in meaning`,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps the long form for the sheet, which is where it reads correctly", () => {
|
||||
const [chapters] = railHints("overview", false);
|
||||
assert.ok(chapters !== undefined);
|
||||
assert.notEqual(chapters.rail, chapters.meaning);
|
||||
assert.ok(chapters.meaning.length > 20, "the sheet should still get the sentence");
|
||||
});
|
||||
|
||||
it("shows nothing at all on a coarse pointer, which has no keys to press", () => {
|
||||
for (const mode of MODES) assert.deepEqual(railHints(mode, true), []);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user