Action Menu - Admin Components

The Medusa Admin often provides additional actions in a dropdown shown when users click a three-dot icon.

Example of an action menu in the Medusa Admin

To create a component that shows this menu in your customizations, create the file src/admin/components/action-menu.tsx with the following content:

src/admin/components/action-menu.tsx
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:

groupsobject[]
Groups of actions to be shown in the dropdown. Each group is separated by a divider.

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:

src/admin/widgets/product-widget.tsx
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.before",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:

src/admin/widgets/product-widget.tsx
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.before",39})40
41export default ProductWidget
Was this page helpful?
Edit this page