Button
Key Changes:​
- Component Library: The primary
Buttoncomponent likely now resides in@ohif/ui-nextinstead of@ohif/ui. Imports need to be updated. ButtonEnumsDeprecated: TheButtonEnums.type(e.g.,ButtonEnums.type.primary) used for button styling is deprecated. Styling is now primarily controlled by thevariantprop using string literals ('default','secondary','ghost','link').- Styling Approach: Manual Tailwind CSS classes for styling (colors, hover states, sizing) are largely replaced by the
variantandsizeprops on the newButtoncomponent. Semantic color names are used internally. IconButtonReplacement: The pattern of using a dedicatedIconButtoncomponent is often replaced by using<Button variant="ghost" size="icon">and embedding an icon component (like<Icons.ByName name="..." />) within it.ButtonGroupDeprecated: TheButtonGroupcomponent is deprecated and replaced by theTabs,TabsList, andTabsTriggercomponents from@ohif/ui-nextfor creating selectable groups.- Specific Action Buttons: In certain contexts (like viewport actions or footers), generic buttons or styled
divelements might be replaced by more specific components likeViewportActionButtonor composite components likeFooterAction. - Color System: Custom color classes (e.g.,
text-primary-active,bg-primary-main) are replaced by a new semantic color system (e.g.,text-primary,bg-primary,text-muted-foreground). Variants often handle color states (hover, active) automatically.
Migration Steps:​
-
Update Imports: Replace imports for
Buttonand related enums from@ohif/uiwith the newButtoncomponent, likely from@ohif/ui-next.- import { Button, ButtonEnums, IconButton } from '@ohif/ui';
+ import { Button, Icons } from '@ohif/ui-next'; -
Migrate Manual Styling to
variantandsizeProps: Remove custom Tailwind CSS classes for basic button appearance, hover states, and sizing. Use thevariant('default','secondary','ghost','link') andsize('sm','default','lg','icon') props instead.Example (
DynamicVolumeControls.tsxchange):- <Button
- className="mt-2 !h-[26px] !w-[115px] self-start !p-0"
- onClick={() => { onGenerate(computeViewMode); }}
- >
+ <Button
+ variant="default"
+ size="sm"
+ className="mt-2 h-[26px] w-[115px] self-start p-0" // Keep only necessary layout/positioning classes
+ onClick={handleGenerate}
+ >
Generate
</Button> -
Replace
IconButton: Update instances of<IconButton>to use<Button variant="ghost" size="icon">. Place the icon component from@ohif/ui-next(e.g.,<Icons.ByName name="icon-name" />) inside the button.Example (
DynamicVolumeControls.tsxchange):- <IconButton
- className="bg-customblue-30 h-[26px] w-[58px] rounded-[4px]"
- onClick={() => onPlayPauseChange(!isPlaying)}
- >
- <Icon
- name={getPlayPauseIconName()}
- className="active:text-primary-light hover:bg-customblue-300 h-[24px] w-[24px] cursor-pointer text-white"
- />
- </IconButton>
+ <Button
+ id="play-pause-button"
+ variant="secondary" // Or "ghost" depending on final desired style
+ size="default" // Or "icon" if only icon is needed
+ className="w-[58px]" // Keep specific width if necessary
+ onClick={() => {
+ if (typeof onPlayPauseChange === 'function') {
+ onPlayPauseChange(!isPlaying);
+ }
+ }}
+ >
+ <Icons.ByName
+ name={getPlayPauseIconName()}
+ className="text-foreground h-[24px] w-[24px]" // Use semantic colors
+ />
+ </Button> -
Replace
ButtonGroupwithTabs: Refactor sections usingButtonGroupto use theTabs,TabsList, andTabsTriggercomponents. Manage the selected state using thevalueandonValueChangeprops of theTabscomponent.Example (
DynamicVolumeControls.tsxchange):- <ButtonGroup className="mt-2 w-full">
- <button className="w-1/2" onClick={() => setComputedView(false)}>4D</button>
- <button className="w-1/2" onClick={() => setComputedView(true)}>Computed</button>
- </ButtonGroup>
+ <Tabs
+ value={computedView ? 'computed' : '4d'}
+ onValueChange={value => setComputedView(value === 'computed')}
+ className="my-2 w-full"
+ >
+ <TabsList className="w-full">
+ <TabsTrigger value="4d" className="w-1/2">4D</TabsTrigger>
+ <TabsTrigger value="computed" className="w-1/2">Computed</TabsTrigger>
+ </TabsList>
+ </Tabs> -
Identify Specific Component Replacements: Review areas where styled
divelements were used as buttons. Replace them with appropriate components like<Button>or domain-specific ones if available (e.g.,ViewportActionButton).Example (
_getStatusComponent.tsxchange):- <div
- className="bg-primary-main hover:bg-primary-light ml-1 cursor-pointer rounded px-1.5 hover:text-black"
- onMouseUp={onStatusClick}
- >
- {loadStr}
- </div>
+ <ViewportActionButton onInteraction={onStatusClick}>{loadStr}</ViewportActionButton>Example (
VolumeRenderingPresetsContent.tsxchange):- <Button
- name="Cancel"
- size={ButtonEnums.size.medium}
- type={ButtonEnums.type.secondary}
- onClick={onClose}
- > Cancel </Button>
+ <FooterAction>
+ <FooterAction.Right>
+ <FooterAction.Secondary onClick={hide}>Cancel</FooterAction.Secondary>
+ </FooterAction.Right>
+ </FooterAction>