Skip to content

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。

属性类型默认值说明
brandResourceStr''
brandIconstring'sparkles'
brandDetailResourceStr | undefinedundefined
navSparkShellNavGroup[][]
controllerSparkSidebarState | undefinedundefined你自己的侧边栏状态对象(无头控制);省略时会自动创建
value!!string | undefinedundefined当前激活的导航项 id
defaultValuestring''
titleResourceStr | undefinedundefined顶栏标题(默认:当前导航项的标题)
subtitleResourceStr | undefinedundefined
actionsSparkTopbarAction[][]
searchbooleanfalse
searchPlaceholderResourceStr$r('app.string.spark_search_placeholder')
userSparkShellUser | undefinedundefined
footerTextResourceStr | undefinedundefined
variantSidebarVariant
SidebarVariant = 'sidebar' | 'floating' | 'inset'
'sidebar'
collapsibleSidebarCollapsible
SidebarCollapsible = 'offcanvas' | 'icon' | 'none'
'icon'
sideSidebarSide
SidebarSide = 'left' | 'right'
'left'
sidebarWidthnumber0停靠侧边栏的宽度(vp);0 表示使用 --sidebar-width 令牌,否则为 256
minInsetWidthnumber360layoutPolicy 的输入:内容区域至少应保持的宽度(vp)
closeOnSelectbooleantrue
motionKeystring'sidebar'
open!!boolean | undefinedundefined
defaultOpenbooleantrue停靠的初始状态;把持久化的值传到这里,并在 onOpenChange 中保存
showTopbarbooleantrue是否显示内置顶栏(false:改用 headerBuilder 或在内容中自行提供)
topbarLeadingTopbarLeading
TopbarLeading = 'auto' | 'trigger' | 'back' | 'none'
'auto'顶栏前导控件:'auto'(侧边栏触发器);例如标题栏已经包含该控件时用 'none'
topbarBlurbooleantrue半透明顶栏,内容在其下方滚动
scrollablebooleantrue把内容包裹在带内边距、居中的滚动容器中(false:内容按原样铺满区域)
safeAreabooleantrue为窗口安全区留出内边距(沉浸式页面)
maxContentWidthnumber | undefinedundefined页面内容的最大宽度(0 表示不限;未设置时取 --app-shell-content-max-width,否则为 1200)
tokensAppShellTokens{}实例级令牌(ADR D13):内容最大宽度 / 内边距,以及外壳自行构建的部分所对应的 sidebar({@link SidebarTokens})和 topbar({@link TopbarTokens})。主题变量:--app-shell-*、--sidebar-*、--topbar-*。
titleBarBuilderWrappedBuilder<[]> | undefinedundefined整个外壳上方的区域,例如用于自由窗口的 STitleBar
sidebarHeaderBuilderWrappedBuilder<[]> | undefinedundefined位于侧边栏头部品牌下方(团队切换器、搜索等)
sidebarContentBuilderWrappedBuilder<[]> | undefinedundefined位于可滚动侧边栏内容中导航分组之后
sidebarFooterBuilderWrappedBuilder<[]> | undefinedundefined位于侧边栏页脚的用户信息下方
navItemBuilderWrappedBuilder<[SparkShellNavItem]>SPARK_SHELL_NAV_ITEM渲染单个导航项(默认:wrapBuilder(sparkShellNavItemBuilder))
navGroupLabelBuilderWrappedBuilder<[SparkShellNavGroup]>SPARK_SHELL_NAV_GROUP_LABEL渲染分组标签(默认:wrapBuilder(sparkShellNavGroupLabelBuilder))
topbarLeadingBuilderWrappedBuilder<[]> | undefinedundefined顶栏额外的前导内容(STopbar 的 leadingBuilder)
topbarTitleBuilderWrappedBuilder<[]> | undefinedundefined顶栏额外的标题内容(STopbar 的 titleBuilder)
topbarActionsBuilderWrappedBuilder<[]> | undefinedundefined位于 actions 之后的顶栏尾部内容(纯图标按钮更适合放进 actions)
headerBuilderWrappedBuilder<[]> | undefinedundefined位于顶栏下方、内容上方(标签页、筛选器等;使用 showTopbar: false 时也可作为自定义顶栏)
footerBuilderWrappedBuilder<[]> | undefinedundefined位于内容之后(位于 footerText 之后)
事件类型默认值说明
onValueChange(value: string) => void() => { }
onNavigate(value: string) => void() => { }每次激活导航项都会触发,即使是当前项(路由钩子)
onAction(id: string) => void() => { }
onSearch(value: string) => void() => { }
onSearchChange(value: string) => void() => { }
layoutPolicySparkSidebarLayoutPolicysparkSidebarDefaultPolicy
onPresentationChange(presentation: SidebarPresentation) => void
SidebarPresentation = 'docked' | 'rail' | 'sheet'
() => { }
onOpenMobileChange(open: boolean) => void() => { }
onOpenChange(open: boolean) => void() => { }

插槽: 子组件(尾随闭包)

MIT Licensed