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>