Skip to content

Top Bar ​

The app header block: leading control, title, search and actions. It condenses on its own when narrow (shorter, subtitle hidden, search behind an icon) and adds the status-bar inset in immersive pages.

Usage ​

Approximate web preview — the HarmonyOS rendering is the reference.

API ​

Extracted from the @Param / @Event / @BuilderParam declarations in the library sources.

STopbar ​

App header (shadcn "site header" block): leading control, title / subtitle, optional search, icon actions and a trailing slot. Breakpoint-free: below ~520 vp of its own width it condenses (48 vp tall, subtitle hidden, search behind an icon that expands over the title).

It stays at the top because it lives outside the scrolling content (SAppShell / SSidebarInset). With translucent the background is translucent + backdrop-blurred, for content that scrolls underneath (SAppShell does that). safeArea adds the status-bar inset for immersive pages (skipped automatically inside a framed 'inset' sidebar layout, whose card already clears it).

Extension points: the trailing closure (after actions); leadingBuilder / titleBuilder regions as WrappedBuilders (titleBuilder: wrapBuilder(myGlobalBuilder); additive — set leading: 'none' or an empty title to replace the built-ins), condenseBelow and barHeight instead of fixed metrics, onBack for any back handling (no routing built in). Inside an SSidebarProvider, leading: 'auto' follows the sidebar controller (toggleable).

PropTypeDefaultDescription
titleResourceStr''
subtitleResourceStr | undefinedundefined
leadingTopbarLeading
TopbarLeading = 'auto' | 'trigger' | 'back' | 'none'
'auto'
actionsSparkTopbarAction[][]
searchbooleanfalseshow a search field (an icon that expands when condensed)
searchPlaceholderResourceStr$r('app.string.spark_search_placeholder')
translucentbooleanfalsetranslucent, backdrop-blurred background
borderedbooleantrue
safeAreabooleanfalseadd the top safe-area inset (immersive pages)
condenseBelownumberTOPBAR_CONDENSED_BELOWcondense below this width of the bar itself (vp)
barHeightnumber0bar height without the safe-area inset (vp, 0 = --topbar-height[-condensed], else 56 / 48 condensed)
leadingBuilderWrappedBuilder<[]> | undefinedundefinedExtra leading content after the built-in leading control (use leading: 'none' to replace it), as wrapBuilder(myLeading) of a global @Builder (no this: render a component or read shared state).
titleBuilderWrappedBuilder<[]> | undefinedundefinedExtra title content under / instead of title (breadcrumbs, a switcher…; leave title empty to replace), as wrapBuilder(myTitle) of a global @Builder.
tokensTopbarTokens{}per-instance look (ADR D13): instance → --topbar-* tokens → recipe
sidebarControllerSparkSidebarState | undefinedundefineddrive the leading trigger from this controller (e.g. a bar outside the SSidebarProvider)
EventTypeDefaultDescription
onBack() => void() => { }
onAction(id: string) => void() => { }
onSearchChange(value: string) => void() => { }
onSearch(value: string) => void() => { }

Slots: children (trailing closure)

MIT Licensed