Action Menu - Admin Components
ActionMenu component from the @medusajs/dashboard package since v2.21.0. Use the exported component instead of building your own. This guide is kept for reference only.In this guide, you'll learn how to add an action menu to your Medusa Admin customizations.
The Medusa Admin often provides additional actions in a dropdown shown when users click a three-dot icon.

To create a component that shows this menu in your customizations, create the file src/admin/components/action-menu.tsx with the following content:
1import { 2 DropdownMenu,3 IconButton,4 clx,5} from "@medusajs/ui"6import { EllipsisHorizontal } from "@medusajs/icons"7import { Link } from "react-router-dom"8 9export type Action = {10 icon: React.ReactNode11 label: string12 disabled?: boolean13} & (14 | {15 to: string16 onClick?: never17 }18 | {19 onClick: () => void20 to?: never21 }22)23 24export type ActionGroup = {25 actions: Action[]26}27 28export type ActionMenuProps = {29 groups: ActionGroup[]30}31 32export const ActionMenu = ({ groups }: ActionMenuProps) => {33 return (34 <DropdownMenu>35 <DropdownMenu.Trigger asChild>36 <IconButton size="small" variant="transparent">37 <EllipsisHorizontal />38 </IconButton>39 </DropdownMenu.Trigger>40 <DropdownMenu.Content>41 {groups.map((group, index) => {42 if (!group.actions.length) {43 return null44 }45 46 const isLast = index === groups.length - 147 48 return (49 <DropdownMenu.Group key={index}>50 {group.actions.map((action, index) => {51 if (action.onClick) {52 return (53 <DropdownMenu.Item54 disabled={action.disabled}55 key={index}56 onClick={(e) => {57 e.stopPropagation()58 action.onClick()59 }}60 className={clx(61 "[&_svg]:text-ui-fg-subtle flex items-center gap-x-2",62 {63 "[&_svg]:text-ui-fg-disabled": action.disabled,64 }65 )}66 >67 {action.icon}68 <span>{action.label}</span>69 </DropdownMenu.Item>70 )71 }72 73 return (74 <div key={index}>75 <DropdownMenu.Item76 className={clx(77 "[&_svg]:text-ui-fg-subtle flex items-center gap-x-2",78 {79 "[&_svg]:text-ui-fg-disabled": action.disabled,80 }81 )}82 asChild83 disabled={action.disabled}84 >85 <Link to={action.to} onClick={(e) => e.stopPropagation()}>86 {action.icon}87 <span>{action.label}</span>88 </Link>89 </DropdownMenu.Item>90 </div>91 )92 })}93 {!isLast && <DropdownMenu.Separator />}94 </DropdownMenu.Group>95 )96 })}97 </DropdownMenu.Content>98 </DropdownMenu>99 )100}
The ActionMenu component shows a three-dots icon (or EllipsisHorizontal) from the Medusa Icons package in a button.
When the button is clicked, a dropdown menu is shown with the actions passed in the props.
The component accepts the following props:
Example#
Use the ActionMenu component in any widget or UI route.
For example, create the widget src/admin/widgets/product-widget.tsx with the following content:
1import { defineWidgetConfig } from "@medusajs/admin-sdk"2import { Pencil } from "@medusajs/icons"3import { Container } from "../components/container"4import { ActionMenu } from "../components/action-menu"5 6const ProductWidget = () => {7 return (8 <Container>9 <ActionMenu groups={[10 {11 actions: [12 {13 icon: <Pencil />,14 label: "Edit",15 onClick: () => {16 alert("You clicked the edit action!")17 },18 },19 ],20 },21 ]} />22 </Container>23 )24}25 26export const config = defineWidgetConfig({27 zone: "product.details",28})29 30export default ProductWidget
This widget also uses a Container custom component.
Use in Header#
You can also use the action menu in the Header component as part of its actions.
For example:
1import { defineWidgetConfig } from "@medusajs/admin-sdk"2import { Pencil } from "@medusajs/icons"3import { Container } from "../components/container"4import { Header } from "../components/header"5 6const ProductWidget = () => {7 return (8 <Container>9 <Header 10 title="Product Widget"11 subtitle="This is my custom product widget"12 actions={[13 {14 type: "action-menu",15 props: {16 groups: [17 {18 actions: [19 {20 icon: <Pencil />,21 label: "Edit",22 onClick: () => {23 alert("You clicked the edit action!")24 },25 },26 ],27 },28 ],29 },30 },31 ]}32 />33 </Container>34 )35}36 37export const config = defineWidgetConfig({38 zone: "product.details",39})40 41export default ProductWidget