Problem
AppUI's ToolbarUsage enum currently supports only two toolbar positions:
ContentManipulation (0) — top-left of content area
ViewNavigation (1) — top-right of content area
There is no built-in way to render toolbar items at the bottom of the content area. Applications that need bottom toolbar positions (e.g., bottom-right for map layer controls, navigation shortcuts, or supplementary view tools) must:
- Patch
@itwin/appui-react to add custom enum values
- Build a custom overlay component with absolute positioning
- Manually render a
<ToolbarComposer> inside that overlay
- Wire it into their frontstage content area
This defeats the purpose of the declarative UiItemsProvider pattern, where providers should only need to return items with a usage and orientation and let the framework handle positioning.
Use Case
The BIC Pineapple Viewer (Bentley Infrastructure Cloud) uses a Cesium-based frontstage that needs toolbar items positioned at the bottom-right of the content area — for example, a map layers toggle button. Today this requires a pnpm patch that extends ToolbarUsage with BottomContentManipulation = 2 and BottomViewNavigation = 3, plus a custom BottomRightToolbarOverlay component that wraps <ToolbarComposer> in an absolutely-positioned <div>.
This works, but it's fragile (patch breaks on every appui update) and forces every consumer to re-implement the same overlay pattern.
Proposed Solution
Extend ToolbarUsage and modify the standard layout to render bottom toolbars natively:
1. Enum extension (toolbar/ToolbarItem.ts):
export enum ToolbarUsage {
ContentManipulation = 0, // top-left (existing)
ViewNavigation = 1, // top-right (existing)
BottomContentManipulation = 2, // bottom-left (new)
BottomViewNavigation = 3, // bottom-right (new)
}
2. ToolbarComposer helpers (toolbar/ToolbarComposer.tsx):
toExpandsTo() — bottom usages expand Direction.Top
toPanelAlignment() — BottomViewNavigation + Horizontal → ToolbarPanelAlignment.End
3. Framework rendering (widget-panels/Toolbars.tsx + Toolbars.scss):
- Add
<ToolbarComposer> instances for BottomContentManipulation and BottomViewNavigation inside WidgetPanelsToolbars
- Conditionally render via
useActiveStageProvidedToolbarItems — hidden when no items exist for those usages
- Extend the CSS grid from 2-column to 2x2 (
grid-template-rows: auto 1fr auto) so bottom toolbars align to the bottom of the content area
No changes needed to useActiveStageProvidedToolbarItems, UiItemsManager, FrontstageConfig, or FrontstageDef — those already accept any ToolbarUsage value. This is additive and non-breaking.
Consumer Experience (After)
A UiItemsProvider returns items with the new usage — no custom overlay needed:
const provider: UiItemsProvider = {
id: "MyBottomToolbar",
getToolbarItems: () => [
ToolbarItemUtilities.createActionItem({
id: "map-layers-toggle",
itemPriority: 10,
icon: <SvgLayers />,
label: "Map Layers",
execute: () => { /* toggle */ },
layouts: {
standard: {
usage: ToolbarUsage.BottomViewNavigation,
orientation: ToolbarOrientation.Horizontal,
},
},
}),
],
};
Environment
@itwin/appui-react: 5.27.1
@itwin/core-frontend: 5.8.1
Problem
AppUI's
ToolbarUsageenum currently supports only two toolbar positions:ContentManipulation(0) — top-left of content areaViewNavigation(1) — top-right of content areaThere is no built-in way to render toolbar items at the bottom of the content area. Applications that need bottom toolbar positions (e.g., bottom-right for map layer controls, navigation shortcuts, or supplementary view tools) must:
@itwin/appui-reactto add custom enum values<ToolbarComposer>inside that overlayThis defeats the purpose of the declarative
UiItemsProviderpattern, where providers should only need to return items with ausageandorientationand let the framework handle positioning.Use Case
The BIC Pineapple Viewer (Bentley Infrastructure Cloud) uses a Cesium-based frontstage that needs toolbar items positioned at the bottom-right of the content area — for example, a map layers toggle button. Today this requires a pnpm patch that extends
ToolbarUsagewithBottomContentManipulation = 2andBottomViewNavigation = 3, plus a customBottomRightToolbarOverlaycomponent that wraps<ToolbarComposer>in an absolutely-positioned<div>.This works, but it's fragile (patch breaks on every appui update) and forces every consumer to re-implement the same overlay pattern.
Proposed Solution
Extend
ToolbarUsageand modify the standard layout to render bottom toolbars natively:1. Enum extension (
toolbar/ToolbarItem.ts):2. ToolbarComposer helpers (
toolbar/ToolbarComposer.tsx):toExpandsTo()— bottom usages expandDirection.ToptoPanelAlignment()—BottomViewNavigation+ Horizontal →ToolbarPanelAlignment.End3. Framework rendering (
widget-panels/Toolbars.tsx+Toolbars.scss):<ToolbarComposer>instances forBottomContentManipulationandBottomViewNavigationinsideWidgetPanelsToolbarsuseActiveStageProvidedToolbarItems— hidden when no items exist for those usagesgrid-template-rows: auto 1fr auto) so bottom toolbars align to the bottom of the content areaNo changes needed to
useActiveStageProvidedToolbarItems,UiItemsManager,FrontstageConfig, orFrontstageDef— those already accept anyToolbarUsagevalue. This is additive and non-breaking.Consumer Experience (After)
A
UiItemsProviderreturns items with the new usage — no custom overlay needed:Environment
@itwin/appui-react: 5.27.1@itwin/core-frontend: 5.8.1