Skip to content

Commit 5cf3f13

Browse files
committed
fix(sessions): the label-collapse thresholds were too low, not just mis-commented
Review flagged the comments: they still said "a fifth button" and "five labelled buttons ... ~300px" next to a row that now renders six. Correct — and going to fix the wording turned up a real bug behind it. MEASURED the shipped styling in headless Chrome, six labels rendered: chat.html 434px padding 0 9px, 11.5px text, gap 6, 1px border sessionsView.html 363px padding 0 8px, 11px text, gap 4, no border The thresholds were 420 and 400. So chat.html had a 14px band — content widths between 420 and 434 — where the labels were still painted and the nowrap row spilled out of the card. Exactly the failure the guard was added to prevent, reintroduced by raising the button count without re-measuring. Now 460 and 390, both above the need with room for a wider system font. The comments are rewritten with the real numbers and a note to re-measure when adding a button. The test is rewritten to assert the RELATIONSHIP rather than a regex shape. It now parses the threshold and requires it to be >= the measured need, so a seventh button fails until someone re-measures, and the message says why: chat.html: labels collapse at 420px but six labelled buttons need 434px — between those widths the labels paint and the nowrap row overflows the card Boundary verified: 433 rejected, 434 accepted, and the 420 that shipped rejected. All 32 suites green.
1 parent 82e76fc commit 5cf3f13

3 files changed

Lines changed: 40 additions & 23 deletions

File tree

extensions/levelcode-ai/media/chat.html

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,12 +1107,16 @@
11071107
.sesscard .sessline2 { margin-top: 4px; min-height: 26px; display: flex; align-items: center; }
11081108
.sesscard .sesssub { font-family: var(--vscode-editor-font-family, ui-monospace, monospace); font-size: 11.5px; color: var(--cc-text3); }
11091109
/* The action row is nowrap by design (the card is two fixed-height lines — nothing may reflow), so
1110-
a fifth button cannot be allowed to overflow a narrow sidebar. Below the width where five
1111-
labelled buttons fit, the labels drop and the row becomes icon-only: ~184px instead of ~300px.
1110+
a button that does not fit OVERFLOWS the card rather than wrapping. Six labelled buttons
1111+
(Rename · Fork · Copy · Done · Delete · Pin) measure 434px at this styling; icon-only they are
1112+
~200px. The threshold therefore has to sit ABOVE 434, not below it — at 420 there was a band of
1113+
widths where the labels were still painted and the row spilled out of the card. 460 leaves room
1114+
for a wider system font.
11121115
`title` + `aria-label` are on every button already, so nothing is lost to a pointer or a screen
1113-
reader — only to the eye, and only when there is no room for it. */
1116+
reader — only to the eye, and only when there is no room for it.
1117+
ADDING A BUTTON? Re-measure and raise this; test/webviewCss.test.js pins the floor. */
11141118
.sesscard { container-type: inline-size; }
1115-
@container (max-width: 420px) { .sesscard .sesslbl { display: none; } }
1119+
@container (max-width: 460px) { .sesscard .sesslbl { display: none; } }
11161120
.sesscard .sessacts { display: none; align-items: center; gap: 6px; flex-wrap: nowrap; }
11171121
.sesscard:hover .sesssub, .sesscard:focus-within .sesssub { display: none; }
11181122
.sesscard:hover .sessacts, .sesscard:focus-within .sessacts { display: flex; }

extensions/levelcode-ai/media/sessionsView.html

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,13 @@
8787
left intact. Sidebar buttons are label-only (icon hidden) to stay compact in a narrow panel. */
8888
.sesscard .sessline2 { margin: 2px 0 0 16px; min-height: 22px; display: flex; align-items: center; }
8989
.sesscard .sesssub { font-size: 12px; color: var(--cc-text3); }
90-
/* Same reasoning as chat.html: the row is nowrap, so a fifth button must not overflow a narrow
91-
pane. Below the width where five labelled buttons fit, drop to icons — title + aria-label are
92-
already on every button, so only the eye loses anything, and only when there is no room. */
90+
/* Same reasoning as chat.html, different numbers — this pane's buttons are smaller (22px tall,
91+
8px padding, 11px text, no border), so six labelled ones measure 363px rather than 434px. The
92+
threshold sits above that; below it the row drops to icons, keeping title + aria-label, so only
93+
the eye loses anything and only when there is no room.
94+
ADDING A BUTTON? Re-measure and raise this; test/webviewCss.test.js pins the floor. */
9395
.sesscard { container-type: inline-size; }
94-
@container (max-width: 400px) { .sesscard .sesslbl { display: none; } }
96+
@container (max-width: 390px) { .sesscard .sesslbl { display: none; } }
9597
.sesscard .sessacts { display: none; align-items: center; gap: 4px; flex-wrap: nowrap; }
9698
.sesscard:hover .sesssub, .sesscard:focus-within .sesssub { display: none; }
9799
.sesscard:hover .sessacts, .sesscard:focus-within .sessacts { display: flex; }

extensions/levelcode-ai/test/webviewCss.test.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -214,24 +214,35 @@ test('an approved MCP tool call folds its run-node into the approval chip (one r
214214
assert.ok(/mcpMergePending = null;/.test(line), 'and closes a stale merge window on any other row');
215215
});
216216

217-
test('SESSION CARD: six nowrap action buttons cannot overflow a narrow pane', () => {
218-
// The card is two fixed-height lines and the action row is `flex-wrap: nowrap`, so buttons that
219-
// do not fit do not wrap — they overflow. Five LABELLED buttons need roughly 300px; a sidebar is
220-
// routinely narrower. The labels therefore have to disappear before that happens.
217+
test('SESSION CARD: the label-collapse threshold is above the width the labels actually need', () => {
218+
// The card is two fixed-height lines and the action row is `flex-wrap: nowrap`, so buttons that do
219+
// not fit do not wrap — they OVERFLOW the card.
221220
//
222-
// This is pinned because the failure is invisible in a wide window: whoever adds a sixth button
223-
// will not see it break, and the person who does see it will be a user with a narrow sidebar.
224-
const both = [
225-
['chat.html', css],
226-
['sessionsView.html', fs.readFileSync(path.join(__dirname, '..', 'media', 'sessionsView.html'), 'utf8')]
227-
];
228-
for (const [where, sheet] of both) {
221+
// The numbers below were MEASURED in headless Chrome against the shipped button styling, with all
222+
// six labels (Rename · Fork · Copy · Done · Delete · Pin) rendered:
223+
//
224+
// chat.html 434px padding 0 9px, 11.5px text, gap 6, 1px border
225+
// sessionsView.html 363px padding 0 8px, 11px text, gap 4, no border
226+
//
227+
// A threshold BELOW those leaves a band of widths where the labels are still painted and the row
228+
// spills out of the card — which is exactly what shipped at 420/400 until this test existed. The
229+
// assertion is therefore on the RELATIONSHIP, not on a magic number: raise a threshold freely,
230+
// but never below what the labels need. Add a seventh button and this fails until you re-measure.
231+
const NEEDS = { 'chat.html': 434, 'sessionsView.html': 363 };
232+
const sheets = {
233+
'chat.html': css,
234+
'sessionsView.html': fs.readFileSync(path.join(__dirname, '..', 'media', 'sessionsView.html'), 'utf8')
235+
};
236+
for (const [where, sheet] of Object.entries(sheets)) {
229237
assert.match(sheet, /\.sesscard\s*\{[^}]*container-type:\s*inline-size/,
230-
where + ': the card must be a container for the query below to resolve against IT rather than the viewport');
231-
assert.match(sheet, /@container\s*\(max-width:\s*[34][0-9]{2}px\)\s*\{\s*\.sesscard \.sesslbl\s*\{\s*display:\s*none/,
232-
where + ': no width at which the labels collapse — a narrow pane will overflow');
238+
where + ': the card must be a container, or the query resolves against the viewport instead');
239+
const m = /@container\s*\(max-width:\s*(\d+)px\)\s*\{\s*\.sesscard \.sesslbl\s*\{\s*display:\s*none/.exec(sheet);
240+
assert.ok(m, where + ': no width at which the labels collapse — a narrow pane will overflow');
241+
assert.ok(Number(m[1]) >= NEEDS[where],
242+
where + ': labels collapse at ' + m[1] + 'px but six labelled buttons need ' + NEEDS[where]
243+
+ 'px — between those widths the labels paint and the nowrap row overflows the card');
233244
assert.match(sheet, /\.sesscard \.sessacts \{[^}]*flex-wrap:\s*nowrap/,
234-
where + ': the row stopped being nowrap, so this guard is now testing the wrong failure');
245+
where + ': the row stopped being nowrap, so this guard now tests the wrong failure');
235246
}
236247
});
237248

0 commit comments

Comments
 (0)