mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-14 20:21:39 +03:00
fix(app): collapse session location names only in narrow headers (#57870)
This commit is contained in:
committed by
GitHub
Unverified
parent
1744121801
commit
4d680fbb31
@@ -130,6 +130,66 @@ test.describe("location", () => {
|
||||
sessions: [{ id: "ses_location", title: "Location session", directory: worktree }],
|
||||
}
|
||||
|
||||
test("only collapses location names when the timeline header is narrow", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 1440, height: 900 })
|
||||
await openSession(page, {
|
||||
...workspace,
|
||||
sessions: [{ id: "ses_location", title: "Investigate session header layout regression", directory: worktree }],
|
||||
})
|
||||
const header = page.locator("[data-session-title]")
|
||||
const names = header.locator('[data-slot="session-location-project"], [data-slot="session-location-worktree"]')
|
||||
const review = page.getByRole("button", { name: "Toggle review", exact: true })
|
||||
await expect(names).toHaveText(["Location", "quiet-falcon"])
|
||||
|
||||
for (const panel of [false, true, false]) {
|
||||
if (panel || (await review.getAttribute("aria-expanded")) === "true") await review.click()
|
||||
await expect(review).toHaveAttribute("aria-expanded", String(panel))
|
||||
await expect
|
||||
.poll(() =>
|
||||
names.evaluateAll((elements) => elements.every((element) => getComputedStyle(element).clipPath === "none")),
|
||||
)
|
||||
.toBe(!panel)
|
||||
await expect(header.getByRole("button", { name: "More options", exact: true })).toBeInViewport()
|
||||
await expect
|
||||
.poll(() => header.getByRole("heading").evaluate((element) => element.scrollWidth <= element.clientWidth))
|
||||
.toBe(true)
|
||||
if (panel) {
|
||||
await expect
|
||||
.poll(() =>
|
||||
header.evaluate((element) => {
|
||||
const icon = element.querySelector('svg:has(use[href="#opencode-v2-icon-outline-worktree"])')
|
||||
const before = icon?.previousElementSibling?.getBoundingClientRect()
|
||||
const separator = element.querySelector('[data-slot="session-title-separator"]')
|
||||
const after = separator?.getBoundingClientRect()
|
||||
const title = element.querySelector("h1")
|
||||
const avatar = element
|
||||
.querySelector('[data-slot="session-location-trigger"]')
|
||||
?.firstElementChild?.getBoundingClientRect()
|
||||
const bounds = icon?.getBoundingClientRect()
|
||||
|
||||
return bounds && before && after && avatar && separator && title
|
||||
? [
|
||||
before.left - avatar.right,
|
||||
bounds.left - before.right,
|
||||
after.left - bounds.right,
|
||||
title.getBoundingClientRect().left +
|
||||
parseFloat(getComputedStyle(title).paddingLeft) -
|
||||
after.right +
|
||||
parseFloat(getComputedStyle(separator).paddingRight),
|
||||
]
|
||||
: []
|
||||
}),
|
||||
)
|
||||
.toEqual([10, 8, 8, 10])
|
||||
const location = header.locator('[data-slot="session-location-trigger"]')
|
||||
await location.hover()
|
||||
await expect(location).toHaveCSS("padding-inline-start", "4px")
|
||||
await expect(location).toHaveCSS("padding-inline-end", "4px")
|
||||
}
|
||||
await header.screenshot({ path: test.info().outputPath(`location-${panel ? "compact" : "expanded"}.png`) })
|
||||
}
|
||||
})
|
||||
|
||||
test("names the project and worktree, and the card copies the full path", async ({ page, context }) => {
|
||||
await context.grantPermissions(["clipboard-read", "clipboard-write"])
|
||||
await openSession(page, workspace)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
}
|
||||
|
||||
.session-header-layout {
|
||||
container: session-header / inline-size;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
@@ -20,20 +21,42 @@
|
||||
|
||||
.session-header-location > [data-slot="session-location-trigger"] {
|
||||
max-inline-size: 100%;
|
||||
gap: 6px;
|
||||
padding-inline: 4px;
|
||||
}
|
||||
|
||||
/* The header shows the location as the project avatar and, in a worktree, the worktree icon, so the title keeps the
|
||||
row. The names stay for assistive tech, and the location card shows them in full. */
|
||||
.session-header-location [data-slot="session-location-project"],
|
||||
.session-header-location [data-slot="session-location-worktree"] {
|
||||
position: absolute;
|
||||
inline-size: 1px;
|
||||
block-size: 1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
/* Use the header's available width, not the window: opening a side panel also narrows the timeline. */
|
||||
@container session-header (max-width: 640px) {
|
||||
.session-header-location {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.session-header-location > [data-slot="session-location-trigger"] {
|
||||
gap: 8px;
|
||||
padding-inline: 4px;
|
||||
}
|
||||
|
||||
.session-header-location [data-component="project-avatar-v2"] {
|
||||
margin-inline-end: 2px;
|
||||
}
|
||||
|
||||
.session-header-location [data-slot="session-location-project"] + span {
|
||||
padding-inline: 0;
|
||||
}
|
||||
|
||||
.session-header-location > .session-location-separator[data-variant="slash"] {
|
||||
/* Together with the row's 2px gap and the title's 4px padding, leave 10px before the title. */
|
||||
padding-inline: 0 4px;
|
||||
}
|
||||
|
||||
/* Keep the names available to assistive tech while the icons leave room for the title. */
|
||||
.session-header-location [data-slot="session-location-project"],
|
||||
.session-header-location [data-slot="session-location-worktree"] {
|
||||
position: absolute;
|
||||
inline-size: 1px;
|
||||
block-size: 1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.session-header-title {
|
||||
|
||||
Reference in New Issue
Block a user