App Shell 应用外壳
侧边栏 + 顶栏 + 滚动内容合为一个区块——也就是本画廊的布局,由数据驱动。它自行处理沉浸式安全区,内容在半透明顶栏下方滚动,切换页面时回到顶部。
基础用法
网页近似预览,真机效果以 HarmonyOS 渲染为准。
API
从组件库源码中的 @Param / @Event / @BuilderParam 声明自动提取。
SAppShell
开箱即用的应用外壳,同时是 SSidebarProvider / SSidebar / SSidebarInset / STopbar 之上的一层薄的数据驱动封装:侧边栏(品牌、分组导航、用户页脚)、顶栏(侧边栏触发器、当前页面标题、搜索、操作)以及页面内容,可选页脚。
无断点:layoutPolicy 根据外壳自身的宽度决定侧边栏是停靠、收成图标栏还是变为侧边面板(默认:放得下就停靠,否则变为侧边面板;sparkSidebarRailPolicy() 增加图标栏这一档)。 支持沉浸式(safeArea,默认开启):侧边栏、顶栏和内容会自行留出窗口的安全区(ADR D10,expandSafeArea 无法穿透自定义组件)。
扩展点(docs/design/blocks-extensibility.md):controller(自行持有 SparkSidebarState)、layoutPolicy、每次状态变化都会触发的事件,以及每个区域的 WrappedBuilder 区域(titleBarBuilder、sidebarHeaderBuilder、sidebarContentBuilder、sidebarFooterBuilder、navItemBuilder(item)、navGroupLabelBuilder(group)、topbarLeadingBuilder、topbarTitleBuilder、topbarActionsBuilder、headerBuilder、footerBuilder),showTopbar / scrollable 可选择不使用内置的顶栏和滚动容器。 区域是对数据属性的补充(把 brand / user / nav 留空即可替换它们)。页面是唯一的 @BuilderParam(尾随闭包);区域接收 wrapBuilder(globalBuilder)——全局 builder 没有 this,因此请在其中渲染你自己的组件,或读取共享状态(自行持有 controller 即可访问侧边栏)。 如需更多定制,直接组合 SSidebarProvider / SSidebar / SSidebarInset / STopbar。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
brand | ResourceStr | '' | |
brandIcon | string | 'sparkles' | |
brandDetail | ResourceStr | undefined | undefined | |
nav | SparkShellNavGroup[] | [] | |
controller | SparkSidebarState | undefined | undefined | 你自己的侧边栏状态对象(无头控制);省略时会自动创建 |
value!! | string | undefined | undefined | 当前激活的导航项 id |
defaultValue | string | '' | |
title | ResourceStr | undefined | undefined | 顶栏标题(默认:当前导航项的标题) |
subtitle | ResourceStr | undefined | undefined | |
actions | SparkTopbarAction[] | [] | |
search | boolean | false | |
searchPlaceholder | ResourceStr | $r('app.string.spark_search_placeholder') | |
user | SparkShellUser | undefined | undefined | |
footerText | ResourceStr | undefined | undefined | |
variant | SidebarVariantSidebarVariant = 'sidebar' | 'floating' | 'inset' | 'sidebar' | |
collapsible | SidebarCollapsibleSidebarCollapsible = 'offcanvas' | 'icon' | 'none' | 'icon' | |
side | SidebarSideSidebarSide = 'left' | 'right' | 'left' | |
sidebarWidth | number | 0 | 停靠侧边栏的宽度(vp);0 表示使用 --sidebar-width 令牌,否则为 256 |
minInsetWidth | number | 360 | layoutPolicy 的输入:内容区域至少应保持的宽度(vp) |
closeOnSelect | boolean | true | |
motionKey | string | 'sidebar' | |
open!! | boolean | undefined | undefined | |
defaultOpen | boolean | true | 停靠的初始状态;把持久化的值传到这里,并在 onOpenChange 中保存 |
showTopbar | boolean | true | 是否显示内置顶栏(false:改用 headerBuilder 或在内容中自行提供) |
topbarLeading | TopbarLeadingTopbarLeading = 'auto' | 'trigger' | 'back' | 'none' | 'auto' | 顶栏前导控件:'auto'(侧边栏触发器);例如标题栏已经包含该控件时用 'none' |
topbarBlur | boolean | true | 半透明顶栏,内容在其下方滚动 |
scrollable | boolean | true | 把内容包裹在带内边距、居中的滚动容器中(false:内容按原样铺满区域) |
safeArea | boolean | true | 为窗口安全区留出内边距(沉浸式页面) |
maxContentWidth | number | undefined | undefined | 页面内容的最大宽度(0 表示不限;未设置时取 --app-shell-content-max-width,否则为 1200) |
tokens | AppShellTokens | {} | 实例级令牌(ADR D13):内容最大宽度 / 内边距,以及外壳自行构建的部分所对应的 sidebar({@link SidebarTokens})和 topbar({@link TopbarTokens})。主题变量:--app-shell-*、--sidebar-*、--topbar-*。 |
titleBarBuilder | WrappedBuilder<[]> | undefined | undefined | 整个外壳上方的区域,例如用于自由窗口的 STitleBar |
sidebarHeaderBuilder | WrappedBuilder<[]> | undefined | undefined | 位于侧边栏头部品牌下方(团队切换器、搜索等) |
sidebarContentBuilder | WrappedBuilder<[]> | undefined | undefined | 位于可滚动侧边栏内容中导航分组之后 |
sidebarFooterBuilder | WrappedBuilder<[]> | undefined | undefined | 位于侧边栏页脚的用户信息下方 |
navItemBuilder | WrappedBuilder<[SparkShellNavItem]> | SPARK_SHELL_NAV_ITEM | 渲染单个导航项(默认:wrapBuilder(sparkShellNavItemBuilder)) |
navGroupLabelBuilder | WrappedBuilder<[SparkShellNavGroup]> | SPARK_SHELL_NAV_GROUP_LABEL | 渲染分组标签(默认:wrapBuilder(sparkShellNavGroupLabelBuilder)) |
topbarLeadingBuilder | WrappedBuilder<[]> | undefined | undefined | 顶栏额外的前导内容(STopbar 的 leadingBuilder) |
topbarTitleBuilder | WrappedBuilder<[]> | undefined | undefined | 顶栏额外的标题内容(STopbar 的 titleBuilder) |
topbarActionsBuilder | WrappedBuilder<[]> | undefined | undefined | 位于 actions 之后的顶栏尾部内容(纯图标按钮更适合放进 actions) |
headerBuilder | WrappedBuilder<[]> | undefined | undefined | 位于顶栏下方、内容上方(标签页、筛选器等;使用 showTopbar: false 时也可作为自定义顶栏) |
footerBuilder | WrappedBuilder<[]> | undefined | undefined | 位于内容之后(位于 footerText 之后) |
| 事件 | 类型 | 默认值 | 说明 |
|---|---|---|---|
onValueChange | (value: string) => void | () => { } | |
onNavigate | (value: string) => void | () => { } | 每次激活导航项都会触发,即使是当前项(路由钩子) |
onAction | (id: string) => void | () => { } | |
onSearch | (value: string) => void | () => { } | |
onSearchChange | (value: string) => void | () => { } | |
layoutPolicy | SparkSidebarLayoutPolicy | sparkSidebarDefaultPolicy | |
onPresentationChange | (presentation: SidebarPresentation) => voidSidebarPresentation = 'docked' | 'rail' | 'sheet' | () => { } | |
onOpenMobileChange | (open: boolean) => void | () => { } | |
onOpenChange | (open: boolean) => void | () => { } |
插槽: 子组件(尾随闭包)