fix(app): add bottom padding to settings pages (#47191)

Co-authored-by: iamdavidhill <1879069+iamdavidhill@users.noreply.github.com>
This commit is contained in:
opencode-agent[bot] 2026-09-04 01:58:55 +00:00 committed by GitHub
parent 331f4ecd2f
commit b3733e9517
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 99 additions and 4 deletions

View file

@ -0,0 +1,95 @@
import { expect, test } from "@playwright/test"
import { mockOpenCodeServer } from "../utils/mock-server"
const directory = "/tmp/settings-padding"
test.beforeEach(async ({ page }) => {
await mockOpenCodeServer(page, {
directory,
project: {
id: "proj_settings_padding",
canonical: directory,
name: "Settings padding",
vcs: "git",
time: { created: 1700000000000, updated: 1700000000000 },
},
provider: { all: [], connected: [], default: {} },
sessions: [],
pageMessages: () => ({ items: [] }),
})
await page.route("https://api.github.com/repos/anomalyco/opencode/contributors?*", (route) =>
route.fulfill({ json: [] }),
)
await page.goto("/")
await page.getByRole("button", { name: "Settings", exact: true }).click()
await expect(page.getByTestId("settings-screen")).toBeFocused()
})
for (const viewport of [
{ width: 1280, height: 720, bottom: false },
{ width: 900, height: 600, bottom: false },
{ width: 780, height: 600, bottom: false },
{ width: 390, height: 844, bottom: false },
{ width: 390, height: 844, bottom: true },
]) {
test.describe(`${viewport.width}px, ${viewport.bottom ? "bottom" : "top"} navigation`, () => {
test.use({ viewport: { width: 1280, height: 720 }, contextOptions: { reducedMotion: "reduce" } })
test("every settings page leaves room below its final content", async ({ page }) => {
await page.setViewportSize(viewport)
const settings = page.getByTestId("settings-screen")
const panel = settings.locator(":scope > .settings > .settings-panel:visible")
if (viewport.bottom) {
const toggle = settings.locator('[data-action="settings-mobile-titlebar-bottom"]')
await toggle.locator('[data-slot="switch-control"]').click()
await expect(toggle.getByRole("switch")).toBeChecked()
}
let current = "Preferences"
for (const name of [
"Preferences",
"Appearance",
"Notifications",
"Shortcuts",
"Servers",
"Projects",
"Worktrees",
"Providers",
"Models",
"Extensions",
"Experimental",
"About",
]) {
if (viewport.width >= 816) await settings.getByRole("tab", { name, exact: true }).click()
if (viewport.width < 816) {
await settings.getByRole("button", { name: current, exact: true }).click()
await page.getByRole("menuitemradio", { name, exact: true }).click()
}
current = name
if (name === "About") await expect(panel.getByText("Released under the MIT License")).toBeVisible()
if (name !== "About") {
await expect(
panel.getByRole("heading", { name: name === "Shortcuts" ? "Keyboard shortcuts" : name, exact: true }),
).toBeVisible()
}
await panel.hover()
await page.mouse.wheel(0, 10000)
await expect
.poll(() => panel.evaluate((el) => el.scrollHeight - el.clientHeight - el.scrollTop))
.toBeLessThanOrEqual(1)
await expect
.poll(
() =>
panel.evaluate((el) => {
const body = el.querySelector(".settings-tab-body, .settings-about-content")!
return el.getBoundingClientRect().bottom - body.lastElementChild!.getBoundingClientRect().bottom
}),
{ message: `${name} bottom clearance` },
)
.toBeGreaterThanOrEqual(viewport.bottom ? 119.5 : 79.5)
await expect
.poll(() => page.getByRole("main").evaluate((el) => el.scrollWidth - el.clientWidth))
.toBeLessThanOrEqual(1)
}
})
})
}

View file

@ -60,7 +60,6 @@
.settings-screen .settings-tab-body {
padding-inline: 0;
padding-bottom: var(--settings-bottom-inset, 0px);
}
.settings-nav {
@ -98,6 +97,7 @@
.settings-about-content {
display: flex;
flex-shrink: 0;
width: 100%;
max-width: 560px;
min-height: 462px;
@ -105,7 +105,7 @@
align-items: center;
justify-content: flex-start;
gap: 24px;
padding-block: 80px 32px;
padding-block: 80px calc(80px + var(--settings-bottom-inset, 0px));
color: var(--v2-text-text-muted);
font-size: 13px;
font-weight: 440;
@ -273,7 +273,7 @@
flex-direction: column;
gap: 36px;
width: 100%;
padding: 0 40px 40px;
padding: 0 40px calc(80px + var(--settings-bottom-inset, 0px));
}
[data-slot="settings-row-description"] a.settings-link {
@ -1170,7 +1170,7 @@
}
.settings-tab-body.settings-workspaces {
padding: 0 20px 24px;
padding-inline: 20px;
}
.settings-workspaces-toolbar,