fix(webui): 候选菜单改用不透明弹层表面 —— 半透明+背景模糊把背后的表单糊进了列表
用户(2026-09-15,看着抄送/转发两处的候选):「你在选择框的模糊逻辑上用力过猛, 导致只能显示一条信息」。 实测(生产构建 4c2bf26,浏览器里读计算样式,壁纸开): 菜单 background: rgba(255,255,255,0.5) + backdrop-filter: blur(8px) saturate(1.1) 而它浮在**表单自己**之上(主题输入框 y=294 正落在菜单 284-510 下面) ⇒ 背后的输入框/标签被糊一遍再从半透明列表底下透上来,只有顶行还读得清。 根因与 2026-09-14 那次「模糊叠模糊」同族:把**控件档**(0.5 透 + 8px 模糊)用在 **弹层**上。控件背后是面板自身,透一点好看;弹层背后是别的内容,透就是叠两份内容。 - 新增 .popup-surface(rgb(var(--c-white)),不取 backdrop-filter;壁纸开时单独压回不透明, 否则会撞上 html[data-bg='on'] .bg-white 那条接管规则) - .popup-surface 并入「滚动区不淡」豁免(原来只认 .glass-control,换类会漏掉 → 弹层又被洗白) - AddressInput 菜单 glass-control → popup-surface;旧断言 nav-merge.test.mjs:109 钉的正是 那个错的意图(『地址建议菜单』必须用控件档),已改钉新意图 判据:narrow-layout 新增 4 条(表面不透明/不取模糊/壁纸开时也压回/菜单穿的类)+ nav-merge 反向对照。两侧都验:变异①换回 glass-control → 红;变异②改回 0.5 → 红; 复原 → 71 通过 0 失败。生产实测:rgba(...,0.5)+blur → rgb(255,255,255)+无模糊。
This commit is contained in:
@ -111,11 +111,13 @@ function record(name, ok, note) {
|
||||
await toInput.fill('gui');
|
||||
await page.waitForTimeout(1200);
|
||||
}
|
||||
const menu = await alpha('.glass-control');
|
||||
const menu = await alpha('.popup-surface');
|
||||
record(
|
||||
'⑤ 控件档(地址建议)比正文面更透',
|
||||
menu !== null && card !== null && menu < card - 0.15,
|
||||
`正文面 α=${card} 控件 α=${menu}`
|
||||
'⑤ 弹层(地址建议菜单)不透明、也不取背景模糊',
|
||||
// 2026-09-15 用户:「你在选择框的模糊逻辑上用力过猛,导致只能显示一条信息」——
|
||||
// 菜单浮在表单之上,半透明 + 背景模糊会把背后的输入框/标签糊进候选行里。
|
||||
menu !== null && menu >= 0.99 && card !== null && menu > card,
|
||||
`正文面 α=${card} 弹层 α=${menu}(弹层必须 ≥0.99)`
|
||||
);
|
||||
} finally {
|
||||
await page.close();
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
//
|
||||
// 不做视觉快照:那需要 headless 浏览器,且像素级比对在字体差异下极脆。
|
||||
// 这里守住几条真正会坏掉的不变量。
|
||||
import { prose } from './lib/read.mjs';
|
||||
import { code, prose } from './lib/read.mjs';
|
||||
import { check, finish } from './lib/checks.mjs';
|
||||
|
||||
const read = p => prose(new URL(p, import.meta.url));
|
||||
@ -205,9 +205,43 @@ check(
|
||||
);
|
||||
check(
|
||||
'弹层(控件档滚动区)不做边缘淡出',
|
||||
/\.overflow-y-auto\.glass-control\s*\{[\s\S]*?mask-image:\s*none/.test(css),
|
||||
/\.overflow-y-auto\.(glass-control|popup-surface)\s*\{[\s\S]*?mask-image:\s*none/.test(css),
|
||||
'候选菜单这类弹层还在淡 —— 它高度只有几十像素,首尾项会被洗白'
|
||||
);
|
||||
|
||||
/*
|
||||
* 候选/转发两个选择框的菜单必须是**不透明**表面(2026-09-15 用户:
|
||||
* 「你在选择框的模糊逻辑上用力过猛,导致只能显示一条信息」)。
|
||||
*
|
||||
* 判据钉的是**结构**而不是某个具体颜色值:
|
||||
* ① 弹层类必须存在,且用 rgb(var(--c-white)) 而不是带 alpha 的 rgb(... / α);
|
||||
* ② 弹层规则里不允许出现 backdrop-filter(背后的表单被模糊正是那份乱);
|
||||
* ③ 壁纸开着时也得另有规则压回不透明(`html[data-bg='on'] .bg-white` 会抢);
|
||||
* ④ AddressInput 的菜单必须穿这个类,不许再穿 .glass-control。
|
||||
*/
|
||||
const popupRule = (css.match(/\.popup-surface\s*\{[\s\S]*?\n\}/) || [''])[0];
|
||||
const popupBgOn = (css.match(/html\[data-bg='on'\]\s*\.popup-surface\s*\{[\s\S]*?\n\}/) || [''])[0];
|
||||
const addrSrc = code('src/components/AddressInput.tsx'); // 判「代码里穿了哪个类」→ 用剥注释版
|
||||
check(
|
||||
'弹层表面存在且不透明',
|
||||
/\.popup-surface\s*\{/.test(css) && /background-color:\s*rgb\(var\(--c-white\)\)/.test(popupRule),
|
||||
'弹层没有独立的不透明表面 —— 半透明列表叠在表单上,下面的行会被背后控件糊掉'
|
||||
);
|
||||
check(
|
||||
'弹层不取背景模糊',
|
||||
!/backdrop-filter:\s*blur/.test(popupRule),
|
||||
'弹层又开了 background blur —— 背后的控件被糊住后和候选行叠在一起'
|
||||
);
|
||||
check(
|
||||
'壁纸开时弹层也不透明',
|
||||
/background-color:\s*rgb\(var\(--c-white\)\)/.test(popupBgOn) && !/backdrop-filter:\s*blur/.test(popupBgOn),
|
||||
"`html[data-bg='on'] .bg-white` 会把弹层拉回半透明那档(0.88),必须单独压回去"
|
||||
);
|
||||
check(
|
||||
'候选菜单穿的是弹层类',
|
||||
/absolute[^`]*popup-surface/.test(addrSrc) && !/absolute[^`]*glass-control/.test(addrSrc),
|
||||
'AddressInput 的菜单还穿着控件档(.glass-control) —— 那档是给贴着面板的小控件用的'
|
||||
);
|
||||
check(
|
||||
'淡出规则同时带 -webkit- 前缀(Electron 里以哪个为准不由我们定)',
|
||||
(maskRule.match(/-webkit-mask-image:/g) || []).length === 1 &&
|
||||
|
||||
@ -106,7 +106,18 @@ test('③ 复选框与地址建议用"控件档"透度(比正文面更透)',
|
||||
assert.match(mailView, /import \{[^}]*ComposerChip[^}]*\} from '\.\/Composer'/, 'MailView 要用共用的胶囊组件');
|
||||
assert.match(mailView, /<ComposerChip/, '授权选项必须是那颗胶囊');
|
||||
assert.match(chip, /glass-control/, '授权多选胶囊(ComposerChip 未选中态)要用控件档');
|
||||
assert.match(addr, /glass-control/, '地址建议菜单');
|
||||
/*
|
||||
* ★ 2026-09-15 用户(看着抄送/转发两处的候选列表):「你在选择框的模糊逻辑上用力过猛,
|
||||
* 导致只能显示一条信息」。
|
||||
*
|
||||
* 实测(壁纸开、生产构建 4c2bf26):建议菜单是 `rgba(255,255,255,0.5)` +
|
||||
* `backdrop-filter: blur(8px)`,而它浮在**表单自己**(主题输入框、各段标签)之上。
|
||||
* 控件档背后是自己的面板,透一点好看;**弹层背后是别的内容**,透就是把两份内容叠在一起。
|
||||
* 所以这里从「菜单必须用控件档」改成「菜单必须用不透明弹层档」——
|
||||
* 旧断言正是那个错的意图的书面记录。
|
||||
*/
|
||||
assert.match(addr, /popup-surface/, '地址建议菜单要用不透明的弹层档');
|
||||
assert.ok(!/absolute[^`]*glass-control/.test(addr), '建议菜单不能再穿控件档(那档浮在表单上会糊成一片)');
|
||||
assert.ok(!/glass-control[^']*bg-white/.test(chip), '胶囊不能再同时写 bg-white');
|
||||
assert.ok(!/glass-control[^"]*bg-white/.test(addr), '建议菜单不能再同时写 bg-white');
|
||||
// 三档透度必须真的递减(正文 > 嵌套 > 控件)
|
||||
|
||||
Reference in New Issue
Block a user