toolbarService
Key Changes:
ViewportActionCornersService
Removed: TheViewportActionCornersService
and its associated provider (ViewportActionCornersProvider
) and hook (useViewportActionCorners
) have been removed. Functionality for viewport corner items is now integrated into theToolbarService
and standard toolbar components.- Viewport Corner Items as Toolbar Buttons: Items previously managed by
ViewportActionCornersService
are now configured as regular toolbar buttons. They are assigned to specific toolbar sections (e.g.,viewportActionMenu.topLeft
) and rendered usingToolbar
components within the viewport corners. ToolbarService
API Updates:ToolbarService.addButtons()
has been renamed toToolbarService.register()
to better reflect its purpose of registering button definitions rather than just adding them.ToolbarService.createButtonSection()
has been renamed toToolbarService.updateSection()
to better reflect that it is not about creating new sections but updating existing ones.ToolbarService
now has asections
property (e.g.,toolbarService.sections.viewportActionMenu.topLeft
) providing predefined section names.
- Enhanced
useToolbar
Hook:- The
useToolbar
hook now returns additional state management functions for toolbar items:openItem
,closeItem
,isItemOpen
(for managing dropdown/popover states).lockItem
,unlockItem
,toggleLock
,isItemLocked
.showItem
,hideItem
,toggleVisibility
,isItemVisible
.
- The
onInteraction
callback now receivesitemId
andviewportId
.
- The
- Toolbar Button Configuration:
- The
groupId
prop in button configurations (e.g., forohif.toolButtonList
,ohif.toolBoxButtonGroup
) is generally replaced by directly usingbuttonSection
to define the set of buttons. - Button
evaluate
functions can now leverageevaluateProps.hideWhenDisabled
to automatically hide a button when it's disabled.
- The
- New UI Components & Hooks for Viewport Corners:
- Specialized components like
ModalityLoadBadge
,NavigationComponent
,TrackingStatus
,ViewportDataOverlayMenuWrapper
,ViewportOrientationMenuWrapper
,WindowLevelActionMenuWrapper
are now used as toolbar buttons, typically in viewport action menu sections. useViewportHover
hook can be used to determine if a viewport is hovered or active, controlling the visibility of corner toolbars.
- Specialized components like
IconPresentationProvider
: A newIconPresentationProvider
anduseIconPresentation
hook have been introduced to standardize icon sizing and styling within toolbars and related components.- Legacy Toolbar Components Removed:
ToolbarSplitButtonWithServicesLegacy
andToolbarButtonGroupWithServicesLegacy
have been removed.
Migration Steps:
-
Update
ToolbarService
Method Calls:- Although the previous method also works but gives warning in the console when used.
- Replace all instances of
toolbarService.addButtons(...)
withtoolbarService.register(...)
. - Replace all instances of
toolbarService.createButtonSection(...)
withtoolbarService.updateSection(...)
.
// Before
- toolbarService.addButtons(toolbarButtons);
- toolbarService.createButtonSection('primary', ['Zoom', 'Pan']);
// After
+ toolbarService.register(toolbarButtons);
+ toolbarService.updateSection('primary', ['Zoom', 'Pan']); -
Migrate Viewport Action Corner Items:
- Remove any direct usage of the old
ViewportActionCornersService
,useViewportActionCorners
, orViewportActionCornersProvider
. - Define your viewport corner items (like orientation menu, W/L menu, data overlay menu) as standard toolbar buttons using
toolbarService.register()
. - Assign these buttons to the new dedicated viewport action menu sections. You can access these section names via
toolbarService.sections.viewportActionMenu.<location>
, e.g.,toolbarService.sections.viewportActionMenu.topLeft
.
// Before: Customization in viewportActionMenuCustomizations.ts (now deleted)
// or direct use of ViewportActionCornersService.addComponent
- // Example: viewportActionCornersService.addComponent({ viewportId, id: 'orientationMenu', component: MyOrientationMenu, location: 'topLeft' });
// After: In your mode's onModeEnter or similar setup
+ const myViewportCornerButtons = [
+ {
+ id: 'orientationMenu',
+ uiType: 'ohif.orientationMenu', // Or your custom component registered as a UI type
+ props: { /* ... props for your component ... */ }
+ },
+ // ... other corner buttons
+ ];
+ toolbarService.register(myViewportCornerButtons);
+ toolbarService.updateSection(
+ toolbarService.sections.viewportActionMenu.topLeft,
+ ['orientationMenu', /* other button IDs */]
+ );- The
OHIFViewportActionCorners.tsx
component now internally usesToolbar
components for each corner, which are populated by these sections. - For custom components that act as menus (e.g., popovers), use the
onOpen
,onClose
,isOpen
props passed down by theToolbar
component (which get these fromuseToolbar
).
// Before: Custom component might have managed its own open state
- // const [isMenuOpen, setIsMenuOpen] = useState(false);
- // const handleOpenChange = (open) => setIsMenuOpen(open);
// After: Custom component receives isOpen, onOpen, onClose from Toolbar
+ function MyCustomMenuButton({ isOpen, onOpen, onClose, ...rest }) {
+ const handleOpenChange = (openState: boolean) => {
+ if (openState) {
+ onOpen?.();
+ } else {
+ onClose?.();
+ }
+ };
+
+ return (
+ <Popover open={isOpen} onOpenChange={handleOpenChange}>
+ {/* ... PopoverTrigger and PopoverContent ... */}
+ </Popover>
+ );
+ } - Remove any direct usage of the old
-
Adapt Toolbar Button and Component Configurations:
The configuration of toolbar buttons, especially how they relate to sections
-
Button Section Association via
props.buttonSection
:The toolbar service now offers two ways to define this association:
-
A. Simple Approach:
buttonSection: true
(Implicitly Uses Button's Own ID)If a button definition includes
props: { buttonSection: true }
, theToolbarService
automatically sets the effectivebuttonSection
ID to be the same as the button's ownid
.// Example: A ToolButtonList component's definition in toolbarButtons.ts
// {
// id: 'MeasurementTools', // ID of this ToolButtonList component
// uiType: 'ohif.toolButtonList',
// props: {
// buttonSection: true // This ToolButtonList will render the section named 'MeasurementTools'
// }
// }later you can use it like
toolbarService.updateSection('MeasurementTools', ['Length', 'Bidirectional', ...]);
-
B. Flexible Approach:
buttonSection: 'customSectionName'
(Explicit Section ID)You can explicitly provide a string for
props.buttonSection
if the button should be associated with a section ID that is different from its ownid
, or if you prefer explicit naming.// Example: A ToolButtonList component's definition
// {
// id: 'MySpecialToolList', // ID of this ToolButtonList component
// uiType: 'ohif.toolButtonList',
// props: {
// buttonSection: 'toolsForAdvancedUsers', // This list renders 'toolsForAdvancedUsers' section
// }
// }
-
-
evaluate
Function Enhancement:- Button
evaluate
functions can now leverageevaluateProps: { hideWhenDisabled: true }
in your button definition to automatically hide a button when it's disabled.
- Button
-
Wrapper Component
onInteraction
(e.g.,ToolButtonListWrapper
):- Update wrappers like
ToolBoxButtonGroupWrapper
andToolButtonListWrapper
:- The
groupId
prop is replaced byid
(which is the ID of the wrapper button component itself). - The
onInteraction
callback in these wrappers now providesid
(the wrapper's ID) instead ofgroupId
.
- The
- Update wrappers like
-
-
Adopt
IconPresentationProvider
(Optional but Recommended):- For consistent icon styling across your application's toolbars, wrap a high-level component (like your main
Header
or layout component) with<IconPresentationProvider size="yourDefaultSize">
. - Custom tool button components can then use the
useIconPresentation
hook to get appropriate class names for icons or a pre-styledIconContainer
.
// In your main App.tsx or Header.tsx
+ import { IconPresentationProvider, ToolButton } from '@ohif/ui-next';
// ...
+ <IconPresentationProvider
+ size="large" // Or "medium", "small", "tiny", or a number
+ IconContainer={ToolButton} // Optional: default is Button
+ containerProps={{ variant: 'primary', className: 'custom-container-class' }} // Optional
+ >
{/* Your Header content including Toolbars */}
+ </IconPresentationProvider>
// In a custom tool button using icons
+ import { useIconPresentation, Icons } from '@ohif/ui-next';
+ function MyCustomToolButton({ iconName }) {
+ const { className: iconClassName } = useIconPresentation();
+ return <button><Icons.ByName name={iconName} className={iconClassName} /></button>;
+ } - For consistent icon styling across your application's toolbars, wrap a high-level component (like your main
-
Remove Legacy Component Usage:
- Replace any usage of
ToolbarSplitButtonWithServicesLegacy
andToolbarButtonGroupWithServicesLegacy
with the newer patterns, typically by configuring individual buttons and usingToolButtonList
orButtonGroup
from@ohif/ui-next
directly, driven byuseToolbar
.
- Replace any usage of