Install the component from your command line.
npm install @radix-ui/react-context-menu
Copy Import the components and piece the parts together.
import * as ContextMenu from '@radix-ui/react-context-menu' ;
export default ( ) => (
< ContextMenu.Root >
< ContextMenu.Trigger />
< ContextMenu.Content >
< ContextMenu.Label />
< ContextMenu.Item />
< ContextMenu.Group >
< ContextMenu.Item />
</ ContextMenu.Group >
< ContextMenu.CheckboxItem >
< ContextMenu.ItemIndicator />
</ ContextMenu.CheckboxItem >
< ContextMenu.RadioGroup >
< ContextMenu.RadioItem >
< ContextMenu.ItemIndicator />
</ ContextMenu.RadioItem >
</ ContextMenu.RadioGroup >
< ContextMenu.Separator />
</ ContextMenu.Content >
</ ContextMenu.Root >
) ;
Copy Create your styled context menu component from the primitive parts.
import * as ContextMenu from '@radix-ui/react-context-menu' ;
const StyledContent = styled ( ContextMenu . Content , {
minWidth : 130 ,
backgroundColor : 'white' ,
borderRadius : 6 ,
padding : 5 ,
boxShadow : '0px 5px 15px -5px hsla(206,22%,7%,.15)' ,
} ) ;
const StyledItem = styled ( ContextMenu . Item , {
fontSize : 13 ,
padding : '5px 10px' ,
borderRadius : 3 ,
cursor : 'default' ,
'&:focus' : {
outline : 'none' ,
backgroundColor : 'dodgerblue' ,
color : 'white' ,
} ,
} ) ;
export default ( ) => (
< ContextMenu.Root >
< ContextMenu.Trigger >
< div
style = { {
backgroundColor : 'gainsboro' ,
padding : 50 ,
textAlign : 'center' ,
} }
>
Right click anywhere
</ div >
</ ContextMenu.Trigger >
< StyledContent >
< StyledItem > Cut </ StyledItem >
< StyledItem > Copy </ StyledItem >
< StyledItem > Paste </ StyledItem >
</ StyledContent >
</ ContextMenu.Root >
) ;
Copy Adheres to the Menu WAI-ARIA design pattern and uses roving tabindex to manage focus movement among menu items.
Contains all the parts of a context menu.
The area that opens the context menu. Wrap it around the target you want the context menu to open from when right-clicking (or using the relevant keyboard shortcuts).
Prop Type Default Required asenumspan
The component that pops out in an open context menu.
Prop Type Default Required asenumdivdisableOutsidePointerEventsbooleantrueonEscapeKeyDownfunctiononPointerDownOutsidefunctiononInteractOutsidefunctionforceMountbooleansideenum"bottom"sideOffsetnumber0alignenum"center"alignOffsetnumber0avoidCollisionsbooleantruecollisionToleranceboolean0
The component that contains the context menu items.
Prop Type Default Required asenumdivdisabledbooleanonSelectfunctiontextValuestring
Used to group multiple ContextMenu.Items.
Prop Type Default Required asenumdiv
Used to render a label. It won't be focusable using arrow keys.
Prop Type Default Required asenumdiv
An item that can be controlled and rendered like a checkbox.
Prop Type Default Required asenumdivcheckedbooleanonCheckedChangefunctiondisabledbooleanonSelectfunctiontextValuestring
Used to group multiple ContextMenu.RadioItems.
Prop Type Default Required asenumdivvaluestringonValueChangefunction
An item that can be controlled and rendered like a radio.
Prop Type Default Required asenumdivvaluestringdisabledbooleanonSelectfunctiontextValuestring
Renders when the parent ContextMenu.CheckboxItem or ContextMenu.RadioItem is checked. You can style this element directly, or you can use it as a wrapper to put an icon into, or both.
Prop Type Default Required asenumspanforceMountboolean
Used to visually separate items in the context menu.
Prop Type Default Required asenumdiv
We expose a CSS custom property --radix-context-menu-content-transform-origin. Use it to animate the content from its computed origin based on side, sideOffset, align, alignOffset and any collisions.
const scaleIn = css . keyframes ( {
'0%' : { opacity : 0 , transform : 'scale(0)' } ,
'100%' : { opacity : 1 , transform : 'scale(1)' } ,
} ) ;
const StyledContent = styled ( ContextMenu . Content , {
transformOrigin :
'var(--radix-context-menu-content-transform-origin)' ,
animation : ` ${ scaleIn } 0.5s ease-out ` ,
} ) ;
Copy We expose data-side and data-align attributes. Their values will change at runtime to reflect collisions. Use them to create collision and direction-aware animations.
const slideDown = css . keyframes ( {
'0%' : { opacity : 0 , transform : 'translateY(-10px)' } ,
'100%' : { opacity : 1 , transform : 'translateY(0)' } ,
} ) ;
const slideUp = css . keyframes ( {
'0%' : { opacity : 0 , transform : 'translateY(10px)' } ,
'100%' : { opacity : 1 , transform : 'translateY(0)' } ,
} ) ;
const StyledContent = styled ( ContextMenu . Content , {
'&[data-side="top"]' : { animationName : slideUp } ,
'&[data-side="bottom"]' : { animationName : slideDown } ,
animationDuration : '0.6s' ,
animationTimingFunction : 'cubic-bezier(0.16, 1, 0.3, 1)' ,
} ) ;
Copy You can add special styles to disabled items via the data-disabled attribute.
Show code
import * as ContextMenu from '@radix-ui/react-context-menu' ;
const StyledContent = styled ( ContextMenu . Content , {
minWidth : 130 ,
backgroundColor : 'white' ,
borderRadius : 6 ,
padding : 5 ,
boxShadow : '0px 5px 15px -5px hsla(206,22%,7%,.15)' ,
} ) ;
const StyledItem = styled ( ContextMenu . Item , {
fontSize : 13 ,
padding : '5px 10px' ,
borderRadius : 3 ,
cursor : 'default' ,
'&[data-disabled]' : {
color : 'gainsboro' ,
} ,
'&:focus' : {
outline : 'none' ,
backgroundColor : 'dodgerblue' ,
color : 'white' ,
} ,
} ) ;
export default ( ) => (
< ContextMenu.Root >
< ContextMenu.Trigger >
< div
style = { {
backgroundColor : 'gainsboro' ,
padding : 50 ,
textAlign : 'center' ,
} }
>
Right click anywhere
</ div >
</ ContextMenu.Trigger >
< StyledContent >
< StyledItem disabled > Cut </ StyledItem >
< StyledItem > Copy </ StyledItem >
< StyledItem > Paste </ StyledItem >
</ StyledContent >
</ ContextMenu.Root >
) ;
Copy Use the Separator part to add a separator between items.
Show code
import * as ContextMenu from '@radix-ui/react-context-menu' ;
const StyledContent = styled ( ContextMenu . Content , {
minWidth : 130 ,
backgroundColor : 'white' ,
borderRadius : 6 ,
padding : 5 ,
boxShadow : '0px 5px 15px -5px hsla(206,22%,7%,.15)' ,
} ) ;
const StyledItem = styled ( ContextMenu . Item , {
fontSize : 13 ,
padding : '5px 10px' ,
borderRadius : 3 ,
cursor : 'default' ,
'&:focus' : {
outline : 'none' ,
backgroundColor : 'dodgerblue' ,
color : 'white' ,
} ,
} ) ;
const StyledSeparator = styled ( ContextMenu . Separator , {
height : 1 ,
backgroundColor : 'gainsboro' ,
margin : 5 ,
} ) ;
export default ( ) => (
< ContextMenu.Root >
< ContextMenu.Trigger >
< div
style = { {
backgroundColor : 'gainsboro' ,
padding : 50 ,
textAlign : 'center' ,
} }
>
Right click anywhere
</ div >
</ ContextMenu.Trigger >
< StyledContent >
< StyledItem > Undo </ StyledItem >
< StyledItem > Redo </ StyledItem >
< StyledSeparator />
< StyledItem > Cut </ StyledItem >
< StyledItem > Copy </ StyledItem >
< StyledItem > Paste </ StyledItem >
</ StyledContent >
</ ContextMenu.Root >
) ;
Copy Use the Label part to help label a section.
Show code
import * as ContextMenu from '@radix-ui/react-context-menu' ;
const StyledContent = styled ( ContextMenu . Content , {
minWidth : 130 ,
backgroundColor : 'white' ,
borderRadius : 6 ,
padding : 5 ,
boxShadow : '0px 5px 15px -5px hsla(206,22%,7%,.15)' ,
} ) ;
const StyledItem = styled ( ContextMenu . Item , {
fontSize : 13 ,
padding : '5px 10px' ,
borderRadius : 3 ,
cursor : 'default' ,
'&:focus' : {
outline : 'none' ,
backgroundColor : 'dodgerblue' ,
color : 'white' ,
} ,
} ) ;
const StyledLabel = styled ( ContextMenu . Label , {
color : 'slategray' ,
fontSize : 13 ,
padding : '5px 10px' ,
cursor : 'default' ,
} ) ;
const StyledSeparator = styled ( ContextMenu . Separator , {
height : 1 ,
backgroundColor : 'gainsboro' ,
margin : 5 ,
} ) ;
export default ( ) => (
< ContextMenu.Root >
< ContextMenu.Trigger >
< div
style = { {
backgroundColor : 'gainsboro' ,
padding : 50 ,
textAlign : 'center' ,
} }
>
Right click anywhere
</ div >
</ ContextMenu.Trigger >
< StyledContent >
< StyledLabel > Recently Closed </ StyledLabel >
< StyledItem > Modulz </ StyledItem >
< StyledItem > Radix - ui </ StyledItem >
< StyledItem > Stitches </ StyledItem >
< StyledSeparator />
< StyledLabel > Recently Visited </ StyledLabel >
< StyledItem > GitHub </ StyledItem >
< StyledItem > Modulz </ StyledItem >
</ StyledContent >
</ ContextMenu.Root >
) ;
Copy Use the CheckboxItem part to add an item that can be checked.
Show code
import * as ContextMenu from '@radix-ui/react-context-menu' ;
import { CheckIcon } from '@modulz/radix-icons' ;
const StyledContent = styled ( ContextMenu . Content , {
minWidth : 130 ,
backgroundColor : 'white' ,
borderRadius : 6 ,
padding : 5 ,
boxShadow : '0px 5px 15px -5px hsla(206,22%,7%,.15)' ,
} ) ;
const itemStyles = {
fontSize : 13 ,
padding : '5px 10px 5px 25px' ,
borderRadius : 3 ,
cursor : 'default' ,
position : 'relative' ,
'&:focus' : {
outline : 'none' ,
backgroundColor : 'dodgerblue' ,
color : 'white' ,
} ,
} ;
const StyledItem = styled ( ContextMenu . Item , itemStyles ) ;
const StyledCheckboxItem = styled (
ContextMenu . CheckboxItem ,
itemStyles
) ;
const StyledItemIndicator = styled ( ContextMenu . ItemIndicator , {
position : 'absolute' ,
left : 5 ,
} ) ;
const StyledSeparator = styled ( ContextMenu . Separator , {
height : 1 ,
backgroundColor : 'gainsboro' ,
margin : 5 ,
} ) ;
export default ( ) => {
const [ checked , setChecked ] = React . useState ( true ) ;
return (
< ContextMenu.Root >
< ContextMenu.Trigger >
< div
style = { {
backgroundColor : 'gainsboro' ,
padding : 50 ,
textAlign : 'center' ,
} }
>
Right click anywhere
</ div >
</ ContextMenu.Trigger >
< StyledContent >
< StyledItem > About Radix UI </ StyledItem >
< StyledItem > Check for updates </ StyledItem >
< StyledSeparator />
< StyledCheckboxItem
checked = { checked }
onCheckedChange = { setChecked }
>
< StyledItemIndicator >
< CheckIcon />
</ StyledItemIndicator >
Show hidden files
</ StyledCheckboxItem >
</ StyledContent >
</ ContextMenu.Root >
) ;
} ;
Copy Use the RadioGroup and RadioItem parts to add an item that can be checked amongst others.
Show code
import * as ContextMenu from '@radix-ui/react-context-menu' ;
import { CheckIcon } from '@modulz/radix-icons' ;
const StyledContent = styled ( ContextMenu . Content , {
minWidth : 130 ,
backgroundColor : 'white' ,
borderRadius : 6 ,
padding : 5 ,
boxShadow : '0px 5px 15px -5px hsla(206,22%,7%,.15)' ,
} ) ;
const itemStyles = {
fontSize : 13 ,
padding : '5px 10px 5px 25px' ,
borderRadius : 3 ,
cursor : 'default' ,
position : 'relative' ,
'&:focus' : {
outline : 'none' ,
backgroundColor : 'dodgerblue' ,
color : 'white' ,
} ,
} ;
const StyledItem = styled ( ContextMenu . Item , itemStyles ) ;
const StyledRadioGroup = styled ( ContextMenu . RadioGroup , { } ) ;
const StyledRadioItem = styled ( ContextMenu . RadioItem , itemStyles ) ;
const StyledItemIndicator = styled ( ContextMenu . ItemIndicator , {
position : 'absolute' ,
left : 5 ,
} ) ;
export default ( ) => {
const [ color , setColor ] = React . useState ( 'blue' ) ;
return (
< ContextMenu.Root >
< ContextMenu.Trigger >
< div
style = { {
backgroundColor : 'gainsboro' ,
padding : 50 ,
textAlign : 'center' ,
} }
>
Right click anywhere
</ div >
</ ContextMenu.Trigger >
< StyledContent >
< StyledRadioGroup value = { color } onValueChange = { setColor } >
< StyledRadioItem value = " red " >
< StyledItemIndicator >
< CheckIcon />
</ StyledItemIndicator >
Red
</ StyledRadioItem >
< StyledRadioItem value = " blue " >
< StyledItemIndicator >
< CheckIcon />
</ StyledItemIndicator >
Blue
</ StyledRadioItem >
< StyledRadioItem value = " green " >
< StyledItemIndicator >
< CheckIcon />
</ StyledItemIndicator >
Green
</ StyledRadioItem >
</ StyledRadioGroup >
</ StyledContent >
</ ContextMenu.Root >
) ;
} ;
Copy Show code
import * as ContextMenu from '@radix-ui/react-context-menu' ;
const StyledContent = styled ( ContextMenu . Content , {
minWidth : 130 ,
backgroundColor : 'white' ,
borderRadius : 6 ,
padding : 5 ,
boxShadow : '0px 5px 15px -5px hsla(206,22%,7%,.15)' ,
} ) ;
const StyledItem = styled ( ContextMenu . Item , {
fontSize : 13 ,
padding : '5px 10px' ,
borderRadius : 3 ,
cursor : 'default' ,
'&:focus' : {
outline : 'none' ,
backgroundColor : 'dodgerblue' ,
color : 'white' ,
} ,
} ) ;
const StyledArrow = styled ( ContextMenu . Arrow , {
fill : 'white' ,
} ) ;
const Image = styled ( 'img' , {
width : 24 ,
height : 24 ,
borderRadius : 9999 ,
marginRight : 10 ,
} ) ;
export default ( ) => (
< ContextMenu.Root >
< ContextMenu.Trigger >
< div
style = { {
backgroundColor : 'gainsboro' ,
padding : 50 ,
textAlign : 'center' ,
} }
>
Right click anywhere
</ div >
</ ContextMenu.Trigger >
< StyledContent >
< StyledItem >
< Image src = " https://images.unsplash.com/photo-1463453091185-61582044d556?auto=format&fit=facearea&facepad=3&w=24&h=24&dpr=2&q=80 " />
Adolfo Hess
</ StyledItem >
< StyledItem >
< Image src = " https://images.unsplash.com/photo-1494790108377-be9c29b29330?auto=format&fit=facearea&facepad=3&w=24&h=24&dpr=2&q=80 " />
Miyah Myles
</ StyledItem >
< StyledItem >
< Image src = " https://images.unsplash.com/photo-1508186225823-0963cf9ab0de?auto=format&fit=facearea&facepad=3&w=24&h=24&dpr=2&q=80 " />
Sylvia Reynolds
</ StyledItem >
< StyledArrow />
</ StyledContent >
</ ContextMenu.Root >
) ;
Copy Key Description Space Activates the focused item. Enter Activates the focused item. ArrowDown Moves focus to the next item. ArrowUp Moves focus to the previous item. Esc Closes Content.