fix(settings): keep compact inline controls readable

This commit is contained in:
l0ng-ai committed 2026-11-08 16:00:54 +08:00
1 parent 6d37f0876c
commit 891758a351
6 files changed
+74

No files matched your search

+59
View File
@@ -0,0 +1,59 @@
import { expect, test } from "./fixtures";
for (const [id, selector] of [
["general", "[class*='radios'] label"],
["notifications", "table tbody td:first-child"],
["keymap", "[class*='presetLabel']"],
["editor.inspections", "[class*='profileRow'] > span:first-child"],
["vcs.issueNavigation", "[class*='pageBody'] button:not([aria-label])"],
]) {
test(`${id} keeps compact labels inside their controls`, async ({ workbench: page }) => {
await page.keyboard.press("Meta+,");
const dialog = page.getByRole("dialog");
await expect(dialog).toBeVisible();
await page.evaluate(async (id) => {
const localePath = "/src/platform/i18n.ts";
await (await import(/* @vite-ignore */ localePath)).setLocale("zh");
const stagingPath = "/src/features/settings/model/staging.ts";
(await import(/* @vite-ignore */ stagingPath)).selectPage(id);
}, id);
const labels = dialog.locator(selector);
await expect(labels.first()).toBeVisible();
for (const width of [1000, 640, 520]) {
await page.setViewportSize({ width, height: 760 });
const fits = await labels.evaluateAll((labels) =>
labels.every((label) => {
const box = label.getBoundingClientRect();
const range = document.createRange();
range.selectNodeContents(label);
const lines = [...range.getClientRects()].filter((r) => r.width > 0 && r.height > 0);
return (
lines.every((r) => r.left >= box.left - 1 && r.right <= box.right + 1 && r.height <= 24) &&
Math.max(...lines.map((r) => r.bottom)) - Math.min(...lines.map((r) => r.top)) <= 24
);
}),
);
expect(fits).toBe(true);
}
});
}
for (const [id, selector] of [
["general", "[class*='fontRow'] > label"],
["build.console", "[class*='inlineRow'] > label"],
]) {
test(`${id} keeps a readable width for inline text`, async ({ workbench: page }) => {
await page.keyboard.press("Meta+,");
await expect(page.getByRole("dialog", { name: "Settings", exact: true })).toBeVisible();
await page.evaluate(async (id) => {
const localePath = "/src/platform/i18n.ts";
await (await import(/* @vite-ignore */ localePath)).setLocale("zh");
const path = "/src/features/settings/model/staging.ts";
(await import(/* @vite-ignore */ path)).selectPage(id);
}, id);
const text = page.locator(selector).first();
await expect(text).toBeVisible();
await page.setViewportSize({ width: 520, height: 760 });
expect((await text.boundingBox())!.width).toBeGreaterThan(100);
});
}
@@ -12,6 +12,8 @@
margin-bottom: 6px;
}
.presetLabel {
flex: none;
white-space: nowrap;
color: var(--fg);
}
.presetSelect {
@@ -27,6 +27,7 @@
/* Inline option groups, with custom font controls wrapping together. */
.fontRow {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
min-height: 28px;
@@ -93,11 +94,14 @@
.radios {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 16px;
}
.radio {
display: inline-flex;
flex: none;
white-space: nowrap;
align-items: center;
gap: 6px;
}
@@ -111,6 +115,7 @@
border-collapse: collapse;
}
.table th {
white-space: nowrap;
text-align: left;
font-weight: normal;
color: var(--fg-muted);
@@ -119,6 +124,7 @@
border-bottom: 1px solid var(--border);
}
.table td {
white-space: nowrap;
height: 32px;
padding: 0 8px;
}
@@ -25,11 +25,13 @@
/* "[x] Limit history to: [1000] rows" */
.fontFamily {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.inlineRow {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
min-height: 28px;
@@ -14,6 +14,10 @@
.profileSelect {
min-width: 220px;
}
.profileRow > span {
flex: none;
white-space: nowrap;
}
.toolbar {
display: flex;
align-items: center;
+1
View File
@@ -2,6 +2,7 @@
.button {
--button-radius: var(--radius-control, 4px);
display: inline-flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
gap: 6px;