/* * 宽屏侧栏图标轨 —— **一比一复刻 WebUI 的 `Sidebar.tsx`**。 * * WebUI 的 `Sidebar`(60px 宽)是**纯图标轨**(无 label 文字): * · 品牌标(顶部) * · 通信 / 日历 / 联系人(中部) * · 设置(底部) * 选中态:图标变色(`navFgActive`),**不加背景块、不加指示条、不加文字** * (用户 2026-09-16:「底部导航栏不允许有文字」⇒ 侧栏同样按纯图标走)。 * 图标 26vp(WebUI 侧是 24,鸿蒙放大一档 —— 用户嫌 22 太小)。 * * 鸿蒙这一侧原先**完全没有宽屏布局**(只有底部导航条),所以这个文件同时承担 * "宽屏入口"的角色。判据 `harmony-widescreen.test.mjs` 会检查: * · 60vp 宽(与 WebUI 的 60px 一致) * · 三项导航 + 设置按钮 * · 选中态只换颜色(与底部导航同一套纪律) */ import { Theme } from '../common/Theme'; import { AmIcon } from '../common/Icons'; import { NAV_ITEMS, NavItem } from '../model/NavItems'; /** 侧栏宽度(vp)。WebUI 的 `Sidebar` 用 `w-[60px]` */ export const SIDEBAR_WIDTH: number = 60; @Component export struct WideSidebar { /** 当前选中的导航下标 */ @Prop currentIndex: number = 0; /** 选中回调 */ onSelect: (index: number) => void = (): void => {}; /** 设置回调 */ onSettings: () => void = (): void => {}; @Builder NavItemBuilder(key: string, iconKey: string, index: number) { Column() { AmIcon({ iconName: iconKey, iconSize: 26, iconColor: this.currentIndex === index ? Theme.navFgActive : Theme.navFg }) } .width('100%') .layoutWeight(1) .justifyContent(FlexAlign.Center) .onClick(() => { this.onSelect(index); }) } build() { Column() { // 品牌标 AmIcon({ iconName: 'brandMark', iconSize: 30, iconColor: Theme.accent }) .margin({ bottom: 16 }) // 导航项 ForEach(NAV_ITEMS, (item: NavItem, index: number) => { this.NavItemBuilder(item.key, item.iconKey, index) }, (item: NavItem) => item.key) Blank() // 设置 Column() { AmIcon({ iconName: 'person', iconSize: 26, iconColor: Theme.navFg }) } .width('100%') .layoutWeight(1) .justifyContent(FlexAlign.Center) .onClick(() => { this.onSettings(); }) } .width(SIDEBAR_WIDTH) .height('100%') .padding({ top: 12, bottom: 12 }) .backgroundColor(Theme.surface) .borderRadius(Theme.glassRadius) } }