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)
This commit is contained in:
@ -313,17 +313,27 @@ test('★ 玻璃只在两处、且这一处是"背后有可变内容"(GLASS
|
||||
* 跨端对齐:这条与 WebUI 的 `nav-merge.test.mjs ④` 是同一条要求的两端实现,
|
||||
* 两边各自钉住自己的写法(`cross-client-*` 那几条钉的是共享数值,不是这里)。
|
||||
*/
|
||||
test('⑤ 选中态只换颜色:图标与文字都变色,且不引入背景/指示条', () => {
|
||||
test('⑤ 选中态只换颜色:纯图标导航、图标变色,且不引入背景/指示条/文字', () => {
|
||||
const item = builderBody(main, 'NavItem(item: NavItem, index: number) {');
|
||||
const itemCode = stripComments(item);
|
||||
/*
|
||||
* 2026-09-16 用户:「底部导航栏不允许有文字」⇒ 导航项是**纯图标**,
|
||||
* 只有 1 处选中三元式(AmIcon 的 iconColor)。文字那一半被去掉。
|
||||
*/
|
||||
const active = /this\.currentIndex === index \? Theme\.navFgActive : Theme\.navFg/g;
|
||||
const hits = itemCode.match(active) || [];
|
||||
assert.equal(hits.length, 2,
|
||||
`图标与文字都要过同一个选中三元式(现在 ${hits.length} 处)—— 只给文字上色就是"选中了一半"`);
|
||||
// 图标(AmIcon 的 iconColor)与文字(Text 的 fontColor)各自紧跟着那个三元式
|
||||
const icon = itemCode.slice(itemCode.indexOf('AmIcon({'), itemCode.indexOf('Text(item.label)'));
|
||||
assert.equal(hits.length, 1,
|
||||
`纯图标导航只应有 1 处选中三元式(现在 ${hits.length} 处)— 若有 2 处是文字还留着`);
|
||||
// 图标上色必须存在(AmIcon 的 iconColor 跟着选中态走)
|
||||
const icon = itemCode.slice(itemCode.indexOf('AmIcon({'), itemCode.indexOf('AmIcon({') + 160);
|
||||
assert.match(icon, /iconColor:\s*this\.currentIndex === index \? Theme\.navFgActive : Theme\.navFg/,
|
||||
'图标的 iconColor 必须跟着选中态走');
|
||||
// 图标不能太小(用户:22 太小)
|
||||
assert.match(icon, /iconSize: 28/,
|
||||
'底部导航图标要 28vp(用户嫌 22 太小)');
|
||||
// 无文字:导航项里不该有 label 的 Text
|
||||
assert.ok(!/Text\(item\.label\)/.test(itemCode),
|
||||
'底部导航是纯图标:不允许有文字 label(2026-09-16 用户明确要求)');
|
||||
// 反面:选中态不得靠形状表达(背景 / 圆角块 / 下划线元素)
|
||||
assert.ok(!/backgroundColor\([^)]*currentIndex/.test(itemCode),
|
||||
'选中态不许改背景色("变色即可",形状是另一套语言)');
|
||||
@ -337,20 +347,19 @@ test('⑤ 选中态只换颜色:图标与文字都变色,且不引入背景/
|
||||
'未选中色取系统次要文字色(不手写色值)');
|
||||
});
|
||||
|
||||
/** ⑤ 的变异自检:把图标那行退回"只给文字上色",判据必须红。 */
|
||||
test('★ ⑤ 变异自检:图标不上色(改造前的写法)必须被判红', () => {
|
||||
const oldIconLine = 'AmIcon({ iconName: item.iconKey, iconSize: 22 })';
|
||||
const itemCode = `Column() {\n ${oldIconLine}\n Text(item.label)\n .fontColor(this.currentIndex === index ? Theme.navFgActive : Theme.navFg)\n }`;
|
||||
const hits = itemCode.match(/this\.currentIndex === index \? Theme\.navFgActive : Theme\.navFg/g) || [];
|
||||
assert.equal(hits.length, 1, '旧写法只有 label 上色 ⇒ ⑤ 的"必须两处"会命中它');
|
||||
/*
|
||||
* 判定窗口必须与 ⑤ **完全同一条规则**:从 `AmIcon({` 切到下一个 `Text(`。
|
||||
* 我第一版在这里写的是 `Text\(item\.icon\)[\s\S]{0,80}fontColor` —— 那个窗口
|
||||
* 把**下一行 label 的** fontColor 也圈进来了,于是"旧写法没有图标上色"这条
|
||||
* 自检自己绿了(正是本仓库反复记的"窗口式判据")。判据被它咬了一次。
|
||||
*/
|
||||
const icon = itemCode.slice(itemCode.indexOf('AmIcon({'), itemCode.indexOf('Text(', itemCode.indexOf('AmIcon({') + 1));
|
||||
assert.ok(!/iconColor:/.test(icon), `旧写法里图标没有 iconColor ⇒ ⑤ 的图标那一半会命中它(切片=${JSON.stringify(icon)})`);
|
||||
/** ⑤ 的变异自检:退回"带文字 / 太小 / 图标不上色"必须被判红。 */
|
||||
test('★ ⑤ 变异自检:nav 项退回带文字或 22 尺寸或图标不上色必须被判红', () => {
|
||||
// 变异 1:带文字(Text(item.label))⇒ ⑤ 的"无文字"会命中它
|
||||
const withLabel = `Column() {\n AmIcon({ iconName: item.iconKey, iconSize: 28 })\n Text(item.label)\n .fontColor(this.currentIndex === index ? Theme.navFgActive : Theme.navFg)\n }`;
|
||||
assert.ok(/Text\(item\.label\)/.test(withLabel),
|
||||
'变异 1 自检失败:样本里必须有 label 文字');
|
||||
// 变异 2:图标 22(太小)⇒ ⑤ 的"iconSize: 28"会命中它
|
||||
const smallIcon = `Column() {\n AmIcon({ iconName: item.iconKey, iconSize: 22, iconColor: this.currentIndex === index ? Theme.navFgActive : Theme.navFg })\n }`;
|
||||
assert.ok(/iconSize: 22/.test(smallIcon) && !/iconSize: 28/.test(smallIcon),
|
||||
'变异 2 自检失败:样本里图标必须是 22 且不是 28');
|
||||
// 变异 3:图标不上色(没有 iconColor)⇒ ⑤ 的"iconColor 跟着选中态"会命中它
|
||||
const noColor = `Column() {\n AmIcon({ iconName: item.iconKey, iconSize: 28 })\n }`;
|
||||
assert.ok(!/iconColor/.test(noColor), '变异 3 自检失败:样本里不该有 iconColor');
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@ -50,14 +50,23 @@ test('② 三项导航 + 设置按钮:内容与 WebUI Sidebar 对齐', () => {
|
||||
assert.match(sidebar, /onSettings/, '设置按钮要回调 onSettings(点击后由 MainPage 路由)');
|
||||
});
|
||||
|
||||
test('③ 选中态只换颜色(与底部导航同一套纪律)', () => {
|
||||
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, 2,
|
||||
`图标与文字都要过同一个选中三元式(现在 ${hits.length} 处)`);
|
||||
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_),
|
||||
'选中态不许改背景色(与底部导航同一纪律:变色即可)');
|
||||
|
||||
Reference in New Issue
Block a user