Files
MailUI4Agents/client/electron/test/harmony-widescreen.test.mjs
JianFeeeee fd4b475920 ke: 鸿蒙导航纯图标 + 图标加大 + 玻璃几何令牌
用户反馈:① 图标太小 ② 底部导航栏不允许有文字。

- NavItem(底部导航):去掉 Text(item.label) 纯图标,AmIcon 22→28vp
- WideSidebar(宽屏侧栏):去掉 label 文字(WebUI Sidebar 本就是 60px 纯图标轨),
  导航图标 22→26vp、品牌标 26→30vp;NavItemBuilder 去掉 label 参数
- Theme:新增 glassRadius=14 / paneGap=10(与 WebUI app-shell CSS 变量同值,
  用于宽屏玻璃面板几何;原有 radiusCard 保持系统跟随不动)
- 判据同步:harmony-nav ⑤ 改纯图标(1 处三元式 + 无文字 + 28vp)+ 变异自检三项;
  harmony-widescreen ③ 同样改纯图标(1 处 + 无文字 + 26vp)
2026-09-16 07:54:44 +08:00

90 lines
5.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 宽屏侧栏图标轨(WideSidebar)判据 —— 一比一复刻 WebUI 的 `Sidebar`(60px 图标轨)。
//
// WebUI 的 `Sidebar`(components/Sidebar.tsx)是 60px 宽的图标列:
// 品牌标(顶) / 通信·日历·联系人(中) / 设置(底)
// 选中态 = 图标+文字变色 + 品牌浅底,**不加背景块/指示条**。
//
// 鸿蒙侧原来是**没有**宽屏布局的(只有底部导航条),WideSidebar 补的就是
// "宽屏模式"这半:≥768vp 时 MainPage 挂侧栏、藏底部条(见 MainPage.build 的 onAreaChange)。
// 这条判据钉的是 Sidebar 自己的形状:宽 60vp、三项导航 + 设置、选中态只换颜色。
import { code, prose, stripComments } from './lib/read.mjs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { test } from 'node:test';
import assert from 'node:assert/strict';
const HERE = dirname(fileURLToPath(import.meta.url));
const ROOT = join(HERE, '..', '..', '..');
const HARMONY_ETS = join(ROOT, 'client/harmony/entry/src/main/ets');
const read = p => prose(join(HARMONY_ETS, p));
/** 取某个成员/方法正文(按行切到下一个成员声明) */
function memberBody(src, signature) {
const lines = src.split('\n');
const start = lines.findIndex(l => l.includes(signature));
assert.ok(start > 0, `要能找到 ${signature}`);
let stop = lines.length;
for (let i = start + 1; i < lines.length; i++) {
if (/^ (@Builder|build\(|NavItemBuilder\()/.test(lines[i])) { stop = i; break; }
}
return lines.slice(start, stop).join('\n');
}
test('① 宽度:SIDEBAR_WIDTH = 60vp(WebUI 的 `w-[60px]` 是同一数字)', () => {
const sidebar = read('pages/WideSidebar.ets');
const code_ = stripComments(sidebar);
assert.match(code_, /export const SIDEBAR_WIDTH: number = 60\s*;/, '要导出 60 这个常量');
const main = read('pages/MainPage.ets');
assert.match(main, /WideSidebar\(/, 'MainPage 要真正挂 WideSidebar');
});
test('② 三项导航 + 设置按钮:内容与 WebUI Sidebar 对齐', () => {
const sidebar = read('pages/WideSidebar.ets');
// NAV_ITEMS 遍历(与底部导航同一份清单 —— 加项两边同时出现)
assert.match(sidebar, /ForEach\(NAV_ITEMS,/, '要遍历 NAV_ITEMS(与底部导航同一清单)');
// 品牌标 + 三项导航 + 设置(与 WebUI:brand / nav / settings 的分组一致)
assert.match(sidebar, /品牌标/, '要有品牌标(注释里的分组依据)');
assert.match(sidebar, /iconName: 'person'/, '设置按钮要用 person 图标(WebUI 侧沿用的同一枚)');
assert.match(sidebar, /onSettings/, '设置按钮要回调 onSettings(点击后由 MainPage 路由)');
});
test('③ 选中态只换颜色(与底部导航同一套纪律):纯图标、无文字', () => {
const sidebar = read('pages/WideSidebar.ets');
const code_ = stripComments(sidebar);
/*
* 2026-09-16 用户:「底部导航栏不允许有文字」⇒ 侧栏同样走纯图标。
* WebUI 的 `Sidebar.tsx` 本就是 60px 纯图标轨(无 label 文字)。
*/
const active = /this\.currentIndex === index \? Theme\.navFgActive : Theme\.navFg/g;
const hits = code_.match(active) || [];
assert.equal(hits.length, 1,
`侧栏导航项只应有 1 处选中三元式(现在 ${hits.length} 处)— 纯图标,无文字`);
// 无文字(label 的 Text)
assert.ok(!/Text\(label\)/.test(code_),
'侧栏是纯图标轨:不允许有 label 文字(WebUI Sidebar 无文字)');
// 图标不能太小(26vp)
assert.match(code_, /iconSize: 26/,
'侧栏导航图标要 26vp(WebUI 是 24,鸿蒙放大一档 —— 用户嫌 22 太小)');
// 不加背景块 / 指示条
assert.ok(!/currentIndex[^{;]{0,40}backgroundColor/.test(code_),
'选中态不许改背景色(与底部导航同一纪律:变色即可)');
});
test('④ MainPage 接线:宽屏才挂侧栏、宽屏藏底部条、断点 768', () => {
const main = read('pages/MainPage.ets');
const code_ = stripComments(main);
// 宽屏分支:isWide 时才渲染 WideSidebar
assert.match(main, /if \(this\.isWide\) \{/, '侧栏要包在 isWide 分支里');
assert.match(code_, /WideSidebar\(\{/, '侧栏要真挂在 build 里(剥注释后仍存在)');
// 窄屏 x 宽屏:底部条只要窄屏有 —— 两半都是条件式的,不是同时出现
assert.match(main, /if \(!this\.isWide\) \{/, '底部导航条要包在 !isWide 分支里');
const both = /if \(this\.isWide\) \{[\s\S]*?if \(!this\.isWide\)/.test(main);
assert.ok(both, 'isWide 与 !isWide 两分支要在同一个结构里(互斥)');
// 断点检测
assert.match(code_, /onAreaChange/, '要用 onAreaChange 实时检测窗口宽度');
assert.match(code_, />=\s*768/s, '断点是 768(与 WebUI 的 lg 断点同一档)');
// let为0(宽屏没有底部条,内容 padding 归零)
assert.match(code_, /bottom:\s*this\.isWide \? 0 : NAV_CONTENT_RESERVE/, '宽屏内容 padding 要归零(没有底部条了)');
});