harmony(ui): 登录页 1:1 对齐 WebUI 卡片规格 + 通信页改用系统 Navigation Auto

登录页(LoginPage.ets):对照 WebUI LoginPage.tsx 同规格重写 build()
- maxWidth 380vp 居中卡片(与 WebUI 380px 同档)
- 14vp 圆角(Theme.glassRadius)
- 48vp 品牌图标(Envelope 浅蓝底 accentSoft)
- 显式字段标签(服务器/用户名/密码/用户密钥)
- 40vp 输入框与登录按钮(WebUI 控件同高)
- 分段式登录方式切换(账号密码 / 用户密钥)
- 窄屏安全边距 16vp + Scroll 可滚

通信页(MainPage.ets CommPage):改用鸿蒙系统 Navigation 组件
- Navigation(navPathStack) 包住列表,navDestination 注册邮件详情目标页
- mode(NavigationMode.Auto):phone 自动 Stack、tablet/2in1 自动 Split
- navBarWidth(320) 对齐 WebUI MailList 320px;navBarWidthRange([280,360])
- minContentWidth(360) 参与 Auto 断点计算
- Inbox/Sent 选中邮件改走 navPathStack.pushPath,不再 router.pushUrl
- 切收件箱/发件箱/授权时清空详情栈避免跨栏残留

详情页(MailDetailPage.ets):抽出可复用 MailDetailView
- 既有详情实现导出为 @Component struct MailDetailView
- 新增 initialMailId/initialAccountId/embedded/onBack 输入
- 无 initialMailId 时才读路由参数(兼容旧 router 入口)
- embedded=true 时返回走 onBack 回调(NavPathStack.pop)
- 薄壳 @Entry MailDetailPage 用 Column 包裹(@Entry 根节点须容器)

module.json5:deviceTypes 扩展为 phone/tablet/2in1 三形态

判据:harmony-widescreen.test.mjs 新增 ⑥ 钉住 Navigation Auto 不许退回手搓分栏

验证:ArkTS 编译通过;harmony-arkts/widescreen/nav/cross-client-theme 35/35 通过
This commit is contained in:
2026-09-17 10:58:31 +08:00
parent f44b15684b
commit a5f680a147
5 changed files with 332 additions and 122 deletions

View File

@ -89,6 +89,33 @@ test('④ MainPage 接线:宽屏才挂侧栏、宽屏藏底部条、断点 768
assert.match(code_, /bottom:\s*this\.isWide \? 0 : NAV_CONTENT_RESERVE/, '宽屏内容 padding 要归零(没有底部条了)');
});
test('⑥ 邮件列表→详情使用系统 Navigation Auto,不再手搓 Row 分栏', () => {
const main = read('pages/MainPage.ets');
const code_ = stripComments(main);
/*
* phone / tablet / 2in1 的列表→详情行为交给系统:
* - 窄宽度自动 Stack(详情覆盖列表,可返回);
* - 宽窗口自动 Split(列表 + 详情并排)。
* 断点由 navBarWidthRange + minContentWidth 共同决定,不复制一套 onAreaChange。
*/
assert.match(code_, /private navPathStack: NavPathStack = new NavPathStack\(\)/,
'通信页必须持有 NavPathStack');
assert.match(code_, /Navigation\(this\.navPathStack\)/,
'通信页列表/详情必须由原生 Navigation 承载');
assert.match(code_, /\.navDestination\(this\.DestinationBuilder\)/,
'Navigation 必须注册邮件详情目标页 builder');
assert.match(code_, /\.mode\(NavigationMode\.Auto\)/,
'必须用 NavigationMode.Auto,让系统自动选择 Stack / Split');
assert.match(code_, /\.navBarWidth\(320\)/,
'宽屏列表栏应与 WebUI MailList 的 320px 同档');
assert.match(code_, /\.navBarWidthRange\(\[280, 360\]\)/,
'列表栏应允许系统在 280–360vp 内适配,而不是固定死布局');
assert.match(code_, /\.minContentWidth\(360\)/,
'详情栏最小宽度参与 Auto 断点计算');
assert.match(code_, /this\.navPathStack\.pushPath\(\{ name: MAIL_DETAIL_ROUTE, param: params \}\)/,
'选中邮件必须进入 NavPathStack,而不是绕回 router.pushUrl');
});
test('⑤ 宽屏 app-shell 几何:padding/gap/radius 与 WebUI 同值(一比一复刻的骨架)', () => {
const main = read('pages/MainPage.ets');
const code_ = stripComments(main);