toolbarService
Key Changes:
ViewportActionCornersServiceRemoved: TheViewportActionCornersServiceand its associated provider (ViewportActionCornersProvider) and hook (useViewportActionCorners) have been removed. Functionality for viewport corner items is now integrated into theToolbarServiceand standard toolbar components.- Viewport Corner Items as Toolbar Buttons: Items previously managed by
ViewportActionCornersServiceare now configured as regular toolbar buttons. They are assigned to specific toolbar sections (e.g.,viewportActionMenu.topLeft) and rendered usingToolbarcomponents within the viewport corners. ToolbarServiceAPI 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.ToolbarServicenow has asectionsproperty (e.g.,toolbarService.sections.viewportActionMenu.topLeft) providing predefined section names.
- Enhanced
useToolbarHook:- The
useToolbarhook 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
onInteractioncallback now receivesitemIdandviewportId.
- The
- Toolbar Button Configuration:
- The
groupIdprop in button configurations (e.g., forohif.toolButtonList,ohif.toolBoxButtonGroup) is generally replaced by directly usingbuttonSectionto define the set of buttons. - Button
evaluatefunctions can now leverageevaluateProps.hideWhenDisabledto automatically hide a button when it's disabled.
- The
- New UI Components & Hooks for Viewport Corners:
- Specialized components like
ModalityLoadBadge,NavigationComponent,TrackingStatus,ViewportDataOverlayMenuWrapper,ViewportOrientationMenuWrapper,WindowLevelActionMenuWrapperare now used as toolbar buttons, typically in viewport action menu sections. useViewportHoverhook can be used to determine if a viewport is hovered or active, controlling the visibility of corner toolbars.
- Specialized components like
IconPresentationProvider: A newIconPresentationProvideranduseIconPresentationhook have been introduced to standardize icon sizing and styling within toolbars and related components.- Legacy Toolbar Components Removed:
ToolbarSplitButtonWithServicesLegacyandToolbarButtonGroupWithServicesLegacyhave been removed.
Migration Steps:
-
Update
ToolbarServiceMethod 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.tsxcomponent now internally usesToolbarcomponents for each corner, which are populated by these sections. - For custom components that act as menus (e.g., popovers), use the
onOpen,onClose,isOpenprops passed down by theToolbarcomponent (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 }, theToolbarServiceautomatically sets the effectivebuttonSectionID 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.buttonSectionif 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
// }
// }
-
-
evaluateFunction Enhancement:- Button
evaluatefunctions 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
ToolBoxButtonGroupWrapperandToolButtonListWrapper:- The
groupIdprop is replaced byid(which is the ID of the wrapper button component itself). - The
onInteractioncallback 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
Headeror layout component) with<IconPresentationProvider size="yourDefaultSize">. - Custom tool button components can then use the
useIconPresentationhook 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
ToolbarSplitButtonWithServicesLegacyandToolbarButtonGroupWithServicesLegacywith the newer patterns, typically by configuring individual buttons and usingToolButtonListorButtonGroupfrom@ohif/ui-nextdirectly, driven byuseToolbar.
- Replace any usage of