Skip to content

Add bottom toolbar positions to ToolbarUsage and render them in the standard layout #1539

Description

@jason-crow

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:

  1. Patch @itwin/appui-react to add custom enum values
  2. Build a custom overlay component with absolute positioning
  3. Manually render a <ToolbarComposer> inside that overlay
  4. 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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions