Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/rail-rename-unclamp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"aicodeman": patch
---

Renaming a session in the detailed vertical tab rail no longer leaves the 3-line name clamp on the inline editor: the card-row rule out-ranked the "unclamp while renaming" override.
11 changes: 11 additions & 0 deletions src/web/public/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -18815,6 +18815,17 @@ html[data-tab-orientation='vertical'][data-tab-rail-detail='rich']:not(.tab-rail
line-clamp: 3;
}

/* The rule above out-ranks the shared "unclamp while renaming" override (it carries four more
selectors of specificity), so a detailed-rail row kept its 3-line clamp around the inline
editor. Restate the override at the same weight; it must stay AFTER the rule it beats. */
html[data-tab-orientation='vertical'][data-tab-rail-detail='rich']:not(.tab-rail-compact)
.tab-rail
.session-tab
.tab-name.tab-name-renaming {
-webkit-line-clamp: unset;
line-clamp: unset;
}

html[data-tab-orientation='vertical'][data-tab-rail-detail='rich']:not(.tab-rail-compact) .tab-rail .session-tab .tab-folder {
font-size: 0.66rem;
margin-top: 0.1rem;
Expand Down
112 changes: 62 additions & 50 deletions test/inline-rename.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,54 +581,66 @@ describe('Inline rename input', () => {
expect(await input.evaluate((node) => node.getBoundingClientRect().width)).toBeGreaterThan(0);
});

it('Vertical rail paints typing in an unclamped editor and restores the clamp on cancel', async () => {
await resetState();
const id = 'vertical-live-input';

await page.evaluate((sessionId) => {
const app = (
window as unknown as {
app: {
sessions: Map<string, { id: string; name: string }>;
startInlineRename: (id: string) => void;
};
}
).app;
document.documentElement.dataset.tabOrientation = 'vertical';
const rail = document.getElementById('tabRail') as HTMLElement;
const tab = document.createElement('div');
tab.setAttribute('data-test-tab', '1');
tab.className = 'session-tab';
tab.innerHTML =
`<span class="tab-name" data-session-id="${sessionId}">` +
'<span class="tab-name-prefix">w9-case: </span>old</span>';
rail.appendChild(tab);
app.sessions.set(sessionId, { id: sessionId, name: 'w9-case: old' });
app.startInlineRename(sessionId);
}, id);

const label = page.locator(`.tab-name[data-session-id="${id}"]`);
const input = label.locator('input.tab-rename-input');
await input.press(process.platform === 'darwin' ? 'Meta+A' : 'Control+A');
await page.keyboard.type('edited title');

expect(await input.inputValue()).toBe('edited title');
expect(await input.evaluate((node) => document.activeElement === node)).toBe(true);
expect(await label.evaluate((node) => node.classList.contains('tab-name-renaming'))).toBe(true);
expect(await label.evaluate((node) => getComputedStyle(node).webkitLineClamp)).toBe('none');
expect(await input.evaluate((node) => node.getBoundingClientRect().width)).toBeGreaterThan(0);

const settled = await page.evaluate((sessionId) => {
const app = (window as unknown as { app: { _activeRename: { cancel: () => void } | null } }).app;
app._activeRename?.cancel();
const label = document.querySelector(`.tab-name[data-session-id="${sessionId}"]`) as HTMLElement;
return {
classActive: label.classList.contains('tab-name-renaming'),
inputPresent: !!label.querySelector('input.tab-rename-input'),
webkitLineClamp: getComputedStyle(label).webkitLineClamp,
};
}, id);

expect(settled).toEqual({ classActive: false, inputPresent: false, webkitLineClamp: '2' });
});
// Both rail layouts: the simple rows clamp a name to 2 lines, the detailed (default) card rows to 3.
// The detailed rule out-ranks the shared "unclamp while renaming" override unless it is restated.
it.each([
['simple', '2'],
['rich', '3'],
])(
'Vertical %s rail paints typing in an unclamped editor and restores its clamp on cancel',
async (detail, clamp) => {
await resetState();
const id = `vertical-live-input-${detail}`;

await page.evaluate(
({ sessionId, railDetail }) => {
const app = (
window as unknown as {
app: {
sessions: Map<string, { id: string; name: string }>;
startInlineRename: (id: string) => void;
};
}
).app;
document.documentElement.dataset.tabOrientation = 'vertical';
document.documentElement.dataset.tabRailDetail = railDetail;
const rail = document.getElementById('tabRail') as HTMLElement;
const tab = document.createElement('div');
tab.setAttribute('data-test-tab', '1');
tab.className = 'session-tab';
tab.innerHTML =
`<span class="tab-name" data-session-id="${sessionId}">` +
'<span class="tab-name-prefix">w9-case: </span>old</span>';
rail.appendChild(tab);
app.sessions.set(sessionId, { id: sessionId, name: 'w9-case: old' });
app.startInlineRename(sessionId);
},
{ sessionId: id, railDetail: detail }
);

const label = page.locator(`.tab-name[data-session-id="${id}"]`);
const input = label.locator('input.tab-rename-input');
await input.press(process.platform === 'darwin' ? 'Meta+A' : 'Control+A');
await page.keyboard.type('edited title');

expect(await input.inputValue()).toBe('edited title');
expect(await input.evaluate((node) => document.activeElement === node)).toBe(true);
expect(await label.evaluate((node) => node.classList.contains('tab-name-renaming'))).toBe(true);
expect(await label.evaluate((node) => getComputedStyle(node).webkitLineClamp)).toBe('none');
expect(await input.evaluate((node) => node.getBoundingClientRect().width)).toBeGreaterThan(0);

const settled = await page.evaluate((sessionId) => {
const app = (window as unknown as { app: { _activeRename: { cancel: () => void } | null } }).app;
app._activeRename?.cancel();
const label = document.querySelector(`.tab-name[data-session-id="${sessionId}"]`) as HTMLElement;
return {
classActive: label.classList.contains('tab-name-renaming'),
inputPresent: !!label.querySelector('input.tab-rename-input'),
webkitLineClamp: getComputedStyle(label).webkitLineClamp,
};
}, id);

expect(settled).toEqual({ classActive: false, inputPresent: false, webkitLineClamp: clamp });
}
);
});
Loading