-
Notifications
You must be signed in to change notification settings - Fork 3
feat: Add bottom toolbar positions to ToolbarUsage and render them in the standard layout #1542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@itwin/appui-react": minor | ||
| --- | ||
|
|
||
| Added `BottomContentManipulation` and `BottomViewNavigation` values to the `ToolbarUsage` enum. The standard layout now automatically renders bottom toolbar positions when a `UiItemsProvider` returns items with these usages — no custom overlay component is needed. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,10 @@ export enum ToolbarUsage { | |
| ContentManipulation = 0, | ||
| /** Manipulate view/camera - in AppUI this is in top right of content area. */ | ||
| ViewNavigation = 1, | ||
| /** Contains tools to Create Update and Delete content - rendered in bottom left of content area. */ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| BottomContentManipulation = 2, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we avoid placement keywords, like "Bottom"? Alternatively, we could introduce an explicit "placement" property, however that is basically re-implementing #1474 |
||
| /** Manipulate view/camera - rendered in bottom right of content area. */ | ||
|
Comment on lines
+25
to
+27
|
||
| BottomViewNavigation = 3, | ||
| } | ||
|
|
||
| /** Used to specify the orientation of the toolbar. | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -11,12 +11,59 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); // TODO: Change this to an AppUI global CSS variable. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| box-sizing: border-box; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-template-columns: 1fr 1fr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-template-rows: auto 1fr auto; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
13
to
15
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .nz-tools-widget { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-column: 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-row: 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &.nz-widget-navigationArea { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-column: 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-row: 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .uifw-widgetPanels-bottomToolbars { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-column: 1 / -1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-row: 3; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| display: flex; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| justify-content: space-between; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| align-items: flex-end; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pointer-events: none; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > * { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pointer-events: auto; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .uifw-bottom-toolArea { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| display: grid; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-gap: 6px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-template-areas: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "vtools ." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "vtools htools"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-template-columns: auto 1fr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-template-rows: 1fr auto; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| align-items: end; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| justify-items: start; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .uifw-bottom-toolArea_vertical { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-area: vtools; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| display: inline-flex; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| flex-direction: column; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .uifw-bottom-toolArea_horizontal { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| grid-area: htools; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| min-width: 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .uifw-bottom-toolArea_right { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| margin-left: auto; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .uifw-bottom-toolArea { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| justify-items: end; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
67
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .uifw-bottom-toolArea { | |
| display: grid; | |
| grid-gap: 6px; | |
| grid-template-areas: | |
| "vtools ." | |
| "vtools htools"; | |
| grid-template-columns: auto 1fr; | |
| grid-template-rows: 1fr auto; | |
| align-items: end; | |
| justify-items: start; | |
| } | |
| .uifw-bottom-toolArea_vertical { | |
| grid-area: vtools; | |
| display: inline-flex; | |
| flex-direction: column; | |
| } | |
| .uifw-bottom-toolArea_horizontal { | |
| grid-area: htools; | |
| min-width: 0; | |
| } | |
| .uifw-bottom-toolArea_right { | |
| margin-left: auto; | |
| .uifw-bottom-toolArea { | |
| justify-items: end; | |
| } | |
| } | |
| .uifw-bottom-toolArea { | |
| display: grid; | |
| grid-gap: 6px; | |
| grid-template-areas: | |
| "vtools ." | |
| "vtools htools"; | |
| grid-template-columns: auto 1fr; | |
| grid-template-rows: 1fr auto; | |
| align-items: end; | |
| justify-items: start; | |
| } | |
| .uifw-bottom-toolArea_vertical { | |
| grid-area: vtools; | |
| display: inline-flex; | |
| flex-direction: column; | |
| } | |
| .uifw-bottom-toolArea_horizontal { | |
| grid-area: htools; | |
| min-width: 0; | |
| } | |
| .uifw-bottom-toolArea_right { | |
| margin-left: auto; | |
| .uifw-bottom-toolArea { | |
| justify-items: end; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,10 +16,22 @@ export function WidgetPanelsToolbars() { | |
| const frontstageDef = useActiveFrontstageDef(); | ||
| const tools = frontstageDef?.contentManipulation?.reactNode; | ||
| const navigation = frontstageDef?.viewNavigation?.reactNode; | ||
| const bottomTools = frontstageDef?.bottomContentManipulation?.reactNode; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| const bottomNavigation = frontstageDef?.bottomViewNavigation?.reactNode; | ||
| return ( | ||
| <div className="uifw-widgetPanels-toolbars"> | ||
| {tools} | ||
| <NavigationWidget>{navigation}</NavigationWidget> | ||
| {(bottomTools || bottomNavigation) && ( | ||
| <div className="uifw-widgetPanels-bottomToolbars"> | ||
| {bottomTools} | ||
| {bottomNavigation && ( | ||
| <div className="uifw-bottom-toolArea_right"> | ||
| {bottomNavigation} | ||
| </div> | ||
| )} | ||
| </div> | ||
| )} | ||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| /*--------------------------------------------------------------------------------------------- | ||
| * Copyright (c) Bentley Systems, Incorporated. All rights reserved. | ||
| * See LICENSE.md in the project root for license terms and full copyright notice. | ||
| *--------------------------------------------------------------------------------------------*/ | ||
| /** @packageDocumentation | ||
| * @module Widget | ||
| */ | ||
|
|
||
| import * as React from "react"; | ||
| import { ToolbarComposer } from "../toolbar/ToolbarComposer.js"; | ||
| import { BottomToolWidgetComposer } from "./BottomToolWidgetComposer.js"; | ||
| import { ToolbarOrientation, ToolbarUsage } from "../toolbar/ToolbarItem.js"; | ||
|
|
||
| /** | ||
| * BottomContentToolWidgetComposer composes a bottom-left Tool Widget with no tools defined by default. | ||
| * UiItemsProviders are used to populate the toolbars by providing items with | ||
| * `ToolbarUsage.BottomContentManipulation`. | ||
| * @public | ||
| */ | ||
| export function BottomContentToolWidgetComposer() { | ||
| return ( | ||
| <BottomToolWidgetComposer | ||
| horizontalToolbar={ | ||
| <ToolbarComposer | ||
| items={[]} | ||
| usage={ToolbarUsage.BottomContentManipulation} | ||
| orientation={ToolbarOrientation.Horizontal} | ||
| /> | ||
| } | ||
| verticalToolbar={ | ||
| <ToolbarComposer | ||
| items={[]} | ||
| usage={ToolbarUsage.BottomContentManipulation} | ||
| orientation={ToolbarOrientation.Vertical} | ||
| /> | ||
| } | ||
| /> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| /*--------------------------------------------------------------------------------------------- | ||
| * Copyright (c) Bentley Systems, Incorporated. All rights reserved. | ||
| * See LICENSE.md in the project root for license terms and full copyright notice. | ||
| *--------------------------------------------------------------------------------------------*/ | ||
| /** @packageDocumentation | ||
| * @module Widget | ||
| */ | ||
|
|
||
| import "../widget-panels/Toolbars.scss"; | ||
| import * as React from "react"; | ||
|
Comment on lines
+8
to
+10
|
||
| import { | ||
| useProximityToMouse, | ||
| WidgetElementSet, | ||
| WidgetOpacityContext, | ||
| } from "@itwin/core-react/internal"; | ||
| import { UiFramework } from "../UiFramework.js"; | ||
| import { useUiVisibility } from "../hooks/useUiVisibility.js"; | ||
|
|
||
| /** Properties for {@link BottomToolWidgetComposer}. | ||
| * @public | ||
| */ | ||
| export interface BottomToolWidgetComposerProps { | ||
| /** Optional Horizontal Toolbar */ | ||
| horizontalToolbar?: React.ReactNode; | ||
| /** Optional Vertical Toolbar */ | ||
| verticalToolbar?: React.ReactNode; | ||
| } | ||
|
|
||
| /** | ||
| * BottomToolWidgetComposer renders an L-shaped toolbar area anchored to the bottom of the content area. | ||
| * The vertical toolbar grows upward and the horizontal toolbar is positioned at the bottom, | ||
| * offset by the vertical toolbar's width. | ||
| * @public | ||
| */ | ||
| export function BottomToolWidgetComposer( | ||
| props: BottomToolWidgetComposerProps | ||
| ) { | ||
| const { horizontalToolbar, verticalToolbar } = props; | ||
| const [elementSet] = React.useState(new WidgetElementSet()); | ||
| const proximityScale = useProximityToMouse( | ||
| elementSet, | ||
| UiFramework.visibility.snapWidgetOpacity | ||
| ); | ||
| const uiIsVisible = useUiVisibility(); | ||
|
|
||
| const addRef = React.useCallback< | ||
| React.ContextType<typeof WidgetOpacityContext>["addRef"] | ||
| >( | ||
| (ref) => { | ||
| elementSet.add(ref); | ||
| }, | ||
| [elementSet] | ||
| ); | ||
| const removeRef = React.useCallback< | ||
| React.ContextType<typeof WidgetOpacityContext>["removeRef"] | ||
| >( | ||
| (ref) => { | ||
| elementSet.delete(ref); | ||
| }, | ||
| [elementSet] | ||
| ); | ||
|
|
||
| if (!uiIsVisible) return null; | ||
|
|
||
| return ( | ||
| <WidgetOpacityContext.Provider | ||
| value={{ | ||
| addRef, | ||
| removeRef, | ||
| proximityScale, | ||
| }} | ||
| > | ||
| <div | ||
| className="uifw-bottom-toolArea" | ||
| onMouseEnter={UiFramework.visibility.handleWidgetMouseEnter} | ||
| > | ||
| <div className="uifw-bottom-toolArea_vertical"> | ||
| {verticalToolbar} | ||
| </div> | ||
| <div className="uifw-bottom-toolArea_horizontal"> | ||
| {horizontalToolbar} | ||
| </div> | ||
| </div> | ||
| </WidgetOpacityContext.Provider> | ||
| ); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if these APIs are useful on the
FrontstageDef? E.g. is there a cuse-case for existingfrontstageDef.viewNavigation?