fix(review): correct the secondary-tier floor claim and pin engine-resolved sizes
The Agent Note (both languages), the PR prose, and the commit message claimed a 13px floor for the table variants; the formula has none — max(13px, setting − 2px) selects the −1 branch at low settings rather than clamping the result, so the tier bottoms out at 11px at the 12px setting, matching think text. Rewrite the claim, say so in the axis comment, and split the README sentence that lumped body-pair and secondary-pair consumers together. Assert the engine-resolved secondary size in the settings-chrome e2e (13px at the default, 13px at the 15px boundary, 14px at 16px, unchanged across reload), sync the StatsLine and workflow-panel spec headers with the tier they now pin, and note why memberLabel stays at the body size.
This commit is contained in:
parent
a77e23a975
commit
9e33469913
11 changed files with 38 additions and 14 deletions
|
|
@ -2,5 +2,5 @@
|
|||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-18-settings-font-size-control.md
|
||||
2026-08-18-settings-font-size-control.md: 9e8b933653359bd45abf34e45fec5497289435ec
|
||||
2026-08-18-settings-font-size-control.zh.md: cff574bd5009db6d4d855384c10d6f9a034ea343
|
||||
2026-08-18-settings-font-size-control.md: 778893a2c0943f1d3af8905a27efb526071e073b
|
||||
2026-08-18-settings-font-size-control.zh.md: 71ff3b556622e7091891f8e18f5eefcbda2b0851
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ The conversation's body text size was fixed (14px after the 0.875 markdown-ladde
|
|||
|
||||
**Scaling via a multiplier (`em`/percentage) instead of a px delta.** Rejected: multiplying spreads the 12–17px range disproportionately across the ladder (21px h1 would swing ~18–25.5px) and produces fractional line heights; the fixed px shift keeps every step integer and the hierarchy's px gaps intact.
|
||||
|
||||
**Scaling every font token (small, code).** Rejected: those variants are dense by design; at −2 the small ladder would hit 10px and code 9px, below legibility. The table variants instead join the secondary tier, whose 13px floor keeps them legible at every setting.
|
||||
**Scaling every font token (small, code).** Rejected: those variants are dense by design; at −2 the small ladder would hit 10px and code 9px, below legibility. The table variants instead join the secondary tier, bottoming out at 11px at the 12px setting — the same size think text reaches there.
|
||||
|
||||
## Consequences
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
**用倍率(`em`/百分比)而非像素增量缩放。**否决:乘法会让 12–17px 的范围在阶梯上不成比例地放大(21px 的 h1 会摆动到约 18–25.5px),并产生小数行高;固定像素平移让每一档都是整数,层级间的像素差保持不变。
|
||||
|
||||
**缩放全部字体 token(code、small)。**否决:这些变体按设计就是密集文本;−2 档时 small 阶梯会降到 10px、code 降到 9px,低于可读下限。表格变体改为并入低一档层级,其 13px 下限在任何设置下都保持可读。
|
||||
**缩放全部字体 token(code、small)。**否决:这些变体按设计就是密集文本;−2 档时 small 阶梯会降到 10px、code 降到 9px,低于可读下限。表格变体改为并入低一档层级,在 12px 设置下触底 11px——与 think 文本在该设置下相同。
|
||||
|
||||
## 后果
|
||||
|
||||
|
|
|
|||
|
|
@ -351,7 +351,19 @@ describe('web e2e: settings modal and General preferences', () => {
|
|||
const readFontSize = async (target: Page = page): Promise<string> => await target.evaluate(
|
||||
() => document.body.style.getPropertyValue('--dsh-content-font-size'),
|
||||
)
|
||||
// The secondary tier resolved by the real engine: a probe element's
|
||||
// font-size forces min/max/calc evaluation, which the CSS-text specs
|
||||
// cannot exercise. Setting −1 at ≤14, setting −2 above.
|
||||
const readSecondaryFontSize = async (): Promise<string> => await page.evaluate(() => {
|
||||
const probe = document.createElement('div')
|
||||
probe.style.fontSize = 'var(--dsh-content-font-size-secondary, 13px)'
|
||||
document.body.appendChild(probe)
|
||||
const size = getComputedStyle(probe).fontSize
|
||||
probe.remove()
|
||||
return size
|
||||
})
|
||||
expect(await readFontSize()).toBe('14px')
|
||||
expect(await readSecondaryFontSize()).toBe('13px')
|
||||
await page.getByRole('button', { name: '设置', exact: true }).click()
|
||||
const dialog = page.getByRole('dialog', { name: '设置' })
|
||||
await dialog.waitFor({ timeout: 10_000 })
|
||||
|
|
@ -360,9 +372,13 @@ describe('web e2e: settings modal and General preferences', () => {
|
|||
const increase = dialog.getByRole('button', { name: '增大字号' })
|
||||
await increase.click()
|
||||
await dialog.getByText('15', { exact: true }).waitFor({ timeout: 5_000 })
|
||||
// 15 is the piecewise boundary: the secondary tier holds at 13px (−2)
|
||||
// where the ≤14 branch would have given 14px (−1).
|
||||
await expect.poll(readSecondaryFontSize, { timeout: 5_000 }).toBe('13px')
|
||||
await increase.click()
|
||||
await dialog.getByText('16', { exact: true }).waitFor({ timeout: 5_000 })
|
||||
await expect.poll(readFontSize, { timeout: 5_000 }).toBe('16px')
|
||||
await expect.poll(readSecondaryFontSize, { timeout: 5_000 }).toBe('14px')
|
||||
await expect.poll(async () => readFile(join(scaffold.harnessHome, 'settings.yaml'), 'utf8'), { timeout: 5_000 })
|
||||
.toMatch(/ui-theme:\n(?:\s+\w+: .*\n)*?\s+fontSize: 16/)
|
||||
await page.keyboard.press('Escape')
|
||||
|
|
@ -375,6 +391,7 @@ describe('web e2e: settings modal and General preferences', () => {
|
|||
acknowledgeReloadConnectionLoss(tripwire, warningStart)
|
||||
await page.waitForSelector('[class*="frame"]', { timeout: 30_000 })
|
||||
await expect.poll(readFontSize, { timeout: 5_000 }).toBe('16px')
|
||||
expect(await readSecondaryFontSize()).toBe('14px')
|
||||
|
||||
// Restore the default for the specs that follow (and the dialog golden).
|
||||
await page.getByRole('button', { name: '设置', exact: true }).click()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* Session stats row: 12/20 tertiary text under the flow, aligned to the
|
||||
shared message column axis (--dsh-chat-content-width). */
|
||||
/* Session stats row: 13/20 tertiary text (the secondary content tier) under
|
||||
the flow, aligned to the shared message column axis
|
||||
(--dsh-chat-content-width). */
|
||||
|
||||
.root {
|
||||
/* Block, not flex: text-overflow only elides a block's inline content, so
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-theme/README.md
|
||||
README.md: 49ea5147b12f382f37fa550455035f948dec4fe8
|
||||
README.zh.md: 427eb4be339f6ad414fc84b7824445edaf934c54
|
||||
README.md: 32ec60edb39b30afdb9b54804e62302cdc58e531
|
||||
README.zh.md: ab17910ab9cec4e1ff519af0922ee27034a6fa7c
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ The service owns theme and font-size state and publishes snapshots. The ui-layou
|
|||
|
||||
`src/styles/` holds five sheets imported in order by ui-theme's dynamic client entry: `base.css`, `design-platform.css`, `scrollbar.css`, `gradient-shadow-text.css`, and `shiki.css`. The client bundle compiles and injects them as plugin-owned global styles, so unload and HMR remove them with ui-theme. `scrollbar.css` is the sole consumer of the `--dsw-alias-scrollbar-*` tokens and must follow `design-platform.css`, which declares them.
|
||||
|
||||
`gradient-shadow-text.css` derives `--dsh-content-font-delta` from `--dsh-content-font-size` and shifts the Markdown heading and base-text ladder by that increment. It also derives the secondary tier `--dsh-content-font-size-secondary` (setting −1 at ≤14, setting −2 above; 13px at the default) with its own `--dsh-content-font-delta-secondary` for the table variants and the flow rows one step under the body. Dense small and code variants stay fixed. The user bubble, the composer draft, and flow-row titles and summaries consume the same variables outside that ladder.
|
||||
`gradient-shadow-text.css` derives `--dsh-content-font-delta` from `--dsh-content-font-size` and shifts the Markdown heading and base-text ladder by that increment. It also derives the secondary tier `--dsh-content-font-size-secondary` (setting −1 at ≤14, setting −2 above; 13px at the default) with its own `--dsh-content-font-delta-secondary` for the table variants and the flow rows one step under the body. Dense small and code variants stay fixed. Outside the ladder, the user bubble and composer draft read the body pair directly, and flow-row titles and summaries read the secondary pair.
|
||||
|
||||
### Scrollbar rebinding
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ kind: "package-reference"
|
|||
|
||||
`src/styles/` 下有五张样式表,由 ui-theme 的动态客户端 entry 依次导入:`base.css`、`design-platform.css`、`scrollbar.css`、`gradient-shadow-text.css` 与 `shiki.css`。客户端 bundle 将其编译并注入为插件持有的全局样式,因此卸载与 HMR 会随 ui-theme 一同移除。`scrollbar.css` 是 `--dsw-alias-scrollbar-*` token 的唯一消费方,必须排在声明这些 token 的 `design-platform.css` 之后。
|
||||
|
||||
`gradient-shadow-text.css` 从 `--dsh-content-font-size` 派生 `--dsh-content-font-delta`,并以该增量移动 Markdown 标题与基础文本阶梯。它同时派生低一档变量 `--dsh-content-font-size-secondary`(设置 ≤14 时为设置值 −1,>14 时为设置值 −2;默认设置下为 13px)及配套的 `--dsh-content-font-delta-secondary`,供表格变体与比正文低一档的流内行使用。紧凑的小号文本与代码变体保持固定字号。用户气泡、composer 草稿与流内行的标题及摘要在该阶梯之外消费相同变量。
|
||||
`gradient-shadow-text.css` 从 `--dsh-content-font-size` 派生 `--dsh-content-font-delta`,并以该增量移动 Markdown 标题与基础文本阶梯。它同时派生低一档变量 `--dsh-content-font-size-secondary`(设置 ≤14 时为设置值 −1,>14 时为设置值 −2;默认设置下为 13px)及配套的 `--dsh-content-font-delta-secondary`,供表格变体与比正文低一档的流内行使用。紧凑的小号文本与代码变体保持固定字号。阶梯之外,用户气泡与 composer 草稿直接读取正文档变量对,流内行的标题及摘要读取低一档变量对。
|
||||
|
||||
### 滚动条重新绑定
|
||||
|
||||
|
|
|
|||
|
|
@ -25,8 +25,9 @@ body[data-ds-dark-theme] {
|
|||
(--dsh-content-font-delta)随动,保持层级。低一档文本(think、工具/bash
|
||||
行的标题与摘要、markdown 表格、流内次级说明等)统一读
|
||||
--dsh-content-font-size-secondary:设置 ≤14 时为设置值 −1,>14 时为
|
||||
设置值 −2(12→11、13→12、14→13、15→13、16→14、17→15);small、code
|
||||
属于密集次级文本,保持固定。 */
|
||||
设置值 −2(12→11、13→12、14→13、15→13、16→14、17→15)。式中
|
||||
max(13px,·) 的作用是让低设置取 −1 而非 −2,不是结果下限——12 设置下
|
||||
层级触底 11px。small、code 属于密集次级文本,保持固定。 */
|
||||
body {
|
||||
--dsh-content-font-delta: calc(var(--dsh-content-font-size, 14px) - 14px);
|
||||
--dsh-content-font-size-secondary: min(calc(var(--dsh-content-font-size, 14px) - 1px), max(13px, calc(var(--dsh-content-font-size, 14px) - 2px)));
|
||||
|
|
|
|||
|
|
@ -223,6 +223,9 @@
|
|||
flex: 1;
|
||||
min-width: 0;
|
||||
color: var(--dsw-alias-label-secondary);
|
||||
/* Body size, not the secondary tier: the member label is the panel's
|
||||
content (an agent's task), while the run/phase headers, counts, and
|
||||
statuses around it are chrome one step down. */
|
||||
font-size: var(--dsh-content-font-size, 14px);
|
||||
line-height: calc(24px + var(--dsh-content-font-delta, 0px));
|
||||
text-overflow: ellipsis;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
/**
|
||||
* WorkflowRunPanel's font-size-axis adoption as CSS text. jsdom has no
|
||||
* layout, so these read the declarations that make the run/phase headers and
|
||||
* the expanded member rows follow the Settings font-size preference through
|
||||
* --dsh-content-font-size / --dsh-content-font-delta.
|
||||
* the expanded member rows follow the Settings font-size preference: member
|
||||
* labels at the body size (--dsh-content-font-size / --dsh-content-font-delta),
|
||||
* the chrome around them on the secondary tier
|
||||
* (--dsh-content-font-size-secondary / --dsh-content-font-delta-secondary).
|
||||
*/
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue